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.
This commit is contained in:
Tom Lane 2005-08-22 17:38:20 +00:00
parent a7f49252d2
commit bf1e33d24a
9 changed files with 132 additions and 97 deletions

View File

@ -9,7 +9,7 @@
*
*
* 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
* The "DefineFoo" routines take the parse tree and pick out the
@ -331,6 +331,9 @@ AlterAggregateOwner(List *name, TypeName *basetype, Oid newOwnerId)
* command to have succeeded. This is for dump restoration purposes.
*/
if (procForm->proowner != newOwnerId)
{
/* Superusers can always do it */
if (!superuser())
{
/* Otherwise, must be owner of the existing object */
if (!pg_proc_ownercheck(procOid, GetUserId()))
@ -341,11 +344,13 @@ AlterAggregateOwner(List *name, TypeName *basetype, Oid newOwnerId)
check_is_member_of_role(GetUserId(), newOwnerId);
/* New owner must have CREATE privilege on namespace */
aclresult = pg_namespace_aclcheck(procForm->pronamespace, newOwnerId,
aclresult = pg_namespace_aclcheck(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

View File

@ -8,7 +8,7 @@
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
@ -205,6 +205,9 @@ AlterConversionOwner(List *name, Oid newOwnerId)
* command to have succeeded. This is for dump restoration purposes.
*/
if (convForm->conowner != newOwnerId)
{
/* Superusers can always do it */
if (!superuser())
{
/* Otherwise, must be owner of the existing object */
if (!pg_conversion_ownercheck(HeapTupleGetOid(tup),GetUserId()))
@ -215,11 +218,13 @@ AlterConversionOwner(List *name, Oid newOwnerId)
check_is_member_of_role(GetUserId(), newOwnerId);
/* New owner must have CREATE privilege on namespace */
aclresult = pg_namespace_aclcheck(convForm->connamespace, newOwnerId,
aclresult = pg_namespace_aclcheck(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

View File

@ -15,7 +15,7 @@
*
*
* 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)
* 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 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())
ereport(ERROR,

View File

@ -10,7 +10,7 @@
*
*
* 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
* These routines take the parse tree and pick out the
@ -894,6 +894,9 @@ AlterFunctionOwner(List *name, List *argtypes, Oid newOwnerId)
bool isNull;
HeapTuple newtuple;
/* Superusers can always do it */
if (!superuser())
{
/* Otherwise, must be owner of the existing object */
if (!pg_proc_ownercheck(procOid,GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC,
@ -903,11 +906,13 @@ AlterFunctionOwner(List *name, List *argtypes, Oid newOwnerId)
check_is_member_of_role(GetUserId(), newOwnerId);
/* New owner must have CREATE privilege on namespace */
aclresult = pg_namespace_aclcheck(procForm->pronamespace, newOwnerId,
aclresult = pg_namespace_aclcheck(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_repl, ' ', sizeof(repl_repl));

View File

@ -9,7 +9,7 @@
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
@ -950,6 +950,9 @@ AlterOpClassOwner(List *name, const char *access_method, Oid newOwnerId)
* command to have succeeded. This is for dump restoration purposes.
*/
if (opcForm->opcowner != newOwnerId)
{
/* Superusers can always do it */
if (!superuser())
{
/* Otherwise, must be owner of the existing object */
if (!pg_opclass_ownercheck(HeapTupleGetOid(tup),GetUserId()))
@ -965,6 +968,7 @@ AlterOpClassOwner(List *name, const char *access_method, Oid newOwnerId)
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

View File

@ -9,7 +9,7 @@
*
*
* 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
* The "DefineFoo" routines take the parse tree and pick out the
@ -295,6 +295,9 @@ AlterOperatorOwner(List *name, TypeName *typeName1, TypeName *typeName2,
* command to have succeeded. This is for dump restoration purposes.
*/
if (oprForm->oprowner != newOwnerId)
{
/* Superusers can always do it */
if (!superuser())
{
/* Otherwise, must be owner of the existing object */
if (!pg_oper_ownercheck(operOid,GetUserId()))
@ -305,11 +308,13 @@ AlterOperatorOwner(List *name, TypeName *typeName1, TypeName *typeName2,
check_is_member_of_role(GetUserId(), newOwnerId);
/* New owner must have CREATE privilege on namespace */
aclresult = pg_namespace_aclcheck(oprForm->oprnamespace, newOwnerId,
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

View File

@ -8,7 +8,7 @@
*
*
* 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)
* 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 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(),
ACL_CREATE);

View File

@ -8,7 +8,7 @@
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
@ -5306,6 +5306,9 @@ ATExecChangeOwner(Oid relationOid, Oid newOwnerId, bool recursing)
/* skip permission checks when recursing to index or toast table */
if (!recursing)
{
/* Superusers can always do it */
if (!superuser())
{
Oid namespaceOid = tuple_class->relnamespace;
AclResult aclresult;
@ -5325,6 +5328,7 @@ ATExecChangeOwner(Oid relationOid, Oid newOwnerId, bool recursing)
aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
get_namespace_name(namespaceOid));
}
}
memset(repl_null, ' ', sizeof(repl_null));
memset(repl_repl, ' ', sizeof(repl_repl));

View File

@ -8,7 +8,7 @@
*
*
* 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
* The "DefineFoo" routines take the parse tree and pick out the
@ -2066,6 +2066,9 @@ AlterTypeOwner(List *names, Oid newOwnerId)
* command to have succeeded. This is for dump restoration purposes.
*/
if (typTup->typowner != newOwnerId)
{
/* Superusers can always do it */
if (!superuser())
{
/* Otherwise, must be owner of the existing object */
if (!pg_type_ownercheck(HeapTupleGetOid(tup),GetUserId()))
@ -2076,11 +2079,13 @@ AlterTypeOwner(List *names, Oid newOwnerId)
check_is_member_of_role(GetUserId(), newOwnerId);
/* New owner must have CREATE privilege on namespace */
aclresult = pg_namespace_aclcheck(typTup->typnamespace, newOwnerId,
aclresult = pg_namespace_aclcheck(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