Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit6566133

Browse files
committed
Ensure that pg_auth_members.grantor is always valid.
Previously, "GRANT foo TO bar" or "GRANT foo TO bar GRANTED BY baz"would record the OID of the grantor in pg_auth_members.grantor, butthat role could later be dropped without modifying or removing thepg_auth_members record. That's not great, because we typically tryto avoid dangling references in catalog data.Now, a role grant depends on the grantor, and the grantor can't bedropped without removing the grant or changing the grantor. "DROPOWNED BY" will remove the grant, just as it does for other kinds ofprivileges. "REASSIGN OWNED BY" will not, again just like what we doin other cases involving privileges.pg_auth_members now has an OID column, because that is needed in orderfor dependencies to work. It also now has an index on the grantorcolumn, because otherwise dropping a role would require a sequentialscan of the entire table to see whether the role's OID is in use asa grantor. That probably wouldn't be too large a problem in practice,but it seems better to have an index just in case.A follow-on patch is planned with the goal of more thoroughlyrationalizing the behavior of role grants. This patch is just tryingto do enough to make sure that the data we store in the catalogs is atsome basic level valid.Patch by me, reviewed by Stephen FrostDiscussion:http://postgr.es/m/CA+TgmoaFr-RZeQ+WoQ5nKPv97oT9+aDgK_a5+qWHSgbDsMp1Vg@mail.gmail.com
1 parent2f17b57 commit6566133

File tree

16 files changed

+397
-68
lines changed

16 files changed

+397
-68
lines changed

‎doc/src/sgml/catalogs.sgml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1669,6 +1669,15 @@ SCRAM-SHA-256$<replaceable>&lt;iteration count&gt;</replaceable>:<replaceable>&l
16691669
</thead>
16701670

16711671
<tbody>
1672+
<row>
1673+
<entry role="catalog_table_entry"><para role="column_definition">
1674+
<structfield>oid</structfield> <type>oid</type>
1675+
</para>
1676+
<para>
1677+
Row identifier
1678+
</para></entry>
1679+
</row>
1680+
16721681
<row>
16731682
<entry role="catalog_table_entry"><para role="column_definition">
16741683
<structfield>roleid</structfield> <type>oid</type>

‎src/backend/catalog/catalog.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,8 @@ IsSharedRelation(Oid relationId)
262262
relationId==AuthIdRolnameIndexId||
263263
relationId==AuthMemMemRoleIndexId||
264264
relationId==AuthMemRoleMemIndexId||
265+
relationId==AuthMemOidIndexId||
266+
relationId==AuthMemGrantorIndexId||
265267
relationId==DatabaseNameIndexId||
266268
relationId==DatabaseOidIndexId||
267269
relationId==DbRoleSettingDatidRolidIndexId||

