10.06.2013, 17:51, Dimitri Fontaine kirjoitti: > Andres Freund <and...@2ndquadrant.com> writes: >>> In any case, no packager is going to ship an insecure-by-default >>> configuration, which is what Dimitri seems to be fantasizing would >>> happen. It would have to be local option to relax the permissions >>> on the directory, no matter where it is. >> >> *I* don't want that at all. All I'd like to have is a postgresql.conf >> option specifying additional locations. > > Same from me. I think I would even take non-plural location.
Here's a patch to allow overriding extension installation directory. The patch allows superusers to change it at runtime, but we could also restrict it to postgresql.conf if needed. I don't really see a point in restricting it (or not implementing the option at all) as the superuser can already load custom C code and sql from anywhere in the filesystem; not having configurable extension directory just makes it harder to test extensions and to create private clusters of PG data in a custom location without using custom binaries. I don't think anyone should be packaging and shipping PG with extension_directory set, but we really should allow it for superusers and postgresql.conf so people can test extensions without hacks like this: https://github.com/ohmu/pgmemcache/blob/master/localtests.sh#L23 / Oskari
From 35cae53aa5e9cf89b19a3ae276e635b42fbe5313 Mon Sep 17 00:00:00 2001 From: Oskari Saarenmaa <o...@ohmu.fi> Date: Tue, 17 Feb 2015 23:27:59 +0200 Subject: [PATCH] Allow overriding extension_directory Add a new GUC, 'extension_directory' to override the default directory for extensions. This allows users running their own PostgreSQL clusters using the system binaries to install custom extensions and makes testing extensions easier. --- doc/src/sgml/config.sgml | 38 +++++++++++++++++++++++++++ src/backend/commands/extension.c | 21 +++++++++------ src/backend/utils/misc/guc.c | 12 +++++++++ src/backend/utils/misc/postgresql.conf.sample | 2 ++ src/include/commands/extension.h | 2 ++ 5 files changed, 67 insertions(+), 8 deletions(-) diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index c669f75..f0c762a 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -6341,6 +6341,44 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' </listitem> </varlistentry> + <varlistentry id="guc-extension-directory" xreflabel="extension_directory"> + <term><varname>extension_directory</varname> (<type>string</type>) + <indexterm> + <primary><varname>extension_directory</> configuration parameter</primary> + </indexterm> + <indexterm><primary>extensions</></> + </term> + <listitem> + <para> + Look up extensions from this path when an extension is created using + the <command>CREATE EXTENSION</command>. + </para> + + <para> + The value for <varname>extension_directory</varname> must be an + existing directory containing <literal>.control</literal> files for + extensions. + </para> + + <para> + By default this is the empty string, which uses a directory based + on the compiled-in <productname>PostgreSQL</productname> package + share data directory; this is where the extensions provided by the + standard <productname>PostgreSQL</productname> distribution are + installed. + </para> + + <para> + This parameter can be changed at run time by superusers, but a + setting done that way will only persist until the end of the + client connection, so this method should be reserved for + development purposes. The recommended way to set this parameter + is in the <filename>postgresql.conf</filename> configuration + file. + </para> + </listitem> + </varlistentry> + <varlistentry id="guc-gin-fuzzy-search-limit" xreflabel="gin_fuzzy_search_limit"> <term><varname>gin_fuzzy_search_limit</varname> (<type>integer</type>) <indexterm> diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c index 9a0afa4..365ad59 100644 --- a/src/backend/commands/extension.c +++ b/src/backend/commands/extension.c @@ -56,6 +56,9 @@ #include "utils/tqual.h" +/* GUC */ +char *Extension_directory; + /* Globally visible state variables */ bool creating_extension = false; Oid CurrentExtensionObject = InvalidOid; @@ -348,6 +351,9 @@ get_extension_control_directory(void) char sharepath[MAXPGPATH]; char *result; + if (Extension_directory != NULL) + return pstrdup(Extension_directory); + get_share_path(my_exec_path, sharepath); result = (char *) palloc(MAXPGPATH); snprintf(result, MAXPGPATH, "%s/extension", sharepath); @@ -358,13 +364,11 @@ get_extension_control_directory(void) static char * get_extension_control_filename(const char *extname) { - char sharepath[MAXPGPATH]; char *result; - get_share_path(my_exec_path, sharepath); result = (char *) palloc(MAXPGPATH); - snprintf(result, MAXPGPATH, "%s/extension/%s.control", - sharepath, extname); + snprintf(result, MAXPGPATH, "%s/%s.control", + get_extension_control_directory(), extname); return result; } @@ -372,12 +376,12 @@ get_extension_control_filename(const char *extname) static char * get_extension_script_directory(ExtensionControlFile *control) { - char sharepath[MAXPGPATH]; char *result; + char *extdir; /* * The directory parameter can be omitted, absolute, or relative to the - * installation's share directory. + * extension directory. */ if (!control->directory) return get_extension_control_directory(); @@ -385,9 +389,10 @@ get_extension_script_directory(ExtensionControlFile *control) if (is_absolute_path(control->directory)) return pstrdup(control->directory); - get_share_path(my_exec_path, sharepath); result = (char *) palloc(MAXPGPATH); - snprintf(result, MAXPGPATH, "%s/%s", sharepath, control->directory); + extdir = get_extension_control_directory(); + get_parent_directory(extdir); + snprintf(result, MAXPGPATH, "%s/%s", extdir, control->directory); return result; } diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 8cb9ceb..edd1b6d 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -32,6 +32,7 @@ #include "access/xact.h" #include "catalog/namespace.h" #include "commands/async.h" +#include "commands/extension.h" #include "commands/prepare.h" #include "commands/vacuum.h" #include "commands/variable.h" @@ -2775,6 +2776,17 @@ static struct config_string ConfigureNamesString[] = }, { + {"extension_directory", PGC_SUSET, CLIENT_CONN_OTHER, + gettext_noop("Sets the directory from which extensions are installed."), + NULL, + GUC_SUPERUSER_ONLY + }, + &Extension_directory, + NULL, + NULL, NULL, NULL + }, + + { {"krb_server_keyfile", PGC_SIGHUP, CONN_AUTH_SECURITY, gettext_noop("Sets the location of the Kerberos server key file."), NULL, diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index 8dfd485..f3fdf7f 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -549,6 +549,8 @@ #dynamic_library_path = '$libdir' #local_preload_libraries = '' #session_preload_libraries = '' +#extension_directory = '' # load extensions from this directory + # instead of installed share directory #------------------------------------------------------------------------------ diff --git a/src/include/commands/extension.h b/src/include/commands/extension.h index 2cf784b..3f54e5a 100644 --- a/src/include/commands/extension.h +++ b/src/include/commands/extension.h @@ -16,6 +16,8 @@ #include "nodes/parsenodes.h" +/* GUC */ +extern char *Extension_directory; /* * creating_extension is only true while running a CREATE EXTENSION command. -- 2.1.0
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers