Skip to content

Commit

Permalink
Add superuser audit tag GUC
Browse files Browse the repository at this point in the history
This commit adds the ability to tag superuser escalation logs with a specific
audit tag. Defaults to "AUDIT".
  • Loading branch information
mpalmi committed May 17, 2018
1 parent 77942df commit 9337606
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 6 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ This PostgreSQL extension allows switching users and optionally privilege escala
* If set_user.block_log_statement is set to "on", ```SET log_statement``` and
variations will be blocked.
* If set_user.block_log_statement is set to "on" and ```rolename``` is a database superuser, the current log_statement setting is changed to "all", meaning every SQL statement executed
* If set_user.superuser_audit_tag is set, the string value will be appended to log_line_prefix upon superuser escalation. All logs after superuser escalation will be tagged with the value of set_user.superuser_audit_tag. This value defaults to 'AUDIT'.
* [Post-execution hook](#post_set_user_hook) for ```set_user``` is called if it is set.

Only users with EXECUTE permission on ```set_user_u('rolename')``` may escalate to superuser. Additionally, only roles explicitly listed or included by a group that is explicitly listed (e.g. '+admin') in set_user.superuser_whitelist can escalate to superuser. If set_user.superuser_whitelist is explicitly set to the empty set, '', superuser escalation is blocked for all users. If the whitelist is equal to the wildcard character, '*', all users with EXECUTE permission on ```set_user_u()``` can escalate to superuser. The default value of set_user.superuser_whitelist is '*'.
Expand Down
39 changes: 33 additions & 6 deletions set_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@

#include "set_user.h"
#define WHITELIST_WILDCARD "*"
#define SUPERUSER_AUDIT_TAG "AUDIT"

PG_MODULE_MAGIC;

Expand All @@ -127,6 +128,7 @@ static bool Block_CP = false;

static bool Block_LS = false;
static char *SU_Whitelist = NULL;
static char *SU_AuditTag = NULL;

#ifdef HAS_TWO_ARG_GETUSERNAMEFROMID
/* 9.5 - master */
Expand Down Expand Up @@ -356,14 +358,34 @@ set_user(PG_FUNCTION_ARGS)
false, false));
MemoryContextSwitchTo(oldcontext);

/*
* Force logging of everything if block_log_statement is true
* and we are escalating to superuser. If not escalating to superuser
* the caller could always set log_statement to all prior to using
* set_user, and ensure Block_LS is true.
*/
if (NewUser_is_superuser && Block_LS)
{
char *new_log_prefix = NULL;
char *old_log_prefix = NULL;


old_log_prefix = GetConfigOption("log_line_prefix", true, false);

if (old_log_prefix)
new_log_prefix = psprintf("%s %s: ", old_log_prefix, SU_AuditTag);
else
new_log_prefix = pstrdup(SU_AuditTag);

/*
* Force logging of everything if block_log_statement is true
* and we are escalating to superuser. If not escalating to superuser the
* caller could always set log_statement to all prior to using set_user,
* and ensure Block_LS is true.
*/
SetConfigOption("log_statement", "all", PGC_SUSET, PGC_S_SESSION);

/*
* Add a custom AUDIT tag to postgresql.conf setting
* 'log_line_prefix' so log statements are tagged for easy
* filtering.
*/
SetConfigOption("log_line_prefix", new_log_prefix, PGC_POSTMASTER, PGC_S_SESSION);
}
}
else if (is_reset)
{
Expand Down Expand Up @@ -453,6 +475,11 @@ _PG_init(void)
"Allows a list of users to use set_user_u for superuser escalation",
NULL, &SU_Whitelist, WHITELIST_WILDCARD, PGC_SIGHUP,
0, NULL, NULL, NULL);

DefineCustomStringVariable("set_user.superuser_audit_tag",
"Set custom tag for superuser audit escalation",
NULL, &SU_AuditTag, SUPERUSER_AUDIT_TAG, PGC_SIGHUP,
0, NULL, NULL, NULL);
/* Install hook */
prev_hook = ProcessUtility_hook;
ProcessUtility_hook = PU_hook;
Expand Down

0 comments on commit 9337606

Please sign in to comment.