On lör, 2011-12-10 at 16:16 +0100, Yeb Havinga wrote:
> 
> * Cannot restrict access to array types. After revoking usage from the 
> element type, the error is perhaps a bit misleading. (smallint[] vs 
> smallint)
> 
> postgres=> create table a (a int2[]);
> ERROR:  permission denied for type smallint[]

This matter was still outstanding.  The problem with fixing this is that
you need to duplicate the array type to element type conversion in two
dozen places.  So I have refactored this into a separate function, which
also takes care of the call to format_type_be, which is equally
duplicated in as many places.

diff --git i/src/backend/access/common/tupdesc.c w/src/backend/access/common/tupdesc.c
index 1f40b7c..aa1ce80 100644
--- i/src/backend/access/common/tupdesc.c
+++ w/src/backend/access/common/tupdesc.c
@@ -573,8 +573,7 @@
 
 		aclresult = pg_type_aclcheck(atttypid, GetUserId(), ACL_USAGE);
 		if (aclresult != ACLCHECK_OK)
-			aclcheck_error(aclresult, ACL_KIND_TYPE,
-						   format_type_be(atttypid));
+			aclcheck_error_type(aclresult, atttypid);
 
 		attcollation = GetColumnDefCollation(NULL, entry, atttypid);
 		attdim = list_length(entry->typeName->arrayBounds);
diff --git i/src/backend/catalog/aclchk.c w/src/backend/catalog/aclchk.c
index 9315e79..89b71b4 100644
--- i/src/backend/catalog/aclchk.c
+++ w/src/backend/catalog/aclchk.c
@@ -3389,6 +3389,19 @@ static AclMode pg_aclmask(AclObjectKind objkind, Oid table_oid, AttrNumber attnu
 }
 
 
+/*
+ * Special common handling for types: use element type instead of array type,
+ * and format nicely
+ */
+void
+aclcheck_error_type(AclResult aclerr, Oid typeOid)
+{
+	Oid element_type = get_element_type(typeOid);
+
+	aclcheck_error(aclerr, ACL_KIND_TYPE, format_type_be(element_type ? element_type : typeOid));
+}
+
+
 /* Check if given user has rolcatupdate privilege according to pg_authid */
 static bool
 has_rolcatupdate(Oid roleid)
diff --git i/src/backend/catalog/objectaddress.c w/src/backend/catalog/objectaddress.c
index 250069f..3c3fd05 100644
--- i/src/backend/catalog/objectaddress.c
+++ w/src/backend/catalog/objectaddress.c
@@ -932,8 +932,7 @@ static ObjectAddress get_object_address_opcf(ObjectType objtype, List *objname,
 		case OBJECT_DOMAIN:
 		case OBJECT_ATTRIBUTE:
 			if (!pg_type_ownercheck(address.objectId, roleid))
-				aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TYPE,
-							   format_type_be(address.objectId));
+				aclcheck_error_type(ACLCHECK_NOT_OWNER, address.objectId);
 			break;
 		case OBJECT_AGGREGATE:
 		case OBJECT_FUNCTION:
