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

Commit29d75b2

Browse files
committed
Fix pg_dumpall to cope with dangling OIDs in pg_auth_members.
There is a race condition between "GRANT role" and "DROP ROLE",which allows GRANT to install pg_auth_members entries that refer todropped roles. (Commit6566133 prevented that for the grantorfield, but not for the granted or grantee roles.) We'll soon fixthat, at least in HEAD, but pg_dumpall needs to cope with thesituation in case of pre-existing inconsistency. As pg_dumpallstands, it will emit invalid commands like 'GRANT foo TO ""',which causes pg_upgrade to fail. Fix it to emit warnings and skipthose GRANTs, instead.There was some discussion of removing the problem by changingdumpRoleMembership's query to use JOIN not LEFT JOIN, but thatwould result in silently ignoring such entries. It seems betterto produce a warning.Pre-v16 branches already coped with dangling grantor OIDs by simplyomitting the GRANTED BY clause. I left that behavior as-is, althoughit's somewhat inconsistent with the behavior of later branches.Reported-by: Virender Singla <virender.cse@gmail.com>Discussion:https://postgr.es/m/CAM6Zo8woa62ZFHtMKox6a4jb8qQ=w87R2L0K8347iE-juQL2EA@mail.gmail.comBackpatch-through: 13
1 parentdfd8e6c commit29d75b2

File tree

1 file changed

+57
-9
lines changed

1 file changed

+57
-9
lines changed

‎src/bin/pg_dump/pg_dumpall.c

Lines changed: 57 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -986,6 +986,13 @@ dumpRoleMembership(PGconn *conn)
986986
total;
987987
booldump_grantors;
988988
booldump_grant_options;
989+
inti_role;
990+
inti_member;
991+
inti_grantor;
992+
inti_roleid;
993+
inti_memberid;
994+
inti_grantorid;
995+
inti_admin_option;
989996
inti_inherit_option;
990997
inti_set_option;
991998

@@ -995,6 +1002,10 @@ dumpRoleMembership(PGconn *conn)
9951002
* they didn't have ADMIN OPTION on the role, or a user that no longer
9961003
* existed. To avoid dump and restore failures, don't dump the grantor
9971004
* when talking to an old server version.
1005+
*
1006+
* Also, in older versions the roleid and/or member could be role OIDs
1007+
* that no longer exist. If we find such cases, print a warning and skip
1008+
* the entry.
9981009
*/
9991010
dump_grantors= (PQserverVersion(conn) >=160000);
10001011

@@ -1006,8 +1017,10 @@ dumpRoleMembership(PGconn *conn)
10061017
/* Generate and execute query. */
10071018
printfPQExpBuffer(buf,"SELECT ur.rolname AS role, "
10081019
"um.rolname AS member, "
1009-
"ug.oid AS grantorid, "
10101020
"ug.rolname AS grantor, "
1021+
"a.roleid AS roleid, "
1022+
"a.member AS memberid, "
1023+
"a.grantor AS grantorid, "
10111024
"a.admin_option");
10121025
if (dump_grant_options)
10131026
appendPQExpBufferStr(buf,", a.inherit_option, a.set_option");
@@ -1016,8 +1029,15 @@ dumpRoleMembership(PGconn *conn)
10161029
"LEFT JOIN %s um on um.oid = a.member "
10171030
"LEFT JOIN %s ug on ug.oid = a.grantor "
10181031
"WHERE NOT (ur.rolname ~ '^pg_' AND um.rolname ~ '^pg_')"
1019-
"ORDER BY 1,2,4",role_catalog,role_catalog,role_catalog);
1032+
"ORDER BY 1,2,3",role_catalog,role_catalog,role_catalog);
10201033
res=executeQuery(conn,buf->data);
1034+
i_role=PQfnumber(res,"role");
1035+
i_member=PQfnumber(res,"member");
1036+
i_grantor=PQfnumber(res,"grantor");
1037+
i_roleid=PQfnumber(res,"roleid");
1038+
i_memberid=PQfnumber(res,"memberid");
1039+
i_grantorid=PQfnumber(res,"grantorid");
1040+
i_admin_option=PQfnumber(res,"admin_option");
10211041
i_inherit_option=PQfnumber(res,"inherit_option");
10221042
i_set_option=PQfnumber(res,"set_option");
10231043

@@ -1041,24 +1061,32 @@ dumpRoleMembership(PGconn *conn)
10411061
total=PQntuples(res);
10421062
while (start<total)
10431063
{
1044-
char*role=PQgetvalue(res,start,0);
1064+
char*role=PQgetvalue(res,start,i_role);
10451065
inti;
10461066
bool*done;
10471067
intremaining;
10481068
intprev_remaining=0;
10491069
rolename_hash*ht;
10501070

1071+
/* If we hit a null roleid, we're done (nulls sort to the end). */
1072+
if (PQgetisnull(res,start,i_role))
1073+
{
1074+
/* translator: %s represents a numeric role OID */
1075+
pg_log_warning("found orphaned pg_auth_members entry for role %s",
1076+
PQgetvalue(res,start,i_roleid));
1077+
break;
1078+
}
1079+
10511080
/* All memberships for a single role should be adjacent. */
10521081
for (end=start;end<total;++end)
10531082
{
10541083
char*otherrole;
10551084

1056-
otherrole=PQgetvalue(res,end,0);
1085+
otherrole=PQgetvalue(res,end,i_role);
10571086
if (strcmp(role,otherrole)!=0)
10581087
break;
10591088
}
10601089

1061-
role=PQgetvalue(res,start,0);
10621090
remaining=end-start;
10631091
done=pg_malloc0(remaining*sizeof(bool));
10641092
ht=rolename_create(remaining,NULL);
@@ -1098,10 +1126,30 @@ dumpRoleMembership(PGconn *conn)
10981126
if (done[i-start])
10991127
continue;
11001128

1101-
member=PQgetvalue(res,i,1);
1102-
grantorid=PQgetvalue(res,i,2);
1103-
grantor=PQgetvalue(res,i,3);
1104-
admin_option=PQgetvalue(res,i,4);
1129+
/* Complain about, then ignore, entries with orphaned OIDs. */
1130+
if (PQgetisnull(res,i,i_member))
1131+
{
1132+
/* translator: %s represents a numeric role OID */
1133+
pg_log_warning("found orphaned pg_auth_members entry for role %s",
1134+
PQgetvalue(res,i,i_memberid));
1135+
done[i-start]= true;
1136+
--remaining;
1137+
continue;
1138+
}
1139+
if (PQgetisnull(res,i,i_grantor))
1140+
{
1141+
/* translator: %s represents a numeric role OID */
1142+
pg_log_warning("found orphaned pg_auth_members entry for role %s",
1143+
PQgetvalue(res,i,i_grantorid));
1144+
done[i-start]= true;
1145+
--remaining;
1146+
continue;
1147+
}
1148+
1149+
member=PQgetvalue(res,i,i_member);
1150+
grantor=PQgetvalue(res,i,i_grantor);
1151+
grantorid=PQgetvalue(res,i,i_grantorid);
1152+
admin_option=PQgetvalue(res,i,i_admin_option);
11051153
if (dump_grant_options)
11061154
set_option=PQgetvalue(res,i,i_set_option);
11071155

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp