From e49dad001718d906676c18185639403014aeacad Mon Sep 17 00:00:00 2001 From: chrisfarms Date: Mon, 20 May 2013 02:13:34 +0100 Subject: [PATCH] rough draft of adding ASYNC prilileges at the database level --- src/backend/catalog/aclchk.c | 4 ++++ src/backend/commands/async.c | 25 +++++++++++++++++++++++++ src/backend/utils/adt/acl.c | 4 ++++ src/include/nodes/parsenodes.h | 3 ++- src/include/utils/acl.h | 5 +++-- src/test/regress/expected/privileges.out | 8 ++++++++ src/test/regress/sql/privileges.sql | 9 +++++++++ 7 files changed, 55 insertions(+), 3 deletions(-) diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c index 976f2d2..5f4084f 100644 --- a/src/backend/catalog/aclchk.c +++ b/src/backend/catalog/aclchk.c @@ -3215,6 +3215,8 @@ string_to_privilege(const char *privname) return ACL_CREATE_TEMP; if (strcmp(privname, "connect") == 0) return ACL_CONNECT; + if (strcmp(privname, "async") == 0) + return ACL_ASYNC; if (strcmp(privname, "rule") == 0) return 0; /* ignore old RULE privileges */ ereport(ERROR, @@ -3252,6 +3254,8 @@ privilege_to_string(AclMode privilege) return "TEMP"; case ACL_CONNECT: return "CONNECT"; + case ACL_ASYNC: + return "ASYNC"; default: elog(ERROR, "unrecognized privilege: %d", (int) privilege); } diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index 9845cf9..0253524 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -120,6 +120,7 @@ #include "access/xact.h" #include "catalog/pg_database.h" #include "commands/async.h" +#include "commands/dbcommands.h" #include "funcapi.h" #include "libpq/libpq.h" #include "libpq/pqformat.h" @@ -133,6 +134,7 @@ #include "utils/memutils.h" #include "utils/ps_status.h" #include "utils/timestamp.h" +#include "utils/acl.h" /* @@ -536,6 +538,8 @@ Async_Notify(const char *channel, const char *payload) Notification *n; MemoryContext oldcontext; + CheckAsyncPriv(); + if (Trace_notify) elog(DEBUG1, "Async_Notify(%s)", channel); @@ -617,6 +621,21 @@ queue_listen(ListenActionKind action, const char *channel) } /* + * CheckAsyncPriv + * + * Ensures that user has prilieges to use LISTEN, NOTIFY + * Executed by Async_* methods + */ +void +CheckAsyncPriv() +{ + AclResult aclresult = pg_database_aclcheck(MyDatabaseId, GetUserId(), ACL_ASYNC); + if( aclresult != ACLCHECK_OK) + aclcheck_error(ACLCHECK_NO_PRIV, ACL_KIND_DATABASE, + get_database_name(MyDatabaseId)); +} + +/* * Async_Listen * * This is executed by the SQL listen command. @@ -627,6 +646,8 @@ Async_Listen(const char *channel) if (Trace_notify) elog(DEBUG1, "Async_Listen(%s,%d)", channel, MyProcPid); + CheckAsyncPriv(); + queue_listen(LISTEN_LISTEN, channel); } @@ -641,6 +662,8 @@ Async_Unlisten(const char *channel) if (Trace_notify) elog(DEBUG1, "Async_Unlisten(%s,%d)", channel, MyProcPid); + CheckAsyncPriv(); + /* If we couldn't possibly be listening, no need to queue anything */ if (pendingActions == NIL && !unlistenExitRegistered) return; @@ -659,6 +682,8 @@ Async_UnlistenAll(void) if (Trace_notify) elog(DEBUG1, "Async_UnlistenAll(%d)", MyProcPid); + CheckAsyncPriv(); + /* If we couldn't possibly be listening, no need to queue anything */ if (pendingActions == NIL && !unlistenExitRegistered) return; diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c index 7a0721e..355fa44 100644 --- a/src/backend/utils/adt/acl.c +++ b/src/backend/utils/adt/acl.c @@ -1625,6 +1625,8 @@ convert_priv_string(text *priv_type_text) return ACL_CREATE_TEMP; if (pg_strcasecmp(priv_type, "CONNECT") == 0) return ACL_CONNECT; + if (pg_strcasecmp(priv_type, "ASYNC") == 0) + return ACL_ASYNC; if (pg_strcasecmp(priv_type, "RULE") == 0) return 0; /* ignore old RULE privileges */ @@ -3056,6 +3058,8 @@ convert_database_priv_string(text *priv_type_text) {"TEMP WITH GRANT OPTION", ACL_GRANT_OPTION_FOR(ACL_CREATE_TEMP)}, {"CONNECT", ACL_CONNECT}, {"CONNECT WITH GRANT OPTION", ACL_GRANT_OPTION_FOR(ACL_CONNECT)}, + {"ASYNC", ACL_ASYNC}, + {"ASYNC WITH GRANT OPTION", ACL_GRANT_OPTION_FOR(ACL_ASYNC)}, {NULL, 0} }; diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 49c2a31..1b03fff 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -72,7 +72,8 @@ typedef uint32 AclMode; /* a bitmask of privilege bits */ #define ACL_CREATE (1<<9) /* for namespaces and databases */ #define ACL_CREATE_TEMP (1<<10) /* for databases */ #define ACL_CONNECT (1<<11) /* for databases */ -#define N_ACL_RIGHTS 12 /* 1 plus the last 1<