22
22
*
23
23
*
24
24
* IDENTIFICATION
25
- * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.257 2002/04/29 17:30:18 tgl Exp $
25
+ * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.258 2002/05/06 18:33:45 tgl Exp $
26
26
*
27
27
*-------------------------------------------------------------------------
28
28
*/
@@ -79,7 +79,7 @@ static void dumpComment(Archive *fout, const char *target, const char *oid,
79
79
const char * ((* deps )[]));
80
80
static void dumpOneDomain (Archive * fout ,TypeInfo * tinfo );
81
81
static void dumpSequence (Archive * fout ,TableInfo tbinfo ,const bool schemaOnly ,const bool dataOnly );
82
- static void dumpACL (Archive * fout ,TableInfo tbinfo );
82
+ static void dumpACL (Archive * fout ,TableInfo * tbinfo );
83
83
static void dumpTriggers (Archive * fout ,const char * tablename ,
84
84
TableInfo * tblinfo ,int numTables );
85
85
static void dumpRules (Archive * fout ,const char * tablename ,
@@ -4129,58 +4129,27 @@ GetPrivileges(Archive *AH, const char *s)
4129
4129
return strdup (aclbuf );
4130
4130
}
4131
4131
4132
- /*
4133
- * The name says it all; a function to append a string if the dest
4134
- * is big enough. If not, it does a realloc.
4135
- */
4136
- static void
4137
- strcatalloc (char * * dest ,int * dSize ,char * src )
4138
- {
4139
- int dLen = strlen (* dest );
4140
- int sLen = strlen (src );
4141
-
4142
- if ((dLen + sLen ) >=* dSize )
4143
- {
4144
- * dSize = (dLen + sLen )* 2 ;
4145
- * dest = realloc (* dest ,* dSize );
4146
- }
4147
- strcpy (* dest + dLen ,src );
4148
- }
4149
-
4150
4132
4151
4133
/*
4152
4134
* dumpACL:
4153
- * Write out grant/revoke information
4154
- * Called for sequences and tables
4135
+ * Write out grant/revoke information for a table, view or sequence
4155
4136
*/
4156
-
4157
4137
static void
4158
- dumpACL (Archive * fout ,TableInfo tbinfo )
4138
+ dumpACL (Archive * fout ,TableInfo * tbinfo )
4159
4139
{
4160
- const char * acls = tbinfo . relacl ;
4140
+ const char * acls = tbinfo -> relacl ;
4161
4141
char * aclbuf ,
4162
4142
* tok ,
4163
4143
* eqpos ,
4164
4144
* priv ;
4165
4145
char * objoid ;
4166
- char * sql ;
4167
- char tmp [1024 ];
4168
- int sSize = 4096 ;
4146
+ PQExpBuffer sql ;
4147
+ bool found_owner_privs = false;
4169
4148
4170
4149
if (strlen (acls )== 0 )
4171
4150
return ;/* table has default permissions */
4172
4151
4173
- /*
4174
- * Allocate a larginsh buffer for the output SQL.
4175
- */
4176
- sql = (char * )malloc (sSize );
4177
-
4178
- /*
4179
- * Revoke Default permissions for PUBLIC. Is this actually necessary,
4180
- * or is it just a waste of time?
4181
- */
4182
- sprintf (sql ,"REVOKE ALL on %s from PUBLIC;\n" ,
4183
- fmtId (tbinfo .relname ,force_quotes ));
4152
+ sql = createPQExpBuffer ();
4184
4153
4185
4154
/* Make a working copy of acls so we can use strtok */
4186
4155
aclbuf = strdup (acls );
@@ -4202,9 +4171,10 @@ dumpACL(Archive *fout, TableInfo tbinfo)
4202
4171
if (!eqpos )
4203
4172
{
4204
4173
write_msg (NULL ,"could not parse ACL list ('%s') for relation %s\n" ,
4205
- acls ,tbinfo . relname );
4174
+ acls ,tbinfo -> relname );
4206
4175
exit_nicely ();
4207
4176
}
4177
+ * eqpos = '\0' ;/* it's ok to clobber aclbuf */
4208
4178
4209
4179
/*
4210
4180
* Parse the privileges (right-hand side).Skip if there are
@@ -4213,41 +4183,69 @@ dumpACL(Archive *fout, TableInfo tbinfo)
4213
4183
priv = GetPrivileges (fout ,eqpos + 1 );
4214
4184
if (* priv )
4215
4185
{
4216
- sprintf (tmp ,"GRANT %s on %s to " ,
4217
- priv ,fmtId (tbinfo .relname ,force_quotes ));
4218
- strcatalloc (& sql ,& sSize ,tmp );
4219
-
4220
- /*
4221
- * Note: fmtId() can only be called once per printf, so don't
4222
- * try to merge printing of username into the above printf.
4223
- */
4224
- if (eqpos == tok )
4186
+ if (strcmp (tok ,tbinfo -> usename )== 0 )
4225
4187
{
4226
- /* Empty left-hand side means "PUBLIC" */
4227
- strcatalloc (& sql ,& sSize ,"PUBLIC;\n" );
4188
+ /*
4189
+ * For the owner, the default privilege level is ALL.
4190
+ */
4191
+ found_owner_privs = true;
4192
+ if (strcmp (priv ,"ALL" )!= 0 )
4193
+ {
4194
+ /* NB: only one fmtId per appendPQExpBuffer! */
4195
+ appendPQExpBuffer (sql ,"REVOKE ALL ON %s FROM " ,
4196
+ fmtId (tbinfo -> relname ,force_quotes ));
4197
+ appendPQExpBuffer (sql ,"%s;\n" ,fmtId (tok ,force_quotes ));
4198
+ appendPQExpBuffer (sql ,"GRANT %s ON %s TO " ,
4199
+ priv ,
4200
+ fmtId (tbinfo -> relname ,force_quotes ));
4201
+ appendPQExpBuffer (sql ,"%s;\n" ,fmtId (tok ,force_quotes ));
4202
+ }
4228
4203
}
4229
4204
else
4230
4205
{
4231
- * eqpos = '\0' ;/* it's ok to clobber aclbuf */
4232
- if (strncmp (tok ,"group " ,strlen ("group " ))== 0 )
4233
- sprintf (tmp ,"GROUP %s;\n" ,
4234
- fmtId (tok + strlen ("group " ),force_quotes ));
4206
+ /*
4207
+ * Otherwise can assume we are starting from no privs.
4208
+ */
4209
+ appendPQExpBuffer (sql ,"GRANT %s ON %s TO " ,
4210
+ priv ,
4211
+ fmtId (tbinfo -> relname ,force_quotes ));
4212
+ if (eqpos == tok )
4213
+ {
4214
+ /* Empty left-hand side means "PUBLIC" */
4215
+ appendPQExpBuffer (sql ,"PUBLIC;\n" );
4216
+ }
4217
+ else if (strncmp (tok ,"group " ,strlen ("group " ))== 0 )
4218
+ appendPQExpBuffer (sql ,"GROUP %s;\n" ,
4219
+ fmtId (tok + strlen ("group " ),
4220
+ force_quotes ));
4235
4221
else
4236
- sprintf (tmp ,"%s;\n" ,fmtId (tok ,force_quotes ));
4237
- strcatalloc (& sql ,& sSize ,tmp );
4222
+ appendPQExpBuffer (sql ,"%s;\n" ,fmtId (tok ,force_quotes ));
4238
4223
}
4239
4224
}
4240
4225
free (priv );
4241
4226
}
4242
4227
4228
+ /*
4229
+ * If we didn't find any owner privs, the owner must have revoked 'em all
4230
+ */
4231
+ if (!found_owner_privs && * tbinfo -> usename )
4232
+ {
4233
+ appendPQExpBuffer (sql ,"REVOKE ALL ON %s FROM " ,
4234
+ fmtId (tbinfo -> relname ,force_quotes ));
4235
+ appendPQExpBuffer (sql ,"%s;\n" ,fmtId (tbinfo -> usename ,force_quotes ));
4236
+ }
4237
+
4243
4238
free (aclbuf );
4244
4239
4245
- if (tbinfo . viewdef != NULL )
4246
- objoid = tbinfo . viewoid ;
4240
+ if (tbinfo -> viewdef != NULL )
4241
+ objoid = tbinfo -> viewoid ;
4247
4242
else
4248
- objoid = tbinfo .oid ;
4243
+ objoid = tbinfo -> oid ;
4244
+
4245
+ ArchiveEntry (fout ,objoid ,tbinfo -> relname ,"ACL" ,
4246
+ NULL ,sql -> data ,"" ,"" ,"" ,NULL ,NULL );
4249
4247
4250
- ArchiveEntry ( fout , objoid , tbinfo . relname , "ACL" , NULL , sql , "" , "" , "" , NULL , NULL );
4248
+ destroyPQExpBuffer ( sql );
4251
4249
}
4252
4250
4253
4251
static void
@@ -4350,7 +4348,7 @@ dumpTables(Archive *fout, TableInfo *tblinfo, int numTables,
4350
4348
/* becomeUser(fout, tblinfo[i].usename); */
4351
4349
dumpSequence (fout ,tblinfo [i ],schemaOnly ,dataOnly );
4352
4350
if (!aclsSkip )
4353
- dumpACL (fout ,tblinfo [i ]);
4351
+ dumpACL (fout ,& tblinfo [i ]);
4354
4352
}
4355
4353
}
4356
4354
if (serialSeq )
@@ -4486,7 +4484,7 @@ dumpTables(Archive *fout, TableInfo *tblinfo, int numTables,
4486
4484
NULL ,NULL );
4487
4485
4488
4486
if (!aclsSkip )
4489
- dumpACL (fout ,tblinfo [i ]);
4487
+ dumpACL (fout ,& tblinfo [i ]);
4490
4488
4491
4489
}
4492
4490