diff --git a/0003-CVE-2019-10164-1.patch b/0003-CVE-2019-10164-1.patch deleted file mode 100644 index 45a21d1bebb8f5d3ad9f653974eb93c2e22b4737..0000000000000000000000000000000000000000 --- a/0003-CVE-2019-10164-1.patch +++ /dev/null @@ -1,108 +0,0 @@ -From 90adc16ea13750a6b6f704c6cf65dc0f1bdb845c Mon Sep 17 00:00:00 2001 -From: Michael Paquier -Date: Mon, 17 Jun 2019 21:48:34 +0900 -Subject: [PATCH] Fix buffer overflow when parsing SCRAM verifiers in backend - -Any authenticated user can overflow a stack-based buffer by changing the -user's own password to a purpose-crafted value. This often suffices to -execute arbitrary code as the PostgreSQL operating system account. - -This fix is contributed by multiple folks, based on an initial analysis -from Tom Lane. This issue has been introduced by 68e61ee, so it was -possible to make use of it at authentication time. It became more -easily to trigger after ccae190 which has made the SCRAM parsing more -strict when changing a password, in the case where the client passes -down a verifier already hashed using SCRAM. Back-patch to v10 where -SCRAM has been introduced. - -Reported-by: Alexander Lakhin -Author: Jonathan Katz, Heikki Linnakangas, Michael Paquier -Security: CVE-2019-10164 -Backpatch-through: 10 ---- - src/backend/libpq/auth-scram.c | 35 ++++++++++++++++++++++++++-------- - src/test/regress/expected/password.out | 23 ++++++++++++++++++++++ - src/test/regress/sql/password.sql | 18 +++++++++++++++++ - 3 files changed, 68 insertions(+), 8 deletions(-) - -diff -Nurp postgresql-10.5/src/backend/libpq/auth-scram.c postgresql-10.5-bak/src/backend/libpq/auth-scram.c ---- postgresql-10.5/src/backend/libpq/auth-scram.c 2018-08-06 16:05:31.000000000 -0400 -+++ postgresql-10.5-bak/src/backend/libpq/auth-scram.c 2019-08-01 10:03:08.505000000 -0400 -@@ -474,6 +474,12 @@ scram_verify_plain_password(const char * - /* - * Parse and validate format of given SCRAM verifier. - * -+ * On success, the iteration count, salt, stored key, and server key are -+ * extracted from the verifier, and returned to the caller. For 'stored_key' -+ * and 'server_key', the caller must pass pre-allocated buffers of size -+ * SCRAM_KEY_LEN. Salt is returned as a base64-encoded, null-terminated -+ * string. The buffer for the salt is palloc'd by this function. -+ * - * Returns true if the SCRAM verifier has been parsed, and false otherwise. - */ - static bool -@@ -489,6 +495,8 @@ parse_scram_verifier(const char *verifie - char *serverkey_str; - int decoded_len; - char *decoded_salt_buf; -+ char *decoded_stored_buf; -+ char *decoded_server_buf; - - /* - * The verifier is of form: -@@ -521,7 +529,8 @@ parse_scram_verifier(const char *verifie - * although we return the encoded version to the caller. - */ - decoded_salt_buf = palloc(pg_b64_dec_len(strlen(salt_str))); -- decoded_len = pg_b64_decode(salt_str, strlen(salt_str), decoded_salt_buf); -+ decoded_len = pg_b64_decode(salt_str, strlen(salt_str), -+ decoded_salt_buf); - if (decoded_len < 0) - goto invalid_verifier; - *salt = pstrdup(salt_str); -@@ -529,28 +538,38 @@ parse_scram_verifier(const char *verifie - /* - * Decode StoredKey and ServerKey. - */ -- if (pg_b64_dec_len(strlen(storedkey_str) != SCRAM_KEY_LEN)) -- goto invalid_verifier; -+ decoded_stored_buf = palloc(pg_b64_dec_len(strlen(storedkey_str))); - decoded_len = pg_b64_decode(storedkey_str, strlen(storedkey_str), -- (char *) stored_key); -+ decoded_stored_buf); - if (decoded_len != SCRAM_KEY_LEN) - goto invalid_verifier; -+ memcpy(stored_key, decoded_stored_buf, SCRAM_KEY_LEN); - -- if (pg_b64_dec_len(strlen(serverkey_str) != SCRAM_KEY_LEN)) -- goto invalid_verifier; -+ decoded_server_buf = palloc(pg_b64_dec_len(strlen(serverkey_str))); - decoded_len = pg_b64_decode(serverkey_str, strlen(serverkey_str), -- (char *) server_key); -+ decoded_server_buf); - if (decoded_len != SCRAM_KEY_LEN) - goto invalid_verifier; -+ memcpy(server_key, decoded_server_buf, SCRAM_KEY_LEN); - - return true; - - invalid_verifier: -- pfree(v); - *salt = NULL; - return false; - } - -+/* -+ * Generate plausible SCRAM verifier parameters for mock authentication. -+ * -+ * In a normal authentication, these are extracted from the verifier -+ * stored in the server. This function generates values that look -+ * realistic, for when there is no stored verifier. -+ * -+ * Like in parse_scram_verifier(), for 'stored_key' and 'server_key', the -+ * caller must pass pre-allocated buffers of size SCRAM_KEY_LEN, and -+ * the buffer for the salt is palloc'd by this function. -+ */ - static void - mock_scram_verifier(const char *username, int *iterations, char **salt, - uint8 *stored_key, uint8 *server_key) diff --git a/0004-CVE-2019-10164-2.patch b/0004-CVE-2019-10164-2.patch deleted file mode 100644 index edb4d260a07d269041e10f75dcb3f4fe4ee8fa2e..0000000000000000000000000000000000000000 --- a/0004-CVE-2019-10164-2.patch +++ /dev/null @@ -1,77 +0,0 @@ -From d72a7e4da1001b29a661a4b1a52cb5c4d708bab0 Mon Sep 17 00:00:00 2001 -From: Michael Paquier -Date: Mon, 17 Jun 2019 22:14:09 +0900 -Subject: [PATCH] Fix buffer overflow when processing SCRAM final message in - libpq - -When a client connects to a rogue server sending specifically-crafted -messages, this can suffice to execute arbitrary code as the operating -system account used by the client. - -While on it, fix one error handling when decoding an incorrect salt -included in the first message received from server. - -Author: Michael Paquier -Reviewed-by: Jonathan Katz, Heikki Linnakangas -Security: CVE-2019-10164 -Backpatch-through: 10 ---- - src/interfaces/libpq/fe-auth-scram.c | 21 ++++++++++++++++++++- - 1 file changed, 20 insertions(+), 1 deletion(-) - -diff --git a/src/interfaces/libpq/fe-auth-scram.c b/src/interfaces/libpq/fe-auth-scram.c -index 7fa7f34c80..4cdf9ba93b 100644 ---- a/src/interfaces/libpq/fe-auth-scram.c -+++ b/src/interfaces/libpq/fe-auth-scram.c -@@ -462,6 +462,12 @@ read_server_first_message(fe_scram_state *state, char *input, - state->saltlen = pg_b64_decode(encoded_salt, - strlen(encoded_salt), - state->salt); -+ if (state->saltlen < 0) -+ { -+ printfPQExpBuffer(errormessage, -+ libpq_gettext("malformed SCRAM message (invalid salt)\n")); -+ return false; -+ } - - iterations_str = read_attr_value(&input, 'i', errormessage); - if (iterations_str == NULL) -@@ -492,6 +498,7 @@ read_server_final_message(fe_scram_state *state, char *input, - PQExpBuffer errormessage) - { - char *encoded_server_signature; -+ char *decoded_server_signature; - int server_signature_len; - - state->server_final_message = strdup(input); -@@ -525,15 +532,27 @@ read_server_final_message(fe_scram_state *state, char *input, - printfPQExpBuffer(errormessage, - libpq_gettext("malformed SCRAM message (garbage at end of server-final-message)\n")); - -+ server_signature_len = pg_b64_dec_len(strlen(encoded_server_signature)); -+ decoded_server_signature = malloc(server_signature_len); -+ if (!decoded_server_signature) -+ { -+ printfPQExpBuffer(errormessage, -+ libpq_gettext("out of memory\n")); -+ return false; -+ } -+ - server_signature_len = pg_b64_decode(encoded_server_signature, - strlen(encoded_server_signature), -- state->ServerSignature); -+ decoded_server_signature); - if (server_signature_len != SCRAM_KEY_LEN) - { -+ free(decoded_server_signature); - printfPQExpBuffer(errormessage, - libpq_gettext("malformed SCRAM message (invalid server signature)\n")); - return false; - } -+ memcpy(state->ServerSignature, decoded_server_signature, SCRAM_KEY_LEN); -+ free(decoded_server_signature); - - return true; - } --- -2.11.0 diff --git a/0005-CVE-2019-10208.patch b/0005-CVE-2019-10208.patch deleted file mode 100644 index d16ae170e88f08cad18ad3409e46a598f0d5c64f..0000000000000000000000000000000000000000 --- a/0005-CVE-2019-10208.patch +++ /dev/null @@ -1,224 +0,0 @@ -From 2062007cbf7008de383c8f2f4a9ad466ea243acf Mon Sep 17 00:00:00 2001 -From: Noah Misch -Date: Mon, 5 Aug 2019 07:48:41 -0700 -Subject: [PATCH] Require the schema qualification in pg_temp.type_name(arg). - -Commit aa27977fe21a7dfa4da4376ad66ae37cb8f0d0b5 introduced this -restriction for pg_temp.function_name(arg); do likewise for types -created in temporary schemas. Programs that this breaks should add -"pg_temp." schema qualification or switch to arg::type_name syntax. -Back-patch to 9.4 (all supported versions). - -Reviewed by Tom Lane. Reported by Tom Lane. - -Security: CVE-2019-10208 ---- - src/backend/catalog/namespace.c | 15 ++++++++++++++- - src/backend/parser/parse_func.c | 7 ++++++- - src/backend/parser/parse_type.c | 24 +++++++++++++++++++++--- - src/backend/utils/adt/ruleutils.c | 8 ++++++++ - src/include/catalog/namespace.h | 1 + - src/include/parser/parse_type.h | 3 +++ - src/test/regress/expected/temp.out | 15 +++++++++++++++ - src/test/regress/sql/temp.sql | 12 ++++++++++++ - 8 files changed, 79 insertions(+), 5 deletions(-) - -diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c -index 5a737c8ab3..6b75ce10da 100644 ---- a/src/backend/catalog/namespace.c -+++ b/src/backend/catalog/namespace.c -@@ -739,13 +739,23 @@ RelationIsVisible(Oid relid) - - /* - * TypenameGetTypid -+ * Wrapper for binary compatibility. -+ */ -+Oid -+TypenameGetTypid(const char *typname) -+{ -+ return TypenameGetTypidExtended(typname, true); -+} -+ -+/* -+ * TypenameGetTypidExtended - * Try to resolve an unqualified datatype name. - * Returns OID if type found in search path, else InvalidOid. - * - * This is essentially the same as RelnameGetRelid. - */ - Oid --TypenameGetTypid(const char *typname) -+TypenameGetTypidExtended(const char *typname, bool temp_ok) - { - Oid typid; - ListCell *l; -@@ -756,6 +766,9 @@ TypenameGetTypid(const char *typname) - { - Oid namespaceId = lfirst_oid(l); - -+ if (!temp_ok && namespaceId == myTempNamespace) -+ continue; /* do not look in temp namespace */ -+ - typid = GetSysCacheOid2(TYPENAMENSP, - PointerGetDatum(typname), - ObjectIdGetDatum(namespaceId)); -diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c -index 25ae4e5949..571d3d1b62 100644 ---- a/src/backend/parser/parse_func.c -+++ b/src/backend/parser/parse_func.c -@@ -1769,7 +1769,12 @@ FuncNameAsType(List *funcname) - Oid result; - Type typtup; - -- typtup = LookupTypeName(NULL, makeTypeNameFromNameList(funcname), NULL, false); -+ /* -+ * temp_ok=false protects the -+ * contract for writing SECURITY DEFINER functions safely. -+ */ -+ typtup = LookupTypeNameExtended(NULL, makeTypeNameFromNameList(funcname), -+ NULL, false, false); - if (typtup == NULL) - return InvalidOid; - -diff --git a/src/backend/parser/parse_type.c b/src/backend/parser/parse_type.c -index d0b3fbeb57..1171381487 100644 ---- a/src/backend/parser/parse_type.c -+++ b/src/backend/parser/parse_type.c -@@ -33,6 +33,18 @@ static int32 typenameTypeMod(ParseState *pstate, const TypeName *typeName, - - /* - * LookupTypeName -+ * Wrapper for typical case. -+ */ -+Type -+LookupTypeName(ParseState *pstate, const TypeName *typeName, -+ int32 *typmod_p, bool missing_ok) -+{ -+ return LookupTypeNameExtended(pstate, -+ typeName, typmod_p, true, missing_ok); -+} -+ -+/* -+ * LookupTypeNameExtended - * Given a TypeName object, lookup the pg_type syscache entry of the type. - * Returns NULL if no such type can be found. If the type is found, - * the typmod value represented in the TypeName struct is computed and -@@ -51,11 +63,17 @@ static int32 typenameTypeMod(ParseState *pstate, const TypeName *typeName, - * found but is a shell, and there is typmod decoration, an error will be - * thrown --- this is intentional. - * -+ * If temp_ok is false, ignore types in the temporary namespace. Pass false -+ * when the caller will decide, using goodness of fit criteria, whether the -+ * typeName is actually a type or something else. If typeName always denotes -+ * a type (or denotes nothing), pass true. -+ * - * pstate is only used for error location info, and may be NULL. - */ - Type --LookupTypeName(ParseState *pstate, const TypeName *typeName, -- int32 *typmod_p, bool missing_ok) -+LookupTypeNameExtended(ParseState *pstate, -+ const TypeName *typeName, int32 *typmod_p, -+ bool temp_ok, bool missing_ok) - { - Oid typoid; - HeapTuple tup; -@@ -172,7 +190,7 @@ LookupTypeName(ParseState *pstate, const TypeName *typeName, - else - { - /* Unqualified type name, so search the search path */ -- typoid = TypenameGetTypid(typname); -+ typoid = TypenameGetTypidExtended(typname, temp_ok); - } - - /* If an array reference, return the array type instead */ -diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c -index 3d1a701775..01789291bb 100644 ---- a/src/backend/utils/adt/ruleutils.c -+++ b/src/backend/utils/adt/ruleutils.c -@@ -9273,6 +9273,14 @@ get_coercion_expr(Node *arg, deparse_context *context, - if (!PRETTY_PAREN(context)) - appendStringInfoChar(buf, ')'); - } -+ -+ /* -+ * Never emit resulttype(arg) functional notation. A pg_proc entry could -+ * take precedence, and a resulttype in pg_temp would require schema -+ * qualification that format_type_with_typemod() would usually omit. We've -+ * standardized on arg::resulttype, but CAST(arg AS resulttype) notation -+ * would work fine. -+ */ - appendStringInfo(buf, "::%s", - format_type_with_typemod(resulttype, resulttypmod)); - } -diff --git a/src/include/catalog/namespace.h b/src/include/catalog/namespace.h -index f2ee935623..59c5ea5be2 100644 ---- a/src/include/catalog/namespace.h -+++ b/src/include/catalog/namespace.h -@@ -66,6 +66,7 @@ extern Oid RelnameGetRelid(const char *relname); - extern bool RelationIsVisible(Oid relid); - - extern Oid TypenameGetTypid(const char *typname); -+extern Oid TypenameGetTypidExtended(const char *typname, bool temp_ok); - extern bool TypeIsVisible(Oid typid); - - extern FuncCandidateList FuncnameGetCandidates(List *names, -diff --git a/src/include/parser/parse_type.h b/src/include/parser/parse_type.h -index 7b843d0b9d..ac1bf1009e 100644 ---- a/src/include/parser/parse_type.h -+++ b/src/include/parser/parse_type.h -@@ -21,6 +21,9 @@ typedef HeapTuple Type; - - extern Type LookupTypeName(ParseState *pstate, const TypeName *typeName, - int32 *typmod_p, bool missing_ok); -+extern Type LookupTypeNameExtended(ParseState *pstate, -+ const TypeName *typeName, int32 *typmod_p, -+ bool temp_ok, bool missing_ok); - extern Oid LookupTypeNameOid(ParseState *pstate, const TypeName *typeName, - bool missing_ok); - extern Type typenameType(ParseState *pstate, const TypeName *typeName, -diff --git a/src/test/regress/expected/temp.out b/src/test/regress/expected/temp.out -index 7046deb0c8..aad562791e 100644 ---- a/src/test/regress/expected/temp.out -+++ b/src/test/regress/expected/temp.out -@@ -199,3 +199,18 @@ select pg_temp.whoami(); - (1 row) - - drop table public.whereami; -+-- types in temp schema -+set search_path = pg_temp, public; -+create domain pg_temp.nonempty as text check (value <> ''); -+-- function-syntax invocation of types matches rules for functions -+select nonempty(''); -+ERROR: function nonempty(unknown) does not exist -+LINE 1: select nonempty(''); -+ ^ -+HINT: No function matches the given name and argument types. You might need to add explicit type casts. -+select pg_temp.nonempty(''); -+ERROR: value for domain nonempty violates check constraint "nonempty_check" -+-- other syntax matches rules for tables -+select ''::nonempty; -+ERROR: value for domain nonempty violates check constraint "nonempty_check" -+reset search_path; -diff --git a/src/test/regress/sql/temp.sql b/src/test/regress/sql/temp.sql -index d69a243fe7..c14c11444c 100644 ---- a/src/test/regress/sql/temp.sql -+++ b/src/test/regress/sql/temp.sql -@@ -151,3 +151,15 @@ select pg_temp.whoami(); - select pg_temp.whoami(); - - drop table public.whereami; -+ -+-- types in temp schema -+set search_path = pg_temp, public; -+create domain pg_temp.nonempty as text check (value <> ''); -+-- function-syntax invocation of types matches rules for functions -+select nonempty(''); -+select pg_temp.nonempty(''); -+-- other syntax matches rules for tables -+select ''::nonempty; -+ -+reset search_path; -+ --- -2.11.0 diff --git a/0006-CVE-2018-16850.patch b/0006-CVE-2018-16850.patch deleted file mode 100644 index cdbf59fc80332e35d5020cf395962c24d8a9c36f..0000000000000000000000000000000000000000 --- a/0006-CVE-2018-16850.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 21a134a26100b377191735ad49f996eac03047de Mon Sep 17 00:00:00 2001 -From: guiyao -Date: Thu, 17 Dec 2020 09:34:13 -0500 -Subject: [PATCH] backport to fix CVE-2018-16850 - ---- - src/backend/utils/adt/ruleutils.c | 10 ++++++---- - 1 files changed, 6 insertions(+), 4 deletions(-) - -diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c -index 4c9a49c..0eea491 100644 ---- a/src/backend/utils/adt/ruleutils.c -+++ b/src/backend/utils/adt/ruleutils.c -@@ -952,22 +952,24 @@ pg_get_triggerdef_worker(Oid trigid, bool pretty) - value = fastgetattr(ht_trig, Anum_pg_trigger_tgoldtable, - tgrel->rd_att, &isnull); - if (!isnull) -- tgoldtable = NameStr(*((NameData *) DatumGetPointer(value))); -+ tgoldtable = NameStr(*DatumGetName(value)); - else - tgoldtable = NULL; - value = fastgetattr(ht_trig, Anum_pg_trigger_tgnewtable, - tgrel->rd_att, &isnull); - if (!isnull) -- tgnewtable = NameStr(*((NameData *) DatumGetPointer(value))); -+ tgnewtable = NameStr(*DatumGetName(value)); - else - tgnewtable = NULL; - if (tgoldtable != NULL || tgnewtable != NULL) - { - appendStringInfoString(&buf, "REFERENCING "); - if (tgoldtable != NULL) -- appendStringInfo(&buf, "OLD TABLE AS %s ", tgoldtable); -+ appendStringInfo(&buf, "OLD TABLE AS %s ", -+ quote_identifier(tgoldtable)); - if (tgnewtable != NULL) -- appendStringInfo(&buf, "NEW TABLE AS %s ", tgnewtable); -+ appendStringInfo(&buf, "NEW TABLE AS %s ", -+ quote_identifier(tgnewtable)); - } - - if (TRIGGER_FOR_ROW(trigrec->tgtype)) --- -1.8.3.1 diff --git a/0007-CVE-2019-10130.patch b/0007-CVE-2019-10130.patch deleted file mode 100644 index b773c405844a15cc8f565a4b3858c7c3bfa3c7a2..0000000000000000000000000000000000000000 --- a/0007-CVE-2019-10130.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 1aebfbea83c4a3e1a0aba4b0910135dc5a45666c Mon Sep 17 00:00:00 2001 -From: Dean Rasheed -Date: Mon, 6 May 2019 11:38:43 +0100 -Subject: [PATCH] Fix security checks for selectivity estimation functions with - RLS. - -In commit e2d4ef8de8, security checks were added to prevent -user-supplied operators from running over data from pg_statistic -unless the user has table or column privileges on the table, or the -operator is leakproof. For a table with RLS, however, checking for -table or column privileges is insufficient, since that does not -guarantee that the user has permission to view all of the column's -data. - -Fix this by also checking for securityQuals on the RTE, and insisting -that the operator be leakproof if there are any. Thus the -leakproofness check will only be skipped if there are no securityQuals -and the user has table or column privileges on the table -- i.e., only -if we know that the user has access to all the data in the column. - -Back-patch to 9.5 where RLS was added. - -Dean Rasheed, reviewed by Jonathan Katz and Stephen Frost. - -Security: CVE-2019-10130 ---- - src/backend/utils/adt/selfuncs.c | 21 +++++++++++++++------ - src/test/regress/expected/rowsecurity.out | 21 +++++++++++++++++++++ - src/test/regress/sql/rowsecurity.sql | 20 ++++++++++++++++++++ - 3 files changed, 56 insertions(+), 6 deletions(-) - -diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c -index b41991315520..514612857ad6 100644 ---- a/src/backend/utils/adt/selfuncs.c -+++ b/src/backend/utils/adt/selfuncs.c -@@ -4597,9 +4597,13 @@ examine_variable(PlannerInfo *root, Node *node, int varRelid, - * For simplicity, we insist on the whole - * table being selectable, rather than trying - * to identify which column(s) the index -- * depends on. -+ * depends on. Also require all rows to be -+ * selectable --- there must be no -+ * securityQuals from security barrier views -+ * or RLS policies. - */ - vardata->acl_ok = -+ rte->securityQuals == NIL && - (pg_class_aclcheck(rte->relid, GetUserId(), - ACL_SELECT) == ACLCHECK_OK); - } -@@ -4663,12 +4667,17 @@ examine_simple_variable(PlannerInfo *root, Var *var, - - if (HeapTupleIsValid(vardata->statsTuple)) - { -- /* check if user has permission to read this column */ -+ /* -+ * Check if user has permission to read this column. We require -+ * all rows to be accessible, so there must be no securityQuals -+ * from security barrier views or RLS policies. -+ */ - vardata->acl_ok = -- (pg_class_aclcheck(rte->relid, GetUserId(), -- ACL_SELECT) == ACLCHECK_OK) || -- (pg_attribute_aclcheck(rte->relid, var->varattno, GetUserId(), -- ACL_SELECT) == ACLCHECK_OK); -+ rte->securityQuals == NIL && -+ ((pg_class_aclcheck(rte->relid, GetUserId(), -+ ACL_SELECT) == ACLCHECK_OK) || -+ (pg_attribute_aclcheck(rte->relid, var->varattno, GetUserId(), -+ ACL_SELECT) == ACLCHECK_OK)); - } - else - { --- -2.11.0 diff --git a/0008-CVE-2020-1720.patch b/0008-CVE-2020-1720.patch deleted file mode 100644 index cf04b4e709821c30b1807eb0b0b20734bc4e504e..0000000000000000000000000000000000000000 --- a/0008-CVE-2020-1720.patch +++ /dev/null @@ -1,42 +0,0 @@ -From b048f558dd7c26a0c630a2cff29d3d8981eaf6b9 Mon Sep 17 00:00:00 2001 -From: Alvaro Herrera -Date: Mon, 10 Feb 2020 11:47:09 -0300 -Subject: [PATCH] Fix priv checks for ALTER DEPENDS ON EXTENSION - -Marking an object as dependant on an extension did not have any -privilege check whatsoever; this allowed any user to mark objects as -droppable by anyone able to DROP EXTENSION, which could be used to cause -system-wide havoc. Disallow by checking that the calling user owns the -mentioned object. - -(No constraints are placed on the extension.) - -Security: CVE-2020-1720 -Reported-by: Tom Lane -Discussion: 31605.1566429043@sss.pgh.pa.us ---- - src/backend/commands/alter.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c -index fca85ba2c17f..1cb84182b05f 100644 ---- a/src/backend/commands/alter.c -+++ b/src/backend/commands/alter.c -@@ -430,6 +430,17 @@ ExecAlterObjectDependsStmt(AlterObjectDependsStmt *stmt, ObjectAddress *refAddre - get_object_address_rv(stmt->objectType, stmt->relation, (List *) stmt->object, - &rel, AccessExclusiveLock, false); - -+ /* -+ * Verify that the user is entitled to run the command. -+ * -+ * We don't check any privileges on the extension, because that's not -+ * needed. The object owner is stipulating, by running this command, that -+ * the extension owner can drop the object whenever they feel like it, -+ * which is not considered a problem. -+ */ -+ check_object_ownership(GetUserId(), -+ stmt->objectType, address, stmt->object, rel); -+ - /* - * If a relation was involved, it would have been opened and locked. We - * don't need the relation here, but we'll retain the lock until commit. diff --git a/0009-CVE-2020-14349-1.patch b/0009-CVE-2020-14349-1.patch deleted file mode 100644 index 42ef13864649a39b12ba4a067b61a24f29081ba5..0000000000000000000000000000000000000000 --- a/0009-CVE-2020-14349-1.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 11da97024abbe76b8c81e3f2375b2a62e9717c67 Mon Sep 17 00:00:00 2001 -From: Noah Misch -Date: Mon, 10 Aug 2020 09:22:54 -0700 -Subject: [PATCH] Empty search_path in logical replication apply worker and - walsender. - -This is like CVE-2018-1058 commit -582edc369cdbd348d68441fc50fa26a84afd0c1a. Today, a malicious user of a -publisher or subscriber database can invoke arbitrary SQL functions -under an identity running replication, often a superuser. This fix may -cause "does not exist" or "no schema has been selected to create in" -errors in a replication process. After upgrading, consider watching -server logs for these errors. Objects accruing schema qualification in -the wake of the earlier commit are unlikely to need further correction. -Back-patch to v10, which introduced logical replication. - -Security: CVE-2020-14349 -reason: fix CVE-2020-14349 -https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=11da97024abbe76b8c81e3f2375b2a62e9717c67 - -Signed-off-by: Noah Misch ---- - .../libpqwalreceiver/libpqwalreceiver.c | 17 +++++++++++++++++ - src/backend/replication/logical/worker.c | 6 ++++++ - src/test/subscription/t/001_rep_changes.pl | 4 ++++ - 3 files changed, 27 insertions(+) - -diff --git a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c -index 37b481c..564e6d3 100644 ---- a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c -+++ b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c -@@ -23,6 +23,7 @@ - #include "pqexpbuffer.h" - #include "access/xlog.h" - #include "catalog/pg_type.h" -+#include "fe_utils/connect.h" - #include "funcapi.h" - #include "mb/pg_wchar.h" - #include "miscadmin.h" -@@ -210,6 +211,22 @@ libpqrcv_connect(const char *conninfo, bool logical, const char *appname, - return NULL; - } - -+ if (logical) -+ { -+ PGresult *res; -+ -+ res = libpqrcv_PQexec(conn->streamConn, -+ ALWAYS_SECURE_SEARCH_PATH_SQL); -+ if (PQresultStatus(res) != PGRES_TUPLES_OK) -+ { -+ PQclear(res); -+ ereport(ERROR, -+ (errmsg("could not clear search path: %s", -+ pchomp(PQerrorMessage(conn->streamConn))))); -+ } -+ PQclear(res); -+ } -+ - conn->logical = logical; - - return conn; -diff --git a/src/backend/replication/logical/worker.c b/src/backend/replication/logical/worker.c -index bd60094..07b765a 100644 ---- a/src/backend/replication/logical/worker.c -+++ b/src/backend/replication/logical/worker.c -@@ -1548,6 +1548,12 @@ ApplyWorkerMain(Datum main_arg) - BackgroundWorkerInitializeConnectionByOid(MyLogicalRepWorker->dbid, - MyLogicalRepWorker->userid); - -+ /* -+ * Set always-secure search path, so malicious users can't redirect user -+ * code (e.g. pg_index.indexprs). -+ */ -+ SetConfigOption("search_path", "", PGC_SUSET, PGC_S_OVERRIDE); -+ - /* Load the subscription into persistent memory context. */ - ApplyContext = AllocSetContextCreate(TopMemoryContext, - "ApplyContext", -diff --git a/src/test/subscription/t/001_rep_changes.pl b/src/test/subscription/t/001_rep_changes.pl -index 0136c79..cda275b 100644 ---- a/src/test/subscription/t/001_rep_changes.pl -+++ b/src/test/subscription/t/001_rep_changes.pl -@@ -16,6 +16,10 @@ $node_subscriber->init(allows_streaming => 'logical'); - $node_subscriber->start; - - # Create some preexisting content on publisher -+$node_publisher->safe_psql( -+ 'postgres', -+ "CREATE FUNCTION public.pg_get_replica_identity_index(int) -+ RETURNS regclass LANGUAGE sql AS 'SELECT 1/0'"); # shall not call - $node_publisher->safe_psql('postgres', - "CREATE TABLE tab_notrep AS SELECT generate_series(1,10) AS a"); - $node_publisher->safe_psql('postgres', --- -2.23.0 \ No newline at end of file diff --git a/0010-CVE-2020-14349-2.patch b/0010-CVE-2020-14349-2.patch deleted file mode 100644 index 0b88b574e2603096b192c3eba03ea0409490bee9..0000000000000000000000000000000000000000 --- a/0010-CVE-2020-14349-2.patch +++ /dev/null @@ -1,54 +0,0 @@ -From cec57b1a0fbcd3833086ba686897c5883e0a2afc Mon Sep 17 00:00:00 2001 -From: Noah Misch -Date: Mon, 10 Aug 2020 09:22:54 -0700 -Subject: [PATCH] Document clashes between logical replication and untrusted -users. - -Back-patch to v10, which introduced logical replication. - -Security: CVE-2020-14349 -reason: fix CVE-2020-14349 -https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=cec57b1a0fbcd3833086ba686897c5883e0a2afc - -Signed-off-by: Noah Misch ---- - doc/src/sgml/logical-replication.sgml | 22 +++++++++++++++++++--- - 1 file changed, 19 insertions(+), 3 deletions(-) - -diff --git a/doc/src/sgml/logical-replication.sgml b/doc/src/sgml/logical-replication.sgml -index 41770a4..f5086b2 100644 ---- a/doc/src/sgml/logical-replication.sgml -+++ b/doc/src/sgml/logical-replication.sgml -@@ -490,11 +490,27 @@ - - Security - -+ -+ A user able to modify the schema of subscriber-side tables can execute -+ arbitrary code as a superuser. Limit ownership -+ and TRIGGER privilege on such tables to roles that -+ superusers trust. Moreover, if untrusted users can create tables, use only -+ publications that list tables explicitly. That is to say, create a -+ subscription FOR ALL TABLES only when superusers trust -+ every user permitted to create a non-temp table on the publisher or the -+ subscriber. -+ -+ - - The role used for the replication connection must have -- the REPLICATION attribute (or be a superuser). Access for the role must be -- configured in pg_hba.conf and it must have the -- LOGIN attribute. -+ the REPLICATION attribute (or be a superuser). If the -+ role lacks SUPERUSER and BYPASSRLS, -+ publisher row security policies can execute. If the role does not trust -+ all table owners, include options=-crow_security=off in -+ the connection string; if a table owner then adds a row security policy, -+ that setting will cause replication to halt rather than execute the policy. -+ Access for the role must be configured in pg_hba.conf -+ and it must have the LOGIN attribute. - - - --- -2.23.0 \ No newline at end of file diff --git a/0011-CVE-2020-14350.patch b/0011-CVE-2020-14350.patch deleted file mode 100644 index 6140806ae956c81f521cbb15fd562d40e52ceee6..0000000000000000000000000000000000000000 --- a/0011-CVE-2020-14350.patch +++ /dev/null @@ -1,1199 +0,0 @@ -From f43931e9bc3431026092b8d21f5b50b9b4896384 Mon Sep 17 00:00:00 2001 -From: Tom Lane -Date: Mon, 10 Aug 2020 10:44:42 -0400 -Subject: [PATCH] Make contrib modules' installation scripts more secure. - -Hostile objects located within the installation-time search_path could -capture references in an extension's installation or upgrade script. -If the extension is being installed with superuser privileges, this -opens the door to privilege escalation. While such hazards have existed -all along, their urgency increases with the v13 "trusted extensions" -feature, because that lets a non-superuser control the installation path -for a superuser-privileged script. Therefore, make a number of changes -to make such situations more secure: - -* Tweak the construction of the installation-time search_path to ensure -that references to objects in pg_catalog can't be subverted; and -explicitly add pg_temp to the end of the path to prevent attacks using -temporary objects. - -* Disable check_function_bodies within installation/upgrade scripts, -so that any security gaps in SQL-language or PL-language function bodies -cannot create a risk of unwanted installation-time code execution. - -* Adjust lookup of type input/receive functions and join estimator -functions to complain if there are multiple candidate functions. This -prevents capture of references to functions whose signature is not the -first one checked; and it's arguably more user-friendly anyway. - -* Modify various contrib upgrade scripts to ensure that catalog -modification queries are executed with secure search paths. (These -are in-place modifications with no extension version changes, since -it is the update process itself that is at issue, not the end result.) - -Extensions that depend on other extensions cannot be made fully secure -by these methods alone; therefore, revert the "trusted" marking that -commit eb67623c9 applied to earthdistance and hstore_plperl, pending -some better solution to that set of issues. - -Also add documentation around these issues, to help extension authors -write secure installation scripts. - -Patch by me, following an observation by Andres Freund; thanks -to Noah Misch for review. - -Security: CVE-2020-14350 -reason: fix CVE-2020-14349 -https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=7eeb1d9861b0a3f453f8b31c7648396cdd7f1e59 - -Signed-off-by: Tom Lane ---- - contrib/btree_gist/btree_gist--1.1--1.2.sql | 56 +++-- - contrib/citext/citext--1.1--1.2.sql | 26 ++- - contrib/citext/citext--1.2--1.3.sql | 18 +- - contrib/cube/cube--1.1--1.2.sql | 25 +- - contrib/earthdistance/earthdistance--1.1.sql | 2 +- - contrib/hstore/hstore--1.1--1.2.sql | 9 +- - contrib/hstore/hstore--1.3--1.4.sql | 35 ++- - contrib/intagg/intagg--1.0--1.1.sql | 14 +- - contrib/intarray/intarray--1.1--1.2.sql | 27 ++- - contrib/ltree/ltree--1.0--1.1.sql | 37 ++- - contrib/pg_trgm/pg_trgm--1.2--1.3.sql | 25 +- - contrib/seg/seg--1.0--1.1.sql | 23 +- - doc/src/sgml/earthdistance.sgml | 27 ++- - doc/src/sgml/extend.sgml | 228 ++++++++++++++++--- - doc/src/sgml/hstore.sgml | 9 + - doc/src/sgml/ltree.sgml | 9 + - doc/src/sgml/ref/create_extension.sgml | 34 ++- - src/backend/commands/extension.c | 21 +- - src/backend/commands/operatorcmds.c | 26 ++- - src/backend/commands/typecmds.c | 92 +- - 20 files changed, 533 insertions(+), 127 deletions(-) - -diff --git a/contrib/btree_gist/btree_gist--1.1--1.2.sql b/contrib/btree_gist/btree_gist--1.1--1.2.sql -index 8487f9b..d5a8c6c 100644 ---- a/contrib/btree_gist/btree_gist--1.1--1.2.sql -+++ b/contrib/btree_gist/btree_gist--1.1--1.2.sql -@@ -8,56 +8,72 @@ - -- wherein the signatures have been updated already. In that case to_regprocedure() will - -- return NULL and no updates will happen. - -+DO LANGUAGE plpgsql -+$$ -+DECLARE -+ my_schema pg_catalog.text := pg_catalog.quote_ident(pg_catalog.current_schema()); -+ old_path pg_catalog.text := pg_catalog.current_setting('search_path'); -+BEGIN -+-- for safety, transiently set search_path to just pg_catalog+pg_temp -+PERFORM pg_catalog.set_config('search_path', 'pg_catalog, pg_temp', true); -+ - UPDATE pg_catalog.pg_proc SET - proargtypes = pg_catalog.array_to_string(newtypes::pg_catalog.oid[], ' ')::pg_catalog.oidvector, - pronargs = pg_catalog.array_length(newtypes, 1) - FROM (VALUES --(NULL::pg_catalog.text, NULL::pg_catalog.regtype[]), -- establish column types -+(NULL::pg_catalog.text, NULL::pg_catalog.text[]), -- establish column types - ('gbt_oid_distance(internal,oid,int2,oid)', '{internal,oid,int2,oid,internal}'), - ('gbt_oid_union(bytea,internal)', '{internal,internal}'), --('gbt_oid_same(internal,internal,internal)', '{gbtreekey8,gbtreekey8,internal}'), -+('gbt_oid_same(internal,internal,internal)', '{SCH.gbtreekey8,SCH.gbtreekey8,internal}'), - ('gbt_int2_distance(internal,int2,int2,oid)', '{internal,int2,int2,oid,internal}'), - ('gbt_int2_union(bytea,internal)', '{internal,internal}'), --('gbt_int2_same(internal,internal,internal)', '{gbtreekey4,gbtreekey4,internal}'), -+('gbt_int2_same(internal,internal,internal)', '{SCH.gbtreekey4,SCH.gbtreekey4,internal}'), - ('gbt_int4_distance(internal,int4,int2,oid)', '{internal,int4,int2,oid,internal}'), - ('gbt_int4_union(bytea,internal)', '{internal,internal}'), --('gbt_int4_same(internal,internal,internal)', '{gbtreekey8,gbtreekey8,internal}'), -+('gbt_int4_same(internal,internal,internal)', '{SCH.gbtreekey8,SCH.gbtreekey8,internal}'), - ('gbt_int8_distance(internal,int8,int2,oid)', '{internal,int8,int2,oid,internal}'), - ('gbt_int8_union(bytea,internal)', '{internal,internal}'), --('gbt_int8_same(internal,internal,internal)', '{gbtreekey16,gbtreekey16,internal}'), -+('gbt_int8_same(internal,internal,internal)', '{SCH.gbtreekey16,SCH.gbtreekey16,internal}'), - ('gbt_float4_distance(internal,float4,int2,oid)', '{internal,float4,int2,oid,internal}'), - ('gbt_float4_union(bytea,internal)', '{internal,internal}'), --('gbt_float4_same(internal,internal,internal)', '{gbtreekey8,gbtreekey8,internal}'), -+('gbt_float4_same(internal,internal,internal)', '{SCH.gbtreekey8,SCH.gbtreekey8,internal}'), - ('gbt_float8_distance(internal,float8,int2,oid)', '{internal,float8,int2,oid,internal}'), - ('gbt_float8_union(bytea,internal)', '{internal,internal}'), --('gbt_float8_same(internal,internal,internal)', '{gbtreekey16,gbtreekey16,internal}'), -+('gbt_float8_same(internal,internal,internal)', '{SCH.gbtreekey16,SCH.gbtreekey16,internal}'), - ('gbt_ts_distance(internal,timestamp,int2,oid)', '{internal,timestamp,int2,oid,internal}'), - ('gbt_tstz_distance(internal,timestamptz,int2,oid)', '{internal,timestamptz,int2,oid,internal}'), - ('gbt_ts_union(bytea,internal)', '{internal,internal}'), --('gbt_ts_same(internal,internal,internal)', '{gbtreekey16,gbtreekey16,internal}'), -+('gbt_ts_same(internal,internal,internal)', '{SCH.gbtreekey16,SCH.gbtreekey16,internal}'), - ('gbt_time_distance(internal,time,int2,oid)', '{internal,time,int2,oid,internal}'), - ('gbt_time_union(bytea,internal)', '{internal,internal}'), --('gbt_time_same(internal,internal,internal)', '{gbtreekey16,gbtreekey16,internal}'), -+('gbt_time_same(internal,internal,internal)', '{SCH.gbtreekey16,SCH.gbtreekey16,internal}'), - ('gbt_date_distance(internal,date,int2,oid)', '{internal,date,int2,oid,internal}'), - ('gbt_date_union(bytea,internal)', '{internal,internal}'), --('gbt_date_same(internal,internal,internal)', '{gbtreekey8,gbtreekey8,internal}'), -+('gbt_date_same(internal,internal,internal)', '{SCH.gbtreekey8,SCH.gbtreekey8,internal}'), - ('gbt_intv_distance(internal,interval,int2,oid)', '{internal,interval,int2,oid,internal}'), - ('gbt_intv_union(bytea,internal)', '{internal,internal}'), --('gbt_intv_same(internal,internal,internal)', '{gbtreekey32,gbtreekey32,internal}'), -+('gbt_intv_same(internal,internal,internal)', '{SCH.gbtreekey32,SCH.gbtreekey32,internal}'), - ('gbt_cash_distance(internal,money,int2,oid)', '{internal,money,int2,oid,internal}'), - ('gbt_cash_union(bytea,internal)', '{internal,internal}'), --('gbt_cash_same(internal,internal,internal)', '{gbtreekey16,gbtreekey16,internal}'), -+('gbt_cash_same(internal,internal,internal)', '{SCH.gbtreekey16,SCH.gbtreekey16,internal}'), - ('gbt_macad_union(bytea,internal)', '{internal,internal}'), --('gbt_macad_same(internal,internal,internal)', '{gbtreekey16,gbtreekey16,internal}'), -+('gbt_macad_same(internal,internal,internal)', '{SCH.gbtreekey16,SCH.gbtreekey16,internal}'), - ('gbt_text_union(bytea,internal)', '{internal,internal}'), --('gbt_text_same(internal,internal,internal)', '{gbtreekey_var,gbtreekey_var,internal}'), -+('gbt_text_same(internal,internal,internal)', '{SCH.gbtreekey_var,SCH.gbtreekey_var,internal}'), - ('gbt_bytea_union(bytea,internal)', '{internal,internal}'), --('gbt_bytea_same(internal,internal,internal)', '{gbtreekey_var,gbtreekey_var,internal}'), -+('gbt_bytea_same(internal,internal,internal)', '{SCH.gbtreekey_var,SCH.gbtreekey_var,internal}'), - ('gbt_numeric_union(bytea,internal)', '{internal,internal}'), --('gbt_numeric_same(internal,internal,internal)', '{gbtreekey_var,gbtreekey_var,internal}'), -+('gbt_numeric_same(internal,internal,internal)', '{SCH.gbtreekey_var,SCH.gbtreekey_var,internal}'), - ('gbt_bit_union(bytea,internal)', '{internal,internal}'), --('gbt_bit_same(internal,internal,internal)', '{gbtreekey_var,gbtreekey_var,internal}'), -+('gbt_bit_same(internal,internal,internal)', '{SCH.gbtreekey_var,SCH.gbtreekey_var,internal}'), - ('gbt_inet_union(bytea,internal)', '{internal,internal}'), --('gbt_inet_same(internal,internal,internal)', '{gbtreekey16,gbtreekey16,internal}') --) AS update_data (oldproc, newtypes) --WHERE oid = pg_catalog.to_regprocedure(oldproc); -+('gbt_inet_same(internal,internal,internal)', '{SCH.gbtreekey16,SCH.gbtreekey16,internal}') -+) AS update_data (oldproc, newtypestext), -+LATERAL ( -+ SELECT array_agg(replace(typ, 'SCH', my_schema)::regtype) as newtypes FROM unnest(newtypestext) typ -+) ls -+WHERE oid = to_regprocedure(my_schema || '.' || replace(oldproc, 'SCH', my_schema)); -+ -+PERFORM pg_catalog.set_config('search_path', old_path, true); -+END -+$$; -diff --git a/contrib/citext/citext--1.1--1.2.sql b/contrib/citext/citext--1.1--1.2.sql -index 4f0e4bc..a8bba86 100644 ---- a/contrib/citext/citext--1.1--1.2.sql -+++ b/contrib/citext/citext--1.1--1.2.sql -@@ -41,14 +41,28 @@ ALTER FUNCTION replace(citext, citext, citext) PARALLEL SAFE; - ALTER FUNCTION split_part(citext, citext, int) PARALLEL SAFE; - ALTER FUNCTION translate(citext, citext, text) PARALLEL SAFE; - -+-- We have to update aggregates the hard way for lack of ALTER support -+DO LANGUAGE plpgsql -+$$ -+DECLARE -+ my_schema pg_catalog.text := pg_catalog.quote_ident(pg_catalog.current_schema()); -+ old_path pg_catalog.text := pg_catalog.current_setting('search_path'); -+BEGIN -+-- for safety, transiently set search_path to just pg_catalog+pg_temp -+PERFORM pg_catalog.set_config('search_path', 'pg_catalog, pg_temp', true); -+ - UPDATE pg_proc SET proparallel = 's' --WHERE oid = 'min(citext)'::pg_catalog.regprocedure; -+WHERE oid = (my_schema || '.min(' || my_schema || '.citext)')::pg_catalog.regprocedure; - - UPDATE pg_proc SET proparallel = 's' --WHERE oid = 'max(citext)'::pg_catalog.regprocedure; -+WHERE oid = (my_schema || '.max(' || my_schema || '.citext)')::pg_catalog.regprocedure; -+ -+UPDATE pg_aggregate SET aggcombinefn = (my_schema || '.citext_smaller')::regproc -+WHERE aggfnoid = (my_schema || '.max(' || my_schema || '.citext)')::pg_catalog.regprocedure; - --UPDATE pg_aggregate SET aggcombinefn = 'citext_smaller' --WHERE aggfnoid = 'max(citext)'::pg_catalog.regprocedure; -+UPDATE pg_aggregate SET aggcombinefn = (my_schema || '.citext_larger')::regproc -+WHERE aggfnoid = (my_schema || '.max(' || my_schema || '.citext)')::pg_catalog.regprocedure; - --UPDATE pg_aggregate SET aggcombinefn = 'citext_larger' --WHERE aggfnoid = 'max(citext)'::pg_catalog.regprocedure; -+PERFORM pg_catalog.set_config('search_path', old_path, true); -+END -+$$; -diff --git a/contrib/citext/citext--1.2--1.3.sql b/contrib/citext/citext--1.2--1.3.sql -index 4ab8679..24a7145 100644 ---- a/contrib/citext/citext--1.2--1.3.sql -+++ b/contrib/citext/citext--1.2--1.3.sql -@@ -3,5 +3,19 @@ - -- complain if script is sourced in psql, rather than via ALTER EXTENSION - \echo Use "ALTER EXTENSION citext UPDATE TO '1.3'" to load this file. \quit - --UPDATE pg_aggregate SET aggcombinefn = 'citext_smaller' --WHERE aggfnoid = 'min(citext)'::pg_catalog.regprocedure; -+-- We have to update aggregates the hard way for lack of ALTER support -+DO LANGUAGE plpgsql -+$$ -+DECLARE -+ my_schema pg_catalog.text := pg_catalog.quote_ident(pg_catalog.current_schema()); -+ old_path pg_catalog.text := pg_catalog.current_setting('search_path'); -+BEGIN -+-- for safety, transiently set search_path to just pg_catalog+pg_temp -+PERFORM pg_catalog.set_config('search_path', 'pg_catalog, pg_temp', true); -+ -+UPDATE pg_aggregate SET aggcombinefn = (my_schema || '.citext_smaller')::regproc -+WHERE aggfnoid = (my_schema || '.min(' || my_schema || '.citext)')::pg_catalog.regprocedure; -+ -+PERFORM pg_catalog.set_config('search_path', old_path, true); -+END -+$$; -diff --git a/contrib/cube/cube--1.1--1.2.sql b/contrib/cube/cube--1.1--1.2.sql -index 64a531e..76aba23 100644 ---- a/contrib/cube/cube--1.1--1.2.sql -+++ b/contrib/cube/cube--1.1--1.2.sql -@@ -7,16 +7,31 @@ - -- We use to_regprocedure() so that query doesn't fail if run against 9.6beta1 definitions, - -- wherein the signatures have been updated already. In that case to_regprocedure() will - -- return NULL and no updates will happen. -+DO LANGUAGE plpgsql -+$$ -+DECLARE -+ my_schema pg_catalog.text := pg_catalog.quote_ident(pg_catalog.current_schema()); -+ old_path pg_catalog.text := pg_catalog.current_setting('search_path'); -+BEGIN -+-- for safety, transiently set search_path to just pg_catalog+pg_temp -+PERFORM pg_catalog.set_config('search_path', 'pg_catalog, pg_temp', true); - - UPDATE pg_catalog.pg_proc SET - proargtypes = pg_catalog.array_to_string(newtypes::pg_catalog.oid[], ' ')::pg_catalog.oidvector, - pronargs = pg_catalog.array_length(newtypes, 1) - FROM (VALUES --(NULL::pg_catalog.text, NULL::pg_catalog.regtype[]), -- establish column types --('g_cube_consistent(internal,cube,int4,oid,internal)', '{internal,cube,int2,oid,internal}'), --('g_cube_distance(internal,cube,smallint,oid)', '{internal,cube,smallint,oid,internal}') --) AS update_data (oldproc, newtypes) --WHERE oid = pg_catalog.to_regprocedure(oldproc); -+(NULL::pg_catalog.text, NULL::pg_catalog.text[]), -- establish column types -+('g_cube_consistent(internal,SCH.cube,int4,oid,internal)', '{internal,SCH.cube,int2,oid,internal}'), -+('g_cube_distance(internal,SCH.cube,smallint,oid)', '{internal,SCH.cube,smallint,oid,internal}') -+) AS update_data (oldproc, newtypestext), -+LATERAL ( -+ SELECT array_agg(replace(typ, 'SCH', my_schema)::regtype) as newtypes FROM unnest(newtypestext) typ -+) ls -+WHERE oid = to_regprocedure(my_schema || '.' || replace(oldproc, 'SCH', my_schema)); -+ -+PERFORM pg_catalog.set_config('search_path', old_path, true); -+END -+$$; - - ALTER FUNCTION cube_in(cstring) PARALLEL SAFE; - ALTER FUNCTION cube(float8[], float8[]) PARALLEL SAFE; -diff --git a/contrib/earthdistance/earthdistance--1.1.sql b/contrib/earthdistance/earthdistance--1.1.sql -index 9136a54..9ef20ab 100644 ---- a/contrib/earthdistance/earthdistance--1.1.sql -+++ b/contrib/earthdistance/earthdistance--1.1.sql -@@ -31,7 +31,7 @@ CREATE DOMAIN earth AS cube - CONSTRAINT not_point check(cube_is_point(value)) - CONSTRAINT not_3d check(cube_dim(value) <= 3) - CONSTRAINT on_surface check(abs(cube_distance(value, '(0)'::cube) / -- earth() - 1) < '10e-7'::float8); -+ earth() - '1'::float8) < '10e-7'::float8); - - CREATE FUNCTION sec_to_gc(float8) - RETURNS float8 -diff --git a/contrib/hstore/hstore--1.1--1.2.sql b/contrib/hstore/hstore--1.1--1.2.sql -index a868ffe..cc69fc7 100644 ---- a/contrib/hstore/hstore--1.1--1.2.sql -+++ b/contrib/hstore/hstore--1.1--1.2.sql -@@ -9,10 +9,13 @@ - -- dependent on the extension. - - DO LANGUAGE plpgsql -- - $$ -- -+DECLARE -+ my_schema pg_catalog.text := pg_catalog.quote_ident(pg_catalog.current_schema()); -+ old_path pg_catalog.text := pg_catalog.current_setting('search_path'); - BEGIN -+-- for safety, transiently set search_path to just pg_catalog+pg_temp -+PERFORM pg_catalog.set_config('search_path', 'pg_catalog, pg_temp', true); - - PERFORM 1 - FROM pg_proc p -@@ -27,6 +30,7 @@ BEGIN - - IF NOT FOUND - THEN -+ PERFORM pg_catalog.set_config('search_path', old_path, true); - - CREATE FUNCTION hstore_to_json(hstore) - RETURNS json -@@ -43,6 +47,7 @@ BEGIN - - END IF; - -+PERFORM pg_catalog.set_config('search_path', old_path, true); - END; - - $$; -diff --git a/contrib/hstore/hstore--1.3--1.4.sql b/contrib/hstore/hstore--1.3--1.4.sql -index d68956b..53f26f9 100644 ---- a/contrib/hstore/hstore--1.3--1.4.sql -+++ b/contrib/hstore/hstore--1.3--1.4.sql -@@ -7,23 +7,38 @@ - -- We use to_regprocedure() so that query doesn't fail if run against 9.6beta1 definitions, - -- wherein the signatures have been updated already. In that case to_regprocedure() will - -- return NULL and no updates will happen. -+DO LANGUAGE plpgsql -+$$ -+DECLARE -+ my_schema pg_catalog.text := pg_catalog.quote_ident(pg_catalog.current_schema()); -+ old_path pg_catalog.text := pg_catalog.current_setting('search_path'); -+BEGIN -+-- for safety, transiently set search_path to just pg_catalog+pg_temp -+PERFORM pg_catalog.set_config('search_path', 'pg_catalog, pg_temp', true); - - UPDATE pg_catalog.pg_proc SET - proargtypes = pg_catalog.array_to_string(newtypes::pg_catalog.oid[], ' ')::pg_catalog.oidvector, - pronargs = pg_catalog.array_length(newtypes, 1) - FROM (VALUES --(NULL::pg_catalog.text, NULL::pg_catalog.regtype[]), -- establish column types --('ghstore_same(internal,internal,internal)', '{ghstore,ghstore,internal}'), --('ghstore_consistent(internal,internal,int4,oid,internal)', '{internal,hstore,int2,oid,internal}'), --('gin_extract_hstore(internal,internal)', '{hstore,internal}'), --('gin_extract_hstore_query(internal,internal,int2,internal,internal)', '{hstore,internal,int2,internal,internal}'), --('gin_consistent_hstore(internal,int2,internal,int4,internal,internal)', '{internal,int2,hstore,int4,internal,internal}') --) AS update_data (oldproc, newtypes) --WHERE oid = pg_catalog.to_regprocedure(oldproc); -+(NULL::pg_catalog.text, NULL::pg_catalog.text[]), -- establish column types -+('ghstore_same(internal,internal,internal)', '{SCH.ghstore,SCH.ghstore,internal}'), -+('ghstore_consistent(internal,internal,int4,oid,internal)', '{internal,SCH.hstore,int2,oid,internal}'), -+('gin_extract_hstore(internal,internal)', '{SCH.hstore,internal}'), -+('gin_extract_hstore_query(internal,internal,int2,internal,internal)', '{SCH.hstore,internal,int2,internal,internal}'), -+('gin_consistent_hstore(internal,int2,internal,int4,internal,internal)', '{internal,int2,SCH.hstore,int4,internal,internal}') -+) AS update_data (oldproc, newtypestext), -+LATERAL ( -+ SELECT array_agg(replace(typ, 'SCH', my_schema)::regtype) as newtypes FROM unnest(newtypestext) typ -+) ls -+WHERE oid = to_regprocedure(my_schema || '.' || replace(oldproc, 'SCH', my_schema)); - - UPDATE pg_catalog.pg_proc SET -- prorettype = 'ghstore'::pg_catalog.regtype --WHERE oid = pg_catalog.to_regprocedure('ghstore_union(internal,internal)'); -+ prorettype = (my_schema || '.ghstore')::pg_catalog.regtype -+WHERE oid = pg_catalog.to_regprocedure((my_schema || '.ghstore_union(internal,internal)')); -+ -+PERFORM pg_catalog.set_config('search_path', old_path, true); -+END -+$$; - - ALTER FUNCTION hstore_in(cstring) PARALLEL SAFE; - ALTER FUNCTION hstore_out(hstore) PARALLEL SAFE; -diff --git a/contrib/intagg/intagg--1.0--1.1.sql b/contrib/intagg/intagg--1.0--1.1.sql -index b2a2820..c0cc17a 100644 ---- a/contrib/intagg/intagg--1.0--1.1.sql -+++ b/contrib/intagg/intagg--1.0--1.1.sql -@@ -6,6 +6,18 @@ - ALTER FUNCTION int_agg_state(internal, int4) PARALLEL SAFE; - ALTER FUNCTION int_agg_final_array(internal) PARALLEL SAFE; - ALTER FUNCTION int_array_enum(int4[]) PARALLEL SAFE; -+DO LANGUAGE plpgsql -+$$ -+DECLARE -+ my_schema pg_catalog.text := pg_catalog.quote_ident(pg_catalog.current_schema()); -+ old_path pg_catalog.text := pg_catalog.current_setting('search_path'); -+BEGIN -+-- for safety, transiently set search_path to just pg_catalog+pg_temp -+PERFORM pg_catalog.set_config('search_path', 'pg_catalog, pg_temp', true); - - UPDATE pg_proc SET proparallel = 's' --WHERE oid = 'int_array_aggregate(int4)'::pg_catalog.regprocedure; -+WHERE oid = (my_schema || '.int_array_aggregate(int4)')::pg_catalog.regprocedure; -+ -+PERFORM pg_catalog.set_config('search_path', old_path, true); -+END -+$$; -diff --git a/contrib/intarray/intarray--1.1--1.2.sql b/contrib/intarray/intarray--1.1--1.2.sql -index 468f245..919340e 100644 ---- a/contrib/intarray/intarray--1.1--1.2.sql -+++ b/contrib/intarray/intarray--1.1--1.2.sql -@@ -7,23 +7,38 @@ - -- We use to_regprocedure() so that query doesn't fail if run against 9.6beta1 definitions, - -- wherein the signatures have been updated already. In that case to_regprocedure() will - -- return NULL and no updates will happen. -+DO LANGUAGE plpgsql -+$$ -+DECLARE -+ my_schema pg_catalog.text := pg_catalog.quote_ident(pg_catalog.current_schema()); -+ old_path pg_catalog.text := pg_catalog.current_setting('search_path'); -+BEGIN -+-- for safety, transiently set search_path to just pg_catalog+pg_temp -+PERFORM pg_catalog.set_config('search_path', 'pg_catalog, pg_temp', true); - - UPDATE pg_catalog.pg_proc SET - proargtypes = pg_catalog.array_to_string(newtypes::pg_catalog.oid[], ' ')::pg_catalog.oidvector, - pronargs = pg_catalog.array_length(newtypes, 1) - FROM (VALUES --(NULL::pg_catalog.text, NULL::pg_catalog.regtype[]), -- establish column types -+(NULL::pg_catalog.text, NULL::pg_catalog.text[]), -- establish column types - ('g_int_consistent(internal,_int4,int4,oid,internal)', '{internal,_int4,int2,oid,internal}'), - ('g_intbig_consistent(internal,internal,int4,oid,internal)', '{internal,_int4,int2,oid,internal}'), --('g_intbig_same(internal,internal,internal)', '{intbig_gkey,intbig_gkey,internal}'), -+('g_intbig_same(internal,internal,internal)', '{SCH.intbig_gkey,SCH.intbig_gkey,internal}'), - ('ginint4_queryextract(internal,internal,int2,internal,internal,internal,internal)', '{_int4,internal,int2,internal,internal,internal,internal}'), - ('ginint4_consistent(internal,int2,internal,int4,internal,internal,internal,internal)', '{internal,int2,_int4,int4,internal,internal,internal,internal}') --) AS update_data (oldproc, newtypes) --WHERE oid = pg_catalog.to_regprocedure(oldproc); -+) AS update_data (oldproc, newtypestext), -+LATERAL ( -+ SELECT array_agg(replace(typ, 'SCH', my_schema)::regtype) as newtypes FROM unnest(newtypestext) typ -+) ls -+WHERE oid = to_regprocedure(my_schema || '.' || replace(oldproc, 'SCH', my_schema)); - - UPDATE pg_catalog.pg_proc SET -- prorettype = 'intbig_gkey'::pg_catalog.regtype --WHERE oid = pg_catalog.to_regprocedure('g_intbig_union(internal,internal)'); -+ prorettype = (my_schema || '.intbig_gkey')::pg_catalog.regtype -+WHERE oid = pg_catalog.to_regprocedure(my_schema || '.g_intbig_union(internal,internal)'); -+ -+PERFORM pg_catalog.set_config('search_path', old_path, true); -+END -+$$; - - ALTER FUNCTION bqarr_in(cstring) PARALLEL SAFE; - ALTER FUNCTION bqarr_out(query_int) PARALLEL SAFE; -diff --git a/contrib/ltree/ltree--1.0--1.1.sql b/contrib/ltree/ltree--1.0--1.1.sql -index 155751a..2ce6f5a 100644 ---- a/contrib/ltree/ltree--1.0--1.1.sql -+++ b/contrib/ltree/ltree--1.0--1.1.sql -@@ -7,26 +7,41 @@ - -- We use to_regprocedure() so that query doesn't fail if run against 9.6beta1 definitions, - -- wherein the signatures have been updated already. In that case to_regprocedure() will - -- return NULL and no updates will happen. -+DO LANGUAGE plpgsql -+$$ -+DECLARE -+ my_schema pg_catalog.text := pg_catalog.quote_ident(pg_catalog.current_schema()); -+ old_path pg_catalog.text := pg_catalog.current_setting('search_path'); -+BEGIN -+-- for safety, transiently set search_path to just pg_catalog+pg_temp -+PERFORM pg_catalog.set_config('search_path', 'pg_catalog, pg_temp', true); - - UPDATE pg_catalog.pg_proc SET - proargtypes = pg_catalog.array_to_string(newtypes::pg_catalog.oid[], ' ')::pg_catalog.oidvector, - pronargs = pg_catalog.array_length(newtypes, 1) - FROM (VALUES --(NULL::pg_catalog.text, NULL::pg_catalog.regtype[]), -- establish column types --('ltree_consistent(internal,internal,int2,oid,internal)', '{internal,ltree,int2,oid,internal}'), --('ltree_same(internal,internal,internal)', '{ltree_gist,ltree_gist,internal}'), --('_ltree_consistent(internal,internal,int2,oid,internal)', '{internal,_ltree,int2,oid,internal}'), --('_ltree_same(internal,internal,internal)', '{ltree_gist,ltree_gist,internal}') --) AS update_data (oldproc, newtypes) --WHERE oid = pg_catalog.to_regprocedure(oldproc); -+(NULL::pg_catalog.text, NULL::pg_catalog.text[]), -- establish column types -+('ltree_consistent(internal,internal,int2,oid,internal)', '{internal,SCH.ltree,int2,oid,internal}'), -+('ltree_same(internal,internal,internal)', '{SCH.ltree_gist,SCH.ltree_gist,internal}'), -+('_ltree_consistent(internal,internal,int2,oid,internal)', '{internal,SCH._ltree,int2,oid,internal}'), -+('_ltree_same(internal,internal,internal)', '{SCH.ltree_gist,SCH.ltree_gist,internal}') -+) AS update_data (oldproc, newtypestext), -+LATERAL ( -+ SELECT array_agg(replace(typ, 'SCH', my_schema)::regtype) as newtypes FROM unnest(newtypestext) typ -+) ls -+WHERE oid = to_regprocedure(my_schema || '.' || replace(oldproc, 'SCH', my_schema)); - - UPDATE pg_catalog.pg_proc SET -- prorettype = 'ltree_gist'::pg_catalog.regtype --WHERE oid = pg_catalog.to_regprocedure('ltree_union(internal,internal)'); -+ prorettype = (my_schema || '.ltree_gist')::pg_catalog.regtype -+WHERE oid = pg_catalog.to_regprocedure(my_schema || '.ltree_union(internal,internal)'); - - UPDATE pg_catalog.pg_proc SET -- prorettype = 'ltree_gist'::pg_catalog.regtype --WHERE oid = pg_catalog.to_regprocedure('_ltree_union(internal,internal)'); -+ prorettype = (my_schema || '.ltree_gist')::pg_catalog.regtype -+WHERE oid = pg_catalog.to_regprocedure(my_schema || '._ltree_union(internal,internal)'); -+ -+PERFORM pg_catalog.set_config('search_path', old_path, true); -+END -+$$; - - ALTER FUNCTION ltree_in(cstring) PARALLEL SAFE; - ALTER FUNCTION ltree_out(ltree) PARALLEL SAFE; -diff --git a/contrib/pg_trgm/pg_trgm--1.2--1.3.sql b/contrib/pg_trgm/pg_trgm--1.2--1.3.sql -index b082dcd..8dc772c 100644 ---- a/contrib/pg_trgm/pg_trgm--1.2--1.3.sql -+++ b/contrib/pg_trgm/pg_trgm--1.2--1.3.sql -@@ -7,21 +7,36 @@ - -- We use to_regprocedure() so that query doesn't fail if run against 9.6beta1 definitions, - -- wherein the signatures have been updated already. In that case to_regprocedure() will - -- return NULL and no updates will happen. -+DO LANGUAGE plpgsql -+$$ -+DECLARE -+ my_schema pg_catalog.text := pg_catalog.quote_ident(pg_catalog.current_schema()); -+ old_path pg_catalog.text := pg_catalog.current_setting('search_path'); -+BEGIN -+-- for safety, transiently set search_path to just pg_catalog+pg_temp -+PERFORM pg_catalog.set_config('search_path', 'pg_catalog, pg_temp', true); - - UPDATE pg_catalog.pg_proc SET - proargtypes = pg_catalog.array_to_string(newtypes::pg_catalog.oid[], ' ')::pg_catalog.oidvector, - pronargs = pg_catalog.array_length(newtypes, 1) - FROM (VALUES --(NULL::pg_catalog.text, NULL::pg_catalog.regtype[]), -- establish column types -+(NULL::pg_catalog.text, NULL::pg_catalog.text[]), -- establish column types - ('gtrgm_consistent(internal,text,int4,oid,internal)', '{internal,text,int2,oid,internal}'), - ('gtrgm_distance(internal,text,int4,oid)', '{internal,text,int2,oid,internal}'), - ('gtrgm_union(bytea,internal)', '{internal,internal}') --) AS update_data (oldproc, newtypes) --WHERE oid = pg_catalog.to_regprocedure(oldproc); -+) AS update_data (oldproc, newtypestext), -+LATERAL ( -+ SELECT array_agg(replace(typ, 'SCH', my_schema)::regtype) as newtypes FROM unnest(newtypestext) typ -+) ls -+WHERE oid = to_regprocedure(my_schema || '.' || replace(oldproc, 'SCH', my_schema)); - - UPDATE pg_catalog.pg_proc SET -- prorettype = 'gtrgm'::pg_catalog.regtype --WHERE oid = pg_catalog.to_regprocedure('gtrgm_union(internal,internal)'); -+ prorettype = (my_schema || '.gtrgm')::pg_catalog.regtype -+WHERE oid = pg_catalog.to_regprocedure(my_schema || '.gtrgm_union(internal,internal)'); -+ -+PERFORM pg_catalog.set_config('search_path', old_path, true); -+END -+$$; - - ALTER FUNCTION set_limit(float4) PARALLEL UNSAFE; - ALTER FUNCTION show_limit() PARALLEL SAFE; -diff --git a/contrib/seg/seg--1.0--1.1.sql b/contrib/seg/seg--1.0--1.1.sql -index 2dcd4d4..ae6cb2f 100644 ---- a/contrib/seg/seg--1.0--1.1.sql -+++ b/contrib/seg/seg--1.0--1.1.sql -@@ -7,15 +7,30 @@ - -- We use to_regprocedure() so that query doesn't fail if run against 9.6beta1 definitions, - -- wherein the signatures have been updated already. In that case to_regprocedure() will - -- return NULL and no updates will happen. -+DO LANGUAGE plpgsql -+$$ -+DECLARE -+ my_schema pg_catalog.text := pg_catalog.quote_ident(pg_catalog.current_schema()); -+ old_path pg_catalog.text := pg_catalog.current_setting('search_path'); -+BEGIN -+-- for safety, transiently set search_path to just pg_catalog+pg_temp -+PERFORM pg_catalog.set_config('search_path', 'pg_catalog, pg_temp', true); - - UPDATE pg_catalog.pg_proc SET - proargtypes = pg_catalog.array_to_string(newtypes::pg_catalog.oid[], ' ')::pg_catalog.oidvector, - pronargs = pg_catalog.array_length(newtypes, 1) - FROM (VALUES --(NULL::pg_catalog.text, NULL::pg_catalog.regtype[]), -- establish column types --('gseg_consistent(internal,seg,int4,oid,internal)', '{internal,seg,int2,oid,internal}') --) AS update_data (oldproc, newtypes) --WHERE oid = pg_catalog.to_regprocedure(oldproc); -+(NULL::pg_catalog.text, NULL::pg_catalog.text[]), -- establish column types -+('gseg_consistent(internal,SCH.seg,int4,oid,internal)', '{internal,SCH.seg,int2,oid,internal}') -+) AS update_data (oldproc, newtypestext), -+LATERAL ( -+ SELECT array_agg(replace(typ, 'SCH', my_schema)::regtype) as newtypes FROM unnest(newtypestext) typ -+) ls -+WHERE oid = to_regprocedure(my_schema || '.' || replace(oldproc, 'SCH', my_schema)); -+ -+PERFORM pg_catalog.set_config('search_path', old_path, true); -+END -+$$; - - ALTER FUNCTION seg_in(cstring) PARALLEL SAFE; - ALTER FUNCTION seg_out(seg) PARALLEL SAFE; - -diff --git a/doc/src/sgml/earthdistance.sgml b/doc/src/sgml/earthdistance.sgml -index 6dedc4a..a58c5a1 100644 ---- a/doc/src/sgml/earthdistance.sgml -+++ b/doc/src/sgml/earthdistance.sgml -@@ -10,9 +10,8 @@ - - The earthdistance module provides two different approaches to - calculating great circle distances on the surface of the Earth. The one -- described first depends on the cube module (which -- must be installed before earthdistance can be -- installed). The second one is based on the built-in point data type, -+ described first depends on the cube module. -+ The second one is based on the built-in point data type, - using longitude and latitude for the coordinates. - - -@@ -23,6 +22,28 @@ - project.) - - -+ -+ The cube module must be installed -+ before earthdistance can be installed -+ (although you can use the CASCADE option -+ of CREATE EXTENSION to install both in one command). -+ -+ -+ -+ -+ It is strongly recommended that earthdistance -+ and cube be installed in the same schema, and that -+ that schema be one for which CREATE privilege has not been and will not -+ be granted to any untrusted users. -+ Otherwise there are installation-time security hazards -+ if earthdistance's schema contains objects defined -+ by a hostile user. -+ Furthermore, when using earthdistance's functions -+ after installation, the entire search path should contain only trusted -+ schemas. -+ -+ -+ - - Cube-based Earth Distances - -diff --git a/doc/src/sgml/extend.sgml b/doc/src/sgml/extend.sgml -index 962515c..4901fe3 100644 ---- a/doc/src/sgml/extend.sgml -+++ b/doc/src/sgml/extend.sgml -@@ -342,7 +342,7 @@ - - - The extension script may set privileges on objects that are part of the -- extension via GRANT and REVOKE -+ extension, using GRANT and REVOKE - statements. The final set of privileges for each object (if any are set) - will be stored in the - pg_init_privs - -@@ -542,9 +516,38 @@ - - If this parameter is true (which is the default), - only superusers can create the extension or update it to a new -- version. If it is set to false, just the privileges -+ version (but see also trusted, below). -+ If it is set to false, just the privileges - required to execute the commands in the installation or update script - are required. -+ This should normally be set to true if any of the -+ script commands require superuser privileges. (Such commands would -+ fail anyway, but it's more user-friendly to give the error up front.) -+ -+ -+ -+ -+ -+ trusted (boolean) -+ -+ -+ This parameter, if set to true (which is not the -+ default), allows some non-superusers to install an extension that -+ has superuser set to true. -+ Specifically, installation will be permitted for anyone who has -+ CREATE privilege on the current database. -+ When the user executing CREATE EXTENSION is not -+ a superuser but is allowed to install by virtue of this parameter, -+ then the installation or update script is run as the bootstrap -+ superuser, not as the calling user. -+ This parameter is irrelevant if superuser is -+ false. -+ Generally, this should not be set true for extensions that could -+ allow access to otherwise-superuser-only abilities, such as -+ file system access. -+ Also, marking an extension trusted requires significant extra effort -+ to write the extension's installation and update script(s) securely; -+ see . - - - -@@ -686,7 +689,7 @@ - schema; that is, CREATE EXTENSION does the equivalent of - this: - --SET LOCAL search_path TO @extschema@; -+SET LOCAL search_path TO @extschema@, pg_temp; - - This allows the objects created by the script file to go into the target - schema. The script file can change search_path if it wishes, -@@ -706,9 +709,15 @@ SET LOCAL search_path TO @extschema@; - - - If any prerequisite extensions are listed in requires -- in the control file, their target schemas are appended to the initial -- setting of search_path. This allows their objects to be -- visible to the new extension's script file. -+ in the control file, their target schemas are added to the initial -+ setting of search_path, following the new -+ extension's target schema. This allows their objects to be visible to -+ the new extension's script file. -+ -+ -+ -+ For security, pg_temp is automatically appended to -+ the end of search_path in all cases. - - - -@@ -962,6 +971,154 @@ SELECT * FROM pg_extension_update_paths('extension_name'); - - - -+ -+ Security Considerations for Extensions -+ -+ -+ Widely-distributed extensions should assume little about the database -+ they occupy. Therefore, it's appropriate to write functions provided -+ by an extension in a secure style that cannot be compromised by -+ search-path-based attacks. -+ -+ -+ -+ An extension that has the superuser property set to -+ true must also consider security hazards for the actions taken within -+ its installation and update scripts. It is not terribly difficult for -+ a malicious user to create trojan-horse objects that will compromise -+ later execution of a carelessly-written extension script, allowing that -+ user to acquire superuser privileges. -+ -+ -+ -+ If an extension is marked trusted, then its -+ installation schema can be selected by the installing user, who might -+ intentionally use an insecure schema in hopes of gaining superuser -+ privileges. Therefore, a trusted extension is extremely exposed from a -+ security standpoint, and all its script commands must be carefully -+ examined to ensure that no compromise is possible. -+ -+ -+ -+ Advice about writing functions securely is provided in -+ below, and advice -+ about writing installation scripts securely is provided in -+ . -+ -+ -+ -+ Security Considerations for Extension Functions -+ -+ -+ SQL-language and PL-language functions provided by extensions are at -+ risk of search-path-based attacks when they are executed, since -+ parsing of these functions occurs at execution time not creation time. -+ -+ -+ -+ The CREATE -+ FUNCTION reference page contains advice about -+ writing SECURITY DEFINER functions safely. It's -+ good practice to apply those techniques for any function provided by -+ an extension, since the function might be called by a high-privilege -+ user. -+ -+ -+ -+ -+ If you cannot set the search_path to contain only -+ secure schemas, assume that each unqualified name could resolve to an -+ object that a malicious user has defined. Beware of constructs that -+ depend on search_path implicitly; for -+ example, IN -+ and CASE expression WHEN -+ always select an operator using the search path. In their place, use -+ OPERATOR(schema.=) ANY -+ and CASE WHEN expression. -+ -+ -+ -+ A general-purpose extension usually should not assume that it's been -+ installed into a secure schema, which means that even schema-qualified -+ references to its own objects are not entirely risk-free. For -+ example, if the extension has defined a -+ function myschema.myfunc(bigint) then a call such -+ as myschema.myfunc(42) could be captured by a -+ hostile function myschema.myfunc(integer). Be -+ careful that the data types of function and operator parameters exactly -+ match the declared argument types, using explicit casts where necessary. -+ -+ -+ -+ -+ Security Considerations for Extension Scripts -+ -+ -+ An extension installation or update script should be written to guard -+ against search-path-based attacks occurring when the script executes. -+ If an object reference in the script can be made to resolve to some -+ other object than the script author intended, then a compromise might -+ occur immediately, or later when the mis-defined extension object is -+ used. -+ -+ -+ -+ DDL commands such as CREATE FUNCTION -+ and CREATE OPERATOR CLASS are generally secure, -+ but beware of any command having a general-purpose expression as a -+ component. For example, CREATE VIEW needs to be -+ vetted, as does a DEFAULT expression -+ in CREATE FUNCTION. -+ -+ -+ -+ Sometimes an extension script might need to execute general-purpose -+ SQL, for example to make catalog adjustments that aren't possible via -+ DDL. Be careful to execute such commands with a -+ secure search_path; do not -+ trust the path provided by CREATE/ALTER EXTENSION -+ to be secure. Best practice is to temporarily -+ set search_path to 'pg_catalog, -+ pg_temp' and insert references to the extension's -+ installation schema explicitly where needed. (This practice might -+ also be helpful for creating views.) Examples can be found in -+ the contrib modules in -+ the PostgreSQL source code distribution. -+ -+ -+ -+ Cross-extension references are extremely difficult to make fully -+ secure, partially because of uncertainty about which schema the other -+ extension is in. The hazards are reduced if both extensions are -+ installed in the same schema, because then a hostile object cannot be -+ placed ahead of the referenced extension in the installation-time -+ search_path. However, no mechanism currently exists -+ to require that. For now, best practice is to not mark an extension -+ trusted if it depends on another one, unless that other one is always -+ installed in pg_catalog. -+ -+ -+ -+ Do not use CREATE OR REPLACE -+ FUNCTION, except in an update script that must change the -+ definition of a function that is known to be an extension member -+ already. (Likewise for other OR REPLACE options.) -+ Using OR REPLACE unnecessarily not only has a risk -+ of accidentally overwriting someone else's function, but it creates a -+ security hazard since the overwritten function would still be owned by -+ its original owner, who could modify it. -+ -+ -+ -+ - - Extension Example - -@@ -981,18 +1138,18 @@ SELECT * FROM pg_extension_update_paths('extension_name'); - - CREATE TYPE pair AS ( k text, v text ); - --CREATE OR REPLACE FUNCTION pair(text, text) -+CREATE FUNCTION pair(text, text) - RETURNS pair LANGUAGE SQL AS 'SELECT ROW($1, $2)::@extschema@.pair;'; - - CREATE OPERATOR ~> (LEFTARG = text, RIGHTARG = text, PROCEDURE = pair); - - -- "SET search_path" is easy to get right, but qualified names perform better. --CREATE OR REPLACE FUNCTION lower(pair) -+CREATE FUNCTION lower(pair) - RETURNS pair LANGUAGE SQL - AS 'SELECT ROW(lower($1.k), lower($1.v))::@extschema@.pair;' - SET search_path = pg_temp; - --CREATE OR REPLACE FUNCTION pair_concat(pair, pair) -+CREATE FUNCTION pair_concat(pair, pair) - RETURNS pair LANGUAGE SQL - AS 'SELECT ROW($1.k OPERATOR(pg_catalog.||) $2.k, - $1.v OPERATOR(pg_catalog.||) $2.v)::@extschema@.pair;'; -@@ -1007,6 +1164,7 @@ AS 'SELECT ROW($1.k OPERATOR(pg_catalog.||) $2.k, - # pair extension - comment = 'A key/value pair data type' - default_version = '1.0' -+# cannot be relocatable because of use of @extschema@ - relocatable = false - - -diff --git a/doc/src/sgml/hstore.sgml b/doc/src/sgml/hstore.sgml -index db5d440..fee2812 100644 ---- a/doc/src/sgml/hstore.sgml -+++ b/doc/src/sgml/hstore.sgml -@@ -633,6 +633,15 @@ ALTER TABLE tablename ALTER hstorecol TYPE hstore USING hstorecol || ''; - convention). If you use them, hstore values are mapped to - Python dictionaries. - -+ -+ -+ -+ It is strongly recommended that the transform extensions be installed in -+ the same schema as hstore. Otherwise there are -+ installation-time security hazards if a transform extension's schema -+ contains objects defined by a hostile user. -+ -+ - - - -diff --git a/doc/src/sgml/ltree.sgml b/doc/src/sgml/ltree.sgml -index 77599ad..16d6a9b 100644 ---- a/doc/src/sgml/ltree.sgml -+++ b/doc/src/sgml/ltree.sgml -@@ -675,6 +675,15 @@ ltreetest=> SELECT ins_label(path,2,'Space') FROM test WHERE path <@ 'Top. - creating a function, ltree values are mapped to Python lists. - (The reverse is currently not supported, however.) - -+ -+ -+ -+ It is strongly recommended that the transform extensions be installed in -+ the same schema as ltree. Otherwise there are -+ installation-time security hazards if a transform extension's schema -+ contains objects defined by a hostile user. -+ -+ - - - -diff --git a/doc/src/sgml/ref/create_extension.sgml b/doc/src/sgml/ref/create_extension.sgml -index 14e9101..8016c78 100644 ---- a/doc/src/sgml/ref/create_extension.sgml -+++ b/doc/src/sgml/ref/create_extension.sgml -@@ -193,6 +193,33 @@ CREATE EXTENSION [ IF NOT EXISTS ] extension_name - system views. - - -+ -+ -+ Installing an extension as superuser requires trusting that the -+ extension's author wrote the extension installation script in a secure -+ fashion. It is not terribly difficult for a malicious user to create -+ trojan-horse objects that will compromise later execution of a -+ carelessly-written extension script, allowing that user to acquire -+ superuser privileges. However, trojan-horse objects are only hazardous -+ if they are in the search_path during script -+ execution, meaning that they are in the extension's installation target -+ schema or in the schema of some extension it depends on. Therefore, a -+ good rule of thumb when dealing with extensions whose scripts have not -+ been carefully vetted is to install them only into schemas for which -+ CREATE privilege has not been and will not be granted to any untrusted -+ users. Likewise for any extensions they depend on. -+ -+ -+ -+ The extensions supplied with PostgreSQL are -+ believed to be secure against installation-time attacks of this sort, -+ except for a few that depend on other extensions. As stated in the -+ documentation for those extensions, they should be installed into secure -+ schemas, or installed into the same schemas as the extensions they -+ depend on, or both. -+ -+ -+ - - For information about writing new extensions, see - . -@@ -204,8 +231,13 @@ CREATE EXTENSION [ IF NOT EXISTS ] extension_name - - - Install the hstore extension into the -- current database: -+ current database, placing its objects in schema addons: -+ -+CREATE EXTENSION hstore SCHEMA addons; -+ -+ Another way to accomplish the same thing: - -+SET search_path = addons; - CREATE EXTENSION hstore; - - -diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c -index e4340ee..068c463 100644 ---- a/src/backend/commands/extension.c -+++ b/src/backend/commands/extension.c -@@ -838,9 +838,21 @@ execute_extension_script(Oid extensionOid, ExtensionControlFile *control, - GUC_ACTION_SAVE, true, 0, false); - - /* -- * Set up the search path to contain the target schema, then the schemas -- * of any prerequisite extensions, and nothing else. In particular this -- * makes the target schema be the default creation target namespace. -+ * Similarly disable check_function_bodies, to ensure that SQL functions -+ * won't be parsed during creation. -+ */ -+ if (check_function_bodies) -+ (void) set_config_option("check_function_bodies", "off", -+ PGC_USERSET, PGC_S_SESSION, -+ GUC_ACTION_SAVE, true, 0, false); -+ -+ /* -+ * Set up the search path to have the target schema first, making it be -+ * the default creation target namespace. Then add the schemas of any -+ * prerequisite extensions, unless they are in pg_catalog which would be -+ * searched anyway. (Listing pg_catalog explicitly in a non-first -+ * position would be bad for security.) Finally add pg_temp to ensure -+ * that temp objects can't take precedence over others. - * - * Note: it might look tempting to use PushOverrideSearchPath for this, - * but we cannot do that. We have to actually set the search_path GUC in -@@ -854,9 +866,10 @@ execute_extension_script(Oid extensionOid, ExtensionControlFile *control, - Oid reqschema = lfirst_oid(lc); - char *reqname = get_namespace_name(reqschema); - -- if (reqname) -+ if (reqname && strcmp(reqname, "pg_catalog") != 0) - appendStringInfo(&pathbuf, ", %s", quote_identifier(reqname)); - } -+ appendStringInfoString(&pathbuf, ", pg_temp"); - - (void) set_config_option("search_path", pathbuf.data, - PGC_USERSET, PGC_S_SESSION, -diff --git a/src/backend/commands/operatorcmds.c b/src/backend/commands/operatorcmds.c -index 6674b41..b637cd4 100644 ---- a/src/backend/commands/operatorcmds.c -+++ b/src/backend/commands/operatorcmds.c -@@ -297,6 +297,7 @@ ValidateJoinEstimator(List *joinName) - { - Oid typeId[5]; - Oid joinOid; -+ Oid joinOid2; - AclResult aclresult; - - typeId[0] = INTERNALOID; /* PlannerInfo */ -@@ -307,15 +308,26 @@ ValidateJoinEstimator(List *joinName) - - /* - * As of Postgres 8.4, the preferred signature for join estimators has 5 -- * arguments, but we still allow the old 4-argument form. Try the -- * preferred form first. -+ * arguments, but we still allow the old 4-argument form. Whine about -+ * ambiguity if both forms exist. - */ - joinOid = LookupFuncName(joinName, 5, typeId, true); -- if (!OidIsValid(joinOid)) -- joinOid = LookupFuncName(joinName, 4, typeId, true); -- /* If not found, reference the 5-argument signature in error msg */ -- if (!OidIsValid(joinOid)) -- joinOid = LookupFuncName(joinName, 5, typeId, false); -+ joinOid2 = LookupFuncName(joinName, 4, typeId, true); -+ if (OidIsValid(joinOid)) -+ { -+ if (OidIsValid(joinOid2)) -+ ereport(ERROR, -+ (errcode(ERRCODE_AMBIGUOUS_FUNCTION), -+ errmsg("join estimator function %s has multiple matches", -+ NameListToString(joinName)))); -+ } -+ else -+ { -+ joinOid = joinOid2; -+ /* If not found, reference the 5-argument signature in error msg */ -+ if (!OidIsValid(joinOid)) -+ joinOid = LookupFuncName(joinName, 5, typeId, false); -+ } - - /* estimators must return float8 */ - if (get_func_rettype(joinOid) != FLOAT8OID) - -diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c -index 8e5134b..6172d47 100644 ---- a/src/backend/commands/typecmds.c -+++ b/src/backend/commands/typecmds.c -@@ -1659,7 +1659,11 @@ static Oid - findTypeInputFunction(List *procname, Oid typeOid) - { - Oid argList[3]; -+ int nmatches = 0; - Oid procOid; -+ Oid procOid2; -+ Oid procOid3; -+ Oid procOid4; - - /* - * Input functions can take a single argument of type CSTRING, or three -@@ -1670,29 +1674,42 @@ findTypeInputFunction(List *procname, Oid typeOid) - */ - argList[0] = CSTRINGOID; - -- procOid = LookupFuncName(procname, 1, argList, true); -- if (OidIsValid(procOid)) -- return procOid; -- - argList[1] = OIDOID; - argList[2] = INT4OID; - -- procOid = LookupFuncName(procname, 3, argList, true); -+ procOid = LookupFuncName(procname, 1, argList, true); - if (OidIsValid(procOid)) -- return procOid; -+ nmatches++; -+ procOid2 = LookupFuncName(procname, 3, argList, true); -+ if (OidIsValid(procOid2)) -+ nmatches++; - - /* No luck, try it with OPAQUE */ - argList[0] = OPAQUEOID; - -- procOid = LookupFuncName(procname, 1, argList, true); -+ procOid3 = LookupFuncName(procname, 1, argList, true); -+ if (OidIsValid(procOid3)) -+ nmatches++; -+ procOid4 = LookupFuncName(procname, 3, argList, true); -+ if (OidIsValid(procOid4)) -+ nmatches++; - -- if (!OidIsValid(procOid)) -- { -- argList[1] = OIDOID; -- argList[2] = INT4OID; -+ if (nmatches > 1) -+ ereport(ERROR, -+ (errcode(ERRCODE_AMBIGUOUS_FUNCTION), -+ errmsg("type input function %s has multiple matches", -+ NameListToString(procname)))); - -- procOid = LookupFuncName(procname, 3, argList, true); -- } -+ if (OidIsValid(procOid)) -+ return procOid; -+ if (OidIsValid(procOid2)) -+ return procOid2; -+ -+ /* Cases with OPAQUE need adjustment */ -+ if (OidIsValid(procOid3)) -+ procOid = procOid3; -+ else -+ procOid = procOid4; - - if (OidIsValid(procOid)) - { -@@ -1778,6 +1795,7 @@ findTypeReceiveFunction(List *procname, Oid typeOid) - { - Oid argList[3]; - Oid procOid; -+ Oid procOid2; - - /* - * Receive functions can take a single argument of type INTERNAL, or three -@@ -1785,17 +1803,24 @@ findTypeReceiveFunction(List *procname, Oid typeOid) - */ - argList[0] = INTERNALOID; - -- procOid = LookupFuncName(procname, 1, argList, true); -- if (OidIsValid(procOid)) -- return procOid; -- - argList[1] = OIDOID; - argList[2] = INT4OID; - -- procOid = LookupFuncName(procname, 3, argList, true); -+ procOid = LookupFuncName(procname, 1, argList, true); -+ procOid2 = LookupFuncName(procname, 3, argList, true); - if (OidIsValid(procOid)) -+ { -+ if (OidIsValid(procOid2)) -+ ereport(ERROR, -+ (errcode(ERRCODE_AMBIGUOUS_FUNCTION), -+ errmsg("type receive function %s has multiple matches", -+ NameListToString(procname)))); - return procOid; -+ } -+ else if (OidIsValid(procOid2)) -+ return procOid2; - -+ /* If not found, reference the 1-argument signature in error msg */ - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_FUNCTION), - errmsg("function %s does not exist", --- -2.23.0 - diff --git a/CVE-2020-25694-1.patch b/CVE-2020-25694-1.patch deleted file mode 100644 index 36d5d8fa7b46345bc48f55e62c49fe3ead9e25ec..0000000000000000000000000000000000000000 --- a/CVE-2020-25694-1.patch +++ /dev/null @@ -1,492 +0,0 @@ -From a062fb822382398c7282810029016400feecf644 Mon Sep 17 00:00:00 2001 -From: Tom Lane -Date: Wed, 21 Oct 2020 16:18:41 -0400 -Subject: [PATCH] Fix connection string handling in psql's \connect command. - -psql's \connect claims to be able to re-use previous connection -parameters, but in fact it only re-uses the database name, user name, -host name (and possibly hostaddr, depending on version), and port. -This is problematic for assorted use cases. Notably, pg_dump[all] -emits "\connect databasename" commands which we would like to have -re-use all other parameters. If such a script is loaded in a psql run -that initially had "-d connstring" with some non-default parameters, -those other parameters would be lost, potentially causing connection -failure. (Thus, this is the same kind of bug addressed in commits -a45bc8a4f and 8e5793ab6, although the details are much different.) - -To fix, redesign do_connect() so that it pulls out all properties -of the old PGconn using PQconninfo(), and then replaces individual -properties in that array. In the case where we don't wish to re-use -anything, get libpq's default settings using PQconndefaults() and -replace entries in that, so that we don't need different code paths -for the two cases. - -This does result in an additional behavioral change for cases where -the original connection parameters allowed multiple hosts, say -"psql -h host1,host2", and the \connect request allows re-use of the -host setting. Because the previous coding relied on PQhost(), it -would only permit reconnection to the same host originally selected. -Although one can think of scenarios where that's a good thing, there -are others where it is not. Moreover, that behavior doesn't seem to -meet the principle of least surprise, nor was it documented; nor is -it even clear it was intended, since that coding long pre-dates the -addition of multi-host support to libpq. Hence, this patch is content -to drop it and re-use the host list as given. - -Per Peter Eisentraut's comments on bug #16604. Back-patch to all -supported branches. - -Discussion: https://postgr.es/m/16604-933f4b8791227b15@postgresql.org ---- - doc/src/sgml/ref/psql-ref.sgml | 44 ++++-- - src/bin/psql/command.c | 272 ++++++++++++++++++++++++--------- - 2 files changed, 230 insertions(+), 86 deletions(-) - -diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml -index c8388513b8..7fda949f3b 100644 ---- a/doc/src/sgml/ref/psql-ref.sgml -+++ b/doc/src/sgml/ref/psql-ref.sgml -@@ -875,21 +875,17 @@ testdb=> - \c or \connect [ -reuse-previous=on|off ] [ dbname [ username ] [ host ] [ port ] | conninfo ] - - -- Establishes a new connection to a PostgreSQL -+ Establishes a new connection to a PostgreSQL - server. The connection parameters to use can be specified either -- using a positional syntax, or using conninfo connection -- strings as detailed in . -+ using a positional syntax (one or more of database name, user, -+ host, and port), or using a conninfo -+ connection string as detailed in -+ . If no arguments are given, a -+ new connection is made using the same parameters as before. - - - -- Where the command omits database name, user, host, or port, the new -- connection can reuse values from the previous connection. By default, -- values from the previous connection are reused except when processing -- a conninfo string. Passing a first argument -- of -reuse-previous=on -- or -reuse-previous=off overrides that default. -- When the command neither specifies nor reuses a particular parameter, -- the libpq default is used. Specifying any -+ Specifying any - of dbname, - username, - host or -@@ -897,12 +893,31 @@ testdb=> - as - is equivalent to omitting that parameter. - - -+ -+ The new connection can re-use connection parameters from the previous -+ connection; not only database name, user, host, and port, but other -+ settings such as sslmode. By default, -+ parameters are re-used in the positional syntax, but not when -+ a conninfo string is given. Passing a -+ first argument of -reuse-previous=on -+ or -reuse-previous=off overrides that default. If -+ parameters are re-used, then any parameter not explicitly specified as -+ a positional parameter or in the conninfo -+ string is taken from the existing connection's parameters. An -+ exception is that if the host setting -+ is changed from its previous value using the positional syntax, -+ any hostaddr setting present in the -+ existing connection's parameters is dropped. -+ When the command neither specifies nor reuses a particular parameter, -+ the libpq default is used. -+ -+ - - If the new connection is successfully made, the previous - connection is closed. -- If the connection attempt failed (wrong user name, access -- denied, etc.), the previous connection will only be kept if -- psql is in interactive mode. When -+ If the connection attempt fails (wrong user name, access -+ denied, etc.), the previous connection will be kept if -+ psql is in interactive mode. But when - executing a non-interactive script, processing will - immediately stop with an error. This distinction was chosen as - a user convenience against typos on the one hand, and a safety -@@ -917,6 +932,7 @@ testdb=> - => \c mydb myuser host.dom 6432 - => \c service=foo - => \c "host=localhost port=5432 dbname=mydb connect_timeout=10 sslmode=disable" -+=> \c -reuse-previous=on sslmode=require -- changes only sslmode - => \c postgresql://tom@localhost/mydb?application_name=myapp - - -diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c -index a30a5f8ea0..91f7f0adc3 100644 ---- a/src/bin/psql/command.c -+++ b/src/bin/psql/command.c -@@ -2979,12 +2979,15 @@ do_connect(enum trivalue reuse_previous_specification, - char *dbname, char *user, char *host, char *port) - { - PGconn *o_conn = pset.db, -- *n_conn; -+ *n_conn = NULL; -+ PQconninfoOption *cinfo; -+ int nconnopts = 0; -+ bool same_host = false; - char *password = NULL; -- bool keep_password; -+ bool success = true; -+ bool keep_password = true; - bool has_connection_string; - bool reuse_previous; -- PQExpBufferData connstr; - - if (!o_conn && (!dbname || !user || !host || !port)) - { -@@ -3012,6 +3015,11 @@ do_connect(enum trivalue reuse_previous_specification, - reuse_previous = !has_connection_string; - break; - } -+ -+ /* If the old connection does not exist, there is nothing to reuse. */ -+ if (!o_conn) -+ reuse_previous = false; -+ - /* Silently ignore arguments subsequent to a connection string. */ - if (has_connection_string) - { -@@ -3020,41 +3028,126 @@ do_connect(enum trivalue reuse_previous_specification, - port = NULL; - } - -- /* grab missing values from the old connection */ -- if (!user && reuse_previous) -- user = PQuser(o_conn); -- if (!host && reuse_previous) -- host = PQhost(o_conn); -- if (!port && reuse_previous) -- port = PQport(o_conn); -- - /* -- * Any change in the parameters read above makes us discard the password. -- * We also discard it if we're to use a conninfo rather than the -- * positional syntax. -+ * If we intend to re-use connection parameters, collect them out of the -+ * old connection, then replace individual values as necessary. Otherwise, -+ * obtain a PQconninfoOption array containing libpq's defaults, and modify -+ * that. Note this function assumes that PQconninfo, PQconndefaults, and -+ * PQconninfoParse will all produce arrays containing the same options in -+ * the same order. - */ -- if (has_connection_string) -- keep_password = false; -+ if (reuse_previous) -+ cinfo = PQconninfo(o_conn); - else -- keep_password = -- (user && PQuser(o_conn) && strcmp(user, PQuser(o_conn)) == 0) && -- (host && PQhost(o_conn) && strcmp(host, PQhost(o_conn)) == 0) && -- (port && PQport(o_conn) && strcmp(port, PQport(o_conn)) == 0); -+ cinfo = PQconndefaults(); - -- /* -- * Grab missing dbname from old connection. No password discard if this -- * changes: passwords aren't (usually) database-specific. -- */ -- if (!dbname && reuse_previous) -+ if (cinfo) - { -- initPQExpBuffer(&connstr); -- appendPQExpBuffer(&connstr, "dbname="); -- appendConnStrVal(&connstr, PQdb(o_conn)); -- dbname = connstr.data; -- /* has_connection_string=true would be a dead store */ -+ if (has_connection_string) -+ { -+ /* Parse the connstring and insert values into cinfo */ -+ PQconninfoOption *replcinfo; -+ char *errmsg; -+ -+ replcinfo = PQconninfoParse(dbname, &errmsg); -+ if (replcinfo) -+ { -+ PQconninfoOption *ci; -+ PQconninfoOption *replci; -+ -+ for (ci = cinfo, replci = replcinfo; -+ ci->keyword && replci->keyword; -+ ci++, replci++) -+ { -+ Assert(strcmp(ci->keyword, replci->keyword) == 0); -+ /* Insert value from connstring if one was provided */ -+ if (replci->val) -+ { -+ /* -+ * We know that both val strings were allocated by -+ * libpq, so the least messy way to avoid memory leaks -+ * is to swap them. -+ */ -+ char *swap = replci->val; -+ -+ replci->val = ci->val; -+ ci->val = swap; -+ } -+ } -+ Assert(ci->keyword == NULL && replci->keyword == NULL); -+ -+ /* While here, determine how many option slots there are */ -+ nconnopts = ci - cinfo; -+ -+ PQconninfoFree(replcinfo); -+ -+ /* We never re-use a password with a conninfo string. */ -+ keep_password = false; -+ -+ /* Don't let code below try to inject dbname into params. */ -+ dbname = NULL; -+ } -+ else -+ { -+ /* PQconninfoParse failed */ -+ if (errmsg) -+ { -+ psql_error("%s", errmsg); -+ PQfreemem(errmsg); -+ } -+ else -+ psql_error("out of memory\n"); -+ success = false; -+ } -+ } -+ else -+ { -+ /* -+ * If dbname isn't a connection string, then we'll inject it and -+ * the other parameters into the keyword array below. (We can't -+ * easily insert them into the cinfo array because of memory -+ * management issues: PQconninfoFree would misbehave on Windows.) -+ * However, to avoid dependencies on the order in which parameters -+ * appear in the array, make a preliminary scan to set -+ * keep_password and same_host correctly. -+ * -+ * While any change in user, host, or port causes us to ignore the -+ * old connection's password, we don't force that for dbname, -+ * since passwords aren't database-specific. -+ */ -+ PQconninfoOption *ci; -+ -+ for (ci = cinfo; ci->keyword; ci++) -+ { -+ if (user && strcmp(ci->keyword, "user") == 0) -+ { -+ if (!(ci->val && strcmp(user, ci->val) == 0)) -+ keep_password = false; -+ } -+ else if (host && strcmp(ci->keyword, "host") == 0) -+ { -+ if (ci->val && strcmp(host, ci->val) == 0) -+ same_host = true; -+ else -+ keep_password = false; -+ } -+ else if (port && strcmp(ci->keyword, "port") == 0) -+ { -+ if (!(ci->val && strcmp(port, ci->val) == 0)) -+ keep_password = false; -+ } -+ } -+ -+ /* While here, determine how many option slots there are */ -+ nconnopts = ci - cinfo; -+ } - } - else -- connstr.data = NULL; -+ { -+ /* We failed to create the cinfo structure */ -+ psql_error("out of memory\n"); -+ success = false; -+ } - - /* - * If the user asked to be prompted for a password, ask for one now. If -@@ -3066,7 +3159,7 @@ do_connect(enum trivalue reuse_previous_specification, - * the postmaster's log. But libpq offers no API that would let us obtain - * a password and then continue with the first connection attempt. - */ -- if (pset.getPassword == TRI_YES) -+ if (pset.getPassword == TRI_YES && success) - { - password = prompt_for_password(user); - } -@@ -3079,52 +3172,60 @@ do_connect(enum trivalue reuse_previous_specification, - password = NULL; - } - -- while (true) -+ /* Loop till we have a connection or fail, which we might've already */ -+ while (success) - { --#define PARAMS_ARRAY_SIZE 8 -- const char **keywords = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords)); -- const char **values = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*values)); -- int paramnum = -1; -- -- keywords[++paramnum] = "host"; -- values[paramnum] = host; -- keywords[++paramnum] = "port"; -- values[paramnum] = port; -- keywords[++paramnum] = "user"; -- values[paramnum] = user; -+ const char **keywords = pg_malloc((nconnopts + 1) * sizeof(*keywords)); -+ const char **values = pg_malloc((nconnopts + 1) * sizeof(*values)); -+ int paramnum = 0; -+ PQconninfoOption *ci; - - /* -- * Position in the array matters when the dbname is a connection -- * string, because settings in a connection string override earlier -- * array entries only. Thus, user= in the connection string always -- * takes effect, but client_encoding= often will not. -+ * Copy non-default settings into the PQconnectdbParams parameter -+ * arrays; but override any values specified old-style, as well as the -+ * password and a couple of fields we want to set forcibly. - * -- * If you change this code, also change the initial-connection code in -+ * If you change this code, see also the initial-connection code in - * main(). For no good reason, a connection string password= takes - * precedence in main() but not here. - */ -- keywords[++paramnum] = "dbname"; -- values[paramnum] = dbname; -- keywords[++paramnum] = "password"; -- values[paramnum] = password; -- keywords[++paramnum] = "fallback_application_name"; -- values[paramnum] = pset.progname; -- keywords[++paramnum] = "client_encoding"; -- values[paramnum] = (pset.notty || getenv("PGCLIENTENCODING")) ? NULL : "auto"; -- -+ for (ci = cinfo; ci->keyword; ci++) -+ { -+ keywords[paramnum] = ci->keyword; -+ -+ if (dbname && strcmp(ci->keyword, "dbname") == 0) -+ values[paramnum++] = dbname; -+ else if (user && strcmp(ci->keyword, "user") == 0) -+ values[paramnum++] = user; -+ else if (host && strcmp(ci->keyword, "host") == 0) -+ values[paramnum++] = host; -+ else if (host && !same_host && strcmp(ci->keyword, "hostaddr") == 0) -+ { -+ /* If we're changing the host value, drop any old hostaddr */ -+ values[paramnum++] = NULL; -+ } -+ else if (port && strcmp(ci->keyword, "port") == 0) -+ values[paramnum++] = port; -+ else if (strcmp(ci->keyword, "password") == 0) -+ values[paramnum++] = password; -+ else if (strcmp(ci->keyword, "fallback_application_name") == 0) -+ values[paramnum++] = pset.progname; -+ else if (strcmp(ci->keyword, "client_encoding") == 0) -+ values[paramnum++] = (pset.notty || getenv("PGCLIENTENCODING")) ? NULL : "auto"; -+ else if (ci->val) -+ values[paramnum++] = ci->val; -+ /* else, don't bother making libpq parse this keyword */ -+ } - /* add array terminator */ -- keywords[++paramnum] = NULL; -+ keywords[paramnum] = NULL; - values[paramnum] = NULL; - -- n_conn = PQconnectdbParams(keywords, values, true); -+ /* Note we do not want libpq to re-expand the dbname parameter */ -+ n_conn = PQconnectdbParams(keywords, values, false); - - pg_free(keywords); - pg_free(values); - -- /* We can immediately discard the password -- no longer needed */ -- if (password) -- pg_free(password); -- - if (PQstatus(n_conn) == CONNECTION_OK) - break; - -@@ -3134,11 +3235,34 @@ do_connect(enum trivalue reuse_previous_specification, - */ - if (!password && PQconnectionNeedsPassword(n_conn) && pset.getPassword != TRI_NO) - { -+ /* -+ * Prompt for password using the username we actually connected -+ * with --- it might've come out of "dbname" rather than "user". -+ */ -+ password = prompt_for_password(PQuser(n_conn)); - PQfinish(n_conn); -- password = prompt_for_password(user); -+ n_conn = NULL; - continue; - } - -+ /* -+ * We'll report the error below ... unless n_conn is NULL, indicating -+ * that libpq didn't have enough memory to make a PGconn. -+ */ -+ if (n_conn == NULL) -+ psql_error("out of memory\n"); -+ -+ success = false; -+ } /* end retry loop */ -+ -+ /* Release locally allocated data, whether we succeeded or not */ -+ if (password) -+ pg_free(password); -+ if (cinfo) -+ PQconninfoFree(cinfo); -+ -+ if (!success) -+ { - /* - * Failed to connect to the database. In interactive mode, keep the - * previous connection to the DB; in scripting mode, close our -@@ -3146,7 +3270,11 @@ do_connect(enum trivalue reuse_previous_specification, - */ - if (pset.cur_cmd_interactive) - { -- psql_error("%s", PQerrorMessage(n_conn)); -+ if (n_conn) -+ { -+ psql_error("%s", PQerrorMessage(n_conn)); -+ PQfinish(n_conn); -+ } - - /* pset.db is left unmodified */ - if (o_conn) -@@ -3154,7 +3282,12 @@ do_connect(enum trivalue reuse_previous_specification, - } - else - { -- psql_error("\\connect: %s", PQerrorMessage(n_conn)); -+ if (n_conn) -+ { -+ psql_error("\\connect: %s", PQerrorMessage(n_conn)); -+ PQfinish(n_conn); -+ } -+ - if (o_conn) - { - PQfinish(o_conn); -@@ -3162,13 +3295,8 @@ do_connect(enum trivalue reuse_previous_specification, - } - } - -- PQfinish(n_conn); -- if (connstr.data) -- termPQExpBuffer(&connstr); - return false; - } -- if (connstr.data) -- termPQExpBuffer(&connstr); - - /* - * Replace the old connection with the new one, and update --- -2.23.0 - diff --git a/CVE-2020-25694-2.patch b/CVE-2020-25694-2.patch deleted file mode 100644 index 76c621aa182baf6250c0b4861868a88546186e47..0000000000000000000000000000000000000000 --- a/CVE-2020-25694-2.patch +++ /dev/null @@ -1,1076 +0,0 @@ -From 27d64ec8da4c0813c5cb0956e74b332d1db67bc7 Mon Sep 17 00:00:00 2001 -From: Tom Lane -Date: Mon, 19 Oct 2020 19:03:47 -0400 -Subject: [PATCH 2/2] Fix connection string handling in src/bin/scripts/ - programs. - -When told to process all databases, clusterdb, reindexdb, and vacuumdb -would reconnect by replacing their --maintenance-db parameter with the -name of the target database. If that parameter is a connstring (which -has been allowed for a long time, though we failed to document that -before this patch), we'd lose any other options it might specify, for -example SSL or GSS parameters, possibly resulting in failure to connect. -Thus, this is the same bug as commit a45bc8a4f fixed in pg_dump and -pg_restore. We can fix it in the same way, by using libpq's rules for -handling multiple "dbname" parameters to add the target database name -separately. I chose to apply the same refactoring approach as in that -patch, with a struct to handle the command line parameters that need to -be passed through to connectDatabase. (Maybe someday we can unify the -very similar functions here and in pg_dump/pg_restore.) - -Per Peter Eisentraut's comments on bug #16604. Back-patch to all -supported branches. - -Discussion: https://postgr.es/m/16604-933f4b8791227b15@postgresql.org ---- - doc/src/sgml/ref/clusterdb.sgml | 20 +++++--- - doc/src/sgml/ref/createdb.sgml | 3 ++ - doc/src/sgml/ref/dropdb.sgml | 3 ++ - doc/src/sgml/ref/reindexdb.sgml | 20 +++++--- - doc/src/sgml/ref/vacuumdb.sgml | 20 +++++--- - src/bin/scripts/clusterdb.c | 67 +++++++++++-------------- - src/bin/scripts/common.c | 89 ++++++++++++++++++++------------- - src/bin/scripts/common.h | 26 +++++++--- - src/bin/scripts/createdb.c | 11 +++- - src/bin/scripts/createuser.c | 11 +++- - src/bin/scripts/dropdb.c | 12 +++-- - src/bin/scripts/dropuser.c | 13 +++-- - src/bin/scripts/reindexdb.c | 85 +++++++++++++++---------------- - src/bin/scripts/vacuumdb.c | 70 +++++++++++--------------- - 14 files changed, 254 insertions(+), 196 deletions(-) - -diff --git a/doc/src/sgml/ref/clusterdb.sgml b/doc/src/sgml/ref/clusterdb.sgml -index 67582fd6e6..e3e2c0cff7 100644 ---- a/doc/src/sgml/ref/clusterdb.sgml -+++ b/doc/src/sgml/ref/clusterdb.sgml -@@ -90,9 +90,9 @@ PostgreSQL documentation - - - -- Specifies the name of the database to be clustered. -- If this is not specified and (or -- ) is not used, the database name is read -+ Specifies the name of the database to be clustered, -+ when / is not used. -+ If this is not specified, the database name is read - from the environment variable PGDATABASE. If - that is not set, the user name specified for the connection is - used. -@@ -246,10 +246,16 @@ PostgreSQL documentation - - - -- Specifies the name of the database to connect to discover what other -- databases should be clustered. If not specified, the -- postgres database will be used, -- and if that does not exist, template1 will be used. -+ Specifies the name of the database to connect to to discover which -+ databases should be clustered, -+ when / is used. -+ If not specified, the postgres database will be used, -+ or if that does not exist, template1 will be used. -+ This can be a connection -+ string. If so, connection string parameters will override any -+ conflicting command line options. Also, connection string parameters -+ other than the database name itself will be re-used when connecting -+ to other databases. - - - -diff --git a/doc/src/sgml/ref/createdb.sgml b/doc/src/sgml/ref/createdb.sgml -index 9fc4c16a81..7bb46a0fb2 100644 ---- a/doc/src/sgml/ref/createdb.sgml -+++ b/doc/src/sgml/ref/createdb.sgml -@@ -286,6 +286,9 @@ PostgreSQL documentation - database will be used; if that does not exist (or if it is the name - of the new database being created), template1 will - be used. -+ This can be a connection -+ string. If so, connection string parameters will override any -+ conflicting command line options. - - - -diff --git a/doc/src/sgml/ref/dropdb.sgml b/doc/src/sgml/ref/dropdb.sgml -index 16c49e7928..0d7170d665 100644 ---- a/doc/src/sgml/ref/dropdb.sgml -+++ b/doc/src/sgml/ref/dropdb.sgml -@@ -205,6 +205,9 @@ PostgreSQL documentation - target database. If not specified, the postgres - database will be used; if that does not exist (or is the database - being dropped), template1 will be used. -+ This can be a connection -+ string. If so, connection string parameters will override any -+ conflicting command line options. - - - -diff --git a/doc/src/sgml/ref/reindexdb.sgml b/doc/src/sgml/ref/reindexdb.sgml -index e4721d8113..202e45e6ae 100644 ---- a/doc/src/sgml/ref/reindexdb.sgml -+++ b/doc/src/sgml/ref/reindexdb.sgml -@@ -123,9 +123,9 @@ PostgreSQL documentation - - - -- Specifies the name of the database to be reindexed. -- If this is not specified and (or -- ) is not used, the database name is read -+ Specifies the name of the database to be reindexed, -+ when / is not used. -+ If this is not specified, the database name is read - from the environment variable PGDATABASE. If - that is not set, the user name specified for the connection is - used. -@@ -314,10 +314,16 @@ PostgreSQL documentation - - - -- Specifies the name of the database to connect to discover what other -- databases should be reindexed. If not specified, the -- postgres database will be used, -- and if that does not exist, template1 will be used. -+ Specifies the name of the database to connect to to discover which -+ databases should be reindexed, -+ when / is used. -+ If not specified, the postgres database will be used, -+ or if that does not exist, template1 will be used. -+ This can be a connection -+ string. If so, connection string parameters will override any -+ conflicting command line options. Also, connection string parameters -+ other than the database name itself will be re-used when connecting -+ to other databases. - - - -diff --git a/doc/src/sgml/ref/vacuumdb.sgml b/doc/src/sgml/ref/vacuumdb.sgml -index 4f6fa0d708..64a9f2dba3 100644 ---- a/doc/src/sgml/ref/vacuumdb.sgml -+++ b/doc/src/sgml/ref/vacuumdb.sgml -@@ -92,9 +92,9 @@ PostgreSQL documentation - - - -- Specifies the name of the database to be cleaned or analyzed. -- If this is not specified and (or -- ) is not used, the database name is read -+ Specifies the name of the database to be cleaned or analyzed, -+ when / is not used. -+ If this is not specified, the database name is read - from the environment variable PGDATABASE. If - that is not set, the user name specified for the connection is - used. -@@ -339,10 +339,16 @@ PostgreSQL documentation - - - -- Specifies the name of the database to connect to discover what other -- databases should be vacuumed. If not specified, the -- postgres database will be used, -- and if that does not exist, template1 will be used. -+ Specifies the name of the database to connect to to discover which -+ databases should be vacuumed, -+ when / is used. -+ If not specified, the postgres database will be used, -+ or if that does not exist, template1 will be used. -+ This can be a connection -+ string. If so, connection string parameters will override any -+ conflicting command line options. Also, connection string parameters -+ other than the database name itself will be re-used when connecting -+ to other databases. - - - -diff --git a/src/bin/scripts/clusterdb.c b/src/bin/scripts/clusterdb.c -index c48b0cb08f..e53cc92405 100644 ---- a/src/bin/scripts/clusterdb.c -+++ b/src/bin/scripts/clusterdb.c -@@ -15,15 +15,10 @@ - #include "fe_utils/string_utils.h" - - --static void cluster_one_database(const char *dbname, bool verbose, const char *table, -- const char *host, const char *port, -- const char *username, enum trivalue prompt_password, -- const char *progname, bool echo); --static void cluster_all_databases(bool verbose, const char *maintenance_db, -- const char *host, const char *port, -- const char *username, enum trivalue prompt_password, -- const char *progname, bool echo, bool quiet); -- -+static void cluster_one_database(const ConnParams *cparams, const char *table, -+ const char *progname, bool verbose, bool echo); -+static void cluster_all_databases(ConnParams *cparams, const char *progname, -+ bool verbose, bool echo, bool quiet); - static void help(const char *progname); - - -@@ -56,6 +51,7 @@ main(int argc, char *argv[]) - char *port = NULL; - char *username = NULL; - enum trivalue prompt_password = TRI_DEFAULT; -+ ConnParams cparams; - bool echo = false; - bool quiet = false; - bool alldb = false; -@@ -131,6 +127,13 @@ main(int argc, char *argv[]) - exit(1); - } - -+ /* fill cparams except for dbname, which is set below */ -+ cparams.pghost = host; -+ cparams.pgport = port; -+ cparams.pguser = username; -+ cparams.prompt_password = prompt_password; -+ cparams.override_dbname = NULL; -+ - setup_cancel_handler(); - - if (alldb) -@@ -149,8 +152,9 @@ main(int argc, char *argv[]) - exit(1); - } - -- cluster_all_databases(verbose, maintenance_db, host, port, username, prompt_password, -- progname, echo, quiet); -+ cparams.dbname = maintenance_db; -+ -+ cluster_all_databases(&cparams, progname, verbose, echo, quiet); - } - else - { -@@ -164,21 +168,21 @@ main(int argc, char *argv[]) - dbname = get_user_name_or_exit(progname); - } - -+ cparams.dbname = dbname; -+ - if (tables.head != NULL) - { - SimpleStringListCell *cell; - - for (cell = tables.head; cell; cell = cell->next) - { -- cluster_one_database(dbname, verbose, cell->val, -- host, port, username, prompt_password, -- progname, echo); -+ cluster_one_database(&cparams, cell->val, -+ progname, verbose, echo); - } - } - else -- cluster_one_database(dbname, verbose, NULL, -- host, port, username, prompt_password, -- progname, echo); -+ cluster_one_database(&cparams, NULL, -+ progname, verbose, echo); - } - - exit(0); -@@ -186,17 +190,14 @@ main(int argc, char *argv[]) - - - static void --cluster_one_database(const char *dbname, bool verbose, const char *table, -- const char *host, const char *port, -- const char *username, enum trivalue prompt_password, -- const char *progname, bool echo) -+cluster_one_database(const ConnParams *cparams, const char *table, -+ const char *progname, bool verbose, bool echo) - { - PQExpBufferData sql; - - PGconn *conn; - -- conn = connectDatabase(dbname, host, port, username, prompt_password, -- progname, echo, false, false); -+ conn = connectDatabase(cparams, progname, echo, false, false); - - initPQExpBuffer(&sql); - -@@ -227,22 +228,17 @@ cluster_one_database(const char *dbname, bool verbose, const char *table, - - - static void --cluster_all_databases(bool verbose, const char *maintenance_db, -- const char *host, const char *port, -- const char *username, enum trivalue prompt_password, -- const char *progname, bool echo, bool quiet) -+cluster_all_databases(ConnParams *cparams, const char *progname, -+ bool verbose, bool echo, bool quiet) - { - PGconn *conn; - PGresult *result; -- PQExpBufferData connstr; - int i; - -- conn = connectMaintenanceDatabase(maintenance_db, host, port, username, -- prompt_password, progname, echo); -+ conn = connectMaintenanceDatabase(cparams, progname, echo); - result = executeQuery(conn, "SELECT datname FROM pg_database WHERE datallowconn ORDER BY 1;", progname, echo); - PQfinish(conn); - -- initPQExpBuffer(&connstr); - for (i = 0; i < PQntuples(result); i++) - { - char *dbname = PQgetvalue(result, i, 0); -@@ -253,15 +249,10 @@ cluster_all_databases(bool verbose, const char *maintenance_db, - fflush(stdout); - } - -- resetPQExpBuffer(&connstr); -- appendPQExpBuffer(&connstr, "dbname="); -- appendConnStrVal(&connstr, dbname); -+ cparams->override_dbname = dbname; - -- cluster_one_database(connstr.data, verbose, NULL, -- host, port, username, prompt_password, -- progname, echo); -+ cluster_one_database(cparams, NULL, progname, verbose, echo); - } -- termPQExpBuffer(&connstr); - - PQclear(result); - } -diff --git a/src/bin/scripts/common.c b/src/bin/scripts/common.c -index 5088c4c48e..ad70ca4ff9 100644 ---- a/src/bin/scripts/common.c -+++ b/src/bin/scripts/common.c -@@ -57,7 +57,7 @@ handle_help_version_opts(int argc, char *argv[], - * Make a database connection with the given parameters. - * - * An interactive password prompt is automatically issued if needed and -- * allowed by prompt_password. -+ * allowed by cparams->prompt_password. - * - * If allow_password_reuse is true, we will try to re-use any password - * given during previous calls to this routine. (Callers should not pass -@@ -65,9 +65,7 @@ handle_help_version_opts(int argc, char *argv[], - * as before, else we might create password exposure hazards.) - */ - PGconn * --connectDatabase(const char *dbname, const char *pghost, -- const char *pgport, const char *pguser, -- enum trivalue prompt_password, const char *progname, -+connectDatabase(const ConnParams *cparams, const char *progname, - bool echo, bool fail_ok, bool allow_password_reuse) - { - PGconn *conn; -@@ -75,10 +73,13 @@ connectDatabase(const char *dbname, const char *pghost, - static bool have_password = false; - static char password[100]; - -+ /* Callers must supply at least dbname; other params can be NULL */ -+ Assert(cparams->dbname); -+ - if (!allow_password_reuse) - have_password = false; - -- if (!have_password && prompt_password == TRI_YES) -+ if (cparams->prompt_password == TRI_YES && !have_password) - { - simple_prompt("Password: ", password, sizeof(password), false); - have_password = true; -@@ -90,23 +91,35 @@ connectDatabase(const char *dbname, const char *pghost, - */ - do - { -- const char *keywords[7]; -- const char *values[7]; -- -- keywords[0] = "host"; -- values[0] = pghost; -- keywords[1] = "port"; -- values[1] = pgport; -- keywords[2] = "user"; -- values[2] = pguser; -- keywords[3] = "password"; -- values[3] = have_password ? password : NULL; -- keywords[4] = "dbname"; -- values[4] = dbname; -- keywords[5] = "fallback_application_name"; -- values[5] = progname; -- keywords[6] = NULL; -- values[6] = NULL; -+ const char *keywords[8]; -+ const char *values[8]; -+ int i = 0; -+ -+ /* -+ * If dbname is a connstring, its entries can override the other -+ * values obtained from cparams; but in turn, override_dbname can -+ * override the dbname component of it. -+ */ -+ keywords[i] = "host"; -+ values[i++] = cparams->pghost; -+ keywords[i] = "port"; -+ values[i++] = cparams->pgport; -+ keywords[i] = "user"; -+ values[i++] = cparams->pguser; -+ keywords[i] = "password"; -+ values[i++] = have_password ? password : NULL; -+ keywords[i] = "dbname"; -+ values[i++] = cparams->dbname; -+ if (cparams->override_dbname) -+ { -+ keywords[i] = "dbname"; -+ values[i++] = cparams->override_dbname; -+ } -+ keywords[i] = "fallback_application_name"; -+ values[i++] = progname; -+ keywords[i] = NULL; -+ values[i++] = NULL; -+ Assert(i <= lengthof(keywords)); - - new_pass = false; - conn = PQconnectdbParams(keywords, values, true); -@@ -114,7 +127,7 @@ connectDatabase(const char *dbname, const char *pghost, - if (!conn) - { - fprintf(stderr, _("%s: could not connect to database %s: out of memory\n"), -- progname, dbname); -+ progname, cparams->dbname); - exit(1); - } - -@@ -123,7 +136,7 @@ connectDatabase(const char *dbname, const char *pghost, - */ - if (PQstatus(conn) == CONNECTION_BAD && - PQconnectionNeedsPassword(conn) && -- prompt_password != TRI_NO) -+ cparams->prompt_password != TRI_NO) - { - PQfinish(conn); - simple_prompt("Password: ", password, sizeof(password), false); -@@ -141,10 +154,11 @@ connectDatabase(const char *dbname, const char *pghost, - return NULL; - } - fprintf(stderr, _("%s: could not connect to database %s: %s"), -- progname, dbname, PQerrorMessage(conn)); -+ progname, cparams->dbname, PQerrorMessage(conn)); - exit(1); - } - -+ /* Start strict; callers may override this. */ - PQclear(executeQuery(conn, ALWAYS_SECURE_SEARCH_PATH_SQL, - progname, echo)); - -@@ -153,27 +167,30 @@ connectDatabase(const char *dbname, const char *pghost, - - /* - * Try to connect to the appropriate maintenance database. -+ * -+ * This differs from connectDatabase only in that it has a rule for -+ * inserting a default "dbname" if none was given (which is why cparams -+ * is not const). Note that cparams->dbname should typically come from -+ * a --maintenance-db command line parameter. - */ - PGconn * --connectMaintenanceDatabase(const char *maintenance_db, -- const char *pghost, const char *pgport, -- const char *pguser, enum trivalue prompt_password, -+connectMaintenanceDatabase(ConnParams *cparams, - const char *progname, bool echo) - { - PGconn *conn; - - /* If a maintenance database name was specified, just connect to it. */ -- if (maintenance_db) -- return connectDatabase(maintenance_db, pghost, pgport, pguser, -- prompt_password, progname, echo, false, false); -+ if (cparams->dbname) -+ return connectDatabase(cparams, progname, echo, false, false); - - /* Otherwise, try postgres first and then template1. */ -- conn = connectDatabase("postgres", pghost, pgport, pguser, prompt_password, -- progname, echo, true, false); -+ cparams->dbname = "postgres"; -+ conn = connectDatabase(cparams, progname, echo, true, false); - if (!conn) -- conn = connectDatabase("template1", pghost, pgport, pguser, -- prompt_password, progname, echo, false, false); -- -+ { -+ cparams->dbname = "template1"; -+ conn = connectDatabase(cparams, progname, echo, false, false); -+ } - return conn; - } - -diff --git a/src/bin/scripts/common.h b/src/bin/scripts/common.h -index 085e3b7cf6..b94c3e907f 100644 ---- a/src/bin/scripts/common.h -+++ b/src/bin/scripts/common.h -@@ -23,20 +23,32 @@ enum trivalue - - extern bool CancelRequested; - -+/* Parameters needed by connectDatabase/connectMaintenanceDatabase */ -+typedef struct _connParams -+{ -+ /* These fields record the actual command line parameters */ -+ const char *dbname; /* this may be a connstring! */ -+ const char *pghost; -+ const char *pgport; -+ const char *pguser; -+ enum trivalue prompt_password; -+ /* If not NULL, this overrides the dbname obtained from command line */ -+ /* (but *only* the DB name, not anything else in the connstring) */ -+ const char *override_dbname; -+} ConnParams; -+ - typedef void (*help_handler) (const char *progname); - - extern void handle_help_version_opts(int argc, char *argv[], - const char *fixed_progname, - help_handler hlp); - --extern PGconn *connectDatabase(const char *dbname, const char *pghost, -- const char *pgport, const char *pguser, -- enum trivalue prompt_password, const char *progname, -- bool echo, bool fail_ok, bool allow_password_reuse); -+extern PGconn *connectDatabase(const ConnParams *cparams, -+ const char *progname, -+ bool echo, bool fail_ok, -+ bool allow_password_reuse); - --extern PGconn *connectMaintenanceDatabase(const char *maintenance_db, -- const char *pghost, const char *pgport, -- const char *pguser, enum trivalue prompt_password, -+extern PGconn *connectMaintenanceDatabase(ConnParams *cparams, - const char *progname, bool echo); - - extern PGresult *executeQuery(PGconn *conn, const char *query, -diff --git a/src/bin/scripts/createdb.c b/src/bin/scripts/createdb.c -index 45d26ecb8c..f1be5745fb 100644 ---- a/src/bin/scripts/createdb.c -+++ b/src/bin/scripts/createdb.c -@@ -50,6 +50,7 @@ main(int argc, char *argv[]) - char *port = NULL; - char *username = NULL; - enum trivalue prompt_password = TRI_DEFAULT; -+ ConnParams cparams; - bool echo = false; - char *owner = NULL; - char *tablespace = NULL; -@@ -181,8 +182,14 @@ main(int argc, char *argv[]) - if (maintenance_db == NULL && strcmp(dbname, "postgres") == 0) - maintenance_db = "template1"; - -- conn = connectMaintenanceDatabase(maintenance_db, host, port, username, -- prompt_password, progname, echo); -+ cparams.dbname = maintenance_db; -+ cparams.pghost = host; -+ cparams.pgport = port; -+ cparams.pguser = username; -+ cparams.prompt_password = prompt_password; -+ cparams.override_dbname = NULL; -+ -+ conn = connectMaintenanceDatabase(&cparams, progname, echo); - - initPQExpBuffer(&sql); - -diff --git a/src/bin/scripts/createuser.c b/src/bin/scripts/createuser.c -index edadd136a6..b1585d7e56 100644 ---- a/src/bin/scripts/createuser.c -+++ b/src/bin/scripts/createuser.c -@@ -60,6 +60,7 @@ main(int argc, char *argv[]) - char *username = NULL; - SimpleStringList roles = {NULL, NULL}; - enum trivalue prompt_password = TRI_DEFAULT; -+ ConnParams cparams; - bool echo = false; - bool interactive = false; - char *conn_limit = NULL; -@@ -251,8 +252,14 @@ main(int argc, char *argv[]) - if (login == 0) - login = TRI_YES; - -- conn = connectDatabase("postgres", host, port, username, prompt_password, -- progname, echo, false, false); -+ cparams.dbname = NULL; /* this program lacks any dbname option... */ -+ cparams.pghost = host; -+ cparams.pgport = port; -+ cparams.pguser = username; -+ cparams.prompt_password = prompt_password; -+ cparams.override_dbname = NULL; -+ -+ conn = connectMaintenanceDatabase(&cparams, progname, echo); - - initPQExpBuffer(&sql); - -diff --git a/src/bin/scripts/dropdb.c b/src/bin/scripts/dropdb.c -index 614110179e..3f14a365ee 100644 ---- a/src/bin/scripts/dropdb.c -+++ b/src/bin/scripts/dropdb.c -@@ -46,6 +46,7 @@ main(int argc, char *argv[]) - char *port = NULL; - char *username = NULL; - enum trivalue prompt_password = TRI_DEFAULT; -+ ConnParams cparams; - bool echo = false; - bool interactive = false; - -@@ -128,9 +129,14 @@ main(int argc, char *argv[]) - if (maintenance_db == NULL && strcmp(dbname, "postgres") == 0) - maintenance_db = "template1"; - -- conn = connectMaintenanceDatabase(maintenance_db, -- host, port, username, prompt_password, -- progname, echo); -+ cparams.dbname = maintenance_db; -+ cparams.pghost = host; -+ cparams.pgport = port; -+ cparams.pguser = username; -+ cparams.prompt_password = prompt_password; -+ cparams.override_dbname = NULL; -+ -+ conn = connectMaintenanceDatabase(&cparams, progname, echo); - - if (echo) - printf("%s\n", sql.data); -diff --git a/src/bin/scripts/dropuser.c b/src/bin/scripts/dropuser.c -index ad400c3518..1dd5ad20fd 100644 ---- a/src/bin/scripts/dropuser.c -+++ b/src/bin/scripts/dropuser.c -@@ -44,6 +44,7 @@ main(int argc, char *argv[]) - char *port = NULL; - char *username = NULL; - enum trivalue prompt_password = TRI_DEFAULT; -+ ConnParams cparams; - bool echo = false; - bool interactive = false; - char dropuser_buf[128]; -@@ -129,13 +130,19 @@ main(int argc, char *argv[]) - exit(0); - } - -+ cparams.dbname = NULL; /* this program lacks any dbname option... */ -+ cparams.pghost = host; -+ cparams.pgport = port; -+ cparams.pguser = username; -+ cparams.prompt_password = prompt_password; -+ cparams.override_dbname = NULL; -+ -+ conn = connectMaintenanceDatabase(&cparams, progname, echo); -+ - initPQExpBuffer(&sql); - appendPQExpBuffer(&sql, "DROP ROLE %s%s;", - (if_exists ? "IF EXISTS " : ""), fmtId(dropuser)); - -- conn = connectDatabase("postgres", host, port, username, prompt_password, -- progname, echo, false, false); -- - if (echo) - printf("%s\n", sql.data); - result = PQexec(conn, sql.data); -diff --git a/src/bin/scripts/reindexdb.c b/src/bin/scripts/reindexdb.c -index cdfb115641..48074afe79 100644 ---- a/src/bin/scripts/reindexdb.c -+++ b/src/bin/scripts/reindexdb.c -@@ -15,19 +15,14 @@ - #include "fe_utils/string_utils.h" - - --static void reindex_one_database(const char *name, const char *dbname, -- const char *type, const char *host, -- const char *port, const char *username, -- enum trivalue prompt_password, const char *progname, -+static void reindex_one_database(const ConnParams *cparams, -+ const char *type, const char *name, -+ const char *progname, - bool echo, bool verbose); --static void reindex_all_databases(const char *maintenance_db, -- const char *host, const char *port, -- const char *username, enum trivalue prompt_password, -+static void reindex_all_databases(ConnParams *cparams, - const char *progname, bool echo, - bool quiet, bool verbose); --static void reindex_system_catalogs(const char *dbname, -- const char *host, const char *port, -- const char *username, enum trivalue prompt_password, -+static void reindex_system_catalogs(const ConnParams *cparams, - const char *progname, bool echo, bool verbose); - static void help(const char *progname); - -@@ -63,6 +58,7 @@ main(int argc, char *argv[]) - const char *port = NULL; - const char *username = NULL; - enum trivalue prompt_password = TRI_DEFAULT; -+ ConnParams cparams; - bool syscatalog = false; - bool alldb = false; - bool echo = false; -@@ -151,6 +147,13 @@ main(int argc, char *argv[]) - exit(1); - } - -+ /* fill cparams except for dbname, which is set below */ -+ cparams.pghost = host; -+ cparams.pgport = port; -+ cparams.pguser = username; -+ cparams.prompt_password = prompt_password; -+ cparams.override_dbname = NULL; -+ - setup_cancel_handler(); - - if (alldb) -@@ -181,8 +184,10 @@ main(int argc, char *argv[]) - exit(1); - } - -- reindex_all_databases(maintenance_db, host, port, username, -- prompt_password, progname, echo, quiet, verbose); -+ cparams.dbname = maintenance_db; -+ -+ reindex_all_databases(&cparams, -+ progname, echo, quiet, verbose); - } - else if (syscatalog) - { -@@ -212,7 +217,9 @@ main(int argc, char *argv[]) - dbname = get_user_name_or_exit(progname); - } - -- reindex_system_catalogs(dbname, host, port, username, prompt_password, -+ cparams.dbname = dbname; -+ -+ reindex_system_catalogs(&cparams, - progname, echo, verbose); - } - else -@@ -227,14 +234,16 @@ main(int argc, char *argv[]) - dbname = get_user_name_or_exit(progname); - } - -+ cparams.dbname = dbname; -+ - if (schemas.head != NULL) - { - SimpleStringListCell *cell; - - for (cell = schemas.head; cell; cell = cell->next) - { -- reindex_one_database(cell->val, dbname, "SCHEMA", host, port, -- username, prompt_password, progname, echo, verbose); -+ reindex_one_database(&cparams, "SCHEMA", cell->val, -+ progname, echo, verbose); - } - } - -@@ -244,8 +253,8 @@ main(int argc, char *argv[]) - - for (cell = indexes.head; cell; cell = cell->next) - { -- reindex_one_database(cell->val, dbname, "INDEX", host, port, -- username, prompt_password, progname, echo, verbose); -+ reindex_one_database(&cparams, "INDEX", cell->val, -+ progname, echo, verbose); - } - } - if (tables.head != NULL) -@@ -254,8 +263,8 @@ main(int argc, char *argv[]) - - for (cell = tables.head; cell; cell = cell->next) - { -- reindex_one_database(cell->val, dbname, "TABLE", host, port, -- username, prompt_password, progname, echo, verbose); -+ reindex_one_database(&cparams, "TABLE", cell->val, -+ progname, echo, verbose); - } - } - -@@ -264,25 +273,24 @@ main(int argc, char *argv[]) - * specified - */ - if (indexes.head == NULL && tables.head == NULL && schemas.head == NULL) -- reindex_one_database(NULL, dbname, "DATABASE", host, port, -- username, prompt_password, progname, echo, verbose); -+ reindex_one_database(&cparams, "DATABASE", NULL, -+ progname, echo, verbose); - } - - exit(0); - } - - static void --reindex_one_database(const char *name, const char *dbname, const char *type, -- const char *host, const char *port, const char *username, -- enum trivalue prompt_password, const char *progname, bool echo, -- bool verbose) -+reindex_one_database(const ConnParams *cparams, -+ const char *type, const char *name, -+ const char *progname, -+ bool echo, bool verbose) - { - PQExpBufferData sql; - - PGconn *conn; - -- conn = connectDatabase(dbname, host, port, username, prompt_password, -- progname, echo, false, false); -+ conn = connectDatabase(cparams, progname, echo, false, false); - - initPQExpBuffer(&sql); - -@@ -325,22 +333,17 @@ reindex_one_database(const char *name, const char *dbname, const char *type, - } - - static void --reindex_all_databases(const char *maintenance_db, -- const char *host, const char *port, -- const char *username, enum trivalue prompt_password, -+reindex_all_databases(ConnParams *cparams, - const char *progname, bool echo, bool quiet, bool verbose) - { - PGconn *conn; - PGresult *result; -- PQExpBufferData connstr; - int i; - -- conn = connectMaintenanceDatabase(maintenance_db, host, port, username, -- prompt_password, progname, echo); -+ conn = connectMaintenanceDatabase(cparams, progname, echo); - result = executeQuery(conn, "SELECT datname FROM pg_database WHERE datallowconn ORDER BY 1;", progname, echo); - PQfinish(conn); - -- initPQExpBuffer(&connstr); - for (i = 0; i < PQntuples(result); i++) - { - char *dbname = PQgetvalue(result, i, 0); -@@ -351,29 +354,23 @@ reindex_all_databases(const char *maintenance_db, - fflush(stdout); - } - -- resetPQExpBuffer(&connstr); -- appendPQExpBuffer(&connstr, "dbname="); -- appendConnStrVal(&connstr, dbname); -+ cparams->override_dbname = dbname; - -- reindex_one_database(NULL, connstr.data, "DATABASE", host, -- port, username, prompt_password, -+ reindex_one_database(cparams, "DATABASE", NULL, - progname, echo, verbose); - } -- termPQExpBuffer(&connstr); - - PQclear(result); - } - - static void --reindex_system_catalogs(const char *dbname, const char *host, const char *port, -- const char *username, enum trivalue prompt_password, -+reindex_system_catalogs(const ConnParams *cparams, - const char *progname, bool echo, bool verbose) - { - PGconn *conn; - PQExpBufferData sql; - -- conn = connectDatabase(dbname, host, port, username, prompt_password, -- progname, echo, false, false); -+ conn = connectDatabase(cparams, progname, echo, false, false); - - initPQExpBuffer(&sql); - -diff --git a/src/bin/scripts/vacuumdb.c b/src/bin/scripts/vacuumdb.c -index 4ac765244a..40b1fbc5a3 100644 ---- a/src/bin/scripts/vacuumdb.c -+++ b/src/bin/scripts/vacuumdb.c -@@ -43,19 +43,16 @@ typedef struct vacuumingOptions - } vacuumingOptions; - - --static void vacuum_one_database(const char *dbname, vacuumingOptions *vacopts, -+static void vacuum_one_database(const ConnParams *cparams, -+ vacuumingOptions *vacopts, - int stage, - SimpleStringList *tables, -- const char *host, const char *port, -- const char *username, enum trivalue prompt_password, - int concurrentCons, - const char *progname, bool echo, bool quiet); - --static void vacuum_all_databases(vacuumingOptions *vacopts, -+static void vacuum_all_databases(ConnParams *cparams, -+ vacuumingOptions *vacopts, - bool analyze_in_stages, -- const char *maintenance_db, -- const char *host, const char *port, -- const char *username, enum trivalue prompt_password, - int concurrentCons, - const char *progname, bool echo, bool quiet); - -@@ -122,6 +119,7 @@ main(int argc, char *argv[]) - char *port = NULL; - char *username = NULL; - enum trivalue prompt_password = TRI_DEFAULT; -+ ConnParams cparams; - bool echo = false; - bool quiet = false; - vacuumingOptions vacopts; -@@ -248,6 +246,13 @@ main(int argc, char *argv[]) - /* allow 'and_analyze' with 'analyze_only' */ - } - -+ /* fill cparams except for dbname, which is set below */ -+ cparams.pghost = host; -+ cparams.pgport = port; -+ cparams.pguser = username; -+ cparams.prompt_password = prompt_password; -+ cparams.override_dbname = NULL; -+ - setup_cancel_handler(); - - /* Avoid opening extra connections. */ -@@ -269,10 +274,10 @@ main(int argc, char *argv[]) - exit(1); - } - -- vacuum_all_databases(&vacopts, -+ cparams.dbname = maintenance_db; -+ -+ vacuum_all_databases(&cparams, &vacopts, - analyze_in_stages, -- maintenance_db, -- host, port, username, prompt_password, - concurrentCons, - progname, echo, quiet); - } -@@ -288,25 +293,25 @@ main(int argc, char *argv[]) - dbname = get_user_name_or_exit(progname); - } - -+ cparams.dbname = dbname; -+ - if (analyze_in_stages) - { - int stage; - - for (stage = 0; stage < ANALYZE_NUM_STAGES; stage++) - { -- vacuum_one_database(dbname, &vacopts, -+ vacuum_one_database(&cparams, &vacopts, - stage, - &tables, -- host, port, username, prompt_password, - concurrentCons, - progname, echo, quiet); - } - } - else -- vacuum_one_database(dbname, &vacopts, -+ vacuum_one_database(&cparams, &vacopts, - ANALYZE_NO_STAGE, - &tables, -- host, port, username, prompt_password, - concurrentCons, - progname, echo, quiet); - } -@@ -328,11 +333,10 @@ main(int argc, char *argv[]) - * a list of tables from the database. - */ - static void --vacuum_one_database(const char *dbname, vacuumingOptions *vacopts, -+vacuum_one_database(const ConnParams *cparams, -+ vacuumingOptions *vacopts, - int stage, - SimpleStringList *tables, -- const char *host, const char *port, -- const char *username, enum trivalue prompt_password, - int concurrentCons, - const char *progname, bool echo, bool quiet) - { -@@ -358,8 +362,7 @@ vacuum_one_database(const char *dbname, vacuumingOptions *vacopts, - Assert(stage == ANALYZE_NO_STAGE || - (stage >= 0 && stage < ANALYZE_NUM_STAGES)); - -- conn = connectDatabase(dbname, host, port, username, prompt_password, -- progname, echo, false, true); -+ conn = connectDatabase(cparams, progname, echo, false, true); - - if (!quiet) - { -@@ -435,8 +438,7 @@ vacuum_one_database(const char *dbname, vacuumingOptions *vacopts, - { - for (i = 1; i < concurrentCons; i++) - { -- conn = connectDatabase(dbname, host, port, username, prompt_password, -- progname, echo, false, true); -+ conn = connectDatabase(cparams, progname, echo, false, true); - - /* - * Fail and exit immediately if trying to use a socket in an -@@ -556,28 +558,23 @@ finish: - * quickly everywhere before generating more detailed ones. - */ - static void --vacuum_all_databases(vacuumingOptions *vacopts, -+vacuum_all_databases(ConnParams *cparams, -+ vacuumingOptions *vacopts, - bool analyze_in_stages, -- const char *maintenance_db, const char *host, -- const char *port, const char *username, -- enum trivalue prompt_password, - int concurrentCons, - const char *progname, bool echo, bool quiet) - { - PGconn *conn; - PGresult *result; -- PQExpBufferData connstr; - int stage; - int i; - -- conn = connectMaintenanceDatabase(maintenance_db, host, port, username, -- prompt_password, progname, echo); -+ conn = connectMaintenanceDatabase(cparams, progname, echo); - result = executeQuery(conn, - "SELECT datname FROM pg_database WHERE datallowconn ORDER BY 1;", - progname, echo); - PQfinish(conn); - -- initPQExpBuffer(&connstr); - if (analyze_in_stages) - { - /* -@@ -592,14 +589,11 @@ vacuum_all_databases(vacuumingOptions *vacopts, - { - for (i = 0; i < PQntuples(result); i++) - { -- resetPQExpBuffer(&connstr); -- appendPQExpBuffer(&connstr, "dbname="); -- appendConnStrVal(&connstr, PQgetvalue(result, i, 0)); -+ cparams->override_dbname = PQgetvalue(result, i, 0); - -- vacuum_one_database(connstr.data, vacopts, -+ vacuum_one_database(cparams, vacopts, - stage, - NULL, -- host, port, username, prompt_password, - concurrentCons, - progname, echo, quiet); - } -@@ -609,19 +603,15 @@ vacuum_all_databases(vacuumingOptions *vacopts, - { - for (i = 0; i < PQntuples(result); i++) - { -- resetPQExpBuffer(&connstr); -- appendPQExpBuffer(&connstr, "dbname="); -- appendConnStrVal(&connstr, PQgetvalue(result, i, 0)); -+ cparams->override_dbname = PQgetvalue(result, i, 0); - -- vacuum_one_database(connstr.data, vacopts, -+ vacuum_one_database(cparams, vacopts, - ANALYZE_NO_STAGE, - NULL, -- host, port, username, prompt_password, - concurrentCons, - progname, echo, quiet); - } - } -- termPQExpBuffer(&connstr); - - PQclear(result); - } --- -2.23.0 - diff --git a/CVE-2020-25694-3.patch b/CVE-2020-25694-3.patch deleted file mode 100644 index e1687e319fe57e8263dcff3caf70a1509b7ff261..0000000000000000000000000000000000000000 --- a/CVE-2020-25694-3.patch +++ /dev/null @@ -1,782 +0,0 @@ -From bb3ab8bfb690721923e987d2dfab683b462c1e88 Mon Sep 17 00:00:00 2001 -From: Tom Lane -Date: Thu, 24 Sep 2020 18:19:39 -0400 -Subject: [PATCH] Fix handling of -d "connection string" in pg_dump/pg_restore. - -Parallel pg_dump failed if its -d parameter was a connection string -containing any essential information other than host, port, or username. -The same was true for pg_restore with --create. - -The reason is that these scenarios failed to preserve the connection -string from the command line; the code felt free to replace that with -just the database name when reconnecting from a pg_dump parallel worker -or after creating the target database. By chance, parallel pg_restore -did not suffer this defect, as long as you didn't say --create. - -In practice it seems that the error would be obvious only if the -connstring included essential, non-default SSL or GSS parameters. -This may explain why it took us so long to notice. (It also makes -it very difficult to craft a regression test case illustrating the -problem, since the test would fail in builds without those options.) - -Fix by refactoring so that ConnectDatabase always receives all the -relevant options directly from the command line, rather than -reconstructed values. Inject a different database name, when necessary, -by relying on libpq's rules for handling multiple "dbname" parameters. - -While here, let's get rid of the essentially duplicate _connectDB -function, as well as some obsolete nearby cruft. - -Per bug #16604 from Zsolt Ero. Back-patch to all supported branches. - -Discussion: https://postgr.es/m/16604-933f4b8791227b15@postgresql.org ---- - src/bin/pg_dump/pg_backup.h | 36 ++-- - src/bin/pg_dump/pg_backup_archiver.c | 96 +++-------- - src/bin/pg_dump/pg_backup_archiver.h | 3 +- - src/bin/pg_dump/pg_backup_db.c | 249 +++++++-------------------- - src/bin/pg_dump/pg_dump.c | 24 +-- - src/bin/pg_dump/pg_restore.c | 14 +- - 6 files changed, 131 insertions(+), 291 deletions(-) - -diff --git a/src/bin/pg_dump/pg_backup.h b/src/bin/pg_dump/pg_backup.h -index 560de01884..72c6a8db6c 100644 ---- a/src/bin/pg_dump/pg_backup.h -+++ b/src/bin/pg_dump/pg_backup.h -@@ -58,6 +58,20 @@ typedef enum _teSection - SECTION_POST_DATA /* stuff to be processed after data */ - } teSection; - -+/* Parameters needed by ConnectDatabase; same for dump and restore */ -+typedef struct _connParams -+{ -+ /* These fields record the actual command line parameters */ -+ char *dbname; /* this may be a connstring! */ -+ char *pgport; -+ char *pghost; -+ char *username; -+ trivalue promptPassword; -+ /* If not NULL, this overrides the dbname obtained from command line */ -+ /* (but *only* the DB name, not anything else in the connstring) */ -+ char *override_dbname; -+} ConnParams; -+ - typedef struct _restoreOptions - { - int createDB; /* Issue commands to create the database */ -@@ -106,12 +120,9 @@ typedef struct _restoreOptions - SimpleStringList tableNames; - - int useDB; -- char *dbname; /* subject to expand_dbname */ -- char *pgport; -- char *pghost; -- char *username; -+ ConnParams cparams; /* parameters to use if useDB */ -+ - int noDataForFailedTables; -- trivalue promptPassword; - int exit_on_error; - int compression; - int suppressDumpWarnings; /* Suppress output of WARNING entries -@@ -126,10 +137,8 @@ typedef struct _restoreOptions - - typedef struct _dumpOptions - { -- const char *dbname; /* subject to expand_dbname */ -- const char *pghost; -- const char *pgport; -- const char *username; -+ ConnParams cparams; -+ - bool oids; - - int binary_upgrade; -@@ -239,12 +248,9 @@ typedef void (*SetupWorkerPtrType) (Archive *AH); - * Main archiver interface. - */ - --extern void ConnectDatabase(Archive *AH, -- const char *dbname, -- const char *pghost, -- const char *pgport, -- const char *username, -- trivalue prompt_password); -+extern void ConnectDatabase(Archive *AHX, -+ const ConnParams *cparams, -+ bool isReconnect); - extern void DisconnectDatabase(Archive *AHX); - extern PGconn *GetConnection(Archive *AHX); - -diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c -index 8892b17790..4003ab3b13 100644 ---- a/src/bin/pg_dump/pg_backup_archiver.c -+++ b/src/bin/pg_dump/pg_backup_archiver.c -@@ -144,6 +144,7 @@ InitDumpOptions(DumpOptions *opts) - memset(opts, 0, sizeof(DumpOptions)); - /* set any fields that shouldn't default to zeroes */ - opts->include_everything = true; -+ opts->cparams.promptPassword = TRI_DEFAULT; - opts->dumpSections = DUMP_UNSECTIONED; - } - -@@ -157,6 +158,11 @@ dumpOptionsFromRestoreOptions(RestoreOptions *ropt) - DumpOptions *dopt = NewDumpOptions(); - - /* this is the inverse of what's at the end of pg_dump.c's main() */ -+ dopt->cparams.dbname = ropt->cparams.dbname ? pg_strdup(ropt->cparams.dbname) : NULL; -+ dopt->cparams.pgport = ropt->cparams.pgport ? pg_strdup(ropt->cparams.pgport) : NULL; -+ dopt->cparams.pghost = ropt->cparams.pghost ? pg_strdup(ropt->cparams.pghost) : NULL; -+ dopt->cparams.username = ropt->cparams.username ? pg_strdup(ropt->cparams.username) : NULL; -+ dopt->cparams.promptPassword = ropt->cparams.promptPassword; - dopt->outputClean = ropt->dropSchema; - dopt->dataOnly = ropt->dataOnly; - dopt->schemaOnly = ropt->schemaOnly; -@@ -401,9 +407,7 @@ RestoreArchive(Archive *AHX) - AHX->minRemoteVersion = 0; - AHX->maxRemoteVersion = 9999999; - -- ConnectDatabase(AHX, ropt->dbname, -- ropt->pghost, ropt->pgport, ropt->username, -- ropt->promptPassword); -+ ConnectDatabase(AHX, &ropt->cparams, false); - - /* - * If we're talking to the DB directly, don't send comments since they -@@ -823,16 +827,8 @@ restore_toc_entry(ArchiveHandle *AH, TocEntry *te, bool is_parallel) - /* If we created a DB, connect to it... */ - if (strcmp(te->desc, "DATABASE") == 0) - { -- PQExpBufferData connstr; -- -- initPQExpBuffer(&connstr); -- appendPQExpBufferStr(&connstr, "dbname="); -- appendConnStrVal(&connstr, te->tag); -- /* Abandon struct, but keep its buffer until process exit. */ -- - ahlog(AH, 1, "connecting to new database \"%s\"\n", te->tag); - _reconnectToDB(AH, te->tag); -- ropt->dbname = connstr.data; - } - } - -@@ -966,7 +962,7 @@ NewRestoreOptions(void) - - /* set any fields that shouldn't default to zeroes */ - opts->format = archUnknown; -- opts->promptPassword = TRI_DEFAULT; -+ opts->cparams.promptPassword = TRI_DEFAULT; - opts->dumpSections = DUMP_UNSECTIONED; - - return opts; -@@ -2388,8 +2384,6 @@ _allocAH(const char *FileSpec, const ArchiveFormat fmt, - else - AH->format = fmt; - -- AH->promptPassword = TRI_DEFAULT; -- - switch (AH->format) - { - case archCustom: -@@ -3157,27 +3151,20 @@ _doSetWithOids(ArchiveHandle *AH, const bool withOids) - * If we're currently restoring right into a database, this will - * actually establish a connection. Otherwise it puts a \connect into - * the script output. -- * -- * NULL dbname implies reconnecting to the current DB (pretty useless). - */ - static void - _reconnectToDB(ArchiveHandle *AH, const char *dbname) - { - if (RestoringToDB(AH)) -- ReconnectToServer(AH, dbname, NULL); -+ ReconnectToServer(AH, dbname); - else - { -- if (dbname) -- { -- PQExpBufferData connectbuf; -+ PQExpBufferData connectbuf; - -- initPQExpBuffer(&connectbuf); -- appendPsqlMetaConnect(&connectbuf, dbname); -- ahprintf(AH, "%s\n", connectbuf.data); -- termPQExpBuffer(&connectbuf); -- } -- else -- ahprintf(AH, "%s\n", "\\connect -\n"); -+ initPQExpBuffer(&connectbuf); -+ appendPsqlMetaConnect(&connectbuf, dbname); -+ ahprintf(AH, "%s\n", connectbuf.data); -+ termPQExpBuffer(&connectbuf); - } - - /* -@@ -4107,9 +4094,7 @@ restore_toc_entries_postfork(ArchiveHandle *AH, TocEntry *pending_list) - /* - * Now reconnect the single parent connection. - */ -- ConnectDatabase((Archive *) AH, ropt->dbname, -- ropt->pghost, ropt->pgport, ropt->username, -- ropt->promptPassword); -+ ConnectDatabase((Archive *) AH, &ropt->cparams, true); - - /* re-establish fixed state */ - _doSetFixedOutputState(AH); -@@ -4690,54 +4675,15 @@ CloneArchive(ArchiveHandle *AH) - clone->public.n_errors = 0; - - /* -- * Connect our new clone object to the database: In parallel restore the -- * parent is already disconnected, because we can connect the worker -- * processes independently to the database (no snapshot sync required). In -- * parallel backup we clone the parent's existing connection. -+ * Connect our new clone object to the database, using the same connection -+ * parameters used for the original connection. - */ -- if (AH->mode == archModeRead) -- { -- RestoreOptions *ropt = AH->public.ropt; -- -- Assert(AH->connection == NULL); -- -- /* this also sets clone->connection */ -- ConnectDatabase((Archive *) clone, ropt->dbname, -- ropt->pghost, ropt->pgport, ropt->username, -- ropt->promptPassword); -+ ConnectDatabase((Archive *) clone, &clone->public.ropt->cparams, true); - -- /* re-establish fixed state */ -+ /* re-establish fixed state */ -+ if (AH->mode == archModeRead) - _doSetFixedOutputState(clone); -- } -- else -- { -- PQExpBufferData connstr; -- char *pghost; -- char *pgport; -- char *username; -- -- Assert(AH->connection != NULL); -- -- /* -- * Even though we are technically accessing the parent's database -- * object here, these functions are fine to be called like that -- * because all just return a pointer and do not actually send/receive -- * any data to/from the database. -- */ -- initPQExpBuffer(&connstr); -- appendPQExpBuffer(&connstr, "dbname="); -- appendConnStrVal(&connstr, PQdb(AH->connection)); -- pghost = PQhost(AH->connection); -- pgport = PQport(AH->connection); -- username = PQuser(AH->connection); -- -- /* this also sets clone->connection */ -- ConnectDatabase((Archive *) clone, connstr.data, -- pghost, pgport, username, TRI_NO); -- -- termPQExpBuffer(&connstr); -- /* setupDumpWorker will fix up connection state */ -- } -+ /* in write case, setupDumpWorker will fix up connection state */ - - /* Let the format-specific code have a chance too */ - (clone->ClonePtr) (clone); -diff --git a/src/bin/pg_dump/pg_backup_archiver.h b/src/bin/pg_dump/pg_backup_archiver.h -index 3b69868359..50829c4b2e 100644 ---- a/src/bin/pg_dump/pg_backup_archiver.h -+++ b/src/bin/pg_dump/pg_backup_archiver.h -@@ -304,7 +304,6 @@ struct _archiveHandle - - /* Stuff for direct DB connection */ - char *archdbname; /* DB name *read* from archive */ -- trivalue promptPassword; - char *savedPassword; /* password for ropt->username, if known */ - char *use_role; - PGconn *connection; -@@ -450,7 +449,7 @@ extern void InitArchiveFmt_Tar(ArchiveHandle *AH); - - extern bool isValidTarHeader(char *header); - --extern int ReconnectToServer(ArchiveHandle *AH, const char *dbname, const char *newUser); -+extern void ReconnectToServer(ArchiveHandle *AH, const char *dbname); - extern void DropBlobIfExists(ArchiveHandle *AH, Oid oid); - - void ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH); -diff --git a/src/bin/pg_dump/pg_backup_db.c b/src/bin/pg_dump/pg_backup_db.c -index 43f5941f93..4eaea4af4f 100644 ---- a/src/bin/pg_dump/pg_backup_db.c -+++ b/src/bin/pg_dump/pg_backup_db.c -@@ -30,7 +30,6 @@ - static const char *modulename = gettext_noop("archiver (db)"); - - static void _check_database_version(ArchiveHandle *AH); --static PGconn *_connectDB(ArchiveHandle *AH, const char *newdbname, const char *newUser); - static void notice_processor(void *arg, const char *message); - - static void -@@ -76,186 +75,51 @@ _check_database_version(ArchiveHandle *AH) - - /* - * Reconnect to the server. If dbname is not NULL, use that database, -- * else the one associated with the archive handle. If username is -- * not NULL, use that user name, else the one from the handle. If -- * both the database and the user match the existing connection already, -- * nothing will be done. -- * -- * Returns 1 in any case. -+ * else the one associated with the archive handle. - */ --int --ReconnectToServer(ArchiveHandle *AH, const char *dbname, const char *username) --{ -- PGconn *newConn; -- const char *newdbname; -- const char *newusername; -- -- if (!dbname) -- newdbname = PQdb(AH->connection); -- else -- newdbname = dbname; -- -- if (!username) -- newusername = PQuser(AH->connection); -- else -- newusername = username; -- -- /* Let's see if the request is already satisfied */ -- if (strcmp(newdbname, PQdb(AH->connection)) == 0 && -- strcmp(newusername, PQuser(AH->connection)) == 0) -- return 1; -- -- newConn = _connectDB(AH, newdbname, newusername); -- -- /* Update ArchiveHandle's connCancel before closing old connection */ -- set_archive_cancel_info(AH, newConn); -- -- PQfinish(AH->connection); -- AH->connection = newConn; -- -- /* Start strict; later phases may override this. */ -- PQclear(ExecuteSqlQueryForSingleRow((Archive *) AH, -- ALWAYS_SECURE_SEARCH_PATH_SQL)); -- -- return 1; --} -- --/* -- * Connect to the db again. -- * -- * Note: it's not really all that sensible to use a single-entry password -- * cache if the username keeps changing. In current usage, however, the -- * username never does change, so one savedPassword is sufficient. We do -- * update the cache on the off chance that the password has changed since the -- * start of the run. -- */ --static PGconn * --_connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser) -+void -+ReconnectToServer(ArchiveHandle *AH, const char *dbname) - { -- PQExpBufferData connstr; -- PGconn *newConn; -- const char *newdb; -- const char *newuser; -- char *password; -- char passbuf[100]; -- bool new_pass; -- -- if (!reqdb) -- newdb = PQdb(AH->connection); -- else -- newdb = reqdb; -- -- if (!requser || strlen(requser) == 0) -- newuser = PQuser(AH->connection); -- else -- newuser = requser; -- -- ahlog(AH, 1, "connecting to database \"%s\" as user \"%s\"\n", -- newdb, newuser); -- -- password = AH->savedPassword; -- -- if (AH->promptPassword == TRI_YES && password == NULL) -- { -- simple_prompt("Password: ", passbuf, sizeof(passbuf), false); -- password = passbuf; -- } -- -- initPQExpBuffer(&connstr); -- appendPQExpBuffer(&connstr, "dbname="); -- appendConnStrVal(&connstr, newdb); -- -- do -- { -- const char *keywords[7]; -- const char *values[7]; -- -- keywords[0] = "host"; -- values[0] = PQhost(AH->connection); -- keywords[1] = "port"; -- values[1] = PQport(AH->connection); -- keywords[2] = "user"; -- values[2] = newuser; -- keywords[3] = "password"; -- values[3] = password; -- keywords[4] = "dbname"; -- values[4] = connstr.data; -- keywords[5] = "fallback_application_name"; -- values[5] = progname; -- keywords[6] = NULL; -- values[6] = NULL; -- -- new_pass = false; -- newConn = PQconnectdbParams(keywords, values, true); -- -- if (!newConn) -- exit_horribly(modulename, "failed to reconnect to database\n"); -- -- if (PQstatus(newConn) == CONNECTION_BAD) -- { -- if (!PQconnectionNeedsPassword(newConn)) -- exit_horribly(modulename, "could not reconnect to database: %s", -- PQerrorMessage(newConn)); -- PQfinish(newConn); -- -- if (password) -- fprintf(stderr, "Password incorrect\n"); -- -- fprintf(stderr, "Connecting to %s as %s\n", -- newdb, newuser); -- -- if (AH->promptPassword != TRI_NO) -- { -- simple_prompt("Password: ", passbuf, sizeof(passbuf), false); -- password = passbuf; -- } -- else -- exit_horribly(modulename, "connection needs password\n"); -- -- new_pass = true; -- } -- } while (new_pass); -+ PGconn *oldConn = AH->connection; -+ RestoreOptions *ropt = AH->public.ropt; - - /* -- * We want to remember connection's actual password, whether or not we got -- * it by prompting. So we don't just store the password variable. -+ * Save the dbname, if given, in override_dbname so that it will also -+ * affect any later reconnection attempt. - */ -- if (PQconnectionUsedPassword(newConn)) -- { -- if (AH->savedPassword) -- free(AH->savedPassword); -- AH->savedPassword = pg_strdup(PQpass(newConn)); -- } -+ if (dbname) -+ ropt->cparams.override_dbname = pg_strdup(dbname); - -- termPQExpBuffer(&connstr); -- -- /* check for version mismatch */ -- _check_database_version(AH); -+ /* -+ * Note: we want to establish the new connection, and in particular update -+ * ArchiveHandle's connCancel, before closing old connection. Otherwise -+ * an ill-timed SIGINT could try to access a dead connection. -+ */ -+ AH->connection = NULL; /* dodge error check in ConnectDatabase */ - -- PQsetNoticeProcessor(newConn, notice_processor, NULL); -+ ConnectDatabase((Archive *) AH, &ropt->cparams, true); - -- return newConn; -+ PQfinish(oldConn); - } - -- - /* -- * Make a database connection with the given parameters. The -- * connection handle is returned, the parameters are stored in AHX. -- * An interactive password prompt is automatically issued if required. -+ * Make, or remake, a database connection with the given parameters. -+ * -+ * The resulting connection handle is stored in AHX->connection. - * -+ * An interactive password prompt is automatically issued if required. -+ * We store the results of that in AHX->savedPassword. - * Note: it's not really all that sensible to use a single-entry password - * cache if the username keeps changing. In current usage, however, the - * username never does change, so one savedPassword is sufficient. - */ - void - ConnectDatabase(Archive *AHX, -- const char *dbname, -- const char *pghost, -- const char *pgport, -- const char *username, -- trivalue prompt_password) -+ const ConnParams *cparams, -+ bool isReconnect) - { - ArchiveHandle *AH = (ArchiveHandle *) AHX; -+ trivalue prompt_password; - char *password; - char passbuf[100]; - bool new_pass; -@@ -263,6 +127,9 @@ ConnectDatabase(Archive *AHX, - if (AH->connection) - exit_horribly(modulename, "already connected to a database\n"); - -+ /* Never prompt for a password during a reconnection */ -+ prompt_password = isReconnect ? TRI_NO : cparams->promptPassword; -+ - password = AH->savedPassword; - - if (prompt_password == TRI_YES && password == NULL) -@@ -270,7 +137,6 @@ ConnectDatabase(Archive *AHX, - simple_prompt("Password: ", passbuf, sizeof(passbuf), false); - password = passbuf; - } -- AH->promptPassword = prompt_password; - - /* - * Start the connection. Loop until we have a password if requested by -@@ -278,23 +144,35 @@ ConnectDatabase(Archive *AHX, - */ - do - { -- const char *keywords[7]; -- const char *values[7]; -- -- keywords[0] = "host"; -- values[0] = pghost; -- keywords[1] = "port"; -- values[1] = pgport; -- keywords[2] = "user"; -- values[2] = username; -- keywords[3] = "password"; -- values[3] = password; -- keywords[4] = "dbname"; -- values[4] = dbname; -- keywords[5] = "fallback_application_name"; -- values[5] = progname; -- keywords[6] = NULL; -- values[6] = NULL; -+ const char *keywords[8]; -+ const char *values[8]; -+ int i = 0; -+ -+ /* -+ * If dbname is a connstring, its entries can override the other -+ * values obtained from cparams; but in turn, override_dbname can -+ * override the dbname component of it. -+ */ -+ keywords[i] = "host"; -+ values[i++] = cparams->pghost; -+ keywords[i] = "port"; -+ values[i++] = cparams->pgport; -+ keywords[i] = "user"; -+ values[i++] = cparams->username; -+ keywords[i] = "password"; -+ values[i++] = password; -+ keywords[i] = "dbname"; -+ values[i++] = cparams->dbname; -+ if (cparams->override_dbname) -+ { -+ keywords[i] = "dbname"; -+ values[i++] = cparams->override_dbname; -+ } -+ keywords[i] = "fallback_application_name"; -+ values[i++] = progname; -+ keywords[i] = NULL; -+ values[i++] = NULL; -+ Assert(i <= lengthof(keywords)); - - new_pass = false; - AH->connection = PQconnectdbParams(keywords, values, true); -@@ -316,9 +194,16 @@ ConnectDatabase(Archive *AHX, - - /* check to see that the backend connection was successfully made */ - if (PQstatus(AH->connection) == CONNECTION_BAD) -- exit_horribly(modulename, "connection to database \"%s\" failed: %s", -- PQdb(AH->connection) ? PQdb(AH->connection) : "", -- PQerrorMessage(AH->connection)); -+ { -+ if (isReconnect) -+ exit_horribly(modulename, "reconnection to database \"%s\" failed: %s", -+ PQdb(AH->connection) ? PQdb(AH->connection) : "", -+ PQerrorMessage(AH->connection)); -+ else -+ exit_horribly(modulename, "connection to database \"%s\" failed: %s", -+ PQdb(AH->connection) ? PQdb(AH->connection) : "", -+ PQerrorMessage(AH->connection)); -+ } - - /* Start strict; later phases may override this. */ - PQclear(ExecuteSqlQueryForSingleRow((Archive *) AH, -diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c -index 8080155a95..abcee89d10 100644 ---- a/src/bin/pg_dump/pg_dump.c -+++ b/src/bin/pg_dump/pg_dump.c -@@ -302,7 +302,6 @@ main(int argc, char **argv) - const char *dumpsnapshot = NULL; - char *use_role = NULL; - int numWorkers = 1; -- trivalue prompt_password = TRI_DEFAULT; - int compressLevel = -1; - int plainText = 0; - ArchiveFormat archiveFormat = archUnknown; -@@ -431,7 +430,7 @@ main(int argc, char **argv) - break; - - case 'd': /* database name */ -- dopt.dbname = pg_strdup(optarg); -+ dopt.cparams.dbname = pg_strdup(optarg); - break; - - case 'E': /* Dump encoding */ -@@ -447,7 +446,7 @@ main(int argc, char **argv) - break; - - case 'h': /* server host */ -- dopt.pghost = pg_strdup(optarg); -+ dopt.cparams.pghost = pg_strdup(optarg); - break; - - case 'j': /* number of dump jobs */ -@@ -472,7 +471,7 @@ main(int argc, char **argv) - break; - - case 'p': /* server port */ -- dopt.pgport = pg_strdup(optarg); -+ dopt.cparams.pgport = pg_strdup(optarg); - break; - - case 'R': -@@ -497,7 +496,7 @@ main(int argc, char **argv) - break; - - case 'U': -- dopt.username = pg_strdup(optarg); -+ dopt.cparams.username = pg_strdup(optarg); - break; - - case 'v': /* verbose */ -@@ -505,11 +504,11 @@ main(int argc, char **argv) - break; - - case 'w': -- prompt_password = TRI_NO; -+ dopt.cparams.promptPassword = TRI_NO; - break; - - case 'W': -- prompt_password = TRI_YES; -+ dopt.cparams.promptPassword = TRI_YES; - break; - - case 'x': /* skip ACL dump */ -@@ -563,8 +562,8 @@ main(int argc, char **argv) - * Non-option argument specifies database name as long as it wasn't - * already specified with -d / --dbname - */ -- if (optind < argc && dopt.dbname == NULL) -- dopt.dbname = argv[optind++]; -+ if (optind < argc && dopt.cparams.dbname == NULL) -+ dopt.cparams.dbname = argv[optind++]; - - /* Complain if any arguments remain */ - if (optind < argc) -@@ -677,7 +676,7 @@ main(int argc, char **argv) - * Open the database using the Archiver, so it knows about it. Errors mean - * death. - */ -- ConnectDatabase(fout, dopt.dbname, dopt.pghost, dopt.pgport, dopt.username, prompt_password); -+ ConnectDatabase(fout, &dopt.cparams, false); - setup_connection(fout, dumpencoding, dumpsnapshot, use_role); - - /* -@@ -860,6 +859,11 @@ main(int argc, char **argv) - ropt->filename = filename; - - /* if you change this list, see dumpOptionsFromRestoreOptions */ -+ ropt->cparams.dbname = dopt.cparams.dbname ? pg_strdup(dopt.cparams.dbname) : NULL; -+ ropt->cparams.pgport = dopt.cparams.pgport ? pg_strdup(dopt.cparams.pgport) : NULL; -+ ropt->cparams.pghost = dopt.cparams.pghost ? pg_strdup(dopt.cparams.pghost) : NULL; -+ ropt->cparams.username = dopt.cparams.username ? pg_strdup(dopt.cparams.username) : NULL; -+ ropt->cparams.promptPassword = dopt.cparams.promptPassword; - ropt->dropSchema = dopt.outputClean; - ropt->dataOnly = dopt.dataOnly; - ropt->schemaOnly = dopt.schemaOnly; -diff --git a/src/bin/pg_dump/pg_restore.c b/src/bin/pg_dump/pg_restore.c -index 860a211a3c..ce03ded8ec 100644 ---- a/src/bin/pg_dump/pg_restore.c -+++ b/src/bin/pg_dump/pg_restore.c -@@ -163,7 +163,7 @@ main(int argc, char **argv) - opts->createDB = 1; - break; - case 'd': -- opts->dbname = pg_strdup(optarg); -+ opts->cparams.dbname = pg_strdup(optarg); - break; - case 'e': - opts->exit_on_error = true; -@@ -177,7 +177,7 @@ main(int argc, char **argv) - break; - case 'h': - if (strlen(optarg) != 0) -- opts->pghost = pg_strdup(optarg); -+ opts->cparams.pghost = pg_strdup(optarg); - break; - - case 'j': /* number of restore jobs */ -@@ -206,7 +206,7 @@ main(int argc, char **argv) - - case 'p': - if (strlen(optarg) != 0) -- opts->pgport = pg_strdup(optarg); -+ opts->cparams.pgport = pg_strdup(optarg); - break; - case 'R': - /* no-op, still accepted for backwards compatibility */ -@@ -240,7 +240,7 @@ main(int argc, char **argv) - break; - - case 'U': -- opts->username = pg_strdup(optarg); -+ opts->cparams.username = pg_strdup(optarg); - break; - - case 'v': /* verbose */ -@@ -248,11 +248,11 @@ main(int argc, char **argv) - break; - - case 'w': -- opts->promptPassword = TRI_NO; -+ opts->cparams.promptPassword = TRI_NO; - break; - - case 'W': -- opts->promptPassword = TRI_YES; -+ opts->cparams.promptPassword = TRI_YES; - break; - - case 'x': /* skip ACL dump */ -@@ -302,7 +302,7 @@ main(int argc, char **argv) - } - - /* Should get at most one of -d and -f, else user is confused */ -- if (opts->dbname) -+ if (opts->cparams.dbname) - { - if (opts->filename) - { --- -2.23.0 - diff --git a/CVE-2020-25695.patch b/CVE-2020-25695.patch deleted file mode 100644 index 6fd067c98fc276eb2ec916aaeab2c8b2ce350167..0000000000000000000000000000000000000000 --- a/CVE-2020-25695.patch +++ /dev/null @@ -1,241 +0,0 @@ -From f97ecea1ed7b09c6f1398540a1d72a57eee70c9f Mon Sep 17 00:00:00 2001 -From: Noah Misch -Date: Mon, 9 Nov 2020 07:32:09 -0800 -Subject: [PATCH] In security-restricted operations, block enqueue of at-commit - user code. - -Specifically, this blocks DECLARE ... WITH HOLD and firing of deferred -triggers within index expressions and materialized view queries. An -attacker having permission to create non-temp objects in at least one -schema could execute arbitrary SQL functions under the identity of the -bootstrap superuser. One can work around the vulnerability by disabling -autovacuum and not manually running ANALYZE, CLUSTER, REINDEX, CREATE -INDEX, VACUUM FULL, or REFRESH MATERIALIZED VIEW. (Don't restore from -pg_dump, since it runs some of those commands.) Plain VACUUM (without -FULL) is safe, and all commands are fine when a trusted user owns the -target object. Performance may degrade quickly under this workaround, -however. Back-patch to 9.5 (all supported versions). - -Reviewed by Robert Haas. Reported by Etienne Stalmans. - -Security: CVE-2020-25695 ---- - contrib/postgres_fdw/connection.c | 4 +++ - src/backend/access/transam/xact.c | 13 ++++---- - src/backend/commands/portalcmds.c | 5 +++ - src/backend/commands/trigger.c | 12 +++++++ - src/test/regress/expected/privileges.out | 42 ++++++++++++++++++++++++ - src/test/regress/sql/privileges.sql | 34 +++++++++++++++++++ - 6 files changed, 104 insertions(+), 6 deletions(-) - -diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c -index 885bd075798c..5dcff3d07624 100644 ---- a/contrib/postgres_fdw/connection.c -+++ b/contrib/postgres_fdw/connection.c -@@ -645,6 +645,10 @@ pgfdw_report_error(int elevel, PGresult *res, PGconn *conn, - - /* - * pgfdw_xact_callback --- cleanup at main-transaction end. -+ * -+ * This runs just late enough that it must not enter user-defined code -+ * locally. (Entering such code on the remote side is fine. Its remote -+ * COMMIT TRANSACTION may run deferred triggers.) - */ - static void - pgfdw_xact_callback(XactEvent event, void *arg) -diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c -index 37f31a2c31ea..00cec50e8402 100644 ---- a/src/backend/access/transam/xact.c -+++ b/src/backend/access/transam/xact.c -@@ -1994,9 +1994,10 @@ CommitTransaction(void) - - /* - * Do pre-commit processing that involves calling user-defined code, such -- * as triggers. Since closing cursors could queue trigger actions, -- * triggers could open cursors, etc, we have to keep looping until there's -- * nothing left to do. -+ * as triggers. SECURITY_RESTRICTED_OPERATION contexts must not queue an -+ * action that would run here, because that would bypass the sandbox. -+ * Since closing cursors could queue trigger actions, triggers could open -+ * cursors, etc, we have to keep looping until there's nothing left to do. - */ - for (;;) - { -@@ -2014,9 +2015,6 @@ CommitTransaction(void) - break; - } - -- CallXactCallbacks(is_parallel_worker ? XACT_EVENT_PARALLEL_PRE_COMMIT -- : XACT_EVENT_PRE_COMMIT); -- - /* - * The remaining actions cannot call any user-defined code, so it's safe - * to start shutting down within-transaction services. But note that most -@@ -2024,6 +2022,9 @@ CommitTransaction(void) - * the transaction-abort path. - */ - -+ CallXactCallbacks(is_parallel_worker ? XACT_EVENT_PARALLEL_PRE_COMMIT -+ : XACT_EVENT_PRE_COMMIT); -+ - /* If we might have parallel workers, clean them up now. */ - if (IsInParallelMode()) - AtEOXact_Parallel(true); -diff --git a/src/backend/commands/portalcmds.c b/src/backend/commands/portalcmds.c -index 46369cf3dbee..3d01a782da06 100644 ---- a/src/backend/commands/portalcmds.c -+++ b/src/backend/commands/portalcmds.c -@@ -27,6 +27,7 @@ - #include "commands/portalcmds.h" - #include "executor/executor.h" - #include "executor/tstoreReceiver.h" -+#include "miscadmin.h" - #include "rewrite/rewriteHandler.h" - #include "tcop/pquery.h" - #include "tcop/tcopprot.h" -@@ -64,6 +65,10 @@ PerformCursorOpen(DeclareCursorStmt *cstmt, ParamListInfo params, - */ - if (!(cstmt->options & CURSOR_OPT_HOLD)) - RequireTransactionChain(isTopLevel, "DECLARE CURSOR"); -+ else if (InSecurityRestrictedOperation()) -+ ereport(ERROR, -+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), -+ errmsg("cannot create a cursor WITH HOLD within security-restricted operation"))); - - /* - * Parse analysis was done already, but we still have to run the rule -diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c -index f83840625348..9c04eee48422 100644 ---- a/src/backend/commands/trigger.c -+++ b/src/backend/commands/trigger.c -@@ -4144,6 +4144,7 @@ afterTriggerMarkEvents(AfterTriggerEventList *events, - bool immediate_only) - { - bool found = false; -+ bool deferred_found = false; - AfterTriggerEvent event; - AfterTriggerEventChunk *chunk; - -@@ -4179,6 +4180,7 @@ afterTriggerMarkEvents(AfterTriggerEventList *events, - */ - if (defer_it && move_list != NULL) - { -+ deferred_found = true; - /* add it to move_list */ - afterTriggerAddEvent(move_list, event, evtshared); - /* mark original copy "done" so we don't do it again */ -@@ -4186,6 +4188,16 @@ afterTriggerMarkEvents(AfterTriggerEventList *events, - } - } - -+ /* -+ * We could allow deferred triggers if, before the end of the -+ * security-restricted operation, we were to verify that a SET CONSTRAINTS -+ * ... IMMEDIATE has fired all such triggers. For now, don't bother. -+ */ -+ if (deferred_found && InSecurityRestrictedOperation()) -+ ereport(ERROR, -+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), -+ errmsg("cannot fire deferred trigger within security-restricted operation"))); -+ - return found; - } - -diff --git a/src/test/regress/expected/privileges.out b/src/test/regress/expected/privileges.out -index dacc98450514..26ee16a0c370 100644 ---- a/src/test/regress/expected/privileges.out -+++ b/src/test/regress/expected/privileges.out -@@ -1253,6 +1253,48 @@ SELECT has_table_privilege('regress_user1', 'atest4', 'SELECT WITH GRANT OPTION' - t - (1 row) - -+-- security-restricted operations -+\c - -+CREATE ROLE regress_sro_user; -+SET SESSION AUTHORIZATION regress_sro_user; -+CREATE FUNCTION unwanted_grant() RETURNS void LANGUAGE sql AS -+ 'GRANT regress_group2 TO regress_sro_user'; -+CREATE FUNCTION mv_action() RETURNS bool LANGUAGE sql AS -+ 'DECLARE c CURSOR WITH HOLD FOR SELECT unwanted_grant(); SELECT true'; -+-- REFRESH of this MV will queue a GRANT at end of transaction -+CREATE MATERIALIZED VIEW sro_mv AS SELECT mv_action() WITH NO DATA; -+REFRESH MATERIALIZED VIEW sro_mv; -+ERROR: cannot create a cursor WITH HOLD within security-restricted operation -+CONTEXT: SQL function "mv_action" statement 1 -+\c - -+REFRESH MATERIALIZED VIEW sro_mv; -+ERROR: cannot create a cursor WITH HOLD within security-restricted operation -+CONTEXT: SQL function "mv_action" statement 1 -+SET SESSION AUTHORIZATION regress_sro_user; -+-- INSERT to this table will queue a GRANT at end of transaction -+CREATE TABLE sro_trojan_table (); -+CREATE FUNCTION sro_trojan() RETURNS trigger LANGUAGE plpgsql AS -+ 'BEGIN PERFORM unwanted_grant(); RETURN NULL; END'; -+CREATE CONSTRAINT TRIGGER t AFTER INSERT ON sro_trojan_table -+ INITIALLY DEFERRED FOR EACH ROW EXECUTE PROCEDURE sro_trojan(); -+-- Now, REFRESH will issue such an INSERT, queueing the GRANT -+CREATE OR REPLACE FUNCTION mv_action() RETURNS bool LANGUAGE sql AS -+ 'INSERT INTO sro_trojan_table DEFAULT VALUES; SELECT true'; -+REFRESH MATERIALIZED VIEW sro_mv; -+ERROR: cannot fire deferred trigger within security-restricted operation -+CONTEXT: SQL function "mv_action" statement 1 -+\c - -+REFRESH MATERIALIZED VIEW sro_mv; -+ERROR: cannot fire deferred trigger within security-restricted operation -+CONTEXT: SQL function "mv_action" statement 1 -+BEGIN; SET CONSTRAINTS ALL IMMEDIATE; REFRESH MATERIALIZED VIEW sro_mv; COMMIT; -+ERROR: must have admin option on role "regress_group2" -+CONTEXT: SQL function "unwanted_grant" statement 1 -+SQL statement "SELECT unwanted_grant()" -+PL/pgSQL function sro_trojan() line 1 at PERFORM -+SQL function "mv_action" statement 1 -+DROP OWNED BY regress_sro_user; -+DROP ROLE regress_sro_user; - -- Admin options - SET SESSION AUTHORIZATION regress_user4; - CREATE FUNCTION dogrant_ok() RETURNS void LANGUAGE sql SECURITY DEFINER AS -diff --git a/src/test/regress/sql/privileges.sql b/src/test/regress/sql/privileges.sql -index 4263315a2d87..f979cccea03f 100644 ---- a/src/test/regress/sql/privileges.sql -+++ b/src/test/regress/sql/privileges.sql -@@ -761,6 +761,40 @@ SELECT has_table_privilege('regress_user3', 'atest4', 'SELECT'); -- false - SELECT has_table_privilege('regress_user1', 'atest4', 'SELECT WITH GRANT OPTION'); -- true - - -+-- security-restricted operations -+\c - -+CREATE ROLE regress_sro_user; -+ -+SET SESSION AUTHORIZATION regress_sro_user; -+CREATE FUNCTION unwanted_grant() RETURNS void LANGUAGE sql AS -+ 'GRANT regress_group2 TO regress_sro_user'; -+CREATE FUNCTION mv_action() RETURNS bool LANGUAGE sql AS -+ 'DECLARE c CURSOR WITH HOLD FOR SELECT unwanted_grant(); SELECT true'; -+-- REFRESH of this MV will queue a GRANT at end of transaction -+CREATE MATERIALIZED VIEW sro_mv AS SELECT mv_action() WITH NO DATA; -+REFRESH MATERIALIZED VIEW sro_mv; -+\c - -+REFRESH MATERIALIZED VIEW sro_mv; -+ -+SET SESSION AUTHORIZATION regress_sro_user; -+-- INSERT to this table will queue a GRANT at end of transaction -+CREATE TABLE sro_trojan_table (); -+CREATE FUNCTION sro_trojan() RETURNS trigger LANGUAGE plpgsql AS -+ 'BEGIN PERFORM unwanted_grant(); RETURN NULL; END'; -+CREATE CONSTRAINT TRIGGER t AFTER INSERT ON sro_trojan_table -+ INITIALLY DEFERRED FOR EACH ROW EXECUTE PROCEDURE sro_trojan(); -+-- Now, REFRESH will issue such an INSERT, queueing the GRANT -+CREATE OR REPLACE FUNCTION mv_action() RETURNS bool LANGUAGE sql AS -+ 'INSERT INTO sro_trojan_table DEFAULT VALUES; SELECT true'; -+REFRESH MATERIALIZED VIEW sro_mv; -+\c - -+REFRESH MATERIALIZED VIEW sro_mv; -+BEGIN; SET CONSTRAINTS ALL IMMEDIATE; REFRESH MATERIALIZED VIEW sro_mv; COMMIT; -+ -+DROP OWNED BY regress_sro_user; -+DROP ROLE regress_sro_user; -+ -+ - -- Admin options - - SET SESSION AUTHORIZATION regress_user4; diff --git a/CVE-2020-25696.patch b/CVE-2020-25696.patch deleted file mode 100644 index 71c7e5431462b79bfe47eb189dd3f8ce3fb0fe8a..0000000000000000000000000000000000000000 --- a/CVE-2020-25696.patch +++ /dev/null @@ -1,121 +0,0 @@ -From a498db87be103f93856dd515a574b2d67d3c1237 Mon Sep 17 00:00:00 2001 -From: Noah Misch -Date: Mon, 9 Nov 2020 07:32:09 -0800 -Subject: [PATCH] Ignore attempts to \gset into specially treated variables. - -If an interactive psql session used \gset when querying a compromised -server, the attacker could execute arbitrary code as the operating -system account running psql. Using a prefix not found among specially -treated variables, e.g. every lowercase string, precluded the attack. -Fix by issuing a warning and setting no variable for the column in -question. Users wanting the old behavior can use a prefix and then a -meta-command like "\set HISTSIZE :prefix_HISTSIZE". Back-patch to 9.5 -(all supported versions). - -Reviewed by Robert Haas. Reported by Nick Cleaton. - -Security: CVE-2020-25696 ---- - src/bin/psql/common.c | 7 +++++++ - src/bin/psql/variables.c | 26 ++++++++++++++++++++++++++ - src/bin/psql/variables.h | 1 + - src/test/regress/expected/psql.out | 4 ++++ - src/test/regress/sql/psql.sql | 3 +++ - 5 files changed, 41 insertions(+) - -diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c -index d04a7943d6a9..4e342c180a6c 100644 ---- a/src/bin/psql/common.c -+++ b/src/bin/psql/common.c -@@ -894,6 +894,13 @@ StoreQueryTuple(const PGresult *result) - /* concatenate prefix and column name */ - varname = psprintf("%s%s", pset.gset_prefix, colname); - -+ if (VariableHasHook(pset.vars, varname)) -+ { -+ psql_error("attempt to \\gset into specially treated variable \"%s\" ignored\n", -+ varname); -+ continue; -+ } -+ - if (!PQgetisnull(result, 0, i)) - value = PQgetvalue(result, 0, i); - else -diff --git a/src/bin/psql/variables.c b/src/bin/psql/variables.c -index 120b25c69661..0d28ba9c92bb 100644 ---- a/src/bin/psql/variables.c -+++ b/src/bin/psql/variables.c -@@ -360,6 +360,32 @@ SetVariableHooks(VariableSpace space, const char *name, - (void) (*ahook) (current->value); - } - -+/* -+ * Return true iff the named variable has substitute and/or assign hook -+ * functions. -+ */ -+bool -+VariableHasHook(VariableSpace space, const char *name) -+{ -+ struct _variable *current; -+ -+ Assert(space); -+ Assert(name); -+ -+ for (current = space->next; current; current = current->next) -+ { -+ int cmp = strcmp(current->name, name); -+ -+ if (cmp == 0) -+ return (current->substitute_hook != NULL || -+ current->assign_hook != NULL); -+ if (cmp > 0) -+ break; /* it's not there */ -+ } -+ -+ return false; -+} -+ - /* - * Convenience function to set a variable's value to "on". - */ -diff --git a/src/bin/psql/variables.h b/src/bin/psql/variables.h -index 02d85b1bc2e4..8dc5c20ee8fc 100644 ---- a/src/bin/psql/variables.h -+++ b/src/bin/psql/variables.h -@@ -90,6 +90,7 @@ bool DeleteVariable(VariableSpace space, const char *name); - void SetVariableHooks(VariableSpace space, const char *name, - VariableSubstituteHook shook, - VariableAssignHook ahook); -+bool VariableHasHook(VariableSpace space, const char *name); - - void PsqlVarEnumError(const char *name, const char *value, const char *suggestions); - -diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out -index 0c94144575af..1ae81912c734 100644 ---- a/src/test/regress/expected/psql.out -+++ b/src/test/regress/expected/psql.out -@@ -84,6 +84,10 @@ select 10 as test01, 20 as test02, 'Hello' as test03 \gset pref01_ - select 10 as "bad name" - \gset - invalid variable name: "bad name" -+select 97 as "EOF", 'ok' as _foo \gset IGNORE -+attempt to \gset into specially treated variable "IGNOREEOF" ignored -+\echo :IGNORE_foo :IGNOREEOF -+ok 0 - -- multiple backslash commands in one line - select 1 as x, 2 as y \gset pref01_ \\ \echo :pref01_x - 1 -diff --git a/src/test/regress/sql/psql.sql b/src/test/regress/sql/psql.sql -index 4a676c311955..7f8ab2e5c218 100644 ---- a/src/test/regress/sql/psql.sql -+++ b/src/test/regress/sql/psql.sql -@@ -48,6 +48,9 @@ select 10 as test01, 20 as test02, 'Hello' as test03 \gset pref01_ - select 10 as "bad name" - \gset - -+select 97 as "EOF", 'ok' as _foo \gset IGNORE -+\echo :IGNORE_foo :IGNOREEOF -+ - -- multiple backslash commands in one line - select 1 as x, 2 as y \gset pref01_ \\ \echo :pref01_x - select 3 as x, 4 as y \gset pref01_ \echo :pref01_x \echo :pref01_y diff --git a/CVE-2021-20229.patch b/CVE-2021-20229.patch deleted file mode 100644 index 1c03e9db1e8c4d24fb9fcd66c7995d5612eac69d..0000000000000000000000000000000000000000 --- a/CVE-2021-20229.patch +++ /dev/null @@ -1,163 +0,0 @@ -From eeede2470a8ec902c80de449d2c4822330c689ca Mon Sep 17 00:00:00 2001 -From: wang_yue111 <648774160@qq.com> -Date: Fri, 26 Feb 2021 12:57:48 +0800 -Subject: [PATCH] Fix mishandling of column-level SELECT privileges for join - aliases. - -scanNSItemForColumn, expandNSItemAttrs, and ExpandSingleTable would -pass the wrong RTE to markVarForSelectPriv when dealing with a join -ParseNamespaceItem: they'd pass the join RTE, when what we need to -mark is the base table that the join column came from. The end -result was to not fill the base table's selectedCols bitmap correctly, -resulting in an understatement of the set of columns that are read -by the query. The executor would still insist on there being at -least one selectable column; but with a correctly crafted query, -a user having SELECT privilege on just one column of a table would -nonetheless be allowed to read all its columns. - -To fix, make markRTEForSelectPriv fetch the correct RTE for itself, -ignoring the possibly-mismatched RTE passed by the caller. Later, -we'll get rid of some now-unused RTE arguments, but that risks -API breaks so we won't do it in released branches. - -This problem was introduced by commit 9ce77d75c, so back-patch -to v13 where that came in. Thanks to Sven Klemm for reporting -the problem. - -Security: CVE-2021-20229 - ---- - src/backend/parser/parse_relation.c | 40 ++++++++++----------- - src/backend/parser/parse_target.c | 8 +++-- - 4 files changed, 91 insertions(+), 22 deletions(-) - -diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c -index bbbb0b6..7ab4ba7 100644 ---- a/src/backend/parser/parse_relation.c -+++ b/src/backend/parser/parse_relation.c -@@ -43,7 +43,8 @@ static RangeTblEntry *scanNameSpaceForRelid(ParseState *pstate, Oid relid, - int location); - static void check_lateral_ref_ok(ParseState *pstate, ParseNamespaceItem *nsitem, - int location); --static void markRTEForSelectPriv(ParseState *pstate, RangeTblEntry *rte, -+static void markRTEForSelectPriv(ParseState *pstate, -+ - int rtindex, AttrNumber col); - static void expandRelation(Oid relid, Alias *eref, - int rtindex, int sublevels_up, -@@ -897,20 +898,15 @@ searchRangeTableForCol(ParseState *pstate, const char *alias, char *colname, - - /* - * markRTEForSelectPriv -- * Mark the specified column of an RTE as requiring SELECT privilege -+ * Mark the specified column of the RTE with index rtindex -+ * as requiring SELECT privilege - * - * col == InvalidAttrNumber means a "whole row" reference -- * -- * The caller should pass the actual RTE if it has it handy; otherwise pass -- * NULL, and we'll look it up here. (This uglification of the API is -- * worthwhile because nearly all external callers have the RTE at hand.) - */ - static void --markRTEForSelectPriv(ParseState *pstate, RangeTblEntry *rte, -- int rtindex, AttrNumber col) -+markRTEForSelectPriv(ParseState *pstate, int rtindex, AttrNumber col) - { -- if (rte == NULL) -- rte = rt_fetch(rtindex, pstate->p_rtable); -+ RangeTblEntry *rte = rt_fetch(rtindex, pstate->p_rtable); - - if (rte->rtekind == RTE_RELATION) - { -@@ -942,13 +938,13 @@ markRTEForSelectPriv(ParseState *pstate, RangeTblEntry *rte, - { - int varno = ((RangeTblRef *) j->larg)->rtindex; - -- markRTEForSelectPriv(pstate, NULL, varno, InvalidAttrNumber); -+ markRTEForSelectPriv(pstate, varno, InvalidAttrNumber); - } - else if (IsA(j->larg, JoinExpr)) - { - int varno = ((JoinExpr *) j->larg)->rtindex; - -- markRTEForSelectPriv(pstate, NULL, varno, InvalidAttrNumber); -+ markRTEForSelectPriv(pstate, varno, InvalidAttrNumber); - } - else - elog(ERROR, "unrecognized node type: %d", -@@ -957,13 +953,13 @@ markRTEForSelectPriv(ParseState *pstate, RangeTblEntry *rte, - { - int varno = ((RangeTblRef *) j->rarg)->rtindex; - -- markRTEForSelectPriv(pstate, NULL, varno, InvalidAttrNumber); -+ markRTEForSelectPriv(pstate, varno, InvalidAttrNumber); - } - else if (IsA(j->rarg, JoinExpr)) - { - int varno = ((JoinExpr *) j->rarg)->rtindex; - -- markRTEForSelectPriv(pstate, NULL, varno, InvalidAttrNumber); -+ markRTEForSelectPriv(pstate, varno, InvalidAttrNumber); - } - else - elog(ERROR, "unrecognized node type: %d", -@@ -994,10 +990,10 @@ markRTEForSelectPriv(ParseState *pstate, RangeTblEntry *rte, - - /* - * markVarForSelectPriv -- * Mark the RTE referenced by a Var as requiring SELECT privilege -+ * Mark the RTE referenced by the Var as requiring SELECT privilege -+ * for the Var's column (the Var could be a whole-row Var, too) - * -- * The caller should pass the Var's referenced RTE if it has it handy -- * (nearly all do); otherwise pass NULL. -+ * The rte argument is unused and will be removed later. - */ - void - markVarForSelectPriv(ParseState *pstate, Var *var, RangeTblEntry *rte) -@@ -1008,7 +1004,7 @@ markVarForSelectPriv(ParseState *pstate, Var *var, RangeTblEntry *rte) - /* Find the appropriate pstate if it's an uplevel Var */ - for (lv = 0; lv < var->varlevelsup; lv++) - pstate = pstate->parentParseState; -- markRTEForSelectPriv(pstate, rte, var->varno, var->varattno); -+ markRTEForSelectPriv(pstate, var->varno, var->varattno); - } - - /* -@@ -2629,9 +2625,13 @@ expandRelAttrs(ParseState *pstate, RangeTblEntry *rte, - /* - * Require read access to the table. This is normally redundant with the - * markVarForSelectPriv calls below, but not if the table has zero -- * columns. -+ * columns. We need not do anything if the nsitem is for a join: its -+ * component tables will have been marked ACL_SELECT when they were added -+ * to the rangetable. (This step changes things only for the target -+ * relation of UPDATE/DELETE, which cannot be under a join.) - */ -- rte->requiredPerms |= ACL_SELECT; -+ if (rte->rtekind == RTE_RELATION) -+ rte->requiredPerms |= ACL_SELECT; - - forboth(name, names, var, vars) - { -diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c -index 64a1b75..c7165cb 100644 ---- a/src/backend/parser/parse_target.c -+++ b/src/backend/parser/parse_target.c -@@ -1328,9 +1328,13 @@ ExpandSingleTable(ParseState *pstate, RangeTblEntry *rte, - /* - * Require read access to the table. This is normally redundant with - * the markVarForSelectPriv calls below, but not if the table has zero -- * columns. -+ * columns. We need not do anything if the nsitem is for a join: its -+ * component tables will have been marked ACL_SELECT when they were -+ * added to the rangetable. (This step changes things only for the -+ * target relation of UPDATE/DELETE, which cannot be under a join.) - */ -- rte->requiredPerms |= ACL_SELECT; -+ if (rte->rtekind == RTE_RELATION) -+ rte->requiredPerms |= ACL_SELECT; - - /* Require read access to each column */ - foreach(l, vars) diff --git a/Fix-error-handling-of-vacuumdb-when-running-out-of-f.patch b/Fix-error-handling-of-vacuumdb-when-running-out-of-f.patch deleted file mode 100644 index 23dda246d01833ddf527fb91a7af9319ad81a16c..0000000000000000000000000000000000000000 --- a/Fix-error-handling-of-vacuumdb-when-running-out-of-f.patch +++ /dev/null @@ -1,70 +0,0 @@ -From eec462367ee2b41e02c6e29135c857ad6f2da66a Mon Sep 17 00:00:00 2001 -From: Michael Paquier -Date: Mon, 26 Aug 2019 11:14:33 +0900 -Subject: [PATCH] Fix error handling of vacuumdb when running out of fds -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -When trying to use a high number of jobs, vacuumdb has only checked for -a maximum number of jobs used, causing confusing failures when running -out of file descriptors when the jobs open connections to Postgres. -This commit changes the error handling so as we do not check anymore for -a maximum number of allowed jobs when parsing the option value with -FD_SETSIZE, but check instead if a file descriptor is within the -supported range when opening the connections for the jobs so as this is -detected at the earliest time possible. - -Also, improve the error message to give a hint about the number of jobs -recommended, using a wording given by the reviewers of the patch. - -Reported-by: Andres Freund -Author: Michael Paquier -Reviewed-by: Andres Freund, Álvaro Herrera, Tom Lane -Discussion: https://postgr.es/m/20190818001858.ho3ev4z57fqhs7a5@alap3.anarazel.de -Backpatch-through: 9.5 ---- - src/bin/scripts/vacuumdb.c | 20 ++++++++++++++------ - 1 file changed, 14 insertions(+), 6 deletions(-) - -diff --git a/src/bin/scripts/vacuumdb.c b/src/bin/scripts/vacuumdb.c -index f888bf73bc..4ac765244a 100644 ---- a/src/bin/scripts/vacuumdb.c -+++ b/src/bin/scripts/vacuumdb.c -@@ -200,12 +200,6 @@ main(int argc, char *argv[]) - progname); - exit(1); - } -- if (concurrentCons > FD_SETSIZE - 1) -- { -- fprintf(stderr, _("%s: too many parallel jobs requested (maximum: %d)\n"), -- progname, FD_SETSIZE - 1); -- exit(1); -- } - break; - case 2: - maintenance_db = pg_strdup(optarg); -@@ -443,6 +437,20 @@ vacuum_one_database(const char *dbname, vacuumingOptions *vacopts, - { - conn = connectDatabase(dbname, host, port, username, prompt_password, - progname, echo, false, true); -+ -+ /* -+ * Fail and exit immediately if trying to use a socket in an -+ * unsupported range. POSIX requires open(2) to use the lowest -+ * unused file descriptor and the hint given relies on that. -+ */ -+ if (PQsocket(conn) >= FD_SETSIZE) -+ { -+ fprintf(stderr, -+ _("%s: too many jobs for this platform -- try %d"), -+ progname, i); -+ exit(1); -+ } -+ - init_slot(slots + i, conn); - } - } --- -2.23.0 - diff --git a/Remove-some-code-related-to-7.3-and-older-servers-fr.patch b/Remove-some-code-related-to-7.3-and-older-servers-fr.patch deleted file mode 100644 index 6f7cdd562fa2bc931724ae40454592013a6f187f..0000000000000000000000000000000000000000 --- a/Remove-some-code-related-to-7.3-and-older-servers-fr.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 57ba539775f1dd0b0460f1dfe673da00eeef3a2f Mon Sep 17 00:00:00 2001 -From: Michael Paquier -Date: Tue, 7 May 2019 14:20:01 +0900 -Subject: [PATCH] Remove some code related to 7.3 and older servers from tools - of src/bin/ - -This code was broken as of 582edc3, and is most likely not used anymore. -Note that pg_dump supports servers down to 8.0, and psql has code to -support servers down to 7.4. - -Author: Julien Rouhaud -Reviewed-by: Tom Lane -Discussion: https://postgr.es/m/CAOBaU_Y5y=zo3+2gf+2NJC1pvMYPcbRXoQaPXx=U7+C8Qh4CzQ@mail.gmail.com ---- - src/bin/scripts/common.c | 12 ++---------- - 1 file changed, 2 insertions(+), 10 deletions(-) - -diff --git a/src/bin/scripts/common.c b/src/bin/scripts/common.c -index 8073ee0d0e..5088c4c48e 100644 ---- a/src/bin/scripts/common.c -+++ b/src/bin/scripts/common.c -@@ -145,9 +145,8 @@ connectDatabase(const char *dbname, const char *pghost, - exit(1); - } - -- if (PQserverVersion(conn) >= 70300) -- PQclear(executeQuery(conn, ALWAYS_SECURE_SEARCH_PATH_SQL, -- progname, echo)); -+ PQclear(executeQuery(conn, ALWAYS_SECURE_SEARCH_PATH_SQL, -+ progname, echo)); - - return conn; - } -@@ -311,13 +310,6 @@ appendQualifiedRelation(PQExpBuffer buf, const char *spec, - PGresult *res; - int ntups; - -- /* Before 7.3, the concept of qualifying a name did not exist. */ -- if (PQserverVersion(conn) < 70300) -- { -- appendPQExpBufferStr(&sql, spec); -- return; -- } -- - split_table_columns_spec(spec, PQclientEncoding(conn), &table, &columns); - - /* --- -2.23.0 - diff --git a/createdb-Fix-quoting-of-encoding-lc-ctype-and-lc-col.patch b/createdb-Fix-quoting-of-encoding-lc-ctype-and-lc-col.patch deleted file mode 100644 index cd03be23f8ea5993c10e3376e380ec5acc234e30..0000000000000000000000000000000000000000 --- a/createdb-Fix-quoting-of-encoding-lc-ctype-and-lc-col.patch +++ /dev/null @@ -1,76 +0,0 @@ -From a1413123f80f470da1ec422592f228aebe4a8866 Mon Sep 17 00:00:00 2001 -From: Michael Paquier -Date: Thu, 27 Feb 2020 11:21:14 +0900 -Subject: [PATCH 1/2] createdb: Fix quoting of --encoding, --lc-ctype and - --lc-collate - -The original coding failed to properly quote those arguments, leading to -failures when using quotes in the values used. As the quoting can be -encoding-sensitive, the connection to the backend needs to be taken -before applying the correct quoting. - -Author: Michael Paquier -Reviewed-by: Daniel Gustafsson -Discussion: https://postgr.es/m/20200214041004.GB1998@paquier.xyz -Backpatch-through: 9.5 ---- - src/bin/scripts/createdb.c | 29 +++++++++++++++++++---------- - 1 file changed, 19 insertions(+), 10 deletions(-) - -diff --git a/src/bin/scripts/createdb.c b/src/bin/scripts/createdb.c -index 8116b084ff..45d26ecb8c 100644 ---- a/src/bin/scripts/createdb.c -+++ b/src/bin/scripts/createdb.c -@@ -177,6 +177,13 @@ main(int argc, char *argv[]) - dbname = get_user_name_or_exit(progname); - } - -+ /* No point in trying to use postgres db when creating postgres db. */ -+ if (maintenance_db == NULL && strcmp(dbname, "postgres") == 0) -+ maintenance_db = "template1"; -+ -+ conn = connectMaintenanceDatabase(maintenance_db, host, port, username, -+ prompt_password, progname, echo); -+ - initPQExpBuffer(&sql); - - appendPQExpBuffer(&sql, "CREATE DATABASE %s", -@@ -187,23 +194,25 @@ main(int argc, char *argv[]) - if (tablespace) - appendPQExpBuffer(&sql, " TABLESPACE %s", fmtId(tablespace)); - if (encoding) -- appendPQExpBuffer(&sql, " ENCODING '%s'", encoding); -+ { -+ appendPQExpBufferStr(&sql, " ENCODING "); -+ appendStringLiteralConn(&sql, encoding, conn); -+ } - if (template) - appendPQExpBuffer(&sql, " TEMPLATE %s", fmtId(template)); - if (lc_collate) -- appendPQExpBuffer(&sql, " LC_COLLATE '%s'", lc_collate); -+ { -+ appendPQExpBufferStr(&sql, " LC_COLLATE "); -+ appendStringLiteralConn(&sql, lc_collate, conn); -+ } - if (lc_ctype) -- appendPQExpBuffer(&sql, " LC_CTYPE '%s'", lc_ctype); -+ { -+ appendPQExpBufferStr(&sql, " LC_CTYPE "); -+ appendStringLiteralConn(&sql, lc_ctype, conn); -+ } - - appendPQExpBufferChar(&sql, ';'); - -- /* No point in trying to use postgres db when creating postgres db. */ -- if (maintenance_db == NULL && strcmp(dbname, "postgres") == 0) -- maintenance_db = "template1"; -- -- conn = connectMaintenanceDatabase(maintenance_db, host, port, username, -- prompt_password, progname, echo); -- - if (echo) - printf("%s\n", sql.data); - result = PQexec(conn, sql.data); --- -2.23.0 - diff --git a/library.sh b/library.sh deleted file mode 100644 index 02d067ac2d1a88fd6b83c9c114c8918aed973e1a..0000000000000000000000000000000000000000 --- a/library.sh +++ /dev/null @@ -1,62 +0,0 @@ -die() { echo >&2 $"FATAL: $@" ; exit 1 ; } -error() { echo >&2 $"ERROR: $@" ; } -error_q() { echo >&2 $" $@" ; } -warn() { echo >&2 $"WARNING: $@" ; } -warn_q() { echo >&2 $" $@" ; } -info() { echo >&2 $" * $@" ; } -info_q() { echo >&2 $" $@" ; } -debug() { test "$option_debug" != "1" || echo >&2 $"DEBUG: $@"; } - - -set_var() -{ - eval "$1=\"$2\"" -} - - -root_prereq() -{ - test -z "$PGSETUP_TEST" || return 0 - test "$(id -u)" -eq 0 || die "$0 requires root access for this action" -} - - -read_config_file() -{ - local key="" val="" - - test -r "$1" || die "can't read file '$1'" - - for i in $2; do - eval "unset __pg_conf_$i" - done - - # No easy (and secure) way to read configuration files from bash script, - # sorry. - while read key val; do - [[ $key =~ ^[a-zA-Z_][a-zA-Z0-9_]*$ ]] || return 1 - - case " $2 " in - *" $key "*) - ;; - *) - warn "config file '$1': unknown key '$key'" - continue - ;; - esac - - # Strip double quotes - case "$val" in - \"*\") - val=${val##\"} - val=${val%%\"} - ;; - esac - - # Make it reasonably safe. Keep dolar-sign escaped. - eval "__pg_conf_$key=\$val" - - done < <(grep -v -e "^$" -e "^#" < "$1") -} - - diff --git a/macros.postgresql b/macros.postgresql deleted file mode 100644 index ff03dd8b5999de0d190b2909aa953532ea0bec76..0000000000000000000000000000000000000000 --- a/macros.postgresql +++ /dev/null @@ -1,9 +0,0 @@ -# Macros from this file should exist on system only once, so it package -# maintainer's responsibility to guarantee that all packages which install -# these macros collide, or that (during package-build time) only one such -# package is installed (e.g. similarly to %%scl macro defined installed by -# *-build subpackage). - -%postgresql_major 10 - -%postgresql_module_requires Requires: postgresql-server(:MODULE_COMPAT_10) diff --git a/macros.postgresql-test b/macros.postgresql-test deleted file mode 100644 index cad185da925a65b5212c28f26c7e4706667e9a58..0000000000000000000000000000000000000000 --- a/macros.postgresql-test +++ /dev/null @@ -1,18 +0,0 @@ -# Initialize the PostgreSQL tests environment. This is supposed to be invoked -# in prep/build/install (where you plan to run the testsuite), while it defines -# several useful shell variables and provies useful commands. Effect of this -# command end with shell exit. -%postgresql_tests_init . "/usr/share/postgresql-setup/postgresql_pkg_tests.sh" - -# Start the testing postgresql server, setting the actual unix user to be the -# PostgreSQL admin. The $PGHOST/$PGPORT are set appropriately, so psql is able -# to run without passwords. This also sets shell exit trap callback so that if -# something goes wrong and package build fails, the temporary database is -# automatically cleaned up. -%postgresql_tests_start pgtests_start - -# Initialize database and run server in one step, if this works well-enough. -%postgresql_tests_run %postgresql_tests_init ; %postgresql_tests_start - -%pgtests_init echo 2>&1 WARN: macro pgtests_init will be removed, use postgresql_tests_init ; %postgresql_tests_init -%pgtests_start echo 2>&1 WARN: macro pgtests_start will be removed, use postgresql_tests_start ; %postgresql_tests_start diff --git a/postgresql-10.5.tar.bz2.sha256 b/postgresql-10.5.tar.bz2.sha256 deleted file mode 100644 index 62d14ed18301dd265ca136e3ae87009744a8c957..0000000000000000000000000000000000000000 --- a/postgresql-10.5.tar.bz2.sha256 +++ /dev/null @@ -1 +0,0 @@ -6c8e616c91a45142b85c0aeb1f29ebba4a361309e86469e0fb4617b6a73c4011 postgresql-10.5.tar.bz2 diff --git a/postgresql-13-A4.pdf b/postgresql-13-A4.pdf new file mode 100644 index 0000000000000000000000000000000000000000..73fc93f7de96d555242a02adc357241ea347eb14 Binary files /dev/null and b/postgresql-13-A4.pdf differ diff --git a/postgresql-13-Makefile.regress b/postgresql-13-Makefile.regress new file mode 100644 index 0000000000000000000000000000000000000000..43c7ba446a48d619609ec588280d34e2de643121 --- /dev/null +++ b/postgresql-13-Makefile.regress @@ -0,0 +1,67 @@ +# +# Simplified makefile for running the PostgreSQL regression tests +# in an RPM installation +# + +# maximum simultaneous connections for parallel tests +MAXCONNOPT = +ifdef MAX_CONNECTIONS +MAXCONNOPT += --max-connections=$(MAX_CONNECTIONS) +endif + +# locale +NOLOCALE = +ifdef NO_LOCALE +NOLOCALE += --no-locale +endif + +srcdir := . + +REGRESS_OPTS += --dlpath=. + +pg_regress_locale_flags = $(if $(ENCODING),--encoding=$(ENCODING)) $(NOLOCALE) + +pg_regress_installcheck = ./pg_regress --inputdir=$(srcdir) --psqldir='/usr/bin' $(pg_regress_locale_flags) + +# Test input and expected files. These are created by pg_regress itself, so we +# don't have a rule to create them. We do need rules to clean them however. +ifile_list := $(subst .source,, $(notdir $(wildcard $(srcdir)/input/*.source))) +input_files := $(foreach file, $(ifile_list), sql/$(file).sql) +ofile_list := $(subst .source,, $(notdir $(wildcard $(srcdir)/output/*.source))) +output_files := $(foreach file, $(ofile_list), expected/$(file).out) + +abs_srcdir := $(shell pwd) +abs_builddir := $(shell pwd) + +check: installcheck-parallel + +installcheck: cleandirs + $(pg_regress_installcheck) $(REGRESS_OPTS) --schedule=$(srcdir)/serial_schedule $(EXTRA_TESTS) + +installcheck-parallel: cleandirs + $(pg_regress_installcheck) $(REGRESS_OPTS) --schedule=$(srcdir)/parallel_schedule $(MAXCONNOPT) $(EXTRA_TESTS) + +# The tests command the server to write into testtablespace and results. +# On a SELinux-enabled system this will fail unless we mark those directories +# as writable by the server. +cleandirs: + -rm -rf testtablespace results + mkdir testtablespace results + [ -x /usr/bin/chcon ] && /usr/bin/chcon -u system_u -r object_r -t postgresql_db_t testtablespace results + +# old interfaces follow... + +runcheck: check +runtest: installcheck +runtest-parallel: installcheck-parallel + + +## +## Clean up +## + +clean distclean maintainer-clean: + rm -f $(output_files) $(input_files) + rm -rf testtablespace + rm -rf results tmp_check log + rm -f regression.diffs regression.out regress.out run_check.out diff --git a/postgresql-13-README-systemd.rpm-dist b/postgresql-13-README-systemd.rpm-dist new file mode 100644 index 0000000000000000000000000000000000000000..be66ddaa93698c1f02b14ec9ff0039bdb4c4fe82 --- /dev/null +++ b/postgresql-13-README-systemd.rpm-dist @@ -0,0 +1,356 @@ +README.rpm-dist +----------------------------------------------------------------------------- +Version 13, for the PostgreSQL 13 RPM set. +Devrim Gündüz +----------------------------------------------------------------------------- + +Contents: + 1.) Introduction and QuickStart + 2.) Upgrading an installation + 3.) PostgreSQL RPM packages and rationale + 4.) Starting multiple postmasters + 5.) Regression Testing + 6.) Starting postmaster automatically on startup + 7.) Grand Unified Configuration(GUC) File + 8.) Logging set up + 9.) Rebuilding from the source RPM +10.) Contrib files +11.) Further Information Resource + +INTRODUCTION +----------------------------------------------------------------------------- +This document exists to explain the layout of the RPMs for PostgreSQL, to +describe various RPM specifics, and to document special features found +in the RPMset. + +This document is written to be applicable to version 13 of PostgreSQL, +which is the current version of the RPMs as of this writing. More to the +point, versions prior to 13 are not documented here. + +Official PostgreSQL Global Development Group RPMs carry a 'PGDG after the +release number. Other RPMsets as distributed with Linux distributions may +have a different release number and initials. + +If you want to stay up-to-date on the PostgreSQL core itself, you may +want to use PGDG set, instead of the binaries supplied by distribution. + +These RPMs do not support any sort of major version upgrading process +other than that documented in the regular documentation. That is, you +must dump, upgrade, initdb, and restore your data if you are +performing a major version update. This is not needed for minor version +updates. + +QUICKSTART (note that this requires postgresql13-server installed) +----------------------------------------------------------------------------- +For a fresh installation, you will need to initialize the cluster first. Run: + + /usr/pgsql-13/bin/postgresql-13-setup initdb + +as root, and it will prepare a new database cluster for you. Then you will +need to start PostgreSQL. Again as root, run: + + systemctl start postgresql-13.service + +You will probably also want to do + + systemctl enable postgresql-13.service + +so that the postmaster is automatically started during future reboots. + +These commands will start a postmaster that will listen on localhost and Unix +socket 5432 only. Edit /var/lib/pgsql/13/data/postgresql.conf and pg_hba.conf +if you want to allow remote access -- see the section on Grand Unified +Configuration. + +The file /var/lib/pgsql/13/.bash_profile is packaged to help with the +setting of environment variables. Users should not edit this file, because +it may be overwritten during every new installation. However, you can create +~/.pgsql_profile file, and add your customizations there. + +The user 'postgres' is created during installation of the server subpackage. +This user by default is UID and GID 26. The user has the default shell set to +bash, and the home directory set to /var/lib/pgsql. This user also has no +default password. If you want to be able to su to it from a non-root account +or login as 'postgres' you will need to set a password using passwd. + +In the default installation, only postgres user is allowed to access to +the database server, because initdb in the RPMs pick up "peer" auth +method in the RPMs. + +All the binaries are installed under /usr/pgsql-13/bin. However, the +tools that are compatible with the previous releases are symlinked under +/usr/bin directory. Please note that RPMs are using alternatives method +in here, so whenever a newer major version is installed, symlinks will +point to the new version. Here is the current list of the binaries that +are under $PATH: + +- clusterdb +- createdb +- createuser +- dropdb +- dropuser +- pg_basebackup +- pg_dump +- pg_dumpall +- pg_restore +- psql +- reindexdb +- vacuumdb + +You may want to add /usr/pgsql-13/bin to your $PATH variable in +/etc/profile, if you want to use them easily. However, please note that +this may lead to some unintentional side effects, so be careful. + + +UPGRADING AN INSTALLATION +----------------------------------------------------------------------------- +For a minor-version upgrade (such as 13.1 to 13.2), just install the +new RPMs; there's usually nothing more to it than that. Upgrading +across a major release of PostgreSQL (for example, from 9.2.x to 13.x) +requires more effort. + +If you are upgrading across more than one major release of PostgreSQL +(for example, from 9.1.x to 13.x), you will need to follow the "traditional" +dump and reload process to bring your data into the new version. That is: +*before* upgrading, run pg_dumpall to extract all your data into a SQL file. +Shut down the old postmaster, upgrade to the new version RPMs, initdb, +and run the dump file through psql to restore your data. + +RPMs also support in-place upgrade from the immediately previous major release. +Currently, you can upgrade in-place from 12.x to 13.x. Just run: + +$ /usr/pgsql-13/bin/postgresql-13-setup upgrade + +Please note that 12 and 13 contrib RPMs need to be installed for this feature +to work. You can also upgrade from other major versions either by editing the +setup script, or passing PostgreSQL major version as the 3rd argument to the +setup script. + +POSTGRESQL RPM PACKAGES AND RATIONALE. +----------------------------------------------------------------------------- +PostgreSQL is split up into multiple packages so that users can 'pick and +choose' what pieces are needed, and what dependencies are required. + +The RPMset is packaged in the following subpackages: + +postgresql13: Key clients and libraries, and documentation +postgresql13-server: Server executables and data files +postgresql13-devel: Development libraries and include files +postgresql13-test: The regression tests and associated files +postgresql13-libs: Client shared libraries +postgresql13-docs: Extra documentation, such as the tutorial files +postgresql13-contrib: The contrib source tree, as well as selected binaries +postgresql13-plperl: PL/Perl procedural language +postgresql13-plpython: PL/Python procedural language +postgresql13-pltcl: PL/Tcl procedural language + +postgresql13-jdbc, postgresql13-python, postgresql13-tcl and postgresql13-odbc have +been splitted into seperate (s)rpms. + +You have to install postgresql and postgresql13-libs to do anything. +postgresql13-server is needed unless you only plan to use the clients to work +with a remote PostgreSQL server. The others are optional. + +postgresql13-python package includes PyGreSQL, and Pgtcl is distributed +via postgresql13-tcl package. + +RPM FILE LOCATIONS. +----------------------------------------------------------------------------- +To be in compliance with the Linux FHS, the PostgreSQL RPMs install files in +a manner not consistent with most of the PostgreSQL documentation. According +to the standard PostgreSQL documentation, PostgreSQL is installed under the +directory /usr/local/pgsql, with executables, source, and data existing in +various subdirectories. + +Different distributions have different ideas of some of these file locations. +In particular, the documentation directory can be /usr/doc, /usr/doc/packages, +/usr/share/doc, /usr/share/doc/packages, or some other similar path. + +However, the Red Hat / Scientific Linux ( CentOS / Fedora RPM's install +the files like this: + +Executables: /usr/bin and /usr/pgsql-13/bin +Libraries: /usr/pgsql-13/lib +Documentation: /usr/pgsql-13/doc +Contrib documentation: /usr/pgsql-13/doc +Source: not installed +Data: /var/lib/pgsql/13/data +Backup area: /var/lib/pgsql/13/backups +Templates: /usr/pgsql-13/share +Procedural Languages: /usr/pgsql-13/lib +Development Headers: /usr/pgsql-13/include +Other shared data: /usr/pgsql-13/share +Regression tests: /usr/pgsql-13/lib/test + +While it may seem gratuitous to place these files in different locations, the +FHS requires it -- distributions should not ever touch /usr/local. It may +also seem like more work to keep track of where everything is -- but, that's +the beauty of RPM -- you don't have to keep track of the files, RPM does it +for you. + +These RPMs are designed to be LSB-compliant -- if you find this not to be the +case, please let us know by way of the pgsql-pkg-yum@postgresql.org +mailing list. + +------------------------------------------------------------------------------- +MULTIPLE POSTMASTERS (For the same PostgreSQL version) +------------------------------------------------------------------------------- +The postgresql-server RPM contains a 'unit file' that is used to start the +postmaster. The current version of this script has logic to be able to start +multiple postmasters, with different data areas, listening on different ports, +etc. To use this functionality requires root access. + +Here are the steps: + +1.) First, you will need to create a new unit file for the new cluster. + You can give any name in here. To distinguish the cluster, you can + add the service name or port value to the unit file name: + + cp /lib/systemd/system/postgresql-13.service /etc/systemd/system/postgresql-13-secondary.service + +2.) Edit this file, and change PGDATA. Please note that you can give + any directory name in here that postgres can access. You don't + have to create this directory now, it will be created in the next step: + + Environment=PGDATA=/var/lib/pgsql/13/data-secondary + +3.) Initialize the cluster: + + /usr/pgsql-13/bin/postgresql-13-setup initdb postgresql-13-secondary + +4.) Edit postgresql.conf to change the port, address, tcpip settings, etc. + +5.) Start the postmaster with 'systemctl start postgresql-13-secondary.service' + +When doing a major-version upgrade of a secondary postmaster, mention the +service name in the postgresql-13-setup command, for example 'postgresql-13-setup +upgrade secondary'. This will let postgresql-13-setup find the correct data +directory from the service file. + +REGRESSION TESTING +------------------------------------------------------------------------------- +If you install the postgresql-test RPM then you can run the PostgreSQL +regression tests. These tests stress your database installation and produce +results that give you assurances that the installation is complete, and that +your database machine is up to the task. + +To run the regression tests under the RPM installation, make sure that the +postmaster has been started (if not, su to root and do "systemctl start +postgresql-13.service"), cd to /usr/pgsql-13/lib/test/regress, su to +postgres, and execute "make check". This command will start the +regression tests and will both show the results to the screen and store +the results in the file regress.out. + +If any tests fail, see the file regression.diffs in that directory for details, +and read the "Regression Tests" section of the PostgreSQL documentation to +find out whether the differences are actually significant. If you need help +interpreting the results, contact the pgsql-general list at +postgresql.org. + +After testing, say "make clean" to remove the files generated by the test +script. + +STARTING POSTMASTER AUTOMATICALLY AT SYSTEM STARTUP +------------------------------------------------------------------------------- +Fedora / Red Hat / CentOS use the systemd package to manage server startup. +A systemd unit file for PostgreSQL is provided in the server package, as +/lib/systemd/system/postgresql-13.service. To start the postmaster manually, +as root run + systemctl start postgresql-13.service +To shut the postmaster down, + systemctl stop postgresql-13.service +These two commands only change the postmaster's current status. If you +want the postmaster to be started automatically during future system startups, +run + systemctl enable postgresql-13.service +To undo that again, + systemctl disable postgresql-13.service +See "man systemctl" for other possible subcommands. + +GRAND UNIFIED CONFIGURATION (GUC) FILE +------------------------------------------------------------------------------- +The PostgreSQL server has many tunable parameters -- the file +/var/lib/pgsql/13/data/postgresql.conf is the master configuration file for the +whole system. + +The RPM ships with a mostly-default file -- you will need to tune the +parameters for your installation. In particular, you might want to allow +nonlocal TCP/IP socket connections -- in order to allow these, you will need +to edit the postgresql.conf file. The line in question contains the string +'listen_addresses' -- you need to both uncomment the line and set the value +to '*' to get the postmaster to accept nonlocal connections. You'll also need +to adjust pg_hba.conf appropriately. + +LOGGING SET UP +------------------------------------------------------------------------------- +By default, the postmaster's stderr log is directed into files placed in a +log subdirectory of the data directory (ie, /var/lib/pgsql/13/data/log). +The out-of-the-box configuration rotates among seven files, one for each +day of the week. You can adjust this by changing postgresql.conf settings. + +REBUILDING FROM SOURCE RPM +------------------------------------------------------------------------------- +If your distribution is not supported by the binary RPMs from PostgreSQL.org, +you will need to rebuild from the source RPM. Download the .src.rpm for this +release. You will need to be root to rebuild, unless you have set up +a non-root build environment (which is the recommended method anyway). + +Install the source RPM with rpm -i, then cd to the rpm building area +(which is /usr/src/redhat by default). You will have to have a full +development environment to rebuild the full RPM set. + +This release of the RPMset includes the ability to conditionally build +sets of packages. The parameters, their defaults, and the meanings are: + +beta 0 #build with cassert and do not strip the binaries +llvm 1 #build with llvm support +python 1 #build the postgresql-python package. +tcl 1 #build the postgresql-tcl package. +test 1 #build the postgresql-test package. +plpython 1 #build the PL/Python procedural language package. +pltcl 1 #build the PL/Tcl procedural language package. +plperl 1 #build the PL/Perl procedural language package. +ssl 1 #use OpenSSL support. +kerberos 1 #use Kerberos 5 support. +nls 1 #build with national language support. +ldap 1 #build with LDAP support. +pam 1 #build with PAM support. +runselftest 1 #do "make check" during the build. +sdt 1 #build with SystemTap support. +xml 1 #build with XML support +pgfts 1 #build with --enable-thread-safety +uuid 1 #build contrib/uuid-ossp + +To use these defines, invoke a rebuild like this: +rpmbuild --rebuild --define 'python 0' --define 'tcl 0' \ + --define 'test 0' --define 'runselftest 0' --define 'kerberos 0' \ + postgresql13-13.3-1PGDG.rhel7.src.rpm +This line would disable the python, tcl, and test subpackages, disable +the regression test run during build, and disable kerberos support. + +You might need to disable runselftest if there is an installed version of +PostgreSQL that is a different major version from what you are trying to +build. The self test tends to pick up the installed libpq.so shared library +in place of the one being built :-(, so if that isn't compatible the test will +fail. Also, you can't use runselftest when doing the build as root. + +More of these conditionals will be added in the future. + +CONTRIB FILES +------------------------------------------------------------------------------- +The contents of the contrib tree are packaged into the -contrib subpackage +and are processed with make and make install. Most of the modules are in +/usr/pgsql-13/lib for loadable modules, and binaries are in +/usr/pgsql-13/bin. In the future these files may be split out, +depending upon function and dependencies. + + +MORE INFORMATION +------------------------------------------------------------------------------- +You can get more information at http://www.postgresql.org and +https://yum.postgresql.org + +Please help make this packaging better -- let us know if you find problems, or +better ways of doing things. You can reach us by e-mail at +pgsql-pkg-yum@lists.postgresql.org +------------------------------------------------------------------------------- diff --git a/postgresql-13-check-db-dir b/postgresql-13-check-db-dir new file mode 100644 index 0000000000000000000000000000000000000000..e503172640672ebd40c1c73d476b07bdf6e71436 --- /dev/null +++ b/postgresql-13-check-db-dir @@ -0,0 +1,57 @@ +#!/bin/sh + +# This script verifies that the postgresql data directory has been correctly +# initialized. We do not want to automatically initdb it, because that has +# a risk of catastrophic failure (ie, overwriting a valuable database) in +# corner cases, such as a remotely mounted database on a volume that's a +# bit slow to mount. But we can at least emit a message advising newbies +# what to do. + +PGDATA="$1" + +if [ -z "$PGDATA" ] +then + echo "Usage: $0 database-path" + exit 1 +fi + +# PGVERSION is the full package version, e.g., 13.0 +# Note: the specfile inserts the correct value during package build +PGVERSION=xxxx +# PGMAJORVERSION is major version, e.g., 9.6 (this should match PG_VERSION) +PGMAJORVERSION=`echo "$PGVERSION" | sed 's/^\([0-9]*\.[0-9]*\).*$/\1/'` +# PREVMAJORVERSION is the previous major version, e.g., 9.5, for upgrades +# Note: the specfile inserts the correct value during package build +PREVMAJORVERSION=xxxx +# PGDOCDIR is the directory containing the package's documentation +# Note: the specfile inserts the correct value during package build +PGDOCDIR=xxxx + +# Check for the PGDATA structure +if [ -f "$PGDATA/PG_VERSION" ] && [ -d "$PGDATA/base" ] +then + # Check version of existing PGDATA + if [ x`cat "$PGDATA/PG_VERSION"` = x"$PGMAJORVERSION" ] + then + : A-OK + elif [ x`cat "$PGDATA/PG_VERSION"` = x"$PREVMAJORVERSION" ] + then + echo $"An old version of the database format was found." + echo $"Use \"postgresql-setup upgrade\" to upgrade to version $PGMAJORVERSION." + echo $"See $PGDOCDIR/README.rpm-dist for more information." + exit 1 + else + echo $"An old version of the database format was found." + echo $"You need to dump and reload before using PostgreSQL $PGMAJORVERSION." + echo $"See $PGDOCDIR/README.rpm-dist for more information." + exit 1 + fi +else + # No existing PGDATA! Warn the user to initdb it. + echo $"\"$PGDATA\" is missing or empty." + echo $"Use \"/usr/pgsql-13/bin/postgresql-13-setup initdb\" to initialize the database cluster." + echo $"See $PGDOCDIR/README.rpm-dist for more information." + exit 1 +fi + +exit 0 diff --git a/postgresql-13-conf.patch b/postgresql-13-conf.patch new file mode 100644 index 0000000000000000000000000000000000000000..4dd608b861514b526b37e42bbc033e40c9585941 --- /dev/null +++ b/postgresql-13-conf.patch @@ -0,0 +1,54 @@ +--- src/backend/utils/misc/postgresql.conf.sample.old 2020-05-22 13:19:53.049155343 +0100 ++++ src/backend/utils/misc/postgresql.conf.sample 2020-05-22 13:20:54.491231312 +0100 +@@ -421,25 +421,25 @@ + + # - Where to Log - + +-#log_destination = 'stderr' # Valid values are combinations of ++log_destination = 'stderr' # Valid values are combinations of + # stderr, csvlog, syslog, and eventlog, + # depending on platform. csvlog + # requires logging_collector to be on. + + # This is used when logging to stderr: +-#logging_collector = off # Enable capturing of stderr and csvlog ++logging_collector = on # Enable capturing of stderr and csvlog + # into log files. Required to be on for + # csvlogs. + # (change requires restart) + + # These are only used if logging_collector is on: +-#log_directory = 'log' # directory where log files are written, ++log_directory = 'log' # directory where log files are written, + # can be absolute or relative to PGDATA +-#log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' # log file name pattern, ++log_filename = 'postgresql-%a.log' # log file name pattern, + # can include strftime() escapes + #log_file_mode = 0600 # creation mode for log files, + # begin with 0 to use octal notation +-#log_truncate_on_rotation = off # If on, an existing log file with the ++log_truncate_on_rotation = on # If on, an existing log file with the + # same name as the new log file will be + # truncated rather than appended to. + # But such truncation only occurs on +@@ -447,9 +447,9 @@ + # or size-driven rotation. Default is + # off, meaning append to existing files + # in all cases. +-#log_rotation_age = 1d # Automatic rotation of logfiles will ++log_rotation_age = 1d # Automatic rotation of logfiles will + # happen after that time. 0 disables. +-#log_rotation_size = 10MB # Automatic rotation of logfiles will ++log_rotation_size = 0 # Automatic rotation of logfiles will + # happen after that much log output. + # 0 disables. + +@@ -525,7 +525,7 @@ + #log_duration = off + #log_error_verbosity = default # terse, default, or verbose messages + #log_hostname = off +-#log_line_prefix = '%m [%p] ' # special values: ++log_line_prefix = '%m [%p] ' # special values: + # %a = application name + # %u = user name + # %d = database name diff --git a/postgresql-13-ecpg_config.h b/postgresql-13-ecpg_config.h new file mode 100644 index 0000000000000000000000000000000000000000..6fecfcb513ceb990c610157ebef0b0b60f2abbc1 --- /dev/null +++ b/postgresql-13-ecpg_config.h @@ -0,0 +1,29 @@ +/* + * Kluge to support multilib installation of both 32- and 64-bit RPMS: + * we need to arrange that header files that appear in both RPMs are + * identical. Hence, this file is architecture-independent and calls + * in an arch-dependent file that will appear in just one RPM. + * + * To avoid breaking arches not explicitly supported by Red Hat, we + * use this indirection file *only* on known multilib arches. + * + * Note: this may well fail if user tries to use gcc's -I- option. + * But that option is deprecated anyway. + */ +#if defined(__x86_64__) +#include "ecpg_config_x86_64.h" +#elif defined(__i386__) +#include "ecpg_config_i386.h" +#elif defined(__ppc64__) || defined(__powerpc64__) +#include "ecpg_config_ppc64.h" +#elif defined(__ppc__) || defined(__powerpc__) +#include "ecpg_config_ppc.h" +#elif defined(__s390x__) +#include "ecpg_config_s390x.h" +#elif defined(__s390__) +#include "ecpg_config_s390.h" +#elif defined(__sparc__) && defined(__arch64__) +#include "ecpg_config_sparc64.h" +#elif defined(__sparc__) +#include "ecpg_config_sparc.h" +#endif diff --git a/postgresql-13-filter-requires-perl-Pg.sh b/postgresql-13-filter-requires-perl-Pg.sh new file mode 100755 index 0000000000000000000000000000000000000000..f37557f2dcc334ee2039bbc02de1b8895acf720a --- /dev/null +++ b/postgresql-13-filter-requires-perl-Pg.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +/usr/lib/rpm/perl.req $* | grep -v 'perl(Pg' diff --git a/postgresql-13-libs.conf b/postgresql-13-libs.conf new file mode 100644 index 0000000000000000000000000000000000000000..0f397715739976d573922682e3ffd708dc4356ba --- /dev/null +++ b/postgresql-13-libs.conf @@ -0,0 +1 @@ +/usr/pgsql-13/lib/ diff --git a/postgresql-13-perl-rpath.patch b/postgresql-13-perl-rpath.patch new file mode 100644 index 0000000000000000000000000000000000000000..b3e6b551de21054b115c4c3748e1b47ba541f25f --- /dev/null +++ b/postgresql-13-perl-rpath.patch @@ -0,0 +1,12 @@ +--- src/pl/plperl/GNUmakefile.old 2020-02-16 20:01:28.953183370 +0300 ++++ src/pl/plperl/GNUmakefile 2020-02-16 20:01:48.943311971 +0300 +@@ -55,6 +55,9 @@ + + SHLIB_LINK = $(perl_embed_ldflags) + ++# Force rpath to be used even though we disable it everywhere else ++SHLIB_LINK += $(rpath) ++ + REGRESS_OPTS = --dbname=$(PL_TESTDB) + REGRESS = plperl_setup plperl plperl_lc plperl_trigger plperl_shared \ + plperl_elog plperl_util plperl_init plperlu plperl_array \ diff --git a/postgresql-13-pg_config.h b/postgresql-13-pg_config.h new file mode 100644 index 0000000000000000000000000000000000000000..97ef2baa0755b8959689ccf90fcba0910e590fb7 --- /dev/null +++ b/postgresql-13-pg_config.h @@ -0,0 +1,29 @@ +/* + * Kluge to support multilib installation of both 32- and 64-bit RPMS: + * we need to arrange that header files that appear in both RPMs are + * identical. Hence, this file is architecture-independent and calls + * in an arch-dependent file that will appear in just one RPM. + * + * To avoid breaking arches not explicitly supported by Red Hat, we + * use this indirection file *only* on known multilib arches. + * + * Note: this may well fail if user tries to use gcc's -I- option. + * But that option is deprecated anyway. + */ +#if defined(__x86_64__) +#include "pg_config_x86_64.h" +#elif defined(__i386__) +#include "pg_config_i386.h" +#elif defined(__ppc64__) || defined(__powerpc64__) +#include "pg_config_ppc64.h" +#elif defined(__ppc__) || defined(__powerpc__) +#include "pg_config_ppc.h" +#elif defined(__s390x__) +#include "pg_config_s390x.h" +#elif defined(__s390__) +#include "pg_config_s390.h" +#elif defined(__sparc__) && defined(__arch64__) +#include "pg_config_sparc64.h" +#elif defined(__sparc__) +#include "pg_config_sparc.h" +#endif diff --git a/0002-rpm-pgsql.patch b/postgresql-13-rpm-pgsql.patch similarity index 31% rename from 0002-rpm-pgsql.patch rename to postgresql-13-rpm-pgsql.patch index aec64ac7aec751cdf589749c90d626ca5ce27c28..d9b6d12b7517407ac81352fa325ec91b05587641 100644 --- a/0002-rpm-pgsql.patch +++ b/postgresql-13-rpm-pgsql.patch @@ -1,72 +1,55 @@ -For the RPMs, we want the custom installation directories to end in -/pgsql not /postgresql. This is historical but not worth changing. - -Notice that this patch also makes the appending of /pgsql unconditional. -This is to avoid unexpected behavior if the RPM is built in a working -directory whose path happens to include "postgres" or "pgsql" already. -However, datadir and sysconfdir are already set up in the specfile's -configure call, so we do not have to append anything to them. - - -diff -Naur postgresql-9.0.1.orig/src/Makefile.global.in postgresql-9.0.1/src/Makefile.global.in ---- postgresql-9.0.1.orig/src/Makefile.global.in 2010-10-01 10:25:44.000000000 -0400 -+++ postgresql-9.0.1/src/Makefile.global.in 2010-10-11 11:52:05.224975308 -0400 -@@ -55,8 +55,7 @@ +--- src/Makefile.global.in.old 2020-02-28 16:17:03.000000000 +0000 ++++ src/Makefile.global.in 2020-04-07 09:14:33.906414682 +0100 +@@ -82,7 +82,7 @@ # Installation directories # # These are set by the equivalent --xxxdir configure options. We -# append "postgresql" to some of them, if the string does not already --# contain "pgsql" or "postgres", in order to avoid directory clutter. -+# append "pgsql" to some of them, in order to avoid directory clutter. ++# append "pgsql" to some of them, if the string does not already + # contain "pgsql" or "postgres", in order to avoid directory clutter. # # In a PGXS build, we cannot use the values inserted into Makefile.global - # by configure, since the installation tree may have been relocated. -@@ -74,45 +73,23 @@ - bindir := @bindir@ - +@@ -103,14 +103,14 @@ datadir := @datadir@ --ifeq "$(findstring pgsql, $(datadir))" "" --ifeq "$(findstring postgres, $(datadir))" "" + ifeq "$(findstring pgsql, $(datadir))" "" + ifeq "$(findstring postgres, $(datadir))" "" -override datadir := $(datadir)/postgresql --endif --endif ++override datadir := $(datadir)/pgsql + endif + endif sysconfdir := @sysconfdir@ --ifeq "$(findstring pgsql, $(sysconfdir))" "" --ifeq "$(findstring postgres, $(sysconfdir))" "" + ifeq "$(findstring pgsql, $(sysconfdir))" "" + ifeq "$(findstring postgres, $(sysconfdir))" "" -override sysconfdir := $(sysconfdir)/postgresql --endif --endif - - libdir := @libdir@ ++override sysconfdir := $(sysconfdir)/pgsql + endif + endif +@@ -119,7 +119,7 @@ pkglibdir = $(libdir) --ifeq "$(findstring pgsql, $(pkglibdir))" "" --ifeq "$(findstring postgres, $(pkglibdir))" "" + ifeq "$(findstring pgsql, $(pkglibdir))" "" + ifeq "$(findstring postgres, $(pkglibdir))" "" -override pkglibdir := $(pkglibdir)/postgresql --endif --endif +override pkglibdir := $(pkglibdir)/pgsql + endif + endif - includedir := @includedir@ - +@@ -128,7 +128,7 @@ pkgincludedir = $(includedir) --ifeq "$(findstring pgsql, $(pkgincludedir))" "" --ifeq "$(findstring postgres, $(pkgincludedir))" "" + ifeq "$(findstring pgsql, $(pkgincludedir))" "" + ifeq "$(findstring postgres, $(pkgincludedir))" "" -override pkgincludedir := $(pkgincludedir)/postgresql --endif --endif +override pkgincludedir := $(pkgincludedir)/pgsql + endif + endif - mandir := @mandir@ - +@@ -137,7 +137,7 @@ docdir := @docdir@ --ifeq "$(findstring pgsql, $(docdir))" "" --ifeq "$(findstring postgres, $(docdir))" "" + ifeq "$(findstring pgsql, $(docdir))" "" + ifeq "$(findstring postgres, $(docdir))" "" -override docdir := $(docdir)/postgresql --endif --endif +override docdir := $(docdir)/pgsql - - htmldir := @htmldir@ + endif + endif diff --git a/postgresql-13-setup b/postgresql-13-setup new file mode 100644 index 0000000000000000000000000000000000000000..b9bd4a8b06d41467d20416bd4ff96ee7287712fe --- /dev/null +++ b/postgresql-13-setup @@ -0,0 +1,299 @@ +#!/bin/sh +# +# postgresql-setup Initialization and upgrade operations for PostgreSQL + +# PGVERSION is the full package version, e.g., 13.0 +# Note: the specfile inserts the correct value during package build +PGVERSION=xxx +# PGMAJORVERSION is major version, e.g., 13 (this should match PG_VERSION) +PGMAJORVERSION=`echo "$PGVERSION" | sed 's/^\([0-9]*\.[0-9]*\).*$/\1/'` +# PGENGINE is the directory containing the postmaster executable +# Note: the specfile inserts the correct value during package build +PGENGINE=xxxx +# PREVMAJORVERSION is the previous major version, e.g., 10, for upgrades +PREVMAJORVERSION=xxx +# PREVPGENGINE is the directory containing the previous postmaster executable +PREVPGENGINE=/usr/pgsql-$PREVMAJORVERSION/bin +# PREVDATADIR is the directory containing the previous postmaster executable +PREVDATADIR=/var/lib/pgsql/$PREVMAJORVERSION/data + +# TODO: Provide a conf file that can override these settings + +# The second parameter is the new database version, i.e. $PGMAJORVERSION in this case. +# Use "postgresql-$PGMAJORVERSION" service, if not specified. +SERVICE_NAME="$2" +if [ x"$SERVICE_NAME" = x ] +then + SERVICE_NAME=postgresql-$PGMAJORVERSION +fi + +# The third parameter is the old database version, i.e. $PREVMAJORVERSION in this case. +# Use "postgresql-$PREVMAJORVERSION" service, if not specified. +OLD_SERVICE_NAME="$3" +if [ x"$OLD_SERVICE_NAME" = x ] +then + OLD_SERVICE_NAME=postgresql-$PREVMAJORVERSION +fi + +USAGE_STRING=$" +Usage: $0 {initdb|check_upgrade|upgrade} [SERVICE_NAME] + +Script is aimed to help sysadmin with basic database cluster administration. + +The SERVICE_NAME is used for selection of proper unit configuration file; For +more info and howto/when use this script please look at README.rpm-dist file. +The 'postgresql' string is used when no SERVICE_NAME is explicitly passed. + +Available operation mode: + initdb Create a new PostgreSQL database cluster. This is usually the + first action you perform after PostgreSQL server installation. + check_upgrade Checks whether the old cluster can be upgraded to the new version + or not. + upgrade Upgrade PostgreSQL database cluster to be usable with new + server. Use this if you upgraded your PostgreSQL server to + newer major version (currently from $PREVMAJORVERSION \ +to $PGMAJORVERSION). + +Environment: + PGSETUP_INITDB_OPTIONS Options carried by this variable are passed to + subsequent call of \`initdb\` binary (see man + initdb(1)). This variable is used also during + 'upgrade' mode because the new cluster is actually + re-initialized from the old one. + PGSETUP_PGUPGRADE_OPTIONS Options in this variable are passed next to the + subsequent call of \`pg_upgrade\`. For more info + about possible options please look at man + pg_upgrade(1). + PGSETUP_DEBUG Set to '1' if you want to see debugging output." + +# note that these options are useful at least for help2man processing +case "$1" in + --version) + echo "PostgreSQL setup script for version $PGVERSION" + exit 0 + ;; + --help|--usage) + echo "$USAGE_STRING" + exit 0 + ;; +esac + +# this parsing technique fails for PGDATA pathnames containing spaces, +# but there's not much I can do about it given systemctl's output format... +PGDATA=`systemctl show -p Environment "${SERVICE_NAME}.service" | + sed 's/^Environment=//' | tr ' ' '\n' | + sed -n 's/^PGDATA=//p' | tail -n 1` +if [ x"$PGDATA" = x ]; then + echo "failed to find PGDATA setting in ${SERVICE_NAME}.service" + exit 1 +fi + +# Find the unit file for new version. +if [ -f "/etc/systemd/system/${SERVICE_NAME}.service" ] +then + SERVICE_FILE="/etc/systemd/system/${SERVICE_NAME}.service" +elif [ -f "/usr/lib/systemd/system/${SERVICE_NAME}.service" ] +then + SERVICE_FILE="/usr/lib/systemd/system/${SERVICE_NAME}.service" +else + echo "Could not find systemd unit file ${SERVICE_NAME}.service" + exit 1 +fi + +# Log file for pg_upgrade +PGUPLOG=/var/lib/pgsql/$PGMAJORVERSION/pgupgrade.log +# Log file for initdb +PGLOG=/var/lib/pgsql/$PGMAJORVERSION/initdb.log + +export PGDATA + +# For SELinux we need to use 'runuser' not 'su' +if [ -x /sbin/runuser ] +then + SU=/sbin/runuser +else + SU=su +fi + +script_result=0 + +# code shared between initdb and upgrade actions +perform_initdb(){ + if [ ! -e "$PGDATA" ]; then + mkdir -p "$PGDATA" || return 1 + chown postgres:postgres "$PGDATA" + chmod go-rwx "$PGDATA" + fi + # Clean up SELinux tagging for PGDATA + [ -x /sbin/restorecon ] && /sbin/restorecon "$PGDATA" + + # Create the initdb log file if needed + if [ ! -e "$PGLOG" -a ! -h "$PGLOG" ]; then + touch "$PGLOG" || return 1 + chown postgres:postgres "$PGLOG" + chmod go-rwx "$PGLOG" + [ -x /sbin/restorecon ] && /sbin/restorecon "$PGLOG" + fi + + # Initialize the database + initdbcmd="$PGENGINE/initdb --pgdata='$PGDATA' -A scram-sha-256 --auth-local=peer --pwfile /dev/zero" + initdbcmd+=" $PGSETUP_INITDB_OPTIONS" + + $SU -l postgres -c "$initdbcmd" >> "$PGLOG" 2>&1 < /dev/null + + # Exit if initdb fails, to prevent the log/ directory to be created. + # Otherwise a subsequent initdb will not even start. + if [ $? -ne 0 ]; then + exit 1 + fi + + # Create directory for postmaster log files + mkdir "$PGDATA/log" + chown postgres:postgres "$PGDATA/log" + chmod go-rwx "$PGDATA/log" + [ -x /sbin/restorecon ] && /sbin/restorecon "$PGDATA/log" + + if [ -f "$PGDATA/PG_VERSION" ]; then + return 0 + fi + return 1 +} + +initdb(){ + if [ -f "$PGDATA/PG_VERSION" ]; then + echo $"Data directory is not empty!" + echo + script_result=1 + else + echo -n $"Initializing database ... " + if perform_initdb; then + echo $"OK" + else + echo $"failed, see $PGLOG" + script_result=1 + fi + echo + fi +} + +check_upgrade(){ + # must see previous version in PG_VERSION + if [ ! -f "$PREVDATADIR/PG_VERSION" -o \ + x`cat "$PREVDATADIR/PG_VERSION"` != x"$PREVMAJORVERSION" ] + then + echo + echo $"Cannot upgrade because the database in $PGDATA is not of" + echo $"compatible previous version $PREVMAJORVERSION." + echo + exit 1 + fi + + # Set up log file for pg_upgrade + rm -f "$PGUPLOG" + touch "$PGUPLOG" || exit 1 + chown postgres:postgres "$PGUPLOG" + chmod go-rwx "$PGUPLOG" + [ -x /sbin/restorecon ] && /sbin/restorecon "$PGUPLOG" + + # Make sure that the user initdb'ed the new cluster: + if [ ! -f "$PGDATA/PG_VERSION" ] + then + echo + echo $"Please initialize the new cluster before upgrading." + echo $"You can run this script with the ''initdb'' parameter:" + echo $"" + echo $"$PGENGINE/postgresql-$PGVERSION-setup initdb" + echo + exit 1 + fi + + # Copy the current pg_hba.conf file to new cluster: + + HBA_CONF_BACKUP_EXISTS=0 + + cp "$PREVDATADIR/pg_hba.conf" "$PGDATA/" + HBA_CONF_BACKUP_EXISTS=1 + + # For fluent upgrade 'postgres' user should be able to connect + # to any database without password. Temporarily, no other type + # of connection is needed. + echo "local all postgres peer" > "$PREVDATADIR/pg_hba.conf" + + echo -n $"Performing upgrade check: " + + # Do the upgrade + $SU -l postgres -c "$PGENGINE/pg_upgrade \ + '--old-bindir=$PREVPGENGINE' \ + '--new-bindir=$PGENGINE' \ + '--old-datadir=$PREVDATADIR' \ + '--new-datadir=$PGDATA' \ + --check \ + --user=postgres \ + $PGSETUP_PGUPGRADE_OPTIONS" \ + >> "$PGUPLOG" 2>&1 < /dev/null + if [ $? -ne 0 ]; then + # pg_upgrade failed + script_result=1 + fi + if [ $script_result -eq 0 ]; then + echo $"OK" + else + # Clean up after failure + echo "Upgrade failed. Removing the new cluster. Please re-initdb the new cluster." + rm -rf "$PGDATA" + echo $"failed" + fi + echo + echo $"See $PGUPLOG for details." +} + + +upgrade(){ +# Perform the upgrade check first: +check_upgrade + echo -n $"Upgrading database: " + + # Do the upgrade + $SU -l postgres -c "$PGENGINE/pg_upgrade \ + '--old-bindir=$PREVPGENGINE' \ + '--new-bindir=$PGENGINE' \ + '--old-datadir=$PREVDATADIR' \ + '--new-datadir=$PGDATA' \ + --link \ + --user=postgres \ + $PGSETUP_PGUPGRADE_OPTIONS" \ + >> "$PGUPLOG" 2>&1 < /dev/null + if [ $? -ne 0 ]; then + # pg_upgrade failed + script_result=1 + fi + if [ $script_result -eq 0 ]; then + echo $"OK" + echo + echo $"pg_hba.conf configuration file of the new cluster was replaced by the one in the old cluster." + else + # Clean up after failure + rm -rf "$PGDATA" + echo $"failed" + fi + echo + echo $"See $PGUPLOG for details." +} + +# See how we were called. +case "$1" in + initdb) + initdb + ;; + upgrade) + upgrade + ;; + check_upgrade) + check_upgrade + ;; + *) + echo >&2 "$USAGE_STRING" + exit 2 +esac + +exit $script_result diff --git a/postgresql-13-tmpfiles.d b/postgresql-13-tmpfiles.d new file mode 100644 index 0000000000000000000000000000000000000000..6c48e34ed1c10c66a651b98acadacb326fb3bacd --- /dev/null +++ b/postgresql-13-tmpfiles.d @@ -0,0 +1 @@ +d /run/postgresql 0755 postgres postgres - diff --git a/0001-postgresql-var-run-socket.patch b/postgresql-13-var-run-socket.patch similarity index 61% rename from 0001-postgresql-var-run-socket.patch rename to postgresql-13-var-run-socket.patch index 8e3b19304cbf5e1ee243ad98c3285158298151f5..ec47b447cdc0fc3e6030a1affbbd78e4df06bd87 100644 --- a/0001-postgresql-var-run-socket.patch +++ b/postgresql-13-var-run-socket.patch @@ -12,11 +12,9 @@ server package update, without requiring any existing postgresql.conf to be updated. (Of course, a user who dislikes this behavior can still override it via postgresql.conf.) -diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c -index 9481f2d..75532c7 100644 ---- a/src/backend/utils/misc/guc.c -+++ b/src/backend/utils/misc/guc.c -@@ -3196,7 +3196,7 @@ static struct config_string ConfigureNamesString[] = +--- src/backend/utils/misc/guc.c.old 2020-04-07 00:53:48.599369279 +0100 ++++ src/backend/utils/misc/guc.c 2020-04-07 00:54:25.604609110 +0100 +@@ -4154,7 +4154,7 @@ }, &Unix_socket_directories, #ifdef HAVE_UNIX_SOCKETS @@ -25,11 +23,9 @@ index 9481f2d..75532c7 100644 #else "", #endif -diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c -index feeff9e..3e3d784 100644 ---- a/src/bin/initdb/initdb.c -+++ b/src/bin/initdb/initdb.c -@@ -1234,7 +1234,7 @@ setup_config(void) +--- src/bin/initdb/initdb.c.old 2020-04-07 00:54:38.785694537 +0100 ++++ src/bin/initdb/initdb.c 2020-04-07 00:55:02.127845817 +0100 +@@ -1091,7 +1091,7 @@ #ifdef HAVE_UNIX_SOCKETS snprintf(repltok, sizeof(repltok), "#unix_socket_directories = '%s'", @@ -38,16 +34,14 @@ index feeff9e..3e3d784 100644 #else snprintf(repltok, sizeof(repltok), "#unix_socket_directories = ''"); #endif -diff --git a/src/include/pg_config_manual.h b/src/include/pg_config_manual.h -index e278fa0..9ee15d4 100644 ---- a/src/include/pg_config_manual.h -+++ b/src/include/pg_config_manual.h -@@ -169,7 +169,7 @@ - * here's where to twiddle it. You can also override this at runtime - * with the postmaster's -k switch. +--- src/include/pg_config_manual.h.old 2020-04-07 00:55:36.609069290 +0100 ++++ src/include/pg_config_manual.h 2020-04-07 00:56:03.018240448 +0100 +@@ -201,7 +201,7 @@ + * support them yet. */ + #ifndef WIN32 -#define DEFAULT_PGSOCKET_DIR "/tmp" +#define DEFAULT_PGSOCKET_DIR "/var/run/postgresql" - - /* - * This is the default event source for Windows event log. + #else + #define DEFAULT_PGSOCKET_DIR "" + #endif diff --git a/postgresql-10.5.tar.bz2 b/postgresql-13.2.tar.bz2 similarity index 67% rename from postgresql-10.5.tar.bz2 rename to postgresql-13.2.tar.bz2 index 813010f74053bbb1e0019c7bfe5cfc1d8c06ec62..d12a72fccf58c1d105348270934676ffb2555da8 100644 Binary files a/postgresql-10.5.tar.bz2 and b/postgresql-13.2.tar.bz2 differ diff --git a/postgresql-13.pam b/postgresql-13.pam new file mode 100644 index 0000000000000000000000000000000000000000..1d785946d3fe6a7a77dbd83de624701afe94f06a --- /dev/null +++ b/postgresql-13.pam @@ -0,0 +1,3 @@ +#%PAM-1.0 +auth include password-auth +account include password-auth diff --git a/postgresql-13.service b/postgresql-13.service new file mode 100644 index 0000000000000000000000000000000000000000..ddc1bae01dc1b882d94db98331ff4bde415a4682 --- /dev/null +++ b/postgresql-13.service @@ -0,0 +1,53 @@ +# It's not recommended to modify this file in-place, because it will be +# overwritten during package upgrades. It is recommended to use systemd +# "dropin" feature; i.e. create file with suffix .conf under +# /etc/systemd/system/postgresql-13.service.d directory overriding the +# unit's defaults. You can also use "systemctl edit postgresql-13" +# Look at systemd.unit(5) manual page for more info. + +# Note: changing PGDATA will typically require adjusting SELinux +# configuration as well. + +# Note: do not use a PGDATA pathname containing spaces, or you will +# break postgresql-13-setup. +[Unit] +Description=PostgreSQL 13 database server +Documentation=https://www.postgresql.org/docs/13/static/ +After=syslog.target +After=network.target + +[Service] +Type=notify + +User=postgres +Group=postgres + +# Note: avoid inserting whitespace in these Environment= lines, or you may +# break postgresql-setup. + +# Location of database directory +Environment=PGDATA=/var/lib/pgsql/13/data/ + +# Where to send early-startup messages from the server (before the logging +# options of postgresql.conf take effect) +# This is normally controlled by the global default set by systemd +# StandardOutput=syslog + +# Disable OOM kill on the postmaster +OOMScoreAdjust=-1000 +Environment=PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj +Environment=PG_OOM_ADJUST_VALUE=0 + +ExecStartPre=/usr/pgsql-13/bin/postgresql-13-check-db-dir ${PGDATA} +ExecStart=/usr/pgsql-13/bin/postmaster -D ${PGDATA} +ExecReload=/bin/kill -HUP $MAINPID +KillMode=mixed +KillSignal=SIGINT + + +# Do not set any timeout value, so that systemd will not kill postmaster +# during crash recovery. +TimeoutSec=0 + +[Install] +WantedBy=multi-user.target diff --git a/postgresql-13.spec b/postgresql-13.spec new file mode 100644 index 0000000000000000000000000000000000000000..1adf382900ee09a70d4fe3884416278441e0000e --- /dev/null +++ b/postgresql-13.spec @@ -0,0 +1,1408 @@ +# These are macros to be used with find_lang and other stuff +%global pgmajorversion 13 +%global packageversion 130 +%global pgpackageversion 13 +%global prevmajorversion 12 +%global sname postgresql +%global pgbaseinstdir /usr/pgsql-%{pgmajorversion} + +%global beta 0 +%{?beta:%global __os_install_post /usr/lib/rpm/brp-compress} + +# Macros that define the configure parameters: +%{!?kerbdir:%global kerbdir "/usr"} +%{!?disablepgfts:%global disablepgfts 0} + +%if 0%{?rhel} || 0%{?suse_version} >= 1315 +%{!?enabletaptests:%global enabletaptests 0} +%else +%{!?enabletaptests:%global enabletaptests 1} +%endif + +%{!?icu:%global icu 1} +%{!?kerberos:%global kerberos 1} +%{!?ldap:%global ldap 1} +%{!?nls:%global nls 1} +%{!?pam:%global pam 1} + +# All Fedora releases now use Python3 +# Support Python3 on RHEL 7.7+ natively +# RHEL 8 uses Python3 +%{!?plpython3:%global plpython3 1} + +%if 0%{?suse_version} +%if 0%{?suse_version} >= 1315 +# Disable PL/Python 3 on SLES 12 +%{!?plpython3:%global plpython3 0} +%endif +%endif + +%{!?pltcl:%global pltcl 1} +%{!?plperl:%global plperl 1} +%{!?ssl:%global ssl 1} +%{!?test:%global test 1} +%{!?runselftest:%global runselftest 1} +%{!?uuid:%global uuid 1} +%{!?xml:%global xml 1} + +%{!?systemd_enabled:%global systemd_enabled 1} + +%ifarch ppc64 ppc64le s390 s390x armv7hl +%{!?sdt:%global sdt 0} +%else + %{!?sdt:%global sdt 1} +%endif + +%ifarch ppc64 ppc64le s390 s390x armv7hl +%if 0%{?rhel} && 0%{?rhel} == 7 +%{!?llvm:%global llvm 0} +%else +%{!?llvm:%global llvm 1} +%endif +%else +%{!?llvm:%global llvm 1} +%endif + +%{!?selinux:%global selinux 1} + +%if 0%{?fedora} > 30 +%global _hardened_build 1 +%endif + +%if 0%{?rhel} && 0%{?rhel} == 7 +%ifarch ppc64 ppc64le +%pgdg_set_ppc64le_compiler_at10 +%endif +%endif + +Summary: PostgreSQL client programs and libraries +Name: %{sname}%{pgmajorversion} +Version: 13.2 +Release: 20 +License: PostgreSQL +Url: https://www.postgresql.org/ + +Source0: https://download.postgresql.org/pub/source/v%{version}/postgresql-%{version}.tar.bz2 +Source4: %{sname}-%{pgmajorversion}-Makefile.regress +Source5: %{sname}-%{pgmajorversion}-pg_config.h +Source6: %{sname}-%{pgmajorversion}-README-systemd.rpm-dist +Source7: %{sname}-%{pgmajorversion}-ecpg_config.h +Source9: %{sname}-%{pgmajorversion}-libs.conf +Source12: https://www.postgresql.org/files/documentation/pdf/%{pgpackageversion}/%{sname}-%{pgpackageversion}-A4.pdf +Source14: %{sname}-%{pgmajorversion}.pam +Source16: %{sname}-%{pgmajorversion}-filter-requires-perl-Pg.sh +Source17: %{sname}-%{pgmajorversion}-setup +%if %{systemd_enabled} +Source10: %{sname}-%{pgmajorversion}-check-db-dir +Source18: %{sname}-%{pgmajorversion}.service +Source19: %{sname}-%{pgmajorversion}-tmpfiles.d +%else +Source3: %{sname}-%{pgmajorversion}.init +%endif + +Patch1: %{sname}-%{pgmajorversion}-rpm-pgsql.patch +Patch3: %{sname}-%{pgmajorversion}-conf.patch +Patch5: %{sname}-%{pgmajorversion}-var-run-socket.patch +Patch6: %{sname}-%{pgmajorversion}-perl-rpath.patch + +BuildRequires: perl glibc-devel bison flex >= 2.5.31 +BuildRequires: perl(ExtUtils::MakeMaker) perl(IPC::Run) +BuildRequires: readline-devel zlib-devel >= 1.0.4 +BuildRequires: clang clang-devel +BuildRequires: llvm llvm-devel llvm-libs + +# This dependency is needed for Source 16: +%if 0%{?fedora} || 0%{?rhel} > 7 +BuildRequires: perl-generators +%endif + +%if 0%{?rhel} && 0%{?rhel} == 7 +%ifarch ppc64 ppc64le +%pgdg_set_ppc64le_min_requires +%endif +%endif + +Requires: /sbin/ldconfig + +%if %icu +BuildRequires: libicu-devel +Requires: libicu +%endif + +%if %llvm +%if 0%{?rhel} && 0%{?rhel} == 7 +# Packages come from EPEL and SCL: +%ifarch aarch64 +BuildRequires: llvm-toolset-7.0-llvm-devel >= 7.0.1 llvm-toolset-7.0-clang >= 7.0.1 +%else +BuildRequires: llvm5.0-devel >= 5.0 llvm-toolset-7-clang >= 4.0.1 +%endif +%endif +%if 0%{?rhel} && 0%{?rhel} >= 8 +# Packages come from Appstream: +BuildRequires: llvm-devel >= 8.0.1 clang-devel >= 8.0.1 +%endif +%if 0%{?fedora} +BuildRequires: llvm-devel >= 5.0 clang-devel >= 5.0 +%endif +%if 0%{?suse_version} >= 1315 && 0%{?suse_version} <= 1499 +BuildRequires: llvm6-devel clang6-devel +%endif +%if 0%{?suse_version} >= 1500 +BuildRequires: llvm10-devel clang10-devel +%endif +%endif + +%if %kerberos +BuildRequires: krb5-devel +BuildRequires: e2fsprogs-devel +%endif + +%if %ldap +%if 0%{?suse_version} +%if 0%{?suse_version} >= 1315 +BuildRequires: openldap2-devel +%endif +%else +BuildRequires: openldap-devel +%endif +%endif + +%if %nls +BuildRequires: gettext >= 0.10.35 +%endif + +%if %pam +BuildRequires: pam-devel +%endif + +%if %plperl +%if 0%{?rhel} && 0%{?rhel} >= 7 +BuildRequires: perl-ExtUtils-Embed +%endif +%if 0%{?fedora} >= 22 +BuildRequires: perl-ExtUtils-Embed +%endif +%endif + +%if %plpython3 +BuildRequires: python3-devel +%endif + +%if %pltcl +BuildRequires: tcl-devel +%endif + +%if %sdt +BuildRequires: systemtap-sdt-devel +%endif + +%if %selinux +# All supported distros have libselinux-devel package: +BuildRequires: libselinux-devel >= 2.0.93 +# SLES: SLES 15 does not have selinux-policy package. Use +# it only on SLES 12: +%if 0%{?suse_version} >= 1315 && 0%{?suse_version} <= 1499 +BuildRequires: selinux-policy >= 3.9.13 +%endif +# RHEL/Fedora has selinux-policy: +%if 0%{?rhel} || 0%{?fedora} +BuildRequires: selinux-policy >= 3.9.13 +%endif +%endif + +%if %ssl +# We depend un the SSL libraries provided by Advance Toolchain on PPC, +# so use openssl-devel only on other platforms: +%ifnarch ppc64 ppc64le +%if 0%{?suse_version} >= 1315 && 0%{?suse_version} <= 1499 +BuildRequires: libopenssl-devel +%else +BuildRequires: openssl-devel +%endif +%endif +%endif + +%if %uuid +%if 0%{?suse_version} +%if 0%{?suse_version} >= 1315 +BuildRequires: uuid-devel +%endif +%else +BuildRequires: libuuid-devel +%endif +%endif + +%if %xml +BuildRequires: libxml2-devel libxslt-devel +%endif + +%if %{systemd_enabled} +BuildRequires: systemd, systemd-devel +# We require this to be present for %%{_prefix}/lib/tmpfiles.d +Requires: systemd +%if 0%{?suse_version} +%if 0%{?suse_version} >= 1315 +Requires(post): systemd-sysvinit +%endif +%else +Requires(post): systemd-sysv +Requires(post): systemd +Requires(preun): systemd +Requires(postun): systemd +%endif +%else +Requires(post): chkconfig +Requires(preun): chkconfig +# This is for /sbin/service +Requires(preun): initscripts +Requires(postun): initscripts +%endif + +Requires: %{name}-libs%{?_isa} = %{version}-%{release} + +Requires(post): %{_sbindir}/update-alternatives +Requires(postun): %{_sbindir}/update-alternatives + +Provides: %{sname} >= %{version}-%{release} + +%description +PostgreSQL is an advanced Object-Relational database management system (DBMS). +The base postgresql package contains the client programs that you'll need to +access a PostgreSQL DBMS server, as well as HTML documentation for the whole +system. These client programs can be located on the same machine as the +PostgreSQL server, or on a remote machine that accesses a PostgreSQL server +over a network connection. The PostgreSQL server can be found in the +postgresql%{pgmajorversion}-server sub-package. + +If you want to manipulate a PostgreSQL database on a local or remote PostgreSQL +server, you need this package. You also need to install this package +if you're installing the postgresql%{pgmajorversion}-server package. + +%package libs +Summary: The shared libraries required for any PostgreSQL clients +Provides: postgresql-libs = %{pgmajorversion} libpq5 >= 10.0 + +%if 0%{?rhel} && 0%{?rhel} <= 6 +Requires: openssl +%else +%if 0%{?suse_version} >= 1315 && 0%{?suse_version} <= 1499 +Requires: libopenssl1_0_0 +%else +%if 0%{?suse_version} >= 1500 +Requires: libopenssl1_1 +%else +Requires: openssl-libs >= 1.0.2k +%endif +%endif +%endif + +%if 0%{?rhel} && 0%{?rhel} == 7 +%ifarch ppc64 ppc64le +AutoReq: 0 +Requires: advance-toolchain-%{atstring}-runtime +%endif +%endif + +%description libs +The postgresql%{pgmajorversion}-libs package provides the essential shared libraries for any +PostgreSQL client program or interface. You will need to install this package +to use any other PostgreSQL package or any clients that need to connect to a +PostgreSQL server. + +%package server +Summary: The programs needed to create and run a PostgreSQL server +Requires: %{name}%{?_isa} = %{version}-%{release} +Requires: %{name}-libs%{?_isa} = %{version}-%{release} +Requires(pre): /usr/sbin/useradd /usr/sbin/groupadd +# for /sbin/ldconfig +Requires(post): glibc +Requires(postun): glibc +%if %{systemd_enabled} +# pre/post stuff needs systemd too + +%if 0%{?suse_version} +%if 0%{?suse_version} >= 1315 +Requires(post): systemd +%endif +%else +Requires(post): systemd +Requires(preun): systemd +Requires(postun): systemd +%endif +%else +Requires: /usr/sbin/useradd, /sbin/chkconfig +%endif +Provides: postgresql-server >= %{version}-%{release} + +%if 0%{?rhel} && 0%{?rhel} == 7 +%ifarch ppc64 ppc64le +AutoReq: 0 +Requires: advance-toolchain-%{atstring}-runtime +%endif +%endif + +%description server +PostgreSQL is an advanced Object-Relational database management system (DBMS). +The postgresql%{pgmajorversion}-server package contains the programs needed to create +and run a PostgreSQL server, which will in turn allow you to create +and maintain PostgreSQL databases. + +%package docs +Summary: Extra documentation for PostgreSQL +Provides: postgresql-docs >= %{version}-%{release} + +%description docs +The postgresql%{pgmajorversion}-docs package includes the SGML source for the documentation +as well as the documentation in PDF format and some extra documentation. +Install this package if you want to help with the PostgreSQL documentation +project, or if you want to generate printed documentation. This package also +includes HTML version of the documentation. + +%package contrib +Summary: Contributed source and binaries distributed with PostgreSQL +Requires: %{name}%{?_isa} = %{version}-%{release} +Requires: %{name}-libs%{?_isa} = %{version}-%{release} +Requires: %{name}-server%{?_isa} = %{version}-%{release} +Provides: postgresql-contrib >= %{version}-%{release} + +%if 0%{?rhel} && 0%{?rhel} == 7 +%ifarch ppc64 ppc64le +AutoReq: 0 +Requires: advance-toolchain-%{atstring}-runtime +%endif +%endif + +%description contrib +The postgresql%{pgmajorversion}-contrib package contains various extension modules that are +included in the PostgreSQL distribution. + +%package devel +Summary: PostgreSQL development header files and libraries +Requires: %{name}%{?_isa} = %{version}-%{release} +Requires: %{name}-libs%{?_isa} = %{version}-%{release} +%if %llvm +%if 0%{?rhel} && 0%{?rhel} == 7 +# Packages come from EPEL and SCL: +%ifarch aarch64 +Requires: llvm-toolset-7.0-llvm-devel >= 7.0.1 llvm-toolset-7.0-clang >= 7.0.1 +%else +Requires: llvm5.0-devel >= 5.0 llvm-toolset-7-clang >= 4.0.1 +%endif +%endif +%if 0%{?rhel} && 0%{?rhel} >= 8 +# Packages come from Appstream: +Requires: llvm-devel >= 8.0.1 clang-devel >= 8.0.1 +%endif +%if 0%{?fedora} +Requires: llvm-devel >= 5.0 clang-devel >= 5.0 +%endif +%if 0%{?suse_version} >= 1315 && 0%{?suse_version} <= 1499 +Requires: llvm6-devel clang6-devel +%endif +%if 0%{?suse_version} >= 1500 +BuildRequires: llvm10-devel clang10-devel +%endif +%endif +%if %icu +Requires: libicu-devel +%endif + +%if %enabletaptests +%if 0%{?suse_version} && 0%{?suse_version} >= 1315 +Requires: perl-IPC-Run +BuildRequires: perl-IPC-Run +%endif +%if 0%{?rhel} && 0%{?rhel} <= 7 +Requires: perl-Test-Simple +BuildRequires: perl-Test-Simple +%endif +%if 0%{?fedora} +Requires: perl-IPC-Run +BuildRequires: perl-IPC-Run +%endif +%endif + +Provides: postgresql-devel >= %{version}-%{release} +Obsoletes: libpq-devel <= 42.0 + +%if 0%{?rhel} && 0%{?rhel} == 7 +%ifarch ppc64 ppc64le +AutoReq: 0 +Requires: advance-toolchain-%{atstring}-runtime +%endif +%endif + +%description devel +The postgresql%{pgmajorversion}-devel package contains the header files and libraries +needed to compile C or C++ applications which will directly interact +with a PostgreSQL database management server. It also contains the ecpg +Embedded C Postgres preprocessor. You need to install this package if you want +to develop applications which will interact with a PostgreSQL server. + +%if %llvm +%package llvmjit +Summary: Just-in-time compilation support for PostgreSQL +Requires: %{name}-server%{?_isa} = %{version}-%{release} +%if 0%{?rhel} && 0%{?rhel} == 7 +%ifarch aarch64 +Requires: llvm-toolset-7.0-llvm >= 7.0.1 +%else +Requires: llvm5.0 >= 5.0 +%endif +%endif +%if 0%{?suse_version} == 1315 +Requires: llvm +%endif +%if 0%{?suse_version} >= 1500 +Requires: llvm10 +%endif +%if 0%{?fedora} || 0%{?rhel} >= 8 +Requires: llvm => 5.0 +%endif + +Provides: postgresql-llvmjit >= %{version}-%{release} + +%if 0%{?rhel} && 0%{?rhel} == 7 +%ifarch ppc64 ppc64le +AutoReq: 0 +Requires: advance-toolchain-%{atstring}-runtime +%endif +%endif + +%description llvmjit +The postgresql%{pgmajorversion}-llvmjit package contains support for +just-in-time compiling parts of PostgreSQL queries. Using LLVM it +compiles e.g. expressions and tuple deforming into native code, with the +goal of accelerating analytics queries. +%endif + +%if %plperl +%package plperl +Summary: The Perl procedural language for PostgreSQL +Requires: %{name}-server%{?_isa} = %{version}-%{release} +Requires: perl(:MODULE_COMPAT_%(eval "`%{__perl} -V:version`"; echo $version)) +%ifarch ppc ppc64 +BuildRequires: perl-devel +%endif +Obsoletes: postgresql%{pgmajorversion}-pl <= %{version}-%{release} +Provides: postgresql-plperl >= %{version}-%{release} + +%if 0%{?rhel} && 0%{?rhel} == 7 +%ifarch ppc64 ppc64le +AutoReq: 0 +Requires: advance-toolchain-%{atstring}-runtime +%endif +%endif + +%description plperl +The postgresql%{pgmajorversion}-plperl package contains the PL/Perl procedural language, +which is an extension to the PostgreSQL database server. +Install this if you want to write database functions in Perl. + +%endif + +%if %plpython3 +%package plpython3 +Summary: The Python3 procedural language for PostgreSQL +Requires: %{name}%{?_isa} = %{version}-%{release} +Requires: %{name}-server%{?_isa} = %{version}-%{release} +Obsoletes: %{name}-pl <= %{version}-%{release} +Provides: postgresql-plpython3 >= %{version}-%{release} +%if 0%{?rhel} == 7 +# We support Python3 natively on RHEL/CentOS 7 as of 7.7+, +Requires: python3-libs +%else +Requires: python3-libs +%endif + +%if 0%{?rhel} && 0%{?rhel} == 7 +%ifarch ppc64 ppc64le +AutoReq: 0 +Requires: advance-toolchain-%{atstring}-runtime +%endif +%endif + +%description plpython3 +The postgresql%{pgmajorversion}-plpython3 package contains the PL/Python3 procedural language, +which is an extension to the PostgreSQL database server. +Install this if you want to write database functions in Python 3. + +%endif + +%if %pltcl +%package pltcl +Summary: The Tcl procedural language for PostgreSQL +Requires: %{name}%{?_isa} = %{version}-%{release} +Requires: %{name}-server%{?_isa} = %{version}-%{release} +Requires: tcl +Obsoletes: %{name}-pl <= %{version}-%{release} +Provides: postgresql-pltcl >= %{version}-%{release} + +%if 0%{?rhel} && 0%{?rhel} == 7 +%ifarch ppc64 ppc64le +AutoReq: 0 +Requires: advance-toolchain-%{atstring}-runtime +%endif +%endif + +%description pltcl +PostgreSQL is an advanced Object-Relational database management +system. The %{name}-pltcl package contains the PL/Tcl language +for the backend. +%endif + +%if %test +%package test +Summary: The test suite distributed with PostgreSQL +Requires: %{name}-server%{?_isa} = %{version}-%{release} +Requires: %{name}-devel%{?_isa} = %{version}-%{release} +Provides: postgresql-test >= %{version}-%{release} + +%if 0%{?rhel} && 0%{?rhel} == 7 +%ifarch ppc64 ppc64le +AutoReq: 0 +Requires: advance-toolchain-%{atstring}-runtime +%endif +%endif + +%description test +The postgresql%{pgmajorversion}-test package contains files needed for various tests for the +PostgreSQL database management system, including regression tests and +benchmarks. +%endif + +%global __perl_requires %{SOURCE16} + +%prep +%setup -q -n %{sname}-%{version} +%patch1 -p0 +%patch3 -p0 +%patch5 -p0 +%patch6 -p0 + +%{__cp} -p %{SOURCE12} . + +%build + +# fail quickly and obviously if user tries to build as root +%if %runselftest + if [ x"`id -u`" = x0 ]; then + echo "postgresql's regression tests fail if run as root." + echo "If you really need to build the RPM as root, use" + echo "--define='runselftest 0' to skip the regression tests." + exit 1 + fi +%endif + +CFLAGS="${CFLAGS:-%optflags}" +%if 0%{?rhel} && 0%{?rhel} == 7 +%ifarch ppc64 ppc64le + CFLAGS="${CFLAGS} $(echo %{__global_cflags} | sed 's/-O2/-O3/g') -m64 -mcpu=power8 -mtune=power8 -I%{atpath}/include" + CXXFLAGS="${CXXFLAGS} $(echo %{__global_cflags} | sed 's/-O2/-O3/g') -m64 -mcpu=power8 -mtune=power8 -I%{atpath}/include" + LDFLAGS="-L%{atpath}/%{_lib}" + CC=%{atpath}/bin/gcc; export CC +%endif +%else + # Strip out -ffast-math from CFLAGS.... + CFLAGS=`echo $CFLAGS|xargs -n 1|grep -v ffast-math|xargs -n 100` + %if 0%{?rhel} + LDFLAGS="-Wl,--as-needed"; export LDFLAGS + %endif +%endif + +export CFLAGS + +%if %plpython3 + +export PYTHON=/usr/bin/python3 + +%if 0%{?rhel} && 0%{?rhel} == 7 +%ifarch aarch64 + export CLANG=/opt/rh/llvm-toolset-7.0/root/usr/bin/clang LLVM_CONFIG=/opt/rh/llvm-toolset-7.0/root/usr/bin/llvm-config +%else + export CLANG=/opt/rh/llvm-toolset-7/root/usr/bin/clang LLVM_CONFIG=%{_libdir}/llvm5.0/bin/llvm-config +%endif +%endif +%if 0%{?rhel} && 0%{?rhel} == 8 + export CLANG=%{_bindir}/clang LLVM_CONFIG=%{_bindir}/llvm-config-64 +%endif + +# These configure options must match main build +./configure --enable-rpath \ + --prefix=%{pgbaseinstdir} \ + --includedir=%{pgbaseinstdir}/include \ + --mandir=%{pgbaseinstdir}/share/man \ + --datadir=%{pgbaseinstdir}/share \ + --libdir=%{pgbaseinstdir}/lib \ +%if %beta + --enable-debug \ + --enable-cassert \ +%endif +%if %enabletaptests + --enable-tap-tests \ +%endif +%if %icu + --with-icu \ +%endif +%if %llvm + --with-llvm \ +%endif +%if %plperl + --with-perl \ +%endif +%if %plpython3 + --with-python \ +%endif +%if %pltcl + --with-tcl \ + --with-tclconfig=%{_libdir} \ +%endif +%if %ssl + --with-openssl \ +%endif +%if %pam + --with-pam \ +%endif +%if %kerberos + --with-gssapi \ + --with-includes=%{kerbdir}/include \ + --with-libraries=%{kerbdir}/%{_lib} \ +%endif +%if %nls + --enable-nls \ +%endif +%if %sdt + --enable-dtrace \ +%endif +%if %disablepgfts + --disable-thread-safety \ +%endif +%if %uuid + --with-uuid=e2fs \ +%endif +%if %xml + --with-libxml \ + --with-libxslt \ +%endif +%if %ldap + --with-ldap \ +%endif +%if %selinux + --with-selinux \ +%endif +%if %{systemd_enabled} + --with-systemd \ +%endif +%if 0%{?rhel} && 0%{?rhel} == 7 +%ifarch ppc64 ppc64le + --with-includes=%{atpath}/include \ + --with-libraries=%{atpath}/lib64 \ +%endif +%endif + --with-system-tzdata=%{_datadir}/zoneinfo \ + --sysconfdir=/etc/sysconfig/pgsql \ + --docdir=%{pgbaseinstdir}/doc \ + --htmldir=%{pgbaseinstdir}/doc/html + +%endif + +cd src/backend +MAKELEVEL=0 %{__make} submake-generated-headers +cd ../.. + +# Have to hack makefile to put correct path into tutorial scripts +sed "s|C=\`pwd\`;|C=%{pgbaseinstdir}/lib/tutorial;|" < src/tutorial/Makefile > src/tutorial/GNUmakefile +%{__make} %{?_smp_mflags} -C src/tutorial NO_PGXS=1 all +%{__rm} -f src/tutorial/GNUmakefile + +%{__mkdir} -p %{buildroot}%{pgbaseinstdir}/share/extensions/ +MAKELEVEL=0 %{__make} %{?_smp_mflags} all +%{__make} %{?_smp_mflags} -C contrib all +%if %uuid +%{__make} %{?_smp_mflags} -C contrib/uuid-ossp all +%endif + + +# run_testsuite WHERE +# ------------------- +# Run 'make check' in WHERE path. When that command fails, return the logs +# given by PostgreSQL build system and set 'test_failure=1'. + +run_testsuite() +{ + %{__make} -C "$1" MAX_CONNECTIONS=5 check && return 0 + + test_failure=1 + + ( + set +x + echo "=== trying to find all regression.diffs files in build directory ===" + find -name 'regression.diffs' | \ + while read line; do + echo "=== make failure: $line ===" + cat "$line" + done + ) +} + +%if %runselftest + run_testsuite "src/test/regress" + %{__make} clean -C "src/test/regress" + run_testsuite "src/pl" +%if %plpython3 + run_testsuite "src/pl/plpython" +%endif + run_testsuite "contrib" +%endif + +%if %test + pushd src/test/regress + %{__make} all + popd +%endif + +%install +%{__rm} -rf %{buildroot} + +%{__make} DESTDIR=%{buildroot} install + +%if %plpython3 + # Install PL/Python3 + pushd src/pl/plpython + %{__make} DESTDIR=%{buildroot} install + popd + +%endif + +%{__mkdir} -p %{buildroot}%{pgbaseinstdir}/share/extensions/ +%{__make} -C contrib DESTDIR=%{buildroot} install +%if %uuid +%{__make} -C contrib/uuid-ossp DESTDIR=%{buildroot} install +%endif + +# multilib header hack; note pg_config.h is installed in two places! +# we only apply this to known Red Hat multilib arches, per bug #177564 +case `uname -i` in + i386 | x86_64 | ppc | ppc64 | s390 | s390x) + %{__mv} %{buildroot}%{pgbaseinstdir}/include/pg_config.h %{buildroot}%{pgbaseinstdir}/include/pg_config_`uname -i`.h + %{__install} -m 644 %{SOURCE5} %{buildroot}%{pgbaseinstdir}/include/pg_config.h + %{__mv} %{buildroot}%{pgbaseinstdir}/include/server/pg_config.h %{buildroot}%{pgbaseinstdir}/include/server/pg_config_`uname -i`.h + %{__install} -m 644 %{SOURCE5} %{buildroot}%{pgbaseinstdir}/include/server/pg_config.h + %{__mv} %{buildroot}%{pgbaseinstdir}/include/ecpg_config.h %{buildroot}%{pgbaseinstdir}/include/ecpg_config_`uname -i`.h + %{__install} -m 644 %{SOURCE7} %{buildroot}%{pgbaseinstdir}/include/ecpg_config.h + ;; + *) + ;; +esac + +# This is only for systemd supported distros: +%if %{systemd_enabled} +# prep the setup script, including insertion of some values it needs +sed -e 's|^PGVERSION=.*$|PGVERSION=%{pgmajorversion}|' \ + -e 's|^PGENGINE=.*$|PGENGINE=%{pgbaseinstdir}/bin|' \ + -e 's|^PREVMAJORVERSION=.*$|PREVMAJORVERSION=%{prevmajorversion}|' \ + <%{SOURCE17} >postgresql-%{pgmajorversion}-setup +%{__install} -m 755 postgresql-%{pgmajorversion}-setup %{buildroot}%{pgbaseinstdir}/bin/postgresql-%{pgmajorversion}-setup +# Create a symlink of the setup script under $PATH +%{__mkdir} -p %{buildroot}%{_bindir} +%{__ln_s} %{pgbaseinstdir}/bin/postgresql-%{pgmajorversion}-setup %{buildroot}%{_bindir}/%{sname}-%{pgmajorversion}-setup + +# prep the startup check script, including insertion of some values it needs +sed -e 's|^PGVERSION=.*$|PGVERSION=%{pgmajorversion}|' \ + -e 's|^PREVMAJORVERSION=.*$|PREVMAJORVERSION=%{prevmajorversion}|' \ + -e 's|^PGDOCDIR=.*$|PGDOCDIR=%{_pkgdocdir}|' \ + <%{SOURCE10} >%{sname}-%{pgmajorversion}-check-db-dir +touch -r %{SOURCE10} %{sname}-%{pgmajorversion}-check-db-dir +%{__install} -m 755 %{sname}-%{pgmajorversion}-check-db-dir %{buildroot}%{pgbaseinstdir}/bin/%{sname}-%{pgmajorversion}-check-db-dir + +%{__install} -d %{buildroot}%{_unitdir} +%{__install} -m 644 %{SOURCE18} %{buildroot}%{_unitdir}/%{sname}-%{pgmajorversion}.service +%else +%{__install} -d %{buildroot}%{_initrddir} +sed 's/^PGVERSION=.*$/PGVERSION=%{version}/' <%{SOURCE3} > %{sname}.init +%{__install} -m 755 %{sname}.init %{buildroot}%{_initrddir}/%{sname}-%{pgmajorversion} +%endif + +%if %pam +%{__install} -d %{buildroot}/etc/pam.d +%{__install} -m 644 %{SOURCE14} %{buildroot}/etc/pam.d/%{sname} +%endif + +# Create the directory for sockets. +%{__install} -d -m 755 %{buildroot}/var/run/%{sname} +%if %{systemd_enabled} +# ... and make a tmpfiles script to recreate it at reboot. +%{__mkdir} -p %{buildroot}/%{_tmpfilesdir} +%{__install} -m 0644 %{SOURCE19} %{buildroot}/%{_tmpfilesdir}/%{sname}-%{pgmajorversion}.conf +%endif + +# PGDATA needs removal of group and world permissions due to pg_pwd hole. +%{__install} -d -m 700 %{buildroot}/var/lib/pgsql/%{pgmajorversion}/data + +# backups of data go here... +%{__install} -d -m 700 %{buildroot}/var/lib/pgsql/%{pgmajorversion}/backups + +# Create the multiple postmaster startup directory +%{__install} -d -m 700 %{buildroot}/etc/sysconfig/pgsql/%{pgmajorversion} + +# Install linker conf file under postgresql installation directory. +# We will install the latest version via alternatives. +%{__install} -d -m 755 %{buildroot}%{pgbaseinstdir}/share/ +%{__install} -m 700 %{SOURCE9} %{buildroot}%{pgbaseinstdir}/share/ + +%if %test + # tests. There are many files included here that are unnecessary, + # but include them anyway for completeness. We replace the original + # Makefiles, however. + %{__mkdir} -p %{buildroot}%{pgbaseinstdir}/lib/test + %{__cp} -a src/test/regress %{buildroot}%{pgbaseinstdir}/lib/test + %{__install} -m 0755 contrib/spi/refint.so %{buildroot}%{pgbaseinstdir}/lib/test/regress + %{__install} -m 0755 contrib/spi/autoinc.so %{buildroot}%{pgbaseinstdir}/lib/test/regress + pushd %{buildroot}%{pgbaseinstdir}/lib/test/regress + strip *.so + %{__rm} -f GNUmakefile Makefile *.o + chmod 0755 pg_regress regress.so + popd + %{__cp} %{SOURCE4} %{buildroot}%{pgbaseinstdir}/lib/test/regress/Makefile + chmod 0644 %{buildroot}%{pgbaseinstdir}/lib/test/regress/Makefile +%endif + +# Quick hack: +%{__rm} -f %{buildroot}/%{pgbaseinstdir}/share/extension/*plpython2u* +%{__rm} -f %{buildroot}/%{pgbaseinstdir}/share/extension/*plpythonu-* +%{__rm} -f %{buildroot}/%{pgbaseinstdir}/share/extension/*_plpythonu.control + +# Fix some more documentation +# gzip doc/internals.ps +%{__cp} %{SOURCE6} README.rpm-dist +%{__mkdir} -p %{buildroot}%{pgbaseinstdir}/share/doc/html +%{__mv} doc/src/sgml/html doc +%{__mkdir} -p %{buildroot}%{pgbaseinstdir}/share/man/ +%{__mv} doc/src/sgml/man1 doc/src/sgml/man3 doc/src/sgml/man7 %{buildroot}%{pgbaseinstdir}/share/man/ +%{__rm} -rf %{buildroot}%{_docdir}/pgsql + +# initialize file lists +%{__cp} /dev/null main.lst +%{__cp} /dev/null libs.lst +%{__cp} /dev/null server.lst +%{__cp} /dev/null devel.lst +%{__cp} /dev/null plperl.lst +%{__cp} /dev/null pltcl.lst +%{__cp} /dev/null plpython.lst +%{__cp} /dev/null pg_plpython3.lst +%{__cp} /dev/null pg_checksums.lst + +%if %nls +%find_lang ecpg-%{pgmajorversion} +%find_lang ecpglib6-%{pgmajorversion} +%find_lang initdb-%{pgmajorversion} +%find_lang libpq5-%{pgmajorversion} +%find_lang pg_archivecleanup-%{pgmajorversion} +%find_lang pg_basebackup-%{pgmajorversion} +%find_lang pg_checksums-%{pgmajorversion} +%find_lang pg_config-%{pgmajorversion} +%find_lang pg_controldata-%{pgmajorversion} +%find_lang pg_ctl-%{pgmajorversion} +%find_lang pg_dump-%{pgmajorversion} +%find_lang pg_resetwal-%{pgmajorversion} +%find_lang pg_rewind-%{pgmajorversion} +%find_lang pg_test_fsync-%{pgmajorversion} +%find_lang pg_test_timing-%{pgmajorversion} +%find_lang pg_upgrade-%{pgmajorversion} +%find_lang pg_verifybackup-%{pgmajorversion} +%find_lang pg_waldump-%{pgmajorversion} +%find_lang pgscripts-%{pgmajorversion} +%if %plperl +%find_lang plperl-%{pgmajorversion} +cat plperl-%{pgmajorversion}.lang > pg_plperl.lst +%endif +%find_lang plpgsql-%{pgmajorversion} +%if %plpython3 +# plpython3 shares message files with plpython +%find_lang plpython-%{pgmajorversion} +cat plpython-%{pgmajorversion}.lang >> pg_plpython3.lst +%endif + +%if %pltcl +%find_lang pltcl-%{pgmajorversion} +cat pltcl-%{pgmajorversion}.lang > pg_pltcl.lst +%endif +%find_lang postgres-%{pgmajorversion} +%find_lang psql-%{pgmajorversion} + +cat libpq5-%{pgmajorversion}.lang > pg_libpq5.lst +cat pg_config-%{pgmajorversion}.lang ecpg-%{pgmajorversion}.lang ecpglib6-%{pgmajorversion}.lang > pg_devel.lst +cat initdb-%{pgmajorversion}.lang pg_ctl-%{pgmajorversion}.lang psql-%{pgmajorversion}.lang pg_dump-%{pgmajorversion}.lang pg_basebackup-%{pgmajorversion}.lang pgscripts-%{pgmajorversion}.lang > pg_main.lst +cat postgres-%{pgmajorversion}.lang pg_resetwal-%{pgmajorversion}.lang pg_checksums-%{pgmajorversion}.lang pg_verifybackup-%{pgmajorversion}.lang pg_controldata-%{pgmajorversion}.lang plpgsql-%{pgmajorversion}.lang pg_test_timing-%{pgmajorversion}.lang pg_test_fsync-%{pgmajorversion}.lang pg_archivecleanup-%{pgmajorversion}.lang pg_waldump-%{pgmajorversion}.lang pg_rewind-%{pgmajorversion}.lang pg_upgrade-%{pgmajorversion}.lang > pg_server.lst +%endif + +%pre server +groupadd -g 26 -o -r postgres >/dev/null 2>&1 || : +useradd -M -g postgres -o -r -d /var/lib/pgsql -s /bin/bash \ + -c "PostgreSQL Server" -u 26 postgres >/dev/null 2>&1 || : + +%post server +/sbin/ldconfig +if [ $1 -eq 1 ] ; then + %if %{systemd_enabled} + /bin/systemctl daemon-reload >/dev/null 2>&1 || : + %if 0%{?suse_version} + %if 0%{?suse_version} >= 1315 + %service_add_pre postgresql-%{pgpackageversion}.service + %endif + %else + %systemd_post %{sname}-%{pgpackageversion}.service + %endif + %else + chkconfig --add %{sname}-%{pgpackageversion} + %endif +fi + +# postgres' .bash_profile. +# We now don't install .bash_profile as we used to in pre 9.0. Instead, use cat, +# so that package manager will be happy during upgrade to new major version. +echo "[ -f /etc/profile ] && source /etc/profile +PGDATA=/var/lib/pgsql/%{pgmajorversion}/data +export PGDATA +# If you want to customize your settings, +# Use the file below. This is not overridden +# by the RPMS. +[ -f /var/lib/pgsql/.pgsql_profile ] && source /var/lib/pgsql/.pgsql_profile" > /var/lib/pgsql/.bash_profile +chown postgres: /var/lib/pgsql/.bash_profile +chmod 700 /var/lib/pgsql/.bash_profile + +%preun server +if [ $1 -eq 0 ] ; then +%if %{systemd_enabled} + # Package removal, not upgrade + /bin/systemctl --no-reload disable %{sname}-%{pgmajorversion}.service >/dev/null 2>&1 || : + /bin/systemctl stop %{sname}-%{pgmajorversion}.service >/dev/null 2>&1 || : +%else + /sbin/service %{sname}-%{pgmajorversion} condstop >/dev/null 2>&1 + chkconfig --del %{sname}-%{pgmajorversion} + +%endif +fi + +%postun server +/sbin/ldconfig +%if %{systemd_enabled} + /bin/systemctl daemon-reload >/dev/null 2>&1 || : +%else + /sbin/service %{sname}-%{pgmajorversion} condrestart >/dev/null 2>&1 +%endif +if [ $1 -ge 1 ] ; then + %if %{systemd_enabled} + # Package upgrade, not uninstall + /bin/systemctl try-restart %{sname}-%{pgmajorversion}.service >/dev/null 2>&1 || : + %else + /sbin/service %{sname}-%{pgmajorversion} condrestart >/dev/null 2>&1 + %endif +fi + +# Create alternatives entries for common binaries and man files +%post +%{_sbindir}/update-alternatives --install %{_bindir}/psql pgsql-psql %{pgbaseinstdir}/bin/psql %{packageversion}0 +%{_sbindir}/update-alternatives --install %{_bindir}/clusterdb pgsql-clusterdb %{pgbaseinstdir}/bin/clusterdb %{packageversion}0 +%{_sbindir}/update-alternatives --install %{_bindir}/createdb pgsql-createdb %{pgbaseinstdir}/bin/createdb %{packageversion}0 +%{_sbindir}/update-alternatives --install %{_bindir}/createuser pgsql-createuser %{pgbaseinstdir}/bin/createuser %{packageversion}0 +%{_sbindir}/update-alternatives --install %{_bindir}/dropdb pgsql-dropdb %{pgbaseinstdir}/bin/dropdb %{packageversion}0 +%{_sbindir}/update-alternatives --install %{_bindir}/dropuser pgsql-dropuser %{pgbaseinstdir}/bin/dropuser %{packageversion}0 +%{_sbindir}/update-alternatives --install %{_bindir}/pg_basebackup pgsql-pg_basebackup %{pgbaseinstdir}/bin/pg_basebackup %{packageversion}0 +%{_sbindir}/update-alternatives --install %{_bindir}/pg_dump pgsql-pg_dump %{pgbaseinstdir}/bin/pg_dump %{packageversion}0 +%{_sbindir}/update-alternatives --install %{_bindir}/pg_dumpall pgsql-pg_dumpall %{pgbaseinstdir}/bin/pg_dumpall %{packageversion}0 +%{_sbindir}/update-alternatives --install %{_bindir}/pg_restore pgsql-pg_restore %{pgbaseinstdir}/bin/pg_restore %{packageversion}0 +%{_sbindir}/update-alternatives --install %{_bindir}/reindexdb pgsql-reindexdb %{pgbaseinstdir}/bin/reindexdb %{packageversion}0 +%{_sbindir}/update-alternatives --install %{_bindir}/vacuumdb pgsql-vacuumdb %{pgbaseinstdir}/bin/vacuumdb %{packageversion}0 +%{_sbindir}/update-alternatives --install %{_mandir}/man1/clusterdb.1 pgsql-clusterdbman %{pgbaseinstdir}/share/man/man1/clusterdb.1 %{packageversion}0 +%{_sbindir}/update-alternatives --install %{_mandir}/man1/createdb.1 pgsql-createdbman %{pgbaseinstdir}/share/man/man1/createdb.1 %{packageversion}0 +%{_sbindir}/update-alternatives --install %{_mandir}/man1/createuser.1 pgsql-createuserman %{pgbaseinstdir}/share/man/man1/createuser.1 %{packageversion}0 +%{_sbindir}/update-alternatives --install %{_mandir}/man1/dropdb.1 pgsql-dropdbman %{pgbaseinstdir}/share/man/man1/dropdb.1 %{packageversion}0 +%{_sbindir}/update-alternatives --install %{_mandir}/man1/dropuser.1 pgsql-dropuserman %{pgbaseinstdir}/share/man/man1/dropuser.1 %{packageversion}0 +%{_sbindir}/update-alternatives --install %{_mandir}/man1/pg_basebackup.1 pgsql-pg_basebackupman %{pgbaseinstdir}/share/man/man1/pg_basebackup.1 %{packageversion}0 +%{_sbindir}/update-alternatives --install %{_mandir}/man1/pg_dump.1 pgsql-pg_dumpman %{pgbaseinstdir}/share/man/man1/pg_dump.1 %{packageversion}0 +%{_sbindir}/update-alternatives --install %{_mandir}/man1/pg_dumpall.1 pgsql-pg_dumpallman %{pgbaseinstdir}/share/man/man1/pg_dumpall.1 %{packageversion}0 +%{_sbindir}/update-alternatives --install %{_mandir}/man1/pg_restore.1 pgsql-pg_restoreman %{pgbaseinstdir}/share/man/man1/pg_restore.1 %{packageversion}0 +%{_sbindir}/update-alternatives --install %{_mandir}/man1/psql.1 pgsql-psqlman %{pgbaseinstdir}/share/man/man1/psql.1 %{packageversion}0 +%{_sbindir}/update-alternatives --install %{_mandir}/man1/reindexdb.1 pgsql-reindexdbman %{pgbaseinstdir}/share/man/man1/reindexdb.1 %{packageversion}0 +%{_sbindir}/update-alternatives --install %{_mandir}/man1/vacuumdb.1 pgsql-vacuumdbman %{pgbaseinstdir}/share/man/man1/vacuumdb.1 %{packageversion}0 + +%post libs +%{_sbindir}/update-alternatives --install /etc/ld.so.conf.d/%{sname}-pgdg-libs.conf pgsql-ld-conf %{pgbaseinstdir}/share/%{sname}-%{pgmajorversion}-libs.conf %{packageversion}0 +/sbin/ldconfig + +# Drop alternatives entries for common binaries and man files +%postun +if [ "$1" -eq 0 ] + then + # Only remove these links if the package is completely removed from the system (vs.just being upgraded) + %{_sbindir}/update-alternatives --remove pgsql-psql %{pgbaseinstdir}/bin/psql + %{_sbindir}/update-alternatives --remove pgsql-clusterdb %{pgbaseinstdir}/bin/clusterdb + %{_sbindir}/update-alternatives --remove pgsql-clusterdbman %{pgbaseinstdir}/share/man/man1/clusterdb.1 + %{_sbindir}/update-alternatives --remove pgsql-createdb %{pgbaseinstdir}/bin/createdb + %{_sbindir}/update-alternatives --remove pgsql-createdbman %{pgbaseinstdir}/share/man/man1/createdb.1 + %{_sbindir}/update-alternatives --remove pgsql-createuser %{pgbaseinstdir}/bin/createuser + %{_sbindir}/update-alternatives --remove pgsql-createuserman %{pgbaseinstdir}/share/man/man1/createuser.1 + %{_sbindir}/update-alternatives --remove pgsql-dropdb %{pgbaseinstdir}/bin/dropdb + %{_sbindir}/update-alternatives --remove pgsql-dropdbman %{pgbaseinstdir}/share/man/man1/dropdb.1 + %{_sbindir}/update-alternatives --remove pgsql-dropuser %{pgbaseinstdir}/bin/dropuser + %{_sbindir}/update-alternatives --remove pgsql-dropuserman %{pgbaseinstdir}/share/man/man1/dropuser.1 + %{_sbindir}/update-alternatives --remove pgsql-pg_basebackup %{pgbaseinstdir}/bin/pg_basebackup + %{_sbindir}/update-alternatives --remove pgsql-pg_dump %{pgbaseinstdir}/bin/pg_dump + %{_sbindir}/update-alternatives --remove pgsql-pg_dumpall %{pgbaseinstdir}/bin/pg_dumpall + %{_sbindir}/update-alternatives --remove pgsql-pg_dumpallman %{pgbaseinstdir}/share/man/man1/pg_dumpall.1 + %{_sbindir}/update-alternatives --remove pgsql-pg_basebackupman %{pgbaseinstdir}/share/man/man1/pg_basebackup.1 + %{_sbindir}/update-alternatives --remove pgsql-pg_dumpman %{pgbaseinstdir}/share/man/man1/pg_dump.1 + %{_sbindir}/update-alternatives --remove pgsql-pg_restore %{pgbaseinstdir}/bin/pg_restore + %{_sbindir}/update-alternatives --remove pgsql-pg_restoreman %{pgbaseinstdir}/share/man/man1/pg_restore.1 + %{_sbindir}/update-alternatives --remove pgsql-psqlman %{pgbaseinstdir}/share/man/man1/psql.1 + %{_sbindir}/update-alternatives --remove pgsql-reindexdb %{pgbaseinstdir}/bin/reindexdb + %{_sbindir}/update-alternatives --remove pgsql-reindexdbman %{pgbaseinstdir}/share/man/man1/reindexdb.1 + %{_sbindir}/update-alternatives --remove pgsql-vacuumdb %{pgbaseinstdir}/bin/vacuumdb + %{_sbindir}/update-alternatives --remove pgsql-vacuumdbman %{pgbaseinstdir}/share/man/man1/vacuumdb.1 + fi + +%postun libs +if [ "$1" -eq 0 ] + then + %{_sbindir}/update-alternatives --remove pgsql-ld-conf %{pgbaseinstdir}/share/%{sname}-%{pgmajorversion}-libs.conf + /sbin/ldconfig +fi + +%clean +%{__rm} -rf %{buildroot} + +# FILES section. + +%files -f pg_main.lst +%defattr(-,root,root) +%if %llvm +# Install bitcode directory along with the main package, +# so that extensions can use this dir. +%dir %{pgbaseinstdir}/lib/bitcode +%endif +%doc doc/KNOWN_BUGS doc/MISSING_FEATURES +%doc COPYRIGHT +%doc README.rpm-dist +%{pgbaseinstdir}/bin/clusterdb +%{pgbaseinstdir}/bin/createdb +%{pgbaseinstdir}/bin/createuser +%{pgbaseinstdir}/bin/dropdb +%{pgbaseinstdir}/bin/dropuser +%{pgbaseinstdir}/bin/pgbench +%{pgbaseinstdir}/bin/pg_basebackup +%{pgbaseinstdir}/bin/pg_config +%{pgbaseinstdir}/bin/pg_dump +%{pgbaseinstdir}/bin/pg_dumpall +%{pgbaseinstdir}/bin/pg_isready +%{pgbaseinstdir}/bin/pg_receivewal +%{pgbaseinstdir}/bin/pg_restore +%{pgbaseinstdir}/bin/pg_waldump +%{pgbaseinstdir}/bin/psql +%{pgbaseinstdir}/bin/reindexdb +%{pgbaseinstdir}/bin/vacuumdb +%{pgbaseinstdir}/share/errcodes.txt +%{pgbaseinstdir}/share/man/man1/clusterdb.* +%{pgbaseinstdir}/share/man/man1/createdb.* +%{pgbaseinstdir}/share/man/man1/createuser.* +%{pgbaseinstdir}/share/man/man1/dropdb.* +%{pgbaseinstdir}/share/man/man1/dropuser.* +%{pgbaseinstdir}/share/man/man1/pgbench.1 +%{pgbaseinstdir}/share/man/man1/pg_basebackup.* +%{pgbaseinstdir}/share/man/man1/pg_config.* +%{pgbaseinstdir}/share/man/man1/pg_dump.* +%{pgbaseinstdir}/share/man/man1/pg_dumpall.* +%{pgbaseinstdir}/share/man/man1/pg_isready.* +%{pgbaseinstdir}/share/man/man1/pg_restore.* +%{pgbaseinstdir}/share/man/man1/psql.* +%{pgbaseinstdir}/share/man/man1/reindexdb.* +%{pgbaseinstdir}/share/man/man1/vacuumdb.* +%{pgbaseinstdir}/share/man/man3/* +%{pgbaseinstdir}/share/man/man7/* + +%files docs +%defattr(-,root,root) +%doc doc/src/* +%doc *-A4.pdf +%doc src/tutorial +%doc doc/html + +%files contrib +%defattr(-,root,root) +%doc %{pgbaseinstdir}/doc/extension/*.example +%{pgbaseinstdir}/lib/_int.so +%{pgbaseinstdir}/lib/adminpack.so +%{pgbaseinstdir}/lib/amcheck.so +%{pgbaseinstdir}/lib/auth_delay.so +%{pgbaseinstdir}/lib/autoinc.so +%{pgbaseinstdir}/lib/auto_explain.so +%{pgbaseinstdir}/lib/bloom.so +%{pgbaseinstdir}/lib/btree_gin.so +%{pgbaseinstdir}/lib/btree_gist.so +%{pgbaseinstdir}/lib/citext.so +%{pgbaseinstdir}/lib/cube.so +%{pgbaseinstdir}/lib/dblink.so +%{pgbaseinstdir}/lib/earthdistance.so +%{pgbaseinstdir}/lib/file_fdw.so* +%{pgbaseinstdir}/lib/fuzzystrmatch.so +%{pgbaseinstdir}/lib/insert_username.so +%{pgbaseinstdir}/lib/isn.so +%{pgbaseinstdir}/lib/hstore.so +%if %plperl +%{pgbaseinstdir}/lib/hstore_plperl.so +%{pgbaseinstdir}/lib/jsonb_plperl.so +%{pgbaseinstdir}/share/extension/jsonb_plperl*.sql +%{pgbaseinstdir}/share/extension/jsonb_plperl*.control +%endif +%{pgbaseinstdir}/lib/lo.so +%{pgbaseinstdir}/lib/ltree.so +%{pgbaseinstdir}/lib/moddatetime.so +%{pgbaseinstdir}/lib/pageinspect.so +%{pgbaseinstdir}/lib/passwordcheck.so +%{pgbaseinstdir}/lib/pgcrypto.so +%{pgbaseinstdir}/lib/pgrowlocks.so +%{pgbaseinstdir}/lib/pgstattuple.so +%{pgbaseinstdir}/lib/pg_buffercache.so +%{pgbaseinstdir}/lib/pg_freespacemap.so +%{pgbaseinstdir}/lib/pg_prewarm.so +%{pgbaseinstdir}/lib/pg_stat_statements.so +%{pgbaseinstdir}/lib/pg_trgm.so +%{pgbaseinstdir}/lib/pg_visibility.so +%{pgbaseinstdir}/lib/postgres_fdw.so +%{pgbaseinstdir}/lib/refint.so +%{pgbaseinstdir}/lib/seg.so +%if %ssl +%{pgbaseinstdir}/lib/sslinfo.so +%endif +%if %selinux +%{pgbaseinstdir}/lib/sepgsql.so +%{pgbaseinstdir}/share/contrib/sepgsql.sql +%endif +%{pgbaseinstdir}/lib/tablefunc.so +%{pgbaseinstdir}/lib/tcn.so +%{pgbaseinstdir}/lib/test_decoding.so +%{pgbaseinstdir}/lib/tsm_system_rows.so +%{pgbaseinstdir}/lib/tsm_system_time.so +%{pgbaseinstdir}/lib/unaccent.so +%if %xml +%{pgbaseinstdir}/lib/pgxml.so +%endif +%if %uuid +%{pgbaseinstdir}/lib/uuid-ossp.so +%endif +%{pgbaseinstdir}/share/extension/adminpack* +%{pgbaseinstdir}/share/extension/amcheck* +%{pgbaseinstdir}/share/extension/autoinc* +%{pgbaseinstdir}/share/extension/bloom* +%{pgbaseinstdir}/share/extension/btree_gin* +%{pgbaseinstdir}/share/extension/btree_gist* +%{pgbaseinstdir}/share/extension/citext* +%{pgbaseinstdir}/share/extension/cube* +%{pgbaseinstdir}/share/extension/dblink* +%{pgbaseinstdir}/share/extension/dict_int* +%{pgbaseinstdir}/share/extension/dict_xsyn* +%{pgbaseinstdir}/share/extension/earthdistance* +%{pgbaseinstdir}/share/extension/file_fdw* +%{pgbaseinstdir}/share/extension/fuzzystrmatch* +%{pgbaseinstdir}/share/extension/hstore.control +%{pgbaseinstdir}/share/extension/hstore--*.sql +%if %plperl +%{pgbaseinstdir}/share/extension/hstore_plperl* +%endif +%{pgbaseinstdir}/share/extension/insert_username* +%{pgbaseinstdir}/share/extension/intagg* +%{pgbaseinstdir}/share/extension/intarray* +%{pgbaseinstdir}/share/extension/isn* +%{pgbaseinstdir}/share/extension/lo* +%{pgbaseinstdir}/share/extension/ltree.control +%{pgbaseinstdir}/share/extension/ltree--*.sql +%{pgbaseinstdir}/share/extension/moddatetime* +%{pgbaseinstdir}/share/extension/pageinspect* +%{pgbaseinstdir}/share/extension/pg_buffercache* +%{pgbaseinstdir}/share/extension/pg_freespacemap* +%{pgbaseinstdir}/share/extension/pg_prewarm* +%{pgbaseinstdir}/share/extension/pg_stat_statements* +%{pgbaseinstdir}/share/extension/pg_trgm* +%{pgbaseinstdir}/share/extension/pg_visibility* +%{pgbaseinstdir}/share/extension/pgcrypto* +%{pgbaseinstdir}/share/extension/pgrowlocks* +%{pgbaseinstdir}/share/extension/pgstattuple* +%{pgbaseinstdir}/share/extension/postgres_fdw* +%{pgbaseinstdir}/share/extension/refint* +%{pgbaseinstdir}/share/extension/seg* +%if %ssl +%{pgbaseinstdir}/share/extension/sslinfo* +%endif +%{pgbaseinstdir}/share/extension/tablefunc* +%{pgbaseinstdir}/share/extension/tcn* +%{pgbaseinstdir}/share/extension/tsm_system_rows* +%{pgbaseinstdir}/share/extension/tsm_system_time* +%{pgbaseinstdir}/share/extension/unaccent* +%if %uuid +%{pgbaseinstdir}/share/extension/uuid-ossp* +%endif +%if %xml +%{pgbaseinstdir}/share/extension/xml2* +%endif +%{pgbaseinstdir}/bin/oid2name +%{pgbaseinstdir}/bin/vacuumlo +%{pgbaseinstdir}/bin/pg_recvlogical +%{pgbaseinstdir}/bin/pg_standby +%{pgbaseinstdir}/share/man/man1/oid2name.1 +%{pgbaseinstdir}/share/man/man1/pg_recvlogical.1 +%{pgbaseinstdir}/share/man/man1/pg_standby.1 +%{pgbaseinstdir}/share/man/man1/vacuumlo.1 + +%files libs -f pg_libpq5.lst +%defattr(-,root,root) +%{pgbaseinstdir}/lib/libpq.so.* +%{pgbaseinstdir}/lib/libecpg.so* +%{pgbaseinstdir}/lib/libpgfeutils.a +%{pgbaseinstdir}/lib/libpgtypes.so.* +%{pgbaseinstdir}/lib/libecpg_compat.so.* +%{pgbaseinstdir}/lib/libpqwalreceiver.so +%config(noreplace) %attr (644,root,root) %{pgbaseinstdir}/share/%{sname}-%{pgmajorversion}-libs.conf + +%files server -f pg_server.lst +%defattr(-,root,root) +%if %{systemd_enabled} +%{pgbaseinstdir}/bin/%{sname}-%{pgmajorversion}-setup +%{_bindir}/%{sname}-%{pgmajorversion}-setup +%{pgbaseinstdir}/bin/%{sname}-%{pgmajorversion}-check-db-dir +%{_tmpfilesdir}/%{sname}-%{pgmajorversion}.conf +%{_unitdir}/%{sname}-%{pgmajorversion}.service +%else +%config(noreplace) %{_initrddir}/%{sname}-%{pgmajorversion} +%endif +%if %pam +%config(noreplace) /etc/pam.d/%{sname} +%endif +%attr (755,root,root) %dir /etc/sysconfig/pgsql +%{pgbaseinstdir}/bin/initdb +%{pgbaseinstdir}/bin/pg_archivecleanup +%{pgbaseinstdir}/bin/pg_checksums +%{pgbaseinstdir}/bin/pg_controldata +%{pgbaseinstdir}/bin/pg_ctl +%{pgbaseinstdir}/bin/pg_resetwal +%{pgbaseinstdir}/bin/pg_rewind +%{pgbaseinstdir}/bin/pg_test_fsync +%{pgbaseinstdir}/bin/pg_test_timing +%{pgbaseinstdir}/bin/pg_upgrade +%{pgbaseinstdir}/bin/pg_verifybackup +%{pgbaseinstdir}/bin/postgres +%{pgbaseinstdir}/bin/postmaster +%{pgbaseinstdir}/share/man/man1/initdb.* +%{pgbaseinstdir}/share/man/man1/pg_archivecleanup.1 +%{pgbaseinstdir}/share/man/man1/pg_checksums.* +%{pgbaseinstdir}/share/man/man1/pg_controldata.* +%{pgbaseinstdir}/share/man/man1/pg_ctl.* +%{pgbaseinstdir}/share/man/man1/pg_resetwal.* +%{pgbaseinstdir}/share/man/man1/pg_receivewal.* +%{pgbaseinstdir}/share/man/man1/pg_rewind.1 +%{pgbaseinstdir}/share/man/man1/pg_test_fsync.1 +%{pgbaseinstdir}/share/man/man1/pg_test_timing.1 +%{pgbaseinstdir}/share/man/man1/pg_upgrade.1 +%{pgbaseinstdir}/share/man/man1/pg_verifybackup.* +%{pgbaseinstdir}/share/man/man1/pg_waldump.1 +%{pgbaseinstdir}/share/man/man1/postgres.* +%{pgbaseinstdir}/share/man/man1/postmaster.* +%{pgbaseinstdir}/share/postgres.bki +%{pgbaseinstdir}/share/system_views.sql +%{pgbaseinstdir}/share/*.sample +%{pgbaseinstdir}/share/timezonesets/* +%{pgbaseinstdir}/share/tsearch_data/*.affix +%{pgbaseinstdir}/share/tsearch_data/*.dict +%{pgbaseinstdir}/share/tsearch_data/*.ths +%{pgbaseinstdir}/share/tsearch_data/*.rules +%{pgbaseinstdir}/share/tsearch_data/*.stop +%{pgbaseinstdir}/share/tsearch_data/*.syn +%{pgbaseinstdir}/lib/dict_int.so +%{pgbaseinstdir}/lib/dict_snowball.so +%{pgbaseinstdir}/lib/dict_xsyn.so +%{pgbaseinstdir}/lib/euc2004_sjis2004.so +%{pgbaseinstdir}/lib/pgoutput.so +%{pgbaseinstdir}/lib/plpgsql.so +%dir %{pgbaseinstdir}/share/extension +%{pgbaseinstdir}/share/extension/plpgsql* + +%dir %{pgbaseinstdir}/lib +%dir %{pgbaseinstdir}/share +%if 0%{?suse_version} +%if 0%{?suse_version} >= 1315 +%endif +%else +%attr(700,postgres,postgres) %dir /var/lib/pgsql +%endif +%attr(700,postgres,postgres) %dir /var/lib/pgsql/%{pgmajorversion} +%attr(700,postgres,postgres) %dir /var/lib/pgsql/%{pgmajorversion}/data +%attr(700,postgres,postgres) %dir /var/lib/pgsql/%{pgmajorversion}/backups +%attr(755,postgres,postgres) %dir /var/run/%{sname} +%{pgbaseinstdir}/lib/*_and_*.so +%{pgbaseinstdir}/share/information_schema.sql +%{pgbaseinstdir}/share/snowball_create.sql +%{pgbaseinstdir}/share/sql_features.txt + +%files devel -f pg_devel.lst +%defattr(-,root,root) +%{pgbaseinstdir}/include/* +%{pgbaseinstdir}/bin/ecpg +%{pgbaseinstdir}/lib/libpq.so +%{pgbaseinstdir}/lib/libecpg.so +%{pgbaseinstdir}/lib/libpq.a +%{pgbaseinstdir}/lib/libecpg.a +%{pgbaseinstdir}/lib/libecpg_compat.so +%{pgbaseinstdir}/lib/libecpg_compat.a +%{pgbaseinstdir}/lib/libpgcommon.a +%{pgbaseinstdir}/lib/libpgcommon_shlib.a +%{pgbaseinstdir}/lib/libpgport.a +%{pgbaseinstdir}/lib/libpgport_shlib.a +%{pgbaseinstdir}/lib/libpgtypes.so +%{pgbaseinstdir}/lib/libpgtypes.a +%{pgbaseinstdir}/lib/pgxs/* +%{pgbaseinstdir}/lib/pkgconfig/* +%{pgbaseinstdir}/share/man/man1/ecpg.* + +%if %llvm +%files llvmjit +%defattr(-,root,root) +%{pgbaseinstdir}/lib/bitcode/* +%{pgbaseinstdir}/lib/llvmjit.so +%{pgbaseinstdir}/lib/llvmjit_types.bc +%endif + +%if %plperl +%files plperl -f pg_plperl.lst +%defattr(-,root,root) +%{pgbaseinstdir}/lib/bool_plperl.so +%{pgbaseinstdir}/lib/plperl.so +%{pgbaseinstdir}/share/extension/plperl* +%{pgbaseinstdir}/share/extension/bool_plperl* +%endif + +%if %pltcl +%files pltcl -f pg_pltcl.lst +%defattr(-,root,root) +%{pgbaseinstdir}/lib/pltcl.so +%{pgbaseinstdir}/share/extension/pltcl* +%endif + +%if %plpython3 +%files plpython3 -f pg_plpython3.lst +%{pgbaseinstdir}/share/extension/plpython3* +%{pgbaseinstdir}/lib/plpython3.so +%{pgbaseinstdir}/lib/hstore_plpython3.so +%{pgbaseinstdir}/lib/jsonb_plpython3.so +%{pgbaseinstdir}/lib/ltree_plpython3.so +%{pgbaseinstdir}/share/extension/*_plpython3u* +%endif + +%if %test +%files test +%defattr(-,postgres,postgres) +%attr(-,postgres,postgres) %{pgbaseinstdir}/lib/test/* +%attr(-,postgres,postgres) %dir %{pgbaseinstdir}/lib/test +%endif + +%changelog + diff --git a/postgresql-bashprofile b/postgresql-bashprofile deleted file mode 100644 index 1cd70d33a794b2e903b1196f810c5bcd85a331d9..0000000000000000000000000000000000000000 --- a/postgresql-bashprofile +++ /dev/null @@ -1,4 +0,0 @@ -[ -f /etc/profile ] && source /etc/profile - -PGDATA=/var/lib/pgsql/data -export PGDATA diff --git a/postgresql-check-db-dir b/postgresql-check-db-dir deleted file mode 100755 index c9e6c0b1fb9bda0fdf847a2f474d5c0c61f8f946..0000000000000000000000000000000000000000 --- a/postgresql-check-db-dir +++ /dev/null @@ -1,104 +0,0 @@ -#!/bin/bash - -# This script verifies that the postgresql data directory has been correctly -# initialized. We do not want to automatically initdb it, because that has -# a risk of catastrophic failure (ie, overwriting a valuable database) in -# corner cases, such as a remotely mounted database on a volume that's a -# bit slow to mount. But we can at least emit a message advising newbies -# what to do. - -if test -z "$1"; then - echo "Maintainer error: $0 must be run with one argument" - exit 1 -fi - -service_name="$1" - -if [ -z "$PGDATA" ]; then - echo $"You try to start '$service_name' service" - echo $"but the required \$PGDATA environment variable is not set." - - if test 0 -eq 1; then - echo $"You should use the /etc/sysconfig/pgsql/$service_name" - else - echo $"You should use the /etc/systemd/system/$service_name.service.d/ANYTHING.conf" - fi - - echo $"configuration file to set \$PGDATA. For more info see" - echo $"the /usr/share/doc/postgresql/README.rpm-dist file." - - exit 1 -fi - - -# Warn the user that the configuration should be adjusted via drop-in, in case -# the $PGDATA variable is set different way (and non-default service name is -# used, systemd systems only). -conf_dir="/etc/systemd/system/$service_name.service.d" -if test 0 = 0 && [[ "$service_name" == *@* ]] && test ! -d "$conf_dir"; then - echo >&2 $"WARNING: Note that the '$conf_dir'" - echo >&2 $"directory does not exist while you are using non-default service" - echo >&2 $"name '$service_name'. You are encouraged to use the" - echo >&2 $"$conf_dir directory for systemd configuration according" - echo >&2 $"to /usr/share/doc/postgresql/README.rpm-dist documentation." -fi - -# Full PostgreSQL version, e.g. 9.0.2 -PGVERSION=10.5 - -# Major version of PostgreSQL, e.g. 9.0 -PGMAJORVERSION=10 - -# Distribution README file -README_DIST=/usr/share/doc/postgresql/README.rpm-dist - -bad_version() -{ - local real_version="$1" - - . "/usr/share/postgresql-setup/library.sh" - - while read id version; do - test "$version" = "$real_version" || continue - - local cmd="postgresql-setup --upgrade" - - test "postgresql" = "$id" \ - || cmd="$cmd --upgrade-from $id" - - echo $"An old version of the database format was found." - echo $"Use '$cmd' to upgrade to version '$PGMAJORVERSION'" - echo $"See $README_DIST for more information." - - return - done < <(parse_upgrade_setup list) - - echo $"An old version '$real_version' of the database format was found." - echo $"You need to dump and reload before using PostgreSQL $PGVERSION." - echo $"See $README_DIST for more information." - - return -} - -# Check for the PGDATA structure -if [ -f "$PGDATA/PG_VERSION" ] && [ -d "$PGDATA/base" ] -then - real_version=`cat "$PGDATA/PG_VERSION"` - # Check version of existing PGDATA - if [ x"$real_version" = x"$PGMAJORVERSION" ] - then - : A-OK - else - bad_version "$real_version" - exit 1 - fi -else - # No existing PGDATA! Warn the user to initdb it. - echo $"Directory \"$PGDATA\" is missing or empty." - echo $"Use \"/usr/bin/postgresql-setup --initdb\"" - echo $"to initialize the database cluster." - echo $"See $README_DIST for more information." - exit 1 -fi - -exit 0 diff --git a/postgresql-setup b/postgresql-setup deleted file mode 100755 index bbb7c73dcd9f7f14c6ed9dfea87cce7a89f31739..0000000000000000000000000000000000000000 --- a/postgresql-setup +++ /dev/null @@ -1,777 +0,0 @@ -#!/bin/bash -# -# postgresql-setup - Initialization and upgrade operations for PostgreSQL - -if test "$(id -u)" -eq 0; then - cmd= - for v in PGSETUP_DEBUG PGSETUP_INITDB_OPTIONS PGSETUP_PGUPGRADE_OPTIONS; do - eval var_content=\$$v - test -z "$var_content" && continue - cmd+=$v="$(printf %q "$var_content") " - done - cmd+=$(printf %q "$(readlink -f "$0")") - for arg; do cmd+=" $(printf %q "$arg")" ; done - # Drop root privileges asap. It's not recommended to run postgresql-setup - # script under root nowadays; so we take the liberty to switch to the - # PostgreSQL admin user (by default 'postgres') without any other option. - exec /usr/sbin/runuser -s /bin/sh -l postgres -c "$cmd" -fi - -# ensure privacy -umask 0077 - -: ${RESTORECON=/sbin/restorecon} -test -x $RESTORECON || RESTORECON=: - -test -z "$PATH" && export PATH="/sbin:/usr/sbin:/bin:/usr/bin" - -test x"$PGSETUP_DEBUG" != x && set -x && PS4='${LINENO}: ' - -# The current user name. -USER=$(id -u -n) - -# Directory containing the postmaster executable -PGENGINE=/usr/bin - -# Distribution README file -README_DIST=/usr/share/doc/postgresql/README.rpm-dist - -# Home directory of postgres user -POSTGRES_HOMEDIR=/var/lib/pgsql - -# The where PostgreSQL server listens by default -PGPORT_DEF=5432 - - -. "/usr/share/postgresql-setup/library.sh" - -: - -# We upgrade by default from system's default PostgreSQL installation -option_upgradefrom="postgresql" - -srvsuff= -test 0 -eq 0 && srvsuff=".service" - -USAGE_STRING=$"\ -Usage: $0 MODE_OPTION [--unit=UNIT_NAME] [OPTION...] - -Script is aimed to help sysadmin with basic database cluster administration. -Usually, \"postgresql-setup --initdb\" and \"postgresql-setup --upgrade\" is -enough, however there are other options described below. - -For more info and howto/when use this script please look at the documentation -file $README_DIST. - -Available operation mode: - --initdb Initialize new PostgreSQL database cluster. This is usually the - first action you perform after PostgreSQL server installation. - --upgrade Upgrade database cluster for new major version of PostgreSQL - server. See the --upgrade-from option for more info. - -Options: - --unit=UNIT_NAME The UNIT_NAME is used to select proper unit - configuration (unit == service or initscript name - on non-systemd systems). For example, if you want - to work with unit called - 'postgresql@com_example.service', you should use - 'postgresql@com_example' (without trailing .service - string). When no UNIT_NAME is explicitly passed, - the 'postgresql' string is used by default. - --port=PORT port where the initialized server will listen for - connections" - -test 0 -eq 0 && \ -USAGE_STRING+=" - --new-systemd-unit We dropped this option for security reasons. - Nowadays, please use the root-only script - /usr/sbin/postgresql-new-systemd-unit. - --datadir Dropped with --new-systemd-unit." - -USAGE_STRING+=" - --upgrade-from-unit=UNIT Select proper unit name to upgrade from. This - has similar semantics as --unit option. - --upgrade-ids Print list of available IDs of upgrade scenarios to - standard output. - --upgrade-from=ID Specify id \"old\" postgresql stack to upgrade - from. List of available IDs can be listed by - --upgrade-ids. Default is '$option_upgradefrom'. - -Other options: - --help show this help - --version show version of this package - --debug show basic debugging information - -Environment: - PGSETUP_INITDB_OPTIONS Options carried by this variable are passed to - subsequent call of \`initdb\` binary (see man - initdb(1)). This variable is used also during - 'upgrade' mode because the new cluster is actually - re-initialized from the old one. - PGSETUP_PGUPGRADE_OPTIONS Options in this variable are passed next to the - subsequent call of \`pg_upgrade\`. For more info - about possible options please look at man - pg_upgrade(1). - PGSETUP_DEBUG Set to '1' if you want to see very verbose shell - debugging output." - - -print_version() -{ - echo "postgresql-setup 8.2" - echo $"Built against PostgreSQL version 10.5." -} - - -check_not_initialized() -{ - if test -f "$pgdata/PG_VERSION"; then - error $"Data directory $pgdata is not empty!" - return 1 - fi - return 0 -} - - -# code shared between initdb and upgrade actions -perform_initdb() -{ - if [ ! -e "$pgdata" ]; then - mkdir "$pgdata" || return 1 - fi - $RESTORECON "$pgdata" - test -w "$pgdata" || die "$pgdata is not writeable by $USER" - - # Clean up SELinux tagging for pgdata - [ -x /sbin/restorecon ] && /sbin/restorecon "$pgdata" - - # Create the initdb log file if needed - if [ ! -e "$initdb_log" ]; then - touch "$initdb_log" || return 1 - fi - $RESTORECON "$initdb_log" - test -w "$initdb_log" || echo "$initdb_log is not writeable by $USER" - - # Initialize the database - initdbcmd+=( "$PGENGINE"/initdb --pgdata="$pgdata" --auth=ident ) - eval "initdbcmd+=( $PGSETUP_INITDB_OPTIONS )" - "${initdbcmd[@]}" >> "$initdb_log" 2>&1 < /dev/null - - # Create directory for postmaster log files - mkdir "$pgdata/pg_log" - $RESTORECON "$pgdata/pg_log" - - # This if-fork is just to not unnecessarily overwrite what upstream - # generates by initdb (upstream implicitly uses PGPORT_DEF). - if test "$pgport" != "$PGPORT_DEF"; then - local pgconf="$pgdata/postgresql.conf" - sed -i "s|^[[:space:]#]*port[[:space:]]=[^#]*|port = $pgport |g" \ - "$pgconf" \ - && grep "^port = " "$pgconf" >/dev/null - - if test $? -ne 0; then - error "can not change port in $pgdata/postgresql.conf" - return 1 - fi - fi - - test -f "$pgdata/PG_VERSION" -} - - -initdb() -{ - port_info= - test "$pgport" != "$PGPORT_DEF" \ - && port_info=$", listening on port '$pgport'" - - info $"Initializing database in '$pgdata'$port_info" - if check_not_initialized && perform_initdb; then - info $"Initialized, logs are in ${initdb_log}" - else - error $"Initializing database failed, possibly see $initdb_log" - script_result=1 - fi -} - - -old_data_in_use() -{ - local pidfile="$pgdataold/postmaster.pid" - test -f "$pidfile" || return 1 - error $"The pidfile '$pidfile' exists. Verify that there is no postmaster" - error_q $"running the $pgdataold directory." -} - - -upgrade() -{ - local inplace=false - test "$pgdata" = "$upgradefrom_data" && inplace=true - - debug "running inplace upgrade: $inplace" - - # must see previous version in PG_VERSION - local old_data_version="`cat "$upgradefrom_data/PG_VERSION"`" - if [ ! -f "$upgradefrom_data/PG_VERSION" -o \ - x"$old_data_version" != x"$upgradefrom_major" ] - then - error $"Cannot upgrade because the database in $upgradefrom_data is of" - error_q $"version $old_data_version but it should be $upgradefrom_major" - exit 1 - fi - if [ ! -x "$upgradefrom_engine/postgres" ]; then - error $"Please install the $upgradefrom_package package." - exit 5 - fi - if [ ! -x "$PGENGINE/pg_upgrade" ]; then - # The "$PGENGINE/postgres" depends transitively on - # pg_upgrade binary in rather newer packaging, but SCL with PostgreSQL - # 9.4 provides '*-upgrade' package having `pg_upgrade` inside. We need - # to have this installed, too. Keep till {rh,sclo}-postgresql94 is - # still a thing. - error $"Please install the postgresql-upgrade package." - exit 5 - fi - - # Set up log file for pg_upgrade - rm -f "$upgrade_log" - touch "$upgrade_log" || die "can't write into $upgrade_log file" - $RESTORECON "$upgrade_log" - - # Move old DB to pgdataold - - if $inplace; then - pgdataold="${pgdata}-old" - rm -rf "$pgdataold" - mv "$pgdata" "$pgdataold" || exit 1 - else - pgdataold="$upgradefrom_data" - fi - - # Create configuration file for upgrade process - HBA_CONF_BACKUP="$pgdataold/pg_hba.conf.postgresql-setup.`date +%s`" - HBA_CONF_BACKUP_EXISTS=0 - - if [ ! -f $HBA_CONF_BACKUP ]; then - mv "$pgdataold/pg_hba.conf" "$HBA_CONF_BACKUP" - HBA_CONF_BACKUP_EXISTS=1 - - # For fluent upgrade 'postgres' user should be able to connect - # to any database without password. Temporarily, no other type - # of connection is needed. - echo "local all postgres ident" > "$pgdataold/pg_hba.conf" - $RESTORECON "$pgdataold" - fi - - info $"Upgrading database." - - scls_upgrade_hacks= - test -n "$upgradefrom_scls" && { - debug "scls [$upgradefrom_scls] will be enabled" - scls_upgrade_hacks="source scl_source enable $upgradefrom_scls" - } - - test x"$upgradefrom_redhat_sockets_hack" = xyes && { - debug "upgrading from redhat server" - socket_hacks="export REDHAT_PGUPGRADE_FROM_RHEL=yes" - } - - test -n "$upgradefrom_pghost_override" && { - pghost_override="export PGHOST='$upgradefrom_pghost_override'" - } - - local failure_cleanup=true - if old_data_in_use; then - script_result=1 - # Cleanup makes sense once perform_initdb gets called. - failure_cleanup=false - elif ! check_not_initialized; then - # Don't try to re-init initialized data directory and also do not - # remove it after this unsuccessful upgrade. - script_result=1 - failure_cleanup=false - elif perform_initdb; then - $inplace && link_option=--link - - # After creating the empty new-format database, do the upgrade - ( - cd # pg_upgrade writes to $PWD - eval " - $scls_upgrade_hacks - $socket_hacks - $pghost_override - " - eval "add_options=( $PGSETUP_PGUPGRADE_OPTIONS )" - - "$PGENGINE"/pg_upgrade \ - --old-bindir="$upgradefrom_engine" \ - --new-bindir="$PGENGINE" \ - --old-datadir="$pgdataold" \ - --new-datadir="$pgdata" \ - $link_option \ - --old-port="$PGPORT" \ - --new-port="$PGPORT" \ - --username=postgres \ - "${add_options[@]}" \ - >>"$upgrade_log" 2>>"$upgrade_log" - ) - - if [ $? -ne 0 ]; then - # pg_upgrade failed - error $"pg_upgrade tool failed" - script_result=1 - fi - else - error $"initdb failed" - script_result=1 - fi - - # Move back the backed-up pg_hba.conf regardless of the script_result. - if [ x$HBA_CONF_BACKUP_EXISTS = x1 ]; then - mv -f "$HBA_CONF_BACKUP" "$pgdataold/pg_hba.conf" - fi - - if [ $script_result -eq 0 ]; then - info $"Upgraded OK." - warn $"The configuration files were replaced by default configuration." - warn $"The previous configuration and data are stored in folder" - warn $pgdataold. - else - # Clean up after failure. - $failure_cleanup && rm -rf "$pgdata" - $inplace && mv "$pgdataold" "$pgdata" - error $"Upgrade failed." - fi - info $"See $upgrade_log for details." -} - - -check_daemon_reload() -{ - local nr_option=NeedDaemonReload - - test 0 = 1 && return 0 - - local nr_out="`systemctl show -p $nr_option $option_service.service 2>/dev/null`" - if [[ "$nr_out" != "$nr_option=no" ]]; then - error $"Note that systemd configuration for '$option_service' changed." - error_q $"You need to perform 'systemctl daemon-reload' otherwise the" - error_q $"results of this script can be inadequate." - exit 1 - fi -} - - -handle_service_env() -{ - local service="$1" - - local systemd_env="$(systemctl show -p Environment "${service}.service")" \ - || { return; } - - for env_var in `echo "$systemd_env" | sed 's/^Environment=//'`; do - # If one variable name is defined multiple times the last definition wins. - case "$env_var" in - PGDATA=*) - unit_pgdata="${env_var##PGDATA=}" - debug "unit's datadir: '$unit_pgdata'" - ;; - PGPORT=*) - unit_pgport="${env_var##PGPORT=}" - debug "unit's pgport: $unit_pgport" - ;; - esac - done -} - - -handle_envfile() -{ - local file="$1" - - debug "trying to read '$file' env file" - if test ! -r "$file"; then - if test 0 = 1; then - return - fi - error "Can not read EnvironmentFile '$file' specified" - error_q "in ${service}.service" - fi - - # Note that the env file parser in systemd does not perform exactly the - # same job. - unset PGPORT PGDATA - . "$file" - envfile_pgdata="$PGDATA" - envfile_pgport="$PGPORT" - unset PGPORT PGDATA -} - - -handle_service_envfiles() -{ - local mode="$1" - local service="$2" - - local envfiles="$(systemctl show -p EnvironmentFiles "${service}.service")"\ - || return - - test -z "$envfiles" && return - - envfiles=$(echo $envfiles | \ - sed -e 's/^EnvironmentFile=//' \ - -e 's| ([^)]*)$||' - ) - - # Read the file names line-by-line (spaces may be inside) - while read line; do - handle_envfile "$line" - done <<<"$envfiles" -} - - -handle_pgconf() -{ - local datadir="$1" - local conffile="$datadir/postgresql.conf" - - debug "postgresql.conf: $conffile" - - test -r "$conffile" || { - error "config file $conffile is not readable or does not exist" - die "Old cluster in '$data' does not seem to be initialized" - } - - local sp='[[:space:]]' - local sed_expr="s/^$sp*port$sp*=$sp\([0-9]\+\).*/\1/p" - - rv=0 - conf_pgport=`sed -n "$sed_expr" $conffile | tail -1` || rv=1 - test -n "$conf_pgport" && debug "postgresql.conf pgport: $conf_pgport" - return $rv -} - - -service_configuration() -{ - local data= - local port= - local unit_pgport= - local unit_pgdata= - local envfile_pgport= - local envfile_pgdata= - - # 'mode' is 'initdb' or 'upgrade'. Basically, if called with mode=initdb, we - # parse configuration of the current (maybe already configured) service. - # When run with mode=upgrade, we try to parse the configuration of the old - # PostgreSQL configuration that we try to upgrade from. - - local mode="$1" datavar="$2" portvar="$3" service="$4" - - debug "running service_configuration() for $service, mode: $mode" - - if test "0" = 1; then - # Sysvinit has the default PGDATA (for default unit name only) - # configured directly in the initscript, so no additional configuration - # must exist. Set the default value of pgdata here to match whats in - # initscript for the cases when no additional configuration file exists. - # This is done to avoid parsing of whole initscript (for the real value) - # and mainly to not fail in the logic following 'service_configuration' - # call, where we usually want to error that pgdata is not defined.. - # Don't set the default pgdata for upgrade case, however, as we must - # upgrade only from already properly configured & working stack (missing - # pgdata here is a good reason to die later). - test initdb = "$mode" && test "$service" = "postgresql" \ - && set_var "$datavar" "/var/lib/pgsql/data" - handle_envfile "/etc/sysconfig/pgsql/$service" - else - # We ship two service files, postgresql.service and - # postgresql@.service. The former has PGDATA set by default - # similarly to sysvinit case. - handle_service_env "$service" - handle_service_envfiles "$option_mode" "$service" - fi - - # EnvironmentFile beats Environment configuration in systemd. In sysvinit - # there is no "unit_pgdata". So make sure the envfile_gpdata is used later - # than unit_pgdata. - test -n "$unit_pgdata" && set_var "$datavar" "$unit_pgdata" - test -n "$envfile_pgdata" && set_var "$datavar" "$envfile_pgdata" - - # skip for the first run - test initdb = "$mode" && return - - set_var data "\$$datavar" - handle_pgconf "$data" - - test -n "$conf_pgport" && set_var "$portvar" "$conf_pgport" - test -n "$unit_pgport" && set_var "$portvar" "$unit_pgport" - test -n "$envfile_pgport" && set_var "$portvar" "$envfile_pgport" -} - -# -# Alow users to use the old style arguments like -# 'postgresql-setup initdb $SERVICE_NAME'. -case "$1" in initdb|upgrade) - action="--$1" - shift - - warn "using obsoleted argument syntax, try --help" - old_long_args="help,usage,version,debug" - oldargs=`getopt -o "" -l "$old_long_args" -n "old-options" -- "$@"` \ - || die "can't parse old arguments" - eval set -- "$oldargs" - additional_opts= - while true; do - case "$1" in - --version|--help|--usage|--debug) - additional_opts="$additional_opts $1" - shift - ;; - --) - shift - break - ;; - esac - done - - service="postgresql" - if test -n "$1"; then - service=$1 - shift - fi - - set -- $additional_opts "$action" --unit "$service" "$@" - warn "arguments transformed to: ${0##*/} $*" -esac -# - - -# postgresql-setup arguments are parsed into those variables -option_mode=none -option_service="postgresql" -option_port= -option_debug=0 -option_upgradefrom_unit= - -# Content of EnvironmentFile= files fills those: -envfile_pgdata= -envfile_pgport= - -# Configuration from (/etc/systemd/system/$option_service.service) fills those -# variables. -unit_pgdata= -unit_pgport= - -# Configuration from postgresql.conf: -conf_pgport= - -# Key variables. Try to fill them by postgresql.conf, Environment= statement in -# service file or EnvironmentFile= content (the later mentioned has more -# priority). -pgdata=default -pgport=default - -## PARSE SCRIPT ARGUMENTS ## - -short_opts="" -long_opts="\ -initdb,upgrade,\ -new-systemd-unit,upgrade-ids,\ -unit:,service:,port:,datadir:,upgrade-from:,upgrade-from-unit:,\ -debug,\ -version,help,usage" - -args=`getopt -o "$short_opts" -l "$long_opts" -n "postgresql-setup" -- "$@"` \ - || die "can't parse arguments" -eval set -- "$args" -parse_fail=0 -while true; do - case "$1" in - --initdb|--upgrade) - if test "$option_mode" != none; then - error "bad argument $1, mode already specified: --$option_mode" - parse_fail=1 - else - option_mode=${1##--} - fi - shift - ;; - - --unit|--service) - option_service=$2 - shift 2 - ;; - - --port) - option_port=$2 - shift 2 - ;; - - --datadir|--new-systemd-unit) - error $"Removed option --new-systemd-unit/--datadir, please use" - error_q $"/usr/sbin/postgresql-new-systemd-unit script" - exit 1 - ;; - - --debug) - option_debug=1 - shift - ;; - - --help|--usage) - echo "$USAGE_STRING" - exit 0 - ;; - - --upgrade-from) - option_upgradefrom="$2" - shift 2 - ;; - - --upgrade-from-unit) - option_upgradefrom_unit="$2" - shift 2 - ;; - - --version) - print_version - exit 0 - ;; - - --) - shift - break - ;; - - *) - die "author's fault: option $1 not handled" - break - ;; - esac -done - -test $parse_fail -ne 0 && die "can't parse arguments" - -test "$option_mode" = none \ - && die "no mode specified, use --initdb or --upgrade, or --help" - -## GATHER THE SETUP FIRST ## - -initdb_log="$POSTGRES_HOMEDIR/initdb_${option_service}.log" -upgrade_log="$POSTGRES_HOMEDIR/upgrade_${option_service}.log" - -debug "mode used: $option_mode" -debug "service name: $option_service" - -# load service's pgdata -service_configuration initdb pgdata UNUSED "$option_service" - -test "$pgdata" = default \ - && die $"no db datadir (PGDATA) configured for '$option_service$srvsuff' unit" - -[[ "$pgdata" =~ ^/.* ]] \ - || die $"the PostgreSQL datadir not absolute path: '$pgdata', try --debug" - -## GATHER DATA FROM INITIALIZED DATADIR ## - -test -n "$option_port" && pgport=$option_port - -if test upgrade = "$option_mode"; then - upgradefrom_data="$upgradefrom_data_default" - - if test -z "$option_upgradefrom_unit"; then - if test "postgresql" = "postgresql"; then - # Fedora usecase -> upgrade while keeping the same name of - # service/unit. - option_upgradefrom_unit=$option_service - else - # PGRPMs/RHSCL usecase -> we upgrade from one service/unit name to - # a different one, e.g. from postgresql92 to postgresql93, or from - # postgresql (system version) to postgresql94 (scl). - option_upgradefrom_unit=$upgradefrom_id - - # Try to predict situations: postgresql93@second -> postgresql94@second - if [[ "$option_service" =~ ^postgresql@(.*)$ ]]; then - option_upgradefrom_unit="$upgradefrom_id@${BASH_REMATCH[1]}" - fi - fi - fi - - test "$option_service" = "$option_upgradefrom_unit" \ - || info "upgrading from '$option_upgradefrom_unit$srvsuff'" \ - "to '$option_service$srvsuff'" - - service_configuration upgrade upgradefrom_data pgport \ - "$option_upgradefrom_unit" - test -n "$option_port" -a "$option_port" != "$pgport" \ - && warn "Old pgport $pgport has bigger priority than --pgport value." -fi - -# We expect that for upgrade - the previous stack was in working state (thus -# running on the default port). -test "$option_mode" = upgrade -a "$pgport" = default \ - && pgport=$PGPORT_DEF - -# This is mostly for 'initdb'. We assume that the default port is $PGPORT_DEF -# if not set explicitly for default service name 'postgresql'. -if test "$pgport" = default -a "$option_service" = "postgresql"; then - debug $"Using the default port '$PGPORT_DEF'" - pgport=$PGPORT_DEF -fi - -if test "$pgport" = default; then - # initdb case.. Note that this may be called by initscripts. If this gets - # called by legacy script, we can't help too much because systemd does not - # allow passing additional arguments to 'service XX initdb' command. - die $"For non-default unit names you must specify port by --port option." -fi - -[[ "$option_port" =~ ^[0-9]*$ ]] \ - || die $"port set to '$option_port', must be integer number" - -## LAST CHECK THE SETUP ## - -check_daemon_reload - -# These variables are read by underlying utilites, rather export them. -export PGDATA=$pgdata -export PGPORT=$pgport - -debug "final pgdata: $pgdata" -debug "final pgport: $pgport" - -script_result=0 - -test -w "/var/lib/pgsql" || { - # pg_upgrade binary needs to have write-able $PWD (and we use 'su -') - error $"The /var/lib/pgsql directory has wrong permissions." - error_q $"Please make sure the directory is writable by $USER." - exit 1 -} - -if /usr/bin/mountpoint -q "$pgdata" || /usr/bin/mountpoint -q "$(dirname "$pgdata")"; then - warn $"Note that either your data directory '$pgdata' or" - warn_q $"the parent directory '$(dirname "$pgdata")'" - warn_q $"is a direct mountpoint. This is usually a bad idea and your" - warn_q $"filesystem layout should ideally look like:" - warn_q $"/ROOT_OWNED_MOUNTPOINT/POSTGRES_OWNED_DIRECTORY/DATADIR." - warn_q $"See the upstream documentation for more info:" - warn_q $"http://www.postgresql.org/docs/10/static/creating-cluster.html" -fi - -# See how we were called. -case "$option_mode" in - initdb) - initdb - ;; - upgrade) - upgrade - ;; - *) - echo >&2 "$USAGE_STRING" - exit 2 -esac - -exit $script_result diff --git a/postgresql.service b/postgresql.service deleted file mode 100644 index 57643a586e8202fa1e958d79e3124d6deeb2c1be..0000000000000000000000000000000000000000 --- a/postgresql.service +++ /dev/null @@ -1,23 +0,0 @@ -[Unit] -Description=PostgreSQL database server -After=network.target -[Service] -Type=notify - -User=postgres -Group=postgres -OOMScoreAdjust=-1000 -Environment=PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj -Environment=PG_OOM_ADJUST_VALUE=0 -Environment=PGDATA=/var/lib/pgsql/data - -ExecStartPre=/usr/libexec/postgresql-check-db-dir %N -ExecStart=/usr/bin/postmaster -D ${PGDATA} -ExecReload=/bin/kill -HUP $MAINPID -KillMode=mixed -KillSignal=SIGINT - -TimeoutSec=0 - -[Install] -WantedBy=multi-user.target diff --git a/postgresql.spec b/postgresql.spec deleted file mode 100644 index 61b78d4761420eaa3ac53de215c10955f0f35209..0000000000000000000000000000000000000000 --- a/postgresql.spec +++ /dev/null @@ -1,498 +0,0 @@ -%global _default_patch_flags --no-backup-if-mismatch -%global __provides_exclude_from %{_libdir}/pgsql -%global macrosdir %(d=%{_rpmconfigdir}/macros.d; [ -d $d ] || d=%{_sysconfdir}/rpm; echo $d) - -Name: postgresql -Version: 10.5 -Release: 19 -Summary: PostgreSQL client programs -License: PostgreSQL -URL: http://www.postgresql.org/ -Source0: https://ftp.postgresql.org/pub/source/v%{version}/postgresql-%{version}.tar.bz2 -Source3: https://ftp.postgresql.org/pub/source/v%{version}/postgresql-%{version}.tar.bz2.sha256 -Source5: postgresql.tmpfiles.d -Source6: postgresql-bashprofile -# https://github.com/devexp-db/postgresql-setup/blob/master/postgresql-check-db-dir.in -Source7: postgresql-check-db-dir -# https://github.com/devexp-db/postgresql-setup/blob/master/bin/postgresql-setup.in -Source8: postgresql-setup -Source9: postgresql.service -# https://github.com/devexp-db/postgresql-setup/blob/master/share/postgresql-setup/library.sh.in -Source10: library.sh -Source11: macros.postgresql -Source12: macros.postgresql-test -Source13: postgresql_pkg_tests.sh - -Patch1: 0001-postgresql-var-run-socket.patch -Patch2: 0002-rpm-pgsql.patch -Patch3: 0003-CVE-2019-10164-1.patch -Patch4: 0004-CVE-2019-10164-2.patch -Patch5: 0005-CVE-2019-10208.patch -Patch6: 0006-CVE-2018-16850.patch -Patch7: 0007-CVE-2019-10130.patch -Patch8: 0008-CVE-2020-1720.patch -Patch9: 0009-CVE-2020-14349-1.patch -Patch10: 0010-CVE-2020-14349-2.patch -Patch11: 0011-CVE-2020-14350.patch -Patch12: Fix-error-handling-of-vacuumdb-when-running-out-of-f.patch -Patch13: Remove-some-code-related-to-7.3-and-older-servers-fr.patch -Patch14: createdb-Fix-quoting-of-encoding-lc-ctype-and-lc-col.patch -Patch15: CVE-2020-25694-1.patch -Patch16: CVE-2020-25694-2.patch -Patch17: CVE-2020-25694-3.patch -Patch18: CVE-2020-25695.patch -Patch19: CVE-2020-25696.patch -Patch20: CVE-2021-20229.patch - -BuildRequires: gcc perl(ExtUtils::MakeMaker) glibc-devel bison flex gawk perl(ExtUtils::Embed) -BuildRequires: perl-devel perl-generators readline-devel zlib-devel systemd systemd-devel -BuildRequires: util-linux m4 elinks docbook-utils help2man docbook-style-xsl -BuildRequires: python3 python3-devel tcl-devel openssl-devel krb5-devel openldap-devel gettext >= 0.10.35 -BuildRequires: uuid-devel libxml2-devel libxslt-devel pam-devel systemtap-sdt-devel libselinux-devel -Requires: %{name}-libs = %{version}-%{release} - -%package libs -Summary: The shared libraries required for any PostgreSQL clients -Requires(post): glibc -Requires(postun): glibc - -%description libs -The postgresql-libs package provides the essential shared libraries for any -PostgreSQL client program or interface. You will need to install this package -to use any other PostgreSQL package or any clients that need to connect to a -PostgreSQL server. - -%description -PostgreSQL is an advanced Object-Relational database management system (DBMS) -that supports almost all SQL constructs (including transactions, subselects -and user-defined types and functions). The postgresql package includes the client -programs and libraries that you'll need to access a PostgreSQL DBMS server. - -%package server -Summary: A package helps to create and run a PostgreSQL server -Requires: %{name} = %{version}-%{release} %{name}-libs = %{version}-%{release} systemd -Requires(pre): shadow -%{?systemd_requires} -Provides: %{name}-server(:MODULE_COMPAT_10) -Provides: bundled(postgresql-setup) = 8.2 - -%description server -The postgresql-server package includes the programs needed to create and run -a PostgreSQL server, which will in turn allow you to create and maintain -PostgreSQL databases. - -%package help -Summary: Help documentation for PostgreSQL -Requires: %{name} = %{version}-%{release} -Provides: %{name}-doc = %{version}-%{release} %{name}-docs = %{version}-%{release} -Obsoletes: %{name}-docs < %{version}-%{release} - -%description help -Man pages and other related help documents for PostgreSQL. - -%package contrib -Summary: Include the contrib tree distributed with PostgreSQL tarball -Requires: %{name} = %{version}-%{release} %{name}-libs = %{version}-%{release} - -%description contrib -The postgresql-contrib package includes the contrib tree distributed -with the PostgreSQL tarball. Selected contrib modules are prebuilt. - -%package devel -Summary: Development files for postgresql -Requires: %{name}-libs = %{version}-%{release} %{name}-server = %{version}-%{release} -Provides: libpq-devel = %{version}-%{release} libecpg-devel = %{version}-%{release} -Provides: postgresql-server-devel = %{version}-%{release} - - -%package static -Summary: Statically linked PostgreSQL libraries -Requires: %{name}-devel = %{version}-%{release} - -%description static -Statically linked PostgreSQL libraries that do not have dynamically linked -counterparts. - -%description devel -This package provides Libraries and header files for postgresql. - - -%package plperl -Summary: The Perl procedural language for PostgreSQL -Requires: %{name}-server = %{version}-%{release} -Requires: perl(:MODULE_COMPAT_%(eval "`%{__perl} -V:version`"; echo $version)) -BuildRequires: perl(Data::Dumper) - -%description plperl -This package contains the PL/Perl procedural language, which is an extension -to the PostgreSQL database server.Install this if you want to write database -functions in Perl. - -%package plpython3 -Summary: The Python3 procedural language for PostgreSQL -Requires: %{name}-server = %{version}-%{release} - -%description plpython3 -This package contains the PL/Python procedural language, which is an extension -to the PostgreSQL database server.It is used when you want to write database -functions in Python3. - - -%package pltcl -Summary: The Tcl procedural language for PostgreSQL -Requires: %{name}-server = %{version}-%{release} - -%description pltcl -This package provides the PL/Tcl procedural language, which is an extension -to the PostgreSQL database server. - -%package test -Summary: The test suite distributed with PostgreSQL -Requires: %{name}-server = %{version}-%{release} %{name}-devel = %{version}-%{release} - -%description test -The postgresql-test package contains files needed for various tests for the -PostgreSQL database management system, including regression tests and benchmarks. - -%package test-rpm-macros -Summary: Convenience RPM macros for build-time testing against PostgreSQL server -Requires: %{name}-server = %{version}-%{release} - -%description test-rpm-macros -This package is meant to be added as BuildRequires: dependency of other packages -that want to run build-time testsuite against running PostgreSQL server. - - -%prep -( - cd "$(dirname "%{SOURCE0}")" - sha256sum -c %{SOURCE3} -) -%autosetup -n %{name}-%{version} -p1 - -%build -if [ x"`id -u`" = x0 ]; then - echo "postgresql's regression tests fail if run as root." - echo "If you really need to build the RPM as root, use" - echo "--define='runselftest 0' to skip the regression tests." - exit 1 -fi - -CFLAGS="${CFLAGS:-%optflags}" -CFLAGS=`echo $CFLAGS|xargs -n 1|grep -v ffast-math|xargs -n 100` -export CFLAGS - -common_configure_options=' - --disable-rpath --with-perl --with-tcl --with-tclconfig=%_libdir - --with-ldap --with-openssl --with-pam --with-gssapi --with-ossp-uuid - --with-libxml --with-libxslt --enable-nls --enable-dtrace - --with-selinux --with-system-tzdata=%_datadir/zoneinfo - --datadir=%_datadir/pgsql --with-systemd -' - -export PYTHON=/usr/bin/python3 - -%configure $common_configure_options --with-python - -%make_build -C src/pl/plpython all -cp -a src/pl/plpython src/pl/plpython3 - -cp src/Makefile.global src/Makefile.global.python3 - -unset PYTHON - -%make_build world - -sed "s|C=\`pwd\`;|C=%{_libdir}/pgsql/tutorial;|" < src/tutorial/Makefile > src/tutorial/GNUmakefile -%make_build -C src/tutorial NO_PGXS=1 all - -rm -f src/tutorial/GNUmakefile src/tutorial/*.o - -run_testsuite() -{ - make -k -C "$1" MAX_CONNECTIONS=5 check && return 0 || test_failure=1 - ( - set +x - echo "=== trying to find all regression.diffs files in build directory ===" - find "$1" -name 'regression.diffs' | \ - while read line; do - echo "=== make failure: $line ===" - cat "$line" - done - ) -} - -test_failure=0 - -run_testsuite "src/test/regress" -make clean -C "src/test/regress" -run_testsuite "src/pl" -mv src/Makefile.global src/Makefile.global.save -cp src/Makefile.global.python3 src/Makefile.global -touch -r src/Makefile.global.save src/Makefile.global -mv src/pl/plpython src/pl/plpython2 -mv src/pl/plpython3 src/pl/plpython - -run_testsuite "src/pl/plpython" - -mv src/pl/plpython src/pl/plpython3 -mv src/pl/plpython2 src/pl/plpython -mv -f src/Makefile.global.save src/Makefile.global -run_testsuite "contrib" - -test "$test_failure" -eq 0 -make all -C src/test/regress - - -%install - -make DESTDIR=$RPM_BUILD_ROOT install-world - -mv src/Makefile.global src/Makefile.global.save -cp src/Makefile.global.python3 src/Makefile.global -touch -r src/Makefile.global.save src/Makefile.global -pushd src/pl/plpython3 -%make_install -popd -mv -f src/Makefile.global.save src/Makefile.global - -install -d -m 755 $RPM_BUILD_ROOT%{_datadir}/pgsql/contrib -install -d -m 755 $RPM_BUILD_ROOT%{_datadir}/pgsql/extension - -install -d -m 755 $RPM_BUILD_ROOT%{_libdir}/pgsql/tutorial -cp -p src/tutorial/* $RPM_BUILD_ROOT%{_libdir}/pgsql/tutorial - -install -d $RPM_BUILD_ROOT%{_tmpfilesdir} -install -d -m 755 $RPM_BUILD_ROOT%{?_localstatedir}/run/postgresql -install -m 0644 %{SOURCE5} $RPM_BUILD_ROOT%{_tmpfilesdir}/postgresql.conf - -install -d -m 700 $RPM_BUILD_ROOT%{?_localstatedir}/lib/pgsql/data -install -d -m 700 $RPM_BUILD_ROOT%{?_localstatedir}/lib/pgsql/backups -install -m 0644 %{SOURCE6} $RPM_BUILD_ROOT%{?_localstatedir}/lib/pgsql/.bash_profile - -install -D %{SOURCE7} $RPM_BUILD_ROOT%{_libexecdir}/postgresql-check-db-dir -install %{SOURCE8} $RPM_BUILD_ROOT%{_bindir}/postgresql-setup -install -Dm 0644 %{SOURCE9} $RPM_BUILD_ROOT%{_unitdir}/postgresql.service -install -D %{SOURCE10} $RPM_BUILD_ROOT%{_datadir}/postgresql-setup/library.sh -install -Dm 0644 %{SOURCE11} $RPM_BUILD_ROOT%{macrosdir}/macros.postgresql -install -m 0644 %{SOURCE12} $RPM_BUILD_ROOT%{macrosdir}/macros.postgresql-test -install %{SOURCE13} $RPM_BUILD_ROOT%{_datadir}/postgresql-setup/postgresql_pkg_tests.sh - -install -d $RPM_BUILD_ROOT%{_libdir}/pgsql/test -cp -a src/test/regress $RPM_BUILD_ROOT%{_libdir}/pgsql/test -ln -sf ../../pgxs/src/test/regress/pg_regress $RPM_BUILD_ROOT%{_libdir}/pgsql/test/regress/pg_regress -pushd $RPM_BUILD_ROOT%{_libdir}/pgsql/test/regress -rm -f GNUmakefile Makefile *.o -chmod 0755 pg_regress regress.so -popd - -rm -rf doc/html -mv $RPM_BUILD_ROOT%{_docdir}/pgsql/html doc - -find_lang_bins () -{ - lstfile=$1 ; shift - cp /dev/null "$lstfile" - for binary; do - %find_lang "$binary"-10 - cat "$binary"-10.lang >>"$lstfile" - done -} - -find_lang_bins devel.lst ecpg pg_config -find_lang_bins libs.lst ecpglib6 libpq5 -find_lang_bins server.lst initdb pg_basebackup pg_controldata pg_ctl pg_resetwal pg_rewind plpgsql postgres -find_lang_bins contrib.lst pg_archivecleanup pg_test_fsync pg_test_timing pg_waldump -find_lang_bins main.lst pg_dump pg_upgrade pgscripts psql -find_lang_bins plperl.lst plperl -find_lang_bins plpython3.lst plpython -find_lang_bins pltcl.lst pltcl - - -%post libs -p /sbin/ldconfig -%postun libs -p /sbin/ldconfig - - -%pre server -/usr/sbin/groupadd -g 26 -o -r postgres >/dev/null 2>&1 || : -/usr/sbin/useradd -M -N -g postgres -o -r -d /var/lib/pgsql -s /bin/bash \ - -c "PostgreSQL Server" -u 26 postgres >/dev/null 2>&1 || : - -%post server -%systemd_post postgresql.service - - -%preun server -%systemd_preun postgresql.service - - -%postun server -%systemd_postun_with_restart postgresql.service - - - -%clean - - -%files -f main.lst -%doc COPYRIGHT README -%{_bindir}/{clusterdb,createdb,createuser,dropdb,dropuser,pg_dump,pg_dumpall} -%{_bindir}/{pg_isready,pg_restore,pg_upgrade,psql,reindexdb,vacuumdb} -%exclude %{_docdir}/pgsql -%exclude %{_libdir}/pgsql/test/regress/pg_regress -%exclude %{_libdir}/lib{ecpg,pq,ecpg_compat,pgfeutils,pgtypes}.a - -%files libs -f libs.lst -%doc COPYRIGHT -%dir %{_libdir}/pgsql -%{_libdir}/libecpg.so.* -%{_libdir}/libecpg_compat.so.* -%{_libdir}/libpgtypes.so.* -%{_libdir}/libpq.so.* - - -%files help -%doc doc/html doc/KNOWN_BUGS doc/MISSING_FEATURES doc/TODO -%doc HISTORY doc/bug.template -%{_libdir}/pgsql/tutorial/ -%{_mandir}/man1/* -%{_mandir}/man3/* -%{_mandir}/man7/* - - -%files contrib -f contrib.lst -%doc contrib/spi/*.example -%{_bindir}/{oid2name,pg_archivecleanup,pg_standby,pg_test_fsync,pg_test_timing,pg_waldump,pgbench,vacuumlo} -%{_datadir}/pgsql/extension/{adminpack*,amcheck*,autoinc*,bloom*,btree_gin*,btree_gist*,chkpass*} -%{_datadir}/pgsql/extension/{citext*,cube*,dblink*,dict_int*,dict_xsyn*,earthdistance*,file_fdw*,fuzzystrmatch*} -%{_datadir}/pgsql/extension/{hstore*,insert_username*,intagg*,intarray*,isn*,lo*,ltree*,moddatetime*} -%{_datadir}/pgsql/extension/{pageinspect*,pg_buffercache*,pg_freespacemap*,pg_prewarm*,pg_stat_statements*} -%{_datadir}/pgsql/extension/{pg_trgm*,pg_visibility*,pgcrypto*,pgrowlocks*,pgstattuple*,postgres_fdw*} -%{_datadir}/pgsql/extension/{refint*,seg*,tablefunc*,tcn*,timetravel*,tsm_system_rows*,tsm_system_time*} -%{_datadir}/pgsql/extension/{unaccent*,sslinfo*,uuid-ossp*,xml2*} -%{_datadir}/pgsql/contrib/sepgsql.sql -%{_libdir}/pgsql/{_int,adminpack,amcheck,auth_delay,auto_explain,autoinc,bloom,btree_gin,btree_gist}.so -%{_libdir}/pgsql/{chkpass,citext,cube,dblink,dict_int,dict_xsyn,earthdistance,file_fdw,fuzzystrmatch}.so -%{_libdir}/pgsql/{hstore,hstore_plperl,hstore_plpython3,insert_username,isn,lo,ltree,ltree_plpython3}.so -%{_libdir}/pgsql/{moddatetime,pageinspect,passwordcheck,pg_buffercache,pg_freespacemap,pg_stat_statements}.so -%{_libdir}/pgsql/{pg_trgm,pg_visibility,pgcrypto,pgrowlocks,pgstattuple,postgres_fdw,refint}.so -%{_libdir}/pgsql/{seg,tablefunc,tcn,test_decoding,timetravel,tsm_system_rows,tsm_system_time,unaccent}.so -%{_libdir}/pgsql/{sepgsql,sslinfo,uuid-ossp,pgxml}.so - - -%files server -f server.lst -%{_bindir}/{initdb,pg_basebackup,pg_controldata,pg_ctl,pg_receivewal,pg_recvlogical} -%{_bindir}/{pg_resetwal,pg_rewind,postgres,postgresql-setup,postmaster} -%{_datadir}/pgsql/{conversion_create.sql,*.sample,extension/plpgsql*,information_schema.sql} -%{_datadir}/pgsql/postgres.{bki,description,shdescription} -%{_datadir}/pgsql/{snowball_create.sql,sql_features.txt,system_views.sql,timezonesets/,tsearch_data/} -%{_datadir}/postgresql-setup/library.sh -%{_tmpfilesdir}/postgresql.conf -%{_libdir}/pgsql/{*_and_*,dict_snowball,euc2004_sjis2004,libpqwalreceiver,pg_prewarm,pgoutput,plpgsql}.so -%{_libexecdir}/postgresql-check-db-dir -%{_unitdir}/*postgresql*.service -%dir %{_datadir}/pgsql/{extension,contrib} -%dir %{_datadir}/postgresql-setup -%attr(700,postgres,postgres) %dir %{?_localstatedir}/lib/pgsql -%attr(700,postgres,postgres) %dir %{?_localstatedir}/lib/pgsql/backups -%attr(700,postgres,postgres) %dir %{?_localstatedir}/lib/pgsql/data -%attr(755,postgres,postgres) %dir %{?_localstatedir}/run/postgresql -%attr(700,postgres,postgres) %config(noreplace) %{?_localstatedir}/lib/pgsql/.bash_profile - - -%files devel -f devel.lst -%{_includedir}/* -%{_bindir}/{ecpg,pg_config} -%{_libdir}/{pgsql/pgxs/,pkgconfig/*.pc} -%{_libdir}/{libecpg,libecpg_compat,libpgtypes,libpq}.so -%{macrosdir}/macros.postgresql - -%files static -%{_libdir}/libpgcommon.a -%{_libdir}/libpgport.a - -%files test-rpm-macros -%{_datadir}/postgresql-setup/postgresql_pkg_tests.sh -%{macrosdir}/macros.postgresql-test - -%files plperl -f plperl.lst -%{_datadir}/pgsql/extension/plperl* -%{_libdir}/pgsql/plperl.so - - -%files pltcl -f pltcl.lst -%{_datadir}/pgsql/extension/pltcl* -%{_libdir}/pgsql/pltcl.so - - -%files plpython3 -f plpython3.lst -%{_datadir}/pgsql/extension/plpython3* -%{_libdir}/pgsql/plpython3.so - -%files test -%attr(-,postgres,postgres) %{_libdir}/pgsql/test - -%changelog -* Fri Feb 26 2021 wangyue - 10.5-19 -- Fix CVE-2021-20229 - -* Tue Dec 8 2020 wangxiao - 10.5-18 -- Fix CVE-2020-25694 CVE-2020-25695 CVE-2020-25696 - -* Web Sep 9 2020 yanglongkang - 10.5-17 -- Fix CVE-2020-14349 CVE-2020-14350 - -* Fri Jun 19 2020 cuibaobao - 10.5-16 -- Type: enhancement -- DESC: delete all about residual parse_upgrade_setup in postgresql-setup - -* Wed May 6 2020 cuibaobao - 10.5-15 -- Type:cve -- ID:CVE-2020-1720 -- SUG: NA -- DESC: fix CVE-2020-1720 - -* Tue Apr 08 2020 daiqianwen - 10.5-14 -- Type: enhancement -- DESC: add postgresql-test-rpm-macros - -* Tue Apr 07 2020 daiqianwen - 10.5-13 -- Type: enhancement -- DESC: delete unseless tarball - -* Tue Mar 10 2020 steven - 10.5-12 -- Type: enhancement -- DESC: remove python2 - -* Mon Mar 10 2020 yanzhihua - 10.5-11 -- Type: bug fix -- ID: #I1AHMH -- SUG: NA -- DESC: fix issue #I1AHMH - -* Mon Feb 3 2020 chenli 10.5-10 -- Type:cve -- ID:CVE-2019-10130 -- SUG: NA -- DESC: fix CVE-2019-10130 - -* Tue Jan 14 2020 openEuler Buildteam - 10.5-9 -- Type:enhancement -- ID:NA -- SUG:restart -- DESC: remove useless files - -* Mon Jan 13 2020 yanzhihua - 10.5-8 -- Type: enhancement -- ID: NA -- SUG: NA -- DESC: modify buildrequire - -* Tue Dec 24 2019 fengbing - 10.5-7 -- Type:cves -- ID:CVE-2019-10208 CVE-2018-16850 -- SUG:restart -- DESC: fix CVE-2019-10208 CVE-2018-16850 - -* Fri Nov 15 2019 yanzhihua - 10.5-6 -- Package init diff --git a/postgresql.tmpfiles.d b/postgresql.tmpfiles.d deleted file mode 100644 index d8d960d75586991fa6d68b95d5c0a49c43e0d090..0000000000000000000000000000000000000000 --- a/postgresql.tmpfiles.d +++ /dev/null @@ -1 +0,0 @@ -d /var/run/postgresql 0755 postgres postgres - diff --git a/postgresql.yaml b/postgresql.yaml deleted file mode 100644 index 00bbaf050db91e87f0ad529e5c29027a1bf150ae..0000000000000000000000000000000000000000 --- a/postgresql.yaml +++ /dev/null @@ -1,4 +0,0 @@ -version_control: NA -src_repo: NA -tag_prefix: NA -seperator: NA diff --git a/postgresql_pkg_tests.sh b/postgresql_pkg_tests.sh deleted file mode 100644 index c382c177ec3718cab6a6e09d20d441bcf9276df8..0000000000000000000000000000000000000000 --- a/postgresql_pkg_tests.sh +++ /dev/null @@ -1,193 +0,0 @@ -#! /bin/sh - -# Do some "integration" testing against running PostgreSQL server. - -# This file is to be sourced. - -try_random_port () -{ - _port=$RANDOM - if test -n "$_port" && eval '_port=$(( $_port + 32000 ))' 2>/dev/null; then - echo "$_port" - elif test -x /usr/bin/shuf; then - /usr/bin/shuf -r -n 1 -i 32000-64767 - else - echo 54321 - fi -} - -: ${PGTESTS_DATADIR=`pwd`/datadir} -: ${PGTESTS_ADMIN=`id -u -n`} -: ${PGTESTS_ADMINDB=$PGTESTS_ADMIN} -: ${PGTESTS_ADMINPASS=$PGTESTS_ADMIN} -: ${PGTESTS_PORT=`try_random_port`} -: ${PGTESTS_SOCKETDIR=/tmp} -: ${PGTESTS_USERS=test:test} -: ${PGTESTS_DATABASES=test:test} - -# Stop the old cluster and/or remove it's data. -: ${PGTESTS_STARTCLEANUP=:} - -# Cleanup once we exit the script. -: ${PGTESTS_CLEANUP=:} - -# Cleanup once we exit the script. -: ${PGTESTS_CLEANUP=:} - -export PGPORT=$PGTESTS_PORT -export PGHOST=$PGTESTS_SOCKETDIR - -: - -warning () -{ - echo >&2 " ! $*" -} - - -__trap_cb () -{ - IFS=' ' - for __func in $__TRAP_ACTIONS - do - $__func - done -} -trap __trap_cb EXIT - - -__pgtests_initdb () -{ - initdb "$PGTESTS_DATADIR" -U "$PGTESTS_ADMIN" \ - --auth-local=peer --auth-host=md5 \ - ${PGTESTS_LOCALE+--locale="$PGTESTS_LOCALE"} -} - - -__pgtests_start () -{ - pg_ctl -D "$PGTESTS_DATADIR" -l "$PGTESTS_DATADIR"/start.log start \ - -o "-k $PGTESTS_SOCKETDIR -p $PGTESTS_PORT" -w || { - cat >&2 "$PGTESTS_DATADIR"/start.log - false - } -} - - -__pgtests_create_admins_db () -{ - createdb -h "$PGTESTS_SOCKETDIR" "$PGTESTS_ADMINDB" --owner "$PGTESTS_ADMIN" -p "$PGTESTS_PORT" -} - - -__pgtests_passwd() -{ - psql -d postgres --set=user="$1" --set=pass="$2" -tA \ - <<<"ALTER USER :\"user\" WITH ENCRYPTED PASSWORD :'pass';" -} - -pgtests_start () -{ - unset __TRAP_ACTIONS - - if $PGTESTS_STARTCLEANUP; then - # We don't plan to be serious here. This pgtests_* effort is just to - # ease _testing_ against running postgresql server without too much - # writing. - if test -f "$PGTESTS_DATADIR"/postmaster.pid; then - # Give it a try. - warning "Seems like server works, trying to stop." - pg_ctl stop -D "$PGTESTS_DATADIR" -w - fi - - # Cleanup testing directory - if test -e "$PGTESTS_DATADIR"; then - warning "Removing old data directory." - rm -r "$PGTESTS_DATADIR" - fi - fi - - __pgtests_initdb - __TRAP_ACTIONS="pgtests_cleanup $__TRAP_ACTIONS" - __pgtests_start - __TRAP_ACTIONS="pgtests_stop $__TRAP_ACTIONS" - __pgtests_create_admins_db - - __pgtests_passwd "$PGTESTS_ADMIN" "$PGTESTS_ADMINPASS" - - - for _pgt_user in $PGTESTS_USERS - do - save_IFS=$IFS - IFS=: - _user= - _pass= - for _part in $_pgt_user - do - if test -z "$_user"; then - _user=$_part - else - _pass=$_part - fi - done - - createuser "$_user" - __pgtests_passwd "$_user" "$_pass" - IFS=$save_IFS - done - - - for _pgt_db in $PGTESTS_DATABASES - do - save_IFS=$IFS - IFS=: - _db= - _user= - for _part in $_pgt_db - do - if test -z "$_user"; then - _user=$_part - else - _db=$_part - fi - done - - createdb "$_db" --owner "$_part" - - IFS=$save_IFS - done -} - - -__clean_trap_action () -{ - __new_actions= - for __action in $__TRAP_ACTIONS - do - if test "$__action" = "$1"; then - : - else - __new_actions="$__action $__new_actions" - fi - done - - __TRAP_ACTIONS=$__new_actions -} - - -pgtests_cleanup () -{ - if $PGTESTS_CLEANUP && $PGTESTS_AUTOSTOP; then - rm -r "$PGTESTS_DATADIR" - fi - __clean_trap_action pgtests_cleanup -} - - -pgtests_stop () -{ - if $PGTESTS_AUTOSTOP; then - pg_ctl stop -D "$PGTESTS_DATADIR" -w - fi - __clean_trap_action pgtests_stop -}