‎src/backend/catalog/dependency.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include"catalog/pg_amproc.h"
2929
#include"catalog/pg_attrdef.h"
3030
#include"catalog/pg_authid.h"
31+
#include"catalog/pg_auth_members.h"
3132
#include"catalog/pg_cast.h"
3233
#include"catalog/pg_collation.h"
3334
#include"catalog/pg_constraint.h"
@@ -172,6 +173,7 @@ static const Oid object_classes[] = {
172173
TSTemplateRelationId,/* OCLASS_TSTEMPLATE */
173174
TSConfigRelationId,/* OCLASS_TSCONFIG */
174175
AuthIdRelationId,/* OCLASS_ROLE */
176+
AuthMemRelationId,/* OCLASS_ROLE_MEMBERSHIP */
175177
DatabaseRelationId,/* OCLASS_DATABASE */
176178
TableSpaceRelationId,/* OCLASS_TBLSPACE */
177179
ForeignDataWrapperRelationId,/* OCLASS_FDW */
@@ -1502,6 +1504,7 @@ doDeletion(const ObjectAddress *object, int flags)
15021504
caseOCLASS_DEFACL:
15031505
caseOCLASS_EVENT_TRIGGER:
15041506
caseOCLASS_TRANSFORM:
1507+
caseOCLASS_ROLE_MEMBERSHIP:
15051508
DropObjectById(object);
15061509
break;
15071510

@@ -1529,9 +1532,8 @@ doDeletion(const ObjectAddress *object, int flags)
15291532
* Accepts the same flags as performDeletion (though currently only
15301533
* PERFORM_DELETION_CONCURRENTLY does anything).
15311534
*
1532-
* We use LockRelation for relations, LockDatabaseObject for everything
1533-
* else. Shared-across-databases objects are not currently supported
1534-
* because no caller cares, but could be modified to use LockSharedObject.
1535+
* We use LockRelation for relations, and otherwise LockSharedObject or
1536+
* LockDatabaseObject as appropriate for the object type.
15351537
*/
15361538
void
15371539
AcquireDeletionLock(constObjectAddress*object,intflags)
@@ -1549,6 +1551,9 @@ AcquireDeletionLock(const ObjectAddress *object, int flags)
15491551
else
15501552
LockRelationOid(object->objectId,AccessExclusiveLock);
15511553
}
1554+
elseif (object->classId==AuthMemRelationId)
1555+
LockSharedObject(object->classId,object->objectId,0,
1556+
AccessExclusiveLock);
15521557
else
15531558
{
15541559
/* assume we should lock the whole object not a sub-object */
@@ -2914,6 +2919,9 @@ getObjectClass(const ObjectAddress *object)
29142919
caseAuthIdRelationId:
29152920
returnOCLASS_ROLE;
29162921

2922+
caseAuthMemRelationId:
2923+
returnOCLASS_ROLE_MEMBERSHIP;
2924+
29172925
caseDatabaseRelationId:
29182926
returnOCLASS_DATABASE;
29192927

‎src/backend/catalog/objectaddress.c

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include"catalog/pg_amproc.h"
2828
#include"catalog/pg_attrdef.h"
2929
#include"catalog/pg_authid.h"
30+
#include"catalog/pg_auth_members.h"
3031
#include"catalog/pg_cast.h"
3132
#include"catalog/pg_collation.h"
3233
#include"catalog/pg_constraint.h"
@@ -386,6 +387,20 @@ static const ObjectPropertyType ObjectProperty[] =
386387
-1,
387388
true
388389
},
390+
{
391+
"role membership",
392+
AuthMemRelationId,
393+
AuthMemOidIndexId,
394+
-1,
395+
-1,
396+
Anum_pg_auth_members_oid,
397+
InvalidAttrNumber,
398+
InvalidAttrNumber,
399+
Anum_pg_auth_members_grantor,
400+
InvalidAttrNumber,
401+
-1,
402+
true
403+
},
389404
{
390405
"rule",
391406
RewriteRelationId,
@@ -787,6 +802,10 @@ static const struct object_type_map
787802
{
788803
"role",OBJECT_ROLE
789804
},
805+
/* OCLASS_ROLE_MEMBERSHIP */
806+
{
807+
"role membership",-1/* unmapped */
808+
},
790809
/* OCLASS_DATABASE */
791810
{
792811
"database",OBJECT_DATABASE
@@ -3644,6 +3663,48 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
36443663
break;
36453664
}
36463665

3666+
caseOCLASS_ROLE_MEMBERSHIP:
3667+
{
3668+
RelationamDesc;
3669+
ScanKeyDataskey[1];
3670+
SysScanDescrcscan;
3671+
HeapTupletup;
3672+
Form_pg_auth_membersamForm;
3673+
3674+
amDesc=table_open(AuthMemRelationId,AccessShareLock);
3675+
3676+
ScanKeyInit(&skey[0],
3677+
Anum_pg_auth_members_oid,
3678+
BTEqualStrategyNumber,F_OIDEQ,
3679+
ObjectIdGetDatum(object->objectId));
3680+
3681+
rcscan=systable_beginscan(amDesc,AuthMemOidIndexId, true,
3682+
NULL,1,skey);
3683+
3684+
tup=systable_getnext(rcscan);
3685+
3686+
if (!HeapTupleIsValid(tup))
3687+
{
3688+
if (!missing_ok)
3689+
elog(ERROR,"could not find tuple for role membership %u",
3690+
object->objectId);
3691+
3692+
systable_endscan(rcscan);
3693+
table_close(amDesc,AccessShareLock);
3694+
break;
3695+
}
3696+
3697+
amForm= (Form_pg_auth_members)GETSTRUCT(tup);
3698+
3699+
appendStringInfo(&buffer,_("membership of role %s in role %s"),
3700+
GetUserNameFromId(amForm->member, false),
3701+
GetUserNameFromId(amForm->roleid, false));
3702+
3703+
systable_endscan(rcscan);
3704+
table_close(amDesc,AccessShareLock);
3705+
break;
3706+
}
3707+
36473708
caseOCLASS_DATABASE:
36483709
{
36493710
char*datname;
@@ -4533,6 +4594,10 @@ getObjectTypeDescription(const ObjectAddress *object, bool missing_ok)
45334594
appendStringInfoString(&buffer,"role");
45344595
break;
45354596

4597+
caseOCLASS_ROLE_MEMBERSHIP:
4598+
appendStringInfoString(&buffer,"role membership");
4599+
break;
4600+
45364601
caseOCLASS_DATABASE:
45374602
appendStringInfoString(&buffer,"database");
45384603
break;
@@ -5476,6 +5541,49 @@ getObjectIdentityParts(const ObjectAddress *object,
54765541
break;
54775542
}
54785543

5544+
caseOCLASS_ROLE_MEMBERSHIP:
5545+
{
5546+
RelationauthMemDesc;
5547+
ScanKeyDataskey[1];
5548+
SysScanDescamscan;
5549+
HeapTupletup;
5550+
Form_pg_auth_membersamForm;
5551+
5552+
authMemDesc=table_open(AuthMemRelationId,
5553+
AccessShareLock);
5554+
5555+
ScanKeyInit(&skey[0],
5556+
Anum_pg_auth_members_oid,
5557+
BTEqualStrategyNumber,F_OIDEQ,
5558+
ObjectIdGetDatum(object->objectId));
5559+
5560+
amscan=systable_beginscan(authMemDesc,AuthMemOidIndexId, true,
5561+
NULL,1,skey);
5562+
5563+
tup=systable_getnext(amscan);
5564+
5565+
if (!HeapTupleIsValid(tup))
5566+
{
5567+
if (!missing_ok)
5568+
elog(ERROR,"could not find tuple for pg_auth_members entry %u",
5569+
object->objectId);
5570+
5571+
systable_endscan(amscan);
5572+
table_close(authMemDesc,AccessShareLock);
5573+
break;
5574+
}
5575+
5576+
amForm= (Form_pg_auth_members)GETSTRUCT(tup);
5577+
5578+
appendStringInfo(&buffer,_("membership of role %s in role %s"),
5579+
GetUserNameFromId(amForm->member, false),
5580+
GetUserNameFromId(amForm->roleid, false));
5581+
5582+
systable_endscan(amscan);
5583+
table_close(authMemDesc,AccessShareLock);
5584+
break;
5585+
}
5586+
54795587
caseOCLASS_DATABASE:
54805588
{
54815589
char*datname;

‎src/backend/catalog/pg_shdepend.c

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include"catalog/dependency.h"
2323
#include"catalog/indexing.h"
2424
#include"catalog/pg_authid.h"
25+
#include"catalog/pg_auth_members.h"
2526
#include"catalog/pg_collation.h"
2627
#include"catalog/pg_conversion.h"
2728
#include"catalog/pg_database.h"
@@ -1364,11 +1365,6 @@ shdepDropOwned(List *roleids, DropBehavior behavior)
13641365
caseSHARED_DEPENDENCY_INVALID:
13651366
elog(ERROR,"unexpected dependency type");
13661367
break;
1367-
caseSHARED_DEPENDENCY_ACL:
1368-
RemoveRoleFromObjectACL(roleid,
1369-
sdepForm->classid,
1370-
sdepForm->objid);
1371-
break;
13721368
caseSHARED_DEPENDENCY_POLICY:
13731369

13741370
/*
@@ -1398,22 +1394,37 @@ shdepDropOwned(List *roleids, DropBehavior behavior)
13981394
add_exact_object_address(&obj,deleteobjs);
13991395
}
14001396
break;
1397+
caseSHARED_DEPENDENCY_ACL:
1398+
1399+
/*
1400+
* Dependencies on role grants are recorded using
1401+
* SHARED_DEPENDENCY_ACL, but unlike a regular ACL list
1402+
* which stores all permissions for a particular object in
1403+
* a single ACL array, there's a separate catalog row for
1404+
* each grant - so removing the grant just means removing
1405+
* the entire row.
1406+
*/
1407+
if (sdepForm->classid!=AuthMemRelationId)
1408+
{
1409+
RemoveRoleFromObjectACL(roleid,
1410+
sdepForm->classid,
1411+
sdepForm->objid);
1412+
break;
1413+
}
1414+
/* FALLTHROUGH */
14011415
caseSHARED_DEPENDENCY_OWNER:
1402-
/* If a local object, save it for deletion below */
1403-
if (sdepForm->dbid==MyDatabaseId)
1416+
/* Save it for deletion below */
1417+
obj.classId=sdepForm->classid;
1418+
obj.objectId=sdepForm->objid;
1419+
obj.objectSubId=sdepForm->objsubid;
1420+
/* as above */
1421+
AcquireDeletionLock(&obj,0);
1422+
if (!systable_recheck_tuple(scan,tuple))
14041423
{
1405-
obj.classId=sdepForm->classid;
1406-
obj.objectId=sdepForm->objid;
1407-
obj.objectSubId=sdepForm->objsubid;
1408-
/* as above */
1409-
AcquireDeletionLock(&obj,0);
1410-
if (!systable_recheck_tuple(scan,tuple))
1411-
{
1412-
ReleaseDeletionLock(&obj);
1413-
break;
1414-
}
1415-
add_exact_object_address(&obj,deleteobjs);
1424+
ReleaseDeletionLock(&obj);
1425+
break;
14161426
}
1427+
add_exact_object_address(&obj,deleteobjs);
14171428
break;
14181429
}
14191430
}

‎src/backend/catalog/system_views.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ CREATE VIEW pg_group AS
5353
SELECT
5454
rolnameAS groname,
5555
oidAS grosysid,
56-
ARRAY(SELECT memberFROM pg_auth_membersWHERE roleid=oid)AS grolist
56+
ARRAY(SELECT memberFROM pg_auth_membersWHERE roleid=pg_authid.oid)AS grolist
5757
FROM pg_authid
5858
WHERE NOT rolcanlogin;
5959

‎src/backend/commands/alter.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,7 @@ AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid,
650650
caseOCLASS_TRIGGER:
651651
caseOCLASS_SCHEMA:
652652
caseOCLASS_ROLE:
653+
caseOCLASS_ROLE_MEMBERSHIP:
653654
caseOCLASS_DATABASE:
654655
caseOCLASS_TBLSPACE:
655656
caseOCLASS_FDW:

‎src/backend/commands/event_trigger.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,6 +1015,7 @@ EventTriggerSupportsObjectClass(ObjectClass objclass)
10151015
caseOCLASS_DATABASE:
10161016
caseOCLASS_TBLSPACE:
10171017
caseOCLASS_ROLE:
1018+
caseOCLASS_ROLE_MEMBERSHIP:
10181019
caseOCLASS_PARAMETER_ACL:
10191020
/* no support for global objects */
10201021
return false;

‎src/backend/commands/tablecmds.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12667,6 +12667,7 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
1266712667
case OCLASS_TSTEMPLATE:
1266812668
case OCLASS_TSCONFIG:
1266912669
case OCLASS_ROLE:
12670+
case OCLASS_ROLE_MEMBERSHIP:
1267012671
case OCLASS_DATABASE:
1267112672
case OCLASS_TBLSPACE:
1267212673
case OCLASS_FDW:

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp