Skip to content

Commit 9a93280

Browse files
committed
Make createlang and droplang proof against weird search_path settings
by forcing search_path to be just pg_catalog.
1 parent 866ffc2 commit 9a93280

File tree

4 files changed

+115
-42
lines changed

4 files changed

+115
-42
lines changed

src/bin/scripts/common.c

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,28 @@
11
/*-------------------------------------------------------------------------
22
*
3-
* Miscellaneous shared code
3+
* common.c
4+
* Common support routines for bin/scripts/
5+
*
46
*
57
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
68
* Portions Copyright (c) 1994, Regents of the University of California
79
*
8-
* $PostgreSQL: pgsql/src/bin/scripts/common.c,v 1.17 2005/02/22 04:41:30 momjian Exp $
10+
* $PostgreSQL: pgsql/src/bin/scripts/common.c,v 1.18 2005/08/15 21:02:26 tgl Exp $
911
*
1012
*-------------------------------------------------------------------------
1113
*/
1214

1315
#include "postgres_fe.h"
14-
#include "common.h"
15-
#include "libpq-fe.h"
1616

1717
#include <pwd.h>
1818
#include <unistd.h>
1919

20+
#include "common.h"
21+
22+
#ifndef HAVE_INT_OPTRESET
23+
int optreset;
24+
#endif
25+
2026

