aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/acl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/acl.c')
-rw-r--r--src/backend/utils/adt/acl.c116
1 files changed, 115 insertions, 1 deletions
diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c
index 411d779be6b..7701fc5ac07 100644
--- a/src/backend/utils/adt/acl.c
+++ b/src/backend/utils/adt/acl.c
@@ -5105,7 +5105,7 @@ select_best_grantor(Oid roleId, AclMode privileges,
/*
* get_role_oid - Given a role name, look up the role's OID.
*
- * If missing_ok is false, throw an error if tablespace name not found. If
+ * If missing_ok is false, throw an error if role name not found. If
* true, just return InvalidOid.
*/
Oid
@@ -5133,3 +5133,117 @@ get_role_oid_or_public(const char *rolname)
return get_role_oid(rolname, false);
}
+
+/*
+ * Given a RoleSpec node, return the OID it corresponds to. If missing_ok is
+ * true, return InvalidOid if the role does not exist.
+ *
+ * PUBLIC is always disallowed here. Routines wanting to handle the PUBLIC
+ * case must check the case separately.
+ */
+Oid
+get_rolespec_oid(const Node *node, bool missing_ok)
+{
+ RoleSpec *role;
+ Oid oid;
+
+ if (!IsA(node, RoleSpec))
+ elog(ERROR, "invalid node type %d", node->type);
+
+ role = (RoleSpec *) node;
+ switch (role->roletype)
+ {
+ case ROLESPEC_CSTRING:
+ Assert(role->rolename);
+ oid = get_role_oid(role->rolename, missing_ok);
+ break;
+
+ case ROLESPEC_CURRENT_USER:
+ oid = GetUserId();
+ break;
+
+ case ROLESPEC_SESSION_USER:
+ oid = GetSessionUserId();
+ break;
+
+ case ROLESPEC_PUBLIC:
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("role \"%s\" does not exist", "public")));
+ oid = InvalidOid; /* make compiler happy */
+ break;
+
+ default:
+ elog(ERROR, "unexpected role type %d", role->roletype);
+ }
+
+ return oid;
+}
+
+/*
+ * Given a RoleSpec node, return the pg_authid HeapTuple it corresponds to.
+ * Caller must ReleaseSysCache when done with the result tuple.
+ */
+HeapTuple
+get_rolespec_tuple(const Node *node)
+{
+ RoleSpec *role;
+ HeapTuple tuple;
+
+ role = (RoleSpec *) node;
+ if (!IsA(node, RoleSpec))
+ elog(ERROR, "invalid node type %d", node->type);
+
+ switch (role->roletype)
+ {
+ case ROLESPEC_CSTRING:
+ Assert(role->rolename);
+ tuple = SearchSysCache1(AUTHNAME, CStringGetDatum(role->rolename));
+ if (!HeapTupleIsValid(tuple))
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("role \"%s\" does not exist", role->rolename)));
+ break;
+
+ case ROLESPEC_CURRENT_USER:
+ tuple = SearchSysCache1(AUTHOID, GetUserId());
+ if (!HeapTupleIsValid(tuple))
+ elog(ERROR, "cache lookup failed for role %u", GetUserId());
+ break;
+
+ case ROLESPEC_SESSION_USER:
+ tuple = SearchSysCache1(AUTHOID, GetSessionUserId());
+ if (!HeapTupleIsValid(tuple))
+ elog(ERROR, "cache lookup failed for role %u", GetSessionUserId());
+ break;
+
+ case ROLESPEC_PUBLIC:
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("role \"%s\" does not exist", "public")));
+ tuple = NULL; /* make compiler happy */
+
+ default:
+ elog(ERROR, "unexpected role type %d", role->roletype);
+ }
+
+ return tuple;
+}
+
+/*
+ * Given a RoleSpec, returns a palloc'ed copy of the corresponding role's name.
+ */
+char *
+get_rolespec_name(const Node *node)
+{
+ HeapTuple tp;
+ Form_pg_authid authForm;
+ char *rolename;
+
+ tp = get_rolespec_tuple(node);
+ authForm = (Form_pg_authid) GETSTRUCT(tp);
+ rolename = pstrdup(NameStr(authForm->rolname));
+ ReleaseSysCache(tp);
+
+ return rolename;
+}