? src/backend/commands/.typecmds.c.swp Index: src/backend/commands/aggregatecmds.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/commands/aggregatecmds.c,v retrieving revision 1.27 diff -c -r1.27 aggregatecmds.c *** src/backend/commands/aggregatecmds.c 28 Jun 2005 05:08:53 -0000 1.27 --- src/backend/commands/aggregatecmds.c 29 Jun 2005 15:29:57 -0000 *************** *** 299,307 **** --- 299,309 ---- { Oid basetypeOid; Oid procOid; + Oid namespaceOid; HeapTuple tup; Form_pg_proc procForm; Relation rel; + AclResult aclresult; /* * if a basetype is passed in, then attempt to find an aggregate for *************** *** 325,341 **** elog(ERROR, "cache lookup failed for function %u", procOid); procForm = (Form_pg_proc) GETSTRUCT(tup); /* * If the new owner is the same as the existing owner, consider the * command to have succeeded. This is for dump restoration purposes. */ if (procForm->proowner != newOwnerId) { ! /* Otherwise, must be superuser to change object ownership */ ! if (!superuser()) ! ereport(ERROR, ! (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), ! errmsg("must be superuser to change owner"))); /* * Modify the owner --- okay to scribble on tup because it's a --- 327,356 ---- elog(ERROR, "cache lookup failed for function %u", procOid); procForm = (Form_pg_proc) GETSTRUCT(tup); + namespaceOid = procForm->pronamespace; + /* * If the new owner is the same as the existing owner, consider the * command to have succeeded. This is for dump restoration purposes. */ if (procForm->proowner != newOwnerId) { ! /* Otherwise, must be owner of the existing object */ ! if (!pg_proc_ownercheck(procOid,GetUserId())) ! aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC, ! NameListToString(name)); ! ! /* Must be able to become new owner */ ! if (!is_member_of_role(GetUserId(),newOwnerId)) ! aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC, ! NameListToString(name)); ! ! /* new owner must have CREATE privilege on namespace */ ! aclresult = pg_namespace_aclcheck(namespaceOid, newOwnerId, ACL_CREATE); ! if (aclresult != ACLCHECK_OK) ! aclcheck_error(aclresult, ACL_KIND_NAMESPACE, ! get_namespace_name(namespaceOid)); ! /* * Modify the owner --- okay to scribble on tup because it's a Index: src/backend/commands/conversioncmds.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/commands/conversioncmds.c,v retrieving revision 1.19 diff -c -r1.19 conversioncmds.c *** src/backend/commands/conversioncmds.c 28 Jun 2005 05:08:53 -0000 1.19 --- src/backend/commands/conversioncmds.c 29 Jun 2005 15:29:57 -0000 *************** *** 151,158 **** newname, get_namespace_name(namespaceOid)))); /* must be owner */ ! if (!superuser() && ! ((Form_pg_conversion) GETSTRUCT(tup))->conowner != GetUserId()) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CONVERSION, NameListToString(name)); --- 151,157 ---- newname, get_namespace_name(namespaceOid)))); /* must be owner */ ! if (!pg_conversion_ownercheck(conversionOid,GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CONVERSION, NameListToString(name)); *************** *** 178,185 **** --- 177,186 ---- AlterConversionOwner(List *name, Oid newOwnerId) { Oid conversionOid; + Oid namespaceOid; HeapTuple tup; Relation rel; + AclResult aclresult; Form_pg_conversion convForm; rel = heap_open(ConversionRelationId, RowExclusiveLock); *************** *** 198,203 **** --- 199,205 ---- elog(ERROR, "cache lookup failed for conversion %u", conversionOid); convForm = (Form_pg_conversion) GETSTRUCT(tup); + namespaceOid = convForm->connamespace; /* * If the new owner is the same as the existing owner, consider the *************** *** 205,215 **** */ if (convForm->conowner != newOwnerId) { ! /* Otherwise, must be superuser to change object ownership */ ! if (!superuser()) ! ereport(ERROR, ! (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), ! errmsg("must be superuser to change owner"))); /* * Modify the owner --- okay to scribble on tup because it's a --- 207,227 ---- */ if (convForm->conowner != newOwnerId) { ! /* must be owner to change object ownership */ ! if (!pg_conversion_ownercheck(HeapTupleGetOid(tup),GetUserId())) ! aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CONVERSION, ! NameListToString(name)); ! ! /* Must be able to become new owner */ ! if (!is_member_of_role(GetUserId(),newOwnerId)) ! aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CONVERSION, ! NameListToString(name)); ! ! /* new owner must have CREATE privilege on namespace */ ! aclresult = pg_namespace_aclcheck(namespaceOid, newOwnerId, ACL_CREATE); ! if (aclresult != ACLCHECK_OK) ! aclcheck_error(aclresult, ACL_KIND_NAMESPACE, ! get_namespace_name(namespaceOid)); /* * Modify the owner --- okay to scribble on tup because it's a Index: src/backend/commands/dbcommands.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/commands/dbcommands.c,v retrieving revision 1.162 diff -c -r1.162 dbcommands.c *** src/backend/commands/dbcommands.c 28 Jun 2005 05:08:53 -0000 1.162 --- src/backend/commands/dbcommands.c 29 Jun 2005 15:29:57 -0000 *************** *** 192,214 **** else datdba = GetUserId(); ! if (is_member_of_role(GetUserId(), datdba)) ! { ! /* creating database for self: can be superuser or createdb */ ! if (!superuser() && !have_createdb_privilege()) ! ereport(ERROR, ! (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), ! errmsg("permission denied to create database"))); ! } ! else ! { ! /* creating database for someone else: must be superuser */ ! /* note that the someone else need not have any permissions */ ! if (!superuser()) ! ereport(ERROR, ! (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), ! errmsg("must be superuser to create database for another user"))); ! } /* * Check for db name conflict. There is a race condition here, since --- 192,209 ---- else datdba = GetUserId(); ! /* creating database, must have createdb ! * must be creating database for role user can become ! * ! * NOTE: This does not require the role for which the database ! * is being created to have createdb privileges. For 'container' ! * type objects where specifying a different owner during ! * creation is allowed this seems reasonable. ! */ ! if (!have_createdb_privilege() || !is_member_of_role(GetUserId(), datdba)) ! ereport(ERROR, ! (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), ! errmsg("permission denied to create database"))); /* * Check for db name conflict. There is a race condition here, since *************** *** 759,765 **** oldname); /* must have createdb rights */ ! if (!superuser() && !have_createdb_privilege()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("permission denied to rename database"))); --- 754,760 ---- oldname); /* must have createdb rights */ ! if (!have_createdb_privilege()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("permission denied to rename database"))); *************** *** 918,928 **** bool isNull; HeapTuple newtuple; ! /* must be superuser to change ownership */ ! if (!superuser()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), ! errmsg("must be superuser to change owner"))); memset(repl_null, ' ', sizeof(repl_null)); memset(repl_repl, ' ', sizeof(repl_repl)); --- 913,941 ---- bool isNull; HeapTuple newtuple; ! /* must be owner of the database */ ! if (!pg_database_ownercheck(HeapTupleGetOid(tuple),GetUserId())) ! aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_DATABASE, ! dbname); ! ! /* Must be able to become new owner */ ! if (!is_member_of_role(GetUserId(),newOwnerId)) ! aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_DATABASE, ! dbname); ! ! /* must have createdb rights ! * ! * NOTE: This is different from other alter-owner checks in ! * that the current user is checked for createdb privileges ! * instead of the destination owner. This is because this ! * is a 'container' type object and the owner can be ! * specified during creation. ! * This matches the current createdb checks. ! */ ! if (!have_createdb_privilege()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), ! errmsg("permission denied to change owner of database"))); memset(repl_null, ' ', sizeof(repl_null)); memset(repl_repl, ' ', sizeof(repl_repl)); *************** *** 1044,1049 **** --- 1057,1066 ---- bool result = false; HeapTuple utup; + /* superuser bybasses privilege checks */ + if (superuser()) + return true; + utup = SearchSysCache(AUTHOID, ObjectIdGetDatum(GetUserId()), 0, 0, 0); Index: src/backend/commands/functioncmds.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/commands/functioncmds.c,v retrieving revision 1.62 diff -c -r1.62 functioncmds.c *** src/backend/commands/functioncmds.c 28 Jun 2005 05:08:53 -0000 1.62 --- src/backend/commands/functioncmds.c 29 Jun 2005 15:29:58 -0000 *************** *** 856,864 **** --- 856,866 ---- AlterFunctionOwner(List *name, List *argtypes, Oid newOwnerId) { Oid procOid; + Oid namespaceOid; HeapTuple tup; Form_pg_proc procForm; Relation rel; + AclResult aclresult; rel = heap_open(ProcedureRelationId, RowExclusiveLock); *************** *** 878,883 **** --- 880,887 ---- NameListToString(name)), errhint("Use ALTER AGGREGATE to change owner of aggregate functions."))); + namespaceOid = procForm->pronamespace; + /* * If the new owner is the same as the existing owner, consider the * command to have succeeded. This is for dump restoration purposes. *************** *** 892,902 **** bool isNull; HeapTuple newtuple; ! /* Otherwise, must be superuser to change object ownership */ ! if (!superuser()) ! ereport(ERROR, ! (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), ! errmsg("must be superuser to change owner"))); memset(repl_null, ' ', sizeof(repl_null)); memset(repl_repl, ' ', sizeof(repl_repl)); --- 896,916 ---- bool isNull; HeapTuple newtuple; ! /* Otherwise, must be owner of the existing object */ ! if (!pg_proc_ownercheck(procOid,GetUserId())) ! aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC, ! NameListToString(name)); ! ! /* Must be able to become new owner */ ! if (!is_member_of_role(GetUserId(),newOwnerId)) ! aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC, ! NameListToString(name)); ! ! /* new role must have CREATE privilege on namespace */ ! aclresult = pg_namespace_aclcheck(namespaceOid, newOwnerId, ACL_CREATE); ! if (aclresult != ACLCHECK_OK) ! aclcheck_error(aclresult, ACL_KIND_NAMESPACE, ! get_namespace_name(namespaceOid)); memset(repl_null, ' ', sizeof(repl_null)); memset(repl_repl, ' ', sizeof(repl_repl)); Index: src/backend/commands/opclasscmds.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/commands/opclasscmds.c,v retrieving revision 1.33 diff -c -r1.33 opclasscmds.c *** src/backend/commands/opclasscmds.c 28 Jun 2005 05:08:53 -0000 1.33 --- src/backend/commands/opclasscmds.c 29 Jun 2005 15:29:58 -0000 *************** *** 889,894 **** --- 889,895 ---- char *opcname; HeapTuple tup; Relation rel; + AclResult aclresult; Form_pg_opclass opcForm; amOid = GetSysCacheOid(AMNAME, *************** *** 947,957 **** */ if (opcForm->opcowner != newOwnerId) { ! /* Otherwise, must be superuser to change object ownership */ ! if (!superuser()) ! ereport(ERROR, ! (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), ! errmsg("must be superuser to change owner"))); /* * Modify the owner --- okay to scribble on tup because it's a --- 948,968 ---- */ if (opcForm->opcowner != newOwnerId) { ! /* 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))); ! ! /* Must be able to become the new owner */ ! if (!is_member_of_role(GetUserId(),newOwnerId)) ! aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TYPE, ! NameListToString(name)); ! ! /* new role must have CREATE privilege on namespace */ ! aclresult = pg_namespace_aclcheck(namespaceOid, newOwnerId, ACL_CREATE); ! if (aclresult != ACLCHECK_OK) ! aclcheck_error(aclresult, ACL_KIND_NAMESPACE, ! get_namespace_name(namespaceOid)); /* * Modify the owner --- okay to scribble on tup because it's a Index: src/backend/commands/operatorcmds.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/commands/operatorcmds.c,v retrieving revision 1.22 diff -c -r1.22 operatorcmds.c *** src/backend/commands/operatorcmds.c 28 Jun 2005 05:08:54 -0000 1.22 --- src/backend/commands/operatorcmds.c 29 Jun 2005 15:29:58 -0000 *************** *** 274,279 **** --- 274,280 ---- Oid operOid; HeapTuple tup; Relation rel; + AclResult aclresult; Form_pg_operator oprForm; rel = heap_open(OperatorRelationId, RowExclusiveLock); *************** *** 295,305 **** */ if (oprForm->oprowner != newOwnerId) { ! /* Otherwise, must be superuser to change object ownership */ ! if (!superuser()) ! ereport(ERROR, ! (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), ! errmsg("must be superuser to change owner"))); /* * Modify the owner --- okay to scribble on tup because it's a --- 296,316 ---- */ if (oprForm->oprowner != newOwnerId) { ! /* Otherwise, must be owner of the existing object */ ! if(!pg_oper_ownercheck(operOid,GetUserId())) ! aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPER, ! NameListToString(name)); ! ! /* Must be able to become new owner */ ! if (!is_member_of_role(GetUserId(),newOwnerId)) ! aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPER, ! NameListToString(name)); ! ! /* new role must have CREATE privilege on namespace */ ! aclresult = pg_namespace_aclcheck(oprForm->oprnamespace, newOwnerId, ACL_CREATE); ! if (aclresult != ACLCHECK_OK) ! aclcheck_error(aclresult, ACL_KIND_NAMESPACE, ! get_namespace_name(oprForm->oprnamespace)); /* * Modify the owner --- okay to scribble on tup because it's a Index: src/backend/commands/schemacmds.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/commands/schemacmds.c,v retrieving revision 1.31 diff -c -r1.31 schemacmds.c *** src/backend/commands/schemacmds.c 28 Jun 2005 05:08:54 -0000 1.31 --- src/backend/commands/schemacmds.c 29 Jun 2005 15:29:58 -0000 *************** *** 52,96 **** * Figure out user identities. */ ! if (!authId) ! { ! owner_uid = saved_uid; ! } ! else if (superuser()) ! { owner_uid = get_roleid_checked(authId); - - /* - * Set the current user to the requested authorization so that - * objects created in the statement have the requested owner. - * (This will revert to session user on error or at the end of - * this routine.) - */ - SetUserId(owner_uid); - } else - { - const char *owner_name; - - /* not superuser */ owner_uid = saved_uid; - owner_name = GetUserNameFromId(owner_uid); - if (strcmp(authId, owner_name) != 0) - ereport(ERROR, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("permission denied"), - errdetail("\"%s\" is not a superuser, so cannot create a schema for \"%s\"", - owner_name, authId))); - } /* * Permissions checks. */ aclresult = pg_database_aclcheck(MyDatabaseId, saved_uid, ACL_CREATE); if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, ACL_KIND_DATABASE, get_database_name(MyDatabaseId)); if (!allowSystemTableMods && IsReservedName(schemaName)) ereport(ERROR, (errcode(ERRCODE_RESERVED_NAME), --- 52,95 ---- * Figure out user identities. */ ! if (authId) owner_uid = get_roleid_checked(authId); else owner_uid = saved_uid; /* * Permissions checks. */ + + /* must be creating schema for role which user is a member of */ + if (!is_member_of_role(saved_uid, owner_uid)) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("permission denied to create schema"))); + + /* creating schema, must have create privs on db + * + * NOTE: This does not require the role for which the schema + * is being created to have create privileges. For 'container' + * type objects where specifying a different owner during + * creation is allowed this seems reasonable. + */ aclresult = pg_database_aclcheck(MyDatabaseId, saved_uid, ACL_CREATE); if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, ACL_KIND_DATABASE, get_database_name(MyDatabaseId)); + /* + * If the requested authorization is different from the current + * user then set the current user to the requested authorization + * so that objects created in the statement have the requested + * owner. + * (This will revert to session user on error or at the end of + * this routine.) + */ + if (saved_uid != owner_uid) + SetUserId(owner_uid); + if (!allowSystemTableMods && IsReservedName(schemaName)) ereport(ERROR, (errcode(ERRCODE_RESERVED_NAME), *************** *** 308,319 **** Datum aclDatum; bool isNull; HeapTuple newtuple; ! /* Otherwise, must be superuser to change object ownership */ ! if (!superuser()) ! ereport(ERROR, ! (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), ! errmsg("must be superuser to change owner"))); memset(repl_null, ' ', sizeof(repl_null)); memset(repl_repl, ' ', sizeof(repl_repl)); --- 307,337 ---- Datum aclDatum; bool isNull; HeapTuple newtuple; + AclResult aclresult; ! /* Otherwise, must be owner of the existing object */ ! if (!pg_proc_ownercheck(HeapTupleGetOid(tup),GetUserId())) ! aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_NAMESPACE, ! name); ! ! /* Must be able to become new owner */ ! if (!is_member_of_role(GetUserId(),newOwnerId)) ! aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_NAMESPACE, ! name); ! ! /* must have create rights ! * ! * NOTE: This is different from other alter-owner checks in ! * that the current user is checked for create privileges ! * instead of the destination owner. This is because this ! * is a 'container' type object and the owner can be ! * specified during creation. ! * This matches the create schema checks. ! */ ! aclresult = pg_database_aclcheck(MyDatabaseId, GetUserId(), ACL_CREATE); ! if (aclresult != ACLCHECK_OK) ! aclcheck_error(aclresult, ACL_KIND_DATABASE, ! get_database_name(MyDatabaseId)); memset(repl_null, ' ', sizeof(repl_null)); memset(repl_repl, ' ', sizeof(repl_repl)); Index: src/backend/commands/tablecmds.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/commands/tablecmds.c,v retrieving revision 1.162 diff -c -r1.162 tablecmds.c *** src/backend/commands/tablecmds.c 28 Jun 2005 05:08:54 -0000 1.162 --- src/backend/commands/tablecmds.c 29 Jun 2005 15:29:58 -0000 *************** *** 5286,5297 **** Datum aclDatum; bool isNull; HeapTuple newtuple; ! /* Otherwise, check that we are the superuser */ ! if (!superuser()) ! ereport(ERROR, ! (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), ! errmsg("must be superuser to change owner"))); memset(repl_null, ' ', sizeof(repl_null)); memset(repl_repl, ' ', sizeof(repl_repl)); --- 5286,5309 ---- Datum aclDatum; bool isNull; HeapTuple newtuple; + Oid namespaceOid = get_rel_namespace(relationOid); + AclResult aclresult; ! /* Otherwise, must be owner of the existing object */ ! if (!pg_class_ownercheck(relationOid,GetUserId())) ! aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, ! RelationGetRelationName(target_rel)); ! ! /* Must be able to become new owner */ ! if (!is_member_of_role(GetUserId(),newOwnerId)) ! aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, ! RelationGetRelationName(target_rel)); ! ! /* new role must have CREATE privilege on namespace */ ! aclresult = pg_namespace_aclcheck(namespaceOid, newOwnerId, ACL_CREATE); ! if (aclresult != ACLCHECK_OK) ! aclcheck_error(aclresult, ACL_KIND_NAMESPACE, ! get_namespace_name(namespaceOid)); memset(repl_null, ' ', sizeof(repl_null)); memset(repl_repl, ' ', sizeof(repl_repl)); Index: src/backend/commands/tablespace.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/commands/tablespace.c,v retrieving revision 1.23 diff -c -r1.23 tablespace.c *** src/backend/commands/tablespace.c 28 Jun 2005 05:08:54 -0000 1.23 --- src/backend/commands/tablespace.c 29 Jun 2005 15:29:58 -0000 *************** *** 784,794 **** bool isNull; HeapTuple newtuple; ! /* Otherwise, must be superuser to change object ownership */ ! if (!superuser()) ! ereport(ERROR, ! (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), ! errmsg("must be superuser to change owner"))); memset(repl_null, ' ', sizeof(repl_null)); memset(repl_repl, ' ', sizeof(repl_repl)); --- 784,806 ---- bool isNull; HeapTuple newtuple; ! /* Must be owner */ ! if (!pg_tablespace_ownercheck(HeapTupleGetOid(tup), GetUserId())) ! aclcheck_error(ACLCHECK_NO_PRIV, ACL_KIND_TABLESPACE, name); ! ! /* Must be able to become new owner */ ! if (!is_member_of_role(GetUserId(),newOwnerId)) ! aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TABLESPACE, name); ! ! /* ! * Normally we would also check for create permissions here, ! * but there are none for tablespaces so we follow the what rename ! * tablespace does and omit the create permissions check. ! * ! * NOTE: Only superusers may create tablespaces to begin with and ! * so initially only a superuser would be able to change its ! * ownership anyway. ! */ memset(repl_null, ' ', sizeof(repl_null)); memset(repl_repl, ' ', sizeof(repl_repl)); Index: src/backend/commands/typecmds.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/commands/typecmds.c,v retrieving revision 1.73 diff -c -r1.73 typecmds.c *** src/backend/commands/typecmds.c 28 Jun 2005 05:08:54 -0000 1.73 --- src/backend/commands/typecmds.c 29 Jun 2005 15:29:58 -0000 *************** *** 2023,2028 **** --- 2023,2030 ---- Relation rel; HeapTuple tup; Form_pg_type typTup; + Oid typeNamespace; + AclResult aclresult; /* Make a TypeName so we can use standard type lookup machinery */ typename = makeNode(TypeName); *************** *** 2065,2075 **** */ if (typTup->typowner != newOwnerId) { ! /* Otherwise, must be superuser to change object ownership */ ! if (!superuser()) ! ereport(ERROR, ! (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), ! errmsg("must be superuser to change owner"))); /* * Modify the owner --- okay to scribble on typTup because it's a --- 2067,2089 ---- */ if (typTup->typowner != newOwnerId) { ! char *name = TypeNameToString(typename); ! ! /* Otherwise, must be owner of the existing object */ ! if (!pg_type_ownercheck(HeapTupleGetOid(tup),GetUserId())) ! aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TYPE, name); ! ! /* Must be able to become new owner */ ! if (!is_member_of_role(GetUserId(),newOwnerId)) ! aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TYPE, name); ! ! typeNamespace = QualifiedNameGetCreationNamespace(names, &name); ! ! /* new role must have CREATE privilege on namespace */ ! aclresult = pg_namespace_aclcheck(typeNamespace, newOwnerId, ACL_CREATE); ! if (aclresult != ACLCHECK_OK) ! aclcheck_error(aclresult, ACL_KIND_NAMESPACE, ! get_namespace_name(typeNamespace)); /* * Modify the owner --- okay to scribble on typTup because it's a Index: src/backend/utils/adt/acl.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/utils/adt/acl.c,v retrieving revision 1.116 diff -c -r1.116 acl.c *** src/backend/utils/adt/acl.c 28 Jun 2005 19:51:23 -0000 1.116 --- src/backend/utils/adt/acl.c 29 Jun 2005 15:29:58 -0000 *************** *** 1031,1036 **** --- 1031,1040 ---- bool is_member_of_role(Oid member, Oid role) { + /* superuser considered part of every role */ + if (superuser_arg(member)) + return true; + /* Fast path for simple case */ if (member == role) return true;