diff --git i/src/backend/catalog/pg_aggregate.c w/src/backend/catalog/pg_aggregate.c
index 9ff70a5..82a2c9f 100644
--- i/src/backend/catalog/pg_aggregate.c
+++ w/src/backend/catalog/pg_aggregate.c
@@ -208,19 +208,16 @@ static Oid lookup_agg_function(List *fnName, int nargs, Oid *input_types,
 	{
 		aclresult = pg_type_aclcheck(aggArgTypes[i], GetUserId(), ACL_USAGE);
 		if (aclresult != ACLCHECK_OK)
-			aclcheck_error(aclresult, ACL_KIND_TYPE,
-						   format_type_be(aggArgTypes[i]));
+			aclcheck_error_type(aclresult, aggArgTypes[i]);
 	}
 
 	aclresult = pg_type_aclcheck(aggTransType, GetUserId(), ACL_USAGE);
 	if (aclresult != ACLCHECK_OK)
-		aclcheck_error(aclresult, ACL_KIND_TYPE,
-					   format_type_be(aggTransType));
+		aclcheck_error_type(aclresult, aggTransType);
 
 	aclresult = pg_type_aclcheck(finaltype, GetUserId(), ACL_USAGE);
 	if (aclresult != ACLCHECK_OK)
-		aclcheck_error(aclresult, ACL_KIND_TYPE,
-					   format_type_be(finaltype));
+		aclcheck_error_type(aclresult, finaltype);
 
 
 	/*
diff --git i/src/backend/commands/functioncmds.c w/src/backend/commands/functioncmds.c
index 5f1c19e..2a075a1 100644
--- i/src/backend/commands/functioncmds.c
+++ w/src/backend/commands/functioncmds.c
@@ -154,8 +154,7 @@ static void AlterFunctionOwner_internal(Relation rel, HeapTuple tup,
 
 	aclresult = pg_type_aclcheck(rettype, GetUserId(), ACL_USAGE);
 	if (aclresult != ACLCHECK_OK)
-		aclcheck_error(aclresult, ACL_KIND_TYPE,
-					   format_type_be(rettype));
+		aclcheck_error_type(aclresult, rettype);
 
 	*prorettype_p = rettype;
 	*returnsSet_p = returnType->setof;
@@ -247,8 +246,7 @@ static void AlterFunctionOwner_internal(Relation rel, HeapTuple tup,
 
 		aclresult = pg_type_aclcheck(toid, GetUserId(), ACL_USAGE);
 		if (aclresult != ACLCHECK_OK)
-			aclcheck_error(aclresult, ACL_KIND_TYPE,
-						   format_type_be(toid));
+			aclcheck_error_type(aclresult, toid);
 
 		if (t->setof)
 			ereport(ERROR,
@@ -1509,13 +1507,11 @@ static void AlterFunctionOwner_internal(Relation rel, HeapTuple tup,
 
 	aclresult = pg_type_aclcheck(sourcetypeid, GetUserId(), ACL_USAGE);
 	if (aclresult != ACLCHECK_OK)
-		aclcheck_error(aclresult, ACL_KIND_TYPE,
-					   format_type_be(sourcetypeid));
+		aclcheck_error_type(aclresult, sourcetypeid);
 
 	aclresult = pg_type_aclcheck(targettypeid, GetUserId(), ACL_USAGE);
 	if (aclresult != ACLCHECK_OK)
-		aclcheck_error(aclresult, ACL_KIND_TYPE,
-					   format_type_be(targettypeid));
+		aclcheck_error_type(aclresult, targettypeid);
 
 	/* Domains are allowed for historical reasons, but we warn */
 	if (sourcetyptype == TYPTYPE_DOMAIN)
diff --git i/src/backend/commands/opclasscmds.c w/src/backend/commands/opclasscmds.c
index 87c8896..84dcf6e 100644
--- i/src/backend/commands/opclasscmds.c
+++ w/src/backend/commands/opclasscmds.c
@@ -414,8 +414,7 @@ static void AlterOpFamilyOwner_internal(Relation rel, HeapTuple tuple,
 	/* XXX this is unnecessary given the superuser check above */
 	/* Check we have ownership of the datatype */
 	if (!pg_type_ownercheck(typeoid, GetUserId()))
-		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TYPE,
-					   format_type_be(typeoid));
+		aclcheck_error_type(ACLCHECK_NOT_OWNER, typeoid);
 #endif
 
 	/*
@@ -565,8 +564,7 @@ static void AlterOpFamilyOwner_internal(Relation rel, HeapTuple tuple,
 				/* XXX this is unnecessary given the superuser check above */
 				/* Check we have ownership of the datatype */
 				if (!pg_type_ownercheck(storageoid, GetUserId()))
-					aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TYPE,
-								   format_type_be(storageoid));
+					aclcheck_error_type(ACLCHECK_NOT_OWNER, storageoid);
 #endif
 				break;
 			default:
