Commit bf1e33d2 authored by Tom Lane's avatar Tom Lane

Fix unwanted denial of ALTER OWNER rights to superusers. There was some

discussion of getting around this by relaxing the checks made for regular
users, but I'm disinclined to toy with the security model right now,
so just special-case it for superusers where needed.
parent a7f49252
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/aggregatecmds.c,v 1.28 2005/07/14 21:46:29 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/aggregatecmds.c,v 1.29 2005/08/22 17:38:20 tgl Exp $
* *
* DESCRIPTION * DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the * The "DefineFoo" routines take the parse tree and pick out the
...@@ -332,20 +332,25 @@ AlterAggregateOwner(List *name, TypeName *basetype, Oid newOwnerId) ...@@ -332,20 +332,25 @@ AlterAggregateOwner(List *name, TypeName *basetype, Oid newOwnerId)
*/ */
if (procForm->proowner != newOwnerId) if (procForm->proowner != newOwnerId)
{ {
/* Otherwise, must be owner of the existing object */ /* Superusers can always do it */
if (!pg_proc_ownercheck(procOid, GetUserId())) if (!superuser())
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC, {
NameListToString(name)); /* Otherwise, must be owner of the existing object */
if (!pg_proc_ownercheck(procOid, GetUserId()))
/* Must be able to become new owner */ aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC,
check_is_member_of_role(GetUserId(), newOwnerId); NameListToString(name));
/* New owner must have CREATE privilege on namespace */ /* Must be able to become new owner */
aclresult = pg_namespace_aclcheck(procForm->pronamespace, newOwnerId, check_is_member_of_role(GetUserId(), newOwnerId);
ACL_CREATE);
if (aclresult != ACLCHECK_OK) /* New owner must have CREATE privilege on namespace */
aclcheck_error(aclresult, ACL_KIND_NAMESPACE, aclresult = pg_namespace_aclcheck(procForm->pronamespace,
get_namespace_name(procForm->pronamespace)); newOwnerId,
ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
get_namespace_name(procForm->pronamespace));
}
/* /*
* Modify the owner --- okay to scribble on tup because it's a * Modify the owner --- okay to scribble on tup because it's a
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/conversioncmds.c,v 1.21 2005/07/14 21:46:29 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/conversioncmds.c,v 1.22 2005/08/22 17:38:20 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -206,20 +206,25 @@ AlterConversionOwner(List *name, Oid newOwnerId) ...@@ -206,20 +206,25 @@ AlterConversionOwner(List *name, Oid newOwnerId)
*/ */
if (convForm->conowner != newOwnerId) if (convForm->conowner != newOwnerId)
{ {
/* Otherwise, must be owner of the existing object */ /* Superusers can always do it */
if (!pg_conversion_ownercheck(HeapTupleGetOid(tup),GetUserId())) if (!superuser())
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CONVERSION, {
NameListToString(name)); /* Otherwise, must be owner of the existing object */
if (!pg_conversion_ownercheck(HeapTupleGetOid(tup),GetUserId()))
/* Must be able to become new owner */ aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CONVERSION,
check_is_member_of_role(GetUserId(), newOwnerId); NameListToString(name));
/* New owner must have CREATE privilege on namespace */ /* Must be able to become new owner */
aclresult = pg_namespace_aclcheck(convForm->connamespace, newOwnerId, check_is_member_of_role(GetUserId(), newOwnerId);
ACL_CREATE);
if (aclresult != ACLCHECK_OK) /* New owner must have CREATE privilege on namespace */
aclcheck_error(aclresult, ACL_KIND_NAMESPACE, aclresult = pg_namespace_aclcheck(convForm->connamespace,
get_namespace_name(convForm->connamespace)); newOwnerId,
ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
get_namespace_name(convForm->connamespace));
}
/* /*
* Modify the owner --- okay to scribble on tup because it's a * Modify the owner --- okay to scribble on tup because it's a
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.170 2005/08/12 01:35:57 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.171 2005/08/22 17:38:20 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1024,7 +1024,8 @@ AlterDatabaseOwner(const char *dbname, Oid newOwnerId) ...@@ -1024,7 +1024,8 @@ AlterDatabaseOwner(const char *dbname, Oid newOwnerId)
* NOTE: This is different from other alter-owner checks in * NOTE: This is different from other alter-owner checks in
* that the current user is checked for createdb privileges * that the current user is checked for createdb privileges
* instead of the destination owner. This is consistent * instead of the destination owner. This is consistent
* with the CREATE case for databases. * with the CREATE case for databases. Because superusers
* will always have this right, we need no special case for them.
*/ */
if (!have_createdb_privilege()) if (!have_createdb_privilege())
ereport(ERROR, ereport(ERROR,
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.65 2005/08/01 04:03:55 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.66 2005/08/22 17:38:20 tgl Exp $
* *
* DESCRIPTION * DESCRIPTION
* These routines take the parse tree and pick out the * These routines take the parse tree and pick out the
...@@ -894,20 +894,25 @@ AlterFunctionOwner(List *name, List *argtypes, Oid newOwnerId) ...@@ -894,20 +894,25 @@ AlterFunctionOwner(List *name, List *argtypes, Oid newOwnerId)
bool isNull; bool isNull;
HeapTuple newtuple; HeapTuple newtuple;
/* Otherwise, must be owner of the existing object */ /* Superusers can always do it */
if (!pg_proc_ownercheck(procOid,GetUserId())) if (!superuser())
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC, {
NameListToString(name)); /* Otherwise, must be owner of the existing object */
if (!pg_proc_ownercheck(procOid,GetUserId()))
/* Must be able to become new owner */ aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC,
check_is_member_of_role(GetUserId(), newOwnerId); NameListToString(name));
/* New owner must have CREATE privilege on namespace */ /* Must be able to become new owner */
aclresult = pg_namespace_aclcheck(procForm->pronamespace, newOwnerId, check_is_member_of_role(GetUserId(), newOwnerId);
ACL_CREATE);
if (aclresult != ACLCHECK_OK) /* New owner must have CREATE privilege on namespace */
aclcheck_error(aclresult, ACL_KIND_NAMESPACE, aclresult = pg_namespace_aclcheck(procForm->pronamespace,
get_namespace_name(procForm->pronamespace)); newOwnerId,
ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
get_namespace_name(procForm->pronamespace));
}
memset(repl_null, ' ', sizeof(repl_null)); memset(repl_null, ' ', sizeof(repl_null));
memset(repl_repl, ' ', sizeof(repl_repl)); memset(repl_repl, ' ', sizeof(repl_repl));
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/opclasscmds.c,v 1.35 2005/07/14 21:46:29 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/opclasscmds.c,v 1.36 2005/08/22 17:38:20 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -951,20 +951,24 @@ AlterOpClassOwner(List *name, const char *access_method, Oid newOwnerId) ...@@ -951,20 +951,24 @@ AlterOpClassOwner(List *name, const char *access_method, Oid newOwnerId)
*/ */
if (opcForm->opcowner != newOwnerId) if (opcForm->opcowner != newOwnerId)
{ {
/* Otherwise, must be owner of the existing object */ /* Superusers can always do it */
if (!pg_opclass_ownercheck(HeapTupleGetOid(tup),GetUserId())) if (!superuser())
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPCLASS, {
NameListToString(name)); /* Otherwise, must be owner of the existing object */
if (!pg_opclass_ownercheck(HeapTupleGetOid(tup),GetUserId()))
/* Must be able to become new owner */ aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPCLASS,
check_is_member_of_role(GetUserId(), newOwnerId); NameListToString(name));
/* New owner must have CREATE privilege on namespace */ /* Must be able to become new owner */
aclresult = pg_namespace_aclcheck(namespaceOid, newOwnerId, check_is_member_of_role(GetUserId(), newOwnerId);
ACL_CREATE);
if (aclresult != ACLCHECK_OK) /* New owner must have CREATE privilege on namespace */
aclcheck_error(aclresult, ACL_KIND_NAMESPACE, aclresult = pg_namespace_aclcheck(namespaceOid, newOwnerId,
get_namespace_name(namespaceOid)); 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 * Modify the owner --- okay to scribble on tup because it's a
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/operatorcmds.c,v 1.24 2005/07/14 21:46:29 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/operatorcmds.c,v 1.25 2005/08/22 17:38:20 tgl Exp $
* *
* DESCRIPTION * DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the * The "DefineFoo" routines take the parse tree and pick out the
...@@ -296,20 +296,25 @@ AlterOperatorOwner(List *name, TypeName *typeName1, TypeName *typeName2, ...@@ -296,20 +296,25 @@ AlterOperatorOwner(List *name, TypeName *typeName1, TypeName *typeName2,
*/ */
if (oprForm->oprowner != newOwnerId) if (oprForm->oprowner != newOwnerId)
{ {
/* Otherwise, must be owner of the existing object */ /* Superusers can always do it */
if (!pg_oper_ownercheck(operOid,GetUserId())) if (!superuser())
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPER, {
NameListToString(name)); /* Otherwise, must be owner of the existing object */
if (!pg_oper_ownercheck(operOid,GetUserId()))
/* Must be able to become new owner */ aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPER,
check_is_member_of_role(GetUserId(), newOwnerId); NameListToString(name));
/* New owner must have CREATE privilege on namespace */ /* Must be able to become new owner */
aclresult = pg_namespace_aclcheck(oprForm->oprnamespace, newOwnerId, check_is_member_of_role(GetUserId(), newOwnerId);
ACL_CREATE);
if (aclresult != ACLCHECK_OK) /* New owner must have CREATE privilege on namespace */
aclcheck_error(aclresult, ACL_KIND_NAMESPACE, aclresult = pg_namespace_aclcheck(oprForm->oprnamespace,
get_namespace_name(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 * Modify the owner --- okay to scribble on tup because it's a
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/schemacmds.c,v 1.33 2005/07/14 21:46:29 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/schemacmds.c,v 1.34 2005/08/22 17:38:20 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -315,7 +315,8 @@ AlterSchemaOwner(const char *name, Oid newOwnerId) ...@@ -315,7 +315,8 @@ AlterSchemaOwner(const char *name, Oid newOwnerId)
* NOTE: This is different from other alter-owner checks in * NOTE: This is different from other alter-owner checks in
* that the current user is checked for create privileges * that the current user is checked for create privileges
* instead of the destination owner. This is consistent * instead of the destination owner. This is consistent
* with the CREATE case for schemas. * with the CREATE case for schemas. Because superusers
* will always have this right, we need no special case for them.
*/ */
aclresult = pg_database_aclcheck(MyDatabaseId, GetUserId(), aclresult = pg_database_aclcheck(MyDatabaseId, GetUserId(),
ACL_CREATE); ACL_CREATE);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.166 2005/08/04 01:09:28 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.167 2005/08/22 17:38:20 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -5307,23 +5307,27 @@ ATExecChangeOwner(Oid relationOid, Oid newOwnerId, bool recursing) ...@@ -5307,23 +5307,27 @@ ATExecChangeOwner(Oid relationOid, Oid newOwnerId, bool recursing)
/* skip permission checks when recursing to index or toast table */ /* skip permission checks when recursing to index or toast table */
if (!recursing) if (!recursing)
{ {
Oid namespaceOid = tuple_class->relnamespace; /* Superusers can always do it */
AclResult aclresult; if (!superuser())
{
/* Otherwise, must be owner of the existing object */ Oid namespaceOid = tuple_class->relnamespace;
if (!pg_class_ownercheck(relationOid,GetUserId())) AclResult aclresult;
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
RelationGetRelationName(target_rel)); /* Otherwise, must be owner of the existing object */
if (!pg_class_ownercheck(relationOid,GetUserId()))
/* Must be able to become new owner */ aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
check_is_member_of_role(GetUserId(), newOwnerId); RelationGetRelationName(target_rel));
/* New owner must have CREATE privilege on namespace */ /* Must be able to become new owner */
aclresult = pg_namespace_aclcheck(namespaceOid, newOwnerId, check_is_member_of_role(GetUserId(), newOwnerId);
ACL_CREATE);
if (aclresult != ACLCHECK_OK) /* New owner must have CREATE privilege on namespace */
aclcheck_error(aclresult, ACL_KIND_NAMESPACE, aclresult = pg_namespace_aclcheck(namespaceOid, newOwnerId,
get_namespace_name(namespaceOid)); ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
get_namespace_name(namespaceOid));
}
} }
memset(repl_null, ' ', sizeof(repl_null)); memset(repl_null, ' ', sizeof(repl_null));
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.79 2005/08/12 01:35:58 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.80 2005/08/22 17:38:20 tgl Exp $
* *
* DESCRIPTION * DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the * The "DefineFoo" routines take the parse tree and pick out the
...@@ -2067,20 +2067,25 @@ AlterTypeOwner(List *names, Oid newOwnerId) ...@@ -2067,20 +2067,25 @@ AlterTypeOwner(List *names, Oid newOwnerId)
*/ */
if (typTup->typowner != newOwnerId) if (typTup->typowner != newOwnerId)
{ {
/* Otherwise, must be owner of the existing object */ /* Superusers can always do it */
if (!pg_type_ownercheck(HeapTupleGetOid(tup),GetUserId())) if (!superuser())
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TYPE, {
TypeNameToString(typename)); /* Otherwise, must be owner of the existing object */
if (!pg_type_ownercheck(HeapTupleGetOid(tup),GetUserId()))
/* Must be able to become new owner */ aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TYPE,
check_is_member_of_role(GetUserId(), newOwnerId); TypeNameToString(typename));
/* New owner must have CREATE privilege on namespace */ /* Must be able to become new owner */
aclresult = pg_namespace_aclcheck(typTup->typnamespace, newOwnerId, check_is_member_of_role(GetUserId(), newOwnerId);
ACL_CREATE);
if (aclresult != ACLCHECK_OK) /* New owner must have CREATE privilege on namespace */
aclcheck_error(aclresult, ACL_KIND_NAMESPACE, aclresult = pg_namespace_aclcheck(typTup->typnamespace,
get_namespace_name(typTup->typnamespace)); newOwnerId,
ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
get_namespace_name(typTup->typnamespace));
}
/* /*
* Modify the owner --- okay to scribble on typTup because it's a * Modify the owner --- okay to scribble on typTup because it's a
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment