7
7
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
8
8
* Portions Copyright (c) 1994, Regents of the University of California
9
9
*
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 $
11
11
*
12
12
*-------------------------------------------------------------------------
13
13
*/
@@ -24,6 +24,7 @@ static bool parseAclItem(const char *item, const char *type, const char *name,
24
24
PQExpBuffer grantee ,PQExpBuffer grantor ,
25
25
PQExpBuffer privs ,PQExpBuffer privswgo );
26
26
static void AddAcl (PQExpBuffer aclbuf ,const char * keyword );
27
+ #define supports_grant_options (version ) ((version) >= 70400)
27
28
28
29
29
30
/*
@@ -187,6 +188,7 @@ buildACLCommands(const char *name, const char *type,
187
188
char * aclbuf ,
188
189
* tok ;
189
190
PQExpBuffer grantee ,grantor ,privs ,privswgo ;
191
+ PQExpBuffer firstsql ,secondsql ;
190
192
bool found_owner_privs = false;
191
193
192
194
if (strlen (acls )== 0 )
@@ -196,13 +198,23 @@ buildACLCommands(const char *name, const char *type,
196
198
grantor = createPQExpBuffer ();
197
199
privs = createPQExpBuffer ();
198
200
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 ();
199
211
200
212
/*
201
213
* Always start with REVOKE ALL FROM PUBLIC, so that we don't have to
202
214
* wire-in knowledge about the default public privileges for different
203
215
* kinds of objects.
204
216
*/
205
- appendPQExpBuffer (sql ,"REVOKE ALL ON %s %s FROM PUBLIC;\n" ,
217
+ appendPQExpBuffer (firstsql ,"REVOKE ALL ON %s %s FROM PUBLIC;\n" ,
206
218
type ,name );
207
219
208
220
/* Make a working copy of acls so we can use strtok */
@@ -234,24 +246,28 @@ buildACLCommands(const char *name, const char *type,
234
246
235
247
if (privs -> len > 0 || privswgo -> len > 0 )
236
248
{
237
- if (owner && strcmp (grantee -> data ,owner )== 0 )
249
+ if (owner
250
+ && strcmp (grantee -> data ,owner )== 0
251
+ && strcmp (grantor -> data ,owner )== 0 )
238
252
{
253
+ found_owner_privs = true;
239
254
/*
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) .
242
257
*/
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 )
245
261
{
246
- appendPQExpBuffer (sql ,"REVOKE ALL ON %s %s FROM %s;\n" ,
262
+ appendPQExpBuffer (firstsql ,"REVOKE ALL ON %s %s FROM %s;\n" ,
247
263
type ,name ,
248
264
fmtId (grantee -> data ));
249
265
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" ,
251
267
privs -> data ,type ,name ,
252
268
fmtId (grantee -> data ));
253
269
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" ,
255
271
privswgo -> data ,type ,name ,
256
272
fmtId (grantee -> data ));
257
273
}
@@ -261,48 +277,44 @@ buildACLCommands(const char *name, const char *type,
261
277
/*
262
278
* Otherwise can assume we are starting from no privs.
263
279
*/
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
+
264
285
if (privs -> len > 0 )
265
286
{
266
- appendPQExpBuffer (sql ,"GRANT %s ON %s %s TO " ,
287
+ appendPQExpBuffer (secondsql ,"GRANT %s ON %s %s TO " ,
267
288
privs -> data ,type ,name );
268
289
if (grantee -> len == 0 )
269
- appendPQExpBuffer (sql ,"PUBLIC;\n" );
290
+ appendPQExpBuffer (secondsql ,"PUBLIC;\n" );
270
291
else if (strncmp (grantee -> data ,"group " ,
271
292
strlen ("group " ))== 0 )
272
- appendPQExpBuffer (sql ,"GROUP %s;\n" ,
293
+ appendPQExpBuffer (secondsql ,"GROUP %s;\n" ,
273
294
fmtId (grantee -> data + strlen ("group " )));
274
295
else
275
- appendPQExpBuffer (sql ,"%s;\n" ,fmtId (grantee -> data ));
296
+ appendPQExpBuffer (secondsql ,"%s;\n" ,fmtId (grantee -> data ));
276
297
}
277
298
if (privswgo -> len > 0 )
278
299
{
279
- appendPQExpBuffer (sql ,"GRANT %s ON %s %s TO " ,
300
+ appendPQExpBuffer (secondsql ,"GRANT %s ON %s %s TO " ,
280
301
privswgo -> data ,type ,name );
281
302
if (grantee -> len == 0 )
282
- appendPQExpBuffer (sql ,"PUBLIC" );
303
+ appendPQExpBuffer (secondsql ,"PUBLIC" );
283
304
else if (strncmp (grantee -> data ,"group " ,
284
305
strlen ("group " ))== 0 )
285
- appendPQExpBuffer (sql ,"GROUP %s" ,
306
+ appendPQExpBuffer (secondsql ,"GROUP %s" ,
286
307
fmtId (grantee -> data + strlen ("group " )));
287
308
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" );
290
311
}
312
+
313
+ if (grantor -> len > 0
314
+ && (!owner || strcmp (owner ,grantor -> data )!= 0 ))
315
+ appendPQExpBuffer (secondsql ,"RESET SESSION AUTHORIZATION;\n" );
291
316
}
292
317
}
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
- }
306
318
}
307
319
308
320
/*
@@ -311,7 +323,7 @@ buildACLCommands(const char *name, const char *type,
311
323
*/
312
324
if (!found_owner_privs && owner )
313
325
{
314
- appendPQExpBuffer (sql ,"REVOKE ALL ON %s %s FROM %s;\n" ,
326
+ appendPQExpBuffer (firstsql ,"REVOKE ALL ON %s %s FROM %s;\n" ,
315
327
type ,name ,fmtId (owner ));
316
328
}
317
329
@@ -321,6 +333,10 @@ buildACLCommands(const char *name, const char *type,
321
333
destroyPQExpBuffer (privs );
322
334
destroyPQExpBuffer (privswgo );
323
335
336
+ appendPQExpBuffer (sql ,"%s%s" ,firstsql -> data ,secondsql -> data );
337
+ destroyPQExpBuffer (firstsql );
338
+ destroyPQExpBuffer (secondsql );
339
+
324
340
return true;
325
341
}
326
342