Commit 60bd2b19 authored by Tom Lane's avatar Tom Lane

Arrange to remove pg_default_acl entries completely if their ACL setting

is changed to match the hard-wired default.  This avoids accumulating useless
catalog entries, and also provides a path for dropping the owning role without
using DROP OWNED BY.  Per yesterday's complaint from Jaime Casanova, the
need to use DROP OWNED BY for that is less than obvious, so providing this
alternative method might save some user frustration.
parent 9029df17
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_default_privileges.sgml,v 1.4 2010/04/03 21:46:59 tgl Exp $ $PostgreSQL: pgsql/doc/src/sgml/ref/alter_default_privileges.sgml,v 1.5 2010/04/05 01:58:03 tgl Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
...@@ -150,9 +150,10 @@ REVOKE [ GRANT OPTION FOR ] ...@@ -150,9 +150,10 @@ REVOKE [ GRANT OPTION FOR ]
</para> </para>
<para> <para>
If you wish to drop a role for which the default privileges have ever been If you wish to drop a role for which the default privileges have been
altered, it is necessary to use <command>DROP OWNED BY</> first, altered, it is necessary to reverse the changes in its default privileges
to get rid of the default privileges entry for the role. or use <command>DROP OWNED BY</> to get rid of the default privileges entry
for the role.
</para> </para>
</refsect1> </refsect1>
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.165 2010/04/05 01:09:52 tgl Exp $ * $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.166 2010/04/05 01:58:03 tgl Exp $
* *
* NOTES * NOTES
* See acl.h. * See acl.h.
...@@ -1072,6 +1072,7 @@ SetDefaultACL(InternalDefaultACL *iacls) ...@@ -1072,6 +1072,7 @@ SetDefaultACL(InternalDefaultACL *iacls)
Relation rel; Relation rel;
HeapTuple tuple; HeapTuple tuple;
bool isNew; bool isNew;
Acl *def_acl;
Acl *old_acl; Acl *old_acl;
Acl *new_acl; Acl *new_acl;
HeapTuple newtuple; HeapTuple newtuple;
...@@ -1085,6 +1086,17 @@ SetDefaultACL(InternalDefaultACL *iacls) ...@@ -1085,6 +1086,17 @@ SetDefaultACL(InternalDefaultACL *iacls)
rel = heap_open(DefaultAclRelationId, RowExclusiveLock); rel = heap_open(DefaultAclRelationId, RowExclusiveLock);
/*
* The default for a global entry is the hard-wired default ACL for the
* particular object type. The default for non-global entries is an empty
* ACL. This must be so because global entries replace the hard-wired
* defaults, while others are added on.
*/
if (!OidIsValid(iacls->nspid))
def_acl = acldefault(iacls->objtype, iacls->roleid);
else
def_acl = make_empty_acl();
/* /*
* Convert ACL object type to pg_default_acl object type and handle * Convert ACL object type to pg_default_acl object type and handle
* all_privs option * all_privs option
...@@ -1133,7 +1145,7 @@ SetDefaultACL(InternalDefaultACL *iacls) ...@@ -1133,7 +1145,7 @@ SetDefaultACL(InternalDefaultACL *iacls)
if (!isNull) if (!isNull)
old_acl = DatumGetAclPCopy(aclDatum); old_acl = DatumGetAclPCopy(aclDatum);
else else
old_acl = NULL; old_acl = NULL; /* this case shouldn't happen, probably */
isNew = false; isNew = false;
} }
else else
...@@ -1153,17 +1165,8 @@ SetDefaultACL(InternalDefaultACL *iacls) ...@@ -1153,17 +1165,8 @@ SetDefaultACL(InternalDefaultACL *iacls)
} }
else else
{ {
/* /* If no or null entry, start with the default ACL value */
* If we are creating a global entry, start with the hard-wired old_acl = aclcopy(def_acl);
* defaults and modify as per command. Otherwise, start with an empty
* ACL and modify that. This is needed because global entries replace
* the hard-wired defaults, while others do not.
*/
if (!OidIsValid(iacls->nspid))
old_acl = acldefault(iacls->objtype, iacls->roleid);
else
old_acl = make_empty_acl();
/* There are no old member roles according to the catalogs */ /* There are no old member roles according to the catalogs */
noldmembers = 0; noldmembers = 0;
oldmembers = NULL; oldmembers = NULL;
...@@ -1182,13 +1185,42 @@ SetDefaultACL(InternalDefaultACL *iacls) ...@@ -1182,13 +1185,42 @@ SetDefaultACL(InternalDefaultACL *iacls)
iacls->roleid, iacls->roleid,
iacls->roleid); iacls->roleid);
/* finished building new ACL value, now insert it */ /*
* If the result is the same as the default value, we do not need an
* explicit pg_default_acl entry, and should in fact remove the entry
* if it exists. Must sort both arrays to compare properly.
*/
aclitemsort(new_acl);
aclitemsort(def_acl);
if (aclequal(new_acl, def_acl))
{
/* delete old entry, if indeed there is one */
if (!isNew)
{
ObjectAddress myself;
/*
* The dependency machinery will take care of removing all
* associated dependency entries. We use DROP_RESTRICT since
* there shouldn't be anything depending on this entry.
*/
myself.classId = DefaultAclRelationId;
myself.objectId = HeapTupleGetOid(tuple);
myself.objectSubId = 0;
performDeletion(&myself, DROP_RESTRICT);
}
}
else
{
/* Prepare to insert or update pg_default_acl entry */
MemSet(values, 0, sizeof(values)); MemSet(values, 0, sizeof(values));
MemSet(nulls, false, sizeof(nulls)); MemSet(nulls, false, sizeof(nulls));
MemSet(replaces, false, sizeof(replaces)); MemSet(replaces, false, sizeof(replaces));
if (isNew) if (isNew)
{ {
/* insert new entry */
values[Anum_pg_default_acl_defaclrole - 1] = ObjectIdGetDatum(iacls->roleid); values[Anum_pg_default_acl_defaclrole - 1] = ObjectIdGetDatum(iacls->roleid);
values[Anum_pg_default_acl_defaclnamespace - 1] = ObjectIdGetDatum(iacls->nspid); values[Anum_pg_default_acl_defaclnamespace - 1] = ObjectIdGetDatum(iacls->nspid);
values[Anum_pg_default_acl_defaclobjtype - 1] = CharGetDatum(objtype); values[Anum_pg_default_acl_defaclobjtype - 1] = CharGetDatum(objtype);
...@@ -1199,6 +1231,7 @@ SetDefaultACL(InternalDefaultACL *iacls) ...@@ -1199,6 +1231,7 @@ SetDefaultACL(InternalDefaultACL *iacls)
} }
else else
{ {
/* update existing entry */
values[Anum_pg_default_acl_defaclacl - 1] = PointerGetDatum(new_acl); values[Anum_pg_default_acl_defaclacl - 1] = PointerGetDatum(new_acl);
replaces[Anum_pg_default_acl_defaclacl - 1] = true; replaces[Anum_pg_default_acl_defaclacl - 1] = true;
...@@ -1241,12 +1274,12 @@ SetDefaultACL(InternalDefaultACL *iacls) ...@@ -1241,12 +1274,12 @@ SetDefaultACL(InternalDefaultACL *iacls)
*/ */
nnewmembers = aclmembers(new_acl, &newmembers); nnewmembers = aclmembers(new_acl, &newmembers);
updateAclDependencies(DefaultAclRelationId, HeapTupleGetOid(newtuple), 0, updateAclDependencies(DefaultAclRelationId,
HeapTupleGetOid(newtuple), 0,
iacls->roleid, iacls->roleid,
noldmembers, oldmembers, noldmembers, oldmembers,
nnewmembers, newmembers); nnewmembers, newmembers);
}
pfree(new_acl);
if (HeapTupleIsValid(tuple)) if (HeapTupleIsValid(tuple))
ReleaseSysCache(tuple); ReleaseSysCache(tuple);
......
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