The attached patch adds a column "authuser" to pg_stat_activity which contains the username of the externally authenticated user, being the same value as the SYSTEM_USER keyword returns in a backend.
This overlaps with for example the values in pg_stat_gss, but it will include values for authentication methods that don't have their own view such as peer/ident. gss/ssl info will of course still be shown, it is just in more than one place. I was originally thinking this column should be "sysuser" to map to the keyword, but since we already have "usesysid" as a column name in pg_stat_activity I figured that could be confusing since it actually means something completely different. But happy to change that back if people think that's better. -- Magnus Hagander Me: https://www.hagander.net/ Work: https://www.redpill-linpro.com/
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index de78d58d4b..ec6a25495f 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -23462,7 +23462,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); <row> <entry role="func_table_entry"><para role="func_signature"> - <indexterm> + <indexterm id="system-user"> <primary>system_user</primary> </indexterm> <function>system_user</function> diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index b804eb8b5e..dc146a4c9f 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -784,6 +784,17 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser </para></entry> </row> + <row> + <entry role="catalog_table_entry"><para role="column_definition"> + <structfield>authname</structfield> <type>name</type> + </para> + <para> + The authentication method and identity (if any) that the user + used to log in. It contains the same value as + <xref linkend="system-user" /> returns in the backend. + </para></entry> + </row> + <row> <entry role="catalog_table_entry"><para role="column_definition"> <structfield>application_name</structfield> <type>text</type> diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql index e43e36f5ac..fe81aefbbb 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -873,6 +873,7 @@ CREATE VIEW pg_stat_activity AS S.leader_pid, S.usesysid, U.rolname AS usename, + S.authname, S.application_name, S.client_addr, S.client_hostname, diff --git a/src/backend/utils/activity/backend_status.c b/src/backend/utils/activity/backend_status.c index 3dac79c30e..ffface119e 100644 --- a/src/backend/utils/activity/backend_status.c +++ b/src/backend/utils/activity/backend_status.c @@ -357,6 +357,11 @@ pgstat_bestart(void) else MemSet(&lbeentry.st_clientaddr, 0, sizeof(lbeentry.st_clientaddr)); + if (MyProcPort && GetSystemUser()) + strlcpy(lbeentry.st_authuser, GetSystemUser(), NAMEDATALEN); + else + MemSet(&lbeentry.st_authuser, 0, sizeof(lbeentry.st_authuser)); + #ifdef USE_SSL if (MyProcPort && MyProcPort->ssl_in_use) { diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c index 30a2063505..cd9769c52c 100644 --- a/src/backend/utils/adt/pgstatfuncs.c +++ b/src/backend/utils/adt/pgstatfuncs.c @@ -304,7 +304,7 @@ pg_stat_get_progress_info(PG_FUNCTION_ARGS) Datum pg_stat_get_activity(PG_FUNCTION_ARGS) { -#define PG_STAT_GET_ACTIVITY_COLS 31 +#define PG_STAT_GET_ACTIVITY_COLS 32 int num_backends = pgstat_fetch_stat_numbackends(); int curr_backend; int pid = PG_ARGISNULL(0) ? -1 : PG_GETARG_INT32(0); @@ -617,6 +617,9 @@ pg_stat_get_activity(PG_FUNCTION_ARGS) nulls[30] = true; else values[30] = UInt64GetDatum(beentry->st_query_id); + + /* Authenticated user */ + values[31] = CStringGetTextDatum(beentry->st_authuser); } else { @@ -646,6 +649,7 @@ pg_stat_get_activity(PG_FUNCTION_ARGS) nulls[28] = true; nulls[29] = true; nulls[30] = true; + nulls[31] = true; } tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 7979392776..bca8ea8db8 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -5440,9 +5440,9 @@ proname => 'pg_stat_get_activity', prorows => '100', proisstrict => 'f', proretset => 't', provolatile => 's', proparallel => 'r', prorettype => 'record', proargtypes => 'int4', - proallargtypes => '{int4,oid,int4,oid,text,text,text,text,text,timestamptz,timestamptz,timestamptz,timestamptz,inet,text,int4,xid,xid,text,bool,text,text,int4,text,numeric,text,bool,text,bool,bool,int4,int8}', - proargmodes => '{i,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}', - proargnames => '{pid,datid,pid,usesysid,application_name,state,query,wait_event_type,wait_event,xact_start,query_start,backend_start,state_change,client_addr,client_hostname,client_port,backend_xid,backend_xmin,backend_type,ssl,sslversion,sslcipher,sslbits,ssl_client_dn,ssl_client_serial,ssl_issuer_dn,gss_auth,gss_princ,gss_enc,gss_delegation,leader_pid,query_id}', + proallargtypes => '{int4,oid,int4,oid,text,text,text,text,text,timestamptz,timestamptz,timestamptz,timestamptz,inet,text,int4,xid,xid,text,bool,text,text,int4,text,numeric,text,bool,text,bool,bool,int4,int8,text}', + proargmodes => '{i,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}', + proargnames => '{pid,datid,pid,usesysid,application_name,state,query,wait_event_type,wait_event,xact_start,query_start,backend_start,state_change,client_addr,client_hostname,client_port,backend_xid,backend_xmin,backend_type,ssl,sslversion,sslcipher,sslbits,ssl_client_dn,ssl_client_serial,ssl_issuer_dn,gss_auth,gss_princ,gss_enc,gss_delegation,leader_pid,query_id,authname}', prosrc => 'pg_stat_get_activity' }, { oid => '8403', descr => 'describe wait events', proname => 'pg_get_wait_events', procost => '10', prorows => '250', diff --git a/src/include/utils/backend_status.h b/src/include/utils/backend_status.h index 7b8a34f64f..7237b40f42 100644 --- a/src/include/utils/backend_status.h +++ b/src/include/utils/backend_status.h @@ -132,6 +132,9 @@ typedef struct PgBackendStatus SockAddr st_clientaddr; char *st_clienthostname; /* MUST be null-terminated */ + /* Information about the authenticated user */ + char st_authuser[NAMEDATALEN]; + /* Information about SSL connection */ bool st_ssl; PgBackendSSLStatus *st_sslstatus; diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out index d878a971df..9d30885c14 100644 --- a/src/test/regress/expected/rules.out +++ b/src/test/regress/expected/rules.out @@ -1744,6 +1744,7 @@ pg_stat_activity| SELECT s.datid, s.leader_pid, s.usesysid, u.rolname AS usename, + s.authname, s.application_name, s.client_addr, s.client_hostname, @@ -1760,7 +1761,7 @@ pg_stat_activity| SELECT s.datid, s.query_id, s.query, s.backend_type - FROM ((pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, ssl_client_dn, ssl_client_serial, ssl_issuer_dn, gss_auth, gss_princ, gss_enc, gss_delegation, leader_pid, query_id) + FROM ((pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, ssl_client_dn, ssl_client_serial, ssl_issuer_dn, gss_auth, gss_princ, gss_enc, gss_delegation, leader_pid, query_id, authname) LEFT JOIN pg_database d ON ((s.datid = d.oid))) LEFT JOIN pg_authid u ON ((s.usesysid = u.oid))); pg_stat_all_indexes| SELECT c.oid AS relid, @@ -1880,7 +1881,7 @@ pg_stat_gssapi| SELECT pid, gss_princ AS principal, gss_enc AS encrypted, gss_delegation AS credentials_delegated - FROM pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, ssl_client_dn, ssl_client_serial, ssl_issuer_dn, gss_auth, gss_princ, gss_enc, gss_delegation, leader_pid, query_id) + FROM pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, ssl_client_dn, ssl_client_serial, ssl_issuer_dn, gss_auth, gss_princ, gss_enc, gss_delegation, leader_pid, query_id, authname) WHERE (client_port IS NOT NULL); pg_stat_io| SELECT backend_type, object, @@ -2082,7 +2083,7 @@ pg_stat_replication| SELECT s.pid, w.sync_priority, w.sync_state, w.reply_time - FROM ((pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, ssl_client_dn, ssl_client_serial, ssl_issuer_dn, gss_auth, gss_princ, gss_enc, gss_delegation, leader_pid, query_id) + FROM ((pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, ssl_client_dn, ssl_client_serial, ssl_issuer_dn, gss_auth, gss_princ, gss_enc, gss_delegation, leader_pid, query_id, authname) JOIN pg_stat_get_wal_senders() w(pid, state, sent_lsn, write_lsn, flush_lsn, replay_lsn, write_lag, flush_lag, replay_lag, sync_priority, sync_state, reply_time) ON ((s.pid = w.pid))) LEFT JOIN pg_authid u ON ((s.usesysid = u.oid))); pg_stat_replication_slots| SELECT s.slot_name, @@ -2116,7 +2117,7 @@ pg_stat_ssl| SELECT pid, ssl_client_dn AS client_dn, ssl_client_serial AS client_serial, ssl_issuer_dn AS issuer_dn - FROM pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, ssl_client_dn, ssl_client_serial, ssl_issuer_dn, gss_auth, gss_princ, gss_enc, gss_delegation, leader_pid, query_id) + FROM pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, ssl_client_dn, ssl_client_serial, ssl_issuer_dn, gss_auth, gss_princ, gss_enc, gss_delegation, leader_pid, query_id, authname) WHERE (client_port IS NOT NULL); pg_stat_subscription| SELECT su.oid AS subid, su.subname,