2002-08-27 20:57:26 +02:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
2005-07-31 19:19:22 +02:00
|
|
|
* pg_dumpall.c
|
2002-08-27 20:57:26 +02:00
|
|
|
*
|
2024-01-04 02:49:05 +01:00
|
|
|
* Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
|
2002-08-27 20:57:26 +02:00
|
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
|
|
*
|
2013-01-17 05:49:54 +01:00
|
|
|
* pg_dumpall forces all pg_dump output to be text, since it also outputs
|
|
|
|
* text into the same output stream.
|
2002-08-27 20:57:26 +02:00
|
|
|
*
|
2010-09-20 22:08:53 +02:00
|
|
|
* src/bin/pg_dump/pg_dumpall.c
|
2002-08-27 20:57:26 +02:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "postgres_fe.h"
|
|
|
|
|
2005-07-31 19:19:22 +02:00
|
|
|
#include <time.h>
|
2002-08-27 20:57:26 +02:00
|
|
|
#include <unistd.h>
|
2006-02-12 07:11:51 +01:00
|
|
|
|
2022-04-06 19:24:33 +02:00
|
|
|
#include "catalog/pg_authid_d.h"
|
2020-08-10 18:22:54 +02:00
|
|
|
#include "common/connect.h"
|
2017-03-22 15:00:30 +01:00
|
|
|
#include "common/file_utils.h"
|
2024-04-06 07:17:07 +02:00
|
|
|
#include "common/hashfn_unstable.h"
|
2019-05-14 20:19:49 +02:00
|
|
|
#include "common/logging.h"
|
Remove arbitrary restrictions on password length.
This patch started out with the goal of harmonizing various arbitrary
limits on password length, but after awhile a better idea emerged:
let's just get rid of those fixed limits.
recv_password_packet() has an arbitrary limit on the packet size,
which we don't really need, so just drop it. (Note that this doesn't
really affect anything for MD5 or SCRAM password verification, since
those will hash the user's password to something shorter anyway.
It does matter for auth methods that require a cleartext password.)
Likewise remove the arbitrary error condition in pg_saslprep().
The remaining limits are mostly in client-side code that prompts
for passwords. To improve those, refactor simple_prompt() so that
it allocates its own result buffer that can be made as big as
necessary. Actually, it proves best to make a separate routine
pg_get_line() that has essentially the semantics of fgets(), except
that it allocates a suitable result buffer and hence will never
return a truncated line. (pg_get_line has a lot of potential
applications to replace randomly-sized fgets buffers elsewhere,
but I'll leave that for another patch.)
I built pg_get_line() atop stringinfo.c, which requires moving
that code to src/common/; but that seems fine since it was a poor
fit for src/port/ anyway.
This patch is mostly mine, but it owes a good deal to Nathan Bossart
who pressed for a solution to the password length problem and
created a predecessor patch. Also thanks to Peter Eisentraut and
Stephen Frost for ideas and discussion.
Discussion: https://postgr.es/m/09512C4F-8CB9-4021-B455-EF4C4F0D55A0@amazon.com
2020-09-04 02:09:18 +02:00
|
|
|
#include "common/string.h"
|
2019-10-23 06:08:53 +02:00
|
|
|
#include "dumputils.h"
|
2016-03-24 20:55:44 +01:00
|
|
|
#include "fe_utils/string_utils.h"
|
Read include/exclude commands for dump/restore from file
When there is a need to filter multiple tables with include and/or exclude
options it's quite possible to run into the limitations of the commandline.
This adds a --filter=FILENAME feature to pg_dump, pg_dumpall and pg_restore
which is used to supply a file containing object exclude/include commands
which work just like their commandline counterparts. The format of the file
is one command per row like:
<command> <object> <objectpattern>
<command> can be "include" or "exclude", <object> can be table_data, index
table_data_and_children, database, extension, foreign_data, function, table
schema, table_and_children or trigger.
This patch has gone through many revisions and design changes over a long
period of time, the list of reviewers reflect reviewers of some version of
the patch, not necessarily the final version.
Patch by Pavel Stehule with some additional hacking by me.
Author: Pavel Stehule <pavel.stehule@gmail.com>
Reviewed-by: Justin Pryzby <pryzby@telsasoft.com>
Reviewed-by: vignesh C <vignesh21@gmail.com>
Reviewed-by: Dean Rasheed <dean.a.rasheed@gmail.com>
Reviewed-by: Tomas Vondra <tomas.vondra@enterprisedb.com>
Reviewed-by: Julien Rouhaud <rjuju123@gmail.com>
Reviewed-by: Erik Rijkers <er@xs4all.nl>
Discussion: https://postgr.es/m/CAFj8pRB10wvW0CC9Xq=1XDs=zCQxer3cbLcNZa+qiX4cUH-G_A@mail.gmail.com
2023-11-29 14:56:24 +01:00
|
|
|
#include "filter.h"
|
2019-10-23 06:08:53 +02:00
|
|
|
#include "getopt_long.h"
|
|
|
|
#include "pg_backup.h"
|
2002-08-27 20:57:26 +02:00
|
|
|
|
2006-05-22 13:21:54 +02:00
|
|
|
/* version string we expect back from pg_dump */
|
|
|
|
#define PGDUMP_VERSIONSTR "pg_dump (PostgreSQL) " PG_VERSION "\n"
|
2004-05-11 23:57:15 +02:00
|
|
|
|
Make role grant system more consistent with other privileges.
Previously, membership of role A in role B could be recorded in the
catalog tables only once. This meant that a new grant of role A to
role B would overwrite the previous grant. For other object types, a
new grant of permission on an object - in this case role A - exists
along side the existing grant provided that the grantor is different.
Either grant can be revoked independently of the other, and
permissions remain so long as at least one grant remains. Make role
grants work similarly.
Previously, when granting membership in a role, the superuser could
specify any role whatsoever as the grantor, but for other object types,
the grantor of record must be either the owner of the object, or a
role that currently has privileges to perform a similar GRANT.
Implement the same scheme for role grants, treating the bootstrap
superuser as the role owner since roles do not have owners. This means
that attempting to revoke a grant, or admin option on a grant, can now
fail if there are dependent privileges, and that CASCADE can be used
to revoke these. It also means that you can't grant ADMIN OPTION on
a role back to a user who granted it directly or indirectly to you,
similar to how you can't give WITH GRANT OPTION on a privilege back
to a role which granted it directly or indirectly to you.
Previously, only the superuser could specify GRANTED BY with a user
other than the current user. Relax that rule to allow the grantor
to be any role whose privileges the current user posseses. This
doesn't improve compatibility with what we do for other object types,
where support for GRANTED BY is entirely vestigial, but it makes this
feature more usable and seems to make sense to change at the same time
we're changing related behaviors.
Along the way, fix "ALTER GROUP group_name ADD USER user_name" to
require the same privileges as "GRANT group_name TO user_name".
Previously, CREATEROLE privileges were sufficient for either, but
only the former form was permissible with ADMIN OPTION on the role.
Now, either CREATEROLE or ADMIN OPTION on the role suffices for
either spelling.
Patch by me, reviewed by Stephen Frost.
Discussion: http://postgr.es/m/CA+TgmoaFr-RZeQ+WoQ5nKPv97oT9+aDgK_a5+qWHSgbDsMp1Vg@mail.gmail.com
2022-08-22 17:35:17 +02:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
uint32 status;
|
|
|
|
uint32 hashval;
|
|
|
|
char *rolename;
|
|
|
|
} RoleNameEntry;
|
|
|
|
|
|
|
|
#define SH_PREFIX rolename
|
|
|
|
#define SH_ELEMENT_TYPE RoleNameEntry
|
|
|
|
#define SH_KEY_TYPE char *
|
|
|
|
#define SH_KEY rolename
|
2024-04-06 07:17:07 +02:00
|
|
|
#define SH_HASH_KEY(tb, key) hash_string(key)
|
Make role grant system more consistent with other privileges.
Previously, membership of role A in role B could be recorded in the
catalog tables only once. This meant that a new grant of role A to
role B would overwrite the previous grant. For other object types, a
new grant of permission on an object - in this case role A - exists
along side the existing grant provided that the grantor is different.
Either grant can be revoked independently of the other, and
permissions remain so long as at least one grant remains. Make role
grants work similarly.
Previously, when granting membership in a role, the superuser could
specify any role whatsoever as the grantor, but for other object types,
the grantor of record must be either the owner of the object, or a
role that currently has privileges to perform a similar GRANT.
Implement the same scheme for role grants, treating the bootstrap
superuser as the role owner since roles do not have owners. This means
that attempting to revoke a grant, or admin option on a grant, can now
fail if there are dependent privileges, and that CASCADE can be used
to revoke these. It also means that you can't grant ADMIN OPTION on
a role back to a user who granted it directly or indirectly to you,
similar to how you can't give WITH GRANT OPTION on a privilege back
to a role which granted it directly or indirectly to you.
Previously, only the superuser could specify GRANTED BY with a user
other than the current user. Relax that rule to allow the grantor
to be any role whose privileges the current user posseses. This
doesn't improve compatibility with what we do for other object types,
where support for GRANTED BY is entirely vestigial, but it makes this
feature more usable and seems to make sense to change at the same time
we're changing related behaviors.
Along the way, fix "ALTER GROUP group_name ADD USER user_name" to
require the same privileges as "GRANT group_name TO user_name".
Previously, CREATEROLE privileges were sufficient for either, but
only the former form was permissible with ADMIN OPTION on the role.
Now, either CREATEROLE or ADMIN OPTION on the role suffices for
either spelling.
Patch by me, reviewed by Stephen Frost.
Discussion: http://postgr.es/m/CA+TgmoaFr-RZeQ+WoQ5nKPv97oT9+aDgK_a5+qWHSgbDsMp1Vg@mail.gmail.com
2022-08-22 17:35:17 +02:00
|
|
|
#define SH_EQUAL(tb, a, b) (strcmp(a, b) == 0)
|
|
|
|
#define SH_STORE_HASH
|
|
|
|
#define SH_GET_HASH(tb, a) (a)->hashval
|
|
|
|
#define SH_SCOPE static inline
|
|
|
|
#define SH_RAW_ALLOCATOR pg_malloc0
|
|
|
|
#define SH_DECLARE
|
|
|
|
#define SH_DEFINE
|
|
|
|
#include "lib/simplehash.h"
|
2002-08-27 20:57:26 +02:00
|
|
|
|
|
|
|
static void help(void);
|
2002-08-28 20:25:05 +02:00
|
|
|
|
2009-04-11 22:23:05 +02:00
|
|
|
static void dropRoles(PGconn *conn);
|
2005-10-11 00:29:48 +02:00
|
|
|
static void dumpRoles(PGconn *conn);
|
2005-07-31 19:19:22 +02:00
|
|
|
static void dumpRoleMembership(PGconn *conn);
|
2022-04-06 19:24:33 +02:00
|
|
|
static void dumpRoleGUCPrivs(PGconn *conn);
|
2009-04-11 22:23:05 +02:00
|
|
|
static void dropTablespaces(PGconn *conn);
|
2004-06-18 08:14:31 +02:00
|
|
|
static void dumpTablespaces(PGconn *conn);
|
2009-04-11 22:23:05 +02:00
|
|
|
static void dropDBs(PGconn *conn);
|
2002-08-28 20:25:05 +02:00
|
|
|
static void dumpUserConfig(PGconn *conn, const char *username);
|
2002-08-27 20:57:26 +02:00
|
|
|
static void dumpDatabases(PGconn *conn);
|
2014-10-27 01:59:21 +01:00
|
|
|
static void dumpTimestamp(const char *msg);
|
Move handling of database properties from pg_dumpall into pg_dump.
This patch rearranges the division of labor between pg_dump and pg_dumpall
so that pg_dump itself handles all properties attached to a single
database. Notably, a database's ACL (GRANT/REVOKE status) and local GUC
settings established by ALTER DATABASE SET and ALTER ROLE IN DATABASE SET
can be dumped and restored by pg_dump. This is a long-requested
improvement.
"pg_dumpall -g" will now produce only role- and tablespace-related output,
nothing about individual databases. The total output of a regular
pg_dumpall run remains the same.
pg_dump (or pg_restore) will restore database-level properties only when
creating the target database with --create. This applies not only to
ACLs and GUCs but to the other database properties it already handled,
that is database comments and security labels. This is more consistent
and useful, but does represent an incompatibility in the behavior seen
without --create.
(This change makes the proposed patch to have pg_dump use "COMMENT ON
DATABASE CURRENT_DATABASE" unnecessary, since there is no case where
the command is issued that we won't know the true name of the database.
We might still want that patch as a feature in its own right, but pg_dump
no longer needs it.)
pg_dumpall with --clean will now drop and recreate the "postgres" and
"template1" databases in the target cluster, allowing their locale and
encoding settings to be changed if necessary, and providing a cleaner
way to set nondefault tablespaces for them than we had before. This
means that such a script must now always be started in the "postgres"
database; the order of drops and reconnects will not work otherwise.
Without --clean, the script will not adjust any database-level properties
of those two databases (including their comments, ACLs, and security
labels, which it formerly would try to set).
Another minor incompatibility is that the CREATE DATABASE commands in a
pg_dumpall script will now always specify locale and encoding settings.
Formerly those would be omitted if they matched the cluster's default.
While that behavior had some usefulness in some migration scenarios,
it also posed a significant hazard of unwanted locale/encoding changes.
To migrate to another locale/encoding, it's now necessary to use pg_dump
without --create to restore into a database with the desired settings.
Commit 4bd371f6f's hack to emit "SET default_transaction_read_only = off"
is gone: we now dodge that problem by the expedient of not issuing ALTER
DATABASE SET commands until after reconnecting to the target database.
Therefore, such settings won't apply during the restore session.
In passing, improve some shaky grammar in the docs, and add a note pointing
out that pg_dumpall's output can't be expected to load without any errors.
(Someday we might want to fix that, but this is not that patch.)
Haribabu Kommi, reviewed at various times by Andreas Karlsson,
Vaishnavi Prabakaran, and Robert Haas; further hacking by me.
Discussion: https://postgr.es/m/CAJrrPGcUurV0eWTeXODwsOYFN=Ekq36t1s0YnFYUNzsmRfdAyA@mail.gmail.com
2018-01-22 20:09:09 +01:00
|
|
|
static int runPgDump(const char *dbname, const char *create_opts);
|
Avoid using unsafe search_path settings during dump and restore.
Historically, pg_dump has "set search_path = foo, pg_catalog" when
dumping an object in schema "foo", and has also caused that setting
to be used while restoring the object. This is problematic because
functions and operators in schema "foo" could capture references meant
to refer to pg_catalog entries, both in the queries issued by pg_dump
and those issued during the subsequent restore run. That could
result in dump/restore misbehavior, or in privilege escalation if a
nefarious user installs trojan-horse functions or operators.
This patch changes pg_dump so that it does not change the search_path
dynamically. The emitted restore script sets the search_path to what
was used at dump time, and then leaves it alone thereafter. Created
objects are placed in the correct schema, regardless of the active
search_path, by dint of schema-qualifying their names in the CREATE
commands, as well as in subsequent ALTER and ALTER-like commands.
Since this change requires a change in the behavior of pg_restore
when processing an archive file made according to this new convention,
bump the archive file version number; old versions of pg_restore will
therefore refuse to process files made with new versions of pg_dump.
Security: CVE-2018-1058
2018-02-26 16:18:21 +01:00
|
|
|
static void buildShSecLabels(PGconn *conn,
|
|
|
|
const char *catalog_name, Oid objectId,
|
|
|
|
const char *objtype, const char *objname,
|
|
|
|
PQExpBuffer buffer);
|
2022-09-23 01:41:23 +02:00
|
|
|
static PGconn *connectDatabase(const char *dbname,
|
|
|
|
const char *connection_string, const char *pghost,
|
|
|
|
const char *pgport, const char *pguser,
|
|
|
|
trivalue prompt_password, bool fail_on_error);
|
2013-02-25 18:39:10 +01:00
|
|
|
static char *constructConnStr(const char **keywords, const char **values);
|
2002-08-27 20:57:26 +02:00
|
|
|
static PGresult *executeQuery(PGconn *conn, const char *query);
|
2005-07-31 19:19:22 +02:00
|
|
|
static void executeCommand(PGconn *conn, const char *query);
|
2019-03-01 16:47:44 +01:00
|
|
|
static void expand_dbname_patterns(PGconn *conn, SimpleStringList *patterns,
|
|
|
|
SimpleStringList *names);
|
Read include/exclude commands for dump/restore from file
When there is a need to filter multiple tables with include and/or exclude
options it's quite possible to run into the limitations of the commandline.
This adds a --filter=FILENAME feature to pg_dump, pg_dumpall and pg_restore
which is used to supply a file containing object exclude/include commands
which work just like their commandline counterparts. The format of the file
is one command per row like:
<command> <object> <objectpattern>
<command> can be "include" or "exclude", <object> can be table_data, index
table_data_and_children, database, extension, foreign_data, function, table
schema, table_and_children or trigger.
This patch has gone through many revisions and design changes over a long
period of time, the list of reviewers reflect reviewers of some version of
the patch, not necessarily the final version.
Patch by Pavel Stehule with some additional hacking by me.
Author: Pavel Stehule <pavel.stehule@gmail.com>
Reviewed-by: Justin Pryzby <pryzby@telsasoft.com>
Reviewed-by: vignesh C <vignesh21@gmail.com>
Reviewed-by: Dean Rasheed <dean.a.rasheed@gmail.com>
Reviewed-by: Tomas Vondra <tomas.vondra@enterprisedb.com>
Reviewed-by: Julien Rouhaud <rjuju123@gmail.com>
Reviewed-by: Erik Rijkers <er@xs4all.nl>
Discussion: https://postgr.es/m/CAFj8pRB10wvW0CC9Xq=1XDs=zCQxer3cbLcNZa+qiX4cUH-G_A@mail.gmail.com
2023-11-29 14:56:24 +01:00
|
|
|
static void read_dumpall_filters(const char *filename, SimpleStringList *patterns);
|
2005-07-31 19:19:22 +02:00
|
|
|
|
|
|
|
static char pg_dump_bin[MAXPGPATH];
|
2013-03-27 17:10:40 +01:00
|
|
|
static const char *progname;
|
2005-07-31 19:19:22 +02:00
|
|
|
static PQExpBuffer pgdumpopts;
|
2013-02-25 18:39:10 +01:00
|
|
|
static char *connstr = "";
|
Move handling of database properties from pg_dumpall into pg_dump.
This patch rearranges the division of labor between pg_dump and pg_dumpall
so that pg_dump itself handles all properties attached to a single
database. Notably, a database's ACL (GRANT/REVOKE status) and local GUC
settings established by ALTER DATABASE SET and ALTER ROLE IN DATABASE SET
can be dumped and restored by pg_dump. This is a long-requested
improvement.
"pg_dumpall -g" will now produce only role- and tablespace-related output,
nothing about individual databases. The total output of a regular
pg_dumpall run remains the same.
pg_dump (or pg_restore) will restore database-level properties only when
creating the target database with --create. This applies not only to
ACLs and GUCs but to the other database properties it already handled,
that is database comments and security labels. This is more consistent
and useful, but does represent an incompatibility in the behavior seen
without --create.
(This change makes the proposed patch to have pg_dump use "COMMENT ON
DATABASE CURRENT_DATABASE" unnecessary, since there is no case where
the command is issued that we won't know the true name of the database.
We might still want that patch as a feature in its own right, but pg_dump
no longer needs it.)
pg_dumpall with --clean will now drop and recreate the "postgres" and
"template1" databases in the target cluster, allowing their locale and
encoding settings to be changed if necessary, and providing a cleaner
way to set nondefault tablespaces for them than we had before. This
means that such a script must now always be started in the "postgres"
database; the order of drops and reconnects will not work otherwise.
Without --clean, the script will not adjust any database-level properties
of those two databases (including their comments, ACLs, and security
labels, which it formerly would try to set).
Another minor incompatibility is that the CREATE DATABASE commands in a
pg_dumpall script will now always specify locale and encoding settings.
Formerly those would be omitted if they matched the cluster's default.
While that behavior had some usefulness in some migration scenarios,
it also posed a significant hazard of unwanted locale/encoding changes.
To migrate to another locale/encoding, it's now necessary to use pg_dump
without --create to restore into a database with the desired settings.
Commit 4bd371f6f's hack to emit "SET default_transaction_read_only = off"
is gone: we now dodge that problem by the expedient of not issuing ALTER
DATABASE SET commands until after reconnecting to the target database.
Therefore, such settings won't apply during the restore session.
In passing, improve some shaky grammar in the docs, and add a note pointing
out that pg_dumpall's output can't be expected to load without any errors.
(Someday we might want to fix that, but this is not that patch.)
Haribabu Kommi, reviewed at various times by Andreas Karlsson,
Vaishnavi Prabakaran, and Robert Haas; further hacking by me.
Discussion: https://postgr.es/m/CAJrrPGcUurV0eWTeXODwsOYFN=Ekq36t1s0YnFYUNzsmRfdAyA@mail.gmail.com
2018-01-22 20:09:09 +01:00
|
|
|
static bool output_clean = false;
|
2005-07-31 19:19:22 +02:00
|
|
|
static bool skip_acls = false;
|
|
|
|
static bool verbose = false;
|
2017-03-22 15:00:30 +01:00
|
|
|
static bool dosync = true;
|
2005-10-15 04:49:52 +02:00
|
|
|
|
2009-03-22 17:44:26 +01:00
|
|
|
static int binary_upgrade = 0;
|
|
|
|
static int column_inserts = 0;
|
2005-07-31 19:19:22 +02:00
|
|
|
static int disable_dollar_quoting = 0;
|
|
|
|
static int disable_triggers = 0;
|
2014-03-03 19:02:18 +01:00
|
|
|
static int if_exists = 0;
|
2009-03-22 17:44:26 +01:00
|
|
|
static int inserts = 0;
|
2022-01-17 06:51:46 +01:00
|
|
|
static int no_table_access_method = 0;
|
2008-03-20 18:36:58 +01:00
|
|
|
static int no_tablespaces = 0;
|
2005-07-31 19:19:22 +02:00
|
|
|
static int use_setsessauth = 0;
|
Support --no-comments in pg_dump, pg_dumpall, pg_restore.
We have switches already to suppress other subsidiary object properties,
such as ACLs, security labels, ownership, and tablespaces, so just on
the grounds of symmetry we should allow suppressing comments as well.
Also, commit 0d4e6ed30 added a positive reason to have this feature,
i.e. to allow obtaining the old behavior of selective pg_restore should
anyone desire that.
Recent commits have removed the cases where pg_dump emitted comments on
built-in objects that the restoring user might not have privileges to
comment on, so the original primary motivation for this feature is gone,
but it still seems at least somewhat useful in its own right.
Robins Tharakan, reviewed by Fabrízio Mello
Discussion: https://postgr.es/m/CAEP4nAx22Z4ch74oJGzr5RyyjcyUSbpiFLyeYXX8pehfou92ug@mail.gmail.com
2018-01-25 21:27:24 +01:00
|
|
|
static int no_comments = 0;
|
2017-05-12 15:15:40 +02:00
|
|
|
static int no_publications = 0;
|
2011-05-19 22:20:11 +02:00
|
|
|
static int no_security_labels = 0;
|
2017-05-09 16:58:06 +02:00
|
|
|
static int no_subscriptions = 0;
|
2021-05-19 02:38:48 +02:00
|
|
|
static int no_toast_compression = 0;
|
2010-12-29 12:48:53 +01:00
|
|
|
static int no_unlogged_table_data = 0;
|
2017-03-07 15:00:54 +01:00
|
|
|
static int no_role_passwords = 0;
|
2005-07-31 19:19:22 +02:00
|
|
|
static int server_version;
|
2017-08-15 04:54:41 +02:00
|
|
|
static int load_via_partition_root = 0;
|
2018-07-13 03:57:03 +02:00
|
|
|
static int on_conflict_do_nothing = 0;
|
2005-07-31 19:19:22 +02:00
|
|
|
|
2017-03-07 15:00:54 +01:00
|
|
|
static char role_catalog[10];
|
|
|
|
#define PG_AUTHID "pg_authid"
|
|
|
|
#define PG_ROLES "pg_roles "
|
|
|
|
|
2007-01-25 04:30:43 +01:00
|
|
|
static FILE *OPF;
|
|
|
|
static char *filename = NULL;
|
2002-08-27 20:57:26 +02:00
|
|
|
|
2019-03-01 16:47:44 +01:00
|
|
|
static SimpleStringList database_exclude_patterns = {NULL, NULL};
|
|
|
|
static SimpleStringList database_exclude_names = {NULL, NULL};
|
|
|
|
|
2013-03-27 17:10:40 +01:00
|
|
|
#define exit_nicely(code) exit(code)
|
2009-02-18 13:07:08 +01:00
|
|
|
|
2002-08-27 20:57:26 +02:00
|
|
|
int
|
|
|
|
main(int argc, char *argv[])
|
|
|
|
{
|
2009-04-11 22:23:05 +02:00
|
|
|
static struct option long_options[] = {
|
2003-05-31 01:55:10 +02:00
|
|
|
{"data-only", no_argument, NULL, 'a'},
|
2002-08-27 20:57:26 +02:00
|
|
|
{"clean", no_argument, NULL, 'c'},
|
2017-09-01 18:23:16 +02:00
|
|
|
{"encoding", required_argument, NULL, 'E'},
|
2007-01-25 04:30:43 +01:00
|
|
|
{"file", required_argument, NULL, 'f'},
|
2003-03-06 22:45:52 +01:00
|
|
|
{"globals-only", no_argument, NULL, 'g'},
|
2002-08-27 20:57:26 +02:00
|
|
|
{"host", required_argument, NULL, 'h'},
|
2013-02-25 18:39:10 +01:00
|
|
|
{"dbname", required_argument, NULL, 'd'},
|
2007-01-25 03:46:33 +01:00
|
|
|
{"database", required_argument, NULL, 'l'},
|
2004-07-12 16:35:45 +02:00
|
|
|
{"no-owner", no_argument, NULL, 'O'},
|
2002-08-27 20:57:26 +02:00
|
|
|
{"port", required_argument, NULL, 'p'},
|
2007-01-25 03:30:32 +01:00
|
|
|
{"roles-only", no_argument, NULL, 'r'},
|
2003-05-31 01:55:10 +02:00
|
|
|
{"schema-only", no_argument, NULL, 's'},
|
2004-07-12 16:35:45 +02:00
|
|
|
{"superuser", required_argument, NULL, 'S'},
|
2007-01-25 03:30:32 +01:00
|
|
|
{"tablespaces-only", no_argument, NULL, 't'},
|
2002-08-27 20:57:26 +02:00
|
|
|
{"username", required_argument, NULL, 'U'},
|
|
|
|
{"verbose", no_argument, NULL, 'v'},
|
2009-02-26 17:02:39 +01:00
|
|
|
{"no-password", no_argument, NULL, 'w'},
|
2007-01-25 03:30:32 +01:00
|
|
|
{"password", no_argument, NULL, 'W'},
|
2003-05-31 01:55:10 +02:00
|
|
|
{"no-privileges", no_argument, NULL, 'x'},
|
|
|
|
{"no-acl", no_argument, NULL, 'x'},
|
2004-07-12 16:35:45 +02:00
|
|
|
|
|
|
|
/*
|
2006-10-07 22:59:05 +02:00
|
|
|
* the following options don't have an equivalent short option letter
|
2004-07-12 16:35:45 +02:00
|
|
|
*/
|
2009-03-22 17:44:26 +01:00
|
|
|
{"attribute-inserts", no_argument, &column_inserts, 1},
|
|
|
|
{"binary-upgrade", no_argument, &binary_upgrade, 1},
|
|
|
|
{"column-inserts", no_argument, &column_inserts, 1},
|
2004-07-12 16:35:45 +02:00
|
|
|
{"disable-dollar-quoting", no_argument, &disable_dollar_quoting, 1},
|
|
|
|
{"disable-triggers", no_argument, &disable_triggers, 1},
|
2019-03-01 16:47:44 +01:00
|
|
|
{"exclude-database", required_argument, NULL, 6},
|
2019-02-18 13:22:00 +01:00
|
|
|
{"extra-float-digits", required_argument, NULL, 5},
|
2014-03-03 19:02:18 +01:00
|
|
|
{"if-exists", no_argument, &if_exists, 1},
|
2009-03-22 17:44:26 +01:00
|
|
|
{"inserts", no_argument, &inserts, 1},
|
2009-01-05 17:54:37 +01:00
|
|
|
{"lock-wait-timeout", required_argument, NULL, 2},
|
2022-01-17 06:51:46 +01:00
|
|
|
{"no-table-access-method", no_argument, &no_table_access_method, 1},
|
2008-03-20 18:36:58 +01:00
|
|
|
{"no-tablespaces", no_argument, &no_tablespaces, 1},
|
2010-07-22 03:22:35 +02:00
|
|
|
{"quote-all-identifiers", no_argument, "e_all_identifiers, 1},
|
2017-08-15 04:54:41 +02:00
|
|
|
{"load-via-partition-root", no_argument, &load_via_partition_root, 1},
|
2009-01-05 17:54:37 +01:00
|
|
|
{"role", required_argument, NULL, 3},
|
2004-07-12 16:35:45 +02:00
|
|
|
{"use-set-session-authorization", no_argument, &use_setsessauth, 1},
|
Support --no-comments in pg_dump, pg_dumpall, pg_restore.
We have switches already to suppress other subsidiary object properties,
such as ACLs, security labels, ownership, and tablespaces, so just on
the grounds of symmetry we should allow suppressing comments as well.
Also, commit 0d4e6ed30 added a positive reason to have this feature,
i.e. to allow obtaining the old behavior of selective pg_restore should
anyone desire that.
Recent commits have removed the cases where pg_dump emitted comments on
built-in objects that the restoring user might not have privileges to
comment on, so the original primary motivation for this feature is gone,
but it still seems at least somewhat useful in its own right.
Robins Tharakan, reviewed by Fabrízio Mello
Discussion: https://postgr.es/m/CAEP4nAx22Z4ch74oJGzr5RyyjcyUSbpiFLyeYXX8pehfou92ug@mail.gmail.com
2018-01-25 21:27:24 +01:00
|
|
|
{"no-comments", no_argument, &no_comments, 1},
|
2017-05-12 15:15:40 +02:00
|
|
|
{"no-publications", no_argument, &no_publications, 1},
|
2017-06-08 18:12:31 +02:00
|
|
|
{"no-role-passwords", no_argument, &no_role_passwords, 1},
|
2011-05-19 22:20:11 +02:00
|
|
|
{"no-security-labels", no_argument, &no_security_labels, 1},
|
2017-05-09 16:58:06 +02:00
|
|
|
{"no-subscriptions", no_argument, &no_subscriptions, 1},
|
2017-03-22 15:00:30 +01:00
|
|
|
{"no-sync", no_argument, NULL, 4},
|
2021-05-19 02:38:48 +02:00
|
|
|
{"no-toast-compression", no_argument, &no_toast_compression, 1},
|
2010-12-29 12:48:53 +01:00
|
|
|
{"no-unlogged-table-data", no_argument, &no_unlogged_table_data, 1},
|
2018-07-13 03:57:03 +02:00
|
|
|
{"on-conflict-do-nothing", no_argument, &on_conflict_do_nothing, 1},
|
2019-06-15 00:21:52 +02:00
|
|
|
{"rows-per-insert", required_argument, NULL, 7},
|
Read include/exclude commands for dump/restore from file
When there is a need to filter multiple tables with include and/or exclude
options it's quite possible to run into the limitations of the commandline.
This adds a --filter=FILENAME feature to pg_dump, pg_dumpall and pg_restore
which is used to supply a file containing object exclude/include commands
which work just like their commandline counterparts. The format of the file
is one command per row like:
<command> <object> <objectpattern>
<command> can be "include" or "exclude", <object> can be table_data, index
table_data_and_children, database, extension, foreign_data, function, table
schema, table_and_children or trigger.
This patch has gone through many revisions and design changes over a long
period of time, the list of reviewers reflect reviewers of some version of
the patch, not necessarily the final version.
Patch by Pavel Stehule with some additional hacking by me.
Author: Pavel Stehule <pavel.stehule@gmail.com>
Reviewed-by: Justin Pryzby <pryzby@telsasoft.com>
Reviewed-by: vignesh C <vignesh21@gmail.com>
Reviewed-by: Dean Rasheed <dean.a.rasheed@gmail.com>
Reviewed-by: Tomas Vondra <tomas.vondra@enterprisedb.com>
Reviewed-by: Julien Rouhaud <rjuju123@gmail.com>
Reviewed-by: Erik Rijkers <er@xs4all.nl>
Discussion: https://postgr.es/m/CAFj8pRB10wvW0CC9Xq=1XDs=zCQxer3cbLcNZa+qiX4cUH-G_A@mail.gmail.com
2023-11-29 14:56:24 +01:00
|
|
|
{"filter", required_argument, NULL, 8},
|
2004-07-12 16:35:45 +02:00
|
|
|
|
2002-08-27 20:57:26 +02:00
|
|
|
{NULL, 0, NULL, 0}
|
|
|
|
};
|
|
|
|
|
2012-11-30 20:49:55 +01:00
|
|
|
char *pghost = NULL;
|
|
|
|
char *pgport = NULL;
|
|
|
|
char *pguser = NULL;
|
|
|
|
char *pgdb = NULL;
|
|
|
|
char *use_role = NULL;
|
2017-09-01 18:23:16 +02:00
|
|
|
const char *dumpencoding = NULL;
|
2014-10-14 20:00:55 +02:00
|
|
|
trivalue prompt_password = TRI_DEFAULT;
|
2012-11-30 20:49:55 +01:00
|
|
|
bool data_only = false;
|
|
|
|
bool globals_only = false;
|
|
|
|
bool roles_only = false;
|
|
|
|
bool tablespaces_only = false;
|
|
|
|
PGconn *conn;
|
|
|
|
int encoding;
|
|
|
|
const char *std_strings;
|
|
|
|
int c,
|
|
|
|
ret;
|
|
|
|
int optindex;
|
|
|
|
|
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
|
|
|
pg_logging_init(argv[0]);
|
|
|
|
pg_logging_set_level(PG_LOG_WARNING);
|
2008-12-11 08:34:09 +01:00
|
|
|
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_dump"));
|
2003-04-04 22:42:13 +02:00
|
|
|
progname = get_progname(argv[0]);
|
2002-08-27 20:57:26 +02:00
|
|
|
|
|
|
|
if (argc > 1)
|
|
|
|
{
|
|
|
|
if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
|
|
|
|
{
|
|
|
|
help();
|
2012-02-16 17:49:20 +01:00
|
|
|
exit_nicely(0);
|
2002-08-27 20:57:26 +02:00
|
|
|
}
|
|
|
|
if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
|
|
|
|
{
|
|
|
|
puts("pg_dumpall (PostgreSQL) " PG_VERSION);
|
2012-02-16 17:49:20 +01:00
|
|
|
exit_nicely(0);
|
2002-08-27 20:57:26 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-05-22 13:21:54 +02:00
|
|
|
if ((ret = find_other_exec(argv[0], "pg_dump", PGDUMP_VERSIONSTR,
|
2004-05-14 19:04:48 +02:00
|
|
|
pg_dump_bin)) < 0)
|
2004-05-11 23:57:15 +02:00
|
|
|
{
|
2004-10-15 06:32:28 +02:00
|
|
|
char full_path[MAXPGPATH];
|
|
|
|
|
|
|
|
if (find_my_exec(argv[0], full_path) < 0)
|
2007-02-10 15:58:55 +01:00
|
|
|
strlcpy(full_path, progname, sizeof(full_path));
|
2004-10-15 06:32:28 +02:00
|
|
|
|
2004-05-11 23:57:15 +02:00
|
|
|
if (ret == -1)
|
2022-04-08 20:55:14 +02:00
|
|
|
pg_fatal("program \"%s\" is needed by %s but was not found in the same directory as \"%s\"",
|
|
|
|
"pg_dump", progname, full_path);
|
2004-05-11 23:57:15 +02:00
|
|
|
else
|
2022-04-08 20:55:14 +02:00
|
|
|
pg_fatal("program \"%s\" was found by \"%s\" but was not the same version as %s",
|
|
|
|
"pg_dump", full_path, progname);
|
2004-05-11 23:57:15 +02:00
|
|
|
}
|
|
|
|
|
2002-08-27 20:57:26 +02:00
|
|
|
pgdumpopts = createPQExpBuffer();
|
|
|
|
|
2019-05-23 02:36:28 +02:00
|
|
|
while ((c = getopt_long(argc, argv, "acd:E:f:gh:l:Op:rsS:tU:vwWx", long_options, &optindex)) != -1)
|
2002-08-27 20:57:26 +02:00
|
|
|
{
|
|
|
|
switch (c)
|
|
|
|
{
|
2003-05-31 01:55:10 +02:00
|
|
|
case 'a':
|
|
|
|
data_only = true;
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(pgdumpopts, " -a");
|
2003-05-31 01:55:10 +02:00
|
|
|
break;
|
|
|
|
|
2002-08-27 20:57:26 +02:00
|
|
|
case 'c':
|
|
|
|
output_clean = true;
|
|
|
|
break;
|
|
|
|
|
2013-02-25 18:39:10 +01:00
|
|
|
case 'd':
|
|
|
|
connstr = pg_strdup(optarg);
|
|
|
|
break;
|
|
|
|
|
2017-09-01 18:23:16 +02:00
|
|
|
case 'E':
|
|
|
|
dumpencoding = pg_strdup(optarg);
|
|
|
|
appendPQExpBufferStr(pgdumpopts, " -E ");
|
|
|
|
appendShellString(pgdumpopts, optarg);
|
|
|
|
break;
|
|
|
|
|
2007-01-25 04:30:43 +01:00
|
|
|
case 'f':
|
2012-10-12 19:35:40 +02:00
|
|
|
filename = pg_strdup(optarg);
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(pgdumpopts, " -f ");
|
2016-08-08 16:07:46 +02:00
|
|
|
appendShellString(pgdumpopts, filename);
|
2007-01-25 04:30:43 +01:00
|
|
|
break;
|
2002-08-27 20:57:26 +02:00
|
|
|
|
|
|
|
case 'g':
|
|
|
|
globals_only = true;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'h':
|
2012-10-12 19:35:40 +02:00
|
|
|
pghost = pg_strdup(optarg);
|
2002-08-27 20:57:26 +02:00
|
|
|
break;
|
|
|
|
|
2007-01-25 03:46:33 +01:00
|
|
|
case 'l':
|
2012-10-12 19:35:40 +02:00
|
|
|
pgdb = pg_strdup(optarg);
|
2007-01-25 03:46:33 +01:00
|
|
|
break;
|
2005-04-19 01:47:52 +02:00
|
|
|
|
2004-07-12 16:35:45 +02:00
|
|
|
case 'O':
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(pgdumpopts, " -O");
|
2004-07-12 16:35:45 +02:00
|
|
|
break;
|
|
|
|
|
2002-08-27 20:57:26 +02:00
|
|
|
case 'p':
|
2012-10-12 19:35:40 +02:00
|
|
|
pgport = pg_strdup(optarg);
|
2002-08-27 20:57:26 +02:00
|
|
|
break;
|
2007-11-15 22:14:46 +01:00
|
|
|
|
2007-01-25 03:30:32 +01:00
|
|
|
case 'r':
|
|
|
|
roles_only = true;
|
|
|
|
break;
|
2002-08-27 20:57:26 +02:00
|
|
|
|
2003-05-31 01:55:10 +02:00
|
|
|
case 's':
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(pgdumpopts, " -s");
|
2003-05-31 01:55:10 +02:00
|
|
|
break;
|
|
|
|
|
2004-07-12 16:35:45 +02:00
|
|
|
case 'S':
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(pgdumpopts, " -S ");
|
2016-08-08 16:07:46 +02:00
|
|
|
appendShellString(pgdumpopts, optarg);
|
2004-07-12 16:35:45 +02:00
|
|
|
break;
|
2007-11-15 22:14:46 +01:00
|
|
|
|
2007-01-25 03:30:32 +01:00
|
|
|
case 't':
|
|
|
|
tablespaces_only = true;
|
|
|
|
break;
|
2004-07-12 16:35:45 +02:00
|
|
|
|
2002-08-27 20:57:26 +02:00
|
|
|
case 'U':
|
2012-10-12 19:35:40 +02:00
|
|
|
pguser = pg_strdup(optarg);
|
2002-08-27 20:57:26 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 'v':
|
|
|
|
verbose = true;
|
2020-09-17 18:52:18 +02:00
|
|
|
pg_logging_increase_verbosity();
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(pgdumpopts, " -v");
|
2002-08-27 20:57:26 +02:00
|
|
|
break;
|
|
|
|
|
2009-02-26 17:02:39 +01:00
|
|
|
case 'w':
|
|
|
|
prompt_password = TRI_NO;
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(pgdumpopts, " -w");
|
2009-02-26 17:02:39 +01:00
|
|
|
break;
|
|
|
|
|
2002-08-27 20:57:26 +02:00
|
|
|
case 'W':
|
2009-02-26 17:02:39 +01:00
|
|
|
prompt_password = TRI_YES;
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(pgdumpopts, " -W");
|
2002-08-27 20:57:26 +02:00
|
|
|
break;
|
|
|
|
|
2003-05-31 01:55:10 +02:00
|
|
|
case 'x':
|
|
|
|
skip_acls = true;
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(pgdumpopts, " -x");
|
2003-05-31 01:55:10 +02:00
|
|
|
break;
|
|
|
|
|
2004-07-12 16:35:45 +02:00
|
|
|
case 0:
|
|
|
|
break;
|
|
|
|
|
2008-08-29 19:28:43 +02:00
|
|
|
case 2:
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(pgdumpopts, " --lock-wait-timeout ");
|
2016-08-08 16:07:46 +02:00
|
|
|
appendShellString(pgdumpopts, optarg);
|
2009-01-05 17:54:37 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 3:
|
2012-10-12 19:35:40 +02:00
|
|
|
use_role = pg_strdup(optarg);
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(pgdumpopts, " --role ");
|
2016-08-08 16:07:46 +02:00
|
|
|
appendShellString(pgdumpopts, use_role);
|
2008-08-29 19:28:43 +02:00
|
|
|
break;
|
|
|
|
|
2017-03-22 15:00:30 +01:00
|
|
|
case 4:
|
|
|
|
dosync = false;
|
|
|
|
appendPQExpBufferStr(pgdumpopts, " --no-sync");
|
|
|
|
break;
|
|
|
|
|
2019-02-18 13:22:00 +01:00
|
|
|
case 5:
|
|
|
|
appendPQExpBufferStr(pgdumpopts, " --extra-float-digits ");
|
|
|
|
appendShellString(pgdumpopts, optarg);
|
|
|
|
break;
|
|
|
|
|
2019-03-01 16:47:44 +01:00
|
|
|
case 6:
|
|
|
|
simple_string_list_append(&database_exclude_patterns, optarg);
|
|
|
|
break;
|
|
|
|
|
2019-06-15 00:21:52 +02:00
|
|
|
case 7:
|
|
|
|
appendPQExpBufferStr(pgdumpopts, " --rows-per-insert ");
|
|
|
|
appendShellString(pgdumpopts, optarg);
|
|
|
|
break;
|
|
|
|
|
Read include/exclude commands for dump/restore from file
When there is a need to filter multiple tables with include and/or exclude
options it's quite possible to run into the limitations of the commandline.
This adds a --filter=FILENAME feature to pg_dump, pg_dumpall and pg_restore
which is used to supply a file containing object exclude/include commands
which work just like their commandline counterparts. The format of the file
is one command per row like:
<command> <object> <objectpattern>
<command> can be "include" or "exclude", <object> can be table_data, index
table_data_and_children, database, extension, foreign_data, function, table
schema, table_and_children or trigger.
This patch has gone through many revisions and design changes over a long
period of time, the list of reviewers reflect reviewers of some version of
the patch, not necessarily the final version.
Patch by Pavel Stehule with some additional hacking by me.
Author: Pavel Stehule <pavel.stehule@gmail.com>
Reviewed-by: Justin Pryzby <pryzby@telsasoft.com>
Reviewed-by: vignesh C <vignesh21@gmail.com>
Reviewed-by: Dean Rasheed <dean.a.rasheed@gmail.com>
Reviewed-by: Tomas Vondra <tomas.vondra@enterprisedb.com>
Reviewed-by: Julien Rouhaud <rjuju123@gmail.com>
Reviewed-by: Erik Rijkers <er@xs4all.nl>
Discussion: https://postgr.es/m/CAFj8pRB10wvW0CC9Xq=1XDs=zCQxer3cbLcNZa+qiX4cUH-G_A@mail.gmail.com
2023-11-29 14:56:24 +01:00
|
|
|
case 8:
|
|
|
|
read_dumpall_filters(optarg, &database_exclude_patterns);
|
|
|
|
break;
|
|
|
|
|
2002-08-27 20:57:26 +02:00
|
|
|
default:
|
2022-04-08 20:55:14 +02:00
|
|
|
/* getopt_long already emitted a complaint */
|
|
|
|
pg_log_error_hint("Try \"%s --help\" for more information.", progname);
|
2012-02-16 17:49:20 +01:00
|
|
|
exit_nicely(1);
|
2002-08-27 20:57:26 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-13 16:38:04 +02:00
|
|
|
/* Complain if any arguments remain */
|
2002-08-27 20:57:26 +02:00
|
|
|
if (optind < argc)
|
|
|
|
{
|
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
|
|
|
pg_log_error("too many command-line arguments (first is \"%s\")",
|
|
|
|
argv[optind]);
|
2022-04-08 20:55:14 +02:00
|
|
|
pg_log_error_hint("Try \"%s --help\" for more information.", progname);
|
2012-02-16 17:49:20 +01:00
|
|
|
exit_nicely(1);
|
2002-08-27 20:57:26 +02:00
|
|
|
}
|
2007-11-15 22:14:46 +01:00
|
|
|
|
2019-03-01 16:47:44 +01:00
|
|
|
if (database_exclude_patterns.head != NULL &&
|
|
|
|
(globals_only || roles_only || tablespaces_only))
|
|
|
|
{
|
2019-07-01 13:07:14 +02:00
|
|
|
pg_log_error("option --exclude-database cannot be used together with -g/--globals-only, -r/--roles-only, or -t/--tablespaces-only");
|
2022-04-08 20:55:14 +02:00
|
|
|
pg_log_error_hint("Try \"%s --help\" for more information.", progname);
|
2019-03-01 16:47:44 +01:00
|
|
|
exit_nicely(1);
|
|
|
|
}
|
|
|
|
|
2007-01-25 03:30:32 +01:00
|
|
|
/* Make sure the user hasn't specified a mix of globals-only options */
|
|
|
|
if (globals_only && roles_only)
|
|
|
|
{
|
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
|
|
|
pg_log_error("options -g/--globals-only and -r/--roles-only cannot be used together");
|
2022-04-08 20:55:14 +02:00
|
|
|
pg_log_error_hint("Try \"%s --help\" for more information.", progname);
|
2012-02-16 17:49:20 +01:00
|
|
|
exit_nicely(1);
|
2007-01-25 03:30:32 +01:00
|
|
|
}
|
2007-11-15 22:14:46 +01:00
|
|
|
|
2007-01-25 03:30:32 +01:00
|
|
|
if (globals_only && tablespaces_only)
|
|
|
|
{
|
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
|
|
|
pg_log_error("options -g/--globals-only and -t/--tablespaces-only cannot be used together");
|
2022-04-08 20:55:14 +02:00
|
|
|
pg_log_error_hint("Try \"%s --help\" for more information.", progname);
|
2012-02-16 17:49:20 +01:00
|
|
|
exit_nicely(1);
|
2007-01-25 03:30:32 +01:00
|
|
|
}
|
2007-11-15 22:14:46 +01:00
|
|
|
|
2014-03-03 19:02:18 +01:00
|
|
|
if (if_exists && !output_clean)
|
2022-04-08 20:55:14 +02:00
|
|
|
pg_fatal("option --if-exists requires option -c/--clean");
|
2014-03-03 19:02:18 +01:00
|
|
|
|
2007-01-25 03:30:32 +01:00
|
|
|
if (roles_only && tablespaces_only)
|
|
|
|
{
|
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
|
|
|
pg_log_error("options -r/--roles-only and -t/--tablespaces-only cannot be used together");
|
2022-04-08 20:55:14 +02:00
|
|
|
pg_log_error_hint("Try \"%s --help\" for more information.", progname);
|
2012-02-16 17:49:20 +01:00
|
|
|
exit_nicely(1);
|
2007-01-25 03:30:32 +01:00
|
|
|
}
|
2002-08-27 20:57:26 +02:00
|
|
|
|
2017-03-07 15:00:54 +01:00
|
|
|
/*
|
|
|
|
* If password values are not required in the dump, switch to using
|
|
|
|
* pg_roles which is equally useful, just more likely to have unrestricted
|
|
|
|
* access than pg_authid.
|
|
|
|
*/
|
|
|
|
if (no_role_passwords)
|
|
|
|
sprintf(role_catalog, "%s", PG_ROLES);
|
|
|
|
else
|
|
|
|
sprintf(role_catalog, "%s", PG_AUTHID);
|
|
|
|
|
2010-08-13 16:38:04 +02:00
|
|
|
/* Add long options to the pg_dump argument list */
|
|
|
|
if (binary_upgrade)
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(pgdumpopts, " --binary-upgrade");
|
2010-08-13 16:38:04 +02:00
|
|
|
if (column_inserts)
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(pgdumpopts, " --column-inserts");
|
2010-08-13 16:38:04 +02:00
|
|
|
if (disable_dollar_quoting)
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(pgdumpopts, " --disable-dollar-quoting");
|
2010-08-13 16:38:04 +02:00
|
|
|
if (disable_triggers)
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(pgdumpopts, " --disable-triggers");
|
2010-08-13 16:38:04 +02:00
|
|
|
if (inserts)
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(pgdumpopts, " --inserts");
|
2022-01-17 06:51:46 +01:00
|
|
|
if (no_table_access_method)
|
|
|
|
appendPQExpBufferStr(pgdumpopts, " --no-table-access-method");
|
2010-08-13 16:38:04 +02:00
|
|
|
if (no_tablespaces)
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(pgdumpopts, " --no-tablespaces");
|
2010-08-13 16:38:04 +02:00
|
|
|
if (quote_all_identifiers)
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(pgdumpopts, " --quote-all-identifiers");
|
2017-08-15 04:54:41 +02:00
|
|
|
if (load_via_partition_root)
|
|
|
|
appendPQExpBufferStr(pgdumpopts, " --load-via-partition-root");
|
2010-08-13 16:38:04 +02:00
|
|
|
if (use_setsessauth)
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(pgdumpopts, " --use-set-session-authorization");
|
Support --no-comments in pg_dump, pg_dumpall, pg_restore.
We have switches already to suppress other subsidiary object properties,
such as ACLs, security labels, ownership, and tablespaces, so just on
the grounds of symmetry we should allow suppressing comments as well.
Also, commit 0d4e6ed30 added a positive reason to have this feature,
i.e. to allow obtaining the old behavior of selective pg_restore should
anyone desire that.
Recent commits have removed the cases where pg_dump emitted comments on
built-in objects that the restoring user might not have privileges to
comment on, so the original primary motivation for this feature is gone,
but it still seems at least somewhat useful in its own right.
Robins Tharakan, reviewed by Fabrízio Mello
Discussion: https://postgr.es/m/CAEP4nAx22Z4ch74oJGzr5RyyjcyUSbpiFLyeYXX8pehfou92ug@mail.gmail.com
2018-01-25 21:27:24 +01:00
|
|
|
if (no_comments)
|
|
|
|
appendPQExpBufferStr(pgdumpopts, " --no-comments");
|
2017-05-12 15:15:40 +02:00
|
|
|
if (no_publications)
|
|
|
|
appendPQExpBufferStr(pgdumpopts, " --no-publications");
|
2011-05-19 22:20:11 +02:00
|
|
|
if (no_security_labels)
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(pgdumpopts, " --no-security-labels");
|
2017-05-09 16:58:06 +02:00
|
|
|
if (no_subscriptions)
|
|
|
|
appendPQExpBufferStr(pgdumpopts, " --no-subscriptions");
|
2021-05-19 02:38:48 +02:00
|
|
|
if (no_toast_compression)
|
|
|
|
appendPQExpBufferStr(pgdumpopts, " --no-toast-compression");
|
2010-12-29 12:48:53 +01:00
|
|
|
if (no_unlogged_table_data)
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(pgdumpopts, " --no-unlogged-table-data");
|
2018-07-13 03:57:03 +02:00
|
|
|
if (on_conflict_do_nothing)
|
|
|
|
appendPQExpBufferStr(pgdumpopts, " --on-conflict-do-nothing");
|
2010-08-13 16:38:04 +02:00
|
|
|
|
2005-07-08 18:51:30 +02:00
|
|
|
/*
|
2007-01-25 03:46:33 +01:00
|
|
|
* If there was a database specified on the command line, use that,
|
|
|
|
* otherwise try to connect to database "postgres", and failing that
|
2021-12-14 23:09:07 +01:00
|
|
|
* "template1".
|
2005-07-08 18:51:30 +02:00
|
|
|
*/
|
2007-01-25 03:46:33 +01:00
|
|
|
if (pgdb)
|
|
|
|
{
|
2013-02-25 18:39:10 +01:00
|
|
|
conn = connectDatabase(pgdb, connstr, pghost, pgport, pguser,
|
2009-02-26 17:02:39 +01:00
|
|
|
prompt_password, false);
|
2007-11-15 22:14:46 +01:00
|
|
|
|
2007-01-25 03:46:33 +01:00
|
|
|
if (!conn)
|
2022-04-08 20:55:14 +02:00
|
|
|
pg_fatal("could not connect to database \"%s\"", pgdb);
|
2007-01-25 03:46:33 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-02-25 18:39:10 +01:00
|
|
|
conn = connectDatabase("postgres", connstr, pghost, pgport, pguser,
|
2009-02-26 17:02:39 +01:00
|
|
|
prompt_password, false);
|
2007-01-25 03:46:33 +01:00
|
|
|
if (!conn)
|
2013-02-25 18:39:10 +01:00
|
|
|
conn = connectDatabase("template1", connstr, pghost, pgport, pguser,
|
2009-02-26 17:02:39 +01:00
|
|
|
prompt_password, true);
|
2007-11-15 22:14:46 +01:00
|
|
|
|
2007-01-25 03:46:33 +01:00
|
|
|
if (!conn)
|
|
|
|
{
|
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
|
|
|
pg_log_error("could not connect to databases \"postgres\" or \"template1\"\n"
|
|
|
|
"Please specify an alternative database.");
|
2022-04-08 20:55:14 +02:00
|
|
|
pg_log_error_hint("Try \"%s --help\" for more information.", progname);
|
2012-02-16 17:49:20 +01:00
|
|
|
exit_nicely(1);
|
2007-01-25 03:46:33 +01:00
|
|
|
}
|
|
|
|
}
|
2007-11-15 22:14:46 +01:00
|
|
|
|
2019-03-01 16:47:44 +01:00
|
|
|
/*
|
|
|
|
* Get a list of database names that match the exclude patterns
|
|
|
|
*/
|
|
|
|
expand_dbname_patterns(conn, &database_exclude_patterns,
|
|
|
|
&database_exclude_names);
|
|
|
|
|
2007-01-25 04:30:43 +01:00
|
|
|
/*
|
|
|
|
* Open the output file if required, otherwise use stdout
|
|
|
|
*/
|
|
|
|
if (filename)
|
|
|
|
{
|
|
|
|
OPF = fopen(filename, PG_BINARY_W);
|
|
|
|
if (!OPF)
|
2022-04-08 20:55:14 +02:00
|
|
|
pg_fatal("could not open output file \"%s\": %m",
|
|
|
|
filename);
|
2007-01-25 04:30:43 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
OPF = stdout;
|
2002-08-27 20:57:26 +02:00
|
|
|
|
2017-09-01 18:23:16 +02:00
|
|
|
/*
|
|
|
|
* Set the client encoding if requested.
|
|
|
|
*/
|
|
|
|
if (dumpencoding)
|
|
|
|
{
|
|
|
|
if (PQsetClientEncoding(conn, dumpencoding) < 0)
|
2022-04-08 20:55:14 +02:00
|
|
|
pg_fatal("invalid client encoding \"%s\" specified",
|
|
|
|
dumpencoding);
|
2017-09-01 18:23:16 +02:00
|
|
|
}
|
|
|
|
|
2006-05-28 23:13:54 +02:00
|
|
|
/*
|
|
|
|
* Get the active encoding and the standard_conforming_strings setting, so
|
|
|
|
* we know how to escape strings.
|
|
|
|
*/
|
|
|
|
encoding = PQclientEncoding(conn);
|
|
|
|
std_strings = PQparameterStatus(conn, "standard_conforming_strings");
|
|
|
|
if (!std_strings)
|
|
|
|
std_strings = "off";
|
|
|
|
|
2009-01-05 17:54:37 +01:00
|
|
|
/* Set the role if requested */
|
2021-12-14 23:09:07 +01:00
|
|
|
if (use_role)
|
2009-01-05 17:54:37 +01:00
|
|
|
{
|
|
|
|
PQExpBuffer query = createPQExpBuffer();
|
|
|
|
|
|
|
|
appendPQExpBuffer(query, "SET ROLE %s", fmtId(use_role));
|
|
|
|
executeCommand(conn, query->data);
|
|
|
|
destroyPQExpBuffer(query);
|
|
|
|
}
|
|
|
|
|
2010-07-22 03:22:35 +02:00
|
|
|
/* Force quoting of all identifiers if requested. */
|
2021-12-14 23:09:07 +01:00
|
|
|
if (quote_all_identifiers)
|
2010-07-22 03:22:35 +02:00
|
|
|
executeCommand(conn, "SET quote_all_identifiers = true");
|
|
|
|
|
2007-01-25 04:30:43 +01:00
|
|
|
fprintf(OPF, "--\n-- PostgreSQL database cluster dump\n--\n\n");
|
2004-06-07 22:35:57 +02:00
|
|
|
if (verbose)
|
|
|
|
dumpTimestamp("Started on");
|
|
|
|
|
2011-10-28 21:45:28 +02:00
|
|
|
/*
|
|
|
|
* We used to emit \connect postgres here, but that served no purpose
|
|
|
|
* other than to break things for installations without a postgres
|
|
|
|
* database. Everything we're restoring here is a global, so whichever
|
|
|
|
* database we're connected to at the moment is fine.
|
|
|
|
*/
|
2002-08-27 20:57:26 +02:00
|
|
|
|
2013-11-30 18:24:56 +01:00
|
|
|
/* Restore will need to write to the target cluster */
|
|
|
|
fprintf(OPF, "SET default_transaction_read_only = off;\n\n");
|
|
|
|
|
2009-04-11 22:23:05 +02:00
|
|
|
/* Replicate encoding and std_strings in output */
|
|
|
|
fprintf(OPF, "SET client_encoding = '%s';\n",
|
|
|
|
pg_encoding_to_char(encoding));
|
|
|
|
fprintf(OPF, "SET standard_conforming_strings = %s;\n", std_strings);
|
|
|
|
if (strcmp(std_strings, "off") == 0)
|
|
|
|
fprintf(OPF, "SET escape_string_warning = off;\n");
|
|
|
|
fprintf(OPF, "\n");
|
|
|
|
|
2003-05-31 01:55:10 +02:00
|
|
|
if (!data_only)
|
|
|
|
{
|
2009-04-11 22:23:05 +02:00
|
|
|
/*
|
|
|
|
* If asked to --clean, do that first. We can avoid detailed
|
|
|
|
* dependency analysis because databases never depend on each other,
|
|
|
|
* and tablespaces never depend on each other. Roles could have
|
|
|
|
* grants to each other, but DROP ROLE will clean those up silently.
|
|
|
|
*/
|
|
|
|
if (output_clean)
|
|
|
|
{
|
|
|
|
if (!globals_only && !roles_only && !tablespaces_only)
|
|
|
|
dropDBs(conn);
|
2006-05-28 23:13:54 +02:00
|
|
|
|
2009-04-11 22:23:05 +02:00
|
|
|
if (!roles_only && !no_tablespaces)
|
2016-10-12 18:19:56 +02:00
|
|
|
dropTablespaces(conn);
|
2009-04-11 22:23:05 +02:00
|
|
|
|
|
|
|
if (!tablespaces_only)
|
|
|
|
dropRoles(conn);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Now create objects as requested. Be careful that option logic here
|
|
|
|
* is the same as for drops above.
|
|
|
|
*/
|
2007-01-25 03:30:32 +01:00
|
|
|
if (!tablespaces_only)
|
|
|
|
{
|
|
|
|
/* Dump roles (users) */
|
|
|
|
dumpRoles(conn);
|
|
|
|
|
2021-12-14 23:09:07 +01:00
|
|
|
/* Dump role memberships */
|
|
|
|
dumpRoleMembership(conn);
|
2022-04-06 19:24:33 +02:00
|
|
|
|
|
|
|
/* Dump role GUC privileges */
|
|
|
|
if (server_version >= 150000 && !skip_acls)
|
|
|
|
dumpRoleGUCPrivs(conn);
|
2007-01-25 03:30:32 +01:00
|
|
|
}
|
2005-07-31 19:19:22 +02:00
|
|
|
|
2016-10-12 18:19:56 +02:00
|
|
|
/* Dump tablespaces */
|
2008-03-20 18:36:58 +01:00
|
|
|
if (!roles_only && !no_tablespaces)
|
2016-10-12 18:19:56 +02:00
|
|
|
dumpTablespaces(conn);
|
2003-05-31 01:55:10 +02:00
|
|
|
}
|
2002-08-27 20:57:26 +02:00
|
|
|
|
2007-01-25 03:30:32 +01:00
|
|
|
if (!globals_only && !roles_only && !tablespaces_only)
|
2003-05-31 01:55:10 +02:00
|
|
|
dumpDatabases(conn);
|
2002-08-27 20:57:26 +02:00
|
|
|
|
|
|
|
PQfinish(conn);
|
2004-05-19 23:21:26 +02:00
|
|
|
|
2004-06-07 22:35:57 +02:00
|
|
|
if (verbose)
|
|
|
|
dumpTimestamp("Completed on");
|
2007-01-25 04:30:43 +01:00
|
|
|
fprintf(OPF, "--\n-- PostgreSQL database cluster dump complete\n--\n\n");
|
2007-11-15 22:14:46 +01:00
|
|
|
|
2007-01-25 04:30:43 +01:00
|
|
|
if (filename)
|
2017-03-22 15:00:30 +01:00
|
|
|
{
|
2007-01-25 04:30:43 +01:00
|
|
|
fclose(OPF);
|
2004-05-19 23:21:26 +02:00
|
|
|
|
2017-03-22 15:00:30 +01:00
|
|
|
/* sync the resulting file, errors are not fatal */
|
|
|
|
if (dosync)
|
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
|
|
|
(void) fsync_fname(filename, false);
|
2017-03-22 15:00:30 +01:00
|
|
|
}
|
|
|
|
|
2012-02-16 17:49:20 +01:00
|
|
|
exit_nicely(0);
|
2002-08-27 20:57:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
help(void)
|
|
|
|
{
|
|
|
|
printf(_("%s extracts a PostgreSQL database cluster into an SQL script file.\n\n"), progname);
|
|
|
|
printf(_("Usage:\n"));
|
2002-10-19 00:05:36 +02:00
|
|
|
printf(_(" %s [OPTION]...\n"), progname);
|
2002-08-27 20:57:26 +02:00
|
|
|
|
2004-07-19 23:39:48 +02:00
|
|
|
printf(_("\nGeneral options:\n"));
|
2012-05-18 19:34:14 +02:00
|
|
|
printf(_(" -f, --file=FILENAME output file name\n"));
|
2016-12-24 07:41:59 +01:00
|
|
|
printf(_(" -v, --verbose verbose mode\n"));
|
2012-06-18 01:44:00 +02:00
|
|
|
printf(_(" -V, --version output version information, then exit\n"));
|
2012-05-18 19:34:14 +02:00
|
|
|
printf(_(" --lock-wait-timeout=TIMEOUT fail after waiting TIMEOUT for a table lock\n"));
|
2012-06-18 01:44:00 +02:00
|
|
|
printf(_(" -?, --help show this help, then exit\n"));
|
2004-07-19 23:39:48 +02:00
|
|
|
printf(_("\nOptions controlling the output content:\n"));
|
2012-05-18 19:34:14 +02:00
|
|
|
printf(_(" -a, --data-only dump only the data, not the schema\n"));
|
|
|
|
printf(_(" -c, --clean clean (drop) databases before recreating\n"));
|
2017-09-01 18:23:16 +02:00
|
|
|
printf(_(" -E, --encoding=ENCODING dump the data in encoding ENCODING\n"));
|
2012-05-18 19:34:14 +02:00
|
|
|
printf(_(" -g, --globals-only dump only global objects, no databases\n"));
|
|
|
|
printf(_(" -O, --no-owner skip restoration of object ownership\n"));
|
|
|
|
printf(_(" -r, --roles-only dump only roles, no databases or tablespaces\n"));
|
|
|
|
printf(_(" -s, --schema-only dump only the schema, no data\n"));
|
|
|
|
printf(_(" -S, --superuser=NAME superuser user name to use in the dump\n"));
|
|
|
|
printf(_(" -t, --tablespaces-only dump only tablespaces, no databases or roles\n"));
|
|
|
|
printf(_(" -x, --no-privileges do not dump privileges (grant/revoke)\n"));
|
|
|
|
printf(_(" --binary-upgrade for use by upgrade utilities only\n"));
|
|
|
|
printf(_(" --column-inserts dump data as INSERT commands with column names\n"));
|
|
|
|
printf(_(" --disable-dollar-quoting disable dollar quoting, use SQL standard quoting\n"));
|
|
|
|
printf(_(" --disable-triggers disable triggers during data-only restore\n"));
|
2019-03-01 16:47:44 +01:00
|
|
|
printf(_(" --exclude-database=PATTERN exclude databases whose name matches PATTERN\n"));
|
2019-02-18 13:22:00 +01:00
|
|
|
printf(_(" --extra-float-digits=NUM override default setting for extra_float_digits\n"));
|
Read include/exclude commands for dump/restore from file
When there is a need to filter multiple tables with include and/or exclude
options it's quite possible to run into the limitations of the commandline.
This adds a --filter=FILENAME feature to pg_dump, pg_dumpall and pg_restore
which is used to supply a file containing object exclude/include commands
which work just like their commandline counterparts. The format of the file
is one command per row like:
<command> <object> <objectpattern>
<command> can be "include" or "exclude", <object> can be table_data, index
table_data_and_children, database, extension, foreign_data, function, table
schema, table_and_children or trigger.
This patch has gone through many revisions and design changes over a long
period of time, the list of reviewers reflect reviewers of some version of
the patch, not necessarily the final version.
Patch by Pavel Stehule with some additional hacking by me.
Author: Pavel Stehule <pavel.stehule@gmail.com>
Reviewed-by: Justin Pryzby <pryzby@telsasoft.com>
Reviewed-by: vignesh C <vignesh21@gmail.com>
Reviewed-by: Dean Rasheed <dean.a.rasheed@gmail.com>
Reviewed-by: Tomas Vondra <tomas.vondra@enterprisedb.com>
Reviewed-by: Julien Rouhaud <rjuju123@gmail.com>
Reviewed-by: Erik Rijkers <er@xs4all.nl>
Discussion: https://postgr.es/m/CAFj8pRB10wvW0CC9Xq=1XDs=zCQxer3cbLcNZa+qiX4cUH-G_A@mail.gmail.com
2023-11-29 14:56:24 +01:00
|
|
|
printf(_(" --filter=FILENAME exclude databases specified in FILENAME\n"));
|
2014-03-03 19:02:18 +01:00
|
|
|
printf(_(" --if-exists use IF EXISTS when dropping objects\n"));
|
2012-05-18 19:34:14 +02:00
|
|
|
printf(_(" --inserts dump data as INSERT commands, rather than COPY\n"));
|
2018-06-04 21:03:15 +02:00
|
|
|
printf(_(" --load-via-partition-root load partitions via the root table\n"));
|
Support --no-comments in pg_dump, pg_dumpall, pg_restore.
We have switches already to suppress other subsidiary object properties,
such as ACLs, security labels, ownership, and tablespaces, so just on
the grounds of symmetry we should allow suppressing comments as well.
Also, commit 0d4e6ed30 added a positive reason to have this feature,
i.e. to allow obtaining the old behavior of selective pg_restore should
anyone desire that.
Recent commits have removed the cases where pg_dump emitted comments on
built-in objects that the restoring user might not have privileges to
comment on, so the original primary motivation for this feature is gone,
but it still seems at least somewhat useful in its own right.
Robins Tharakan, reviewed by Fabrízio Mello
Discussion: https://postgr.es/m/CAEP4nAx22Z4ch74oJGzr5RyyjcyUSbpiFLyeYXX8pehfou92ug@mail.gmail.com
2018-01-25 21:27:24 +01:00
|
|
|
printf(_(" --no-comments do not dump comments\n"));
|
2017-05-12 15:15:40 +02:00
|
|
|
printf(_(" --no-publications do not dump publications\n"));
|
2017-06-08 18:12:31 +02:00
|
|
|
printf(_(" --no-role-passwords do not dump passwords for roles\n"));
|
2012-05-18 19:34:14 +02:00
|
|
|
printf(_(" --no-security-labels do not dump security label assignments\n"));
|
2017-05-09 16:58:06 +02:00
|
|
|
printf(_(" --no-subscriptions do not dump subscriptions\n"));
|
2017-03-22 15:00:30 +01:00
|
|
|
printf(_(" --no-sync do not wait for changes to be written safely to disk\n"));
|
2022-01-17 08:03:12 +01:00
|
|
|
printf(_(" --no-table-access-method do not dump table access methods\n"));
|
2012-05-18 19:34:14 +02:00
|
|
|
printf(_(" --no-tablespaces do not dump tablespace assignments\n"));
|
2021-05-19 02:38:48 +02:00
|
|
|
printf(_(" --no-toast-compression do not dump TOAST compression methods\n"));
|
2012-05-18 19:34:14 +02:00
|
|
|
printf(_(" --no-unlogged-table-data do not dump unlogged table data\n"));
|
2018-07-13 03:57:03 +02:00
|
|
|
printf(_(" --on-conflict-do-nothing add ON CONFLICT DO NOTHING to INSERT commands\n"));
|
2012-05-18 19:34:14 +02:00
|
|
|
printf(_(" --quote-all-identifiers quote all identifiers, even if not key words\n"));
|
2019-06-15 00:21:52 +02:00
|
|
|
printf(_(" --rows-per-insert=NROWS number of rows per INSERT; implies --inserts\n"));
|
2006-10-07 22:59:05 +02:00
|
|
|
printf(_(" --use-set-session-authorization\n"
|
2012-05-18 19:34:14 +02:00
|
|
|
" use SET SESSION AUTHORIZATION commands instead of\n"
|
|
|
|
" ALTER OWNER commands to set ownership\n"));
|
2002-10-19 00:05:36 +02:00
|
|
|
|
|
|
|
printf(_("\nConnection options:\n"));
|
2013-02-25 18:39:10 +01:00
|
|
|
printf(_(" -d, --dbname=CONNSTR connect using connection string\n"));
|
2003-06-11 07:13:12 +02:00
|
|
|
printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
|
2009-02-25 14:03:07 +01:00
|
|
|
printf(_(" -l, --database=DBNAME alternative default database\n"));
|
2002-10-19 00:05:36 +02:00
|
|
|
printf(_(" -p, --port=PORT database server port number\n"));
|
|
|
|
printf(_(" -U, --username=NAME connect as specified database user\n"));
|
2009-02-26 17:02:39 +01:00
|
|
|
printf(_(" -w, --no-password never prompt for password\n"));
|
2002-10-19 00:05:36 +02:00
|
|
|
printf(_(" -W, --password force password prompt (should happen automatically)\n"));
|
2011-05-25 20:53:26 +02:00
|
|
|
printf(_(" --role=ROLENAME do SET ROLE before dump\n"));
|
2002-08-27 20:57:26 +02:00
|
|
|
|
2009-02-25 14:03:07 +01:00
|
|
|
printf(_("\nIf -f/--file is not used, then the SQL script will be written to the standard\n"
|
|
|
|
"output.\n\n"));
|
2020-02-28 08:54:49 +01:00
|
|
|
printf(_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT);
|
2020-02-28 08:54:49 +01:00
|
|
|
printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
|
2002-08-27 20:57:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-04-11 22:23:05 +02:00
|
|
|
/*
|
|
|
|
* Drop roles
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
dropRoles(PGconn *conn)
|
|
|
|
{
|
2017-03-07 15:00:54 +01:00
|
|
|
PQExpBuffer buf = createPQExpBuffer();
|
2009-04-11 22:23:05 +02:00
|
|
|
PGresult *res;
|
|
|
|
int i_rolname;
|
|
|
|
int i;
|
|
|
|
|
2016-05-25 05:31:55 +02:00
|
|
|
if (server_version >= 90600)
|
2017-03-07 15:00:54 +01:00
|
|
|
printfPQExpBuffer(buf,
|
2016-05-25 05:31:55 +02:00
|
|
|
"SELECT rolname "
|
2017-03-07 15:00:54 +01:00
|
|
|
"FROM %s "
|
2016-05-25 05:31:55 +02:00
|
|
|
"WHERE rolname !~ '^pg_' "
|
2017-03-07 15:00:54 +01:00
|
|
|
"ORDER BY 1", role_catalog);
|
2021-12-14 23:09:07 +01:00
|
|
|
else
|
2017-03-07 15:00:54 +01:00
|
|
|
printfPQExpBuffer(buf,
|
2009-04-11 22:23:05 +02:00
|
|
|
"SELECT rolname "
|
2017-03-07 15:00:54 +01:00
|
|
|
"FROM %s "
|
|
|
|
"ORDER BY 1", role_catalog);
|
2009-04-11 22:23:05 +02:00
|
|
|
|
2017-03-07 15:00:54 +01:00
|
|
|
res = executeQuery(conn, buf->data);
|
|
|
|
|
2009-04-11 22:23:05 +02:00
|
|
|
i_rolname = PQfnumber(res, "rolname");
|
|
|
|
|
|
|
|
if (PQntuples(res) > 0)
|
|
|
|
fprintf(OPF, "--\n-- Drop roles\n--\n\n");
|
|
|
|
|
|
|
|
for (i = 0; i < PQntuples(res); i++)
|
|
|
|
{
|
|
|
|
const char *rolename;
|
|
|
|
|
|
|
|
rolename = PQgetvalue(res, i, i_rolname);
|
|
|
|
|
2014-03-03 19:02:18 +01:00
|
|
|
fprintf(OPF, "DROP ROLE %s%s;\n",
|
|
|
|
if_exists ? "IF EXISTS " : "",
|
|
|
|
fmtId(rolename));
|
2009-04-11 22:23:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
PQclear(res);
|
2017-03-07 15:00:54 +01:00
|
|
|
destroyPQExpBuffer(buf);
|
2009-04-11 22:23:05 +02:00
|
|
|
|
|
|
|
fprintf(OPF, "\n\n");
|
|
|
|
}
|
2002-08-27 20:57:26 +02:00
|
|
|
|
|
|
|
/*
|
2005-07-31 19:19:22 +02:00
|
|
|
* Dump roles
|
2002-08-27 20:57:26 +02:00
|
|
|
*/
|
|
|
|
static void
|
2005-10-11 00:29:48 +02:00
|
|
|
dumpRoles(PGconn *conn)
|
2002-08-27 20:57:26 +02:00
|
|
|
{
|
2005-07-08 18:51:30 +02:00
|
|
|
PQExpBuffer buf = createPQExpBuffer();
|
2002-08-27 20:57:26 +02:00
|
|
|
PGresult *res;
|
2011-01-08 03:59:29 +01:00
|
|
|
int i_oid,
|
|
|
|
i_rolname,
|
2005-07-31 19:19:22 +02:00
|
|
|
i_rolsuper,
|
|
|
|
i_rolinherit,
|
|
|
|
i_rolcreaterole,
|
|
|
|
i_rolcreatedb,
|
|
|
|
i_rolcanlogin,
|
|
|
|
i_rolconnlimit,
|
|
|
|
i_rolpassword,
|
2006-02-12 04:22:21 +01:00
|
|
|
i_rolvaliduntil,
|
2010-12-29 11:05:03 +01:00
|
|
|
i_rolreplication,
|
Row-Level Security Policies (RLS)
Building on the updatable security-barrier views work, add the
ability to define policies on tables to limit the set of rows
which are returned from a query and which are allowed to be added
to a table. Expressions defined by the policy for filtering are
added to the security barrier quals of the query, while expressions
defined to check records being added to a table are added to the
with-check options of the query.
New top-level commands are CREATE/ALTER/DROP POLICY and are
controlled by the table owner. Row Security is able to be enabled
and disabled by the owner on a per-table basis using
ALTER TABLE .. ENABLE/DISABLE ROW SECURITY.
Per discussion, ROW SECURITY is disabled on tables by default and
must be enabled for policies on the table to be used. If no
policies exist on a table with ROW SECURITY enabled, a default-deny
policy is used and no records will be visible.
By default, row security is applied at all times except for the
table owner and the superuser. A new GUC, row_security, is added
which can be set to ON, OFF, or FORCE. When set to FORCE, row
security will be applied even for the table owner and superusers.
When set to OFF, row security will be disabled when allowed and an
error will be thrown if the user does not have rights to bypass row
security.
Per discussion, pg_dump sets row_security = OFF by default to ensure
that exports and backups will have all data in the table or will
error if there are insufficient privileges to bypass row security.
A new option has been added to pg_dump, --enable-row-security, to
ask pg_dump to export with row security enabled.
A new role capability, BYPASSRLS, which can only be set by the
superuser, is added to allow other users to be able to bypass row
security using row_security = OFF.
Many thanks to the various individuals who have helped with the
design, particularly Robert Haas for his feedback.
Authors include Craig Ringer, KaiGai Kohei, Adam Brightwell, Dean
Rasheed, with additional changes and rework by me.
Reviewers have included all of the above, Greg Smith,
Jeff McCormick, and Robert Haas.
2014-09-19 17:18:35 +02:00
|
|
|
i_rolbypassrls,
|
2012-12-04 01:43:02 +01:00
|
|
|
i_rolcomment,
|
|
|
|
i_is_current_user;
|
2002-08-27 20:57:26 +02:00
|
|
|
int i;
|
|
|
|
|
2024-03-21 23:31:57 +01:00
|
|
|
/*
|
|
|
|
* Notes: rolconfig is dumped later, and pg_authid must be used for
|
|
|
|
* extracting rolcomment regardless of role_catalog.
|
|
|
|
*/
|
2016-04-08 22:56:27 +02:00
|
|
|
if (server_version >= 90600)
|
Row-Level Security Policies (RLS)
Building on the updatable security-barrier views work, add the
ability to define policies on tables to limit the set of rows
which are returned from a query and which are allowed to be added
to a table. Expressions defined by the policy for filtering are
added to the security barrier quals of the query, while expressions
defined to check records being added to a table are added to the
with-check options of the query.
New top-level commands are CREATE/ALTER/DROP POLICY and are
controlled by the table owner. Row Security is able to be enabled
and disabled by the owner on a per-table basis using
ALTER TABLE .. ENABLE/DISABLE ROW SECURITY.
Per discussion, ROW SECURITY is disabled on tables by default and
must be enabled for policies on the table to be used. If no
policies exist on a table with ROW SECURITY enabled, a default-deny
policy is used and no records will be visible.
By default, row security is applied at all times except for the
table owner and the superuser. A new GUC, row_security, is added
which can be set to ON, OFF, or FORCE. When set to FORCE, row
security will be applied even for the table owner and superusers.
When set to OFF, row security will be disabled when allowed and an
error will be thrown if the user does not have rights to bypass row
security.
Per discussion, pg_dump sets row_security = OFF by default to ensure
that exports and backups will have all data in the table or will
error if there are insufficient privileges to bypass row security.
A new option has been added to pg_dump, --enable-row-security, to
ask pg_dump to export with row security enabled.
A new role capability, BYPASSRLS, which can only be set by the
superuser, is added to allow other users to be able to bypass row
security using row_security = OFF.
Many thanks to the various individuals who have helped with the
design, particularly Robert Haas for his feedback.
Authors include Craig Ringer, KaiGai Kohei, Adam Brightwell, Dean
Rasheed, with additional changes and rework by me.
Reviewers have included all of the above, Greg Smith,
Jeff McCormick, and Robert Haas.
2014-09-19 17:18:35 +02:00
|
|
|
printfPQExpBuffer(buf,
|
2014-12-23 19:35:49 +01:00
|
|
|
"SELECT oid, rolname, rolsuper, rolinherit, "
|
|
|
|
"rolcreaterole, rolcreatedb, "
|
|
|
|
"rolcanlogin, rolconnlimit, rolpassword, "
|
|
|
|
"rolvaliduntil, rolreplication, rolbypassrls, "
|
2024-03-21 23:31:57 +01:00
|
|
|
"pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, "
|
Row-Level Security Policies (RLS)
Building on the updatable security-barrier views work, add the
ability to define policies on tables to limit the set of rows
which are returned from a query and which are allowed to be added
to a table. Expressions defined by the policy for filtering are
added to the security barrier quals of the query, while expressions
defined to check records being added to a table are added to the
with-check options of the query.
New top-level commands are CREATE/ALTER/DROP POLICY and are
controlled by the table owner. Row Security is able to be enabled
and disabled by the owner on a per-table basis using
ALTER TABLE .. ENABLE/DISABLE ROW SECURITY.
Per discussion, ROW SECURITY is disabled on tables by default and
must be enabled for policies on the table to be used. If no
policies exist on a table with ROW SECURITY enabled, a default-deny
policy is used and no records will be visible.
By default, row security is applied at all times except for the
table owner and the superuser. A new GUC, row_security, is added
which can be set to ON, OFF, or FORCE. When set to FORCE, row
security will be applied even for the table owner and superusers.
When set to OFF, row security will be disabled when allowed and an
error will be thrown if the user does not have rights to bypass row
security.
Per discussion, pg_dump sets row_security = OFF by default to ensure
that exports and backups will have all data in the table or will
error if there are insufficient privileges to bypass row security.
A new option has been added to pg_dump, --enable-row-security, to
ask pg_dump to export with row security enabled.
A new role capability, BYPASSRLS, which can only be set by the
superuser, is added to allow other users to be able to bypass row
security using row_security = OFF.
Many thanks to the various individuals who have helped with the
design, particularly Robert Haas for his feedback.
Authors include Craig Ringer, KaiGai Kohei, Adam Brightwell, Dean
Rasheed, with additional changes and rework by me.
Reviewers have included all of the above, Greg Smith,
Jeff McCormick, and Robert Haas.
2014-09-19 17:18:35 +02:00
|
|
|
"rolname = current_user AS is_current_user "
|
2017-03-07 15:00:54 +01:00
|
|
|
"FROM %s "
|
2016-04-08 22:56:27 +02:00
|
|
|
"WHERE rolname !~ '^pg_' "
|
2024-03-21 23:31:57 +01:00
|
|
|
"ORDER BY 2", role_catalog);
|
2016-05-06 22:15:52 +02:00
|
|
|
else if (server_version >= 90500)
|
|
|
|
printfPQExpBuffer(buf,
|
|
|
|
"SELECT oid, rolname, rolsuper, rolinherit, "
|
|
|
|
"rolcreaterole, rolcreatedb, "
|
|
|
|
"rolcanlogin, rolconnlimit, rolpassword, "
|
|
|
|
"rolvaliduntil, rolreplication, rolbypassrls, "
|
2024-03-21 23:31:57 +01:00
|
|
|
"pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, "
|
2016-05-06 22:15:52 +02:00
|
|
|
"rolname = current_user AS is_current_user "
|
2017-03-07 15:00:54 +01:00
|
|
|
"FROM %s "
|
2024-03-21 23:31:57 +01:00
|
|
|
"ORDER BY 2", role_catalog);
|
2021-12-14 23:09:07 +01:00
|
|
|
else
|
2005-07-31 19:19:22 +02:00
|
|
|
printfPQExpBuffer(buf,
|
2011-01-08 03:59:29 +01:00
|
|
|
"SELECT oid, rolname, rolsuper, rolinherit, "
|
2011-04-11 21:28:45 +02:00
|
|
|
"rolcreaterole, rolcreatedb, "
|
2005-07-31 19:19:22 +02:00
|
|
|
"rolcanlogin, rolconnlimit, rolpassword, "
|
2010-12-29 11:05:03 +01:00
|
|
|
"rolvaliduntil, rolreplication, "
|
Row-Level Security Policies (RLS)
Building on the updatable security-barrier views work, add the
ability to define policies on tables to limit the set of rows
which are returned from a query and which are allowed to be added
to a table. Expressions defined by the policy for filtering are
added to the security barrier quals of the query, while expressions
defined to check records being added to a table are added to the
with-check options of the query.
New top-level commands are CREATE/ALTER/DROP POLICY and are
controlled by the table owner. Row Security is able to be enabled
and disabled by the owner on a per-table basis using
ALTER TABLE .. ENABLE/DISABLE ROW SECURITY.
Per discussion, ROW SECURITY is disabled on tables by default and
must be enabled for policies on the table to be used. If no
policies exist on a table with ROW SECURITY enabled, a default-deny
policy is used and no records will be visible.
By default, row security is applied at all times except for the
table owner and the superuser. A new GUC, row_security, is added
which can be set to ON, OFF, or FORCE. When set to FORCE, row
security will be applied even for the table owner and superusers.
When set to OFF, row security will be disabled when allowed and an
error will be thrown if the user does not have rights to bypass row
security.
Per discussion, pg_dump sets row_security = OFF by default to ensure
that exports and backups will have all data in the table or will
error if there are insufficient privileges to bypass row security.
A new option has been added to pg_dump, --enable-row-security, to
ask pg_dump to export with row security enabled.
A new role capability, BYPASSRLS, which can only be set by the
superuser, is added to allow other users to be able to bypass row
security using row_security = OFF.
Many thanks to the various individuals who have helped with the
design, particularly Robert Haas for his feedback.
Authors include Craig Ringer, KaiGai Kohei, Adam Brightwell, Dean
Rasheed, with additional changes and rework by me.
Reviewers have included all of the above, Greg Smith,
Jeff McCormick, and Robert Haas.
2014-09-19 17:18:35 +02:00
|
|
|
"false as rolbypassrls, "
|
2024-03-21 23:31:57 +01:00
|
|
|
"pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, "
|
2013-03-24 16:27:20 +01:00
|
|
|
"rolname = current_user AS is_current_user "
|
2017-03-07 15:00:54 +01:00
|
|
|
"FROM %s "
|
2024-03-21 23:31:57 +01:00
|
|
|
"ORDER BY 2", role_catalog);
|
2005-07-31 19:19:22 +02:00
|
|
|
|
|
|
|
res = executeQuery(conn, buf->data);
|
|
|
|
|
2011-01-08 03:59:29 +01:00
|
|
|
i_oid = PQfnumber(res, "oid");
|
2005-07-31 19:19:22 +02:00
|
|
|
i_rolname = PQfnumber(res, "rolname");
|
|
|
|
i_rolsuper = PQfnumber(res, "rolsuper");
|
|
|
|
i_rolinherit = PQfnumber(res, "rolinherit");
|
|
|
|
i_rolcreaterole = PQfnumber(res, "rolcreaterole");
|
|
|
|
i_rolcreatedb = PQfnumber(res, "rolcreatedb");
|
|
|
|
i_rolcanlogin = PQfnumber(res, "rolcanlogin");
|
|
|
|
i_rolconnlimit = PQfnumber(res, "rolconnlimit");
|
|
|
|
i_rolpassword = PQfnumber(res, "rolpassword");
|
|
|
|
i_rolvaliduntil = PQfnumber(res, "rolvaliduntil");
|
2010-12-29 11:05:03 +01:00
|
|
|
i_rolreplication = PQfnumber(res, "rolreplication");
|
Row-Level Security Policies (RLS)
Building on the updatable security-barrier views work, add the
ability to define policies on tables to limit the set of rows
which are returned from a query and which are allowed to be added
to a table. Expressions defined by the policy for filtering are
added to the security barrier quals of the query, while expressions
defined to check records being added to a table are added to the
with-check options of the query.
New top-level commands are CREATE/ALTER/DROP POLICY and are
controlled by the table owner. Row Security is able to be enabled
and disabled by the owner on a per-table basis using
ALTER TABLE .. ENABLE/DISABLE ROW SECURITY.
Per discussion, ROW SECURITY is disabled on tables by default and
must be enabled for policies on the table to be used. If no
policies exist on a table with ROW SECURITY enabled, a default-deny
policy is used and no records will be visible.
By default, row security is applied at all times except for the
table owner and the superuser. A new GUC, row_security, is added
which can be set to ON, OFF, or FORCE. When set to FORCE, row
security will be applied even for the table owner and superusers.
When set to OFF, row security will be disabled when allowed and an
error will be thrown if the user does not have rights to bypass row
security.
Per discussion, pg_dump sets row_security = OFF by default to ensure
that exports and backups will have all data in the table or will
error if there are insufficient privileges to bypass row security.
A new option has been added to pg_dump, --enable-row-security, to
ask pg_dump to export with row security enabled.
A new role capability, BYPASSRLS, which can only be set by the
superuser, is added to allow other users to be able to bypass row
security using row_security = OFF.
Many thanks to the various individuals who have helped with the
design, particularly Robert Haas for his feedback.
Authors include Craig Ringer, KaiGai Kohei, Adam Brightwell, Dean
Rasheed, with additional changes and rework by me.
Reviewers have included all of the above, Greg Smith,
Jeff McCormick, and Robert Haas.
2014-09-19 17:18:35 +02:00
|
|
|
i_rolbypassrls = PQfnumber(res, "rolbypassrls");
|
2006-02-12 04:22:21 +01:00
|
|
|
i_rolcomment = PQfnumber(res, "rolcomment");
|
2012-12-04 01:43:02 +01:00
|
|
|
i_is_current_user = PQfnumber(res, "is_current_user");
|
2004-07-19 23:39:48 +02:00
|
|
|
|
2005-10-11 00:29:48 +02:00
|
|
|
if (PQntuples(res) > 0)
|
2007-01-25 04:30:43 +01:00
|
|
|
fprintf(OPF, "--\n-- Roles\n--\n\n");
|
2002-08-27 20:57:26 +02:00
|
|
|
|
|
|
|
for (i = 0; i < PQntuples(res); i++)
|
|
|
|
{
|
2005-07-31 19:19:22 +02:00
|
|
|
const char *rolename;
|
2011-07-20 19:18:24 +02:00
|
|
|
Oid auth_oid;
|
2004-08-29 07:07:03 +02:00
|
|
|
|
2011-07-20 19:18:24 +02:00
|
|
|
auth_oid = atooid(PQgetvalue(res, i, i_oid));
|
2005-07-31 19:19:22 +02:00
|
|
|
rolename = PQgetvalue(res, i, i_rolname);
|
2004-07-19 23:39:48 +02:00
|
|
|
|
2016-04-08 22:56:27 +02:00
|
|
|
if (strncmp(rolename, "pg_", 3) == 0)
|
|
|
|
{
|
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
|
|
|
pg_log_warning("role name starting with \"pg_\" skipped (%s)",
|
|
|
|
rolename);
|
2016-04-08 22:56:27 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2005-10-11 00:29:48 +02:00
|
|
|
resetPQExpBuffer(buf);
|
|
|
|
|
2011-01-08 03:59:29 +01:00
|
|
|
if (binary_upgrade)
|
|
|
|
{
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(buf, "\n-- For binary upgrade, must preserve pg_authid.oid\n");
|
2011-01-08 03:59:29 +01:00
|
|
|
appendPQExpBuffer(buf,
|
2015-03-11 03:33:25 +01:00
|
|
|
"SELECT pg_catalog.binary_upgrade_set_next_pg_authid_oid('%u'::pg_catalog.oid);\n\n",
|
2011-01-08 03:59:29 +01:00
|
|
|
auth_oid);
|
|
|
|
}
|
|
|
|
|
2004-07-19 23:39:48 +02:00
|
|
|
/*
|
2005-10-11 00:29:48 +02:00
|
|
|
* We dump CREATE ROLE followed by ALTER ROLE to ensure that the role
|
2009-04-11 22:23:05 +02:00
|
|
|
* will acquire the right properties even if it already exists (ie, it
|
|
|
|
* won't hurt for the CREATE to fail). This is particularly important
|
|
|
|
* for the role we are connected as, since even with --clean we will
|
2013-03-24 16:27:20 +01:00
|
|
|
* have failed to drop it. binary_upgrade cannot generate any errors,
|
2012-12-04 01:43:02 +01:00
|
|
|
* so we assume the current role is already created.
|
2004-07-19 23:39:48 +02:00
|
|
|
*/
|
2012-12-04 01:43:02 +01:00
|
|
|
if (!binary_upgrade ||
|
|
|
|
strcmp(PQgetvalue(res, i, i_is_current_user), "f") == 0)
|
2012-11-30 22:30:13 +01:00
|
|
|
appendPQExpBuffer(buf, "CREATE ROLE %s;\n", fmtId(rolename));
|
2005-10-11 00:29:48 +02:00
|
|
|
appendPQExpBuffer(buf, "ALTER ROLE %s WITH", fmtId(rolename));
|
2002-08-27 20:57:26 +02:00
|
|
|
|
2005-07-31 19:19:22 +02:00
|
|
|
if (strcmp(PQgetvalue(res, i, i_rolsuper), "t") == 0)
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(buf, " SUPERUSER");
|
2005-07-31 19:19:22 +02:00
|
|
|
else
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(buf, " NOSUPERUSER");
|
2002-08-27 20:57:26 +02:00
|
|
|
|
2005-07-31 19:19:22 +02:00
|
|
|
if (strcmp(PQgetvalue(res, i, i_rolinherit), "t") == 0)
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(buf, " INHERIT");
|
2005-07-31 19:19:22 +02:00
|
|
|
else
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(buf, " NOINHERIT");
|
2005-07-31 19:19:22 +02:00
|
|
|
|
|
|
|
if (strcmp(PQgetvalue(res, i, i_rolcreaterole), "t") == 0)
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(buf, " CREATEROLE");
|
2005-07-31 19:19:22 +02:00
|
|
|
else
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(buf, " NOCREATEROLE");
|
2005-07-31 19:19:22 +02:00
|
|
|
|
|
|
|
if (strcmp(PQgetvalue(res, i, i_rolcreatedb), "t") == 0)
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(buf, " CREATEDB");
|
2002-08-27 20:57:26 +02:00
|
|
|
else
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(buf, " NOCREATEDB");
|
2002-08-27 20:57:26 +02:00
|
|
|
|
2005-07-31 19:19:22 +02:00
|
|
|
if (strcmp(PQgetvalue(res, i, i_rolcanlogin), "t") == 0)
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(buf, " LOGIN");
|
2002-08-27 20:57:26 +02:00
|
|
|
else
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(buf, " NOLOGIN");
|
2005-07-31 19:19:22 +02:00
|
|
|
|
2010-12-29 11:05:03 +01:00
|
|
|
if (strcmp(PQgetvalue(res, i, i_rolreplication), "t") == 0)
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(buf, " REPLICATION");
|
2010-12-29 11:05:03 +01:00
|
|
|
else
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(buf, " NOREPLICATION");
|
2010-12-29 11:05:03 +01:00
|
|
|
|
Row-Level Security Policies (RLS)
Building on the updatable security-barrier views work, add the
ability to define policies on tables to limit the set of rows
which are returned from a query and which are allowed to be added
to a table. Expressions defined by the policy for filtering are
added to the security barrier quals of the query, while expressions
defined to check records being added to a table are added to the
with-check options of the query.
New top-level commands are CREATE/ALTER/DROP POLICY and are
controlled by the table owner. Row Security is able to be enabled
and disabled by the owner on a per-table basis using
ALTER TABLE .. ENABLE/DISABLE ROW SECURITY.
Per discussion, ROW SECURITY is disabled on tables by default and
must be enabled for policies on the table to be used. If no
policies exist on a table with ROW SECURITY enabled, a default-deny
policy is used and no records will be visible.
By default, row security is applied at all times except for the
table owner and the superuser. A new GUC, row_security, is added
which can be set to ON, OFF, or FORCE. When set to FORCE, row
security will be applied even for the table owner and superusers.
When set to OFF, row security will be disabled when allowed and an
error will be thrown if the user does not have rights to bypass row
security.
Per discussion, pg_dump sets row_security = OFF by default to ensure
that exports and backups will have all data in the table or will
error if there are insufficient privileges to bypass row security.
A new option has been added to pg_dump, --enable-row-security, to
ask pg_dump to export with row security enabled.
A new role capability, BYPASSRLS, which can only be set by the
superuser, is added to allow other users to be able to bypass row
security using row_security = OFF.
Many thanks to the various individuals who have helped with the
design, particularly Robert Haas for his feedback.
Authors include Craig Ringer, KaiGai Kohei, Adam Brightwell, Dean
Rasheed, with additional changes and rework by me.
Reviewers have included all of the above, Greg Smith,
Jeff McCormick, and Robert Haas.
2014-09-19 17:18:35 +02:00
|
|
|
if (strcmp(PQgetvalue(res, i, i_rolbypassrls), "t") == 0)
|
|
|
|
appendPQExpBufferStr(buf, " BYPASSRLS");
|
|
|
|
else
|
|
|
|
appendPQExpBufferStr(buf, " NOBYPASSRLS");
|
|
|
|
|
2005-07-31 19:19:22 +02:00
|
|
|
if (strcmp(PQgetvalue(res, i, i_rolconnlimit), "-1") != 0)
|
|
|
|
appendPQExpBuffer(buf, " CONNECTION LIMIT %s",
|
|
|
|
PQgetvalue(res, i, i_rolconnlimit));
|
2002-08-27 20:57:26 +02:00
|
|
|
|
2017-03-07 15:00:54 +01:00
|
|
|
|
|
|
|
if (!PQgetisnull(res, i, i_rolpassword) && !no_role_passwords)
|
2005-07-31 19:19:22 +02:00
|
|
|
{
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(buf, " PASSWORD ");
|
2006-05-28 23:13:54 +02:00
|
|
|
appendStringLiteralConn(buf, PQgetvalue(res, i, i_rolpassword), conn);
|
2005-07-31 19:19:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!PQgetisnull(res, i, i_rolvaliduntil))
|
2003-05-31 00:55:16 +02:00
|
|
|
appendPQExpBuffer(buf, " VALID UNTIL '%s'",
|
2005-07-31 19:19:22 +02:00
|
|
|
PQgetvalue(res, i, i_rolvaliduntil));
|
2002-08-27 20:57:26 +02:00
|
|
|
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(buf, ";\n");
|
2002-08-27 20:57:26 +02:00
|
|
|
|
Support --no-comments in pg_dump, pg_dumpall, pg_restore.
We have switches already to suppress other subsidiary object properties,
such as ACLs, security labels, ownership, and tablespaces, so just on
the grounds of symmetry we should allow suppressing comments as well.
Also, commit 0d4e6ed30 added a positive reason to have this feature,
i.e. to allow obtaining the old behavior of selective pg_restore should
anyone desire that.
Recent commits have removed the cases where pg_dump emitted comments on
built-in objects that the restoring user might not have privileges to
comment on, so the original primary motivation for this feature is gone,
but it still seems at least somewhat useful in its own right.
Robins Tharakan, reviewed by Fabrízio Mello
Discussion: https://postgr.es/m/CAEP4nAx22Z4ch74oJGzr5RyyjcyUSbpiFLyeYXX8pehfou92ug@mail.gmail.com
2018-01-25 21:27:24 +01:00
|
|
|
if (!no_comments && !PQgetisnull(res, i, i_rolcomment))
|
2006-02-12 04:22:21 +01:00
|
|
|
{
|
|
|
|
appendPQExpBuffer(buf, "COMMENT ON ROLE %s IS ", fmtId(rolename));
|
2006-05-28 23:13:54 +02:00
|
|
|
appendStringLiteralConn(buf, PQgetvalue(res, i, i_rolcomment), conn);
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(buf, ";\n");
|
2006-02-12 04:22:21 +01:00
|
|
|
}
|
|
|
|
|
2021-12-14 23:09:07 +01:00
|
|
|
if (!no_security_labels)
|
2011-07-20 19:18:24 +02:00
|
|
|
buildShSecLabels(conn, "pg_authid", auth_oid,
|
Avoid using unsafe search_path settings during dump and restore.
Historically, pg_dump has "set search_path = foo, pg_catalog" when
dumping an object in schema "foo", and has also caused that setting
to be used while restoring the object. This is problematic because
functions and operators in schema "foo" could capture references meant
to refer to pg_catalog entries, both in the queries issued by pg_dump
and those issued during the subsequent restore run. That could
result in dump/restore misbehavior, or in privilege escalation if a
nefarious user installs trojan-horse functions or operators.
This patch changes pg_dump so that it does not change the search_path
dynamically. The emitted restore script sets the search_path to what
was used at dump time, and then leaves it alone thereafter. Created
objects are placed in the correct schema, regardless of the active
search_path, by dint of schema-qualifying their names in the CREATE
commands, as well as in subsequent ALTER and ALTER-like commands.
Since this change requires a change in the behavior of pg_restore
when processing an archive file made according to this new convention,
bump the archive file version number; old versions of pg_restore will
therefore refuse to process files made with new versions of pg_dump.
Security: CVE-2018-1058
2018-02-26 16:18:21 +01:00
|
|
|
"ROLE", rolename,
|
|
|
|
buf);
|
2011-07-20 19:18:24 +02:00
|
|
|
|
2007-01-25 04:30:43 +01:00
|
|
|
fprintf(OPF, "%s", buf->data);
|
2002-08-27 20:57:26 +02:00
|
|
|
}
|
|
|
|
|
2011-10-14 20:16:02 +02:00
|
|
|
/*
|
|
|
|
* Dump configuration settings for roles after all roles have been dumped.
|
|
|
|
* We do it this way because config settings for roles could mention the
|
|
|
|
* names of other roles.
|
|
|
|
*/
|
2021-12-14 23:09:07 +01:00
|
|
|
if (PQntuples(res) > 0)
|
|
|
|
fprintf(OPF, "\n--\n-- User Configurations\n--\n");
|
|
|
|
|
2016-10-12 18:19:56 +02:00
|
|
|
for (i = 0; i < PQntuples(res); i++)
|
|
|
|
dumpUserConfig(conn, PQgetvalue(res, i, i_rolname));
|
2011-10-14 20:16:02 +02:00
|
|
|
|
2002-08-27 20:57:26 +02:00
|
|
|
PQclear(res);
|
2005-07-08 18:51:30 +02:00
|
|
|
|
2007-01-25 04:30:43 +01:00
|
|
|
fprintf(OPF, "\n\n");
|
2005-07-08 18:51:30 +02:00
|
|
|
|
|
|
|
destroyPQExpBuffer(buf);
|
2002-08-27 20:57:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-07-31 19:19:22 +02:00
|
|
|
/*
|
2021-12-14 23:09:07 +01:00
|
|
|
* Dump role memberships.
|
2005-07-31 19:19:22 +02:00
|
|
|
*
|
|
|
|
* Note: we expect dumpRoles already created all the roles, but there is
|
|
|
|
* no membership yet.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
dumpRoleMembership(PGconn *conn)
|
|
|
|
{
|
2017-03-07 15:00:54 +01:00
|
|
|
PQExpBuffer buf = createPQExpBuffer();
|
2022-08-25 16:06:02 +02:00
|
|
|
PQExpBuffer optbuf = createPQExpBuffer();
|
2005-07-31 19:19:22 +02:00
|
|
|
PGresult *res;
|
Make role grant system more consistent with other privileges.
Previously, membership of role A in role B could be recorded in the
catalog tables only once. This meant that a new grant of role A to
role B would overwrite the previous grant. For other object types, a
new grant of permission on an object - in this case role A - exists
along side the existing grant provided that the grantor is different.
Either grant can be revoked independently of the other, and
permissions remain so long as at least one grant remains. Make role
grants work similarly.
Previously, when granting membership in a role, the superuser could
specify any role whatsoever as the grantor, but for other object types,
the grantor of record must be either the owner of the object, or a
role that currently has privileges to perform a similar GRANT.
Implement the same scheme for role grants, treating the bootstrap
superuser as the role owner since roles do not have owners. This means
that attempting to revoke a grant, or admin option on a grant, can now
fail if there are dependent privileges, and that CASCADE can be used
to revoke these. It also means that you can't grant ADMIN OPTION on
a role back to a user who granted it directly or indirectly to you,
similar to how you can't give WITH GRANT OPTION on a privilege back
to a role which granted it directly or indirectly to you.
Previously, only the superuser could specify GRANTED BY with a user
other than the current user. Relax that rule to allow the grantor
to be any role whose privileges the current user posseses. This
doesn't improve compatibility with what we do for other object types,
where support for GRANTED BY is entirely vestigial, but it makes this
feature more usable and seems to make sense to change at the same time
we're changing related behaviors.
Along the way, fix "ALTER GROUP group_name ADD USER user_name" to
require the same privileges as "GRANT group_name TO user_name".
Previously, CREATEROLE privileges were sufficient for either, but
only the former form was permissible with ADMIN OPTION on the role.
Now, either CREATEROLE or ADMIN OPTION on the role suffices for
either spelling.
Patch by me, reviewed by Stephen Frost.
Discussion: http://postgr.es/m/CA+TgmoaFr-RZeQ+WoQ5nKPv97oT9+aDgK_a5+qWHSgbDsMp1Vg@mail.gmail.com
2022-08-22 17:35:17 +02:00
|
|
|
int start = 0,
|
|
|
|
end,
|
|
|
|
total;
|
|
|
|
bool dump_grantors;
|
Add a SET option to the GRANT command.
Similar to how the INHERIT option controls whether or not the
permissions of the granted role are automatically available to the
grantee, the new SET permission controls whether or not the grantee
may use the SET ROLE command to assume the privileges of the granted
role.
In addition, the new SET permission controls whether or not it
is possible to transfer ownership of objects to the target role
or to create new objects owned by the target role using commands
such as CREATE DATABASE .. OWNER. We could alternatively have made
this controlled by the INHERIT option, or allow it when either
option is given. An advantage of this approach is that if you
are granted a predefined role with INHERIT TRUE, SET FALSE, you
can't go and create objects owned by that role.
The underlying theory here is that the ability to create objects
as a target role is not a privilege per se, and thus does not
depend on whether you inherit the target role's privileges. However,
it's surely something you could do anyway if you could SET ROLE
to the target role, and thus making it contingent on whether you
have that ability is reasonable.
Design review by Nathan Bossat, Wolfgang Walther, Jeff Davis,
Peter Eisentraut, and Stephen Frost.
Discussion: http://postgr.es/m/CA+Tgmob+zDSRS6JXYrgq0NWdzCXuTNzT5eK54Dn2hhgt17nm8A@mail.gmail.com
2022-11-18 18:32:50 +01:00
|
|
|
bool dump_grant_options;
|
2022-08-25 16:06:02 +02:00
|
|
|
int i_inherit_option;
|
Add a SET option to the GRANT command.
Similar to how the INHERIT option controls whether or not the
permissions of the granted role are automatically available to the
grantee, the new SET permission controls whether or not the grantee
may use the SET ROLE command to assume the privileges of the granted
role.
In addition, the new SET permission controls whether or not it
is possible to transfer ownership of objects to the target role
or to create new objects owned by the target role using commands
such as CREATE DATABASE .. OWNER. We could alternatively have made
this controlled by the INHERIT option, or allow it when either
option is given. An advantage of this approach is that if you
are granted a predefined role with INHERIT TRUE, SET FALSE, you
can't go and create objects owned by that role.
The underlying theory here is that the ability to create objects
as a target role is not a privilege per se, and thus does not
depend on whether you inherit the target role's privileges. However,
it's surely something you could do anyway if you could SET ROLE
to the target role, and thus making it contingent on whether you
have that ability is reasonable.
Design review by Nathan Bossat, Wolfgang Walther, Jeff Davis,
Peter Eisentraut, and Stephen Frost.
Discussion: http://postgr.es/m/CA+Tgmob+zDSRS6JXYrgq0NWdzCXuTNzT5eK54Dn2hhgt17nm8A@mail.gmail.com
2022-11-18 18:32:50 +01:00
|
|
|
int i_set_option;
|
2005-07-31 19:19:22 +02:00
|
|
|
|
Make role grant system more consistent with other privileges.
Previously, membership of role A in role B could be recorded in the
catalog tables only once. This meant that a new grant of role A to
role B would overwrite the previous grant. For other object types, a
new grant of permission on an object - in this case role A - exists
along side the existing grant provided that the grantor is different.
Either grant can be revoked independently of the other, and
permissions remain so long as at least one grant remains. Make role
grants work similarly.
Previously, when granting membership in a role, the superuser could
specify any role whatsoever as the grantor, but for other object types,
the grantor of record must be either the owner of the object, or a
role that currently has privileges to perform a similar GRANT.
Implement the same scheme for role grants, treating the bootstrap
superuser as the role owner since roles do not have owners. This means
that attempting to revoke a grant, or admin option on a grant, can now
fail if there are dependent privileges, and that CASCADE can be used
to revoke these. It also means that you can't grant ADMIN OPTION on
a role back to a user who granted it directly or indirectly to you,
similar to how you can't give WITH GRANT OPTION on a privilege back
to a role which granted it directly or indirectly to you.
Previously, only the superuser could specify GRANTED BY with a user
other than the current user. Relax that rule to allow the grantor
to be any role whose privileges the current user posseses. This
doesn't improve compatibility with what we do for other object types,
where support for GRANTED BY is entirely vestigial, but it makes this
feature more usable and seems to make sense to change at the same time
we're changing related behaviors.
Along the way, fix "ALTER GROUP group_name ADD USER user_name" to
require the same privileges as "GRANT group_name TO user_name".
Previously, CREATEROLE privileges were sufficient for either, but
only the former form was permissible with ADMIN OPTION on the role.
Now, either CREATEROLE or ADMIN OPTION on the role suffices for
either spelling.
Patch by me, reviewed by Stephen Frost.
Discussion: http://postgr.es/m/CA+TgmoaFr-RZeQ+WoQ5nKPv97oT9+aDgK_a5+qWHSgbDsMp1Vg@mail.gmail.com
2022-08-22 17:35:17 +02:00
|
|
|
/*
|
|
|
|
* Previous versions of PostgreSQL didn't used to track the grantor very
|
|
|
|
* carefully in the backend, and the grantor could be any user even if
|
|
|
|
* they didn't have ADMIN OPTION on the role, or a user that no longer
|
|
|
|
* existed. To avoid dump and restore failures, don't dump the grantor
|
|
|
|
* when talking to an old server version.
|
|
|
|
*/
|
|
|
|
dump_grantors = (PQserverVersion(conn) >= 160000);
|
|
|
|
|
2022-08-25 16:06:02 +02:00
|
|
|
/*
|
Add a SET option to the GRANT command.
Similar to how the INHERIT option controls whether or not the
permissions of the granted role are automatically available to the
grantee, the new SET permission controls whether or not the grantee
may use the SET ROLE command to assume the privileges of the granted
role.
In addition, the new SET permission controls whether or not it
is possible to transfer ownership of objects to the target role
or to create new objects owned by the target role using commands
such as CREATE DATABASE .. OWNER. We could alternatively have made
this controlled by the INHERIT option, or allow it when either
option is given. An advantage of this approach is that if you
are granted a predefined role with INHERIT TRUE, SET FALSE, you
can't go and create objects owned by that role.
The underlying theory here is that the ability to create objects
as a target role is not a privilege per se, and thus does not
depend on whether you inherit the target role's privileges. However,
it's surely something you could do anyway if you could SET ROLE
to the target role, and thus making it contingent on whether you
have that ability is reasonable.
Design review by Nathan Bossat, Wolfgang Walther, Jeff Davis,
Peter Eisentraut, and Stephen Frost.
Discussion: http://postgr.es/m/CA+Tgmob+zDSRS6JXYrgq0NWdzCXuTNzT5eK54Dn2hhgt17nm8A@mail.gmail.com
2022-11-18 18:32:50 +01:00
|
|
|
* Previous versions of PostgreSQL also did not have grant-level options.
|
2022-08-25 16:06:02 +02:00
|
|
|
*/
|
Add a SET option to the GRANT command.
Similar to how the INHERIT option controls whether or not the
permissions of the granted role are automatically available to the
grantee, the new SET permission controls whether or not the grantee
may use the SET ROLE command to assume the privileges of the granted
role.
In addition, the new SET permission controls whether or not it
is possible to transfer ownership of objects to the target role
or to create new objects owned by the target role using commands
such as CREATE DATABASE .. OWNER. We could alternatively have made
this controlled by the INHERIT option, or allow it when either
option is given. An advantage of this approach is that if you
are granted a predefined role with INHERIT TRUE, SET FALSE, you
can't go and create objects owned by that role.
The underlying theory here is that the ability to create objects
as a target role is not a privilege per se, and thus does not
depend on whether you inherit the target role's privileges. However,
it's surely something you could do anyway if you could SET ROLE
to the target role, and thus making it contingent on whether you
have that ability is reasonable.
Design review by Nathan Bossat, Wolfgang Walther, Jeff Davis,
Peter Eisentraut, and Stephen Frost.
Discussion: http://postgr.es/m/CA+Tgmob+zDSRS6JXYrgq0NWdzCXuTNzT5eK54Dn2hhgt17nm8A@mail.gmail.com
2022-11-18 18:32:50 +01:00
|
|
|
dump_grant_options = (server_version >= 160000);
|
2022-08-25 16:06:02 +02:00
|
|
|
|
Make role grant system more consistent with other privileges.
Previously, membership of role A in role B could be recorded in the
catalog tables only once. This meant that a new grant of role A to
role B would overwrite the previous grant. For other object types, a
new grant of permission on an object - in this case role A - exists
along side the existing grant provided that the grantor is different.
Either grant can be revoked independently of the other, and
permissions remain so long as at least one grant remains. Make role
grants work similarly.
Previously, when granting membership in a role, the superuser could
specify any role whatsoever as the grantor, but for other object types,
the grantor of record must be either the owner of the object, or a
role that currently has privileges to perform a similar GRANT.
Implement the same scheme for role grants, treating the bootstrap
superuser as the role owner since roles do not have owners. This means
that attempting to revoke a grant, or admin option on a grant, can now
fail if there are dependent privileges, and that CASCADE can be used
to revoke these. It also means that you can't grant ADMIN OPTION on
a role back to a user who granted it directly or indirectly to you,
similar to how you can't give WITH GRANT OPTION on a privilege back
to a role which granted it directly or indirectly to you.
Previously, only the superuser could specify GRANTED BY with a user
other than the current user. Relax that rule to allow the grantor
to be any role whose privileges the current user posseses. This
doesn't improve compatibility with what we do for other object types,
where support for GRANTED BY is entirely vestigial, but it makes this
feature more usable and seems to make sense to change at the same time
we're changing related behaviors.
Along the way, fix "ALTER GROUP group_name ADD USER user_name" to
require the same privileges as "GRANT group_name TO user_name".
Previously, CREATEROLE privileges were sufficient for either, but
only the former form was permissible with ADMIN OPTION on the role.
Now, either CREATEROLE or ADMIN OPTION on the role suffices for
either spelling.
Patch by me, reviewed by Stephen Frost.
Discussion: http://postgr.es/m/CA+TgmoaFr-RZeQ+WoQ5nKPv97oT9+aDgK_a5+qWHSgbDsMp1Vg@mail.gmail.com
2022-08-22 17:35:17 +02:00
|
|
|
/* Generate and execute query. */
|
|
|
|
printfPQExpBuffer(buf, "SELECT ur.rolname AS role, "
|
2005-07-31 19:19:22 +02:00
|
|
|
"um.rolname AS member, "
|
Make role grant system more consistent with other privileges.
Previously, membership of role A in role B could be recorded in the
catalog tables only once. This meant that a new grant of role A to
role B would overwrite the previous grant. For other object types, a
new grant of permission on an object - in this case role A - exists
along side the existing grant provided that the grantor is different.
Either grant can be revoked independently of the other, and
permissions remain so long as at least one grant remains. Make role
grants work similarly.
Previously, when granting membership in a role, the superuser could
specify any role whatsoever as the grantor, but for other object types,
the grantor of record must be either the owner of the object, or a
role that currently has privileges to perform a similar GRANT.
Implement the same scheme for role grants, treating the bootstrap
superuser as the role owner since roles do not have owners. This means
that attempting to revoke a grant, or admin option on a grant, can now
fail if there are dependent privileges, and that CASCADE can be used
to revoke these. It also means that you can't grant ADMIN OPTION on
a role back to a user who granted it directly or indirectly to you,
similar to how you can't give WITH GRANT OPTION on a privilege back
to a role which granted it directly or indirectly to you.
Previously, only the superuser could specify GRANTED BY with a user
other than the current user. Relax that rule to allow the grantor
to be any role whose privileges the current user posseses. This
doesn't improve compatibility with what we do for other object types,
where support for GRANTED BY is entirely vestigial, but it makes this
feature more usable and seems to make sense to change at the same time
we're changing related behaviors.
Along the way, fix "ALTER GROUP group_name ADD USER user_name" to
require the same privileges as "GRANT group_name TO user_name".
Previously, CREATEROLE privileges were sufficient for either, but
only the former form was permissible with ADMIN OPTION on the role.
Now, either CREATEROLE or ADMIN OPTION on the role suffices for
either spelling.
Patch by me, reviewed by Stephen Frost.
Discussion: http://postgr.es/m/CA+TgmoaFr-RZeQ+WoQ5nKPv97oT9+aDgK_a5+qWHSgbDsMp1Vg@mail.gmail.com
2022-08-22 17:35:17 +02:00
|
|
|
"ug.oid AS grantorid, "
|
|
|
|
"ug.rolname AS grantor, "
|
2022-08-25 16:06:02 +02:00
|
|
|
"a.admin_option");
|
Add a SET option to the GRANT command.
Similar to how the INHERIT option controls whether or not the
permissions of the granted role are automatically available to the
grantee, the new SET permission controls whether or not the grantee
may use the SET ROLE command to assume the privileges of the granted
role.
In addition, the new SET permission controls whether or not it
is possible to transfer ownership of objects to the target role
or to create new objects owned by the target role using commands
such as CREATE DATABASE .. OWNER. We could alternatively have made
this controlled by the INHERIT option, or allow it when either
option is given. An advantage of this approach is that if you
are granted a predefined role with INHERIT TRUE, SET FALSE, you
can't go and create objects owned by that role.
The underlying theory here is that the ability to create objects
as a target role is not a privilege per se, and thus does not
depend on whether you inherit the target role's privileges. However,
it's surely something you could do anyway if you could SET ROLE
to the target role, and thus making it contingent on whether you
have that ability is reasonable.
Design review by Nathan Bossat, Wolfgang Walther, Jeff Davis,
Peter Eisentraut, and Stephen Frost.
Discussion: http://postgr.es/m/CA+Tgmob+zDSRS6JXYrgq0NWdzCXuTNzT5eK54Dn2hhgt17nm8A@mail.gmail.com
2022-11-18 18:32:50 +01:00
|
|
|
if (dump_grant_options)
|
|
|
|
appendPQExpBufferStr(buf, ", a.inherit_option, a.set_option");
|
2022-08-25 16:06:02 +02:00
|
|
|
appendPQExpBuffer(buf, " FROM pg_auth_members a "
|
2017-03-07 15:00:54 +01:00
|
|
|
"LEFT JOIN %s ur on ur.oid = a.roleid "
|
|
|
|
"LEFT JOIN %s um on um.oid = a.member "
|
|
|
|
"LEFT JOIN %s ug on ug.oid = a.grantor "
|
2016-04-08 22:56:27 +02:00
|
|
|
"WHERE NOT (ur.rolname ~ '^pg_' AND um.rolname ~ '^pg_')"
|
Make role grant system more consistent with other privileges.
Previously, membership of role A in role B could be recorded in the
catalog tables only once. This meant that a new grant of role A to
role B would overwrite the previous grant. For other object types, a
new grant of permission on an object - in this case role A - exists
along side the existing grant provided that the grantor is different.
Either grant can be revoked independently of the other, and
permissions remain so long as at least one grant remains. Make role
grants work similarly.
Previously, when granting membership in a role, the superuser could
specify any role whatsoever as the grantor, but for other object types,
the grantor of record must be either the owner of the object, or a
role that currently has privileges to perform a similar GRANT.
Implement the same scheme for role grants, treating the bootstrap
superuser as the role owner since roles do not have owners. This means
that attempting to revoke a grant, or admin option on a grant, can now
fail if there are dependent privileges, and that CASCADE can be used
to revoke these. It also means that you can't grant ADMIN OPTION on
a role back to a user who granted it directly or indirectly to you,
similar to how you can't give WITH GRANT OPTION on a privilege back
to a role which granted it directly or indirectly to you.
Previously, only the superuser could specify GRANTED BY with a user
other than the current user. Relax that rule to allow the grantor
to be any role whose privileges the current user posseses. This
doesn't improve compatibility with what we do for other object types,
where support for GRANTED BY is entirely vestigial, but it makes this
feature more usable and seems to make sense to change at the same time
we're changing related behaviors.
Along the way, fix "ALTER GROUP group_name ADD USER user_name" to
require the same privileges as "GRANT group_name TO user_name".
Previously, CREATEROLE privileges were sufficient for either, but
only the former form was permissible with ADMIN OPTION on the role.
Now, either CREATEROLE or ADMIN OPTION on the role suffices for
either spelling.
Patch by me, reviewed by Stephen Frost.
Discussion: http://postgr.es/m/CA+TgmoaFr-RZeQ+WoQ5nKPv97oT9+aDgK_a5+qWHSgbDsMp1Vg@mail.gmail.com
2022-08-22 17:35:17 +02:00
|
|
|
"ORDER BY 1,2,4", role_catalog, role_catalog, role_catalog);
|
2017-03-07 15:00:54 +01:00
|
|
|
res = executeQuery(conn, buf->data);
|
2022-08-25 16:06:02 +02:00
|
|
|
i_inherit_option = PQfnumber(res, "inherit_option");
|
Add a SET option to the GRANT command.
Similar to how the INHERIT option controls whether or not the
permissions of the granted role are automatically available to the
grantee, the new SET permission controls whether or not the grantee
may use the SET ROLE command to assume the privileges of the granted
role.
In addition, the new SET permission controls whether or not it
is possible to transfer ownership of objects to the target role
or to create new objects owned by the target role using commands
such as CREATE DATABASE .. OWNER. We could alternatively have made
this controlled by the INHERIT option, or allow it when either
option is given. An advantage of this approach is that if you
are granted a predefined role with INHERIT TRUE, SET FALSE, you
can't go and create objects owned by that role.
The underlying theory here is that the ability to create objects
as a target role is not a privilege per se, and thus does not
depend on whether you inherit the target role's privileges. However,
it's surely something you could do anyway if you could SET ROLE
to the target role, and thus making it contingent on whether you
have that ability is reasonable.
Design review by Nathan Bossat, Wolfgang Walther, Jeff Davis,
Peter Eisentraut, and Stephen Frost.
Discussion: http://postgr.es/m/CA+Tgmob+zDSRS6JXYrgq0NWdzCXuTNzT5eK54Dn2hhgt17nm8A@mail.gmail.com
2022-11-18 18:32:50 +01:00
|
|
|
i_set_option = PQfnumber(res, "set_option");
|
2005-07-31 19:19:22 +02:00
|
|
|
|
2005-10-11 00:29:48 +02:00
|
|
|
if (PQntuples(res) > 0)
|
2007-01-25 04:30:43 +01:00
|
|
|
fprintf(OPF, "--\n-- Role memberships\n--\n\n");
|
2005-07-31 19:19:22 +02:00
|
|
|
|
Make role grant system more consistent with other privileges.
Previously, membership of role A in role B could be recorded in the
catalog tables only once. This meant that a new grant of role A to
role B would overwrite the previous grant. For other object types, a
new grant of permission on an object - in this case role A - exists
along side the existing grant provided that the grantor is different.
Either grant can be revoked independently of the other, and
permissions remain so long as at least one grant remains. Make role
grants work similarly.
Previously, when granting membership in a role, the superuser could
specify any role whatsoever as the grantor, but for other object types,
the grantor of record must be either the owner of the object, or a
role that currently has privileges to perform a similar GRANT.
Implement the same scheme for role grants, treating the bootstrap
superuser as the role owner since roles do not have owners. This means
that attempting to revoke a grant, or admin option on a grant, can now
fail if there are dependent privileges, and that CASCADE can be used
to revoke these. It also means that you can't grant ADMIN OPTION on
a role back to a user who granted it directly or indirectly to you,
similar to how you can't give WITH GRANT OPTION on a privilege back
to a role which granted it directly or indirectly to you.
Previously, only the superuser could specify GRANTED BY with a user
other than the current user. Relax that rule to allow the grantor
to be any role whose privileges the current user posseses. This
doesn't improve compatibility with what we do for other object types,
where support for GRANTED BY is entirely vestigial, but it makes this
feature more usable and seems to make sense to change at the same time
we're changing related behaviors.
Along the way, fix "ALTER GROUP group_name ADD USER user_name" to
require the same privileges as "GRANT group_name TO user_name".
Previously, CREATEROLE privileges were sufficient for either, but
only the former form was permissible with ADMIN OPTION on the role.
Now, either CREATEROLE or ADMIN OPTION on the role suffices for
either spelling.
Patch by me, reviewed by Stephen Frost.
Discussion: http://postgr.es/m/CA+TgmoaFr-RZeQ+WoQ5nKPv97oT9+aDgK_a5+qWHSgbDsMp1Vg@mail.gmail.com
2022-08-22 17:35:17 +02:00
|
|
|
/*
|
2023-02-09 06:43:53 +01:00
|
|
|
* We can't dump these GRANT commands in arbitrary order, because a role
|
Make role grant system more consistent with other privileges.
Previously, membership of role A in role B could be recorded in the
catalog tables only once. This meant that a new grant of role A to
role B would overwrite the previous grant. For other object types, a
new grant of permission on an object - in this case role A - exists
along side the existing grant provided that the grantor is different.
Either grant can be revoked independently of the other, and
permissions remain so long as at least one grant remains. Make role
grants work similarly.
Previously, when granting membership in a role, the superuser could
specify any role whatsoever as the grantor, but for other object types,
the grantor of record must be either the owner of the object, or a
role that currently has privileges to perform a similar GRANT.
Implement the same scheme for role grants, treating the bootstrap
superuser as the role owner since roles do not have owners. This means
that attempting to revoke a grant, or admin option on a grant, can now
fail if there are dependent privileges, and that CASCADE can be used
to revoke these. It also means that you can't grant ADMIN OPTION on
a role back to a user who granted it directly or indirectly to you,
similar to how you can't give WITH GRANT OPTION on a privilege back
to a role which granted it directly or indirectly to you.
Previously, only the superuser could specify GRANTED BY with a user
other than the current user. Relax that rule to allow the grantor
to be any role whose privileges the current user posseses. This
doesn't improve compatibility with what we do for other object types,
where support for GRANTED BY is entirely vestigial, but it makes this
feature more usable and seems to make sense to change at the same time
we're changing related behaviors.
Along the way, fix "ALTER GROUP group_name ADD USER user_name" to
require the same privileges as "GRANT group_name TO user_name".
Previously, CREATEROLE privileges were sufficient for either, but
only the former form was permissible with ADMIN OPTION on the role.
Now, either CREATEROLE or ADMIN OPTION on the role suffices for
either spelling.
Patch by me, reviewed by Stephen Frost.
Discussion: http://postgr.es/m/CA+TgmoaFr-RZeQ+WoQ5nKPv97oT9+aDgK_a5+qWHSgbDsMp1Vg@mail.gmail.com
2022-08-22 17:35:17 +02:00
|
|
|
* that is named as a grantor must already have ADMIN OPTION on the role
|
2023-04-18 04:03:30 +02:00
|
|
|
* for which it is granting permissions, except for the bootstrap
|
Make role grant system more consistent with other privileges.
Previously, membership of role A in role B could be recorded in the
catalog tables only once. This meant that a new grant of role A to
role B would overwrite the previous grant. For other object types, a
new grant of permission on an object - in this case role A - exists
along side the existing grant provided that the grantor is different.
Either grant can be revoked independently of the other, and
permissions remain so long as at least one grant remains. Make role
grants work similarly.
Previously, when granting membership in a role, the superuser could
specify any role whatsoever as the grantor, but for other object types,
the grantor of record must be either the owner of the object, or a
role that currently has privileges to perform a similar GRANT.
Implement the same scheme for role grants, treating the bootstrap
superuser as the role owner since roles do not have owners. This means
that attempting to revoke a grant, or admin option on a grant, can now
fail if there are dependent privileges, and that CASCADE can be used
to revoke these. It also means that you can't grant ADMIN OPTION on
a role back to a user who granted it directly or indirectly to you,
similar to how you can't give WITH GRANT OPTION on a privilege back
to a role which granted it directly or indirectly to you.
Previously, only the superuser could specify GRANTED BY with a user
other than the current user. Relax that rule to allow the grantor
to be any role whose privileges the current user posseses. This
doesn't improve compatibility with what we do for other object types,
where support for GRANTED BY is entirely vestigial, but it makes this
feature more usable and seems to make sense to change at the same time
we're changing related behaviors.
Along the way, fix "ALTER GROUP group_name ADD USER user_name" to
require the same privileges as "GRANT group_name TO user_name".
Previously, CREATEROLE privileges were sufficient for either, but
only the former form was permissible with ADMIN OPTION on the role.
Now, either CREATEROLE or ADMIN OPTION on the role suffices for
either spelling.
Patch by me, reviewed by Stephen Frost.
Discussion: http://postgr.es/m/CA+TgmoaFr-RZeQ+WoQ5nKPv97oT9+aDgK_a5+qWHSgbDsMp1Vg@mail.gmail.com
2022-08-22 17:35:17 +02:00
|
|
|
* superuser, who can always be named as the grantor.
|
|
|
|
*
|
|
|
|
* We handle this by considering these grants role by role. For each role,
|
2023-04-18 04:03:30 +02:00
|
|
|
* we initially consider the only allowable grantor to be the bootstrap
|
Make role grant system more consistent with other privileges.
Previously, membership of role A in role B could be recorded in the
catalog tables only once. This meant that a new grant of role A to
role B would overwrite the previous grant. For other object types, a
new grant of permission on an object - in this case role A - exists
along side the existing grant provided that the grantor is different.
Either grant can be revoked independently of the other, and
permissions remain so long as at least one grant remains. Make role
grants work similarly.
Previously, when granting membership in a role, the superuser could
specify any role whatsoever as the grantor, but for other object types,
the grantor of record must be either the owner of the object, or a
role that currently has privileges to perform a similar GRANT.
Implement the same scheme for role grants, treating the bootstrap
superuser as the role owner since roles do not have owners. This means
that attempting to revoke a grant, or admin option on a grant, can now
fail if there are dependent privileges, and that CASCADE can be used
to revoke these. It also means that you can't grant ADMIN OPTION on
a role back to a user who granted it directly or indirectly to you,
similar to how you can't give WITH GRANT OPTION on a privilege back
to a role which granted it directly or indirectly to you.
Previously, only the superuser could specify GRANTED BY with a user
other than the current user. Relax that rule to allow the grantor
to be any role whose privileges the current user posseses. This
doesn't improve compatibility with what we do for other object types,
where support for GRANTED BY is entirely vestigial, but it makes this
feature more usable and seems to make sense to change at the same time
we're changing related behaviors.
Along the way, fix "ALTER GROUP group_name ADD USER user_name" to
require the same privileges as "GRANT group_name TO user_name".
Previously, CREATEROLE privileges were sufficient for either, but
only the former form was permissible with ADMIN OPTION on the role.
Now, either CREATEROLE or ADMIN OPTION on the role suffices for
either spelling.
Patch by me, reviewed by Stephen Frost.
Discussion: http://postgr.es/m/CA+TgmoaFr-RZeQ+WoQ5nKPv97oT9+aDgK_a5+qWHSgbDsMp1Vg@mail.gmail.com
2022-08-22 17:35:17 +02:00
|
|
|
* superuser. Every time we grant ADMIN OPTION on the role to some user,
|
|
|
|
* that user also becomes an allowable grantor. We make repeated passes
|
|
|
|
* over the grants for the role, each time dumping those whose grantors
|
|
|
|
* are allowable and which we haven't done yet. Eventually this should let
|
|
|
|
* us dump all the grants.
|
|
|
|
*/
|
|
|
|
total = PQntuples(res);
|
|
|
|
while (start < total)
|
2005-07-31 19:19:22 +02:00
|
|
|
{
|
Make role grant system more consistent with other privileges.
Previously, membership of role A in role B could be recorded in the
catalog tables only once. This meant that a new grant of role A to
role B would overwrite the previous grant. For other object types, a
new grant of permission on an object - in this case role A - exists
along side the existing grant provided that the grantor is different.
Either grant can be revoked independently of the other, and
permissions remain so long as at least one grant remains. Make role
grants work similarly.
Previously, when granting membership in a role, the superuser could
specify any role whatsoever as the grantor, but for other object types,
the grantor of record must be either the owner of the object, or a
role that currently has privileges to perform a similar GRANT.
Implement the same scheme for role grants, treating the bootstrap
superuser as the role owner since roles do not have owners. This means
that attempting to revoke a grant, or admin option on a grant, can now
fail if there are dependent privileges, and that CASCADE can be used
to revoke these. It also means that you can't grant ADMIN OPTION on
a role back to a user who granted it directly or indirectly to you,
similar to how you can't give WITH GRANT OPTION on a privilege back
to a role which granted it directly or indirectly to you.
Previously, only the superuser could specify GRANTED BY with a user
other than the current user. Relax that rule to allow the grantor
to be any role whose privileges the current user posseses. This
doesn't improve compatibility with what we do for other object types,
where support for GRANTED BY is entirely vestigial, but it makes this
feature more usable and seems to make sense to change at the same time
we're changing related behaviors.
Along the way, fix "ALTER GROUP group_name ADD USER user_name" to
require the same privileges as "GRANT group_name TO user_name".
Previously, CREATEROLE privileges were sufficient for either, but
only the former form was permissible with ADMIN OPTION on the role.
Now, either CREATEROLE or ADMIN OPTION on the role suffices for
either spelling.
Patch by me, reviewed by Stephen Frost.
Discussion: http://postgr.es/m/CA+TgmoaFr-RZeQ+WoQ5nKPv97oT9+aDgK_a5+qWHSgbDsMp1Vg@mail.gmail.com
2022-08-22 17:35:17 +02:00
|
|
|
char *role = PQgetvalue(res, start, 0);
|
|
|
|
int i;
|
|
|
|
bool *done;
|
|
|
|
int remaining;
|
|
|
|
int prev_remaining = 0;
|
|
|
|
rolename_hash *ht;
|
|
|
|
|
|
|
|
/* All memberships for a single role should be adjacent. */
|
|
|
|
for (end = start; end < total; ++end)
|
|
|
|
{
|
|
|
|
char *otherrole;
|
|
|
|
|
|
|
|
otherrole = PQgetvalue(res, end, 0);
|
|
|
|
if (strcmp(role, otherrole) != 0)
|
|
|
|
break;
|
|
|
|
}
|
2005-07-31 19:19:22 +02:00
|
|
|
|
Make role grant system more consistent with other privileges.
Previously, membership of role A in role B could be recorded in the
catalog tables only once. This meant that a new grant of role A to
role B would overwrite the previous grant. For other object types, a
new grant of permission on an object - in this case role A - exists
along side the existing grant provided that the grantor is different.
Either grant can be revoked independently of the other, and
permissions remain so long as at least one grant remains. Make role
grants work similarly.
Previously, when granting membership in a role, the superuser could
specify any role whatsoever as the grantor, but for other object types,
the grantor of record must be either the owner of the object, or a
role that currently has privileges to perform a similar GRANT.
Implement the same scheme for role grants, treating the bootstrap
superuser as the role owner since roles do not have owners. This means
that attempting to revoke a grant, or admin option on a grant, can now
fail if there are dependent privileges, and that CASCADE can be used
to revoke these. It also means that you can't grant ADMIN OPTION on
a role back to a user who granted it directly or indirectly to you,
similar to how you can't give WITH GRANT OPTION on a privilege back
to a role which granted it directly or indirectly to you.
Previously, only the superuser could specify GRANTED BY with a user
other than the current user. Relax that rule to allow the grantor
to be any role whose privileges the current user posseses. This
doesn't improve compatibility with what we do for other object types,
where support for GRANTED BY is entirely vestigial, but it makes this
feature more usable and seems to make sense to change at the same time
we're changing related behaviors.
Along the way, fix "ALTER GROUP group_name ADD USER user_name" to
require the same privileges as "GRANT group_name TO user_name".
Previously, CREATEROLE privileges were sufficient for either, but
only the former form was permissible with ADMIN OPTION on the role.
Now, either CREATEROLE or ADMIN OPTION on the role suffices for
either spelling.
Patch by me, reviewed by Stephen Frost.
Discussion: http://postgr.es/m/CA+TgmoaFr-RZeQ+WoQ5nKPv97oT9+aDgK_a5+qWHSgbDsMp1Vg@mail.gmail.com
2022-08-22 17:35:17 +02:00
|
|
|
role = PQgetvalue(res, start, 0);
|
|
|
|
remaining = end - start;
|
|
|
|
done = pg_malloc0(remaining * sizeof(bool));
|
|
|
|
ht = rolename_create(remaining, NULL);
|
2007-05-15 22:20:21 +02:00
|
|
|
|
|
|
|
/*
|
2023-01-03 08:26:14 +01:00
|
|
|
* Make repeated passes over the grants for this role until all have
|
Make role grant system more consistent with other privileges.
Previously, membership of role A in role B could be recorded in the
catalog tables only once. This meant that a new grant of role A to
role B would overwrite the previous grant. For other object types, a
new grant of permission on an object - in this case role A - exists
along side the existing grant provided that the grantor is different.
Either grant can be revoked independently of the other, and
permissions remain so long as at least one grant remains. Make role
grants work similarly.
Previously, when granting membership in a role, the superuser could
specify any role whatsoever as the grantor, but for other object types,
the grantor of record must be either the owner of the object, or a
role that currently has privileges to perform a similar GRANT.
Implement the same scheme for role grants, treating the bootstrap
superuser as the role owner since roles do not have owners. This means
that attempting to revoke a grant, or admin option on a grant, can now
fail if there are dependent privileges, and that CASCADE can be used
to revoke these. It also means that you can't grant ADMIN OPTION on
a role back to a user who granted it directly or indirectly to you,
similar to how you can't give WITH GRANT OPTION on a privilege back
to a role which granted it directly or indirectly to you.
Previously, only the superuser could specify GRANTED BY with a user
other than the current user. Relax that rule to allow the grantor
to be any role whose privileges the current user posseses. This
doesn't improve compatibility with what we do for other object types,
where support for GRANTED BY is entirely vestigial, but it makes this
feature more usable and seems to make sense to change at the same time
we're changing related behaviors.
Along the way, fix "ALTER GROUP group_name ADD USER user_name" to
require the same privileges as "GRANT group_name TO user_name".
Previously, CREATEROLE privileges were sufficient for either, but
only the former form was permissible with ADMIN OPTION on the role.
Now, either CREATEROLE or ADMIN OPTION on the role suffices for
either spelling.
Patch by me, reviewed by Stephen Frost.
Discussion: http://postgr.es/m/CA+TgmoaFr-RZeQ+WoQ5nKPv97oT9+aDgK_a5+qWHSgbDsMp1Vg@mail.gmail.com
2022-08-22 17:35:17 +02:00
|
|
|
* been dumped.
|
2007-05-15 22:20:21 +02:00
|
|
|
*/
|
Make role grant system more consistent with other privileges.
Previously, membership of role A in role B could be recorded in the
catalog tables only once. This meant that a new grant of role A to
role B would overwrite the previous grant. For other object types, a
new grant of permission on an object - in this case role A - exists
along side the existing grant provided that the grantor is different.
Either grant can be revoked independently of the other, and
permissions remain so long as at least one grant remains. Make role
grants work similarly.
Previously, when granting membership in a role, the superuser could
specify any role whatsoever as the grantor, but for other object types,
the grantor of record must be either the owner of the object, or a
role that currently has privileges to perform a similar GRANT.
Implement the same scheme for role grants, treating the bootstrap
superuser as the role owner since roles do not have owners. This means
that attempting to revoke a grant, or admin option on a grant, can now
fail if there are dependent privileges, and that CASCADE can be used
to revoke these. It also means that you can't grant ADMIN OPTION on
a role back to a user who granted it directly or indirectly to you,
similar to how you can't give WITH GRANT OPTION on a privilege back
to a role which granted it directly or indirectly to you.
Previously, only the superuser could specify GRANTED BY with a user
other than the current user. Relax that rule to allow the grantor
to be any role whose privileges the current user posseses. This
doesn't improve compatibility with what we do for other object types,
where support for GRANTED BY is entirely vestigial, but it makes this
feature more usable and seems to make sense to change at the same time
we're changing related behaviors.
Along the way, fix "ALTER GROUP group_name ADD USER user_name" to
require the same privileges as "GRANT group_name TO user_name".
Previously, CREATEROLE privileges were sufficient for either, but
only the former form was permissible with ADMIN OPTION on the role.
Now, either CREATEROLE or ADMIN OPTION on the role suffices for
either spelling.
Patch by me, reviewed by Stephen Frost.
Discussion: http://postgr.es/m/CA+TgmoaFr-RZeQ+WoQ5nKPv97oT9+aDgK_a5+qWHSgbDsMp1Vg@mail.gmail.com
2022-08-22 17:35:17 +02:00
|
|
|
while (remaining > 0)
|
2007-05-15 22:20:21 +02:00
|
|
|
{
|
Make role grant system more consistent with other privileges.
Previously, membership of role A in role B could be recorded in the
catalog tables only once. This meant that a new grant of role A to
role B would overwrite the previous grant. For other object types, a
new grant of permission on an object - in this case role A - exists
along side the existing grant provided that the grantor is different.
Either grant can be revoked independently of the other, and
permissions remain so long as at least one grant remains. Make role
grants work similarly.
Previously, when granting membership in a role, the superuser could
specify any role whatsoever as the grantor, but for other object types,
the grantor of record must be either the owner of the object, or a
role that currently has privileges to perform a similar GRANT.
Implement the same scheme for role grants, treating the bootstrap
superuser as the role owner since roles do not have owners. This means
that attempting to revoke a grant, or admin option on a grant, can now
fail if there are dependent privileges, and that CASCADE can be used
to revoke these. It also means that you can't grant ADMIN OPTION on
a role back to a user who granted it directly or indirectly to you,
similar to how you can't give WITH GRANT OPTION on a privilege back
to a role which granted it directly or indirectly to you.
Previously, only the superuser could specify GRANTED BY with a user
other than the current user. Relax that rule to allow the grantor
to be any role whose privileges the current user posseses. This
doesn't improve compatibility with what we do for other object types,
where support for GRANTED BY is entirely vestigial, but it makes this
feature more usable and seems to make sense to change at the same time
we're changing related behaviors.
Along the way, fix "ALTER GROUP group_name ADD USER user_name" to
require the same privileges as "GRANT group_name TO user_name".
Previously, CREATEROLE privileges were sufficient for either, but
only the former form was permissible with ADMIN OPTION on the role.
Now, either CREATEROLE or ADMIN OPTION on the role suffices for
either spelling.
Patch by me, reviewed by Stephen Frost.
Discussion: http://postgr.es/m/CA+TgmoaFr-RZeQ+WoQ5nKPv97oT9+aDgK_a5+qWHSgbDsMp1Vg@mail.gmail.com
2022-08-22 17:35:17 +02:00
|
|
|
/*
|
|
|
|
* We should make progress on every iteration, because a notional
|
|
|
|
* graph whose vertices are grants and whose edges point from
|
|
|
|
* grantors to members should be connected and acyclic. If we fail
|
|
|
|
* to make progress, either we or the server have messed up.
|
|
|
|
*/
|
|
|
|
if (remaining == prev_remaining)
|
|
|
|
{
|
|
|
|
pg_log_error("could not find a legal dump ordering for memberships in role \"%s\"",
|
|
|
|
role);
|
|
|
|
PQfinish(conn);
|
|
|
|
exit_nicely(1);
|
|
|
|
}
|
2023-04-26 14:24:13 +02:00
|
|
|
prev_remaining = remaining;
|
2007-05-15 22:20:21 +02:00
|
|
|
|
Make role grant system more consistent with other privileges.
Previously, membership of role A in role B could be recorded in the
catalog tables only once. This meant that a new grant of role A to
role B would overwrite the previous grant. For other object types, a
new grant of permission on an object - in this case role A - exists
along side the existing grant provided that the grantor is different.
Either grant can be revoked independently of the other, and
permissions remain so long as at least one grant remains. Make role
grants work similarly.
Previously, when granting membership in a role, the superuser could
specify any role whatsoever as the grantor, but for other object types,
the grantor of record must be either the owner of the object, or a
role that currently has privileges to perform a similar GRANT.
Implement the same scheme for role grants, treating the bootstrap
superuser as the role owner since roles do not have owners. This means
that attempting to revoke a grant, or admin option on a grant, can now
fail if there are dependent privileges, and that CASCADE can be used
to revoke these. It also means that you can't grant ADMIN OPTION on
a role back to a user who granted it directly or indirectly to you,
similar to how you can't give WITH GRANT OPTION on a privilege back
to a role which granted it directly or indirectly to you.
Previously, only the superuser could specify GRANTED BY with a user
other than the current user. Relax that rule to allow the grantor
to be any role whose privileges the current user posseses. This
doesn't improve compatibility with what we do for other object types,
where support for GRANTED BY is entirely vestigial, but it makes this
feature more usable and seems to make sense to change at the same time
we're changing related behaviors.
Along the way, fix "ALTER GROUP group_name ADD USER user_name" to
require the same privileges as "GRANT group_name TO user_name".
Previously, CREATEROLE privileges were sufficient for either, but
only the former form was permissible with ADMIN OPTION on the role.
Now, either CREATEROLE or ADMIN OPTION on the role suffices for
either spelling.
Patch by me, reviewed by Stephen Frost.
Discussion: http://postgr.es/m/CA+TgmoaFr-RZeQ+WoQ5nKPv97oT9+aDgK_a5+qWHSgbDsMp1Vg@mail.gmail.com
2022-08-22 17:35:17 +02:00
|
|
|
/* Make one pass over the grants for this role. */
|
|
|
|
for (i = start; i < end; ++i)
|
|
|
|
{
|
|
|
|
char *member;
|
|
|
|
char *admin_option;
|
|
|
|
char *grantorid;
|
|
|
|
char *grantor;
|
Add a SET option to the GRANT command.
Similar to how the INHERIT option controls whether or not the
permissions of the granted role are automatically available to the
grantee, the new SET permission controls whether or not the grantee
may use the SET ROLE command to assume the privileges of the granted
role.
In addition, the new SET permission controls whether or not it
is possible to transfer ownership of objects to the target role
or to create new objects owned by the target role using commands
such as CREATE DATABASE .. OWNER. We could alternatively have made
this controlled by the INHERIT option, or allow it when either
option is given. An advantage of this approach is that if you
are granted a predefined role with INHERIT TRUE, SET FALSE, you
can't go and create objects owned by that role.
The underlying theory here is that the ability to create objects
as a target role is not a privilege per se, and thus does not
depend on whether you inherit the target role's privileges. However,
it's surely something you could do anyway if you could SET ROLE
to the target role, and thus making it contingent on whether you
have that ability is reasonable.
Design review by Nathan Bossat, Wolfgang Walther, Jeff Davis,
Peter Eisentraut, and Stephen Frost.
Discussion: http://postgr.es/m/CA+Tgmob+zDSRS6JXYrgq0NWdzCXuTNzT5eK54Dn2hhgt17nm8A@mail.gmail.com
2022-11-18 18:32:50 +01:00
|
|
|
char *set_option = "true";
|
Make role grant system more consistent with other privileges.
Previously, membership of role A in role B could be recorded in the
catalog tables only once. This meant that a new grant of role A to
role B would overwrite the previous grant. For other object types, a
new grant of permission on an object - in this case role A - exists
along side the existing grant provided that the grantor is different.
Either grant can be revoked independently of the other, and
permissions remain so long as at least one grant remains. Make role
grants work similarly.
Previously, when granting membership in a role, the superuser could
specify any role whatsoever as the grantor, but for other object types,
the grantor of record must be either the owner of the object, or a
role that currently has privileges to perform a similar GRANT.
Implement the same scheme for role grants, treating the bootstrap
superuser as the role owner since roles do not have owners. This means
that attempting to revoke a grant, or admin option on a grant, can now
fail if there are dependent privileges, and that CASCADE can be used
to revoke these. It also means that you can't grant ADMIN OPTION on
a role back to a user who granted it directly or indirectly to you,
similar to how you can't give WITH GRANT OPTION on a privilege back
to a role which granted it directly or indirectly to you.
Previously, only the superuser could specify GRANTED BY with a user
other than the current user. Relax that rule to allow the grantor
to be any role whose privileges the current user posseses. This
doesn't improve compatibility with what we do for other object types,
where support for GRANTED BY is entirely vestigial, but it makes this
feature more usable and seems to make sense to change at the same time
we're changing related behaviors.
Along the way, fix "ALTER GROUP group_name ADD USER user_name" to
require the same privileges as "GRANT group_name TO user_name".
Previously, CREATEROLE privileges were sufficient for either, but
only the former form was permissible with ADMIN OPTION on the role.
Now, either CREATEROLE or ADMIN OPTION on the role suffices for
either spelling.
Patch by me, reviewed by Stephen Frost.
Discussion: http://postgr.es/m/CA+TgmoaFr-RZeQ+WoQ5nKPv97oT9+aDgK_a5+qWHSgbDsMp1Vg@mail.gmail.com
2022-08-22 17:35:17 +02:00
|
|
|
bool found;
|
|
|
|
|
|
|
|
/* If we already did this grant, don't do it again. */
|
|
|
|
if (done[i - start])
|
|
|
|
continue;
|
|
|
|
|
|
|
|
member = PQgetvalue(res, i, 1);
|
|
|
|
grantorid = PQgetvalue(res, i, 2);
|
|
|
|
grantor = PQgetvalue(res, i, 3);
|
|
|
|
admin_option = PQgetvalue(res, i, 4);
|
Add a SET option to the GRANT command.
Similar to how the INHERIT option controls whether or not the
permissions of the granted role are automatically available to the
grantee, the new SET permission controls whether or not the grantee
may use the SET ROLE command to assume the privileges of the granted
role.
In addition, the new SET permission controls whether or not it
is possible to transfer ownership of objects to the target role
or to create new objects owned by the target role using commands
such as CREATE DATABASE .. OWNER. We could alternatively have made
this controlled by the INHERIT option, or allow it when either
option is given. An advantage of this approach is that if you
are granted a predefined role with INHERIT TRUE, SET FALSE, you
can't go and create objects owned by that role.
The underlying theory here is that the ability to create objects
as a target role is not a privilege per se, and thus does not
depend on whether you inherit the target role's privileges. However,
it's surely something you could do anyway if you could SET ROLE
to the target role, and thus making it contingent on whether you
have that ability is reasonable.
Design review by Nathan Bossat, Wolfgang Walther, Jeff Davis,
Peter Eisentraut, and Stephen Frost.
Discussion: http://postgr.es/m/CA+Tgmob+zDSRS6JXYrgq0NWdzCXuTNzT5eK54Dn2hhgt17nm8A@mail.gmail.com
2022-11-18 18:32:50 +01:00
|
|
|
if (dump_grant_options)
|
|
|
|
set_option = PQgetvalue(res, i, i_set_option);
|
Make role grant system more consistent with other privileges.
Previously, membership of role A in role B could be recorded in the
catalog tables only once. This meant that a new grant of role A to
role B would overwrite the previous grant. For other object types, a
new grant of permission on an object - in this case role A - exists
along side the existing grant provided that the grantor is different.
Either grant can be revoked independently of the other, and
permissions remain so long as at least one grant remains. Make role
grants work similarly.
Previously, when granting membership in a role, the superuser could
specify any role whatsoever as the grantor, but for other object types,
the grantor of record must be either the owner of the object, or a
role that currently has privileges to perform a similar GRANT.
Implement the same scheme for role grants, treating the bootstrap
superuser as the role owner since roles do not have owners. This means
that attempting to revoke a grant, or admin option on a grant, can now
fail if there are dependent privileges, and that CASCADE can be used
to revoke these. It also means that you can't grant ADMIN OPTION on
a role back to a user who granted it directly or indirectly to you,
similar to how you can't give WITH GRANT OPTION on a privilege back
to a role which granted it directly or indirectly to you.
Previously, only the superuser could specify GRANTED BY with a user
other than the current user. Relax that rule to allow the grantor
to be any role whose privileges the current user posseses. This
doesn't improve compatibility with what we do for other object types,
where support for GRANTED BY is entirely vestigial, but it makes this
feature more usable and seems to make sense to change at the same time
we're changing related behaviors.
Along the way, fix "ALTER GROUP group_name ADD USER user_name" to
require the same privileges as "GRANT group_name TO user_name".
Previously, CREATEROLE privileges were sufficient for either, but
only the former form was permissible with ADMIN OPTION on the role.
Now, either CREATEROLE or ADMIN OPTION on the role suffices for
either spelling.
Patch by me, reviewed by Stephen Frost.
Discussion: http://postgr.es/m/CA+TgmoaFr-RZeQ+WoQ5nKPv97oT9+aDgK_a5+qWHSgbDsMp1Vg@mail.gmail.com
2022-08-22 17:35:17 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If we're not dumping grantors or if the grantor is the
|
|
|
|
* bootstrap superuser, it's fine to dump this now. Otherwise,
|
|
|
|
* it's got to be someone who has already been granted ADMIN
|
|
|
|
* OPTION.
|
|
|
|
*/
|
|
|
|
if (dump_grantors &&
|
|
|
|
atooid(grantorid) != BOOTSTRAP_SUPERUSERID &&
|
|
|
|
rolename_lookup(ht, grantor) == NULL)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* Remember that we did this so that we don't do it again. */
|
|
|
|
done[i - start] = true;
|
|
|
|
--remaining;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If ADMIN OPTION is being granted, remember that grants
|
|
|
|
* listing this member as the grantor can now be dumped.
|
|
|
|
*/
|
|
|
|
if (*admin_option == 't')
|
|
|
|
rolename_insert(ht, member, &found);
|
|
|
|
|
|
|
|
/* Generate the actual GRANT statement. */
|
2022-08-25 16:06:02 +02:00
|
|
|
resetPQExpBuffer(optbuf);
|
Make role grant system more consistent with other privileges.
Previously, membership of role A in role B could be recorded in the
catalog tables only once. This meant that a new grant of role A to
role B would overwrite the previous grant. For other object types, a
new grant of permission on an object - in this case role A - exists
along side the existing grant provided that the grantor is different.
Either grant can be revoked independently of the other, and
permissions remain so long as at least one grant remains. Make role
grants work similarly.
Previously, when granting membership in a role, the superuser could
specify any role whatsoever as the grantor, but for other object types,
the grantor of record must be either the owner of the object, or a
role that currently has privileges to perform a similar GRANT.
Implement the same scheme for role grants, treating the bootstrap
superuser as the role owner since roles do not have owners. This means
that attempting to revoke a grant, or admin option on a grant, can now
fail if there are dependent privileges, and that CASCADE can be used
to revoke these. It also means that you can't grant ADMIN OPTION on
a role back to a user who granted it directly or indirectly to you,
similar to how you can't give WITH GRANT OPTION on a privilege back
to a role which granted it directly or indirectly to you.
Previously, only the superuser could specify GRANTED BY with a user
other than the current user. Relax that rule to allow the grantor
to be any role whose privileges the current user posseses. This
doesn't improve compatibility with what we do for other object types,
where support for GRANTED BY is entirely vestigial, but it makes this
feature more usable and seems to make sense to change at the same time
we're changing related behaviors.
Along the way, fix "ALTER GROUP group_name ADD USER user_name" to
require the same privileges as "GRANT group_name TO user_name".
Previously, CREATEROLE privileges were sufficient for either, but
only the former form was permissible with ADMIN OPTION on the role.
Now, either CREATEROLE or ADMIN OPTION on the role suffices for
either spelling.
Patch by me, reviewed by Stephen Frost.
Discussion: http://postgr.es/m/CA+TgmoaFr-RZeQ+WoQ5nKPv97oT9+aDgK_a5+qWHSgbDsMp1Vg@mail.gmail.com
2022-08-22 17:35:17 +02:00
|
|
|
fprintf(OPF, "GRANT %s", fmtId(role));
|
|
|
|
fprintf(OPF, " TO %s", fmtId(member));
|
|
|
|
if (*admin_option == 't')
|
2022-08-25 16:06:02 +02:00
|
|
|
appendPQExpBufferStr(optbuf, "ADMIN OPTION");
|
Add a SET option to the GRANT command.
Similar to how the INHERIT option controls whether or not the
permissions of the granted role are automatically available to the
grantee, the new SET permission controls whether or not the grantee
may use the SET ROLE command to assume the privileges of the granted
role.
In addition, the new SET permission controls whether or not it
is possible to transfer ownership of objects to the target role
or to create new objects owned by the target role using commands
such as CREATE DATABASE .. OWNER. We could alternatively have made
this controlled by the INHERIT option, or allow it when either
option is given. An advantage of this approach is that if you
are granted a predefined role with INHERIT TRUE, SET FALSE, you
can't go and create objects owned by that role.
The underlying theory here is that the ability to create objects
as a target role is not a privilege per se, and thus does not
depend on whether you inherit the target role's privileges. However,
it's surely something you could do anyway if you could SET ROLE
to the target role, and thus making it contingent on whether you
have that ability is reasonable.
Design review by Nathan Bossat, Wolfgang Walther, Jeff Davis,
Peter Eisentraut, and Stephen Frost.
Discussion: http://postgr.es/m/CA+Tgmob+zDSRS6JXYrgq0NWdzCXuTNzT5eK54Dn2hhgt17nm8A@mail.gmail.com
2022-11-18 18:32:50 +01:00
|
|
|
if (dump_grant_options)
|
2022-08-25 16:06:02 +02:00
|
|
|
{
|
|
|
|
char *inherit_option;
|
|
|
|
|
|
|
|
if (optbuf->data[0] != '\0')
|
|
|
|
appendPQExpBufferStr(optbuf, ", ");
|
|
|
|
inherit_option = PQgetvalue(res, i, i_inherit_option);
|
|
|
|
appendPQExpBuffer(optbuf, "INHERIT %s",
|
|
|
|
*inherit_option == 't' ?
|
|
|
|
"TRUE" : "FALSE");
|
|
|
|
}
|
Add a SET option to the GRANT command.
Similar to how the INHERIT option controls whether or not the
permissions of the granted role are automatically available to the
grantee, the new SET permission controls whether or not the grantee
may use the SET ROLE command to assume the privileges of the granted
role.
In addition, the new SET permission controls whether or not it
is possible to transfer ownership of objects to the target role
or to create new objects owned by the target role using commands
such as CREATE DATABASE .. OWNER. We could alternatively have made
this controlled by the INHERIT option, or allow it when either
option is given. An advantage of this approach is that if you
are granted a predefined role with INHERIT TRUE, SET FALSE, you
can't go and create objects owned by that role.
The underlying theory here is that the ability to create objects
as a target role is not a privilege per se, and thus does not
depend on whether you inherit the target role's privileges. However,
it's surely something you could do anyway if you could SET ROLE
to the target role, and thus making it contingent on whether you
have that ability is reasonable.
Design review by Nathan Bossat, Wolfgang Walther, Jeff Davis,
Peter Eisentraut, and Stephen Frost.
Discussion: http://postgr.es/m/CA+Tgmob+zDSRS6JXYrgq0NWdzCXuTNzT5eK54Dn2hhgt17nm8A@mail.gmail.com
2022-11-18 18:32:50 +01:00
|
|
|
if (*set_option != 't')
|
|
|
|
{
|
|
|
|
if (optbuf->data[0] != '\0')
|
|
|
|
appendPQExpBufferStr(optbuf, ", ");
|
|
|
|
appendPQExpBuffer(optbuf, "SET FALSE");
|
|
|
|
}
|
2022-08-25 16:06:02 +02:00
|
|
|
if (optbuf->data[0] != '\0')
|
|
|
|
fprintf(OPF, " WITH %s", optbuf->data);
|
Make role grant system more consistent with other privileges.
Previously, membership of role A in role B could be recorded in the
catalog tables only once. This meant that a new grant of role A to
role B would overwrite the previous grant. For other object types, a
new grant of permission on an object - in this case role A - exists
along side the existing grant provided that the grantor is different.
Either grant can be revoked independently of the other, and
permissions remain so long as at least one grant remains. Make role
grants work similarly.
Previously, when granting membership in a role, the superuser could
specify any role whatsoever as the grantor, but for other object types,
the grantor of record must be either the owner of the object, or a
role that currently has privileges to perform a similar GRANT.
Implement the same scheme for role grants, treating the bootstrap
superuser as the role owner since roles do not have owners. This means
that attempting to revoke a grant, or admin option on a grant, can now
fail if there are dependent privileges, and that CASCADE can be used
to revoke these. It also means that you can't grant ADMIN OPTION on
a role back to a user who granted it directly or indirectly to you,
similar to how you can't give WITH GRANT OPTION on a privilege back
to a role which granted it directly or indirectly to you.
Previously, only the superuser could specify GRANTED BY with a user
other than the current user. Relax that rule to allow the grantor
to be any role whose privileges the current user posseses. This
doesn't improve compatibility with what we do for other object types,
where support for GRANTED BY is entirely vestigial, but it makes this
feature more usable and seems to make sense to change at the same time
we're changing related behaviors.
Along the way, fix "ALTER GROUP group_name ADD USER user_name" to
require the same privileges as "GRANT group_name TO user_name".
Previously, CREATEROLE privileges were sufficient for either, but
only the former form was permissible with ADMIN OPTION on the role.
Now, either CREATEROLE or ADMIN OPTION on the role suffices for
either spelling.
Patch by me, reviewed by Stephen Frost.
Discussion: http://postgr.es/m/CA+TgmoaFr-RZeQ+WoQ5nKPv97oT9+aDgK_a5+qWHSgbDsMp1Vg@mail.gmail.com
2022-08-22 17:35:17 +02:00
|
|
|
if (dump_grantors)
|
|
|
|
fprintf(OPF, " GRANTED BY %s", fmtId(grantor));
|
|
|
|
fprintf(OPF, ";\n");
|
|
|
|
}
|
2007-05-15 22:20:21 +02:00
|
|
|
}
|
Make role grant system more consistent with other privileges.
Previously, membership of role A in role B could be recorded in the
catalog tables only once. This meant that a new grant of role A to
role B would overwrite the previous grant. For other object types, a
new grant of permission on an object - in this case role A - exists
along side the existing grant provided that the grantor is different.
Either grant can be revoked independently of the other, and
permissions remain so long as at least one grant remains. Make role
grants work similarly.
Previously, when granting membership in a role, the superuser could
specify any role whatsoever as the grantor, but for other object types,
the grantor of record must be either the owner of the object, or a
role that currently has privileges to perform a similar GRANT.
Implement the same scheme for role grants, treating the bootstrap
superuser as the role owner since roles do not have owners. This means
that attempting to revoke a grant, or admin option on a grant, can now
fail if there are dependent privileges, and that CASCADE can be used
to revoke these. It also means that you can't grant ADMIN OPTION on
a role back to a user who granted it directly or indirectly to you,
similar to how you can't give WITH GRANT OPTION on a privilege back
to a role which granted it directly or indirectly to you.
Previously, only the superuser could specify GRANTED BY with a user
other than the current user. Relax that rule to allow the grantor
to be any role whose privileges the current user posseses. This
doesn't improve compatibility with what we do for other object types,
where support for GRANTED BY is entirely vestigial, but it makes this
feature more usable and seems to make sense to change at the same time
we're changing related behaviors.
Along the way, fix "ALTER GROUP group_name ADD USER user_name" to
require the same privileges as "GRANT group_name TO user_name".
Previously, CREATEROLE privileges were sufficient for either, but
only the former form was permissible with ADMIN OPTION on the role.
Now, either CREATEROLE or ADMIN OPTION on the role suffices for
either spelling.
Patch by me, reviewed by Stephen Frost.
Discussion: http://postgr.es/m/CA+TgmoaFr-RZeQ+WoQ5nKPv97oT9+aDgK_a5+qWHSgbDsMp1Vg@mail.gmail.com
2022-08-22 17:35:17 +02:00
|
|
|
|
|
|
|
rolename_destroy(ht);
|
|
|
|
pg_free(done);
|
|
|
|
start = end;
|
2005-07-31 19:19:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
PQclear(res);
|
2017-03-07 15:00:54 +01:00
|
|
|
destroyPQExpBuffer(buf);
|
2005-07-31 19:19:22 +02:00
|
|
|
|
2007-01-25 04:30:43 +01:00
|
|
|
fprintf(OPF, "\n\n");
|
2005-07-31 19:19:22 +02:00
|
|
|
}
|
2002-08-27 20:57:26 +02:00
|
|
|
|
2009-04-11 22:23:05 +02:00
|
|
|
|
2022-04-06 19:24:33 +02:00
|
|
|
/*
|
|
|
|
* Dump role configuration parameter privileges. This code is used for 15.0
|
|
|
|
* and later servers.
|
|
|
|
*
|
|
|
|
* Note: we expect dumpRoles already created all the roles, but there are
|
|
|
|
* no per-role configuration parameter privileges yet.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
dumpRoleGUCPrivs(PGconn *conn)
|
|
|
|
{
|
|
|
|
PGresult *res;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get all parameters that have non-default acls defined.
|
|
|
|
*/
|
|
|
|
res = executeQuery(conn, "SELECT parname, "
|
|
|
|
"pg_catalog.pg_get_userbyid(" CppAsString2(BOOTSTRAP_SUPERUSERID) ") AS parowner, "
|
|
|
|
"paracl, "
|
|
|
|
"pg_catalog.acldefault('p', " CppAsString2(BOOTSTRAP_SUPERUSERID) ") AS acldefault "
|
|
|
|
"FROM pg_catalog.pg_parameter_acl "
|
|
|
|
"ORDER BY 1");
|
|
|
|
|
|
|
|
if (PQntuples(res) > 0)
|
|
|
|
fprintf(OPF, "--\n-- Role privileges on configuration parameters\n--\n\n");
|
|
|
|
|
|
|
|
for (i = 0; i < PQntuples(res); i++)
|
|
|
|
{
|
|
|
|
PQExpBuffer buf = createPQExpBuffer();
|
|
|
|
char *parname = PQgetvalue(res, i, 0);
|
|
|
|
char *parowner = PQgetvalue(res, i, 1);
|
|
|
|
char *paracl = PQgetvalue(res, i, 2);
|
|
|
|
char *acldefault = PQgetvalue(res, i, 3);
|
|
|
|
char *fparname;
|
|
|
|
|
|
|
|
/* needed for buildACLCommands() */
|
|
|
|
fparname = pg_strdup(fmtId(parname));
|
|
|
|
|
|
|
|
if (!buildACLCommands(fparname, NULL, NULL, "PARAMETER",
|
|
|
|
paracl, acldefault,
|
|
|
|
parowner, "", server_version, buf))
|
|
|
|
{
|
|
|
|
pg_log_error("could not parse ACL list (%s) for parameter \"%s\"",
|
|
|
|
paracl, parname);
|
|
|
|
PQfinish(conn);
|
|
|
|
exit_nicely(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
fprintf(OPF, "%s", buf->data);
|
|
|
|
|
|
|
|
free(fparname);
|
|
|
|
destroyPQExpBuffer(buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
PQclear(res);
|
|
|
|
fprintf(OPF, "\n\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-04-11 22:23:05 +02:00
|
|
|
/*
|
|
|
|
* Drop tablespaces.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
dropTablespaces(PGconn *conn)
|
|
|
|
{
|
|
|
|
PGresult *res;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get all tablespaces except built-in ones (which we assume are named
|
|
|
|
* pg_xxx)
|
|
|
|
*/
|
|
|
|
res = executeQuery(conn, "SELECT spcname "
|
|
|
|
"FROM pg_catalog.pg_tablespace "
|
|
|
|
"WHERE spcname !~ '^pg_' "
|
|
|
|
"ORDER BY 1");
|
|
|
|
|
|
|
|
if (PQntuples(res) > 0)
|
|
|
|
fprintf(OPF, "--\n-- Drop tablespaces\n--\n\n");
|
|
|
|
|
|
|
|
for (i = 0; i < PQntuples(res); i++)
|
|
|
|
{
|
|
|
|
char *spcname = PQgetvalue(res, i, 0);
|
|
|
|
|
2014-03-03 19:02:18 +01:00
|
|
|
fprintf(OPF, "DROP TABLESPACE %s%s;\n",
|
|
|
|
if_exists ? "IF EXISTS " : "",
|
|
|
|
fmtId(spcname));
|
2009-04-11 22:23:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
PQclear(res);
|
|
|
|
|
|
|
|
fprintf(OPF, "\n\n");
|
|
|
|
}
|
|
|
|
|
2004-06-18 08:14:31 +02:00
|
|
|
/*
|
|
|
|
* Dump tablespaces.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
dumpTablespaces(PGconn *conn)
|
|
|
|
{
|
|
|
|
PGresult *res;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
/*
|
2004-06-21 15:36:42 +02:00
|
|
|
* Get all tablespaces except built-in ones (which we assume are named
|
|
|
|
* pg_xxx)
|
2004-06-18 08:14:31 +02:00
|
|
|
*/
|
2021-12-14 23:09:07 +01:00
|
|
|
res = executeQuery(conn, "SELECT oid, spcname, "
|
|
|
|
"pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
|
|
|
|
"pg_catalog.pg_tablespace_location(oid), "
|
|
|
|
"spcacl, acldefault('t', spcowner) AS acldefault, "
|
|
|
|
"array_to_string(spcoptions, ', '),"
|
|
|
|
"pg_catalog.shobj_description(oid, 'pg_tablespace') "
|
|
|
|
"FROM pg_catalog.pg_tablespace "
|
|
|
|
"WHERE spcname !~ '^pg_' "
|
|
|
|
"ORDER BY 1");
|
2004-08-29 07:07:03 +02:00
|
|
|
|
2004-07-19 23:39:48 +02:00
|
|
|
if (PQntuples(res) > 0)
|
2007-01-25 04:30:43 +01:00
|
|
|
fprintf(OPF, "--\n-- Tablespaces\n--\n\n");
|
2004-06-18 08:14:31 +02:00
|
|
|
|
|
|
|
for (i = 0; i < PQntuples(res); i++)
|
|
|
|
{
|
|
|
|
PQExpBuffer buf = createPQExpBuffer();
|
Avoid using unsafe search_path settings during dump and restore.
Historically, pg_dump has "set search_path = foo, pg_catalog" when
dumping an object in schema "foo", and has also caused that setting
to be used while restoring the object. This is problematic because
functions and operators in schema "foo" could capture references meant
to refer to pg_catalog entries, both in the queries issued by pg_dump
and those issued during the subsequent restore run. That could
result in dump/restore misbehavior, or in privilege escalation if a
nefarious user installs trojan-horse functions or operators.
This patch changes pg_dump so that it does not change the search_path
dynamically. The emitted restore script sets the search_path to what
was used at dump time, and then leaves it alone thereafter. Created
objects are placed in the correct schema, regardless of the active
search_path, by dint of schema-qualifying their names in the CREATE
commands, as well as in subsequent ALTER and ALTER-like commands.
Since this change requires a change in the behavior of pg_restore
when processing an archive file made according to this new convention,
bump the archive file version number; old versions of pg_restore will
therefore refuse to process files made with new versions of pg_dump.
Security: CVE-2018-1058
2018-02-26 16:18:21 +01:00
|
|
|
Oid spcoid = atooid(PQgetvalue(res, i, 0));
|
2011-07-20 19:18:24 +02:00
|
|
|
char *spcname = PQgetvalue(res, i, 1);
|
|
|
|
char *spcowner = PQgetvalue(res, i, 2);
|
|
|
|
char *spclocation = PQgetvalue(res, i, 3);
|
|
|
|
char *spcacl = PQgetvalue(res, i, 4);
|
2021-12-06 18:39:45 +01:00
|
|
|
char *acldefault = PQgetvalue(res, i, 5);
|
2016-07-17 15:04:46 +02:00
|
|
|
char *spcoptions = PQgetvalue(res, i, 6);
|
|
|
|
char *spccomment = PQgetvalue(res, i, 7);
|
2004-06-18 08:14:31 +02:00
|
|
|
char *fspcname;
|
|
|
|
|
|
|
|
/* needed for buildACLCommands() */
|
2011-11-25 21:40:51 +01:00
|
|
|
fspcname = pg_strdup(fmtId(spcname));
|
2004-06-18 08:14:31 +02:00
|
|
|
|
2022-02-17 16:53:51 +01:00
|
|
|
if (binary_upgrade)
|
|
|
|
{
|
|
|
|
appendPQExpBufferStr(buf, "\n-- For binary upgrade, must preserve pg_tablespace oid\n");
|
|
|
|
appendPQExpBuffer(buf, "SELECT pg_catalog.binary_upgrade_set_next_pg_tablespace_oid('%u'::pg_catalog.oid);\n", spcoid);
|
|
|
|
}
|
pg_upgrade: Preserve relfilenodes and tablespace OIDs.
Currently, database OIDs, relfilenodes, and tablespace OIDs can all
change when a cluster is upgraded using pg_upgrade. It seems better
to preserve them, because (1) it makes troubleshooting pg_upgrade
easier, since you don't have to do a lot of work to match up files
in the old and new clusters, (2) it allows 'rsync' to save bandwidth
when used to re-sync a cluster after an upgrade, and (3) if we ever
encrypt or sign blocks, we would likely want to use a nonce that
depends on these values.
This patch only arranges to preserve relfilenodes and tablespace
OIDs. The task of preserving database OIDs is left for another patch,
since it involves some complexities that don't exist in these cases.
Database OIDs have a similar issue, but there are some tricky points
in that case that do not apply to these cases, so that problem is left
for another patch.
Shruthi KC, based on an earlier patch from Antonin Houska, reviewed
and with some adjustments by me.
Discussion: http://postgr.es/m/CA+TgmoYgTwYcUmB=e8+hRHOFA0kkS6Kde85+UNdon6q7bt1niQ@mail.gmail.com
2022-01-17 19:32:44 +01:00
|
|
|
|
2004-06-18 08:14:31 +02:00
|
|
|
appendPQExpBuffer(buf, "CREATE TABLESPACE %s", fspcname);
|
|
|
|
appendPQExpBuffer(buf, " OWNER %s", fmtId(spcowner));
|
2002-08-27 20:57:26 +02:00
|
|
|
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(buf, " LOCATION ");
|
2023-08-09 01:56:05 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* In-place tablespaces use a relative path, and need to be dumped
|
|
|
|
* with an empty string as location.
|
|
|
|
*/
|
|
|
|
if (is_absolute_path(spclocation))
|
|
|
|
appendStringLiteralConn(buf, spclocation, conn);
|
|
|
|
else
|
|
|
|
appendStringLiteralConn(buf, "", conn);
|
|
|
|
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(buf, ";\n");
|
2004-06-18 08:14:31 +02:00
|
|
|
|
2010-01-05 22:54:00 +01:00
|
|
|
if (spcoptions && spcoptions[0] != '\0')
|
|
|
|
appendPQExpBuffer(buf, "ALTER TABLESPACE %s SET (%s);\n",
|
|
|
|
fspcname, spcoptions);
|
|
|
|
|
2021-12-06 18:39:45 +01:00
|
|
|
/* tablespaces can't have initprivs */
|
|
|
|
|
2004-06-18 08:14:31 +02:00
|
|
|
if (!skip_acls &&
|
Avoid using unsafe search_path settings during dump and restore.
Historically, pg_dump has "set search_path = foo, pg_catalog" when
dumping an object in schema "foo", and has also caused that setting
to be used while restoring the object. This is problematic because
functions and operators in schema "foo" could capture references meant
to refer to pg_catalog entries, both in the queries issued by pg_dump
and those issued during the subsequent restore run. That could
result in dump/restore misbehavior, or in privilege escalation if a
nefarious user installs trojan-horse functions or operators.
This patch changes pg_dump so that it does not change the search_path
dynamically. The emitted restore script sets the search_path to what
was used at dump time, and then leaves it alone thereafter. Created
objects are placed in the correct schema, regardless of the active
search_path, by dint of schema-qualifying their names in the CREATE
commands, as well as in subsequent ALTER and ALTER-like commands.
Since this change requires a change in the behavior of pg_restore
when processing an archive file made according to this new convention,
bump the archive file version number; old versions of pg_restore will
therefore refuse to process files made with new versions of pg_dump.
Security: CVE-2018-1058
2018-02-26 16:18:21 +01:00
|
|
|
!buildACLCommands(fspcname, NULL, NULL, "TABLESPACE",
|
2021-12-06 18:39:45 +01:00
|
|
|
spcacl, acldefault,
|
2016-04-07 03:45:32 +02:00
|
|
|
spcowner, "", server_version, buf))
|
2004-06-18 08:14:31 +02:00
|
|
|
{
|
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
|
|
|
pg_log_error("could not parse ACL list (%s) for tablespace \"%s\"",
|
|
|
|
spcacl, spcname);
|
2004-06-18 08:14:31 +02:00
|
|
|
PQfinish(conn);
|
2012-02-16 17:49:20 +01:00
|
|
|
exit_nicely(1);
|
2004-06-18 08:14:31 +02:00
|
|
|
}
|
|
|
|
|
Support --no-comments in pg_dump, pg_dumpall, pg_restore.
We have switches already to suppress other subsidiary object properties,
such as ACLs, security labels, ownership, and tablespaces, so just on
the grounds of symmetry we should allow suppressing comments as well.
Also, commit 0d4e6ed30 added a positive reason to have this feature,
i.e. to allow obtaining the old behavior of selective pg_restore should
anyone desire that.
Recent commits have removed the cases where pg_dump emitted comments on
built-in objects that the restoring user might not have privileges to
comment on, so the original primary motivation for this feature is gone,
but it still seems at least somewhat useful in its own right.
Robins Tharakan, reviewed by Fabrízio Mello
Discussion: https://postgr.es/m/CAEP4nAx22Z4ch74oJGzr5RyyjcyUSbpiFLyeYXX8pehfou92ug@mail.gmail.com
2018-01-25 21:27:24 +01:00
|
|
|
if (!no_comments && spccomment && spccomment[0] != '\0')
|
2006-02-12 04:22:21 +01:00
|
|
|
{
|
|
|
|
appendPQExpBuffer(buf, "COMMENT ON TABLESPACE %s IS ", fspcname);
|
2006-05-28 23:13:54 +02:00
|
|
|
appendStringLiteralConn(buf, spccomment, conn);
|
2013-11-18 17:29:01 +01:00
|
|
|
appendPQExpBufferStr(buf, ";\n");
|
2006-02-12 04:22:21 +01:00
|
|
|
}
|
|
|
|
|
2021-12-14 23:09:07 +01:00
|
|
|
if (!no_security_labels)
|
2011-07-20 19:18:24 +02:00
|
|
|
buildShSecLabels(conn, "pg_tablespace", spcoid,
|
Avoid using unsafe search_path settings during dump and restore.
Historically, pg_dump has "set search_path = foo, pg_catalog" when
dumping an object in schema "foo", and has also caused that setting
to be used while restoring the object. This is problematic because
functions and operators in schema "foo" could capture references meant
to refer to pg_catalog entries, both in the queries issued by pg_dump
and those issued during the subsequent restore run. That could
result in dump/restore misbehavior, or in privilege escalation if a
nefarious user installs trojan-horse functions or operators.
This patch changes pg_dump so that it does not change the search_path
dynamically. The emitted restore script sets the search_path to what
was used at dump time, and then leaves it alone thereafter. Created
objects are placed in the correct schema, regardless of the active
search_path, by dint of schema-qualifying their names in the CREATE
commands, as well as in subsequent ALTER and ALTER-like commands.
Since this change requires a change in the behavior of pg_restore
when processing an archive file made according to this new convention,
bump the archive file version number; old versions of pg_restore will
therefore refuse to process files made with new versions of pg_dump.
Security: CVE-2018-1058
2018-02-26 16:18:21 +01:00
|
|
|
"TABLESPACE", spcname,
|
|
|
|
buf);
|
2011-07-20 19:18:24 +02:00
|
|
|
|
2007-01-25 04:30:43 +01:00
|
|
|
fprintf(OPF, "%s", buf->data);
|
2004-06-18 08:14:31 +02:00
|
|
|
|
|
|
|
free(fspcname);
|
|
|
|
destroyPQExpBuffer(buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
PQclear(res);
|
2007-01-25 04:30:43 +01:00
|
|
|
fprintf(OPF, "\n\n");
|
2004-06-18 08:14:31 +02:00
|
|
|
}
|
2002-08-27 20:57:26 +02:00
|
|
|
|
2009-04-11 22:23:05 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Dump commands to drop each database.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
dropDBs(PGconn *conn)
|
|
|
|
{
|
|
|
|
PGresult *res;
|
|
|
|
int i;
|
|
|
|
|
Move handling of database properties from pg_dumpall into pg_dump.
This patch rearranges the division of labor between pg_dump and pg_dumpall
so that pg_dump itself handles all properties attached to a single
database. Notably, a database's ACL (GRANT/REVOKE status) and local GUC
settings established by ALTER DATABASE SET and ALTER ROLE IN DATABASE SET
can be dumped and restored by pg_dump. This is a long-requested
improvement.
"pg_dumpall -g" will now produce only role- and tablespace-related output,
nothing about individual databases. The total output of a regular
pg_dumpall run remains the same.
pg_dump (or pg_restore) will restore database-level properties only when
creating the target database with --create. This applies not only to
ACLs and GUCs but to the other database properties it already handled,
that is database comments and security labels. This is more consistent
and useful, but does represent an incompatibility in the behavior seen
without --create.
(This change makes the proposed patch to have pg_dump use "COMMENT ON
DATABASE CURRENT_DATABASE" unnecessary, since there is no case where
the command is issued that we won't know the true name of the database.
We might still want that patch as a feature in its own right, but pg_dump
no longer needs it.)
pg_dumpall with --clean will now drop and recreate the "postgres" and
"template1" databases in the target cluster, allowing their locale and
encoding settings to be changed if necessary, and providing a cleaner
way to set nondefault tablespaces for them than we had before. This
means that such a script must now always be started in the "postgres"
database; the order of drops and reconnects will not work otherwise.
Without --clean, the script will not adjust any database-level properties
of those two databases (including their comments, ACLs, and security
labels, which it formerly would try to set).
Another minor incompatibility is that the CREATE DATABASE commands in a
pg_dumpall script will now always specify locale and encoding settings.
Formerly those would be omitted if they matched the cluster's default.
While that behavior had some usefulness in some migration scenarios,
it also posed a significant hazard of unwanted locale/encoding changes.
To migrate to another locale/encoding, it's now necessary to use pg_dump
without --create to restore into a database with the desired settings.
Commit 4bd371f6f's hack to emit "SET default_transaction_read_only = off"
is gone: we now dodge that problem by the expedient of not issuing ALTER
DATABASE SET commands until after reconnecting to the target database.
Therefore, such settings won't apply during the restore session.
In passing, improve some shaky grammar in the docs, and add a note pointing
out that pg_dumpall's output can't be expected to load without any errors.
(Someday we might want to fix that, but this is not that patch.)
Haribabu Kommi, reviewed at various times by Andreas Karlsson,
Vaishnavi Prabakaran, and Robert Haas; further hacking by me.
Discussion: https://postgr.es/m/CAJrrPGcUurV0eWTeXODwsOYFN=Ekq36t1s0YnFYUNzsmRfdAyA@mail.gmail.com
2018-01-22 20:09:09 +01:00
|
|
|
/*
|
|
|
|
* Skip databases marked not datallowconn, since we'd be unable to connect
|
|
|
|
* to them anyway. This must agree with dumpDatabases().
|
|
|
|
*/
|
2016-10-12 18:19:56 +02:00
|
|
|
res = executeQuery(conn,
|
|
|
|
"SELECT datname "
|
|
|
|
"FROM pg_database d "
|
Handle DROP DATABASE getting interrupted
Until now, when DROP DATABASE got interrupted in the wrong moment, the removal
of the pg_database row would also roll back, even though some irreversible
steps have already been taken. E.g. DropDatabaseBuffers() might have thrown
out dirty buffers, or files could have been unlinked. But we continued to
allow connections to such a corrupted database.
To fix this, mark databases invalid with an in-place update, just before
starting to perform irreversible steps. As we can't add a new column in the
back branches, we use pg_database.datconnlimit = -2 for this purpose.
An invalid database cannot be connected to anymore, but can still be
dropped.
Unfortunately we can't easily add output to psql's \l to indicate that some
database is invalid, it doesn't fit in any of the existing columns.
Add tests verifying that a interrupted DROP DATABASE is handled correctly in
the backend and in various tools.
Reported-by: Evgeny Morozov <postgresql3@realityexists.net>
Author: Andres Freund <andres@anarazel.de>
Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
Reviewed-by: Thomas Munro <thomas.munro@gmail.com>
Discussion: https://postgr.es/m/20230509004637.cgvmfwrbht7xm7p6@awork3.anarazel.de
Discussion: https://postgr.es/m/20230314174521.74jl6ffqsee5mtug@awork3.anarazel.de
Backpatch: 11-, bug present in all supported versions
2023-07-13 22:03:28 +02:00
|
|
|
"WHERE datallowconn AND datconnlimit != -2 "
|
Move handling of database properties from pg_dumpall into pg_dump.
This patch rearranges the division of labor between pg_dump and pg_dumpall
so that pg_dump itself handles all properties attached to a single
database. Notably, a database's ACL (GRANT/REVOKE status) and local GUC
settings established by ALTER DATABASE SET and ALTER ROLE IN DATABASE SET
can be dumped and restored by pg_dump. This is a long-requested
improvement.
"pg_dumpall -g" will now produce only role- and tablespace-related output,
nothing about individual databases. The total output of a regular
pg_dumpall run remains the same.
pg_dump (or pg_restore) will restore database-level properties only when
creating the target database with --create. This applies not only to
ACLs and GUCs but to the other database properties it already handled,
that is database comments and security labels. This is more consistent
and useful, but does represent an incompatibility in the behavior seen
without --create.
(This change makes the proposed patch to have pg_dump use "COMMENT ON
DATABASE CURRENT_DATABASE" unnecessary, since there is no case where
the command is issued that we won't know the true name of the database.
We might still want that patch as a feature in its own right, but pg_dump
no longer needs it.)
pg_dumpall with --clean will now drop and recreate the "postgres" and
"template1" databases in the target cluster, allowing their locale and
encoding settings to be changed if necessary, and providing a cleaner
way to set nondefault tablespaces for them than we had before. This
means that such a script must now always be started in the "postgres"
database; the order of drops and reconnects will not work otherwise.
Without --clean, the script will not adjust any database-level properties
of those two databases (including their comments, ACLs, and security
labels, which it formerly would try to set).
Another minor incompatibility is that the CREATE DATABASE commands in a
pg_dumpall script will now always specify locale and encoding settings.
Formerly those would be omitted if they matched the cluster's default.
While that behavior had some usefulness in some migration scenarios,
it also posed a significant hazard of unwanted locale/encoding changes.
To migrate to another locale/encoding, it's now necessary to use pg_dump
without --create to restore into a database with the desired settings.
Commit 4bd371f6f's hack to emit "SET default_transaction_read_only = off"
is gone: we now dodge that problem by the expedient of not issuing ALTER
DATABASE SET commands until after reconnecting to the target database.
Therefore, such settings won't apply during the restore session.
In passing, improve some shaky grammar in the docs, and add a note pointing
out that pg_dumpall's output can't be expected to load without any errors.
(Someday we might want to fix that, but this is not that patch.)
Haribabu Kommi, reviewed at various times by Andreas Karlsson,
Vaishnavi Prabakaran, and Robert Haas; further hacking by me.
Discussion: https://postgr.es/m/CAJrrPGcUurV0eWTeXODwsOYFN=Ekq36t1s0YnFYUNzsmRfdAyA@mail.gmail.com
2018-01-22 20:09:09 +01:00
|
|
|
"ORDER BY datname");
|
2009-04-11 22:23:05 +02:00
|
|
|
|
|
|
|
if (PQntuples(res) > 0)
|
Move handling of database properties from pg_dumpall into pg_dump.
This patch rearranges the division of labor between pg_dump and pg_dumpall
so that pg_dump itself handles all properties attached to a single
database. Notably, a database's ACL (GRANT/REVOKE status) and local GUC
settings established by ALTER DATABASE SET and ALTER ROLE IN DATABASE SET
can be dumped and restored by pg_dump. This is a long-requested
improvement.
"pg_dumpall -g" will now produce only role- and tablespace-related output,
nothing about individual databases. The total output of a regular
pg_dumpall run remains the same.
pg_dump (or pg_restore) will restore database-level properties only when
creating the target database with --create. This applies not only to
ACLs and GUCs but to the other database properties it already handled,
that is database comments and security labels. This is more consistent
and useful, but does represent an incompatibility in the behavior seen
without --create.
(This change makes the proposed patch to have pg_dump use "COMMENT ON
DATABASE CURRENT_DATABASE" unnecessary, since there is no case where
the command is issued that we won't know the true name of the database.
We might still want that patch as a feature in its own right, but pg_dump
no longer needs it.)
pg_dumpall with --clean will now drop and recreate the "postgres" and
"template1" databases in the target cluster, allowing their locale and
encoding settings to be changed if necessary, and providing a cleaner
way to set nondefault tablespaces for them than we had before. This
means that such a script must now always be started in the "postgres"
database; the order of drops and reconnects will not work otherwise.
Without --clean, the script will not adjust any database-level properties
of those two databases (including their comments, ACLs, and security
labels, which it formerly would try to set).
Another minor incompatibility is that the CREATE DATABASE commands in a
pg_dumpall script will now always specify locale and encoding settings.
Formerly those would be omitted if they matched the cluster's default.
While that behavior had some usefulness in some migration scenarios,
it also posed a significant hazard of unwanted locale/encoding changes.
To migrate to another locale/encoding, it's now necessary to use pg_dump
without --create to restore into a database with the desired settings.
Commit 4bd371f6f's hack to emit "SET default_transaction_read_only = off"
is gone: we now dodge that problem by the expedient of not issuing ALTER
DATABASE SET commands until after reconnecting to the target database.
Therefore, such settings won't apply during the restore session.
In passing, improve some shaky grammar in the docs, and add a note pointing
out that pg_dumpall's output can't be expected to load without any errors.
(Someday we might want to fix that, but this is not that patch.)
Haribabu Kommi, reviewed at various times by Andreas Karlsson,
Vaishnavi Prabakaran, and Robert Haas; further hacking by me.
Discussion: https://postgr.es/m/CAJrrPGcUurV0eWTeXODwsOYFN=Ekq36t1s0YnFYUNzsmRfdAyA@mail.gmail.com
2018-01-22 20:09:09 +01:00
|
|
|
fprintf(OPF, "--\n-- Drop databases (except postgres and template1)\n--\n\n");
|
2009-04-11 22:23:05 +02:00
|
|
|
|
|
|
|
for (i = 0; i < PQntuples(res); i++)
|
|
|
|
{
|
|
|
|
char *dbname = PQgetvalue(res, i, 0);
|
|
|
|
|
|
|
|
/*
|
Move handling of database properties from pg_dumpall into pg_dump.
This patch rearranges the division of labor between pg_dump and pg_dumpall
so that pg_dump itself handles all properties attached to a single
database. Notably, a database's ACL (GRANT/REVOKE status) and local GUC
settings established by ALTER DATABASE SET and ALTER ROLE IN DATABASE SET
can be dumped and restored by pg_dump. This is a long-requested
improvement.
"pg_dumpall -g" will now produce only role- and tablespace-related output,
nothing about individual databases. The total output of a regular
pg_dumpall run remains the same.
pg_dump (or pg_restore) will restore database-level properties only when
creating the target database with --create. This applies not only to
ACLs and GUCs but to the other database properties it already handled,
that is database comments and security labels. This is more consistent
and useful, but does represent an incompatibility in the behavior seen
without --create.
(This change makes the proposed patch to have pg_dump use "COMMENT ON
DATABASE CURRENT_DATABASE" unnecessary, since there is no case where
the command is issued that we won't know the true name of the database.
We might still want that patch as a feature in its own right, but pg_dump
no longer needs it.)
pg_dumpall with --clean will now drop and recreate the "postgres" and
"template1" databases in the target cluster, allowing their locale and
encoding settings to be changed if necessary, and providing a cleaner
way to set nondefault tablespaces for them than we had before. This
means that such a script must now always be started in the "postgres"
database; the order of drops and reconnects will not work otherwise.
Without --clean, the script will not adjust any database-level properties
of those two databases (including their comments, ACLs, and security
labels, which it formerly would try to set).
Another minor incompatibility is that the CREATE DATABASE commands in a
pg_dumpall script will now always specify locale and encoding settings.
Formerly those would be omitted if they matched the cluster's default.
While that behavior had some usefulness in some migration scenarios,
it also posed a significant hazard of unwanted locale/encoding changes.
To migrate to another locale/encoding, it's now necessary to use pg_dump
without --create to restore into a database with the desired settings.
Commit 4bd371f6f's hack to emit "SET default_transaction_read_only = off"
is gone: we now dodge that problem by the expedient of not issuing ALTER
DATABASE SET commands until after reconnecting to the target database.
Therefore, such settings won't apply during the restore session.
In passing, improve some shaky grammar in the docs, and add a note pointing
out that pg_dumpall's output can't be expected to load without any errors.
(Someday we might want to fix that, but this is not that patch.)
Haribabu Kommi, reviewed at various times by Andreas Karlsson,
Vaishnavi Prabakaran, and Robert Haas; further hacking by me.
Discussion: https://postgr.es/m/CAJrrPGcUurV0eWTeXODwsOYFN=Ekq36t1s0YnFYUNzsmRfdAyA@mail.gmail.com
2018-01-22 20:09:09 +01:00
|
|
|
* Skip "postgres" and "template1"; dumpDatabases() will deal with
|
|
|
|
* them specially. Also, be sure to skip "template0", even if for
|
|
|
|
* some reason it's not marked !datallowconn.
|
2009-04-11 22:23:05 +02:00
|
|
|
*/
|
|
|
|
if (strcmp(dbname, "template1") != 0 &&
|
Move handling of database properties from pg_dumpall into pg_dump.
This patch rearranges the division of labor between pg_dump and pg_dumpall
so that pg_dump itself handles all properties attached to a single
database. Notably, a database's ACL (GRANT/REVOKE status) and local GUC
settings established by ALTER DATABASE SET and ALTER ROLE IN DATABASE SET
can be dumped and restored by pg_dump. This is a long-requested
improvement.
"pg_dumpall -g" will now produce only role- and tablespace-related output,
nothing about individual databases. The total output of a regular
pg_dumpall run remains the same.
pg_dump (or pg_restore) will restore database-level properties only when
creating the target database with --create. This applies not only to
ACLs and GUCs but to the other database properties it already handled,
that is database comments and security labels. This is more consistent
and useful, but does represent an incompatibility in the behavior seen
without --create.
(This change makes the proposed patch to have pg_dump use "COMMENT ON
DATABASE CURRENT_DATABASE" unnecessary, since there is no case where
the command is issued that we won't know the true name of the database.
We might still want that patch as a feature in its own right, but pg_dump
no longer needs it.)
pg_dumpall with --clean will now drop and recreate the "postgres" and
"template1" databases in the target cluster, allowing their locale and
encoding settings to be changed if necessary, and providing a cleaner
way to set nondefault tablespaces for them than we had before. This
means that such a script must now always be started in the "postgres"
database; the order of drops and reconnects will not work otherwise.
Without --clean, the script will not adjust any database-level properties
of those two databases (including their comments, ACLs, and security
labels, which it formerly would try to set).
Another minor incompatibility is that the CREATE DATABASE commands in a
pg_dumpall script will now always specify locale and encoding settings.
Formerly those would be omitted if they matched the cluster's default.
While that behavior had some usefulness in some migration scenarios,
it also posed a significant hazard of unwanted locale/encoding changes.
To migrate to another locale/encoding, it's now necessary to use pg_dump
without --create to restore into a database with the desired settings.
Commit 4bd371f6f's hack to emit "SET default_transaction_read_only = off"
is gone: we now dodge that problem by the expedient of not issuing ALTER
DATABASE SET commands until after reconnecting to the target database.
Therefore, such settings won't apply during the restore session.
In passing, improve some shaky grammar in the docs, and add a note pointing
out that pg_dumpall's output can't be expected to load without any errors.
(Someday we might want to fix that, but this is not that patch.)
Haribabu Kommi, reviewed at various times by Andreas Karlsson,
Vaishnavi Prabakaran, and Robert Haas; further hacking by me.
Discussion: https://postgr.es/m/CAJrrPGcUurV0eWTeXODwsOYFN=Ekq36t1s0YnFYUNzsmRfdAyA@mail.gmail.com
2018-01-22 20:09:09 +01:00
|
|
|
strcmp(dbname, "template0") != 0 &&
|
2009-04-11 22:23:05 +02:00
|
|
|
strcmp(dbname, "postgres") != 0)
|
|
|
|
{
|
2014-03-03 19:02:18 +01:00
|
|
|
fprintf(OPF, "DROP DATABASE %s%s;\n",
|
|
|
|
if_exists ? "IF EXISTS " : "",
|
|
|
|
fmtId(dbname));
|
2009-04-11 22:23:05 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
PQclear(res);
|
|
|
|
|
|
|
|
fprintf(OPF, "\n\n");
|
|
|
|
}
|
|
|
|
|
2002-08-28 20:25:05 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Dump user-specific configuration
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
dumpUserConfig(PGconn *conn, const char *username)
|
|
|
|
{
|
|
|
|
PQExpBuffer buf = createPQExpBuffer();
|
2021-12-14 23:09:07 +01:00
|
|
|
PGresult *res;
|
2002-08-28 20:25:05 +02:00
|
|
|
|
2023-05-17 19:06:50 +02:00
|
|
|
printfPQExpBuffer(buf, "SELECT unnest(setconfig) FROM pg_db_role_setting "
|
2021-12-14 23:09:07 +01:00
|
|
|
"WHERE setdatabase = 0 AND setrole = "
|
|
|
|
"(SELECT oid FROM %s WHERE rolname = ",
|
|
|
|
role_catalog);
|
|
|
|
appendStringLiteralConn(buf, username, conn);
|
|
|
|
appendPQExpBufferChar(buf, ')');
|
2019-03-01 17:38:54 +01:00
|
|
|
|
2021-12-14 23:09:07 +01:00
|
|
|
res = executeQuery(conn, buf->data);
|
|
|
|
|
|
|
|
if (PQntuples(res) > 0)
|
|
|
|
fprintf(OPF, "\n--\n-- User Config \"%s\"\n--\n\n", username);
|
|
|
|
|
|
|
|
for (int i = 0; i < PQntuples(res); i++)
|
|
|
|
{
|
|
|
|
resetPQExpBuffer(buf);
|
2023-05-17 19:06:50 +02:00
|
|
|
makeAlterConfigCommand(conn, PQgetvalue(res, i, 0),
|
2021-12-14 23:09:07 +01:00
|
|
|
"ROLE", username, NULL, NULL,
|
|
|
|
buf);
|
|
|
|
fprintf(OPF, "%s", buf->data);
|
2002-08-28 20:25:05 +02:00
|
|
|
}
|
|
|
|
|
2021-12-14 23:09:07 +01:00
|
|
|
PQclear(res);
|
|
|
|
|
2002-08-28 20:25:05 +02:00
|
|
|
destroyPQExpBuffer(buf);
|
|
|
|
}
|
|
|
|
|
2019-03-01 16:47:44 +01:00
|
|
|
/*
|
|
|
|
* Find a list of database names that match the given patterns.
|
|
|
|
* See also expand_table_name_patterns() in pg_dump.c
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
expand_dbname_patterns(PGconn *conn,
|
|
|
|
SimpleStringList *patterns,
|
|
|
|
SimpleStringList *names)
|
|
|
|
{
|
|
|
|
PQExpBuffer query;
|
|
|
|
PGresult *res;
|
|
|
|
|
|
|
|
if (patterns->head == NULL)
|
|
|
|
return; /* nothing to do */
|
|
|
|
|
|
|
|
query = createPQExpBuffer();
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The loop below runs multiple SELECTs, which might sometimes result in
|
|
|
|
* duplicate entries in the name list, but we don't care, since all we're
|
|
|
|
* going to do is test membership of the list.
|
|
|
|
*/
|
|
|
|
|
|
|
|
for (SimpleStringListCell *cell = patterns->head; cell; cell = cell->next)
|
|
|
|
{
|
Allow db.schema.table patterns, but complain about random garbage.
psql, pg_dump, and pg_amcheck share code to process object name
patterns like 'foo*.bar*' to match all tables with names starting in
'bar' that are in schemas starting with 'foo'. Before v14, any number
of extra name parts were silently ignored, so a command line '\d
foo.bar.baz.bletch.quux' was interpreted as '\d bletch.quux'. In v14,
as a result of commit 2c8726c4b0a496608919d1f78a5abc8c9b6e0868, we
instead treated this as a request for table quux in a schema named
'foo.bar.baz.bletch'. That caused problems for people like Justin
Pryzby who were accustomed to copying strings of the form
db.schema.table from messages generated by PostgreSQL itself and using
them as arguments to \d.
Accordingly, revise things so that if an object name pattern contains
more parts than we're expecting, we throw an error, unless there's
exactly one extra part and it matches the current database name.
That way, thisdb.myschema.mytable is accepted as meaning just
myschema.mytable, but otherdb.myschema.mytable is an error, and so
is some.random.garbage.myschema.mytable.
Mark Dilger, per report from Justin Pryzby and discussion among
various people.
Discussion: https://www.postgresql.org/message-id/20211013165426.GD27491%40telsasoft.com
2022-04-20 17:02:35 +02:00
|
|
|
int dotcnt;
|
|
|
|
|
2019-07-04 03:01:13 +02:00
|
|
|
appendPQExpBufferStr(query,
|
|
|
|
"SELECT datname FROM pg_catalog.pg_database n\n");
|
2019-03-01 16:47:44 +01:00
|
|
|
processSQLNamePattern(conn, query, cell->val, false,
|
Allow db.schema.table patterns, but complain about random garbage.
psql, pg_dump, and pg_amcheck share code to process object name
patterns like 'foo*.bar*' to match all tables with names starting in
'bar' that are in schemas starting with 'foo'. Before v14, any number
of extra name parts were silently ignored, so a command line '\d
foo.bar.baz.bletch.quux' was interpreted as '\d bletch.quux'. In v14,
as a result of commit 2c8726c4b0a496608919d1f78a5abc8c9b6e0868, we
instead treated this as a request for table quux in a schema named
'foo.bar.baz.bletch'. That caused problems for people like Justin
Pryzby who were accustomed to copying strings of the form
db.schema.table from messages generated by PostgreSQL itself and using
them as arguments to \d.
Accordingly, revise things so that if an object name pattern contains
more parts than we're expecting, we throw an error, unless there's
exactly one extra part and it matches the current database name.
That way, thisdb.myschema.mytable is accepted as meaning just
myschema.mytable, but otherdb.myschema.mytable is an error, and so
is some.random.garbage.myschema.mytable.
Mark Dilger, per report from Justin Pryzby and discussion among
various people.
Discussion: https://www.postgresql.org/message-id/20211013165426.GD27491%40telsasoft.com
2022-04-20 17:02:35 +02:00
|
|
|
false, NULL, "datname", NULL, NULL, NULL,
|
|
|
|
&dotcnt);
|
|
|
|
|
|
|
|
if (dotcnt > 0)
|
|
|
|
{
|
|
|
|
pg_log_error("improper qualified name (too many dotted names): %s",
|
|
|
|
cell->val);
|
|
|
|
PQfinish(conn);
|
|
|
|
exit_nicely(1);
|
|
|
|
}
|
2019-03-01 16:47:44 +01:00
|
|
|
|
|
|
|
res = executeQuery(conn, query->data);
|
|
|
|
for (int i = 0; i < PQntuples(res); i++)
|
|
|
|
{
|
|
|
|
simple_string_list_append(names, PQgetvalue(res, i, 0));
|
|
|
|
}
|
|
|
|
|
|
|
|
PQclear(res);
|
|
|
|
resetPQExpBuffer(query);
|
|
|
|
}
|
|
|
|
|
|
|
|
destroyPQExpBuffer(query);
|
|
|
|
}
|
2002-08-28 20:25:05 +02:00
|
|
|
|
2002-08-27 20:57:26 +02:00
|
|
|
/*
|
|
|
|
* Dump contents of databases.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
dumpDatabases(PGconn *conn)
|
|
|
|
{
|
|
|
|
PGresult *res;
|
|
|
|
int i;
|
|
|
|
|
Move handling of database properties from pg_dumpall into pg_dump.
This patch rearranges the division of labor between pg_dump and pg_dumpall
so that pg_dump itself handles all properties attached to a single
database. Notably, a database's ACL (GRANT/REVOKE status) and local GUC
settings established by ALTER DATABASE SET and ALTER ROLE IN DATABASE SET
can be dumped and restored by pg_dump. This is a long-requested
improvement.
"pg_dumpall -g" will now produce only role- and tablespace-related output,
nothing about individual databases. The total output of a regular
pg_dumpall run remains the same.
pg_dump (or pg_restore) will restore database-level properties only when
creating the target database with --create. This applies not only to
ACLs and GUCs but to the other database properties it already handled,
that is database comments and security labels. This is more consistent
and useful, but does represent an incompatibility in the behavior seen
without --create.
(This change makes the proposed patch to have pg_dump use "COMMENT ON
DATABASE CURRENT_DATABASE" unnecessary, since there is no case where
the command is issued that we won't know the true name of the database.
We might still want that patch as a feature in its own right, but pg_dump
no longer needs it.)
pg_dumpall with --clean will now drop and recreate the "postgres" and
"template1" databases in the target cluster, allowing their locale and
encoding settings to be changed if necessary, and providing a cleaner
way to set nondefault tablespaces for them than we had before. This
means that such a script must now always be started in the "postgres"
database; the order of drops and reconnects will not work otherwise.
Without --clean, the script will not adjust any database-level properties
of those two databases (including their comments, ACLs, and security
labels, which it formerly would try to set).
Another minor incompatibility is that the CREATE DATABASE commands in a
pg_dumpall script will now always specify locale and encoding settings.
Formerly those would be omitted if they matched the cluster's default.
While that behavior had some usefulness in some migration scenarios,
it also posed a significant hazard of unwanted locale/encoding changes.
To migrate to another locale/encoding, it's now necessary to use pg_dump
without --create to restore into a database with the desired settings.
Commit 4bd371f6f's hack to emit "SET default_transaction_read_only = off"
is gone: we now dodge that problem by the expedient of not issuing ALTER
DATABASE SET commands until after reconnecting to the target database.
Therefore, such settings won't apply during the restore session.
In passing, improve some shaky grammar in the docs, and add a note pointing
out that pg_dumpall's output can't be expected to load without any errors.
(Someday we might want to fix that, but this is not that patch.)
Haribabu Kommi, reviewed at various times by Andreas Karlsson,
Vaishnavi Prabakaran, and Robert Haas; further hacking by me.
Discussion: https://postgr.es/m/CAJrrPGcUurV0eWTeXODwsOYFN=Ekq36t1s0YnFYUNzsmRfdAyA@mail.gmail.com
2018-01-22 20:09:09 +01:00
|
|
|
/*
|
|
|
|
* Skip databases marked not datallowconn, since we'd be unable to connect
|
|
|
|
* to them anyway. This must agree with dropDBs().
|
|
|
|
*
|
|
|
|
* We arrange for template1 to be processed first, then we process other
|
|
|
|
* DBs in alphabetical order. If we just did them all alphabetically, we
|
|
|
|
* might find ourselves trying to drop the "postgres" database while still
|
|
|
|
* connected to it. This makes trying to run the restore script while
|
|
|
|
* connected to "template1" a bad idea, but there's no fixed order that
|
|
|
|
* doesn't have some failure mode with --clean.
|
|
|
|
*/
|
|
|
|
res = executeQuery(conn,
|
|
|
|
"SELECT datname "
|
|
|
|
"FROM pg_database d "
|
Handle DROP DATABASE getting interrupted
Until now, when DROP DATABASE got interrupted in the wrong moment, the removal
of the pg_database row would also roll back, even though some irreversible
steps have already been taken. E.g. DropDatabaseBuffers() might have thrown
out dirty buffers, or files could have been unlinked. But we continued to
allow connections to such a corrupted database.
To fix this, mark databases invalid with an in-place update, just before
starting to perform irreversible steps. As we can't add a new column in the
back branches, we use pg_database.datconnlimit = -2 for this purpose.
An invalid database cannot be connected to anymore, but can still be
dropped.
Unfortunately we can't easily add output to psql's \l to indicate that some
database is invalid, it doesn't fit in any of the existing columns.
Add tests verifying that a interrupted DROP DATABASE is handled correctly in
the backend and in various tools.
Reported-by: Evgeny Morozov <postgresql3@realityexists.net>
Author: Andres Freund <andres@anarazel.de>
Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
Reviewed-by: Thomas Munro <thomas.munro@gmail.com>
Discussion: https://postgr.es/m/20230509004637.cgvmfwrbht7xm7p6@awork3.anarazel.de
Discussion: https://postgr.es/m/20230314174521.74jl6ffqsee5mtug@awork3.anarazel.de
Backpatch: 11-, bug present in all supported versions
2023-07-13 22:03:28 +02:00
|
|
|
"WHERE datallowconn AND datconnlimit != -2 "
|
Move handling of database properties from pg_dumpall into pg_dump.
This patch rearranges the division of labor between pg_dump and pg_dumpall
so that pg_dump itself handles all properties attached to a single
database. Notably, a database's ACL (GRANT/REVOKE status) and local GUC
settings established by ALTER DATABASE SET and ALTER ROLE IN DATABASE SET
can be dumped and restored by pg_dump. This is a long-requested
improvement.
"pg_dumpall -g" will now produce only role- and tablespace-related output,
nothing about individual databases. The total output of a regular
pg_dumpall run remains the same.
pg_dump (or pg_restore) will restore database-level properties only when
creating the target database with --create. This applies not only to
ACLs and GUCs but to the other database properties it already handled,
that is database comments and security labels. This is more consistent
and useful, but does represent an incompatibility in the behavior seen
without --create.
(This change makes the proposed patch to have pg_dump use "COMMENT ON
DATABASE CURRENT_DATABASE" unnecessary, since there is no case where
the command is issued that we won't know the true name of the database.
We might still want that patch as a feature in its own right, but pg_dump
no longer needs it.)
pg_dumpall with --clean will now drop and recreate the "postgres" and
"template1" databases in the target cluster, allowing their locale and
encoding settings to be changed if necessary, and providing a cleaner
way to set nondefault tablespaces for them than we had before. This
means that such a script must now always be started in the "postgres"
database; the order of drops and reconnects will not work otherwise.
Without --clean, the script will not adjust any database-level properties
of those two databases (including their comments, ACLs, and security
labels, which it formerly would try to set).
Another minor incompatibility is that the CREATE DATABASE commands in a
pg_dumpall script will now always specify locale and encoding settings.
Formerly those would be omitted if they matched the cluster's default.
While that behavior had some usefulness in some migration scenarios,
it also posed a significant hazard of unwanted locale/encoding changes.
To migrate to another locale/encoding, it's now necessary to use pg_dump
without --create to restore into a database with the desired settings.
Commit 4bd371f6f's hack to emit "SET default_transaction_read_only = off"
is gone: we now dodge that problem by the expedient of not issuing ALTER
DATABASE SET commands until after reconnecting to the target database.
Therefore, such settings won't apply during the restore session.
In passing, improve some shaky grammar in the docs, and add a note pointing
out that pg_dumpall's output can't be expected to load without any errors.
(Someday we might want to fix that, but this is not that patch.)
Haribabu Kommi, reviewed at various times by Andreas Karlsson,
Vaishnavi Prabakaran, and Robert Haas; further hacking by me.
Discussion: https://postgr.es/m/CAJrrPGcUurV0eWTeXODwsOYFN=Ekq36t1s0YnFYUNzsmRfdAyA@mail.gmail.com
2018-01-22 20:09:09 +01:00
|
|
|
"ORDER BY (datname <> 'template1'), datname");
|
2003-05-31 00:55:16 +02:00
|
|
|
|
2019-03-01 17:38:54 +01:00
|
|
|
if (PQntuples(res) > 0)
|
|
|
|
fprintf(OPF, "--\n-- Databases\n--\n\n");
|
|
|
|
|
2002-08-27 20:57:26 +02:00
|
|
|
for (i = 0; i < PQntuples(res); i++)
|
|
|
|
{
|
Move handling of database properties from pg_dumpall into pg_dump.
This patch rearranges the division of labor between pg_dump and pg_dumpall
so that pg_dump itself handles all properties attached to a single
database. Notably, a database's ACL (GRANT/REVOKE status) and local GUC
settings established by ALTER DATABASE SET and ALTER ROLE IN DATABASE SET
can be dumped and restored by pg_dump. This is a long-requested
improvement.
"pg_dumpall -g" will now produce only role- and tablespace-related output,
nothing about individual databases. The total output of a regular
pg_dumpall run remains the same.
pg_dump (or pg_restore) will restore database-level properties only when
creating the target database with --create. This applies not only to
ACLs and GUCs but to the other database properties it already handled,
that is database comments and security labels. This is more consistent
and useful, but does represent an incompatibility in the behavior seen
without --create.
(This change makes the proposed patch to have pg_dump use "COMMENT ON
DATABASE CURRENT_DATABASE" unnecessary, since there is no case where
the command is issued that we won't know the true name of the database.
We might still want that patch as a feature in its own right, but pg_dump
no longer needs it.)
pg_dumpall with --clean will now drop and recreate the "postgres" and
"template1" databases in the target cluster, allowing their locale and
encoding settings to be changed if necessary, and providing a cleaner
way to set nondefault tablespaces for them than we had before. This
means that such a script must now always be started in the "postgres"
database; the order of drops and reconnects will not work otherwise.
Without --clean, the script will not adjust any database-level properties
of those two databases (including their comments, ACLs, and security
labels, which it formerly would try to set).
Another minor incompatibility is that the CREATE DATABASE commands in a
pg_dumpall script will now always specify locale and encoding settings.
Formerly those would be omitted if they matched the cluster's default.
While that behavior had some usefulness in some migration scenarios,
it also posed a significant hazard of unwanted locale/encoding changes.
To migrate to another locale/encoding, it's now necessary to use pg_dump
without --create to restore into a database with the desired settings.
Commit 4bd371f6f's hack to emit "SET default_transaction_read_only = off"
is gone: we now dodge that problem by the expedient of not issuing ALTER
DATABASE SET commands until after reconnecting to the target database.
Therefore, such settings won't apply during the restore session.
In passing, improve some shaky grammar in the docs, and add a note pointing
out that pg_dumpall's output can't be expected to load without any errors.
(Someday we might want to fix that, but this is not that patch.)
Haribabu Kommi, reviewed at various times by Andreas Karlsson,
Vaishnavi Prabakaran, and Robert Haas; further hacking by me.
Discussion: https://postgr.es/m/CAJrrPGcUurV0eWTeXODwsOYFN=Ekq36t1s0YnFYUNzsmRfdAyA@mail.gmail.com
2018-01-22 20:09:09 +01:00
|
|
|
char *dbname = PQgetvalue(res, i, 0);
|
|
|
|
const char *create_opts;
|
2002-08-27 20:57:26 +02:00
|
|
|
int ret;
|
2002-09-04 22:31:48 +02:00
|
|
|
|
Move handling of database properties from pg_dumpall into pg_dump.
This patch rearranges the division of labor between pg_dump and pg_dumpall
so that pg_dump itself handles all properties attached to a single
database. Notably, a database's ACL (GRANT/REVOKE status) and local GUC
settings established by ALTER DATABASE SET and ALTER ROLE IN DATABASE SET
can be dumped and restored by pg_dump. This is a long-requested
improvement.
"pg_dumpall -g" will now produce only role- and tablespace-related output,
nothing about individual databases. The total output of a regular
pg_dumpall run remains the same.
pg_dump (or pg_restore) will restore database-level properties only when
creating the target database with --create. This applies not only to
ACLs and GUCs but to the other database properties it already handled,
that is database comments and security labels. This is more consistent
and useful, but does represent an incompatibility in the behavior seen
without --create.
(This change makes the proposed patch to have pg_dump use "COMMENT ON
DATABASE CURRENT_DATABASE" unnecessary, since there is no case where
the command is issued that we won't know the true name of the database.
We might still want that patch as a feature in its own right, but pg_dump
no longer needs it.)
pg_dumpall with --clean will now drop and recreate the "postgres" and
"template1" databases in the target cluster, allowing their locale and
encoding settings to be changed if necessary, and providing a cleaner
way to set nondefault tablespaces for them than we had before. This
means that such a script must now always be started in the "postgres"
database; the order of drops and reconnects will not work otherwise.
Without --clean, the script will not adjust any database-level properties
of those two databases (including their comments, ACLs, and security
labels, which it formerly would try to set).
Another minor incompatibility is that the CREATE DATABASE commands in a
pg_dumpall script will now always specify locale and encoding settings.
Formerly those would be omitted if they matched the cluster's default.
While that behavior had some usefulness in some migration scenarios,
it also posed a significant hazard of unwanted locale/encoding changes.
To migrate to another locale/encoding, it's now necessary to use pg_dump
without --create to restore into a database with the desired settings.
Commit 4bd371f6f's hack to emit "SET default_transaction_read_only = off"
is gone: we now dodge that problem by the expedient of not issuing ALTER
DATABASE SET commands until after reconnecting to the target database.
Therefore, such settings won't apply during the restore session.
In passing, improve some shaky grammar in the docs, and add a note pointing
out that pg_dumpall's output can't be expected to load without any errors.
(Someday we might want to fix that, but this is not that patch.)
Haribabu Kommi, reviewed at various times by Andreas Karlsson,
Vaishnavi Prabakaran, and Robert Haas; further hacking by me.
Discussion: https://postgr.es/m/CAJrrPGcUurV0eWTeXODwsOYFN=Ekq36t1s0YnFYUNzsmRfdAyA@mail.gmail.com
2018-01-22 20:09:09 +01:00
|
|
|
/* Skip template0, even if it's not marked !datallowconn. */
|
|
|
|
if (strcmp(dbname, "template0") == 0)
|
|
|
|
continue;
|
2002-08-27 20:57:26 +02:00
|
|
|
|
2019-03-01 16:47:44 +01:00
|
|
|
/* Skip any explicitly excluded database */
|
|
|
|
if (simple_string_list_member(&database_exclude_names, dbname))
|
|
|
|
{
|
2019-07-09 15:47:09 +02:00
|
|
|
pg_log_info("excluding database \"%s\"", dbname);
|
2019-03-01 16:47:44 +01:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2019-07-09 15:47:09 +02:00
|
|
|
pg_log_info("dumping database \"%s\"", dbname);
|
2002-08-27 20:57:26 +02:00
|
|
|
|
2019-03-01 17:38:54 +01:00
|
|
|
fprintf(OPF, "--\n-- Database \"%s\" dump\n--\n\n", dbname);
|
|
|
|
|
2013-11-30 18:24:56 +01:00
|
|
|
/*
|
Move handling of database properties from pg_dumpall into pg_dump.
This patch rearranges the division of labor between pg_dump and pg_dumpall
so that pg_dump itself handles all properties attached to a single
database. Notably, a database's ACL (GRANT/REVOKE status) and local GUC
settings established by ALTER DATABASE SET and ALTER ROLE IN DATABASE SET
can be dumped and restored by pg_dump. This is a long-requested
improvement.
"pg_dumpall -g" will now produce only role- and tablespace-related output,
nothing about individual databases. The total output of a regular
pg_dumpall run remains the same.
pg_dump (or pg_restore) will restore database-level properties only when
creating the target database with --create. This applies not only to
ACLs and GUCs but to the other database properties it already handled,
that is database comments and security labels. This is more consistent
and useful, but does represent an incompatibility in the behavior seen
without --create.
(This change makes the proposed patch to have pg_dump use "COMMENT ON
DATABASE CURRENT_DATABASE" unnecessary, since there is no case where
the command is issued that we won't know the true name of the database.
We might still want that patch as a feature in its own right, but pg_dump
no longer needs it.)
pg_dumpall with --clean will now drop and recreate the "postgres" and
"template1" databases in the target cluster, allowing their locale and
encoding settings to be changed if necessary, and providing a cleaner
way to set nondefault tablespaces for them than we had before. This
means that such a script must now always be started in the "postgres"
database; the order of drops and reconnects will not work otherwise.
Without --clean, the script will not adjust any database-level properties
of those two databases (including their comments, ACLs, and security
labels, which it formerly would try to set).
Another minor incompatibility is that the CREATE DATABASE commands in a
pg_dumpall script will now always specify locale and encoding settings.
Formerly those would be omitted if they matched the cluster's default.
While that behavior had some usefulness in some migration scenarios,
it also posed a significant hazard of unwanted locale/encoding changes.
To migrate to another locale/encoding, it's now necessary to use pg_dump
without --create to restore into a database with the desired settings.
Commit 4bd371f6f's hack to emit "SET default_transaction_read_only = off"
is gone: we now dodge that problem by the expedient of not issuing ALTER
DATABASE SET commands until after reconnecting to the target database.
Therefore, such settings won't apply during the restore session.
In passing, improve some shaky grammar in the docs, and add a note pointing
out that pg_dumpall's output can't be expected to load without any errors.
(Someday we might want to fix that, but this is not that patch.)
Haribabu Kommi, reviewed at various times by Andreas Karlsson,
Vaishnavi Prabakaran, and Robert Haas; further hacking by me.
Discussion: https://postgr.es/m/CAJrrPGcUurV0eWTeXODwsOYFN=Ekq36t1s0YnFYUNzsmRfdAyA@mail.gmail.com
2018-01-22 20:09:09 +01:00
|
|
|
* We assume that "template1" and "postgres" already exist in the
|
|
|
|
* target installation. dropDBs() won't have removed them, for fear
|
|
|
|
* of removing the DB the restore script is initially connected to. If
|
|
|
|
* --clean was specified, tell pg_dump to drop and recreate them;
|
|
|
|
* otherwise we'll merely restore their contents. Other databases
|
|
|
|
* should simply be created.
|
2013-11-30 18:24:56 +01:00
|
|
|
*/
|
Move handling of database properties from pg_dumpall into pg_dump.
This patch rearranges the division of labor between pg_dump and pg_dumpall
so that pg_dump itself handles all properties attached to a single
database. Notably, a database's ACL (GRANT/REVOKE status) and local GUC
settings established by ALTER DATABASE SET and ALTER ROLE IN DATABASE SET
can be dumped and restored by pg_dump. This is a long-requested
improvement.
"pg_dumpall -g" will now produce only role- and tablespace-related output,
nothing about individual databases. The total output of a regular
pg_dumpall run remains the same.
pg_dump (or pg_restore) will restore database-level properties only when
creating the target database with --create. This applies not only to
ACLs and GUCs but to the other database properties it already handled,
that is database comments and security labels. This is more consistent
and useful, but does represent an incompatibility in the behavior seen
without --create.
(This change makes the proposed patch to have pg_dump use "COMMENT ON
DATABASE CURRENT_DATABASE" unnecessary, since there is no case where
the command is issued that we won't know the true name of the database.
We might still want that patch as a feature in its own right, but pg_dump
no longer needs it.)
pg_dumpall with --clean will now drop and recreate the "postgres" and
"template1" databases in the target cluster, allowing their locale and
encoding settings to be changed if necessary, and providing a cleaner
way to set nondefault tablespaces for them than we had before. This
means that such a script must now always be started in the "postgres"
database; the order of drops and reconnects will not work otherwise.
Without --clean, the script will not adjust any database-level properties
of those two databases (including their comments, ACLs, and security
labels, which it formerly would try to set).
Another minor incompatibility is that the CREATE DATABASE commands in a
pg_dumpall script will now always specify locale and encoding settings.
Formerly those would be omitted if they matched the cluster's default.
While that behavior had some usefulness in some migration scenarios,
it also posed a significant hazard of unwanted locale/encoding changes.
To migrate to another locale/encoding, it's now necessary to use pg_dump
without --create to restore into a database with the desired settings.
Commit 4bd371f6f's hack to emit "SET default_transaction_read_only = off"
is gone: we now dodge that problem by the expedient of not issuing ALTER
DATABASE SET commands until after reconnecting to the target database.
Therefore, such settings won't apply during the restore session.
In passing, improve some shaky grammar in the docs, and add a note pointing
out that pg_dumpall's output can't be expected to load without any errors.
(Someday we might want to fix that, but this is not that patch.)
Haribabu Kommi, reviewed at various times by Andreas Karlsson,
Vaishnavi Prabakaran, and Robert Haas; further hacking by me.
Discussion: https://postgr.es/m/CAJrrPGcUurV0eWTeXODwsOYFN=Ekq36t1s0YnFYUNzsmRfdAyA@mail.gmail.com
2018-01-22 20:09:09 +01:00
|
|
|
if (strcmp(dbname, "template1") == 0 || strcmp(dbname, "postgres") == 0)
|
|
|
|
{
|
|
|
|
if (output_clean)
|
|
|
|
create_opts = "--clean --create";
|
|
|
|
else
|
|
|
|
{
|
|
|
|
create_opts = "";
|
|
|
|
/* Since pg_dump won't emit a \connect command, we must */
|
|
|
|
fprintf(OPF, "\\connect %s\n\n", dbname);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
create_opts = "--create";
|
2013-11-30 18:24:56 +01:00
|
|
|
|
2007-01-25 04:30:43 +01:00
|
|
|
if (filename)
|
|
|
|
fclose(OPF);
|
2007-11-15 22:14:46 +01:00
|
|
|
|
Move handling of database properties from pg_dumpall into pg_dump.
This patch rearranges the division of labor between pg_dump and pg_dumpall
so that pg_dump itself handles all properties attached to a single
database. Notably, a database's ACL (GRANT/REVOKE status) and local GUC
settings established by ALTER DATABASE SET and ALTER ROLE IN DATABASE SET
can be dumped and restored by pg_dump. This is a long-requested
improvement.
"pg_dumpall -g" will now produce only role- and tablespace-related output,
nothing about individual databases. The total output of a regular
pg_dumpall run remains the same.
pg_dump (or pg_restore) will restore database-level properties only when
creating the target database with --create. This applies not only to
ACLs and GUCs but to the other database properties it already handled,
that is database comments and security labels. This is more consistent
and useful, but does represent an incompatibility in the behavior seen
without --create.
(This change makes the proposed patch to have pg_dump use "COMMENT ON
DATABASE CURRENT_DATABASE" unnecessary, since there is no case where
the command is issued that we won't know the true name of the database.
We might still want that patch as a feature in its own right, but pg_dump
no longer needs it.)
pg_dumpall with --clean will now drop and recreate the "postgres" and
"template1" databases in the target cluster, allowing their locale and
encoding settings to be changed if necessary, and providing a cleaner
way to set nondefault tablespaces for them than we had before. This
means that such a script must now always be started in the "postgres"
database; the order of drops and reconnects will not work otherwise.
Without --clean, the script will not adjust any database-level properties
of those two databases (including their comments, ACLs, and security
labels, which it formerly would try to set).
Another minor incompatibility is that the CREATE DATABASE commands in a
pg_dumpall script will now always specify locale and encoding settings.
Formerly those would be omitted if they matched the cluster's default.
While that behavior had some usefulness in some migration scenarios,
it also posed a significant hazard of unwanted locale/encoding changes.
To migrate to another locale/encoding, it's now necessary to use pg_dump
without --create to restore into a database with the desired settings.
Commit 4bd371f6f's hack to emit "SET default_transaction_read_only = off"
is gone: we now dodge that problem by the expedient of not issuing ALTER
DATABASE SET commands until after reconnecting to the target database.
Therefore, such settings won't apply during the restore session.
In passing, improve some shaky grammar in the docs, and add a note pointing
out that pg_dumpall's output can't be expected to load without any errors.
(Someday we might want to fix that, but this is not that patch.)
Haribabu Kommi, reviewed at various times by Andreas Karlsson,
Vaishnavi Prabakaran, and Robert Haas; further hacking by me.
Discussion: https://postgr.es/m/CAJrrPGcUurV0eWTeXODwsOYFN=Ekq36t1s0YnFYUNzsmRfdAyA@mail.gmail.com
2018-01-22 20:09:09 +01:00
|
|
|
ret = runPgDump(dbname, create_opts);
|
2002-08-27 20:57:26 +02:00
|
|
|
if (ret != 0)
|
2022-04-08 20:55:14 +02:00
|
|
|
pg_fatal("pg_dump failed on database \"%s\", exiting", dbname);
|
2007-11-15 22:14:46 +01:00
|
|
|
|
2007-01-25 04:30:43 +01:00
|
|
|
if (filename)
|
|
|
|
{
|
|
|
|
OPF = fopen(filename, PG_BINARY_A);
|
|
|
|
if (!OPF)
|
2022-04-08 20:55:14 +02:00
|
|
|
pg_fatal("could not re-open the output file \"%s\": %m",
|
|
|
|
filename);
|
2007-01-25 04:30:43 +01:00
|
|
|
}
|
2002-08-27 20:57:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
PQclear(res);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
Move handling of database properties from pg_dumpall into pg_dump.
This patch rearranges the division of labor between pg_dump and pg_dumpall
so that pg_dump itself handles all properties attached to a single
database. Notably, a database's ACL (GRANT/REVOKE status) and local GUC
settings established by ALTER DATABASE SET and ALTER ROLE IN DATABASE SET
can be dumped and restored by pg_dump. This is a long-requested
improvement.
"pg_dumpall -g" will now produce only role- and tablespace-related output,
nothing about individual databases. The total output of a regular
pg_dumpall run remains the same.
pg_dump (or pg_restore) will restore database-level properties only when
creating the target database with --create. This applies not only to
ACLs and GUCs but to the other database properties it already handled,
that is database comments and security labels. This is more consistent
and useful, but does represent an incompatibility in the behavior seen
without --create.
(This change makes the proposed patch to have pg_dump use "COMMENT ON
DATABASE CURRENT_DATABASE" unnecessary, since there is no case where
the command is issued that we won't know the true name of the database.
We might still want that patch as a feature in its own right, but pg_dump
no longer needs it.)
pg_dumpall with --clean will now drop and recreate the "postgres" and
"template1" databases in the target cluster, allowing their locale and
encoding settings to be changed if necessary, and providing a cleaner
way to set nondefault tablespaces for them than we had before. This
means that such a script must now always be started in the "postgres"
database; the order of drops and reconnects will not work otherwise.
Without --clean, the script will not adjust any database-level properties
of those two databases (including their comments, ACLs, and security
labels, which it formerly would try to set).
Another minor incompatibility is that the CREATE DATABASE commands in a
pg_dumpall script will now always specify locale and encoding settings.
Formerly those would be omitted if they matched the cluster's default.
While that behavior had some usefulness in some migration scenarios,
it also posed a significant hazard of unwanted locale/encoding changes.
To migrate to another locale/encoding, it's now necessary to use pg_dump
without --create to restore into a database with the desired settings.
Commit 4bd371f6f's hack to emit "SET default_transaction_read_only = off"
is gone: we now dodge that problem by the expedient of not issuing ALTER
DATABASE SET commands until after reconnecting to the target database.
Therefore, such settings won't apply during the restore session.
In passing, improve some shaky grammar in the docs, and add a note pointing
out that pg_dumpall's output can't be expected to load without any errors.
(Someday we might want to fix that, but this is not that patch.)
Haribabu Kommi, reviewed at various times by Andreas Karlsson,
Vaishnavi Prabakaran, and Robert Haas; further hacking by me.
Discussion: https://postgr.es/m/CAJrrPGcUurV0eWTeXODwsOYFN=Ekq36t1s0YnFYUNzsmRfdAyA@mail.gmail.com
2018-01-22 20:09:09 +01:00
|
|
|
* Run pg_dump on dbname, with specified options.
|
2002-08-27 20:57:26 +02:00
|
|
|
*/
|
|
|
|
static int
|
Move handling of database properties from pg_dumpall into pg_dump.
This patch rearranges the division of labor between pg_dump and pg_dumpall
so that pg_dump itself handles all properties attached to a single
database. Notably, a database's ACL (GRANT/REVOKE status) and local GUC
settings established by ALTER DATABASE SET and ALTER ROLE IN DATABASE SET
can be dumped and restored by pg_dump. This is a long-requested
improvement.
"pg_dumpall -g" will now produce only role- and tablespace-related output,
nothing about individual databases. The total output of a regular
pg_dumpall run remains the same.
pg_dump (or pg_restore) will restore database-level properties only when
creating the target database with --create. This applies not only to
ACLs and GUCs but to the other database properties it already handled,
that is database comments and security labels. This is more consistent
and useful, but does represent an incompatibility in the behavior seen
without --create.
(This change makes the proposed patch to have pg_dump use "COMMENT ON
DATABASE CURRENT_DATABASE" unnecessary, since there is no case where
the command is issued that we won't know the true name of the database.
We might still want that patch as a feature in its own right, but pg_dump
no longer needs it.)
pg_dumpall with --clean will now drop and recreate the "postgres" and
"template1" databases in the target cluster, allowing their locale and
encoding settings to be changed if necessary, and providing a cleaner
way to set nondefault tablespaces for them than we had before. This
means that such a script must now always be started in the "postgres"
database; the order of drops and reconnects will not work otherwise.
Without --clean, the script will not adjust any database-level properties
of those two databases (including their comments, ACLs, and security
labels, which it formerly would try to set).
Another minor incompatibility is that the CREATE DATABASE commands in a
pg_dumpall script will now always specify locale and encoding settings.
Formerly those would be omitted if they matched the cluster's default.
While that behavior had some usefulness in some migration scenarios,
it also posed a significant hazard of unwanted locale/encoding changes.
To migrate to another locale/encoding, it's now necessary to use pg_dump
without --create to restore into a database with the desired settings.
Commit 4bd371f6f's hack to emit "SET default_transaction_read_only = off"
is gone: we now dodge that problem by the expedient of not issuing ALTER
DATABASE SET commands until after reconnecting to the target database.
Therefore, such settings won't apply during the restore session.
In passing, improve some shaky grammar in the docs, and add a note pointing
out that pg_dumpall's output can't be expected to load without any errors.
(Someday we might want to fix that, but this is not that patch.)
Haribabu Kommi, reviewed at various times by Andreas Karlsson,
Vaishnavi Prabakaran, and Robert Haas; further hacking by me.
Discussion: https://postgr.es/m/CAJrrPGcUurV0eWTeXODwsOYFN=Ekq36t1s0YnFYUNzsmRfdAyA@mail.gmail.com
2018-01-22 20:09:09 +01:00
|
|
|
runPgDump(const char *dbname, const char *create_opts)
|
2002-08-27 20:57:26 +02:00
|
|
|
{
|
2023-07-05 06:56:37 +02:00
|
|
|
PQExpBufferData connstrbuf;
|
|
|
|
PQExpBufferData cmd;
|
2002-08-27 20:57:26 +02:00
|
|
|
int ret;
|
|
|
|
|
2023-07-05 06:56:37 +02:00
|
|
|
initPQExpBuffer(&connstrbuf);
|
|
|
|
initPQExpBuffer(&cmd);
|
|
|
|
|
|
|
|
printfPQExpBuffer(&cmd, "\"%s\" %s %s", pg_dump_bin,
|
Move handling of database properties from pg_dumpall into pg_dump.
This patch rearranges the division of labor between pg_dump and pg_dumpall
so that pg_dump itself handles all properties attached to a single
database. Notably, a database's ACL (GRANT/REVOKE status) and local GUC
settings established by ALTER DATABASE SET and ALTER ROLE IN DATABASE SET
can be dumped and restored by pg_dump. This is a long-requested
improvement.
"pg_dumpall -g" will now produce only role- and tablespace-related output,
nothing about individual databases. The total output of a regular
pg_dumpall run remains the same.
pg_dump (or pg_restore) will restore database-level properties only when
creating the target database with --create. This applies not only to
ACLs and GUCs but to the other database properties it already handled,
that is database comments and security labels. This is more consistent
and useful, but does represent an incompatibility in the behavior seen
without --create.
(This change makes the proposed patch to have pg_dump use "COMMENT ON
DATABASE CURRENT_DATABASE" unnecessary, since there is no case where
the command is issued that we won't know the true name of the database.
We might still want that patch as a feature in its own right, but pg_dump
no longer needs it.)
pg_dumpall with --clean will now drop and recreate the "postgres" and
"template1" databases in the target cluster, allowing their locale and
encoding settings to be changed if necessary, and providing a cleaner
way to set nondefault tablespaces for them than we had before. This
means that such a script must now always be started in the "postgres"
database; the order of drops and reconnects will not work otherwise.
Without --clean, the script will not adjust any database-level properties
of those two databases (including their comments, ACLs, and security
labels, which it formerly would try to set).
Another minor incompatibility is that the CREATE DATABASE commands in a
pg_dumpall script will now always specify locale and encoding settings.
Formerly those would be omitted if they matched the cluster's default.
While that behavior had some usefulness in some migration scenarios,
it also posed a significant hazard of unwanted locale/encoding changes.
To migrate to another locale/encoding, it's now necessary to use pg_dump
without --create to restore into a database with the desired settings.
Commit 4bd371f6f's hack to emit "SET default_transaction_read_only = off"
is gone: we now dodge that problem by the expedient of not issuing ALTER
DATABASE SET commands until after reconnecting to the target database.
Therefore, such settings won't apply during the restore session.
In passing, improve some shaky grammar in the docs, and add a note pointing
out that pg_dumpall's output can't be expected to load without any errors.
(Someday we might want to fix that, but this is not that patch.)
Haribabu Kommi, reviewed at various times by Andreas Karlsson,
Vaishnavi Prabakaran, and Robert Haas; further hacking by me.
Discussion: https://postgr.es/m/CAJrrPGcUurV0eWTeXODwsOYFN=Ekq36t1s0YnFYUNzsmRfdAyA@mail.gmail.com
2018-01-22 20:09:09 +01:00
|
|
|
pgdumpopts->data, create_opts);
|
2009-01-05 17:54:37 +01:00
|
|
|
|
2004-08-08 08:44:36 +02:00
|
|
|
/*
|
2007-01-25 04:30:43 +01:00
|
|
|
* If we have a filename, use the undocumented plain-append pg_dump
|
|
|
|
* format.
|
2004-08-08 08:44:36 +02:00
|
|
|
*/
|
2007-01-25 04:30:43 +01:00
|
|
|
if (filename)
|
2023-07-05 06:56:37 +02:00
|
|
|
appendPQExpBufferStr(&cmd, " -Fa ");
|
2007-01-25 04:30:43 +01:00
|
|
|
else
|
2023-07-05 06:56:37 +02:00
|
|
|
appendPQExpBufferStr(&cmd, " -Fp ");
|
2002-11-22 04:09:43 +01:00
|
|
|
|
2013-02-20 16:08:54 +01:00
|
|
|
/*
|
2013-02-25 18:39:10 +01:00
|
|
|
* Append the database name to the already-constructed stem of connection
|
|
|
|
* string.
|
2013-02-20 16:08:54 +01:00
|
|
|
*/
|
2023-07-05 06:56:37 +02:00
|
|
|
appendPQExpBuffer(&connstrbuf, "%s dbname=", connstr);
|
|
|
|
appendConnStrVal(&connstrbuf, dbname);
|
2013-02-20 16:08:54 +01:00
|
|
|
|
2023-07-05 06:56:37 +02:00
|
|
|
appendShellString(&cmd, connstrbuf.data);
|
2004-08-29 07:07:03 +02:00
|
|
|
|
2023-07-05 06:56:37 +02:00
|
|
|
pg_log_info("running \"%s\"", cmd.data);
|
2002-08-27 20:57:26 +02:00
|
|
|
|
2022-08-29 19:55:38 +02:00
|
|
|
fflush(NULL);
|
2002-08-27 23:33:41 +02:00
|
|
|
|
2023-07-05 06:56:37 +02:00
|
|
|
ret = system(cmd.data);
|
2002-11-22 04:09:43 +01:00
|
|
|
|
2023-07-05 06:56:37 +02:00
|
|
|
termPQExpBuffer(&cmd);
|
|
|
|
termPQExpBuffer(&connstrbuf);
|
2002-08-27 20:57:26 +02:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-07-20 19:18:24 +02:00
|
|
|
/*
|
|
|
|
* buildShSecLabels
|
|
|
|
*
|
2015-05-20 15:18:11 +02:00
|
|
|
* Build SECURITY LABEL command(s) for a shared object
|
2011-07-20 19:18:24 +02:00
|
|
|
*
|
Avoid using unsafe search_path settings during dump and restore.
Historically, pg_dump has "set search_path = foo, pg_catalog" when
dumping an object in schema "foo", and has also caused that setting
to be used while restoring the object. This is problematic because
functions and operators in schema "foo" could capture references meant
to refer to pg_catalog entries, both in the queries issued by pg_dump
and those issued during the subsequent restore run. That could
result in dump/restore misbehavior, or in privilege escalation if a
nefarious user installs trojan-horse functions or operators.
This patch changes pg_dump so that it does not change the search_path
dynamically. The emitted restore script sets the search_path to what
was used at dump time, and then leaves it alone thereafter. Created
objects are placed in the correct schema, regardless of the active
search_path, by dint of schema-qualifying their names in the CREATE
commands, as well as in subsequent ALTER and ALTER-like commands.
Since this change requires a change in the behavior of pg_restore
when processing an archive file made according to this new convention,
bump the archive file version number; old versions of pg_restore will
therefore refuse to process files made with new versions of pg_dump.
Security: CVE-2018-1058
2018-02-26 16:18:21 +01:00
|
|
|
* The caller has to provide object type and identity in two separate formats:
|
|
|
|
* catalog_name (e.g., "pg_database") and object OID, as well as
|
|
|
|
* type name (e.g., "DATABASE") and object name (not pre-quoted).
|
|
|
|
*
|
|
|
|
* The command(s) are appended to "buffer".
|
2011-07-20 19:18:24 +02:00
|
|
|
*/
|
|
|
|
static void
|
Avoid using unsafe search_path settings during dump and restore.
Historically, pg_dump has "set search_path = foo, pg_catalog" when
dumping an object in schema "foo", and has also caused that setting
to be used while restoring the object. This is problematic because
functions and operators in schema "foo" could capture references meant
to refer to pg_catalog entries, both in the queries issued by pg_dump
and those issued during the subsequent restore run. That could
result in dump/restore misbehavior, or in privilege escalation if a
nefarious user installs trojan-horse functions or operators.
This patch changes pg_dump so that it does not change the search_path
dynamically. The emitted restore script sets the search_path to what
was used at dump time, and then leaves it alone thereafter. Created
objects are placed in the correct schema, regardless of the active
search_path, by dint of schema-qualifying their names in the CREATE
commands, as well as in subsequent ALTER and ALTER-like commands.
Since this change requires a change in the behavior of pg_restore
when processing an archive file made according to this new convention,
bump the archive file version number; old versions of pg_restore will
therefore refuse to process files made with new versions of pg_dump.
Security: CVE-2018-1058
2018-02-26 16:18:21 +01:00
|
|
|
buildShSecLabels(PGconn *conn, const char *catalog_name, Oid objectId,
|
|
|
|
const char *objtype, const char *objname,
|
|
|
|
PQExpBuffer buffer)
|
2011-07-20 19:18:24 +02:00
|
|
|
{
|
|
|
|
PQExpBuffer sql = createPQExpBuffer();
|
|
|
|
PGresult *res;
|
|
|
|
|
2020-08-25 07:24:15 +02:00
|
|
|
buildShSecLabelQuery(catalog_name, objectId, sql);
|
2011-07-20 19:18:24 +02:00
|
|
|
res = executeQuery(conn, sql->data);
|
Avoid using unsafe search_path settings during dump and restore.
Historically, pg_dump has "set search_path = foo, pg_catalog" when
dumping an object in schema "foo", and has also caused that setting
to be used while restoring the object. This is problematic because
functions and operators in schema "foo" could capture references meant
to refer to pg_catalog entries, both in the queries issued by pg_dump
and those issued during the subsequent restore run. That could
result in dump/restore misbehavior, or in privilege escalation if a
nefarious user installs trojan-horse functions or operators.
This patch changes pg_dump so that it does not change the search_path
dynamically. The emitted restore script sets the search_path to what
was used at dump time, and then leaves it alone thereafter. Created
objects are placed in the correct schema, regardless of the active
search_path, by dint of schema-qualifying their names in the CREATE
commands, as well as in subsequent ALTER and ALTER-like commands.
Since this change requires a change in the behavior of pg_restore
when processing an archive file made according to this new convention,
bump the archive file version number; old versions of pg_restore will
therefore refuse to process files made with new versions of pg_dump.
Security: CVE-2018-1058
2018-02-26 16:18:21 +01:00
|
|
|
emitShSecLabels(conn, res, buffer, objtype, objname);
|
2011-07-20 19:18:24 +02:00
|
|
|
|
|
|
|
PQclear(res);
|
|
|
|
destroyPQExpBuffer(sql);
|
|
|
|
}
|
2002-08-27 20:57:26 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Make a database connection with the given parameters. An
|
|
|
|
* interactive password prompt is automatically issued if required.
|
2005-07-08 18:51:30 +02:00
|
|
|
*
|
|
|
|
* If fail_on_error is false, we return NULL without printing any message
|
|
|
|
* on failure, but preserve any prompted password for the next try.
|
2013-02-25 18:39:10 +01:00
|
|
|
*
|
|
|
|
* On success, the global variable 'connstr' is set to a connection string
|
|
|
|
* containing the options used.
|
2002-08-27 20:57:26 +02:00
|
|
|
*/
|
|
|
|
static PGconn *
|
2013-02-25 18:39:10 +01:00
|
|
|
connectDatabase(const char *dbname, const char *connection_string,
|
|
|
|
const char *pghost, const char *pgport, const char *pguser,
|
2014-10-14 20:00:55 +02:00
|
|
|
trivalue prompt_password, bool fail_on_error)
|
2002-08-27 20:57:26 +02:00
|
|
|
{
|
|
|
|
PGconn *conn;
|
2007-07-08 21:07:38 +02:00
|
|
|
bool new_pass;
|
2003-06-22 02:56:58 +02:00
|
|
|
const char *remoteversion_str;
|
2005-04-19 01:47:52 +02:00
|
|
|
int my_version;
|
2013-02-25 18:39:10 +01:00
|
|
|
const char **keywords = NULL;
|
|
|
|
const char **values = NULL;
|
|
|
|
PQconninfoOption *conn_opts = NULL;
|
Remove arbitrary restrictions on password length.
This patch started out with the goal of harmonizing various arbitrary
limits on password length, but after awhile a better idea emerged:
let's just get rid of those fixed limits.
recv_password_packet() has an arbitrary limit on the packet size,
which we don't really need, so just drop it. (Note that this doesn't
really affect anything for MD5 or SCRAM password verification, since
those will hash the user's password to something shorter anyway.
It does matter for auth methods that require a cleartext password.)
Likewise remove the arbitrary error condition in pg_saslprep().
The remaining limits are mostly in client-side code that prompts
for passwords. To improve those, refactor simple_prompt() so that
it allocates its own result buffer that can be made as big as
necessary. Actually, it proves best to make a separate routine
pg_get_line() that has essentially the semantics of fgets(), except
that it allocates a suitable result buffer and hence will never
return a truncated line. (pg_get_line has a lot of potential
applications to replace randomly-sized fgets buffers elsewhere,
but I'll leave that for another patch.)
I built pg_get_line() atop stringinfo.c, which requires moving
that code to src/common/; but that seems fine since it was a poor
fit for src/port/ anyway.
This patch is mostly mine, but it owes a good deal to Nathan Bossart
who pressed for a solution to the password length problem and
created a predecessor patch. Also thanks to Peter Eisentraut and
Stephen Frost for ideas and discussion.
Discussion: https://postgr.es/m/09512C4F-8CB9-4021-B455-EF4C4F0D55A0@amazon.com
2020-09-04 02:09:18 +02:00
|
|
|
static char *password = NULL;
|
2002-08-27 20:57:26 +02:00
|
|
|
|
Remove arbitrary restrictions on password length.
This patch started out with the goal of harmonizing various arbitrary
limits on password length, but after awhile a better idea emerged:
let's just get rid of those fixed limits.
recv_password_packet() has an arbitrary limit on the packet size,
which we don't really need, so just drop it. (Note that this doesn't
really affect anything for MD5 or SCRAM password verification, since
those will hash the user's password to something shorter anyway.
It does matter for auth methods that require a cleartext password.)
Likewise remove the arbitrary error condition in pg_saslprep().
The remaining limits are mostly in client-side code that prompts
for passwords. To improve those, refactor simple_prompt() so that
it allocates its own result buffer that can be made as big as
necessary. Actually, it proves best to make a separate routine
pg_get_line() that has essentially the semantics of fgets(), except
that it allocates a suitable result buffer and hence will never
return a truncated line. (pg_get_line has a lot of potential
applications to replace randomly-sized fgets buffers elsewhere,
but I'll leave that for another patch.)
I built pg_get_line() atop stringinfo.c, which requires moving
that code to src/common/; but that seems fine since it was a poor
fit for src/port/ anyway.
This patch is mostly mine, but it owes a good deal to Nathan Bossart
who pressed for a solution to the password length problem and
created a predecessor patch. Also thanks to Peter Eisentraut and
Stephen Frost for ideas and discussion.
Discussion: https://postgr.es/m/09512C4F-8CB9-4021-B455-EF4C4F0D55A0@amazon.com
2020-09-04 02:09:18 +02:00
|
|
|
if (prompt_password == TRI_YES && !password)
|
|
|
|
password = simple_prompt("Password: ", false);
|
2002-08-27 20:57:26 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Start the connection. Loop until we have a password if requested by
|
|
|
|
* backend.
|
|
|
|
*/
|
|
|
|
do
|
|
|
|
{
|
2013-02-25 18:39:10 +01:00
|
|
|
int argcount = 6;
|
|
|
|
PQconninfoOption *conn_opt;
|
|
|
|
char *err_msg = NULL;
|
|
|
|
int i = 0;
|
|
|
|
|
2022-06-16 21:50:56 +02:00
|
|
|
free(keywords);
|
|
|
|
free(values);
|
2022-07-03 20:11:05 +02:00
|
|
|
PQconninfoFree(conn_opts);
|
2013-02-25 18:39:10 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Merge the connection info inputs given in form of connection string
|
2016-08-08 16:07:46 +02:00
|
|
|
* and other options. Explicitly discard any dbname value in the
|
|
|
|
* connection string; otherwise, PQconnectdbParams() would interpret
|
|
|
|
* that value as being itself a connection string.
|
2013-02-25 18:39:10 +01:00
|
|
|
*/
|
|
|
|
if (connection_string)
|
|
|
|
{
|
|
|
|
conn_opts = PQconninfoParse(connection_string, &err_msg);
|
|
|
|
if (conn_opts == NULL)
|
2022-04-08 20:55:14 +02:00
|
|
|
pg_fatal("%s", err_msg);
|
2013-02-25 18:39:10 +01:00
|
|
|
|
|
|
|
for (conn_opt = conn_opts; conn_opt->keyword != NULL; conn_opt++)
|
|
|
|
{
|
2016-08-08 16:07:46 +02:00
|
|
|
if (conn_opt->val != NULL && conn_opt->val[0] != '\0' &&
|
|
|
|
strcmp(conn_opt->keyword, "dbname") != 0)
|
2013-02-25 18:39:10 +01:00
|
|
|
argcount++;
|
|
|
|
}
|
|
|
|
|
|
|
|
keywords = pg_malloc0((argcount + 1) * sizeof(*keywords));
|
|
|
|
values = pg_malloc0((argcount + 1) * sizeof(*values));
|
|
|
|
|
|
|
|
for (conn_opt = conn_opts; conn_opt->keyword != NULL; conn_opt++)
|
|
|
|
{
|
2016-08-08 16:07:46 +02:00
|
|
|
if (conn_opt->val != NULL && conn_opt->val[0] != '\0' &&
|
|
|
|
strcmp(conn_opt->keyword, "dbname") != 0)
|
2013-02-25 18:39:10 +01:00
|
|
|
{
|
|
|
|
keywords[i] = conn_opt->keyword;
|
|
|
|
values[i] = conn_opt->val;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
keywords = pg_malloc0((argcount + 1) * sizeof(*keywords));
|
|
|
|
values = pg_malloc0((argcount + 1) * sizeof(*values));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pghost)
|
|
|
|
{
|
|
|
|
keywords[i] = "host";
|
|
|
|
values[i] = pghost;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
if (pgport)
|
|
|
|
{
|
|
|
|
keywords[i] = "port";
|
|
|
|
values[i] = pgport;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
if (pguser)
|
|
|
|
{
|
|
|
|
keywords[i] = "user";
|
|
|
|
values[i] = pguser;
|
|
|
|
i++;
|
|
|
|
}
|
Remove arbitrary restrictions on password length.
This patch started out with the goal of harmonizing various arbitrary
limits on password length, but after awhile a better idea emerged:
let's just get rid of those fixed limits.
recv_password_packet() has an arbitrary limit on the packet size,
which we don't really need, so just drop it. (Note that this doesn't
really affect anything for MD5 or SCRAM password verification, since
those will hash the user's password to something shorter anyway.
It does matter for auth methods that require a cleartext password.)
Likewise remove the arbitrary error condition in pg_saslprep().
The remaining limits are mostly in client-side code that prompts
for passwords. To improve those, refactor simple_prompt() so that
it allocates its own result buffer that can be made as big as
necessary. Actually, it proves best to make a separate routine
pg_get_line() that has essentially the semantics of fgets(), except
that it allocates a suitable result buffer and hence will never
return a truncated line. (pg_get_line has a lot of potential
applications to replace randomly-sized fgets buffers elsewhere,
but I'll leave that for another patch.)
I built pg_get_line() atop stringinfo.c, which requires moving
that code to src/common/; but that seems fine since it was a poor
fit for src/port/ anyway.
This patch is mostly mine, but it owes a good deal to Nathan Bossart
who pressed for a solution to the password length problem and
created a predecessor patch. Also thanks to Peter Eisentraut and
Stephen Frost for ideas and discussion.
Discussion: https://postgr.es/m/09512C4F-8CB9-4021-B455-EF4C4F0D55A0@amazon.com
2020-09-04 02:09:18 +02:00
|
|
|
if (password)
|
2013-02-25 18:39:10 +01:00
|
|
|
{
|
|
|
|
keywords[i] = "password";
|
|
|
|
values[i] = password;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
if (dbname)
|
|
|
|
{
|
|
|
|
keywords[i] = "dbname";
|
|
|
|
values[i] = dbname;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
keywords[i] = "fallback_application_name";
|
|
|
|
values[i] = progname;
|
|
|
|
i++;
|
2010-02-05 04:09:05 +01:00
|
|
|
|
2007-07-08 21:07:38 +02:00
|
|
|
new_pass = false;
|
2010-02-05 04:09:05 +01:00
|
|
|
conn = PQconnectdbParams(keywords, values, true);
|
|
|
|
|
2002-08-27 20:57:26 +02:00
|
|
|
if (!conn)
|
2022-04-08 20:55:14 +02:00
|
|
|
pg_fatal("could not connect to database \"%s\"", dbname);
|
2002-08-27 20:57:26 +02:00
|
|
|
|
|
|
|
if (PQstatus(conn) == CONNECTION_BAD &&
|
2007-12-09 20:01:40 +01:00
|
|
|
PQconnectionNeedsPassword(conn) &&
|
Remove arbitrary restrictions on password length.
This patch started out with the goal of harmonizing various arbitrary
limits on password length, but after awhile a better idea emerged:
let's just get rid of those fixed limits.
recv_password_packet() has an arbitrary limit on the packet size,
which we don't really need, so just drop it. (Note that this doesn't
really affect anything for MD5 or SCRAM password verification, since
those will hash the user's password to something shorter anyway.
It does matter for auth methods that require a cleartext password.)
Likewise remove the arbitrary error condition in pg_saslprep().
The remaining limits are mostly in client-side code that prompts
for passwords. To improve those, refactor simple_prompt() so that
it allocates its own result buffer that can be made as big as
necessary. Actually, it proves best to make a separate routine
pg_get_line() that has essentially the semantics of fgets(), except
that it allocates a suitable result buffer and hence will never
return a truncated line. (pg_get_line has a lot of potential
applications to replace randomly-sized fgets buffers elsewhere,
but I'll leave that for another patch.)
I built pg_get_line() atop stringinfo.c, which requires moving
that code to src/common/; but that seems fine since it was a poor
fit for src/port/ anyway.
This patch is mostly mine, but it owes a good deal to Nathan Bossart
who pressed for a solution to the password length problem and
created a predecessor patch. Also thanks to Peter Eisentraut and
Stephen Frost for ideas and discussion.
Discussion: https://postgr.es/m/09512C4F-8CB9-4021-B455-EF4C4F0D55A0@amazon.com
2020-09-04 02:09:18 +02:00
|
|
|
!password &&
|
2009-02-26 17:02:39 +01:00
|
|
|
prompt_password != TRI_NO)
|
2002-08-27 20:57:26 +02:00
|
|
|
{
|
|
|
|
PQfinish(conn);
|
Remove arbitrary restrictions on password length.
This patch started out with the goal of harmonizing various arbitrary
limits on password length, but after awhile a better idea emerged:
let's just get rid of those fixed limits.
recv_password_packet() has an arbitrary limit on the packet size,
which we don't really need, so just drop it. (Note that this doesn't
really affect anything for MD5 or SCRAM password verification, since
those will hash the user's password to something shorter anyway.
It does matter for auth methods that require a cleartext password.)
Likewise remove the arbitrary error condition in pg_saslprep().
The remaining limits are mostly in client-side code that prompts
for passwords. To improve those, refactor simple_prompt() so that
it allocates its own result buffer that can be made as big as
necessary. Actually, it proves best to make a separate routine
pg_get_line() that has essentially the semantics of fgets(), except
that it allocates a suitable result buffer and hence will never
return a truncated line. (pg_get_line has a lot of potential
applications to replace randomly-sized fgets buffers elsewhere,
but I'll leave that for another patch.)
I built pg_get_line() atop stringinfo.c, which requires moving
that code to src/common/; but that seems fine since it was a poor
fit for src/port/ anyway.
This patch is mostly mine, but it owes a good deal to Nathan Bossart
who pressed for a solution to the password length problem and
created a predecessor patch. Also thanks to Peter Eisentraut and
Stephen Frost for ideas and discussion.
Discussion: https://postgr.es/m/09512C4F-8CB9-4021-B455-EF4C4F0D55A0@amazon.com
2020-09-04 02:09:18 +02:00
|
|
|
password = simple_prompt("Password: ", false);
|
2007-07-08 21:07:38 +02:00
|
|
|
new_pass = true;
|
2002-08-27 20:57:26 +02:00
|
|
|
}
|
2007-07-08 21:07:38 +02:00
|
|
|
} while (new_pass);
|
2002-08-27 20:57:26 +02:00
|
|
|
|
|
|
|
/* check to see that the backend connection was successfully made */
|
|
|
|
if (PQstatus(conn) == CONNECTION_BAD)
|
|
|
|
{
|
2005-07-08 18:51:30 +02:00
|
|
|
if (fail_on_error)
|
2022-04-08 20:55:14 +02:00
|
|
|
pg_fatal("%s", PQerrorMessage(conn));
|
2005-07-08 18:51:30 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
PQfinish(conn);
|
2013-02-25 18:39:10 +01:00
|
|
|
|
|
|
|
free(keywords);
|
|
|
|
free(values);
|
|
|
|
PQconninfoFree(conn_opts);
|
|
|
|
|
2005-07-08 18:51:30 +02:00
|
|
|
return NULL;
|
|
|
|
}
|
2002-09-07 18:14:33 +02:00
|
|
|
}
|
|
|
|
|
2013-02-25 18:39:10 +01:00
|
|
|
/*
|
2013-03-24 16:27:20 +01:00
|
|
|
* Ok, connected successfully. Remember the options used, in the form of a
|
|
|
|
* connection string.
|
2013-02-25 18:39:10 +01:00
|
|
|
*/
|
|
|
|
connstr = constructConnStr(keywords, values);
|
|
|
|
|
|
|
|
free(keywords);
|
|
|
|
free(values);
|
|
|
|
PQconninfoFree(conn_opts);
|
|
|
|
|
|
|
|
/* Check version */
|
2003-06-22 02:56:58 +02:00
|
|
|
remoteversion_str = PQparameterStatus(conn, "server_version");
|
|
|
|
if (!remoteversion_str)
|
2022-04-08 20:55:14 +02:00
|
|
|
pg_fatal("could not get server version");
|
2013-03-26 14:21:57 +01:00
|
|
|
server_version = PQserverVersion(conn);
|
|
|
|
if (server_version == 0)
|
2022-04-08 20:55:14 +02:00
|
|
|
pg_fatal("could not parse server version \"%s\"",
|
|
|
|
remoteversion_str);
|
2002-08-27 20:57:26 +02:00
|
|
|
|
2013-03-26 14:21:57 +01:00
|
|
|
my_version = PG_VERSION_NUM;
|
2005-04-19 01:47:52 +02:00
|
|
|
|
2008-04-13 05:49:22 +02:00
|
|
|
/*
|
2021-12-14 23:09:07 +01:00
|
|
|
* We allow the server to be back to 9.2, and up to any minor release of
|
2008-04-13 05:49:22 +02:00
|
|
|
* our own major version. (See also version check in pg_dump.c.)
|
|
|
|
*/
|
2005-04-19 01:47:52 +02:00
|
|
|
if (my_version != server_version
|
2021-12-14 23:09:07 +01:00
|
|
|
&& (server_version < 90200 ||
|
2008-04-13 05:49:22 +02:00
|
|
|
(server_version / 100) > (my_version / 100)))
|
2005-04-19 01:47:52 +02:00
|
|
|
{
|
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
|
|
|
pg_log_error("aborting because of server version mismatch");
|
2022-04-08 20:55:14 +02:00
|
|
|
pg_log_error_detail("server version: %s; %s version: %s",
|
|
|
|
remoteversion_str, progname, PG_VERSION);
|
2012-02-16 17:49:20 +01:00
|
|
|
exit_nicely(1);
|
2005-04-19 01:47:52 +02:00
|
|
|
}
|
|
|
|
|
Empty search_path in Autovacuum and non-psql/pgbench clients.
This makes the client programs behave as documented regardless of the
connect-time search_path and regardless of user-created objects. Today,
a malicious user with CREATE permission on a search_path schema can take
control of certain of these clients' queries and invoke arbitrary SQL
functions under the client identity, often a superuser. This is
exploitable in the default configuration, where all users have CREATE
privilege on schema "public".
This changes behavior of user-defined code stored in the database, like
pg_index.indexprs and pg_extension_config_dump(). If they reach code
bearing unqualified names, "does not exist" or "no schema has been
selected to create in" errors might appear. Users may fix such errors
by schema-qualifying affected names. After upgrading, consider watching
server logs for these errors.
The --table arguments of src/bin/scripts clients have been lax; for
example, "vacuumdb -Zt pg_am\;CHECKPOINT" performed a checkpoint. That
now fails, but for now, "vacuumdb -Zt 'pg_am(amname);CHECKPOINT'" still
performs a checkpoint.
Back-patch to 9.3 (all supported versions).
Reviewed by Tom Lane, though this fix strategy was not his first choice.
Reported by Arseniy Sharoglazov.
Security: CVE-2018-1058
2018-02-26 16:39:44 +01:00
|
|
|
PQclear(executeQuery(conn, ALWAYS_SECURE_SEARCH_PATH_SQL));
|
2005-07-31 19:19:22 +02:00
|
|
|
|
2002-08-27 20:57:26 +02:00
|
|
|
return conn;
|
|
|
|
}
|
|
|
|
|
2013-02-25 18:39:10 +01:00
|
|
|
/* ----------
|
|
|
|
* Construct a connection string from the given keyword/value pairs. It is
|
|
|
|
* used to pass the connection options to the pg_dump subprocess.
|
|
|
|
*
|
|
|
|
* The following parameters are excluded:
|
|
|
|
* dbname - varies in each pg_dump invocation
|
|
|
|
* password - it's not secure to pass a password on the command line
|
|
|
|
* fallback_application_name - we'll let pg_dump set it
|
|
|
|
* ----------
|
|
|
|
*/
|
|
|
|
static char *
|
|
|
|
constructConnStr(const char **keywords, const char **values)
|
|
|
|
{
|
|
|
|
PQExpBuffer buf = createPQExpBuffer();
|
|
|
|
char *connstr;
|
|
|
|
int i;
|
|
|
|
bool firstkeyword = true;
|
|
|
|
|
|
|
|
/* Construct a new connection string in key='value' format. */
|
|
|
|
for (i = 0; keywords[i] != NULL; i++)
|
|
|
|
{
|
|
|
|
if (strcmp(keywords[i], "dbname") == 0 ||
|
|
|
|
strcmp(keywords[i], "password") == 0 ||
|
|
|
|
strcmp(keywords[i], "fallback_application_name") == 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (!firstkeyword)
|
|
|
|
appendPQExpBufferChar(buf, ' ');
|
|
|
|
firstkeyword = false;
|
|
|
|
appendPQExpBuffer(buf, "%s=", keywords[i]);
|
2016-08-08 16:07:46 +02:00
|
|
|
appendConnStrVal(buf, values[i]);
|
2013-02-25 18:39:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
connstr = pg_strdup(buf->data);
|
|
|
|
destroyPQExpBuffer(buf);
|
|
|
|
return connstr;
|
|
|
|
}
|
2002-08-27 20:57:26 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Run a query, return the results, exit program on failure.
|
|
|
|
*/
|
|
|
|
static PGresult *
|
|
|
|
executeQuery(PGconn *conn, const char *query)
|
|
|
|
{
|
|
|
|
PGresult *res;
|
|
|
|
|
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
|
|
|
pg_log_info("executing %s", query);
|
2003-05-31 00:55:16 +02:00
|
|
|
|
2002-08-27 20:57:26 +02:00
|
|
|
res = PQexec(conn, query);
|
|
|
|
if (!res ||
|
|
|
|
PQresultStatus(res) != PGRES_TUPLES_OK)
|
|
|
|
{
|
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
|
|
|
pg_log_error("query failed: %s", PQerrorMessage(conn));
|
2022-04-08 20:55:14 +02:00
|
|
|
pg_log_error_detail("Query was: %s", query);
|
2002-08-27 20:57:26 +02:00
|
|
|
PQfinish(conn);
|
2012-02-16 17:49:20 +01:00
|
|
|
exit_nicely(1);
|
2002-08-27 20:57:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
2004-06-07 22:35:57 +02:00
|
|
|
|
2005-07-31 19:19:22 +02:00
|
|
|
/*
|
|
|
|
* As above for a SQL command (which returns nothing).
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
executeCommand(PGconn *conn, const char *query)
|
|
|
|
{
|
|
|
|
PGresult *res;
|
|
|
|
|
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
|
|
|
pg_log_info("executing %s", query);
|
2005-07-31 19:19:22 +02:00
|
|
|
|
|
|
|
res = PQexec(conn, query);
|
|
|
|
if (!res ||
|
|
|
|
PQresultStatus(res) != PGRES_COMMAND_OK)
|
|
|
|
{
|
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
|
|
|
pg_log_error("query failed: %s", PQerrorMessage(conn));
|
2022-04-08 20:55:14 +02:00
|
|
|
pg_log_error_detail("Query was: %s", query);
|
2005-07-31 19:19:22 +02:00
|
|
|
PQfinish(conn);
|
2012-02-16 17:49:20 +01:00
|
|
|
exit_nicely(1);
|
2005-07-31 19:19:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
PQclear(res);
|
|
|
|
}
|
|
|
|
|
2004-06-07 22:35:57 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* dumpTimestamp
|
|
|
|
*/
|
|
|
|
static void
|
2014-10-27 01:59:21 +01:00
|
|
|
dumpTimestamp(const char *msg)
|
2004-06-07 22:35:57 +02:00
|
|
|
{
|
2014-09-06 01:22:31 +02:00
|
|
|
char buf[64];
|
2004-06-07 22:35:57 +02:00
|
|
|
time_t now = time(NULL);
|
|
|
|
|
2014-10-27 01:59:21 +01:00
|
|
|
if (strftime(buf, sizeof(buf), PGDUMP_STRFTIME_FMT, localtime(&now)) != 0)
|
2007-01-25 04:30:43 +01:00
|
|
|
fprintf(OPF, "-- %s %s\n\n", msg, buf);
|
2004-06-07 22:35:57 +02:00
|
|
|
}
|
Make role grant system more consistent with other privileges.
Previously, membership of role A in role B could be recorded in the
catalog tables only once. This meant that a new grant of role A to
role B would overwrite the previous grant. For other object types, a
new grant of permission on an object - in this case role A - exists
along side the existing grant provided that the grantor is different.
Either grant can be revoked independently of the other, and
permissions remain so long as at least one grant remains. Make role
grants work similarly.
Previously, when granting membership in a role, the superuser could
specify any role whatsoever as the grantor, but for other object types,
the grantor of record must be either the owner of the object, or a
role that currently has privileges to perform a similar GRANT.
Implement the same scheme for role grants, treating the bootstrap
superuser as the role owner since roles do not have owners. This means
that attempting to revoke a grant, or admin option on a grant, can now
fail if there are dependent privileges, and that CASCADE can be used
to revoke these. It also means that you can't grant ADMIN OPTION on
a role back to a user who granted it directly or indirectly to you,
similar to how you can't give WITH GRANT OPTION on a privilege back
to a role which granted it directly or indirectly to you.
Previously, only the superuser could specify GRANTED BY with a user
other than the current user. Relax that rule to allow the grantor
to be any role whose privileges the current user posseses. This
doesn't improve compatibility with what we do for other object types,
where support for GRANTED BY is entirely vestigial, but it makes this
feature more usable and seems to make sense to change at the same time
we're changing related behaviors.
Along the way, fix "ALTER GROUP group_name ADD USER user_name" to
require the same privileges as "GRANT group_name TO user_name".
Previously, CREATEROLE privileges were sufficient for either, but
only the former form was permissible with ADMIN OPTION on the role.
Now, either CREATEROLE or ADMIN OPTION on the role suffices for
either spelling.
Patch by me, reviewed by Stephen Frost.
Discussion: http://postgr.es/m/CA+TgmoaFr-RZeQ+WoQ5nKPv97oT9+aDgK_a5+qWHSgbDsMp1Vg@mail.gmail.com
2022-08-22 17:35:17 +02:00
|
|
|
|
Read include/exclude commands for dump/restore from file
When there is a need to filter multiple tables with include and/or exclude
options it's quite possible to run into the limitations of the commandline.
This adds a --filter=FILENAME feature to pg_dump, pg_dumpall and pg_restore
which is used to supply a file containing object exclude/include commands
which work just like their commandline counterparts. The format of the file
is one command per row like:
<command> <object> <objectpattern>
<command> can be "include" or "exclude", <object> can be table_data, index
table_data_and_children, database, extension, foreign_data, function, table
schema, table_and_children or trigger.
This patch has gone through many revisions and design changes over a long
period of time, the list of reviewers reflect reviewers of some version of
the patch, not necessarily the final version.
Patch by Pavel Stehule with some additional hacking by me.
Author: Pavel Stehule <pavel.stehule@gmail.com>
Reviewed-by: Justin Pryzby <pryzby@telsasoft.com>
Reviewed-by: vignesh C <vignesh21@gmail.com>
Reviewed-by: Dean Rasheed <dean.a.rasheed@gmail.com>
Reviewed-by: Tomas Vondra <tomas.vondra@enterprisedb.com>
Reviewed-by: Julien Rouhaud <rjuju123@gmail.com>
Reviewed-by: Erik Rijkers <er@xs4all.nl>
Discussion: https://postgr.es/m/CAFj8pRB10wvW0CC9Xq=1XDs=zCQxer3cbLcNZa+qiX4cUH-G_A@mail.gmail.com
2023-11-29 14:56:24 +01:00
|
|
|
/*
|
|
|
|
* read_dumpall_filters - retrieve database identifier patterns from file
|
|
|
|
*
|
|
|
|
* Parse the specified filter file for include and exclude patterns, and add
|
|
|
|
* them to the relevant lists. If the filename is "-" then filters will be
|
|
|
|
* read from STDIN rather than a file.
|
|
|
|
*
|
|
|
|
* At the moment, the only allowed filter is for database exclusion.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
read_dumpall_filters(const char *filename, SimpleStringList *pattern)
|
|
|
|
{
|
|
|
|
FilterStateData fstate;
|
|
|
|
char *objname;
|
|
|
|
FilterCommandType comtype;
|
|
|
|
FilterObjectType objtype;
|
|
|
|
|
|
|
|
filter_init(&fstate, filename, exit);
|
|
|
|
|
|
|
|
while (filter_read_item(&fstate, &objname, &comtype, &objtype))
|
|
|
|
{
|
|
|
|
if (comtype == FILTER_COMMAND_TYPE_INCLUDE)
|
|
|
|
{
|
2023-11-30 10:56:53 +01:00
|
|
|
pg_log_filter_error(&fstate, _("%s filter for \"%s\" is not allowed"),
|
Read include/exclude commands for dump/restore from file
When there is a need to filter multiple tables with include and/or exclude
options it's quite possible to run into the limitations of the commandline.
This adds a --filter=FILENAME feature to pg_dump, pg_dumpall and pg_restore
which is used to supply a file containing object exclude/include commands
which work just like their commandline counterparts. The format of the file
is one command per row like:
<command> <object> <objectpattern>
<command> can be "include" or "exclude", <object> can be table_data, index
table_data_and_children, database, extension, foreign_data, function, table
schema, table_and_children or trigger.
This patch has gone through many revisions and design changes over a long
period of time, the list of reviewers reflect reviewers of some version of
the patch, not necessarily the final version.
Patch by Pavel Stehule with some additional hacking by me.
Author: Pavel Stehule <pavel.stehule@gmail.com>
Reviewed-by: Justin Pryzby <pryzby@telsasoft.com>
Reviewed-by: vignesh C <vignesh21@gmail.com>
Reviewed-by: Dean Rasheed <dean.a.rasheed@gmail.com>
Reviewed-by: Tomas Vondra <tomas.vondra@enterprisedb.com>
Reviewed-by: Julien Rouhaud <rjuju123@gmail.com>
Reviewed-by: Erik Rijkers <er@xs4all.nl>
Discussion: https://postgr.es/m/CAFj8pRB10wvW0CC9Xq=1XDs=zCQxer3cbLcNZa+qiX4cUH-G_A@mail.gmail.com
2023-11-29 14:56:24 +01:00
|
|
|
"include",
|
|
|
|
filter_object_type_name(objtype));
|
|
|
|
exit_nicely(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (objtype)
|
|
|
|
{
|
|
|
|
case FILTER_OBJECT_TYPE_NONE:
|
|
|
|
break;
|
|
|
|
case FILTER_OBJECT_TYPE_FUNCTION:
|
|
|
|
case FILTER_OBJECT_TYPE_INDEX:
|
|
|
|
case FILTER_OBJECT_TYPE_TABLE_DATA:
|
|
|
|
case FILTER_OBJECT_TYPE_TABLE_DATA_AND_CHILDREN:
|
|
|
|
case FILTER_OBJECT_TYPE_TRIGGER:
|
|
|
|
case FILTER_OBJECT_TYPE_EXTENSION:
|
|
|
|
case FILTER_OBJECT_TYPE_FOREIGN_DATA:
|
|
|
|
case FILTER_OBJECT_TYPE_SCHEMA:
|
|
|
|
case FILTER_OBJECT_TYPE_TABLE:
|
|
|
|
case FILTER_OBJECT_TYPE_TABLE_AND_CHILDREN:
|
2023-11-30 10:56:53 +01:00
|
|
|
pg_log_filter_error(&fstate, _("unsupported filter object"));
|
Read include/exclude commands for dump/restore from file
When there is a need to filter multiple tables with include and/or exclude
options it's quite possible to run into the limitations of the commandline.
This adds a --filter=FILENAME feature to pg_dump, pg_dumpall and pg_restore
which is used to supply a file containing object exclude/include commands
which work just like their commandline counterparts. The format of the file
is one command per row like:
<command> <object> <objectpattern>
<command> can be "include" or "exclude", <object> can be table_data, index
table_data_and_children, database, extension, foreign_data, function, table
schema, table_and_children or trigger.
This patch has gone through many revisions and design changes over a long
period of time, the list of reviewers reflect reviewers of some version of
the patch, not necessarily the final version.
Patch by Pavel Stehule with some additional hacking by me.
Author: Pavel Stehule <pavel.stehule@gmail.com>
Reviewed-by: Justin Pryzby <pryzby@telsasoft.com>
Reviewed-by: vignesh C <vignesh21@gmail.com>
Reviewed-by: Dean Rasheed <dean.a.rasheed@gmail.com>
Reviewed-by: Tomas Vondra <tomas.vondra@enterprisedb.com>
Reviewed-by: Julien Rouhaud <rjuju123@gmail.com>
Reviewed-by: Erik Rijkers <er@xs4all.nl>
Discussion: https://postgr.es/m/CAFj8pRB10wvW0CC9Xq=1XDs=zCQxer3cbLcNZa+qiX4cUH-G_A@mail.gmail.com
2023-11-29 14:56:24 +01:00
|
|
|
exit_nicely(1);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case FILTER_OBJECT_TYPE_DATABASE:
|
|
|
|
simple_string_list_append(pattern, objname);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (objname)
|
|
|
|
free(objname);
|
|
|
|
}
|
|
|
|
|
|
|
|
filter_free(&fstate);
|
|
|
|
}
|