88 *
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.165 2010/04/05 01:09:52 tgl Exp $
11+ * $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.166 2010/04/05 01:58:03 tgl Exp $
1212 *
1313 * NOTES
1414 * See acl.h.
@@ -1072,6 +1072,7 @@ SetDefaultACL(InternalDefaultACL *iacls)
10721072Relation rel ;
10731073HeapTuple tuple ;
10741074bool isNew ;
1075+ Acl * def_acl ;
10751076Acl * old_acl ;
10761077Acl * new_acl ;
10771078HeapTuple newtuple ;
@@ -1085,6 +1086,17 @@ SetDefaultACL(InternalDefaultACL *iacls)
10851086
10861087rel = heap_open (DefaultAclRelationId ,RowExclusiveLock );
10871088
1089+ /*
1090+ * The default for a global entry is the hard-wired default ACL for the
1091+ * particular object type. The default for non-global entries is an empty
1092+ * ACL. This must be so because global entries replace the hard-wired
1093+ * defaults, while others are added on.
1094+ */
1095+ if (!OidIsValid (iacls -> nspid ))
1096+ def_acl = acldefault (iacls -> objtype ,iacls -> roleid );
1097+ else
1098+ def_acl = make_empty_acl ();
1099+
10881100/*
10891101 * Convert ACL object type to pg_default_acl object type and handle
10901102 * all_privs option
@@ -1133,7 +1145,7 @@ SetDefaultACL(InternalDefaultACL *iacls)
11331145if (!isNull )
11341146old_acl = DatumGetAclPCopy (aclDatum );
11351147else
1136- old_acl = NULL ;
1148+ old_acl = NULL ;/* this case shouldn't happen, probably */
11371149isNew = false;
11381150}
11391151else
@@ -1153,17 +1165,8 @@ SetDefaultACL(InternalDefaultACL *iacls)
11531165}
11541166else
11551167{
1156- /*
1157- * If we are creating a global entry, start with the hard-wired
1158- * defaults and modify as per command.Otherwise, start with an empty
1159- * ACL and modify that. This is needed because global entries replace
1160- * the hard-wired defaults, while others do not.
1161- */
1162- if (!OidIsValid (iacls -> nspid ))
1163- old_acl = acldefault (iacls -> objtype ,iacls -> roleid );
1164- else
1165- old_acl = make_empty_acl ();
1166-
1168+ /* If no or null entry, start with the default ACL value */
1169+ old_acl = aclcopy (def_acl );
11671170/* There are no old member roles according to the catalogs */
11681171noldmembers = 0 ;
11691172oldmembers = NULL ;
@@ -1182,71 +1185,101 @@ SetDefaultACL(InternalDefaultACL *iacls)
11821185iacls -> roleid ,
11831186iacls -> roleid );
11841187
1185- /* finished building new ACL value, now insert it */
1186- MemSet (values ,0 ,sizeof (values ));
1187- MemSet (nulls , false,sizeof (nulls ));
1188- MemSet (replaces , false,sizeof (replaces ));
1189-
1190- if (isNew )
1188+ /*
1189+ * If the result is the same as the default value, we do not need an
1190+ * explicit pg_default_acl entry, and should in fact remove the entry
1191+ * if it exists. Must sort both arrays to compare properly.
1192+ */
1193+ aclitemsort (new_acl );
1194+ aclitemsort (def_acl );
1195+ if (aclequal (new_acl ,def_acl ))
11911196{
1192- values [ Anum_pg_default_acl_defaclrole - 1 ] = ObjectIdGetDatum ( iacls -> roleid );
1193- values [ Anum_pg_default_acl_defaclnamespace - 1 ] = ObjectIdGetDatum ( iacls -> nspid );
1194- values [ Anum_pg_default_acl_defaclobjtype - 1 ] = CharGetDatum ( objtype );
1195- values [ Anum_pg_default_acl_defaclacl - 1 ] = PointerGetDatum ( new_acl ) ;
1197+ /* delete old entry, if indeed there is one */
1198+ if (! isNew )
1199+ {
1200+ ObjectAddress myself ;
11961201
1197- newtuple = heap_form_tuple (RelationGetDescr (rel ),values ,nulls );
1198- simple_heap_insert (rel ,newtuple );
1202+ /*
1203+ * The dependency machinery will take care of removing all
1204+ * associated dependency entries. We use DROP_RESTRICT since
1205+ * there shouldn't be anything depending on this entry.
1206+ */
1207+ myself .classId = DefaultAclRelationId ;
1208+ myself .objectId = HeapTupleGetOid (tuple );
1209+ myself .objectSubId = 0 ;
1210+
1211+ performDeletion (& myself ,DROP_RESTRICT );
1212+ }
11991213}
12001214else
12011215{
1202- values [Anum_pg_default_acl_defaclacl - 1 ]= PointerGetDatum (new_acl );
1203- replaces [Anum_pg_default_acl_defaclacl - 1 ]= true;
1216+ /* Prepare to insert or update pg_default_acl entry */
1217+ MemSet (values ,0 ,sizeof (values ));
1218+ MemSet (nulls , false,sizeof (nulls ));
1219+ MemSet (replaces , false,sizeof (replaces ));
12041220
1205- newtuple = heap_modify_tuple (tuple ,RelationGetDescr (rel ),
1206- values ,nulls ,replaces );
1207- simple_heap_update (rel ,& newtuple -> t_self ,newtuple );
1208- }
1221+ if (isNew )
1222+ {
1223+ /* insert new entry */
1224+ values [Anum_pg_default_acl_defaclrole - 1 ]= ObjectIdGetDatum (iacls -> roleid );
1225+ values [Anum_pg_default_acl_defaclnamespace - 1 ]= ObjectIdGetDatum (iacls -> nspid );
1226+ values [Anum_pg_default_acl_defaclobjtype - 1 ]= CharGetDatum (objtype );
1227+ values [Anum_pg_default_acl_defaclacl - 1 ]= PointerGetDatum (new_acl );
1228+
1229+ newtuple = heap_form_tuple (RelationGetDescr (rel ),values ,nulls );
1230+ simple_heap_insert (rel ,newtuple );
1231+ }
1232+ else
1233+ {
1234+ /* update existing entry */
1235+ values [Anum_pg_default_acl_defaclacl - 1 ]= PointerGetDatum (new_acl );
1236+ replaces [Anum_pg_default_acl_defaclacl - 1 ]= true;
12091237
1210- /* keep the catalog indexes up to date */
1211- CatalogUpdateIndexes (rel ,newtuple );
1238+ newtuple = heap_modify_tuple (tuple ,RelationGetDescr (rel ),
1239+ values ,nulls ,replaces );
1240+ simple_heap_update (rel ,& newtuple -> t_self ,newtuple );
1241+ }
12121242
1213- /* these dependencies don't change in an update */
1214- if (isNew )
1215- {
1216- /* dependency on role */
1217- recordDependencyOnOwner (DefaultAclRelationId ,
1218- HeapTupleGetOid (newtuple ),
1219- iacls -> roleid );
1243+ /* keep the catalog indexes up to date */
1244+ CatalogUpdateIndexes (rel ,newtuple );
12201245
1221- /*dependency on namespace */
1222- if (OidIsValid ( iacls -> nspid ) )
1246+ /*these dependencies don't change in an update */
1247+ if (isNew )
12231248{
1224- ObjectAddress myself ,
1225- referenced ;
1249+ /* dependency on role */
1250+ recordDependencyOnOwner (DefaultAclRelationId ,
1251+ HeapTupleGetOid (newtuple ),
1252+ iacls -> roleid );
12261253
1227- myself .classId = DefaultAclRelationId ;
1228- myself .objectId = HeapTupleGetOid (newtuple );
1229- myself .objectSubId = 0 ;
1254+ /* dependency on namespace */
1255+ if (OidIsValid (iacls -> nspid ))
1256+ {
1257+ ObjectAddress myself ,
1258+ referenced ;
12301259
1231- referenced .classId = NamespaceRelationId ;
1232- referenced .objectId = iacls -> nspid ;
1233- referenced .objectSubId = 0 ;
1260+ myself .classId = DefaultAclRelationId ;
1261+ myself .objectId = HeapTupleGetOid ( newtuple ) ;
1262+ myself .objectSubId = 0 ;
12341263
1235- recordDependencyOn ( & myself , & referenced , DEPENDENCY_AUTO ) ;
1236- }
1237- }
1264+ referenced . classId = NamespaceRelationId ;
1265+ referenced . objectId = iacls -> nspid ;
1266+ referenced . objectSubId = 0 ;
12381267
1239- /*
1240- * Update the shared dependency ACL info
1241- */
1242- nnewmembers = aclmembers (new_acl ,& newmembers );
1268+ recordDependencyOn (& myself ,& referenced ,DEPENDENCY_AUTO );
1269+ }
1270+ }
12431271
1244- updateAclDependencies ( DefaultAclRelationId , HeapTupleGetOid ( newtuple ), 0 ,
1245- iacls -> roleid ,
1246- noldmembers , oldmembers ,
1247- nnewmembers , newmembers );
1272+ /*
1273+ * Update the shared dependency ACL info
1274+ */
1275+ nnewmembers = aclmembers ( new_acl , & newmembers );
12481276
1249- pfree (new_acl );
1277+ updateAclDependencies (DefaultAclRelationId ,
1278+ HeapTupleGetOid (newtuple ),0 ,
1279+ iacls -> roleid ,
1280+ noldmembers ,oldmembers ,
1281+ nnewmembers ,newmembers );
1282+ }
12501283
12511284if (HeapTupleIsValid (tuple ))
12521285ReleaseSysCache (tuple );