Skip to content

Commit

Permalink
Add post-set_user hooks
Browse files Browse the repository at this point in the history
This commit introduces two hooks which allow another extension to do something
(and return) immediately after `set_user` and `reset_user` are called.

There is a new make target, `make install-headers`, which is responsible for
exposing the hook to other extensions. The target is prepended to the
`install` target by default.

To use the post-set_user hooks in an extension:
1) Add '-I$(includedir)' to CPPFLAGS
2) #include set_user.h in whichever file implements the hook
3) Register the 'post_reset_user_hook' and 'post_set_user_hook' with a local
implementation
  • Loading branch information
mpalmi committed Apr 10, 2018
1 parent bb5e0ce commit e673604
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 0 deletions.
12 changes: 12 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,15 @@ top_builddir = ../..
include $(top_builddir)/src/Makefile.global
include $(top_srcdir)/contrib/contrib-global.mk
endif

.PHONY: install-headers uninstall-headers

install: install-headers

install-headers:
$(INSTALL_DATA) "set_user.h" $(includedir)

uninstall: uninstall-headers

uninstall-headers:
rm "$(includedir)/set_user.h"
23 changes: 23 additions & 0 deletions set_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "postgres.h"

#include "pg_config.h"

#if !defined(PG_VERSION_NUM) || PG_VERSION_NUM < 90100
/* prior to 9.1 */
#error "This extension only builds with PostgreSQL 9.1 or later"
Expand Down Expand Up @@ -100,6 +101,7 @@
#include "utils/varlena.h"
#endif /* HAS_VARLENA_H */

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

PG_MODULE_MAGIC;
Expand All @@ -109,6 +111,9 @@ static Oid save_OldUserId = InvalidOid;
static char *reset_token = NULL;
static ProcessUtility_hook_type prev_hook = NULL;

post_reset_user_hook_type post_reset_user_hook = NULL;
post_set_user_hook_type post_set_user_hook = NULL;

#ifdef HAS_ALTER_SYSTEM
/* 9.4 & up */
static bool Block_AS = false;
Expand Down Expand Up @@ -151,6 +156,8 @@ static void PU_hook(Node *parsetree, const char *queryString,
#endif
#endif

extern void PostSetUserHook(bool is_reset, const char *newuser);

extern Datum set_user(PG_FUNCTION_ARGS);
void _PG_init(void);
void _PG_fini(void);
Expand Down Expand Up @@ -399,6 +406,7 @@ set_user(PG_FUNCTION_ARGS)
newuser);

SetCurrentRoleId(NewUserId, NewUser_is_superuser);
PostSetUserHook(is_reset, newuser);

PG_RETURN_TEXT_P(cstring_to_text("OK"));
}
Expand Down Expand Up @@ -543,3 +551,18 @@ PU_hook(Node *parsetree, const char *queryString,
#endif
#endif
}

/*
* PostSetUserHook
*
* Handler for the post_set_user_hook
*/
void
PostSetUserHook(bool is_reset, const char *username)
{
if (post_reset_user_hook && is_reset)
(*post_reset_user_hook) ();
else if (post_set_user_hook)
(*post_set_user_hook) (username);
return;
}
11 changes: 11 additions & 0 deletions set_user.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#ifndef SET_USER_H
#define SET_USER_H

/* Expose a hook for other extensions to use after reset_user finishes up. */
typedef void (*post_reset_user_hook_type) (void);
extern PGDLLIMPORT post_reset_user_hook_type post_reset_user_hook;

/* Expose a hook for other extensions to use after set_user finishes up. */
typedef void (*post_set_user_hook_type) (const char *username);
extern PGDLLIMPORT post_set_user_hook_type post_set_user_hook;
#endif

0 comments on commit e673604

Please sign in to comment.