Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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)