2127
/*
2228
* Returns the current user name.
@@ -55,7 +61,8 @@ get_user_name(const char *progname)
5561
* options.
5662
*/
5763
void
58-
handle_help_version_opts(int argc, char *argv[], const char *fixed_progname, help_handler hlp)
64+
handle_help_version_opts(int argc, char *argv[],
65+
const char *fixed_progname, help_handler hlp)
5966
{
6067
if (argc > 1)
6168
{
@@ -79,7 +86,8 @@ handle_help_version_opts(int argc, char *argv[], const char *fixed_progname, hel
7986
*/
8087
PGconn *
8188
connectDatabase(const char *dbname, const char *pghost, const char *pgport,
82-
const char *pguser, bool require_password, const char *progname)
89+
const char *pguser, bool require_password,
90+
const char *progname)
8391
{
8492
PGconn *conn;
8593
char *password = NULL;
@@ -146,8 +154,10 @@ executeQuery(PGconn *conn, const char *query, const char *progname, bool echo)
146154
if (!res ||
147155
PQresultStatus(res) != PGRES_TUPLES_OK)
148156
{
149-
fprintf(stderr, _("%s: query failed: %s"), progname, PQerrorMessage(conn));
150-
fprintf(stderr, _("%s: query was: %s\n"), progname, query);
157+
fprintf(stderr, _("%s: query failed: %s"),
158+
progname, PQerrorMessage(conn));
159+
fprintf(stderr, _("%s: query was: %s\n"),
160+
progname, query);
151161
PQfinish(conn);
152162
exit(1);
153163
}
@@ -156,6 +166,34 @@ executeQuery(PGconn *conn, const char *query, const char *progname, bool echo)
156166
}
157167

158168

169+
/*
170+
* As above for a SQL command (which returns nothing).
171+
*/
172+
void
173+
executeCommand(PGconn *conn, const char *query,
174+
const char *progname, bool echo)
175+
{
176+
PGresult *res;
177+
178+
if (echo)
179+
printf("%s\n", query);
180+
181+
res = PQexec(conn, query);
182+
if (!res ||
183+
PQresultStatus(res) != PGRES_COMMAND_OK)
184+
{
185+
fprintf(stderr, _("%s: query failed: %s"),
186+
progname, PQerrorMessage(conn));
187+
fprintf(stderr, _("%s: query was: %s\n"),
188+
progname, query);
189+
PQfinish(conn);
190+
exit(1);
191+
}
192+
193+
PQclear(res);
194+
}
195+
196+
159197
/*
160198
* Check yes/no answer in a localized way. 1=yes, 0=no, -1=neither.
161199
*/

src/bin/scripts/common.h

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,40 @@
1-
#include "postgres_fe.h"
1+
/*
2+
* common.h
3+
* Common support routines for bin/scripts/
4+
*
5+
* Copyright (c) 2003-2005, PostgreSQL Global Development Group
6+
*
7+
* $PostgreSQL: pgsql/src/bin/scripts/common.h,v 1.11 2005/08/15 21:02:26 tgl Exp $
8+
*/
9+
#ifndef COMMON_H
10+
#define COMMON_H
211

312
#include "libpq-fe.h"
413
#include "pqexpbuffer.h"
514
#include "getopt_long.h"
615

716
#ifndef HAVE_INT_OPTRESET
8-
int optreset;
17+
extern int optreset;
918
#endif
1019

11-
const char *get_user_name(const char *progname);
20+
typedef void (*help_handler) (const char *progname);
1221

13-
typedef void (*help_handler) (const char *);
22+
extern const char *get_user_name(const char *progname);
1423

15-
void handle_help_version_opts(int argc, char *argv[], const char *fixed_progname, help_handler hlp);
24+
extern void handle_help_version_opts(int argc, char *argv[],
25+
const char *fixed_progname,
26+
help_handler hlp);
1627

17-
PGconn *connectDatabase(const char *dbname, const char *pghost, const char *pgport,
18-
const char *pguser, bool require_password, const char *progname);
28+
extern PGconn *connectDatabase(const char *dbname, const char *pghost,
29+
const char *pgport, const char *pguser,
30+
bool require_password, const char *progname);
1931

20-
PGresult *
21-
executeQuery(PGconn *conn, const char *command, const char *progname, bool echo);
32+
extern PGresult *executeQuery(PGconn *conn, const char *query,
33+
const char *progname, bool echo);
2234

23-
int
24-
check_yesno_response(const char *string);
35+
extern void executeCommand(PGconn *conn, const char *query,
36+
const char *progname, bool echo);
37+
38+
extern int check_yesno_response(const char *string);
39+
40+
#endif /* COMMON_H */

src/bin/scripts/createlang.c

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
66
* Portions Copyright (c) 1994, Regents of the University of California
77
*
8-
* $PostgreSQL: pgsql/src/bin/scripts/createlang.c,v 1.18 2005/07/10 14:26:30 momjian Exp $
8+
* $PostgreSQL: pgsql/src/bin/scripts/createlang.c,v 1.19 2005/08/15 21:02:26 tgl Exp $
99
*
1010
*-------------------------------------------------------------------------
1111
*/
@@ -138,11 +138,12 @@ main(int argc, char *argv[])
138138
{
139139
printQueryOpt popt;
140140

141-
conn = connectDatabase(dbname, host, port, username, password, progname);
141+
conn = connectDatabase(dbname, host, port, username, password,
142+
progname);
142143

143-
printfPQExpBuffer(&sql, "SELECT lanname as \"%s\", (CASE WHEN lanpltrusted "
144-
"THEN '%s' ELSE '%s' END) as \"%s\" FROM pg_language "
145-
"WHERE lanispl IS TRUE;",
144+
printfPQExpBuffer(&sql, "SELECT lanname as \"%s\", "
145+
"(CASE WHEN lanpltrusted THEN '%s' ELSE '%s' END) as \"%s\" "
146+
"FROM pg_catalog.pg_language WHERE lanispl;",
146147
_("Name"), _("yes"), _("no"), _("Trusted?"));
147148
result = executeQuery(conn, sql.data, progname, echo);
148149

@@ -221,6 +222,13 @@ main(int argc, char *argv[])
221222

222223
conn = connectDatabase(dbname, host, port, username, password, progname);
223224

225+
/*
226+
* Force schema search path to be just pg_catalog, so that we don't
227+
* have to be paranoid about search paths below.
228+
*/
229+
executeCommand(conn, "SET search_path = pg_catalog;",
230+
progname, echo);
231+
224232
/*
225233
* Make sure the language isn't already installed
226234
*/
@@ -232,8 +240,7 @@ main(int argc, char *argv[])
232240
{
233241
PQfinish(conn);
234242
fprintf(stderr,
235-
_("%s: language \"%s\" is already installed in "
236-
"database \"%s\"\n"),
243+
_("%s: language \"%s\" is already installed in database \"%s\"\n"),
237244
progname, langname, dbname);
238245
/* separate exit status for "already installed" */
239246
exit(2);
@@ -244,7 +251,8 @@ main(int argc, char *argv[])
244251
* Check whether the call handler exists
245252
*/
246253
printfPQExpBuffer(&sql, "SELECT oid FROM pg_proc WHERE proname = '%s' "
247-
"AND prorettype = 'pg_catalog.language_handler'::regtype "
254+
"AND pronamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'pg_catalog') "
255+
"AND prorettype = 'language_handler'::regtype "
248256
"AND pronargs = 0;", handler);
249257
result = executeQuery(conn, sql.data, progname, echo);
250258
handlerexists = (PQntuples(result) > 0);
@@ -255,9 +263,10 @@ main(int argc, char *argv[])
255263
*/
256264
if (validator)
257265
{
258-
printfPQExpBuffer(&sql, "SELECT oid FROM pg_proc WHERE proname = '%s'"
259-
" AND proargtypes[0] = 'pg_catalog.oid'::regtype "
260-
" AND pronargs = 1;", validator);
266+
printfPQExpBuffer(&sql, "SELECT oid FROM pg_proc WHERE proname = '%s' "
267+
"AND pronamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'pg_catalog') "
268+
"AND proargtypes[0] = 'oid'::regtype "
269+
"AND pronargs = 1;", validator);
261270
result = executeQuery(conn, sql.data, progname, echo);
262271
validatorexists = (PQntuples(result) > 0);
263272
PQclear(result);
@@ -267,27 +276,30 @@ main(int argc, char *argv[])
267276

268277
/*
269278
* Create the function(s) and the language
279+
*
280+
* NOTE: the functions will be created in pg_catalog because
281+
* of our previous "SET search_path".
270282
*/
271283
resetPQExpBuffer(&sql);
272284

273285
if (!handlerexists)
274286
appendPQExpBuffer(&sql,
275-
"CREATE FUNCTION pg_catalog.\"%s\" () RETURNS "
276-
"language_handler AS '%s/%s' LANGUAGE C;\n",
287+
"CREATE FUNCTION \"%s\" () RETURNS language_handler "
288+
"AS '%s/%s' LANGUAGE C;\n",
277289
handler, pglib, object);
278290

279291
if (!validatorexists)
280292
appendPQExpBuffer(&sql,
281-
"CREATE FUNCTION pg_catalog.\"%s\" (oid) RETURNS "
282-
"void AS '%s/%s' LANGUAGE C;\n",
293+
"CREATE FUNCTION \"%s\" (oid) RETURNS void "
294+
"AS '%s/%s' LANGUAGE C;\n",
283295
validator, pglib, object);
284296

285297
appendPQExpBuffer(&sql,
286-
"CREATE %sLANGUAGE \"%s\" HANDLER pg_catalog.\"%s\"",
298+
"CREATE %sLANGUAGE \"%s\" HANDLER \"%s\"",
287299
(trusted ? "TRUSTED " : ""), langname, handler);
288300

289301
if (validator)
290-
appendPQExpBuffer(&sql, " VALIDATOR pg_catalog.\"%s\"", validator);
302+
appendPQExpBuffer(&sql, " VALIDATOR \"%s\"", validator);
291303

292304
appendPQExpBuffer(&sql, ";\n");
293305

src/bin/scripts/droplang.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
66
* Portions Copyright (c) 1994, Regents of the University of California
77
*
8-
* $PostgreSQL: pgsql/src/bin/scripts/droplang.c,v 1.16 2005/07/10 14:26:30 momjian Exp $
8+
* $PostgreSQL: pgsql/src/bin/scripts/droplang.c,v 1.17 2005/08/15 21:02:26 tgl Exp $
99
*
1010
*-------------------------------------------------------------------------
1111
*/
@@ -140,9 +140,9 @@ main(int argc, char *argv[])
140140
conn = connectDatabase(dbname, host, port, username, password,
141141
progname);
142142

143-
printfPQExpBuffer(&sql, "SELECT lanname as \"%s\", (CASE "
144-
"WHEN lanpltrusted THEN '%s' ELSE '%s' END) "
145-
"as \"%s\" FROM pg_language WHERE lanispl IS TRUE;",
143+
printfPQExpBuffer(&sql, "SELECT lanname as \"%s\", "
144+
"(CASE WHEN lanpltrusted THEN '%s' ELSE '%s' END) as \"%s\" "
145+
"FROM pg_catalog.pg_language WHERE lanispl;",
146146
_("Name"), _("yes"), _("no"), _("Trusted?"));
147147
result = executeQuery(conn, sql.data, progname, echo);
148148

@@ -172,6 +172,13 @@ main(int argc, char *argv[])
172172

173173
conn = connectDatabase(dbname, host, port, username, password, progname);
174174

175+
/*
176+
* Force schema search path to be just pg_catalog, so that we don't
177+
* have to be paranoid about search paths below.
178+
*/
179+
executeCommand(conn, "SET search_path = pg_catalog;",
180+
progname, echo);
181+
175182
/*
176183
* Make sure the language is installed and find the OIDs of the
177184
* handler and validator functions
@@ -248,8 +255,8 @@ main(int argc, char *argv[])
248255
*/
249256
if (OidIsValid(lanvalidator))
250257
{
251-
printfPQExpBuffer(&sql, "SELECT count(*) FROM pg_language WHERE "
252-
"lanvalidator = %u AND lanname <> '%s';",
258+
printfPQExpBuffer(&sql, "SELECT count(*) FROM pg_language "
259+
"WHERE lanvalidator = %u AND lanname <> '%s';",
253260
lanvalidator, langname);
254261
result = executeQuery(conn, sql.data, progname, echo);
255262
if (strcmp(PQgetvalue(result, 0, 0), "0") == 0)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy