mirror of
https://github.com/postgres/postgres.git
synced 2025-06-05 00:02:04 -04:00
Make createlang and droplang proof against weird search_path settings
by forcing search_path to be just pg_catalog.
This commit is contained in:
parent
866ffc2fe3
commit
9a9328003d
@ -1,22 +1,28 @@
|
|||||||
/*-------------------------------------------------------------------------
|
/*-------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* Miscellaneous shared code
|
* common.c
|
||||||
|
* Common support routines for bin/scripts/
|
||||||
|
*
|
||||||
*
|
*
|
||||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/bin/scripts/common.c,v 1.17 2005/02/22 04:41:30 momjian Exp $
|
* $PostgreSQL: pgsql/src/bin/scripts/common.c,v 1.18 2005/08/15 21:02:26 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres_fe.h"
|
#include "postgres_fe.h"
|
||||||
#include "common.h"
|
|
||||||
#include "libpq-fe.h"
|
|
||||||
|
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#ifndef HAVE_INT_OPTRESET
|
||||||
|
int optreset;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns the current user name.
|
* Returns the current user name.
|
||||||
@ -55,7 +61,8 @@ get_user_name(const char *progname)
|
|||||||
* options.
|
* options.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
handle_help_version_opts(int argc, char *argv[], const char *fixed_progname, help_handler hlp)
|
handle_help_version_opts(int argc, char *argv[],
|
||||||
|
const char *fixed_progname, help_handler hlp)
|
||||||
{
|
{
|
||||||
if (argc > 1)
|
if (argc > 1)
|
||||||
{
|
{
|
||||||
@ -79,7 +86,8 @@ handle_help_version_opts(int argc, char *argv[], const char *fixed_progname, hel
|
|||||||
*/
|
*/
|
||||||
PGconn *
|
PGconn *
|
||||||
connectDatabase(const char *dbname, const char *pghost, const char *pgport,
|
connectDatabase(const char *dbname, const char *pghost, const char *pgport,
|
||||||
const char *pguser, bool require_password, const char *progname)
|
const char *pguser, bool require_password,
|
||||||
|
const char *progname)
|
||||||
{
|
{
|
||||||
PGconn *conn;
|
PGconn *conn;
|
||||||
char *password = NULL;
|
char *password = NULL;
|
||||||
@ -146,8 +154,10 @@ executeQuery(PGconn *conn, const char *query, const char *progname, bool echo)
|
|||||||
if (!res ||
|
if (!res ||
|
||||||
PQresultStatus(res) != PGRES_TUPLES_OK)
|
PQresultStatus(res) != PGRES_TUPLES_OK)
|
||||||
{
|
{
|
||||||
fprintf(stderr, _("%s: query failed: %s"), progname, PQerrorMessage(conn));
|
fprintf(stderr, _("%s: query failed: %s"),
|
||||||
fprintf(stderr, _("%s: query was: %s\n"), progname, query);
|
progname, PQerrorMessage(conn));
|
||||||
|
fprintf(stderr, _("%s: query was: %s\n"),
|
||||||
|
progname, query);
|
||||||
PQfinish(conn);
|
PQfinish(conn);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@ -156,6 +166,34 @@ executeQuery(PGconn *conn, const char *query, const char *progname, bool echo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* As above for a SQL command (which returns nothing).
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
executeCommand(PGconn *conn, const char *query,
|
||||||
|
const char *progname, bool echo)
|
||||||
|
{
|
||||||
|
PGresult *res;
|
||||||
|
|
||||||
|
if (echo)
|
||||||
|
printf("%s\n", query);
|
||||||
|
|
||||||
|
res = PQexec(conn, query);
|
||||||
|
if (!res ||
|
||||||
|
PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||||
|
{
|
||||||
|
fprintf(stderr, _("%s: query failed: %s"),
|
||||||
|
progname, PQerrorMessage(conn));
|
||||||
|
fprintf(stderr, _("%s: query was: %s\n"),
|
||||||
|
progname, query);
|
||||||
|
PQfinish(conn);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
PQclear(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check yes/no answer in a localized way. 1=yes, 0=no, -1=neither.
|
* Check yes/no answer in a localized way. 1=yes, 0=no, -1=neither.
|
||||||
*/
|
*/
|
||||||
|
@ -1,24 +1,40 @@
|
|||||||
#include "postgres_fe.h"
|
/*
|
||||||
|
* common.h
|
||||||
|
* Common support routines for bin/scripts/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2003-2005, PostgreSQL Global Development Group
|
||||||
|
*
|
||||||
|
* $PostgreSQL: pgsql/src/bin/scripts/common.h,v 1.11 2005/08/15 21:02:26 tgl Exp $
|
||||||
|
*/
|
||||||
|
#ifndef COMMON_H
|
||||||
|
#define COMMON_H
|
||||||
|
|
||||||
#include "libpq-fe.h"
|
#include "libpq-fe.h"
|
||||||
#include "pqexpbuffer.h"
|
#include "pqexpbuffer.h"
|
||||||
#include "getopt_long.h"
|
#include "getopt_long.h"
|
||||||
|
|
||||||
#ifndef HAVE_INT_OPTRESET
|
#ifndef HAVE_INT_OPTRESET
|
||||||
int optreset;
|
extern int optreset;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const char *get_user_name(const char *progname);
|
typedef void (*help_handler) (const char *progname);
|
||||||
|
|
||||||
typedef void (*help_handler) (const char *);
|
extern const char *get_user_name(const char *progname);
|
||||||
|
|
||||||
void handle_help_version_opts(int argc, char *argv[], const char *fixed_progname, help_handler hlp);
|
extern void handle_help_version_opts(int argc, char *argv[],
|
||||||
|
const char *fixed_progname,
|
||||||
|
help_handler hlp);
|
||||||
|
|
||||||
PGconn *connectDatabase(const char *dbname, const char *pghost, const char *pgport,
|
extern PGconn *connectDatabase(const char *dbname, const char *pghost,
|
||||||
const char *pguser, bool require_password, const char *progname);
|
const char *pgport, const char *pguser,
|
||||||
|
bool require_password, const char *progname);
|
||||||
|
|
||||||
PGresult *
|
extern PGresult *executeQuery(PGconn *conn, const char *query,
|
||||||
executeQuery(PGconn *conn, const char *command, const char *progname, bool echo);
|
const char *progname, bool echo);
|
||||||
|
|
||||||
int
|
extern void executeCommand(PGconn *conn, const char *query,
|
||||||
check_yesno_response(const char *string);
|
const char *progname, bool echo);
|
||||||
|
|
||||||
|
extern int check_yesno_response(const char *string);
|
||||||
|
|
||||||
|
#endif /* COMMON_H */
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/bin/scripts/createlang.c,v 1.18 2005/07/10 14:26:30 momjian Exp $
|
* $PostgreSQL: pgsql/src/bin/scripts/createlang.c,v 1.19 2005/08/15 21:02:26 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -138,11 +138,12 @@ main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
printQueryOpt popt;
|
printQueryOpt popt;
|
||||||
|
|
||||||
conn = connectDatabase(dbname, host, port, username, password, progname);
|
conn = connectDatabase(dbname, host, port, username, password,
|
||||||
|
progname);
|
||||||
|
|
||||||
printfPQExpBuffer(&sql, "SELECT lanname as \"%s\", (CASE WHEN lanpltrusted "
|
printfPQExpBuffer(&sql, "SELECT lanname as \"%s\", "
|
||||||
"THEN '%s' ELSE '%s' END) as \"%s\" FROM pg_language "
|
"(CASE WHEN lanpltrusted THEN '%s' ELSE '%s' END) as \"%s\" "
|
||||||
"WHERE lanispl IS TRUE;",
|
"FROM pg_catalog.pg_language WHERE lanispl;",
|
||||||
_("Name"), _("yes"), _("no"), _("Trusted?"));
|
_("Name"), _("yes"), _("no"), _("Trusted?"));
|
||||||
result = executeQuery(conn, sql.data, progname, echo);
|
result = executeQuery(conn, sql.data, progname, echo);
|
||||||
|
|
||||||
@ -221,6 +222,13 @@ main(int argc, char *argv[])
|
|||||||
|
|
||||||
conn = connectDatabase(dbname, host, port, username, password, progname);
|
conn = connectDatabase(dbname, host, port, username, password, progname);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Force schema search path to be just pg_catalog, so that we don't
|
||||||
|
* have to be paranoid about search paths below.
|
||||||
|
*/
|
||||||
|
executeCommand(conn, "SET search_path = pg_catalog;",
|
||||||
|
progname, echo);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make sure the language isn't already installed
|
* Make sure the language isn't already installed
|
||||||
*/
|
*/
|
||||||
@ -232,8 +240,7 @@ main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
PQfinish(conn);
|
PQfinish(conn);
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
_("%s: language \"%s\" is already installed in "
|
_("%s: language \"%s\" is already installed in database \"%s\"\n"),
|
||||||
"database \"%s\"\n"),
|
|
||||||
progname, langname, dbname);
|
progname, langname, dbname);
|
||||||
/* separate exit status for "already installed" */
|
/* separate exit status for "already installed" */
|
||||||
exit(2);
|
exit(2);
|
||||||
@ -244,7 +251,8 @@ main(int argc, char *argv[])
|
|||||||
* Check whether the call handler exists
|
* Check whether the call handler exists
|
||||||
*/
|
*/
|
||||||
printfPQExpBuffer(&sql, "SELECT oid FROM pg_proc WHERE proname = '%s' "
|
printfPQExpBuffer(&sql, "SELECT oid FROM pg_proc WHERE proname = '%s' "
|
||||||
"AND prorettype = 'pg_catalog.language_handler'::regtype "
|
"AND pronamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'pg_catalog') "
|
||||||
|
"AND prorettype = 'language_handler'::regtype "
|
||||||
"AND pronargs = 0;", handler);
|
"AND pronargs = 0;", handler);
|
||||||
result = executeQuery(conn, sql.data, progname, echo);
|
result = executeQuery(conn, sql.data, progname, echo);
|
||||||
handlerexists = (PQntuples(result) > 0);
|
handlerexists = (PQntuples(result) > 0);
|
||||||
@ -255,9 +263,10 @@ main(int argc, char *argv[])
|
|||||||
*/
|
*/
|
||||||
if (validator)
|
if (validator)
|
||||||
{
|
{
|
||||||
printfPQExpBuffer(&sql, "SELECT oid FROM pg_proc WHERE proname = '%s'"
|
printfPQExpBuffer(&sql, "SELECT oid FROM pg_proc WHERE proname = '%s' "
|
||||||
" AND proargtypes[0] = 'pg_catalog.oid'::regtype "
|
"AND pronamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'pg_catalog') "
|
||||||
" AND pronargs = 1;", validator);
|
"AND proargtypes[0] = 'oid'::regtype "
|
||||||
|
"AND pronargs = 1;", validator);
|
||||||
result = executeQuery(conn, sql.data, progname, echo);
|
result = executeQuery(conn, sql.data, progname, echo);
|
||||||
validatorexists = (PQntuples(result) > 0);
|
validatorexists = (PQntuples(result) > 0);
|
||||||
PQclear(result);
|
PQclear(result);
|
||||||
@ -267,27 +276,30 @@ main(int argc, char *argv[])
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Create the function(s) and the language
|
* Create the function(s) and the language
|
||||||
|
*
|
||||||
|
* NOTE: the functions will be created in pg_catalog because
|
||||||
|
* of our previous "SET search_path".
|
||||||
*/
|
*/
|
||||||
resetPQExpBuffer(&sql);
|
resetPQExpBuffer(&sql);
|
||||||
|
|
||||||
if (!handlerexists)
|
if (!handlerexists)
|
||||||
appendPQExpBuffer(&sql,
|
appendPQExpBuffer(&sql,
|
||||||
"CREATE FUNCTION pg_catalog.\"%s\" () RETURNS "
|
"CREATE FUNCTION \"%s\" () RETURNS language_handler "
|
||||||
"language_handler AS '%s/%s' LANGUAGE C;\n",
|
"AS '%s/%s' LANGUAGE C;\n",
|
||||||
handler, pglib, object);
|
handler, pglib, object);
|
||||||
|
|
||||||
if (!validatorexists)
|
if (!validatorexists)
|
||||||
appendPQExpBuffer(&sql,
|
appendPQExpBuffer(&sql,
|
||||||
"CREATE FUNCTION pg_catalog.\"%s\" (oid) RETURNS "
|
"CREATE FUNCTION \"%s\" (oid) RETURNS void "
|
||||||
"void AS '%s/%s' LANGUAGE C;\n",
|
"AS '%s/%s' LANGUAGE C;\n",
|
||||||
validator, pglib, object);
|
validator, pglib, object);
|
||||||
|
|
||||||
appendPQExpBuffer(&sql,
|
appendPQExpBuffer(&sql,
|
||||||
"CREATE %sLANGUAGE \"%s\" HANDLER pg_catalog.\"%s\"",
|
"CREATE %sLANGUAGE \"%s\" HANDLER \"%s\"",
|
||||||
(trusted ? "TRUSTED " : ""), langname, handler);
|
(trusted ? "TRUSTED " : ""), langname, handler);
|
||||||
|
|
||||||
if (validator)
|
if (validator)
|
||||||
appendPQExpBuffer(&sql, " VALIDATOR pg_catalog.\"%s\"", validator);
|
appendPQExpBuffer(&sql, " VALIDATOR \"%s\"", validator);
|
||||||
|
|
||||||
appendPQExpBuffer(&sql, ";\n");
|
appendPQExpBuffer(&sql, ";\n");
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/bin/scripts/droplang.c,v 1.16 2005/07/10 14:26:30 momjian Exp $
|
* $PostgreSQL: pgsql/src/bin/scripts/droplang.c,v 1.17 2005/08/15 21:02:26 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -140,9 +140,9 @@ main(int argc, char *argv[])
|
|||||||
conn = connectDatabase(dbname, host, port, username, password,
|
conn = connectDatabase(dbname, host, port, username, password,
|
||||||
progname);
|
progname);
|
||||||
|
|
||||||
printfPQExpBuffer(&sql, "SELECT lanname as \"%s\", (CASE "
|
printfPQExpBuffer(&sql, "SELECT lanname as \"%s\", "
|
||||||
"WHEN lanpltrusted THEN '%s' ELSE '%s' END) "
|
"(CASE WHEN lanpltrusted THEN '%s' ELSE '%s' END) as \"%s\" "
|
||||||
"as \"%s\" FROM pg_language WHERE lanispl IS TRUE;",
|
"FROM pg_catalog.pg_language WHERE lanispl;",
|
||||||
_("Name"), _("yes"), _("no"), _("Trusted?"));
|
_("Name"), _("yes"), _("no"), _("Trusted?"));
|
||||||
result = executeQuery(conn, sql.data, progname, echo);
|
result = executeQuery(conn, sql.data, progname, echo);
|
||||||
|
|
||||||
@ -172,6 +172,13 @@ main(int argc, char *argv[])
|
|||||||
|
|
||||||
conn = connectDatabase(dbname, host, port, username, password, progname);
|
conn = connectDatabase(dbname, host, port, username, password, progname);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Force schema search path to be just pg_catalog, so that we don't
|
||||||
|
* have to be paranoid about search paths below.
|
||||||
|
*/
|
||||||
|
executeCommand(conn, "SET search_path = pg_catalog;",
|
||||||
|
progname, echo);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make sure the language is installed and find the OIDs of the
|
* Make sure the language is installed and find the OIDs of the
|
||||||
* handler and validator functions
|
* handler and validator functions
|
||||||
@ -248,8 +255,8 @@ main(int argc, char *argv[])
|
|||||||
*/
|
*/
|
||||||
if (OidIsValid(lanvalidator))
|
if (OidIsValid(lanvalidator))
|
||||||
{
|
{
|
||||||
printfPQExpBuffer(&sql, "SELECT count(*) FROM pg_language WHERE "
|
printfPQExpBuffer(&sql, "SELECT count(*) FROM pg_language "
|
||||||
"lanvalidator = %u AND lanname <> '%s';",
|
"WHERE lanvalidator = %u AND lanname <> '%s';",
|
||||||
lanvalidator, langname);
|
lanvalidator, langname);
|
||||||
result = executeQuery(conn, sql.data, progname, echo);
|
result = executeQuery(conn, sql.data, progname, echo);
|
||||||
if (strcmp(PQgetvalue(result, 0, 0), "0") == 0)
|
if (strcmp(PQgetvalue(result, 0, 0), "0") == 0)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user