diff --git i/src/backend/commands/operatorcmds.c w/src/backend/commands/operatorcmds.c
index afae5e4..410c708 100644
--- i/src/backend/commands/operatorcmds.c
+++ w/src/backend/commands/operatorcmds.c
@@ -181,16 +181,14 @@
 	{
 		aclresult = pg_type_aclcheck(typeId1, GetUserId(), ACL_USAGE);
 		if (aclresult != ACLCHECK_OK)
-			aclcheck_error(aclresult, ACL_KIND_TYPE,
-						   format_type_be(typeId1));
+			aclcheck_error_type(aclresult, typeId1);
 	}
 
 	if (typeName2)
 	{
 		aclresult = pg_type_aclcheck(typeId2, GetUserId(), ACL_USAGE);
 		if (aclresult != ACLCHECK_OK)
-			aclcheck_error(aclresult, ACL_KIND_TYPE,
-						   format_type_be(typeId2));
+			aclcheck_error_type(aclresult, typeId2);
 	}
 
 	/*
@@ -227,8 +225,7 @@
 	rettype = get_func_rettype(functionOid);
 	aclresult = pg_type_aclcheck(rettype, GetUserId(), ACL_USAGE);
 	if (aclresult != ACLCHECK_OK)
-		aclcheck_error(aclresult, ACL_KIND_TYPE,
-					   format_type_be(rettype));
+		aclcheck_error_type(aclresult, rettype);
 
 	/*
 	 * Look up restriction estimator if specified
diff --git i/src/backend/commands/tablecmds.c w/src/backend/commands/tablecmds.c
index 6148bd6..a597c22 100644
--- i/src/backend/commands/tablecmds.c
+++ w/src/backend/commands/tablecmds.c
@@ -526,8 +526,7 @@ static void RangeVarCallbackForAlterRelation(const RangeVar *rv, Oid relid,
 
 		aclresult = pg_type_aclcheck(ofTypeId, GetUserId(), ACL_USAGE);
 		if (aclresult != ACLCHECK_OK)
-			aclcheck_error(aclresult, ACL_KIND_TYPE,
-						   format_type_be(ofTypeId));
+			aclcheck_error_type(aclresult, ofTypeId);
 	}
 	else
 		ofTypeId = InvalidOid;
@@ -4496,8 +4495,7 @@ static void RangeVarCallbackForAlterRelation(const RangeVar *rv, Oid relid,
 
 	aclresult = pg_type_aclcheck(typeOid, GetUserId(), ACL_USAGE);
 	if (aclresult != ACLCHECK_OK)
-		aclcheck_error(aclresult, ACL_KIND_TYPE,
-					   format_type_be(typeOid));
+		aclcheck_error_type(aclresult, typeOid);
 
 	collOid = GetColumnDefCollation(NULL, colDef, typeOid);
 
@@ -7243,8 +7241,7 @@ static void RangeVarCallbackForAlterRelation(const RangeVar *rv, Oid relid,
 
 	aclresult = pg_type_aclcheck(targettype, GetUserId(), ACL_USAGE);
 	if (aclresult != ACLCHECK_OK)
-		aclcheck_error(aclresult, ACL_KIND_TYPE,
-					   format_type_be(targettype));
+		aclcheck_error_type(aclresult, targettype);
 
 	/* And the collation */
 	targetcollid = GetColumnDefCollation(NULL, def, targettype);
diff --git i/src/backend/commands/typecmds.c w/src/backend/commands/typecmds.c
index 140b3f8..91ac742 100644
--- i/src/backend/commands/typecmds.c
+++ w/src/backend/commands/typecmds.c
@@ -757,8 +757,7 @@ static char *domainAddConstraint(Oid domainOid, Oid domainNamespace,
 
 	aclresult = pg_type_aclcheck(basetypeoid, GetUserId(), ACL_USAGE);
 	if (aclresult != ACLCHECK_OK)
-		aclcheck_error(aclresult, ACL_KIND_TYPE,
-					   format_type_be(basetypeoid));
+		aclcheck_error_type(aclresult, basetypeoid);
 
 	/*
 	 * Identify the collation if any
@@ -1207,8 +1206,7 @@ static char *domainAddConstraint(Oid domainOid, Oid domainNamespace,
 
 	/* Permission check: must own type */
 	if (!pg_type_ownercheck(HeapTupleGetOid(tup), GetUserId()))
-		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TYPE,
-					   format_type_be(HeapTupleGetOid(tup)));
+		aclcheck_error_type(ACLCHECK_NOT_OWNER, HeapTupleGetOid(tup));
 }
 
 
