* Robert Haas (robertmh...@gmail.com) wrote: > Ugg, wait a minute. This not only adds %U; it also changes the > behavior of %u, which I don't think we've agreed on. Also, emitting > 'none' when not SET ROLE has been done is pretty ugly. I'm back to > thinking we need to push this out to 9.2 and take more time to think > about this.
%u, user_name, etc changes reverted. %U now always returns the role currently being used for permissions checks, by using show_session_authorization() when show_role() returns 'none'. Ditto for CSV updates. git log below, re-based patch attached. All regression tests passed, tested with log_line_prefix and csvlog also, all looks good to me. Robert, if you say this has to be punted to 9.2 again, I'm giving up. ;) Thanks, Stephen
*** a/doc/src/sgml/config.sgml --- b/doc/src/sgml/config.sgml *************** *** 3562,3568 **** local0.* /var/log/postgresql </row> <row> <entry><literal>%u</literal></entry> ! <entry>User name</entry> <entry>yes</entry> </row> <row> --- 3562,3579 ---- </row> <row> <entry><literal>%u</literal></entry> ! <entry>Authenticated user name, the user name that the user used ! to authenticate to <productname>PostgreSQL</productname> with. ! <entry>yes</entry> ! </row> ! <row> ! <entry><literal>%U</literal></entry> ! <entry>Current role being used for permissions checking, can be ! set with <command>SET ROLE</> or <command>SET SESSION ! AUTHORIZATION</> (only allowed for superusers); ! Note: Log messages from inside <literal>SECURITY DEFINER</> ! functions will show the calling role, not the effective role ! inside the <literal>SECURITY DEFINER</> function</entry> <entry>yes</entry> </row> <row> *************** *** 3790,3795 **** FROM pg_stat_activity; --- 3801,3807 ---- with these columns: timestamp with milliseconds, user name, + current role name, database name, process ID, client host:port number, *************** *** 3820,3825 **** CREATE TABLE postgres_log --- 3832,3838 ---- ( log_time timestamp(3) with time zone, user_name text, + curr_role text, database_name text, process_id integer, connection_from text, *** a/src/backend/commands/variable.c --- b/src/backend/commands/variable.c *************** *** 847,852 **** assign_session_authorization(const char *value, bool doit, GucSource source) --- 847,857 ---- return result; } + /* + * function to return the stored session username, needed because we + * can't do catalog lookups when possibly being called after an error, + * eg: from elog.c or part of GUC handling. + */ const char * show_session_authorization(void) { *************** *** 972,977 **** assign_role(const char *value, bool doit, GucSource source) --- 977,987 ---- return result; } + /* + * function to return the stored role username, needed because we + * can't do catalog lookups when possibly being called after an error, + * eg: from elog.c or part of GUC handling. + */ const char * show_role(void) { *** a/src/backend/utils/error/elog.c --- b/src/backend/utils/error/elog.c *************** *** 65,70 **** --- 65,71 ---- #include "access/transam.h" #include "access/xact.h" + #include "commands/variable.h" #include "libpq/libpq.h" #include "libpq/pqformat.h" #include "mb/pg_wchar.h" *************** *** 1777,1782 **** log_line_prefix(StringInfo buf, ErrorData *edata) --- 1778,1795 ---- int format_len; int i; + /* gather current session and role names */ + const char *session_auth = show_session_authorization(); + const char *role_auth = show_role(); + + /* what we'll actually log as current role, based on if + * a set role has been done or not */ + char *curr_role = role_auth; + + /* if show_role() returns 'none', then we log the session user instead */ + if (strcmp(role_auth,"none") == 0) + curr_role = session_auth; + /* * This is one of the few places where we'd rather not inherit a static * variable's value from the postmaster. But since we will, reset it when *************** *** 1832,1837 **** log_line_prefix(StringInfo buf, ErrorData *edata) --- 1845,1853 ---- appendStringInfoString(buf, username); } break; + case 'U': + appendStringInfoString(buf, curr_role); + break; case 'd': if (MyProcPort) { *************** *** 1967,1972 **** write_csvlog(ErrorData *edata) --- 1983,2000 ---- /* has counter been reset in current process? */ static int log_my_pid = 0; + /* pull the session authorization */ + const char *session_auth = show_session_authorization(); + const char *role_auth = show_role(); + + /* what we'll actually log as current role, based on if + * a set role has been done or not */ + char *curr_role = role_auth; + + /* if show_role() returns 'none', then we log the session user instead */ + if (strcmp(role_auth,"none") == 0) + curr_role = session_auth; + /* * This is one of the few places where we'd rather not inherit a static * variable's value from the postmaster. But since we will, reset it when *************** *** 1995,2005 **** write_csvlog(ErrorData *edata) appendStringInfoString(&buf, formatted_log_time); appendStringInfoChar(&buf, ','); ! /* username */ if (MyProcPort) appendCSVLiteral(&buf, MyProcPort->user_name); appendStringInfoChar(&buf, ','); /* database name */ if (MyProcPort) appendCSVLiteral(&buf, MyProcPort->database_name); --- 2023,2037 ---- appendStringInfoString(&buf, formatted_log_time); appendStringInfoChar(&buf, ','); ! /* authenticated-with username */ if (MyProcPort) appendCSVLiteral(&buf, MyProcPort->user_name); appendStringInfoChar(&buf, ','); + /* current role name, matches %U in log_line_prefix */ + appendStringInfoString(&buf, curr_role); + appendStringInfoChar(&buf, ','); + /* database name */ if (MyProcPort) appendCSVLiteral(&buf, MyProcPort->database_name); *** a/src/backend/utils/misc/postgresql.conf.sample --- b/src/backend/utils/misc/postgresql.conf.sample *************** *** 361,367 **** #log_hostname = off #log_line_prefix = '' # special values: # %a = application name ! # %u = user name # %d = database name # %r = remote host and port # %h = remote host --- 361,368 ---- #log_hostname = off #log_line_prefix = '' # special values: # %a = application name ! # %u = authenticated user name ! # %U = current role name # %d = database name # %r = remote host and port # %h = remote host
signature.asc
Description: Digital signature