Skip to content

Commit 15162ae

Browse files
committed
Make dumpACL behave more reasonably for case where owner has revoked
some of his own privileges.
1 parent 340b66c commit 15162ae

File tree

1 file changed

+61
-63
lines changed

1 file changed

+61
-63
lines changed

src/bin/pg_dump/pg_dump.c

Lines changed: 61 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
*
2323
*
2424
* 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 $
2626
*
2727
*-------------------------------------------------------------------------
2828
*/
@@ -79,7 +79,7 @@ static void dumpComment(Archive *fout, const char *target, const char *oid,
7979
const char *((*deps)[]));
8080
static void dumpOneDomain(Archive *fout, TypeInfo *tinfo);
8181
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);
8383
static void dumpTriggers(Archive *fout, const char *tablename,
8484
TableInfo *tblinfo, int numTables);
8585
static void dumpRules(Archive *fout, const char *tablename,
@@ -4129,58 +4129,27 @@ GetPrivileges(Archive *AH, const char *s)
41294129
return strdup(aclbuf);
41304130
}
41314131

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-
41504132

41514133
/*
41524134
* 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
41554136
*/
4156-
41574137
static void
4158-
dumpACL(Archive *fout, TableInfo tbinfo)
4138+
dumpACL(Archive *fout, TableInfo *tbinfo)
41594139
{
4160-
const char *acls = tbinfo.relacl;
4140+
const char *acls = tbinfo->relacl;
41614141
char *aclbuf,
41624142
*tok,
41634143
*eqpos,
41644144
*priv;
41654145
char *objoid;
4166-
char *sql;
4167-
char tmp[1024];
4168-
int sSize = 4096;
4146+
PQExpBuffer sql;
4147+
bool found_owner_privs = false;
41694148

41704149
if (strlen(acls) == 0)
41714150
return; /* table has default permissions */
41724151

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();
41844153

41854154
/* Make a working copy of acls so we can use strtok */
41864155
aclbuf = strdup(acls);
@@ -4202,9 +4171,10 @@ dumpACL(Archive *fout, TableInfo tbinfo)
42024171
if (!eqpos)
42034172
{
42044173
write_msg(NULL, "could not parse ACL list ('%s') for relation %s\n",
4205-
acls, tbinfo.relname);
4174+
acls, tbinfo->relname);
42064175
exit_nicely();
42074176
}
4177+
*eqpos = '\0'; /* it's ok to clobber aclbuf */
42084178

42094179
/*
42104180
* Parse the privileges (right-hand side). Skip if there are
@@ -4213,41 +4183,69 @@ dumpACL(Archive *fout, TableInfo tbinfo)
42134183
priv = GetPrivileges(fout, eqpos + 1);
42144184
if (*priv)
42154185
{
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)
42254187
{
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+
}
42284203
}
42294204
else
42304205
{
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));
42354221
else
4236-
sprintf(tmp, "%s;\n", fmtId(tok, force_quotes));
4237-
strcatalloc(&sql, &sSize, tmp);
4222+
appendPQExpBuffer(sql, "%s;\n", fmtId(tok, force_quotes));
42384223
}
42394224
}
42404225
free(priv);
42414226
}
42424227

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+
42434238
free(aclbuf);
42444239

4245-
if (tbinfo.viewdef != NULL)
4246-
objoid = tbinfo.viewoid;
4240+
if (tbinfo->viewdef != NULL)
4241+
objoid = tbinfo->viewoid;
42474242
else
4248-
objoid = tbinfo.oid;
4243+
objoid = tbinfo->oid;
4244+
4245+
ArchiveEntry(fout, objoid, tbinfo->relname, "ACL",
4246+
NULL, sql->data, "", "", "", NULL, NULL);
42494247

4250-
ArchiveEntry(fout, objoid, tbinfo.relname, "ACL", NULL, sql, "", "", "", NULL, NULL);
4248+
destroyPQExpBuffer(sql);
42514249
}
42524250

42534251
static void
@@ -4350,7 +4348,7 @@ dumpTables(Archive *fout, TableInfo *tblinfo, int numTables,
43504348
/* becomeUser(fout, tblinfo[i].usename); */
43514349
dumpSequence(fout, tblinfo[i], schemaOnly, dataOnly);
43524350
if (!aclsSkip)
4353-
dumpACL(fout, tblinfo[i]);
4351+
dumpACL(fout, &tblinfo[i]);
43544352
}
43554353
}
43564354
if (serialSeq)
@@ -4486,7 +4484,7 @@ dumpTables(Archive *fout, TableInfo *tblinfo, int numTables,
44864484
NULL, NULL);
44874485

44884486
if (!aclsSkip)
4489-
dumpACL(fout, tblinfo[i]);
4487+
dumpACL(fout, &tblinfo[i]);
44904488

44914489
}
44924490

0 commit comments

Comments
 (0)