Skip to content

Commit cf16f51

Browse files
committed
Fix grant option dumping and related cross-version compatibility issues.
1 parent 060229b commit cf16f51

File tree

1 file changed

+49
-33
lines changed

1 file changed

+49
-33
lines changed

src/bin/pg_dump/dumputils.c

Lines changed: 49 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Header: /cvsroot/pgsql/src/bin/pg_dump/dumputils.c,v 1.4 2003/05/30 22:55:15 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/bin/pg_dump/dumputils.c,v 1.5 2003/07/24 15:52:53 petere Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -24,6 +24,7 @@ static bool parseAclItem(const char *item, const char *type, const char *name,
2424
PQExpBuffer grantee, PQExpBuffer grantor,
2525
PQExpBuffer privs, PQExpBuffer privswgo);
2626
static void AddAcl(PQExpBuffer aclbuf, const char *keyword);
27+
#define supports_grant_options(version) ((version) >= 70400)
2728

2829

2930
/*
@@ -187,6 +188,7 @@ buildACLCommands(const char *name, const char *type,
187188
char *aclbuf,
188189
*tok;
189190
PQExpBuffer grantee, grantor, privs, privswgo;
191+
PQExpBuffer firstsql, secondsql;
190192
bool found_owner_privs = false;
191193

192194
if (strlen(acls) == 0)
@@ -196,13 +198,23 @@ buildACLCommands(const char *name, const char *type,
196198
grantor = createPQExpBuffer();
197199
privs = createPQExpBuffer();
198200
privswgo = createPQExpBuffer();
201+
/*
202+
* At the end, these two will be pasted together to form the
203+
* result. But the owner privileges need to go before the other
204+
* ones to keep the dependencies valid. In recent versions this
205+
* is normally the case, but in old versions they come after the
206+
* PUBLIC privileges and that results in problems if we need to
207+
* run REVOKE on the owner privileges.
208+
*/
209+
firstsql = createPQExpBuffer();
210+
secondsql = createPQExpBuffer();
199211

