Make dumpACL behave more reasonably for case where owner has revoked

some of his own privileges.
This commit is contained in:
Tom Lane 2002-05-06 18:33:45 +00:00
parent 340b66cc70
commit 15162aef24
1 changed files with 61 additions and 63 deletions

View File

@ -22,7 +22,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.257 2002/04/29 17:30:18 tgl Exp $ * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.258 2002/05/06 18:33:45 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -79,7 +79,7 @@ static void dumpComment(Archive *fout, const char *target, const char *oid,
const char *((*deps)[])); const char *((*deps)[]));
static void dumpOneDomain(Archive *fout, TypeInfo *tinfo); static void dumpOneDomain(Archive *fout, TypeInfo *tinfo);
static void dumpSequence(Archive *fout, TableInfo tbinfo, const bool schemaOnly, const bool dataOnly); static void dumpSequence(Archive *fout, TableInfo tbinfo, const bool schemaOnly, const bool dataOnly);
static void dumpACL(Archive *fout, TableInfo tbinfo); static void dumpACL(Archive *fout, TableInfo *tbinfo);
static void dumpTriggers(Archive *fout, const char *tablename, static void dumpTriggers(Archive *fout, const char *tablename,
TableInfo *tblinfo, int numTables); TableInfo *tblinfo, int numTables);
static void dumpRules(Archive *fout, const char *tablename, static void dumpRules(Archive *fout, const char *tablename,
@ -4129,58 +4129,27 @@ GetPrivileges(Archive *AH, const char *s)
return strdup(aclbuf); return strdup(aclbuf);
} }
/*
* The name says it all; a function to append a string if the dest
* is big enough. If not, it does a realloc.
*/
static void
strcatalloc(char **dest, int *dSize, char *src)
{
int dLen = strlen(*dest);
int sLen = strlen(src);
if ((dLen + sLen) >= *dSize)
{
*dSize = (dLen + sLen) * 2;
*dest = realloc(*dest, *dSize);
}
strcpy(*dest + dLen, src);
}
/* /*
* dumpACL: * dumpACL:
* Write out grant/revoke information * Write out grant/revoke information for a table, view or sequence
* Called for sequences and tables
*/ */
static void static void
dumpACL(Archive *fout, TableInfo tbinfo) dumpACL(Archive *fout, TableInfo *tbinfo)
{ {
const char *acls = tbinfo.relacl; const char *acls = tbinfo->relacl;
char *aclbuf, char *aclbuf,
*tok, *tok,
*eqpos, *eqpos,
*priv; *priv;
char *objoid; char *objoid;
char *sql; PQExpBuffer sql;
char tmp[1024]; bool found_owner_privs = false;
int sSize = 4096;
if (strlen(acls) == 0) if (strlen(acls) == 0)
return; /* table has default permissions */ return; /* table has default permissions */
/* sql = createPQExpBuffer();
* Allocate a larginsh buffer for the output SQL.
*/
sql = (char *) malloc(sSize);
/*
* Revoke Default permissions for PUBLIC. Is this actually necessary,
* or is it just a waste of time?
*/
sprintf(sql, "REVOKE ALL on %s from PUBLIC;\n",
fmtId(tbinfo.relname, force_quotes));
/* Make a working copy of acls so we can use strtok */ /* Make a working copy of acls so we can use strtok */
aclbuf = strdup(acls); aclbuf = strdup(acls);
@ -4202,9 +4171,10 @@ dumpACL(Archive *fout, TableInfo tbinfo)
if (!eqpos) if (!eqpos)
{ {
write_msg(NULL, "could not parse ACL list ('%s') for relation %s\n", write_msg(NULL, "could not parse ACL list ('%s') for relation %s\n",
acls, tbinfo.relname); acls, tbinfo->relname);
exit_nicely(); exit_nicely();
} }
*eqpos = '\0'; /* it's ok to clobber aclbuf */
/* /*
* Parse the privileges (right-hand side). Skip if there are * Parse the privileges (right-hand side). Skip if there are
@ -4213,41 +4183,69 @@ dumpACL(Archive *fout, TableInfo tbinfo)
priv = GetPrivileges(fout, eqpos + 1); priv = GetPrivileges(fout, eqpos + 1);
if (*priv) if (*priv)
{ {
sprintf(tmp, "GRANT %s on %s to ", if (strcmp(tok, tbinfo->usename) == 0)
priv, fmtId(tbinfo.relname, force_quotes));
strcatalloc(&sql, &sSize, tmp);
/*
* Note: fmtId() can only be called once per printf, so don't
* try to merge printing of username into the above printf.
*/
if (eqpos == tok)
{ {
/* Empty left-hand side means "PUBLIC" */ /*
strcatalloc(&sql, &sSize, "PUBLIC;\n"); * For the owner, the default privilege level is ALL.
*/
found_owner_privs = true;
if (strcmp(priv, "ALL") != 0)
{
/* NB: only one fmtId per appendPQExpBuffer! */
appendPQExpBuffer(sql, "REVOKE ALL ON %s FROM ",
fmtId(tbinfo->relname, force_quotes));
appendPQExpBuffer(sql, "%s;\n", fmtId(tok, force_quotes));
appendPQExpBuffer(sql, "GRANT %s ON %s TO ",
priv,
fmtId(tbinfo->relname, force_quotes));
appendPQExpBuffer(sql, "%s;\n", fmtId(tok, force_quotes));
}
} }
else else
{ {
*eqpos = '\0'; /* it's ok to clobber aclbuf */ /*
if (strncmp(tok, "group ", strlen("group ")) == 0) * Otherwise can assume we are starting from no privs.
sprintf(tmp, "GROUP %s;\n", */
fmtId(tok + strlen("group "), force_quotes)); appendPQExpBuffer(sql, "GRANT %s ON %s TO ",
priv,
fmtId(tbinfo->relname, force_quotes));
if (eqpos == tok)
{
/* Empty left-hand side means "PUBLIC" */
appendPQExpBuffer(sql, "PUBLIC;\n");
}
else if (strncmp(tok, "group ", strlen("group ")) == 0)
appendPQExpBuffer(sql, "GROUP %s;\n",
fmtId(tok + strlen("group "),
force_quotes));
else else
sprintf(tmp, "%s;\n", fmtId(tok, force_quotes)); appendPQExpBuffer(sql, "%s;\n", fmtId(tok, force_quotes));
strcatalloc(&sql, &sSize, tmp);
} }
} }
free(priv); free(priv);
} }
/*
* If we didn't find any owner privs, the owner must have revoked 'em all
*/
if (!found_owner_privs && *tbinfo->usename)
{
appendPQExpBuffer(sql, "REVOKE ALL ON %s FROM ",
fmtId(tbinfo->relname, force_quotes));
appendPQExpBuffer(sql, "%s;\n", fmtId(tbinfo->usename, force_quotes));
}
free(aclbuf); free(aclbuf);
if (tbinfo.viewdef != NULL) if (tbinfo->viewdef != NULL)
objoid = tbinfo.viewoid; objoid = tbinfo->viewoid;
else else
objoid = tbinfo.oid; objoid = tbinfo->oid;
ArchiveEntry(fout, objoid, tbinfo.relname, "ACL", NULL, sql, "", "", "", NULL, NULL); ArchiveEntry(fout, objoid, tbinfo->relname, "ACL",
NULL, sql->data, "", "", "", NULL, NULL);
destroyPQExpBuffer(sql);
} }
static void static void
@ -4350,7 +4348,7 @@ dumpTables(Archive *fout, TableInfo *tblinfo, int numTables,
/* becomeUser(fout, tblinfo[i].usename); */ /* becomeUser(fout, tblinfo[i].usename); */
dumpSequence(fout, tblinfo[i], schemaOnly, dataOnly); dumpSequence(fout, tblinfo[i], schemaOnly, dataOnly);
if (!aclsSkip) if (!aclsSkip)
dumpACL(fout, tblinfo[i]); dumpACL(fout, &tblinfo[i]);
} }
} }
if (serialSeq) if (serialSeq)
@ -4486,7 +4484,7 @@ dumpTables(Archive *fout, TableInfo *tblinfo, int numTables,
NULL, NULL); NULL, NULL);
if (!aclsSkip) if (!aclsSkip)
dumpACL(fout, tblinfo[i]); dumpACL(fout, &tblinfo[i]);
} }