@@ -2807,8 +2805,7 @@ static char *domainAddConstraint(Oid domainOid, Oid domainNamespace,
 
 	/* Permission check: must own type */
 	if (!pg_type_ownercheck(HeapTupleGetOid(tup), GetUserId()))
-		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TYPE,
-					   format_type_be(HeapTupleGetOid(tup)));
+		aclcheck_error_type(ACLCHECK_NOT_OWNER, HeapTupleGetOid(tup));
 }
 
 /*
@@ -3114,8 +3111,7 @@ static char *domainAddConstraint(Oid domainOid, Oid domainNamespace,
 
 	/* check permissions on type */
 	if (!pg_type_ownercheck(typeOid, GetUserId()))
-		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TYPE,
-					   format_type_be(typeOid));
+		aclcheck_error_type(ACLCHECK_NOT_OWNER, typeOid);
 
 	/* ALTER DOMAIN used on a non-domain? */
 	if (stmt->renameType == OBJECT_DOMAIN && typTup->typtype != TYPTYPE_DOMAIN)
@@ -3236,8 +3232,7 @@ static char *domainAddConstraint(Oid domainOid, Oid domainNamespace,
 		{
 			/* Otherwise, must be owner of the existing object */
 			if (!pg_type_ownercheck(HeapTupleGetOid(tup), GetUserId()))
-				aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TYPE,
-							   format_type_be(HeapTupleGetOid(tup)));
+				aclcheck_error_type(ACLCHECK_NOT_OWNER, HeapTupleGetOid(tup));
 
 			/* Must be able to become new owner */
 			check_is_member_of_role(GetUserId(), newOwnerId);
@@ -3365,8 +3360,7 @@ static char *domainAddConstraint(Oid domainOid, Oid domainNamespace,
 
 	/* check permissions on type */
 	if (!pg_type_ownercheck(typeOid, GetUserId()))
-		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TYPE,
-					   format_type_be(typeOid));
+		aclcheck_error_type(ACLCHECK_NOT_OWNER, typeOid);
 
 	/* don't allow direct alteration of array types */
 	elemOid = get_element_type(typeOid);
diff --git i/src/include/utils/acl.h w/src/include/utils/acl.h
index ff3c6aa..8e3316f 100644
--- i/src/include/utils/acl.h
+++ w/src/include/utils/acl.h
@@ -302,6 +302,8 @@ extern void aclcheck_error(AclResult aclerr, AclObjectKind objectkind,
 extern void aclcheck_error_col(AclResult aclerr, AclObjectKind objectkind,
 				   const char *objectname, const char *colname);
 
+extern void aclcheck_error_type(AclResult aclerr, Oid typeOid);
+
 /* ownercheck routines just return true (owner) or false (not) */
 extern bool pg_class_ownercheck(Oid class_oid, Oid roleid);
 extern bool pg_type_ownercheck(Oid type_oid, Oid roleid);
diff --git i/src/test/regress/expected/privileges.out w/src/test/regress/expected/privileges.out
index dfaf3a7..f99ebde 100644
--- i/src/test/regress/expected/privileges.out
+++ w/src/test/regress/expected/privileges.out
@@ -547,7 +547,7 @@ ERROR:  permission denied for type testdomain1
 CREATE TABLE test6a OF testtype1;
 ERROR:  permission denied for type testtype1
 CREATE TABLE test10a (a int[], b testtype1[]);
-ERROR:  permission denied for type testtype1[]
+ERROR:  permission denied for type testtype1
 CREATE TABLE test9a (a int, b int);
 ALTER TABLE test9a ADD COLUMN c testdomain1;
 ERROR:  permission denied for type testdomain1
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to