pg_dump -z has gotten rather thoroughly broken in the last couple
of days --- it was emitting stuff like REVOKE ALL on 'table' from PUBLIC; GRANT ALL on "table" to "Public"; neither of which work. While I was at it I cleaned up a few other things: * \connect commands are issued only in -z mode. In this way, reloading a pg_dump script made without -z will generate a simple database wholly owned by the invoking user, rather than a mishmash of tables owned by various people but lacking in access rights. (Analogy: cp versus cp -p.) * \connect commands are issued just before COPY FROM stdin commands; without this, reloading a database containing non-world-writable tables tended to fail because the COPY was not necessarily attempted as the table owner. * Redundant \connect commands are suppressed (each one costs a backend launch, so...). * Man page updated (-z wasn't ever documented). The first two items were discussed in a pgsql-hackers thread around 6 May 98 ("An item for the TODO list: pg_dump and multiple table owners") but no one had bothered to deal with 'em yet. regards, tom lane
This commit is contained in:
parent
b41468dad2
commit
916710fc91
@ -21,7 +21,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.77 1998/07/08 14:33:19 thomas Exp $
|
||||
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.78 1998/07/19 05:24:49 momjian Exp $
|
||||
*
|
||||
* Modifications - 6/10/96 - dave@bensoft.com - version 1.13.dhb
|
||||
*
|
||||
@ -95,6 +95,7 @@ static void setMaxOid(FILE *fout);
|
||||
static char *AddAcl(char *s, const char *add);
|
||||
static char *GetPrivledges(char *s);
|
||||
static ACL *ParseACL(const char *acls, int *count);
|
||||
static void becomeUser(FILE *fout, const char *username);
|
||||
|
||||
extern char *optarg;
|
||||
extern int optind,
|
||||
@ -110,6 +111,7 @@ int dumpData; /* dump data using proper insert strings */
|
||||
int attrNames; /* put attr names into insert strings */
|
||||
int schemaOnly;
|
||||
int dataOnly;
|
||||
int aclsOption;
|
||||
|
||||
char g_opaque_type[10]; /* name for the opaque type */
|
||||
|
||||
@ -141,12 +143,12 @@ usage(const char *progname)
|
||||
"\t -s \t\t dump out only the schema, no data\n");
|
||||
fprintf(stderr,
|
||||
"\t -t table \t\t dump for this table only\n");
|
||||
fprintf(stderr,
|
||||
"\t -u \t\t use password authentication\n");
|
||||
fprintf(stderr,
|
||||
"\t -v \t\t verbose\n");
|
||||
fprintf(stderr,
|
||||
"\t -z \t\t dump ACLs (grant/revoke)\n");
|
||||
fprintf(stderr,
|
||||
"\t -u \t\t use password authentication\n");
|
||||
fprintf(stderr,
|
||||
"\nIf dbname is not supplied, then the DATABASE environment "
|
||||
"variable value is used.\n");
|
||||
@ -435,7 +437,7 @@ dumpClasses(const TableInfo tblinfo[], const int numTables, FILE *fout,
|
||||
if (g_verbose)
|
||||
fprintf(stderr, "%s dumping out schema of sequence '%s' %s\n",
|
||||
g_comment_start, tblinfo[i].relname, g_comment_end);
|
||||
fprintf(fout, "\\connect - %s\n", tblinfo[i].usename);
|
||||
becomeUser(fout, tblinfo[i].usename);
|
||||
dumpSequence(fout, tblinfo[i]);
|
||||
}
|
||||
}
|
||||
@ -458,6 +460,8 @@ dumpClasses(const TableInfo tblinfo[], const int numTables, FILE *fout,
|
||||
fprintf(stderr, "%s dumping out the contents of Table '%s' %s\n",
|
||||
g_comment_start, classname, g_comment_end);
|
||||
|
||||
becomeUser(fout, tblinfo[i].usename);
|
||||
|
||||
if (!dumpData)
|
||||
dumpClasses_nodumpData(fout, classname, oids);
|
||||
else
|
||||
@ -534,8 +538,7 @@ main(int argc, char **argv)
|
||||
const char *pghost = NULL;
|
||||
const char *pgport = NULL;
|
||||
char *tablename = NULL;
|
||||
int oids = 0,
|
||||
acls = 0;
|
||||
int oids = 0;
|
||||
TableInfo *tblinfo;
|
||||
int numTables;
|
||||
char connect_string[512] = "";
|
||||
@ -598,8 +601,8 @@ main(int argc, char **argv)
|
||||
case 'v': /* verbose */
|
||||
g_verbose = true;
|
||||
break;
|
||||
case 'z': /* Dump oids */
|
||||
acls = 1;
|
||||
case 'z': /* Dump ACLs and table ownership info */
|
||||
aclsOption = 1;
|
||||
break;
|
||||
case 'u':
|
||||
use_password = 1;
|
||||
@ -657,11 +660,11 @@ main(int argc, char **argv)
|
||||
strcat(connect_string, tmp_string);
|
||||
sprintf(tmp_string, "password=%s ", password);
|
||||
strcat(connect_string, tmp_string);
|
||||
bzero(tmp_string, sizeof(tmp_string));
|
||||
bzero(password, sizeof(password));
|
||||
MemSet(tmp_string, 0, sizeof(tmp_string));
|
||||
MemSet(password, 0, sizeof(password));
|
||||
}
|
||||
g_conn = PQconnectdb(connect_string);
|
||||
bzero(connect_string, sizeof(connect_string));
|
||||
MemSet(connect_string, 0, sizeof(connect_string));
|
||||
/* check to see that the backend connection was successfully made */
|
||||
if (PQstatus(g_conn) == CONNECTION_BAD)
|
||||
{
|
||||
@ -679,10 +682,10 @@ main(int argc, char **argv)
|
||||
if (g_verbose)
|
||||
fprintf(stderr, "%s last builtin oid is %d %s\n",
|
||||
g_comment_start, g_last_builtin_oid, g_comment_end);
|
||||
tblinfo = dumpSchema(g_fout, &numTables, tablename, acls);
|
||||
tblinfo = dumpSchema(g_fout, &numTables, tablename, aclsOption);
|
||||
}
|
||||
else
|
||||
tblinfo = dumpSchema(NULL, &numTables, tablename, acls);
|
||||
tblinfo = dumpSchema(NULL, &numTables, tablename, aclsOption);
|
||||
|
||||
if (!schemaOnly)
|
||||
dumpClasses(tblinfo, numTables, g_fout, tablename, oids);
|
||||
@ -1961,7 +1964,7 @@ dumpTypes(FILE *fout, FuncInfo *finfo, int numFuncs,
|
||||
if (funcInd != -1)
|
||||
dumpOneFunc(fout, finfo, funcInd, tinfo, numTypes);
|
||||
|
||||
fprintf(fout, "\\connect - %s\n", tinfo[i].usename);
|
||||
becomeUser(fout, tinfo[i].usename);
|
||||
|
||||
sprintf(q,
|
||||
"CREATE TYPE \"%s\" "
|
||||
@ -2028,7 +2031,7 @@ dumpOneFunc(FILE *fout, FuncInfo *finfo, int i,
|
||||
else
|
||||
finfo[i].dumped = 1;
|
||||
|
||||
fprintf(fout, "\\connect - %s\n", finfo[i].usename);
|
||||
becomeUser(fout, finfo[i].usename);
|
||||
|
||||
sprintf(q, "CREATE FUNCTION \"%s\" (", finfo[i].proname);
|
||||
for (j = 0; j < finfo[i].nargs; j++)
|
||||
@ -2143,7 +2146,7 @@ dumpOprs(FILE *fout, OprInfo *oprinfo, int numOperators,
|
||||
oprinfo[i].oprlsortop));
|
||||
}
|
||||
|
||||
fprintf(fout, "\\connect - %s\n", oprinfo[i].usename);
|
||||
becomeUser(fout, oprinfo[i].usename);
|
||||
|
||||
sprintf(q,
|
||||
"CREATE OPERATOR %s "
|
||||
@ -2238,7 +2241,7 @@ dumpAggs(FILE *fout, AggInfo *agginfo, int numAggs,
|
||||
else
|
||||
comma2[0] = '\0';
|
||||
|
||||
fprintf(fout, "\\connect - %s\n", agginfo[i].usename);
|
||||
becomeUser(fout, agginfo[i].usename);
|
||||
|
||||
sprintf(q, "CREATE AGGREGATE %s ( %s %s%s %s%s %s );\n",
|
||||
agginfo[i].aggname,
|
||||
@ -2349,7 +2352,7 @@ ParseACL(const char *acls, int *count)
|
||||
s = strdup(acls);
|
||||
|
||||
/* Setup up public */
|
||||
ParsedAcl[0].user = strdup("Public");
|
||||
ParsedAcl[0].user = NULL; /* indicates PUBLIC */
|
||||
tok = strtok(s, ",");
|
||||
ParsedAcl[0].privledges = GetPrivledges(strchr(tok, '='));
|
||||
|
||||
@ -2397,16 +2400,23 @@ dumpACL(FILE *fout, TableInfo tbinfo)
|
||||
|
||||
/* Revoke Default permissions for PUBLIC */
|
||||
fprintf(fout,
|
||||
"REVOKE ALL on '%s' from PUBLIC;\n",
|
||||
"REVOKE ALL on \"%s\" from PUBLIC;\n",
|
||||
tbinfo.relname);
|
||||
|
||||
for (k = 0; k < l; k++)
|
||||
{
|
||||
if (ACLlist[k].privledges != (char *) NULL)
|
||||
fprintf(fout,
|
||||
"GRANT %s on \"%s\" to \"%s\";\n",
|
||||
ACLlist[k].privledges, tbinfo.relname,
|
||||
ACLlist[k].user);
|
||||
{
|
||||
if (ACLlist[k].user == (char *) NULL)
|
||||
fprintf(fout,
|
||||
"GRANT %s on \"%s\" to PUBLIC;\n",
|
||||
ACLlist[k].privledges, tbinfo.relname);
|
||||
else
|
||||
fprintf(fout,
|
||||
"GRANT %s on \"%s\" to \"%s\";\n",
|
||||
ACLlist[k].privledges, tbinfo.relname,
|
||||
ACLlist[k].user);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2437,7 +2447,7 @@ dumpTables(FILE *fout, TableInfo *tblinfo, int numTables,
|
||||
continue;
|
||||
if (!tablename || (!strcmp(tblinfo[i].relname, tablename)))
|
||||
{
|
||||
fprintf(fout, "\\connect - %s\n", tblinfo[i].usename);
|
||||
becomeUser(fout, tblinfo[i].usename);
|
||||
dumpSequence(fout, tblinfo[i]);
|
||||
if (acls)
|
||||
dumpACL(fout, tblinfo[i]);
|
||||
@ -2459,7 +2469,7 @@ dumpTables(FILE *fout, TableInfo *tblinfo, int numTables,
|
||||
parentRels = tblinfo[i].parentRels;
|
||||
numParents = tblinfo[i].numParents;
|
||||
|
||||
fprintf(fout, "\\connect - %s\n", tblinfo[i].usename);
|
||||
becomeUser(fout, tblinfo[i].usename);
|
||||
|
||||
sprintf(q, "CREATE TABLE \"%s\" (", fmtId(tblinfo[i].relname));
|
||||
actual_atts = 0;
|
||||
@ -2954,8 +2964,30 @@ dumpTriggers(FILE *fout, const char *tablename,
|
||||
continue;
|
||||
for (j = 0; j < tblinfo[i].ntrig; j++)
|
||||
{
|
||||
fprintf(fout, "\\connect - %s\n", tblinfo[i].usename);
|
||||
becomeUser(fout, tblinfo[i].usename);
|
||||
fputs(tblinfo[i].triggers[j], fout);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Issue a psql \connect command to become the specified user.
|
||||
* We want to do this only if we are dumping ACLs,
|
||||
* and only if the new username is different from the last one
|
||||
* (to avoid the overhead of useless backend launches).
|
||||
*/
|
||||
|
||||
static void becomeUser(FILE *fout, const char *username)
|
||||
{
|
||||
static const char *lastusername = "";
|
||||
|
||||
if (! aclsOption)
|
||||
return;
|
||||
|
||||
if (strcmp(lastusername, username) == 0)
|
||||
return;
|
||||
|
||||
fprintf(fout, "\\connect - %s\n", username);
|
||||
|
||||
lastusername = username;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
.\" This is -*-nroff-*-
|
||||
.\" XXX standard disclaimer belongs here....
|
||||
.\" $Header: /cvsroot/pgsql/src/man/Attic/pg_dump.1,v 1.11 1998/06/24 13:21:28 momjian Exp $
|
||||
.TH PG_DUMP UNIX 1/20/96 PostgreSQL PostgreSQL
|
||||
.\" $Header: /cvsroot/pgsql/src/man/Attic/pg_dump.1,v 1.12 1998/07/19 05:24:51 momjian Exp $
|
||||
.TH PG_DUMP UNIX 7/15/98 PostgreSQL PostgreSQL
|
||||
.SH NAME
|
||||
pg_dump - dumps out a Postgres database into a script file
|
||||
.SH SYNOPSIS
|
||||
@ -36,23 +36,27 @@ port]
|
||||
.BR "-t"
|
||||
table]
|
||||
[\c
|
||||
.BR "-u"
|
||||
]
|
||||
[\c
|
||||
.BR "-v"
|
||||
]
|
||||
[\c
|
||||
.BR "-u"]
|
||||
.BR "-z"
|
||||
]
|
||||
dbname
|
||||
.in -5n
|
||||
.SH DESCRIPTION
|
||||
.IR "pg_dump"
|
||||
is a utility for dumping out a
|
||||
Postgres database into a script file containing query commands. The script
|
||||
files are in a ASCII format and can be used to reconstruct the database,
|
||||
files are in ASCII format and can be used to reconstruct the database,
|
||||
even on other machines and other architectures.
|
||||
.IR "pg_dump"
|
||||
will produce the queries necessary to re-generate all
|
||||
user-defined types, functions, tables, indices, aggregates, and
|
||||
operators. In addition, all the data is copied out in ASCII format so
|
||||
that it can be readily copied in again, as well, as imported into tools
|
||||
that it can be readily copied in again, as well as imported into tools
|
||||
for textual editing.
|
||||
.PP
|
||||
.IR "pg_dump"
|
||||
@ -92,10 +96,13 @@ Dump out only the schema, no data
|
||||
Dump for this table only
|
||||
.TP
|
||||
.BR "-u"
|
||||
Use password authentication. Prompts for username and password.
|
||||
Use password authentication. Prompts for username and password
|
||||
.TP
|
||||
.BR "-v" ""
|
||||
Specifies verbose mode
|
||||
.TP
|
||||
.BR "-z" ""
|
||||
Include ACLs (grant/revoke commands) and table ownership information
|
||||
.PP
|
||||
If dbname is not supplied, then the DATABASE environment variable value is used.
|
||||
.SH "CAVEATS AND LIMITATIONS"
|
||||
|
Loading…
x
Reference in New Issue
Block a user