200212
/*
201213
* Always start with REVOKE ALL FROM PUBLIC, so that we don't have to
202214
* wire-in knowledge about the default public privileges for different
203215
* kinds of objects.
204216
*/
205-
appendPQExpBuffer(sql, "REVOKE ALL ON %s %s FROM PUBLIC;\n",
217+
appendPQExpBuffer(firstsql, "REVOKE ALL ON %s %s FROM PUBLIC;\n",
206218
type, name);
207219

208220
/* Make a working copy of acls so we can use strtok */
@@ -234,24 +246,28 @@ buildACLCommands(const char *name, const char *type,
234246

235247
if (privs->len > 0 || privswgo->len > 0)
236248
{
237-
if (owner && strcmp(grantee->data, owner) == 0)
249+
if (owner
250+
&& strcmp(grantee->data, owner) == 0
251+
&& strcmp(grantor->data, owner) == 0)
238252
{
253+
found_owner_privs = true;
239254
/*
240-
* For the owner, the default privilege level is
241-
* ALL WITH GRANT OPTION.
255+
* For the owner, the default privilege level is ALL
256+
* WITH GRANT OPTION (only ALL prior to 7.4).
242257
*/
243-
found_owner_privs = true;
244-
if (strcmp(privswgo->data, "ALL") != 0)
258+
if (supports_grant_options(remoteVersion)
259+
? strcmp(privswgo->data, "ALL") != 0
260+
: strcmp(privs->data, "ALL") != 0)
245261
{
246-
appendPQExpBuffer(sql, "REVOKE ALL ON %s %s FROM %s;\n",
262+
appendPQExpBuffer(firstsql, "REVOKE ALL ON %s %s FROM %s;\n",
247263
type, name,
248264
fmtId(grantee->data));
249265
if (privs->len > 0)
250-
appendPQExpBuffer(sql, "GRANT %s ON %s %s TO %s;\n",
266+
appendPQExpBuffer(firstsql, "GRANT %s ON %s %s TO %s;\n",
251267
privs->data, type, name,
252268
fmtId(grantee->data));
253269
if (privswgo->len > 0)
254-
appendPQExpBuffer(sql, "GRANT %s ON %s %s TO %s WITH GRANT OPTION;\n",
270+
appendPQExpBuffer(firstsql, "GRANT %s ON %s %s TO %s WITH GRANT OPTION;\n",
255271
privswgo->data, type, name,
256272
fmtId(grantee->data));
257273
}
@@ -261,48 +277,44 @@ buildACLCommands(const char *name, const char *type,
261277
/*
262278
* Otherwise can assume we are starting from no privs.
263279
*/
280+
if (grantor->len > 0
281+
&& (!owner || strcmp(owner, grantor->data) != 0))
282+
appendPQExpBuffer(secondsql, "SET SESSION AUTHORIZATION %s;\n",
283+
fmtId(grantor->data));
284+
264285
if (privs->len > 0)
265286
{
266-
appendPQExpBuffer(sql, "GRANT %s ON %s %s TO ",
287+
appendPQExpBuffer(secondsql, "GRANT %s ON %s %s TO ",
267288
privs->data, type, name);
268289
if (grantee->len == 0)
269-
appendPQExpBuffer(sql, "PUBLIC;\n");
290+
appendPQExpBuffer(secondsql, "PUBLIC;\n");
270291
else if (strncmp(grantee->data, "group ",
271292
strlen("group ")) == 0)
272-
appendPQExpBuffer(sql, "GROUP %s;\n",
293+
appendPQExpBuffer(secondsql, "GROUP %s;\n",
273294
fmtId(grantee->data + strlen("group ")));
274295
else
275-
appendPQExpBuffer(sql, "%s;\n", fmtId(grantee->data));
296+
appendPQExpBuffer(secondsql, "%s;\n", fmtId(grantee->data));
276297
}
277298
if (privswgo->len > 0)
278299
{
279-
appendPQExpBuffer(sql, "GRANT %s ON %s %s TO ",
300+
appendPQExpBuffer(secondsql, "GRANT %s ON %s %s TO ",
280301
privswgo->data, type, name);
281302
if (grantee->len == 0)
282-
appendPQExpBuffer(sql, "PUBLIC");
303+
appendPQExpBuffer(secondsql, "PUBLIC");
283304
else if (strncmp(grantee->data, "group ",
284305
strlen("group ")) == 0)
285-
appendPQExpBuffer(sql, "GROUP %s",
306+
appendPQExpBuffer(secondsql, "GROUP %s",
286307
fmtId(grantee->data + strlen("group ")));
287308
else
288-
appendPQExpBuffer(sql, "%s", fmtId(grantee->data));
289-
appendPQExpBuffer(sql, " WITH GRANT OPTION;\n");
309+
appendPQExpBuffer(secondsql, "%s", fmtId(grantee->data));
310+
appendPQExpBuffer(secondsql, " WITH GRANT OPTION;\n");
290311
}
312+
313+
if (grantor->len > 0
314+
&& (!owner || strcmp(owner, grantor->data) != 0))
315+
appendPQExpBuffer(secondsql, "RESET SESSION AUTHORIZATION;\n");
291316
}
292317
}
293-
else
294-
{
295-
/* No privileges. Issue explicit REVOKE for safety. */
296-
if (grantee->len == 0)
297-
; /* Empty left-hand side means "PUBLIC"; already did it */
298-
else if (strncmp(grantee->data, "group ", strlen("group ")) == 0)
299-
appendPQExpBuffer(sql, "REVOKE ALL ON %s %s FROM GROUP %s;\n",
300-
type, name,
301-
fmtId(grantee->data + strlen("group ")));
302-
else
303-
appendPQExpBuffer(sql, "REVOKE ALL ON %s %s FROM %s;\n",
304-
type, name, fmtId(grantee->data));
305-
}
306318
}
307319

308320
/*
@@ -311,7 +323,7 @@ buildACLCommands(const char *name, const char *type,
311323
*/
312324
if (!found_owner_privs && owner)
313325
{
314-
appendPQExpBuffer(sql, "REVOKE ALL ON %s %s FROM %s;\n",
326+
appendPQExpBuffer(firstsql, "REVOKE ALL ON %s %s FROM %s;\n",
315327
type, name, fmtId(owner));
316328
}
317329

@@ -321,6 +333,10 @@ buildACLCommands(const char *name, const char *type,
321333
destroyPQExpBuffer(privs);
322334
destroyPQExpBuffer(privswgo);
323335

336+
appendPQExpBuffer(sql, "%s%s", firstsql->data, secondsql->data);
337+
destroyPQExpBuffer(firstsql);
338+
destroyPQExpBuffer(secondsql);
339+
324340
return true;
325341
}
326342

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy