aboutsummaryrefslogtreecommitdiff
path: root/src/backend/catalog/aclchk.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/catalog/aclchk.c')
-rw-r--r--src/backend/catalog/aclchk.c116
1 files changed, 101 insertions, 15 deletions
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index add3d147e76..4b2afffb8fa 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -3706,6 +3706,20 @@ AclMode
pg_attribute_aclmask(Oid table_oid, AttrNumber attnum, Oid roleid,
AclMode mask, AclMaskHow how)
{
+ return pg_attribute_aclmask_ext(table_oid, attnum, roleid,
+ mask, how, NULL);
+}
+
+/*
+ * Exported routine for examining a user's privileges for a column
+ *
+ * Does the bulk of the work for pg_attribute_aclmask(), and allows other
+ * callers to avoid the missing attribute ERROR when is_missing is non-NULL.
+ */
+AclMode
+pg_attribute_aclmask_ext(Oid table_oid, AttrNumber attnum, Oid roleid,
+ AclMode mask, AclMaskHow how, bool *is_missing)
+{
AclMode result;
HeapTuple classTuple;
HeapTuple attTuple;
@@ -3723,18 +3737,38 @@ pg_attribute_aclmask(Oid table_oid, AttrNumber attnum, Oid roleid,
ObjectIdGetDatum(table_oid),
Int16GetDatum(attnum));
if (!HeapTupleIsValid(attTuple))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_COLUMN),
- errmsg("attribute %d of relation with OID %u does not exist",
- attnum, table_oid)));
+ {
+ if (is_missing != NULL)
+ {
+ /* return "no privileges" instead of throwing an error */
+ *is_missing = true;
+ return 0;
+ }
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_COLUMN),
+ errmsg("attribute %d of relation with OID %u does not exist",
+ attnum, table_oid)));
+ }
+
attributeForm = (Form_pg_attribute) GETSTRUCT(attTuple);
- /* Throw error on dropped columns, too */
+ /* Check dropped columns, too */
if (attributeForm->attisdropped)
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_COLUMN),
- errmsg("attribute %d of relation with OID %u does not exist",
- attnum, table_oid)));
+ {
+ if (is_missing != NULL)
+ {
+ /* return "no privileges" instead of throwing an error */
+ *is_missing = true;
+ ReleaseSysCache(attTuple);
+ return 0;
+ }
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_COLUMN),
+ errmsg("attribute %d of relation with OID %u does not exist",
+ attnum, table_oid)));
+ }
aclDatum = SysCacheGetAttr(ATTNUM, attTuple, Anum_pg_attribute_attacl,
&isNull);
@@ -3791,6 +3825,19 @@ AclMode
pg_class_aclmask(Oid table_oid, Oid roleid,
AclMode mask, AclMaskHow how)
{
+ return pg_class_aclmask_ext(table_oid, roleid, mask, how, NULL);
+}
+
+/*
+ * Exported routine for examining a user's privileges for a table
+ *
+ * Does the bulk of the work for pg_class_aclmask(), and allows other
+ * callers to avoid the missing relation ERROR when is_missing is non-NULL.
+ */
+AclMode
+pg_class_aclmask_ext(Oid table_oid, Oid roleid, AclMode mask,
+ AclMaskHow how, bool *is_missing)
+{
AclMode result;
HeapTuple tuple;
Form_pg_class classForm;
@@ -3804,10 +3851,20 @@ pg_class_aclmask(Oid table_oid, Oid roleid,
*/
tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(table_oid));
if (!HeapTupleIsValid(tuple))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_TABLE),
- errmsg("relation with OID %u does not exist",
- table_oid)));
+ {
+ if (is_missing != NULL)
+ {
+ /* return "no privileges" instead of throwing an error */
+ *is_missing = true;
+ return 0;
+ }
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_TABLE),
+ errmsg("relation with OID %u does not exist",
+ table_oid)));
+ }
+
classForm = (Form_pg_class) GETSTRUCT(tuple);
/*
@@ -4468,7 +4525,22 @@ AclResult
pg_attribute_aclcheck(Oid table_oid, AttrNumber attnum,
Oid roleid, AclMode mode)
{
- if (pg_attribute_aclmask(table_oid, attnum, roleid, mode, ACLMASK_ANY) != 0)
+ return pg_attribute_aclcheck_ext(table_oid, attnum, roleid, mode, NULL);
+}
+
+
+/*
+ * Exported routine for checking a user's access privileges to a column
+ *
+ * Does the bulk of the work for pg_attribute_aclcheck(), and allows other
+ * callers to avoid the missing attribute ERROR when is_missing is non-NULL.
+ */
+AclResult
+pg_attribute_aclcheck_ext(Oid table_oid, AttrNumber attnum,
+ Oid roleid, AclMode mode, bool *is_missing)
+{
+ if (pg_attribute_aclmask_ext(table_oid, attnum, roleid, mode,
+ ACLMASK_ANY, is_missing) != 0)
return ACLCHECK_OK;
else
return ACLCHECK_NO_PRIV;
@@ -4581,7 +4653,21 @@ pg_attribute_aclcheck_all(Oid table_oid, Oid roleid, AclMode mode,
AclResult
pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode)
{
- if (pg_class_aclmask(table_oid, roleid, mode, ACLMASK_ANY) != 0)
+ return pg_class_aclcheck_ext(table_oid, roleid, mode, NULL);
+}
+
+/*
+ * Exported routine for checking a user's access privileges to a table
+ *
+ * Does the bulk of the work for pg_class_aclcheck(), and allows other
+ * callers to avoid the missing relation ERROR when is_missing is non-NULL.
+ */
+AclResult
+pg_class_aclcheck_ext(Oid table_oid, Oid roleid,
+ AclMode mode, bool *is_missing)
+{
+ if (pg_class_aclmask_ext(table_oid, roleid, mode,
+ ACLMASK_ANY, is_missing) != 0)
return ACLCHECK_OK;
else
return ACLCHECK_NO_PRIV;