summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Sommerseth <dazo@users.sourceforge.net>2012-01-15 23:53:12 +0100
committerDavid Sommerseth <dazo@users.sourceforge.net>2013-06-13 01:01:55 +0200
commit6ce2be3d09484d393c894a291dc9429525d3d914 (patch)
treedf9680acfeac526974173445341d25afdc144476
parent6c1f8ff4f7966f0d1f9cb1b2ff447f0dfc5f8aeb (diff)
downloadeurephia-6ce2be3d09484d393c894a291dc9429525d3d914.tar.gz
eurephia-6ce2be3d09484d393c894a291dc9429525d3d914.tar.xz
eurephia-6ce2be3d09484d393c894a291dc9429525d3d914.zip
edb-pgsql: Reworked the prepared statements infrastructure
Moved all SQL statements out of each function and into a const struct which is loaded at startup. Implemented a safer way of handling parameters to these prepared statements as well. Signed-off-by: David Sommerseth <dazo@users.sourceforge.net>
-rw-r--r--database/postgresql/CMakeLists.txt6
-rw-r--r--database/postgresql/edb-pgsql.c980
-rw-r--r--database/postgresql/pgsql-common.c93
-rw-r--r--database/postgresql/pgsql-common.h47
-rw-r--r--database/postgresql/prepared-sql.c526
-rw-r--r--database/postgresql/prepared-sql.h72
6 files changed, 943 insertions, 781 deletions
diff --git a/database/postgresql/CMakeLists.txt b/database/postgresql/CMakeLists.txt
index 9464f87..ec50b6a 100644
--- a/database/postgresql/CMakeLists.txt
+++ b/database/postgresql/CMakeLists.txt
@@ -88,7 +88,11 @@ LINK_DIRECTORIES(${PGSQL_LIBRARIES_DIRS})
#
# Build instructions
#
-ADD_LIBRARY(edb-pgsql SHARED edb-pgsql.c ../../common/eurephiadb_session_common.c ${pgsql_admin_SRC})
+ADD_LIBRARY(edb-pgsql SHARED edb-pgsql.c
+ pgsql-common.c
+ prepared-sql.c
+ ../../common/eurephiadb_session_common.c
+ ${pgsql_admin_SRC})
TARGET_LINK_LIBRARIES(edb-pgsql common pq ${EXTRA_LIBS})
SET_TARGET_PROPERTIES(edb-pgsql PROPERTIES COMPILE_FLAGS -fPIC)
diff --git a/database/postgresql/edb-pgsql.c b/database/postgresql/edb-pgsql.c
index eabe4fe..2fe1463 100644
--- a/database/postgresql/edb-pgsql.c
+++ b/database/postgresql/edb-pgsql.c
@@ -49,125 +49,21 @@
#include <eurephiadb_session_struct.h>
#include <passwd.h>
-typedef enum { PREPSQL_NONE = 0, PREPSQL_TLS_AUTH, PREPSQL_USERPWD_AUTH,
- PREPSQL_BLACKLIST_ATTEMPTUPD, PREPSQL_USERS_LASTACC_UPD,
- PREPSQL_USERS_GETUID, PREPSQL_ATTEMPTS_RESET, PREPSQL_ATTEMPTS_INCR,
- PREPSQL_ATTEMPTS_REG_CERT, PREPSQL_ATTEMPTS_REG_USERNAME,
- PREPSQL_ATTEMPTS_REG_IPADDR,
- PREPSQL_BLACKLIST_CHECK_CERT, PREPSQL_BLACKLIST_CHECK_USERNAME,
- PREPSQL_BLACKLIST_CHECK_IPADDR,
- PREPSQL_BLACKLIST_REG_CERT, PREPSQL_BLACKLIST_REG_USERNAME,
- PREPSQL_BLACKLIST_REG_IPADDR,
- PREPSQL_SESSIONKEY_GETSEED_SESSION, PREPSQL_SESSIONKEY_GETSEED_AUTH,
- PREPSQL_SESSIONKEY_GETMAC,
- PREPSQL_SESSIONKEY_UNIQ_ADMIN, PREPSQL_SESSIONKEY_UNIQ_PLAUTH,
- PREPSQL_SESSIONKEY_REGISTER, PREPSQL_SESSIONKEY_REMOVE,
- PREPSQL_SESSIONVARS_LOAD, PREPSQL_SESSIONVARS_STORE_NEW,
- PREPSQL_SESSIONVARS_STORE_UPDATE, PREPSQL_SESSIONVARS_STORE_DELETE,
- PREPSQL_SESSIONS_DESTROY_LASTLOG, PREPSQL_SESSIONS_DESTROY_SESS,
- PREPSQL_REGISTER_LOGIN, PREPSQL_REGISTER_LOGOUT,
- PREPSQL_MACHISTORY_REGISTER, PREPSQL_MACHISTORY_LASTLOG,
- PREPSQL_FIREWALL_GETPROFILE
-} _ePG_prepID;
-
-typedef struct {
- _ePG_prepID prepid;
- const char *name;
- unsigned int numargs;
- unsigned int prepared;
-} _ePGprepStatements_t;
-
-static _ePGprepStatements_t _ePGprepStatements[] = {
- {.prepid = PREPSQL_TLS_AUTH,
- .name = "eurephia_tls_auth", .numargs = 0, .prepared = 0},
- {.prepid = PREPSQL_USERPWD_AUTH,
- .name = "eurephia_userpwd_auth", .numargs = 0, .prepared = 0},
- {.prepid = PREPSQL_BLACKLIST_ATTEMPTUPD,
- .name ="eurephia_blacklist_attupd" , .numargs = 0, .prepared = 0},
- {.prepid = PREPSQL_USERS_LASTACC_UPD,
- .name = "eurephia_users_lastacc_upd", .numargs = 0, .prepared = 0},
- {.prepid = PREPSQL_USERS_GETUID,
- .name = "eurephia_getuid", .numargs = 0, .prepared = 0},
- {.prepid = PREPSQL_ATTEMPTS_RESET,
- .name = "eurephia_attempts_reset", .numargs = 0, .prepared = 0},
- {.prepid = PREPSQL_ATTEMPTS_INCR,
- .name = "eurephia_attempts_increment", .numargs = 0, .prepared = 0},
- {.prepid = PREPSQL_ATTEMPTS_REG_CERT,
- .name = "eurephia_attempts_reg_cert", .numargs = 0, .prepared = 0},
- {.prepid = PREPSQL_ATTEMPTS_REG_USERNAME,
- .name = "eurephia_attempts_reg_username", .numargs = 0, .prepared = 0},
- {.prepid = PREPSQL_ATTEMPTS_REG_IPADDR,
- .name = "eurephia_attempts_reg_ipaddr", .numargs = 0, .prepared = 0},
- {.prepid = PREPSQL_BLACKLIST_CHECK_CERT,
- .name = "eurephia_blacklist_check_cert", .numargs = 0, .prepared = 0},
- {.prepid = PREPSQL_BLACKLIST_CHECK_USERNAME,
- .name = "eurephia_blacklist_check_username", .numargs = 0, .prepared = 0},
- {.prepid = PREPSQL_BLACKLIST_CHECK_IPADDR,
- .name = "eurephia_blacklist_check_cert_ipaddr", .numargs = 0, .prepared = 0},
- {.prepid = PREPSQL_BLACKLIST_REG_CERT,
- .name = "eurephia_blacklist_reg_cert", .numargs = 0, .prepared = 0},
- {.prepid = PREPSQL_BLACKLIST_REG_USERNAME,
- .name = "eurephia_blacklist_reg_username", .numargs = 0, .prepared = 0},
- {.prepid = PREPSQL_BLACKLIST_REG_IPADDR,
- .name = "eurephia_blacklist_reg_ipaddr", .numargs = 0, .prepared = 0},
- {.prepid = PREPSQL_SESSIONKEY_GETSEED_SESSION,
- .name = "eurephia_sessionkey_getseed_session", .numargs = 0, .prepared = 0},
- {.prepid = PREPSQL_SESSIONKEY_GETSEED_AUTH,
- .name = "eurephia_sessionkey_getseed_auth", .numargs = 0, .prepared = 0},
- {.prepid = PREPSQL_SESSIONKEY_GETMAC,
- .name = "eurephia_sessionkey_getmac", .numargs = 0, .prepared = 0},
- {.prepid = PREPSQL_SESSIONKEY_UNIQ_ADMIN,
- .name = "eurephia_sessionkey_uniq_admin", .numargs = 0, .prepared = 0},
- {.prepid = PREPSQL_SESSIONKEY_UNIQ_PLAUTH,
- .name = "eurephia_sessionkey_uniq_plauth", .numargs = 0, .prepared = 0},
- {.prepid = PREPSQL_SESSIONKEY_REGISTER,
- .name = "eurephia_sessionkey_register", .numargs = 0, .prepared = 0},
- {.prepid = PREPSQL_SESSIONKEY_REMOVE,
- .name = "eurephia_sessionkey_remove", .numargs = 0, .prepared = 0},
- {.prepid = PREPSQL_SESSIONVARS_LOAD,
- .name = "eurephia_sessionvars_load", .numargs = 0, .prepared = 0},
- {.prepid = PREPSQL_SESSIONVARS_STORE_NEW,
- .name = "eurephia_sessionvars_store_new", .numargs = 0, .prepared = 0},
- {.prepid = PREPSQL_SESSIONVARS_STORE_UPDATE,
- .name = "eurephia_sessionvars_store_upd", .numargs = 0, .prepared = 0},
- {.prepid = PREPSQL_SESSIONVARS_STORE_DELETE,
- .name = "eurephia_sessionvars_store_del", .numargs = 0, .prepared = 0},
- {.prepid = PREPSQL_SESSIONS_DESTROY_LASTLOG,
- .name = "eurephia_sessions_destr_lastlogupd", .numargs = 0, .prepared = 0},
- {.prepid = PREPSQL_SESSIONS_DESTROY_SESS,
- .name = "eurephia_sessions_destr_sessions", .numargs = 0, .prepared = 0},
- {.prepid = PREPSQL_REGISTER_LOGIN,
- .name = "eurephia_register_login", .numargs = 0, .prepared = 0},
- {.prepid = PREPSQL_REGISTER_LOGOUT,
- .name = "eurephia_register_logout", .numargs = 0, .prepared = 0},
- {.prepid = PREPSQL_MACHISTORY_REGISTER,
- .name = "eurephia_machistory_reg", .numargs = 0, .prepared = 0},
- {.prepid = PREPSQL_MACHISTORY_LASTLOG,
- .name = "eurephia_machistory_lastlog_upd", .numargs = 0, .prepared = 0},
- {.prepid = PREPSQL_FIREWALL_GETPROFILE,
- .name = "eurephia_firewall_getprofile", .numargs = 0, .prepared = 0},
- {.prepid = PREPSQL_NONE,
- .name = NULL, .numargs = 0, .prepared = 0},
-};
-
-/* FIXME: Go through the code and place all ePGprepStatement() in a function called from eDBconnect()
- * Let the SQL be declared in _ePGprepStatements_t ... the prep-function will just loop _ePGprepStatements[]
- */
+#include "pgsql-common.h"
+#include "prepared-sql.h"
/**
* Mapping struct - maps attempt types (attempt_IPADDR, attempt_CERTIFICATE, attempt_USERNAME)
* to database field names, configuration options (with default values) and description
*/
typedef struct {
- char *colname; /** Field when doing look up in blacklist and attempts tables */
- char *colname_where; /** Field when using column name in WHERE section of SQL queries */
char *allow_cfg; /** Configure parameter for the attempt limits */
char *descr; /** Description, used to give more readable output for users */
char *default_value; /** Default value, if config option is not found */
- char *value_func; /** If not NULL, value will be passed through given SQL function */
- _ePG_prepID sql_blacklist_check; /** Prepared SQL ID reference for blacklist check queries */
- _ePG_prepID sql_blacklist_reg; /** Prepared SQL ID reference for blacklist register queries */
- _ePG_prepID sql_attempts_reg; /** Prepared SQL ID reference for attempts register queries */
+ ePG_prepID sql_blacklist_check; /** Prepared SQL ID reference for blacklist check queries */
+ ePG_prepID sql_blacklist_reg; /** Prepared SQL ID reference for blacklist register queries */
+ ePG_prepID sql_attempts_reg; /** Prepared SQL ID reference for attempts register queries */
+
} eDBattempt_types_t;
@@ -176,23 +72,20 @@ typedef struct {
*/
static const eDBattempt_types_t eDBattempt_types[] = {
{NULL},
- {.colname = "remoteip", .colname_where = "remoteip",
- .allow_cfg = "allow_ipaddr_attempts", .descr = "IP Address",
- .default_value = "10", .value_func = NULL,
+ {.allow_cfg = "allow_ipaddr_attempts", .descr = "IP Address",
+ .default_value = "10",
.sql_blacklist_check = PREPSQL_BLACKLIST_CHECK_IPADDR,
.sql_blacklist_reg = PREPSQL_BLACKLIST_REG_IPADDR,
.sql_attempts_reg = PREPSQL_ATTEMPTS_REG_IPADDR
},
- {.colname = "digest", .colname_where = "lower(digest)",
- .allow_cfg = "allow_cert_attempts", .descr = "Certificate",
- .default_value = "5", .value_func = "lower",
+ {.allow_cfg = "allow_cert_attempts", .descr = "Certificate",
+ .default_value = "5",
.sql_blacklist_check = PREPSQL_BLACKLIST_CHECK_CERT,
.sql_blacklist_reg = PREPSQL_BLACKLIST_REG_CERT,
.sql_attempts_reg = PREPSQL_ATTEMPTS_REG_CERT
},
- {.colname = "username", .colname_where = "username",
- .allow_cfg = "allow_username_attempts", .descr = "Username",
- .default_value = "3", .value_func = NULL,
+ {.allow_cfg = "allow_username_attempts", .descr = "Username",
+ .default_value = "3",
.sql_blacklist_check = PREPSQL_BLACKLIST_CHECK_USERNAME,
.sql_blacklist_reg = PREPSQL_BLACKLIST_REG_USERNAME,
.sql_attempts_reg = PREPSQL_ATTEMPTS_REG_USERNAME
@@ -201,124 +94,6 @@ static const eDBattempt_types_t eDBattempt_types[] = {
};
-static inline char *ePGgetValue(PGresult *res, int row, int col) {
- if( (res == NULL) || (PQgetisnull(res, row, col) == 1) ) {
- return NULL;
- } else {
- return PQgetvalue(res, row, col);
- }
-}
-
-
-int ePGprepStatementGetID(_ePG_prepID prepid)
-{
- int i;
- for( i = 0; _ePGprepStatements[i].prepid != PREPSQL_NONE; i++ ) {
- if( _ePGprepStatements[i].prepid == prepid ) {
- return i;
- }
- }
- return -1;
-}
-
-
-#define ePGerrorMessage(ctx, dbr, logdst, loglvl, prepid, fmt...) __ePGerrorMessage(ctx, dbr, logdst,loglvl, prepid, __FILE__, __LINE__, ## fmt)
-static void __ePGerrorMessage(eurephiaCTX *ctx, PGresult *dbr, int logdst, int loglvl,
- _ePG_prepID prepid, const char *errfile, const long errline,
- const char *fmt, ...)
-{
- char msgfmt[514];
- va_list ap;
- int id = -1;
-
- if( prepid != PREPSQL_NONE ) {
- id = ePGprepStatementGetID(prepid);
- if( id < 0 ) {
- eurephia_log(ctx, LOG_ERROR, 0,
- "Failed to map prepared statement ID %i to "
- "a valid statement", prepid);
- return;
- }
- }
- memset(&msgfmt, 0, 514);
- va_start(ap, fmt);
- if( prepid != PREPSQL_NONE ) {
- snprintf(msgfmt, 512, "[%s] SQL query failed: %s %s: %s",
- _ePGprepStatements[id].name,
- (dbr != NULL ? PQresStatus(PQresultStatus(dbr)) : ""), fmt,
- (dbr != NULL ? PQresultErrorMessage(dbr)
- : (ctx->dbc != NULL ? PQerrorMessage(ctx->dbc->dbhandle)
- : "[unknown error]")
- ));
- } else {
- snprintf(msgfmt, 512, "SQL query failed: %s %s: %s",
- (dbr != NULL ? PQresStatus(PQresultStatus(dbr)) : ""),
- fmt,
- (dbr != NULL ? PQresultErrorMessage(dbr)
- : (ctx->dbc != NULL ? PQerrorMessage(ctx->dbc->dbhandle)
- : "[unknown error]")
- ));
- }
-#ifdef ENABLE_DEBUG
- _veurephia_log_func(ctx, logdst, loglvl, errfile, errline, ap, msgfmt);
-#else
- veurephia_log(ctx, logdst, loglvl, ap, msgfmt);
-#endif
- va_end(ap);
- memset(&msgfmt, 0, 514);
- if( dbr ) {
- PQclear(dbr);
- }
- if( (loglvl == LOG_EMERG) && (ctx->dbc != NULL)
- && (PQstatus(ctx->dbc->dbhandle) != CONNECTION_OK) ) {
- PQfinish(ctx->dbc->dbhandle);
- }
-}
-
-
-int ePGprepStatement(eurephiaCTX *ctx, _ePG_prepID prepid, const char *sql, int argc)
-{
- int id;
-
- /* Check if this statement is already prepared */
- id = ePGprepStatementGetID(prepid);
- if( _ePGprepStatements[id].prepid == prepid ) {
- PGresult *dbr = NULL;
- _ePGprepStatements_t *prep = &_ePGprepStatements[id];
-
- if( prep->prepared == 1 ) {
- /* statement found, and was already prepared */
- return id;
- }
-
- /* statement found in lookup table, but not prepared in database */
- dbr = PQprepare(ctx->dbc->dbhandle,
- prep->name, sql, argc, NULL);
- if( !dbr || (PQresultStatus(dbr) != PGRES_COMMAND_OK) ) {
- ePGerrorMessage(ctx, dbr, LOG_FATAL, 0, prepid,
- "Failed to prepare SQL query: %s", sql);
- return -2;
- }
- PQclear(dbr);
- _ePGprepStatements[id].numargs = argc;
- _ePGprepStatements[id].prepared = 1; /* Flag statement as prepared */
- return id;
- }
- return -1;
-};
-
-
-PGresult * ePGprepExec(eurephiaCTX *ctx, int prepid, const char **qry_args) {
- if( prepid < 0 ) {
- eurephia_log(ctx, LOG_ERROR, 0,
- "Invalid prepared statement ID %i", prepid);
- return NULL;
- }
- return PQexecPrepared(ctx->dbc->dbhandle,
- _ePGprepStatements[prepid].name,
- _ePGprepStatements[prepid].numargs,
- qry_args, NULL, NULL, 0);
-}
/**
@@ -347,24 +122,11 @@ int eDB_DriverAPIVersion() {
static inline void update_blacklist_attempt(eurephiaCTX *ctx, const char *blid) {
if( blid != NULL ) {
PGresult *dbr = NULL;
- int prepid = -1;
-
- const char ** qry_args = NULL;
+ ePGprepParams *qry_args = NULL;
- prepid = ePGprepStatement(ctx, PREPSQL_BLACKLIST_ATTEMPTUPD,
- "UPDATE blacklist"
- " SET last_accessed = CURRENT_TIMESTAMP"
- " WHERE blid = $1", 1);
- if( prepid < 0 ) {
- ePGerrorMessage(ctx, dbr, LOG_CRITICAL, 0, PREPSQL_BLACKLIST_ATTEMPTUPD,
- "Preparing last attempt query update failed");
- return;
- }
-
- qry_args = calloc(1, sizeof(char *));
- qry_args[0] = blid;
- dbr = ePGprepExec(ctx, prepid, qry_args);
- free_nullsafe(ctx, qry_args);
+ qry_args = ePGprepParamsAlloc(ctx, PREPSQL_BLACKLIST_ATTEMPTUPD);
+ ePGprepParamsAddArgument(ctx, qry_args, blid);
+ dbr = ePGprepExec(ctx, qry_args);
if( !dbr || (PQresultStatus(dbr) != PGRES_COMMAND_OK) ) {
ePGerrorMessage(ctx, dbr, LOG_CRITICAL, 0, PREPSQL_BLACKLIST_ATTEMPTUPD,
"Failed to update blaclist.last_access timestamp for blid %s",
@@ -463,7 +225,9 @@ int eDBconnect(eurephiaCTX *ctx, const int argc, const char **argv)
free_nullsafe(ctx, dbc);
return 0;
}
- return 1;
+
+ // Load all prepared SQL statements
+ return ePGprepLoadStatements(ctx);
}
@@ -518,11 +282,11 @@ void eDBdisconnect_firewall(eurephiaCTX *ctx) {
int eDBauth_TLS(eurephiaCTX *ctx, const char *org, const char *cname, const char *email,
const char *digest, const unsigned int depth)
{
- int certid = 0, prepid = -1;
+ int certid = 0;
PGresult *dbr = NULL;
char *blid = NULL;
char depth_str[5];
- const char **qry_args = NULL;
+ ePGprepParams *qry_args = NULL;
DEBUG(ctx, 20, "Function call: eDBauth_TLS(ctx, '%s', '%s', '%s', '%s', %i)",
org, cname, email, digest, depth);
@@ -532,32 +296,16 @@ int eDBauth_TLS(eurephiaCTX *ctx, const char *org, const char *cname, const char
return 0;
}
- prepid = ePGprepStatement(ctx, PREPSQL_TLS_AUTH,
- "SELECT cert.certid, blid "
- " FROM certificates cert"
- " LEFT JOIN blacklist bl USING(digest)"
- " WHERE organisation=$1::VARCHAR"
- " AND common_name=$2::VARCHAR"
- " AND email=$3::VARCHAR AND depth=$4::INTEGER"
- " AND lower(cert.digest)=lower($5::VARCHAR)\0",
- 5);
- if( prepid < 0 ) {
- ePGerrorMessage(ctx, dbr, LOG_FATAL, 0, PREPSQL_TLS_AUTH,
- "Failed to prepare SQL query");
- return 0;
- }
-
// Check if certificate is valid, and not too many attempts has been tried with
// the given certificate
snprintf(depth_str, 4, "%3i%c", depth, 0);
- qry_args = calloc(5, sizeof(char *));
- qry_args[0] = org;
- qry_args[1] = cname;
- qry_args[2] = email;
- qry_args[3] = depth_str;
- qry_args[4] = digest;
- dbr = ePGprepExec(ctx, prepid, qry_args);
- free_nullsafe(ctx, qry_args);
+ qry_args = ePGprepParamsAlloc(ctx, PREPSQL_TLS_AUTH);
+ ePGprepParamsAddArgument(ctx, qry_args, org);
+ ePGprepParamsAddArgument(ctx, qry_args, cname);
+ ePGprepParamsAddArgument(ctx, qry_args, email);
+ ePGprepParamsAddArgument(ctx, qry_args, depth_str);
+ ePGprepParamsAddArgument(ctx, qry_args, digest);
+ dbr = ePGprepExec(ctx, qry_args);
if( !dbr || (PQresultStatus(dbr) != PGRES_TUPLES_OK) ) {
ePGerrorMessage(ctx, dbr, LOG_FATAL, 0, PREPSQL_TLS_AUTH,
"Could not lookup certificate information "
@@ -591,13 +339,13 @@ int eDBauth_TLS(eurephiaCTX *ctx, const char *org, const char *cname, const char
*/
int eDBauth_user(eurephiaCTX *ctx, const int certid, const char *username, const char *passwd)
{
- int uicid = 0, pwdok = 0, prepid = -1;
+ int uicid = 0, pwdok = 0;
PGresult *dbr = NULL;
char certid_str[10];
char *crpwd = NULL, *activated = NULL, *deactivated = NULL;
char *blid_uname = NULL, *blid_cert = NULL;
char *dbpwd = NULL, *uid = NULL;
- const char **qry_args = NULL;
+ ePGprepParams *qry_args = NULL;
DEBUG(ctx, 20, "Function call: eDBauth_user(ctx, %i, '%s','xxxxxxxx')", certid, username);
@@ -606,34 +354,14 @@ int eDBauth_user(eurephiaCTX *ctx, const int certid, const char *username, const
return 0;
}
- prepid = ePGprepStatement(ctx, PREPSQL_USERPWD_AUTH,
- "SELECT uicid, ou.uid, activated, deactivated,"
- "bl1.blid, bl2.blid, password"
- " FROM users ou"
- " JOIN usercerts uc USING(uid)"
- " LEFT JOIN blacklist bl1 ON( ou.username = bl1.username)"
- " LEFT JOIN (SELECT blid, certid"
- " FROM certificates"
- " JOIN blacklist USING(digest)) bl2"
- " ON(uc.certid = bl2.certid)"
- " WHERE uc.certid = $1::INTEGER"
- " AND ou.username = $2::VARCHAR", 2);
- if( prepid < 0 ) {
- ePGerrorMessage(ctx, dbr, LOG_FATAL, 0, PREPSQL_USERPWD_AUTH,
- "Failed to prepare SQL query");
- uicid = 0;
- goto exit;
- }
-
// Look up the user in the database
snprintf(certid_str, 9, "%8i%c", certid, 0);
- qry_args = calloc(2, sizeof(char *));
- qry_args[0] = certid_str;
- qry_args[1] = username;
- dbr = ePGprepExec(ctx, prepid, qry_args);
- free_nullsafe(ctx, qry_args);
+ qry_args = ePGprepParamsAlloc(ctx, PREPSQL_USERPWD_AUTH);
+ ePGprepParamsAddArgument(ctx, qry_args, certid_str);
+ ePGprepParamsAddArgument(ctx, qry_args, username);
+ dbr = ePGprepExec(ctx, qry_args);
if( !dbr || (PQresultStatus(dbr) != PGRES_TUPLES_OK) ) {
- ePGerrorMessage(ctx, dbr, LOG_FATAL, 0, PREPSQL_NONE,
+ ePGerrorMessage(ctx, dbr, LOG_FATAL, 0, PREPSQL_USERPWD_AUTH,
"Failed to lookup user account information "
"[username=%s, certid=%s]",
username, certid_str);
@@ -694,34 +422,20 @@ int eDBauth_user(eurephiaCTX *ctx, const int certid, const char *username, const
uicid = -1;
} else {
PGresult *upd = NULL;
- int prepid = -1;
uicid = atoi_nullsafe(ePGgetValue(dbr, 0, 0));
// Update last accessed status
- prepid = ePGprepStatement(ctx, PREPSQL_USERS_LASTACC_UPD,
- "UPDATE users_last_access SET last_accessed = NULL"
- " WHERE uid = $1::INTEGER", 1);
- if( prepid < 0 ) {
- ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, PREPSQL_USERS_LASTACC_UPD,
- "Failed to prepare SQL query");
- } else {
+ qry_args = ePGprepParamsAlloc(ctx, PREPSQL_USERS_LASTACC_UPD);
+ ePGprepParamsAddArgument(ctx, qry_args, uid);
+ upd = ePGprepExec(ctx, qry_args);
+ if( !upd || (PQresultStatus(upd) != PGRES_COMMAND_OK) ) {
+ ePGerrorMessage(ctx, upd, LOG_FATAL, 0,
+ PREPSQL_USERS_LASTACC_UPD,
+ "Failed to update last access status "
+ "for uid %s", uid);
+ } else if( upd ) {
PQclear(upd);
-
- qry_args = calloc(1, sizeof(char *));
- qry_args[0] = uid;
- upd = ePGprepExec(ctx, prepid, qry_args);
- free_nullsafe(ctx, qry_args);
- if( !upd || (PQresultStatus(upd) != PGRES_COMMAND_OK) ) {
- ePGerrorMessage(ctx, upd, LOG_FATAL, 0,
- PREPSQL_USERS_LASTACC_UPD,
- "Failed to update last access status "
- "for uid %s", uid);
- } else {
- if( upd ) {
- PQclear(upd);
- }
- }
}
}
if( dbr ) {
@@ -741,9 +455,9 @@ int eDBauth_user(eurephiaCTX *ctx, const int certid, const char *username, const
*/
int eDBget_uid(eurephiaCTX *ctx, const int certid, const char *username)
{
- int ret = 0, prepid = -1;
+ int ret = 0;
PGresult *dbr = NULL;
- const char **qry_args = NULL;
+ ePGprepParams*qry_args = NULL;
char certid_str[10];
DEBUG(ctx, 20, "Function call: eDBget_uid(ctx, %i, '%s')", certid, username);
@@ -753,25 +467,11 @@ int eDBget_uid(eurephiaCTX *ctx, const int certid, const char *username)
return 0;
}
- prepid = ePGprepStatement(ctx, PREPSQL_USERS_GETUID,
- "SELECT uid "
- " FROM usercerts "
- " JOIN users USING (uid) "
- " WHERE certid = $1::INTEGER AND username = $2::VARCHAR",
- 2);
- if( prepid < 0 ) {
- ePGerrorMessage(ctx, dbr, LOG_FATAL, 0, PREPSQL_USERS_GETUID,
- "Failed to prepare SQL query");
- ret = -1;
- goto exit;
- }
-
snprintf(certid_str, 9, "%8i%c", certid, 0);
- qry_args = calloc(2, sizeof(char *));
- qry_args[0] = certid_str;
- qry_args[1] = username;
- dbr = ePGprepExec(ctx, prepid, qry_args);
- free_nullsafe(ctx, qry_args);
+ qry_args = ePGprepParamsAlloc(ctx, PREPSQL_USERS_GETUID);
+ ePGprepParamsAddArgument(ctx, qry_args, certid_str);
+ ePGprepParamsAddArgument(ctx, qry_args, username);
+ dbr = ePGprepExec(ctx, qry_args);
if( !dbr || (PQresultStatus(dbr) != PGRES_TUPLES_OK) ) {
ePGerrorMessage(ctx, dbr, LOG_FATAL, 0, PREPSQL_USERS_GETUID,
"Failed to lookup userid for user '%s'", username);
@@ -810,43 +510,25 @@ int eDBget_uid(eurephiaCTX *ctx, const int certid, const char *username)
*/
int eDBblacklist_check(eurephiaCTX *ctx, const int type, const char *val)
{
- int blacklisted = 0, prepid = -1;
- char sql[4098], *blid = NULL;
- const char **qry_args = NULL;
+ int blacklisted = 0;
+ char *blid = NULL;
+ ePGprepParams *qry_args = NULL;
PGresult *dbr = NULL;
const eDBattempt_types_t *atmptype = &eDBattempt_types[type];
DEBUG(ctx, 20, "Function call: eDBblacklist_check(ctx, '%s', '%s')",
atmptype->descr, val);
- qry_args = calloc(1, sizeof(char *));
- qry_args[0] = val;
-
- snprintf(sql, 4096,
- "SELECT atpid, attempts >= %s, blid, attempts "
- " FROM attempts "
- " LEFT JOIN blacklist USING(%s)"
- " WHERE %s = %s%s$1::VARCHAR%s",
- defaultValue(eGet_value(ctx->dbc->config, atmptype->allow_cfg),
- atmptype->default_value),
- atmptype->colname, atmptype->colname_where,
- defaultValue(atmptype->value_func, ""),
- (atmptype->value_func ? "(" : ""),
- (atmptype->value_func ? ")" : ""));
-
- prepid = ePGprepStatement(ctx, atmptype->sql_blacklist_check, sql, 1);
- if( prepid < 0 ) {
- ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, atmptype->sql_blacklist_check,
- "Failed to prepare SQL query");
- blacklisted = -1;
- goto error;
- }
-
- dbr = ePGprepExec(ctx, prepid, qry_args);
+ qry_args = ePGprepParamsAlloc(ctx, atmptype->sql_blacklist_check);
+ ePGprepParamsAddArgument(ctx, qry_args, val);
+ ePGprepParamsAddArgument(ctx, qry_args, defaultValue(eGet_value(ctx->dbc->config,
+ atmptype->allow_cfg),
+ atmptype->default_value));
+ dbr = ePGprepExec(ctx, qry_args);
if( !dbr || (PQresultStatus(dbr) != PGRES_TUPLES_OK) ) {
ePGerrorMessage(ctx, dbr, LOG_FATAL, 0, atmptype->sql_blacklist_check,
- "Failed to lookup %s in the attempts/blacklist table for '%s'",
- atmptype->descr, val);
+ "Failed to lookup %s in the blacklist table for '%s'",
+ atmptype->descr, val);
blacklisted = -1;
goto error;
}
@@ -877,25 +559,17 @@ int eDBblacklist_check(eurephiaCTX *ctx, const int type, const char *val)
"%s got BLACKLISTED due to too many (%i) failed attempts: %s",
atmptype->descr, atpcount, val);
- snprintf(sql, 4096, "INSERT INTO blacklist (%s) VALUES ($1)",
- atmptype->colname);
- prepid = ePGprepStatement(ctx, atmptype->sql_blacklist_reg, sql, 1);
- if( prepid < 0 ) {
- ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, atmptype->sql_blacklist_reg,
- "Failed to prepare SQL query");
- } else {
- blr = ePGprepExec(ctx, prepid, qry_args);
- if( !blr
- || (PQresultStatus(blr) != PGRES_COMMAND_OK) ) {
- ePGerrorMessage(ctx, blr, LOG_FATAL, 0,
- atmptype->sql_blacklist_reg,
- "Failed to register %s value "
- "'%s' in the blacklist:",
- atmptype->descr,
- val);
- }
- PQclear(blr);
+ qry_args = ePGprepParamsAlloc(ctx, atmptype->sql_blacklist_reg);
+ ePGprepParamsAddArgument(ctx, qry_args, val);
+
+ blr = ePGprepExec(ctx, qry_args);
+ if( !blr || (PQresultStatus(blr) != PGRES_COMMAND_OK) ) {
+ ePGerrorMessage(ctx, blr, LOG_FATAL, 0,
+ atmptype->sql_blacklist_reg,
+ "Failed to register %s value '%s' in the blacklist:",
+ atmptype->descr, val);
}
+ PQclear(blr);
blacklisted = 1; // [type] is blacklisted
}
atpid = NULL;
@@ -904,11 +578,12 @@ int eDBblacklist_check(eurephiaCTX *ctx, const int type, const char *val)
exit:
DEBUG(ctx, 20, "Result - function call: eDBblacklist_check(ctx, '%s', '%s') - %i",
atmptype->descr, val, blacklisted);
+ return blacklisted;
error:
+ DEBUG(ctx, 20, "Result - function call: eDBblacklist_check(ctx, '%s', '%s') - ERROR: %i",
+ atmptype->descr, val, blacklisted);
blid = NULL;
- free_nullsafe(ctx, qry_args);
-
return blacklisted;
}
@@ -919,38 +594,23 @@ int eDBblacklist_check(eurephiaCTX *ctx, const int type, const char *val)
void eDBregister_attempt(eurephiaCTX *ctx, int type, int mode, const char *value)
{
const eDBattempt_types_t *atmptype = &eDBattempt_types[type];
- const char **qry_args = NULL;
- char sql[4098];
+ ePGprepParams *qry_args = NULL;
char *id = NULL, *atmpt_block = NULL, *blid = NULL;
- int prepid = -1, attempts = 0;
+ int attempts = 0;
PGresult *dbr = NULL;
DEBUG(ctx, 20, "Function call: eDBregister_attempt(ctx, %s, %s, '%s')",
- atmptype->colname,
+ atmptype->descr,
(mode == ATTEMPT_RESET ? "ATTEMPT_RESET" : "ATTEMPT_REGISTER"),
value);
- qry_args = calloc(1, sizeof(char *));
- qry_args[0] = value;
-
- snprintf(sql, 4096,
- "SELECT atpid, attempts > %s, blid, attempts "
- " FROM attempts "
- " LEFT JOIN blacklist USING(%s)"
- " WHERE %s = %s%s$1::VARCHAR%s",
- defaultValue(eGet_value(ctx->dbc->config, atmptype->allow_cfg),
- atmptype->default_value),
- atmptype->colname, atmptype->colname_where,
- defaultValue(atmptype->value_func, ""),
- (atmptype->value_func ? "(" : ""),
- (atmptype->value_func ? ")" : ""));
- prepid = ePGprepStatement(ctx, atmptype->sql_blacklist_check, sql, 1);
- if( prepid < 0 ) {
- ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, atmptype->sql_blacklist_check,
- "Failed to prepare SQL query");
- }
- dbr = ePGprepExec(ctx, prepid, qry_args);
+ qry_args = ePGprepParamsAlloc(ctx, atmptype->sql_blacklist_check);
+ ePGprepParamsAddArgument(ctx, qry_args, value);
+ ePGprepParamsAddArgument(ctx, qry_args, defaultValue(eGet_value(ctx->dbc->config,
+ atmptype->allow_cfg),
+ atmptype->default_value));
+ dbr = ePGprepExec(ctx, qry_args);
if( !dbr || (PQresultStatus(dbr) != PGRES_TUPLES_OK) ) {
ePGerrorMessage(ctx, dbr, LOG_FATAL, 0, atmptype->sql_blacklist_check,
"Failed to lookup %s in the attempts/blacklist table for '%s'",
@@ -958,6 +618,7 @@ void eDBregister_attempt(eurephiaCTX *ctx, int type, int mode, const char *value
return;
}
+ // FIXME: Will we always have a record from this query?
attempts = atoi_nullsafe(ePGgetValue(dbr, 0, 3));
// If we are asked to reset the attempt counter and we do not find any attempts, exit here
if( (mode == ATTEMPT_RESET) && ((PQntuples(dbr) == 0) || (attempts == 0))) {
@@ -972,16 +633,10 @@ void eDBregister_attempt(eurephiaCTX *ctx, int type, int mode, const char *value
if( (id == NULL) && (mode == ATTEMPT_REGISTER) ) {
// Only insert record when we are in registering mode
- snprintf(sql, 4096, "INSERT INTO attempts (%s, attempts) VALUES ($1::VARCHAR, 1)",
- atmptype->colname);
- prepid = ePGprepStatement(ctx, atmptype->sql_attempts_reg, sql, 1);
- if( prepid < 0 ) {
- ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, atmptype->sql_attempts_reg,
- "Failed to prepare SQL query");
- goto error;
- }
+ qry_args = ePGprepParamsAlloc(ctx, atmptype->sql_attempts_reg);
+ ePGprepParamsAddArgument(ctx, qry_args, value);
- dbr = ePGprepExec(ctx, prepid, qry_args);
+ dbr = ePGprepExec(ctx, qry_args);
if( !dbr || (PQresultStatus(dbr) != PGRES_COMMAND_OK) ) {
ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, atmptype->sql_attempts_reg,
"Failed to register failed attempt for %s '%s'",
@@ -991,20 +646,12 @@ void eDBregister_attempt(eurephiaCTX *ctx, int type, int mode, const char *value
PQclear(dbr);
} else if( id != NULL ){
// if a attempt record exists, update it according to mode
- qry_args[0] = id;
switch( mode ) {
case ATTEMPT_RESET:
- prepid = ePGprepStatement(ctx, PREPSQL_ATTEMPTS_RESET,
- "UPDATE attempts"
- " SET attempts = 0 "
- " WHERE atpid = $1::INTEGER", 1);
- if( prepid < 0 ) {
- ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, PREPSQL_ATTEMPTS_RESET,
- "Failed to prepare SQL query");
- goto error;
- }
+ qry_args = ePGprepParamsAlloc(ctx, PREPSQL_ATTEMPTS_RESET);
+ ePGprepParamsAddArgument(ctx, qry_args, id);
- dbr = ePGprepExec(ctx, prepid, qry_args);
+ dbr = ePGprepExec(ctx, qry_args);
if( !dbr || (PQresultStatus(dbr) != PGRES_COMMAND_OK) ) {
ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, PREPSQL_ATTEMPTS_RESET,
"Failed to reset attempts counter for atpid '%s' (%s %s)",
@@ -1014,21 +661,14 @@ void eDBregister_attempt(eurephiaCTX *ctx, int type, int mode, const char *value
PQclear(dbr);
break;
default:
- prepid = ePGprepStatement(ctx, PREPSQL_ATTEMPTS_INCR,
- "UPDATE attempts"
- " SET last_attempt = CURRENT_TIMESTAMP, "
- " attempts = attempts + 1"
- " WHERE atpid = $1::INTEGER", 1);
- if( prepid < 0 ) {
- ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, PREPSQL_ATTEMPTS_INCR,
- "Failed to prepare SQL query");
- goto error;
- }
- dbr = ePGprepExec(ctx, prepid, qry_args);
+ qry_args = ePGprepParamsAlloc(ctx, PREPSQL_ATTEMPTS_INCR);
+ ePGprepParamsAddArgument(ctx, qry_args, id);
+
+ dbr = ePGprepExec(ctx, qry_args);
if( !dbr || (PQresultStatus(dbr) != PGRES_COMMAND_OK) ) {
ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, PREPSQL_ATTEMPTS_INCR,
- "Failed to increment attempts counter for atpid '%s' (%s %s)",
- id, atmptype->descr, value);
+ "Failed to increment attempts counter for "
+ "atpid '%s' (%s %s)", id, atmptype->descr, value);
goto error;
}
PQclear(dbr);
@@ -1042,35 +682,25 @@ void eDBregister_attempt(eurephiaCTX *ctx, int type, int mode, const char *value
eurephia_log(ctx, LOG_WARNING, 0, "Blacklisting %s due to too many attempts: %s",
eDBattempt_types[type].descr, value);
- snprintf(sql, 4096, "INSERT INTO blacklist (%s) VALUES ($1)",
- atmptype->colname);
- prepid = ePGprepStatement(ctx, atmptype->sql_blacklist_reg, sql, 1);
- if( prepid < 0 ) {
- ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, atmptype->sql_blacklist_reg,
- "Failed to prepare SQL query");
- } else {
- qry_args[0] = value;
-
- dbr = ePGprepExec(ctx, prepid, qry_args);
- if( !dbr
- || (PQresultStatus(dbr) != PGRES_COMMAND_OK) ) {
- ePGerrorMessage(ctx, dbr, LOG_FATAL, 0,
- atmptype->sql_blacklist_reg,
- "Failed to blacklist %s value "
- "'%s':",
- atmptype->descr,
- value);
- goto error;
- }
- PQclear(dbr);
+ qry_args = ePGprepParamsAlloc(ctx, atmptype->sql_blacklist_reg);
+ ePGprepParamsAddArgument(ctx, qry_args, value);
+
+ dbr = ePGprepExec(ctx, qry_args);
+ if( !dbr || (PQresultStatus(dbr) != PGRES_COMMAND_OK) ) {
+ ePGerrorMessage(ctx, dbr, LOG_FATAL, 0,
+ atmptype->sql_blacklist_reg,
+ "Failed to blacklist %s value "
+ "'%s':",
+ atmptype->descr,
+ value);
+ goto error;
}
+ PQclear(dbr);
}
-
error:
free_nullsafe(ctx, id);
free_nullsafe(ctx, atmpt_block);
free_nullsafe(ctx, blid);
-
}
/**
@@ -1080,41 +710,24 @@ int eDBregister_login(eurephiaCTX *ctx, eurephiaSESSION *skey, const int certid,
const char *proto, const char *remipaddr, const char *remport,
const char *vpnipaddr, const char *vpnipmask)
{
- char uidstr[10], certidstr[10];
- const char **qry_args = NULL;
- int prepid = -1, ret = 0;
+ ePGprepParams*qry_args = NULL;
+ int ret = 0;
PGresult *dbr = NULL;
DEBUG(ctx, 20, "Function call: eDBregister_login(ctx, '%s', %i, %i, '%s','%s','%s','%s','%s')",
skey->sessionkey, certid, uid, proto, remipaddr, remport, vpnipaddr, vpnipmask);
- prepid = ePGprepStatement(ctx, PREPSQL_REGISTER_LOGIN,
- "INSERT INTO lastlog (uid, certid, "
- " protocol, remotehost, remoteport,"
- " vpnipaddr, vpnipmask,"
- " sessionstatus, sessionkey, login) "
- "VALUES ($1::INTEGER, $2::INTEGER, "
- " $3::VARCHAR, $4::VARCHAR, $5::INTEGER,"
- " $6::VARCHAR, $7::VARCHAR,"
- " 1, $8::VARCHAR, CURRENT_TIMESTAMP)", 8);
- if( prepid < 0 ) {
- ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, PREPSQL_REGISTER_LOGIN,
- "Failed to prepare query");
- return 0;
- }
-
- qry_args = calloc(8, sizeof(char *));
- snprintf(uidstr, 8, "%i", uid); qry_args[0] = uidstr;
- snprintf(certidstr, 8, "%i", certid); qry_args[1] = certidstr;
- qry_args[2] = proto;
- qry_args[3] = remipaddr;
- qry_args[4] = remport;
- qry_args[5] = vpnipaddr;
- qry_args[6] = vpnipmask;
- qry_args[7] = skey->sessionkey;
-
- dbr = ePGprepExec(ctx, prepid, qry_args);
- free_nullsafe(ctx, qry_args);
+ qry_args = ePGprepParamsAlloc(ctx, PREPSQL_REGISTER_LOGIN);
+ ePGprepParamsAddArgumentInt(ctx, qry_args, uid);
+ ePGprepParamsAddArgumentInt(ctx, qry_args, certid);
+ ePGprepParamsAddArgument(ctx, qry_args, proto);
+ ePGprepParamsAddArgument(ctx, qry_args, remipaddr);
+ ePGprepParamsAddArgument(ctx, qry_args, remport);
+ ePGprepParamsAddArgument(ctx, qry_args, vpnipaddr);
+ ePGprepParamsAddArgument(ctx, qry_args, vpnipmask);
+ ePGprepParamsAddArgument(ctx, qry_args, skey->sessionkey);
+
+ dbr = ePGprepExec(ctx, qry_args);
if( !dbr || (PQresultStatus(dbr) != PGRES_COMMAND_OK) ) {
ePGerrorMessage(ctx, dbr, LOG_CRITICAL, 0, PREPSQL_REGISTER_LOGIN,
"Failed to register session login for session key '%s'",
@@ -1133,8 +746,8 @@ int eDBregister_login(eurephiaCTX *ctx, eurephiaSESSION *skey, const int certid,
*/
int eDBregister_vpnmacaddr(eurephiaCTX *ctx, eurephiaSESSION *session, const char *macaddr)
{
- const char **qry_args = NULL;
- int prepid_reg = -1, prepid_ll = -1, ret = 0;
+ ePGprepParams *qry_args = NULL;
+ int ret = 0;
PGresult *dbr = NULL;
DEBUG(ctx, 20, "Function call: eDBregister_vpnmacaddr(ctx, '%s', '%s')",
@@ -1142,31 +755,12 @@ int eDBregister_vpnmacaddr(eurephiaCTX *ctx, eurephiaSESSION *session, const cha
/* TODO: Use transaction */
- prepid_reg = ePGprepStatement(ctx, PREPSQL_MACHISTORY_REGISTER,
- "INSERT INTO macaddr_history (sessionkey, macaddr)"
- " VALUES ($1::VARCHAR, $2::VARCHAR)", 2);
- if( prepid_reg < 0 ) {
- ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, PREPSQL_MACHISTORY_REGISTER,
- "Failed to prepare SQL query");
- return 0;
- }
-
- prepid_ll = ePGprepStatement(ctx, PREPSQL_MACHISTORY_LASTLOG,
- "UPDATE lastlog_update "
- " SET sessionstatus = 2,macaddr = $2::VARCHAR"
- " WHERE sessionkey = $1::VARCHAR AND sessionstatus = 1", 2);
- if( prepid_ll < 0 ) {
- ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, PREPSQL_MACHISTORY_LASTLOG,
- "Failed to prepare SQL query");
- return 0;
- }
-
- qry_args = calloc(2, sizeof(const char *));
- qry_args[0] = session->sessionkey;
- qry_args[1] = macaddr;
+ qry_args = ePGprepParamsAlloc(ctx, PREPSQL_MACHISTORY_REGISTER);
+ ePGprepParamsAddArgument(ctx, qry_args, session->sessionkey);
+ ePGprepParamsAddArgument(ctx, qry_args, macaddr);
// Register the MAC address into the macaddr_history table
- dbr = ePGprepExec(ctx, prepid_reg, qry_args);
+ dbr = ePGprepExec(ctx, qry_args);
if( !dbr || (PQresultStatus(dbr) != PGRES_COMMAND_OK) ) {
ePGerrorMessage(ctx, dbr, LOG_CRITICAL, 0,
PREPSQL_MACHISTORY_REGISTER,
@@ -1179,7 +773,10 @@ int eDBregister_vpnmacaddr(eurephiaCTX *ctx, eurephiaSESSION *session, const cha
PQclear(dbr);
// Update lastlog table with the latest used MAC address
- dbr = ePGprepExec(ctx, prepid_ll, qry_args);
+ qry_args = ePGprepParamsAlloc(ctx, PREPSQL_MACHISTORY_LASTLOG);
+ ePGprepParamsAddArgument(ctx, qry_args, session->sessionkey);
+ ePGprepParamsAddArgument(ctx, qry_args, macaddr);
+ dbr = ePGprepExec(ctx, qry_args);
if( !dbr || (PQresultStatus(dbr) != PGRES_COMMAND_OK) ) {
ePGerrorMessage(ctx, dbr, LOG_CRITICAL, 0,
PREPSQL_MACHISTORY_LASTLOG,
@@ -1198,7 +795,6 @@ int eDBregister_vpnmacaddr(eurephiaCTX *ctx, eurephiaSESSION *session, const cha
}
exit:
- free_nullsafe(ctx, qry_args);
return 1;
}
@@ -1209,40 +805,26 @@ int eDBregister_vpnmacaddr(eurephiaCTX *ctx, eurephiaSESSION *session, const cha
int eDBregister_logout(eurephiaCTX *ctx, eurephiaSESSION *skey,
const char *bytes_sent, const char *bytes_received, const char *duration)
{
- const char **qry_args = NULL;
- int prepid = -1;
+ ePGprepParams *qry_args = NULL;
PGresult *dbr = NULL;
DEBUG(ctx, 20, "Function call: eDBregister_logout(ctx, '%s', %s, %s)",
skey->sessionkey, bytes_sent, bytes_received);
- prepid = ePGprepStatement(ctx, PREPSQL_REGISTER_LOGOUT,
- "UPDATE lastlog_update "
- " SET sessionstatus = 3, logout = CURRENT_TIMESTAMP, "
- " bytes_sent=$2::INTEGER, bytes_received=$3::INTEGER,"
- " session_duration = $4::INTERVAL "
- " WHERE sessionkey = $1::VARCHAR AND sessionstatus = 2", 4);
- if( prepid < 0 ) {
- ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, PREPSQL_REGISTER_LOGOUT,
- "Failed to prepare SQL query");
- }
-
- qry_args = calloc(4, sizeof(char *));
- qry_args[0] = skey->sessionkey;
- qry_args[1] = bytes_sent;
- qry_args[2] = bytes_received;
- qry_args[3] = duration;
+ qry_args = ePGprepParamsAlloc(ctx, PREPSQL_REGISTER_LOGOUT);
+ ePGprepParamsAddArgument(ctx, qry_args, skey->sessionkey);
+ ePGprepParamsAddArgument(ctx, qry_args, bytes_sent);
+ ePGprepParamsAddArgument(ctx, qry_args, bytes_received);
+ ePGprepParamsAddArgument(ctx, qry_args, duration);
- dbr = ePGprepExec(ctx, prepid, qry_args);
+ dbr = ePGprepExec(ctx, qry_args);
if( !dbr || (PQresultStatus(dbr) != PGRES_COMMAND_OK) ) {
ePGerrorMessage(ctx, dbr, LOG_CRITICAL, 0, PREPSQL_REGISTER_LOGOUT,
"Failed to lastlog with logout info (%s)",
skey->sessionkey);
- free_nullsafe(ctx, qry_args);
return 0;
}
PQclear(dbr);
- free_nullsafe(ctx, qry_args);
skey->sessionstatus = SESSION_LOGGEDOUT;
return 1;
}
@@ -1253,10 +835,9 @@ int eDBregister_logout(eurephiaCTX *ctx, eurephiaSESSION *skey,
*/
char *eDBget_sessionkey_seed(eurephiaCTX *ctx, sessionType type, const char *sessionseed)
{
- const char **qry_args = NULL;
+ ePGprepParams *qry_args = NULL;
char *skey = NULL;
- _ePG_prepID preptype = PREPSQL_NONE;
- int prepid = -1;
+ ePG_prepID preptype = PREPSQL_NONE;
PGresult *dbr = NULL;
DEBUG(ctx, 20, "eDBget_sessionkey_seed(ctx, %i, '%s')", type, sessionseed);
@@ -1267,57 +848,34 @@ char *eDBget_sessionkey_seed(eurephiaCTX *ctx, sessionType type, const char *ses
return NULL;
}
- qry_args = calloc(1, sizeof(char *));
- qry_args[0] = sessionseed;
-
switch( type ) {
case stSESSION:
preptype = PREPSQL_SESSIONKEY_GETSEED_SESSION;
- prepid = ePGprepStatement(ctx, preptype,
- "SELECT sessionkey "
- " FROM sessionkeys "
- " JOIN lastlog USING (sessionkey)"
- " WHERE sessionstatus IN (1,2)"
- " AND sessionseed = $1::VARCHAR", 1);
break;
case stAUTHENTICATION:
preptype = PREPSQL_SESSIONKEY_GETSEED_AUTH;
- prepid = ePGprepStatement(ctx, preptype,
- "SELECT sessionkey "
- " FROM sessionkeys "
- " LEFT JOIN lastlog USING (sessionkey)"
- " WHERE sessionstatus IS NULL"
- " AND sessionseed = $1::VARCHAR", 1);
break;
default:
eurephia_log(ctx, LOG_ERROR, 0, "Invalid session type: %i", type);
- goto exit;
+ return NULL;
}
- if( prepid < 0 ) {
- ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, preptype,
- "Failed to prepare SQL query");
- skey = NULL;
- goto exit;
- }
+ qry_args = ePGprepParamsAlloc(ctx, preptype);
+ ePGprepParamsAddArgument(ctx, qry_args, sessionseed);
- dbr = ePGprepExec(ctx, prepid, qry_args);
+ dbr = ePGprepExec(ctx, qry_args);
if( !dbr || (PQresultStatus(dbr) != PGRES_TUPLES_OK) ) {
ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, preptype,
"Failed to lookup session key from session seed '%s'",
sessionseed);
- skey = NULL;
- goto exit;
+ return NULL;
}
skey = (PQntuples(dbr) == 1 ? strdup_nullsafe(PQgetvalue(dbr, 0, 0)) : NULL);
PQclear(dbr);
- exit:
- free_nullsafe(ctx, qry_args);
return skey;
-
}
@@ -1327,43 +885,26 @@ char *eDBget_sessionkey_seed(eurephiaCTX *ctx, sessionType type, const char *ses
char *eDBget_sessionkey_macaddr(eurephiaCTX *ctx, const char *macaddr)
{
char *skey = NULL;
- const char **qry_args = NULL;
- int prepid = -1;
+ ePGprepParams *qry_args = NULL;
PGresult *dbr = NULL;
DEBUG(ctx, 20, "eDBget_sessionkey_macaddr(ctx, '%s')", macaddr);
// Find sessionkey from MAC address
- prepid = ePGprepStatement(ctx, PREPSQL_SESSIONKEY_GETMAC,
- "SELECT sessionkey "
- " FROM sessions "
- " JOIN lastlog USING (sessionkey)"
- " WHERE sessionstatus = 3 "
- " AND datakey = 'macaddr'"
- " AND dataval = $1::VARCHAR", 1);
- if( prepid < 0 ) {
- ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, PREPSQL_SESSIONKEY_GETMAC,
- "Failed to prepare SQL query");
- return NULL;
- }
+ qry_args = ePGprepParamsAlloc(ctx, PREPSQL_SESSIONKEY_GETMAC);
+ ePGprepParamsAddArgument(ctx, qry_args, macaddr);
- qry_args = calloc(1, sizeof(char *));
- qry_args[0] = macaddr;
-
- dbr = ePGprepExec(ctx, prepid, qry_args);
+ dbr = ePGprepExec(ctx, qry_args);
if( !dbr || (PQresultStatus(dbr) != PGRES_TUPLES_OK) ) {
ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, PREPSQL_SESSIONKEY_GETMAC,
"Failed to lookup session key from MAC address '%s'",
macaddr);
- skey = NULL;
- goto exit;
+ return NULL;
}
skey = (PQntuples(dbr) == 1 ? strdup_nullsafe(PQgetvalue(dbr, 0, 0)) : NULL);
PQclear(dbr);
- exit:
- free_nullsafe(ctx, qry_args);
return skey;
}
@@ -1374,9 +915,8 @@ char *eDBget_sessionkey_macaddr(eurephiaCTX *ctx, const char *macaddr)
int eDBcheck_sessionkey_uniqueness(eurephiaCTX *ctx, const char *seskey)
{
int uniq = 0;
- const char **qry_args = NULL;
- int prepid = -1;
- _ePG_prepID preptype;
+ ePGprepParams *qry_args = NULL;
+ ePG_prepID preptype;
PGresult *dbr = NULL;
DEBUG(ctx, 20, "eDBcheck_sessionkey_uniqueness(ctx, '%s')", seskey);
@@ -1395,44 +935,29 @@ int eDBcheck_sessionkey_uniqueness(eurephiaCTX *ctx, const char *seskey)
case ECTX_ADMIN_CONSOLE:
case ECTX_ADMIN_WEB:
preptype = PREPSQL_SESSIONKEY_UNIQ_ADMIN;
- prepid = ePGprepStatement(ctx, preptype,
- "SELECT count(sessionkey) = 0 "
- "FROM eurephia_adminlog WHERE sessionkey = $1::VARCHAR", 1);
break;
case ECTX_PLUGIN_AUTH:
default:
preptype = PREPSQL_SESSIONKEY_UNIQ_PLAUTH;
- prepid = ePGprepStatement(ctx, preptype,
- "SELECT count(sessionkey) = 0 "
- "FROM lastlog WHERE sessionkey = $1::VARCHAR", 1);
break;
}
- if( prepid < 0 ) {
- ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, preptype,
- "Failed to prepare SQL query");
- return 0;
- }
-
- qry_args = calloc(1, sizeof(char *));
- qry_args[0] = seskey;
+ qry_args = ePGprepParamsAlloc(ctx, preptype);
+ ePGprepParamsAddArgument(ctx, qry_args, seskey);
- dbr = ePGprepExec(ctx, prepid, qry_args);
+ dbr = ePGprepExec(ctx, qry_args);
if( !dbr || (PQresultStatus(dbr) != PGRES_TUPLES_OK) ) {
ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, preptype,
"Failed to check session key uniqueness for '%s'",
seskey);
- uniq = 0;
- goto exit;
+ return 0;
} else if( PQntuples(dbr) == 1 ) {
char *res = PQgetvalue(dbr, 0, 0);
uniq = (*res == 't');
}
PQclear(dbr);
- exit:
- free_nullsafe(ctx, qry_args);
return uniq;
}
@@ -1441,8 +966,7 @@ int eDBcheck_sessionkey_uniqueness(eurephiaCTX *ctx, const char *seskey)
* @copydoc eDBregister_sessionkey()
*/
int eDBregister_sessionkey(eurephiaCTX *ctx, const char *seed, const char *seskey) {
- const char **qry_args = NULL;
- int prepid = -1, ret = 0;
+ ePGprepParams *qry_args = NULL;
PGresult *dbr = NULL;
DEBUG(ctx, 20, "eDBregister_sessionkey(ctx, '%s', '%s')", seed, seskey);
@@ -1452,32 +976,19 @@ int eDBregister_sessionkey(eurephiaCTX *ctx, const char *seed, const char *seske
return 0;
}
- prepid = ePGprepStatement(ctx, PREPSQL_SESSIONKEY_REGISTER,
- "INSERT INTO sessionkeys (sessionseed, sessionkey) "
- " VALUES($1::VARCHAR, $2::VARCHAR)", 2);
- if( prepid < 0 ) {
- ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, PREPSQL_SESSIONKEY_REGISTER,
- "Failed to prepare SQL query");
- return 0;
- }
-
- qry_args = calloc(2, sizeof(char *));
- qry_args[0] = seed;
- qry_args[1] = seskey;
+ qry_args = ePGprepParamsAlloc(ctx, PREPSQL_SESSIONKEY_REGISTER);
+ ePGprepParamsAddArgument(ctx, qry_args, seed);
+ ePGprepParamsAddArgument(ctx, qry_args, seskey);
- dbr = ePGprepExec(ctx, prepid, qry_args);
+ dbr = ePGprepExec(ctx, qry_args);
if( !dbr || (PQresultStatus(dbr) != PGRES_COMMAND_OK) ) {
ePGerrorMessage(ctx, dbr, LOG_FATAL, 0, PREPSQL_SESSIONKEY_REGISTER,
"eDBregister_sessionkey: Error registering sessionkey"
" into 'sessionkeys'");
- ret = 0;
- goto exit;
+ return 0;
}
PQclear(dbr);
- ret = 1;
- exit:
- free_nullsafe(ctx, qry_args);
- return ret;
+ return 1;
}
/**
@@ -1490,8 +1001,7 @@ int eDBregister_sessionkey(eurephiaCTX *ctx, const char *seed, const char *seske
*
*/
int eDBremove_sessionkey(eurephiaCTX *ctx, const char *seskey) {
- const char **qry_args = NULL;
- int prepid = -1, ret = 0;
+ ePGprepParams *qry_args = NULL;
PGresult *dbr = NULL;
DEBUG(ctx, 20, "eDBremove_sessionkey(ctx, '%s')", seskey);
@@ -1501,30 +1011,18 @@ int eDBremove_sessionkey(eurephiaCTX *ctx, const char *seskey) {
return 0;
}
- prepid = ePGprepStatement(ctx, PREPSQL_SESSIONKEY_REMOVE,
- "DELETE FROM sessionkeys WHERE sessionkey = $1::VARCHAR", 1);
- if( prepid < 0 ) {
- ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, PREPSQL_SESSIONKEY_REMOVE,
- "Failed to prepare SQL query");
- return 0;
- }
-
- qry_args = calloc(1, sizeof(char *));
- qry_args[0] = seskey;
+ qry_args = ePGprepParamsAlloc(ctx, PREPSQL_SESSIONKEY_REMOVE);
+ ePGprepParamsAddArgument(ctx, qry_args, seskey);
- dbr = ePGprepExec(ctx, prepid, qry_args);
+ dbr = ePGprepExec(ctx, qry_args);
if( !dbr || (PQresultStatus(dbr) != PGRES_COMMAND_OK) ) {
ePGerrorMessage(ctx, dbr, LOG_FATAL, 0, PREPSQL_SESSIONKEY_REMOVE,
"eDBremove_sessionkey: Error removing sessionkey '%s'",
seskey);
- ret = 0;
- goto exit;
+ return 0;
}
PQclear(dbr);
- ret = 1;
- exit:
- free_nullsafe(ctx, qry_args);
- return ret;
+ return 1;
}
@@ -1534,32 +1032,21 @@ int eDBremove_sessionkey(eurephiaCTX *ctx, const char *seskey) {
eurephiaVALUES *eDBload_sessiondata(eurephiaCTX *ctx, const char *seskey)
{
eurephiaVALUES *sessvals = NULL;
- const char **qry_args = NULL;
- int prepid = -1, i = 0;
+ ePGprepParams *qry_args = NULL;
+ int i = 0;
PGresult *dbr = NULL;
DEBUG(ctx, 20, "Function call: eDBload_sessiondata(ctx, '%s')", seskey);
- prepid = ePGprepStatement(ctx, PREPSQL_SESSIONVARS_LOAD,
- "SELECT datakey, dataval"
- " FROM sessions"
- " WHERE sessionkey = $1::VARCHAR", 1);
- if( prepid < 0 ) {
- ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, PREPSQL_SESSIONVARS_LOAD,
- "Failed to prepare SQL query");
- return NULL;
- }
-
- qry_args = calloc(1, sizeof(char *));
- qry_args[0] = seskey;
+ qry_args = ePGprepParamsAlloc(ctx, PREPSQL_SESSIONVARS_LOAD);
+ ePGprepParamsAddArgument(ctx, qry_args, seskey);
- dbr = ePGprepExec(ctx, prepid, qry_args);
+ dbr = ePGprepExec(ctx, qry_args);
if( !dbr || (PQresultStatus(dbr) != PGRES_TUPLES_OK) ) {
ePGerrorMessage(ctx, dbr, LOG_FATAL, 0, PREPSQL_SESSIONVARS_LOAD,
"eDBload_sessiondata: Failed to load session variables for session '%s'",
seskey);
- sessvals = NULL;
- goto exit;
+ return NULL;
}
sessvals = eCreate_value_space(ctx, 10);
@@ -1567,7 +1054,7 @@ eurephiaVALUES *eDBload_sessiondata(eurephiaCTX *ctx, const char *seskey)
eurephia_log(ctx, LOG_CRITICAL, 0,
"Failed to create value storage for session variables for session '%s'",
seskey);
- goto exit;
+ return NULL;
}
for( i = 0; i < PQntuples(dbr); i++ ) {
@@ -1577,8 +1064,6 @@ eurephiaVALUES *eDBload_sessiondata(eurephiaCTX *ctx, const char *seskey)
}
PQclear(dbr);
- exit:
- free_nullsafe(ctx, qry_args);
return sessvals;
}
@@ -1589,9 +1074,8 @@ eurephiaVALUES *eDBload_sessiondata(eurephiaCTX *ctx, const char *seskey)
int eDBstore_session_value(eurephiaCTX *ctx, eurephiaSESSION *session, int mode,
const char *key, const char *val)
{
- const char **qry_args = NULL;
- int prepid = -1, ret = 0;
- _ePG_prepID preptype = PREPSQL_NONE;
+ ePGprepParams *qry_args = NULL;
+ ePG_prepID preptype = PREPSQL_NONE;
PGresult *dbr = NULL;
if( session == NULL ) {
@@ -1603,30 +1087,17 @@ int eDBstore_session_value(eurephiaCTX *ctx, eurephiaSESSION *session, int mode,
DEBUG(ctx, 20, "Function call: eDBstore_session_value(ctx, '%s', %i, '%s', '%s')",
session->sessionkey, mode, key, val);
- /* TODO: Need testing */
-
switch( mode ) {
case SESSVAL_NEW:
preptype = PREPSQL_SESSIONVARS_STORE_NEW;
- prepid = ePGprepStatement(ctx, preptype,
- "INSERT INTO sessions (sessionkey, datakey, dataval) "
- "VALUES ($1::VARCHAR,$2::VARCHAR,$3::VARCHAR)", 3);
break;
case SESSVAL_UPDATE:
preptype = PREPSQL_SESSIONVARS_STORE_UPDATE;
- prepid = ePGprepStatement(ctx, preptype,
- "UPDATE sessions SET dataval = $3::VARCHAR "
- " WHERE sessionkey = $1::VARCHAR"
- " AND datakey = $2::VARCHAR", 2);
break;
case SESSVAL_DELETE:
preptype = PREPSQL_SESSIONVARS_STORE_DELETE;
- prepid = ePGprepStatement(ctx, preptype,
- "DELETE FROM sessions "
- " WHERE sessionkey = $1::VARCHAR"
- " AND datakey = $2::VARCHAR", 2);
break;
default:
@@ -1634,31 +1105,20 @@ int eDBstore_session_value(eurephiaCTX *ctx, eurephiaSESSION *session, int mode,
return 0;
}
- if( prepid < 0 ) {
- ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, preptype,
- "Failed to prepare SQL query");
- return 0;
- }
-
- qry_args = calloc(3, sizeof(char *));
- qry_args[0] = session->sessionkey;
- qry_args[1] = key;
- qry_args[2] = val;
+ qry_args = ePGprepParamsAlloc(ctx, preptype);
+ ePGprepParamsAddArgument(ctx, qry_args, session->sessionkey);
+ ePGprepParamsAddArgument(ctx, qry_args, key);
+ ePGprepParamsAddArgument(ctx, qry_args, val);
- dbr = ePGprepExec(ctx, prepid, qry_args);
+ dbr = ePGprepExec(ctx, qry_args);
if( !dbr || (PQresultStatus(dbr) != PGRES_COMMAND_OK) ) {
ePGerrorMessage(ctx, dbr, LOG_FATAL, 0, preptype,
"eDBstore_session_value: Failed to update session value [%s] %s",
session->sessionkey, key);
- ret = 0;
- goto exit;
+ return 0;
}
PQclear(dbr);
- ret = 1;
-
- exit:
- free_nullsafe(ctx, qry_args);
- return ret;
+ return 1;
}
@@ -1667,8 +1127,8 @@ int eDBstore_session_value(eurephiaCTX *ctx, eurephiaSESSION *session, int mode,
*/
int eDBdestroy_session(eurephiaCTX *ctx, eurephiaSESSION *session)
{
- const char **qry_args = NULL;
- int prepid = -1, ret = 0;
+ ePGprepParams *qry_args = NULL;
+ int ret = 0;
PGresult *dbr = NULL;
DEBUG(ctx, 20, "Function call: eDBdestroy_session(ctx, '%s')", session->sessionkey);
@@ -1678,57 +1138,35 @@ int eDBdestroy_session(eurephiaCTX *ctx, eurephiaSESSION *session)
return 1;
}
- qry_args = calloc(1, sizeof(char *));
- qry_args[0] = session->sessionkey;
+ qry_args = ePGprepParamsAlloc(ctx, PREPSQL_SESSIONS_DESTROY_LASTLOG);
+ ePGprepParamsAddArgument(ctx, qry_args, session->sessionkey);
// Update session status - if we have a "real" session (not auth-session)
if( session->type == stSESSION ) {
- prepid = ePGprepStatement(ctx, PREPSQL_SESSIONS_DESTROY_LASTLOG,
- "UPDATE lastlog_update "
- " SET sessionstatus = 4,"
- " session_deleted = CURRENT_TIMESTAMP "
- " WHERE sessionkey = $1::VARCHAR"
- " AND sessionstatus = 3", 1);
- if( prepid < 0 ) {
- ePGerrorMessage(ctx, dbr, LOG_FATAL, 0, PREPSQL_SESSIONS_DESTROY_LASTLOG,
- "Failed to prepare SQL query");
- ret = 0;
- goto exit;
- }
-
- dbr = ePGprepExec(ctx, prepid, qry_args);
+ dbr = ePGprepExec(ctx, qry_args);
if( !dbr || (PQresultStatus(dbr) != PGRES_COMMAND_OK) ) {
ePGerrorMessage(ctx, dbr, LOG_CRITICAL, 0,
PREPSQL_SESSIONS_DESTROY_LASTLOG,
"eDBdestroy_session: Failed to update "
"update lastlog with session deleted status (%s)",
session->sessionkey);
- ret = 0;
- goto exit;
+ return 0;
}
PQclear(dbr);
}
// Delete session variables
- prepid = ePGprepStatement(ctx, PREPSQL_SESSIONS_DESTROY_SESS,
- "DELETE FROM sessions WHERE sessionkey = $1::VARCHAR", 1);
- if( prepid < 0 ) {
- ePGerrorMessage(ctx, NULL, LOG_FATAL, 0,
- PREPSQL_SESSIONS_DESTROY_SESS,
- "Failed to prepare SQL query");
- ret = 0;
- goto exit;
- }
+ qry_args = ePGprepParamsAlloc(ctx, PREPSQL_SESSIONS_DESTROY_SESS);
+ ePGprepParamsAddArgument(ctx, qry_args, session->sessionkey);
- dbr = ePGprepExec(ctx, prepid, qry_args);
+ dbr = ePGprepExec(ctx, qry_args);
if( !dbr || (PQresultStatus(dbr) != PGRES_COMMAND_OK) ) {
ePGerrorMessage(ctx, dbr, LOG_CRITICAL, 0,
PREPSQL_SESSIONS_DESTROY_SESS,
"eDBdestroy_session: Failed to delete "
"session variables (%s)",
session->sessionkey);
- ret = 0;
- goto exit;
+ return 0;
}
PQclear(dbr);
@@ -1742,8 +1180,6 @@ int eDBdestroy_session(eurephiaCTX *ctx, eurephiaSESSION *session)
ret = 1;
}
- exit:
- free_nullsafe(ctx, qry_args);
return ret;
}
@@ -1753,33 +1189,17 @@ int eDBdestroy_session(eurephiaCTX *ctx, eurephiaSESSION *session)
*/
char *eDBget_firewall_profile(eurephiaCTX *ctx, eurephiaSESSION *session)
{
- const char **qry_args = NULL;
- int prepid = -1;
+ ePGprepParams *qry_args = NULL;
char *ret = NULL;
PGresult *dbr = NULL;
DEBUG(ctx, 20, "Function call: eDBget_firewall_profile(ctx, {session}'%s')",
session->sessionkey);
- /* TODO: Need testing */
-
- prepid = ePGprepStatement(ctx, PREPSQL_FIREWALL_GETPROFILE,
- "SELECT fw_profile "
- " FROM lastlog "
- " JOIN usercerts USING(certid, uid)"
- " JOIN accesses USING(accessprofile)"
- " WHERE sessionkey = $1::VARCHAR", 1);
- if( prepid < 0 ) {
- ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, PREPSQL_FIREWALL_GETPROFILE,
- "Failed to prepare SQL query");
- return NULL;
- }
-
- qry_args = calloc(1, sizeof(char *));
- qry_args[0] = session->sessionkey;
+ qry_args = ePGprepParamsAlloc(ctx, PREPSQL_FIREWALL_GETPROFILE);
+ ePGprepParamsAddArgument(ctx, qry_args, session->sessionkey);
- dbr = ePGprepExec(ctx, prepid, qry_args);
- free_nullsafe(ctx,qry_args);
+ dbr = ePGprepExec(ctx, qry_args);
if( !dbr || (PQresultStatus(dbr) != PGRES_TUPLES_OK) || (PQntuples(dbr) > 1) ) {
ePGerrorMessage(ctx, dbr, LOG_WARNING, 0, PREPSQL_FIREWALL_GETPROFILE,
"Failed to retrieve the firewall profile for session '%s'",
diff --git a/database/postgresql/pgsql-common.c b/database/postgresql/pgsql-common.c
new file mode 100644
index 0000000..35ae03a
--- /dev/null
+++ b/database/postgresql/pgsql-common.c
@@ -0,0 +1,93 @@
+/* pgsql-error.c -- PostgreSQL database driver for eurephia
+ *
+ * GPLv2 only - Copyright (C) 2012
+ * David Sommerseth <dazo@users.sourceforge.net>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/**
+ * @file pgsql-error.c
+ * @author David Sommerseth <dazo@users.sourceforge.net>
+ * @date 2012-01-15
+ *
+ * @brief eurephia database driver for the PostgreSQL database.
+ * Shared functions for the PostgreSQL driver
+ *
+ */
+
+#include <string.h>
+#include <stdarg.h>
+#include <libpq-fe.h>
+
+#include <eurephia_context.h>
+#include <eurephia_log.h>
+#include "prepared-sql.h"
+
+
+char *ePGgetValue(PGresult *res, int row, int col)
+{
+ if( (res == NULL) || (PQgetisnull(res, row, col) == 1) ) {
+ return NULL;
+ } else {
+ // FIXME: should we check if we have the row number accesible first? row > PQntuples()
+ return PQgetvalue(res, row, col);
+ }
+}
+
+
+void __ePGerrorMessage(eurephiaCTX *ctx, PGresult *dbr, int logdst, int loglvl,
+ ePG_prepID prepid, const char *errfile, const long errline,
+ const char *fmt, ...)
+{
+ char msgfmt[514];
+ va_list ap;
+
+ memset(&msgfmt, 0, 514);
+ va_start(ap, fmt);
+ if( prepid != PREPSQL_NONE ) {
+ snprintf(msgfmt, 512, "[%s] SQL query failed: %s %s: %s",
+ ePGprepStatementGetName(ctx, prepid),
+ (dbr != NULL ? PQresStatus(PQresultStatus(dbr)) : ""), fmt,
+ (dbr != NULL ? PQresultErrorMessage(dbr)
+ : (ctx->dbc != NULL ? PQerrorMessage(ctx->dbc->dbhandle)
+ : "[unknown error]")
+ ));
+ } else {
+ snprintf(msgfmt, 512, "SQL query failed: %s %s: %s",
+ (dbr != NULL ? PQresStatus(PQresultStatus(dbr)) : ""),
+ fmt,
+ (dbr != NULL ? PQresultErrorMessage(dbr)
+ : (ctx->dbc != NULL ? PQerrorMessage(ctx->dbc->dbhandle)
+ : "[unknown error]")
+ ));
+ }
+#ifdef ENABLE_DEBUG
+ _veurephia_log_func(ctx, logdst, loglvl, errfile, errline, ap, msgfmt);
+#else
+ veurephia_log(ctx, logdst, loglvl, ap, msgfmt);
+#endif
+ va_end(ap);
+ memset(&msgfmt, 0, 514);
+ if( dbr ) {
+ PQclear(dbr);
+ }
+ if( (loglvl == LOG_EMERG) && (ctx->dbc != NULL)
+ && (PQstatus(ctx->dbc->dbhandle) != CONNECTION_OK) ) {
+ PQfinish(ctx->dbc->dbhandle);
+ }
+}
+
diff --git a/database/postgresql/pgsql-common.h b/database/postgresql/pgsql-common.h
new file mode 100644
index 0000000..a1bbed0
--- /dev/null
+++ b/database/postgresql/pgsql-common.h
@@ -0,0 +1,47 @@
+/* pgsql-error.h -- PostgreSQL database driver for eurephia
+ *
+ * GPLv2 only - Copyright (C) 2012
+ * David Sommerseth <dazo@users.sourceforge.net>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/**
+ * @file pgsql-error.h
+ * @author David Sommerseth <dazo@users.sourceforge.net>
+ * @date 2012-01-15
+ *
+ * @brief eurephia database driver for the PostgreSQL database.
+ * Shared functions for the PostgreSQL driver
+ *
+ */
+
+#ifndef _PGSQL_ERROR_H
+#define _PGSQL_ERROR_H
+
+#include <stdarg.h>
+#include <eurephia_context.h>
+#include "prepared-sql.h"
+
+char *ePGgetValue(PGresult *res, int row, int col);
+
+#define ePGerrorMessage(ctx, dbr, logdst, loglvl, prepid, fmt...) __ePGerrorMessage(ctx, dbr, logdst,loglvl, prepid, __FILE__, __LINE__, ## fmt)
+void __ePGerrorMessage(eurephiaCTX *ctx, PGresult *dbr, int logdst, int loglvl,
+ ePG_prepID prepid, const char *errfile, const long errline,
+ const char *fmt, ...);
+
+
+#endif
diff --git a/database/postgresql/prepared-sql.c b/database/postgresql/prepared-sql.c
new file mode 100644
index 0000000..d969744
--- /dev/null
+++ b/database/postgresql/prepared-sql.c
@@ -0,0 +1,526 @@
+/* prepared-sql.c -- PostgreSQL database driver for eurephia
+ *
+ * GPLv2 only - Copyright (C) 2012
+ * David Sommerseth <dazo@users.sourceforge.net>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/**
+ * @file prepared-sql.c
+ * @author David Sommerseth <dazo@users.sourceforge.net>
+ * @date 2012-01-15
+ *
+ * @brief eurephia database driver for the PostgreSQL database.
+ * The infrastructure needed for prepared SQL statements
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <libpq-fe.h>
+
+#include <eurephia_context.h>
+#include <eurephia_log.h>
+#include <eurephia_nullsafe.h>
+
+#include "prepared-sql.h"
+#include "pgsql-common.h"
+
+typedef struct {
+ const ePG_prepID prepid;
+ const char *name;
+ const unsigned int numargs;
+ const char *sql;
+} _ePGprepStatements_t;
+
+
+/* All prepared statements are declared here, including the SQL part */
+static const _ePGprepStatements_t _ePGprepStatements[] = {
+ {.prepid = PREPSQL_TLS_AUTH,
+ .name = "eurephia_tls_auth", .numargs = 5,
+ .sql =
+ "SELECT cert.certid, blid "
+ " FROM certificates cert"
+ " LEFT JOIN blacklist bl USING(digest)"
+ " WHERE organisation=$1::VARCHAR"
+ " AND common_name=$2::VARCHAR"
+ " AND email=$3::VARCHAR AND depth=$4::INTEGER"
+ " AND lower(cert.digest)=lower($5::VARCHAR)"
+ },
+
+ {.prepid = PREPSQL_USERPWD_AUTH,
+ .name = "eurephia_userpwd_auth", .numargs = 2,
+ .sql =
+ "SELECT uicid, ou.uid, activated, deactivated,"
+ "bl1.blid, bl2.blid, password"
+ " FROM users ou"
+ " JOIN usercerts uc USING(uid)"
+ " LEFT JOIN blacklist bl1 ON( ou.username = bl1.username)"
+ " LEFT JOIN (SELECT blid, certid"
+ " FROM certificates"
+ " JOIN blacklist USING(digest)) bl2"
+ " ON(uc.certid = bl2.certid)"
+ " WHERE uc.certid = $1::INTEGER"
+ " AND ou.username = $2::VARCHAR"
+ },
+
+ {.prepid = PREPSQL_BLACKLIST_ATTEMPTUPD,
+ .name ="eurephia_blacklist_attupd" , .numargs = 2,
+ .sql =
+ "SELECT uicid, ou.uid, activated, deactivated,"
+ "bl1.blid, bl2.blid, password"
+ " FROM users ou"
+ " JOIN usercerts uc USING(uid)"
+ " LEFT JOIN blacklist bl1 ON( ou.username = bl1.username)"
+ " LEFT JOIN (SELECT blid, certid"
+ " FROM certificates"
+ " JOIN blacklist USING(digest)) bl2"
+ " ON(uc.certid = bl2.certid)"
+ " WHERE uc.certid = $1::INTEGER"
+ " AND ou.username = $2::VARCHAR"
+ },
+
+ {.prepid = PREPSQL_USERS_LASTACC_UPD,
+ .name = "eurephia_users_lastacc_upd", .numargs = 1,
+ .sql =
+ "UPDATE users_last_access SET last_accessed = NULL"
+ " WHERE uid = $1::INTEGER"
+ },
+
+ {.prepid = PREPSQL_USERS_GETUID,
+ .name = "eurephia_getuid", .numargs = 2,
+ .sql =
+ "SELECT uid "
+ " FROM usercerts "
+ " JOIN users USING (uid) "
+ " WHERE certid = $1::INTEGER AND username = $2::VARCHAR",
+ },
+
+ {.prepid = PREPSQL_ATTEMPTS_RESET,
+ .name = "eurephia_attempts_reset", .numargs = 1,
+ .sql =
+ "UPDATE attempts"
+ " SET attempts = 0 "
+ " WHERE atpid = $1::INTEGER"
+ },
+
+ {.prepid = PREPSQL_ATTEMPTS_INCR,
+ .name = "eurephia_attempts_increment", .numargs = 1,
+ .sql =
+ "UPDATE attempts"
+ " SET last_attempt = CURRENT_TIMESTAMP, "
+ " attempts = attempts + 1"
+ " WHERE atpid = $1::INTEGER"
+ },
+
+ {.prepid = PREPSQL_ATTEMPTS_REG_CERT,
+ .name = "eurephia_attempts_reg_cert", .numargs = 1,
+ .sql = "INSERT INTO attempts (digest, attempts) VALUES ($1::VARCHAR, 1)"
+ },
+
+ {.prepid = PREPSQL_ATTEMPTS_REG_USERNAME,
+ .name = "eurephia_attempts_reg_username", .numargs = 0,
+ .sql = "INSERT INTO attempts (username, attempts) VALUES ($1::VARCHAR, 1)"
+ },
+
+ {.prepid = PREPSQL_ATTEMPTS_REG_IPADDR,
+ .name = "eurephia_attempts_reg_ipaddr", .numargs = 0,
+ .sql = "INSERT INTO attempts (remoteip, attempts) VALUES ($1::VARCHAR, 1)"
+ },
+
+ {.prepid = PREPSQL_BLACKLIST_CHECK_CERT,
+ .name = "eurephia_blacklist_check_cert", .numargs = 2,
+ .sql =
+ "SELECT atpid, attempts >= $2::INTEGER, blid, attempts "
+ " FROM attempts "
+ " LEFT JOIN blacklist USING(digest)"
+ " WHERE lower(digest) = lower($1::VARCHAR)"
+ },
+
+ {.prepid = PREPSQL_BLACKLIST_CHECK_USERNAME,
+ .name = "eurephia_blacklist_check_username", .numargs = 2,
+ .sql =
+ "SELECT atpid, attempts >= $2::INTEGER, blid, attempts "
+ " FROM attempts "
+ " LEFT JOIN blacklist USING(username)"
+ " WHERE username = $1::VARCHAR"
+ },
+
+ {.prepid = PREPSQL_BLACKLIST_CHECK_IPADDR,
+ .name = "eurephia_blacklist_check_cert_ipaddr", .numargs = 2,
+ .sql =
+ "SELECT atpid, attempts >= $2::INTEGER, blid, attempts "
+ " FROM attempts "
+ " LEFT JOIN blacklist USING(remoteip)"
+ " WHERE remoteip = $1::VARCHAR"
+ },
+
+ {.prepid = PREPSQL_BLACKLIST_REG_CERT,
+ .name = "eurephia_blacklist_reg_cert", .numargs = 0,
+ .sql = "INSERT INTO blacklist (digest) VALUES ($1::VARCHAR)"
+ },
+
+ {.prepid = PREPSQL_BLACKLIST_REG_USERNAME,
+ .name = "eurephia_blacklist_reg_username", .numargs = 0,
+ .sql = "INSERT INTO blacklist (username) VALUES ($1::VARCHAR)"
+ },
+
+ {.prepid = PREPSQL_BLACKLIST_REG_IPADDR,
+ .name = "eurephia_blacklist_reg_ipaddr", .numargs = 0,
+ .sql = "INSERT INTO blacklist (remoteip) VALUES ($1::VARCHAR)"
+ },
+
+ {.prepid = PREPSQL_SESSIONKEY_GETSEED_SESSION,
+ .name = "eurephia_sessionkey_getseed_session", .numargs = 1,
+ .sql =
+ "SELECT sessionkey "
+ " FROM sessionkeys "
+ " JOIN lastlog USING (sessionkey)"
+ " WHERE sessionstatus IN (1,2)"
+ " AND sessionseed = $1::VARCHAR"
+ },
+
+ {.prepid = PREPSQL_SESSIONKEY_GETSEED_AUTH,
+ .name = "eurephia_sessionkey_getseed_auth", .numargs = 1,
+ .sql =
+ "SELECT sessionkey "
+ " FROM sessionkeys "
+ " LEFT JOIN lastlog USING (sessionkey)"
+ " WHERE sessionstatus IS NULL"
+ " AND sessionseed = $1::VARCHAR"
+ },
+
+ {.prepid = PREPSQL_SESSIONKEY_GETMAC,
+ .name = "eurephia_sessionkey_getmac", .numargs = 1,
+ .sql =
+ "SELECT sessionkey "
+ " FROM sessions "
+ " JOIN lastlog USING (sessionkey)"
+ " WHERE sessionstatus = 3 "
+ " AND datakey = 'macaddr'"
+ " AND dataval = $1::VARCHAR"
+ },
+
+ {.prepid = PREPSQL_SESSIONKEY_UNIQ_ADMIN,
+ .name = "eurephia_sessionkey_uniq_admin", .numargs = 1,
+ .sql =
+ "SELECT count(sessionkey) = 0 "
+ "FROM eurephia_adminlog WHERE sessionkey = $1::VARCHAR"
+ },
+
+ {.prepid = PREPSQL_SESSIONKEY_UNIQ_PLAUTH,
+ .name = "eurephia_sessionkey_uniq_plauth", .numargs = 1,
+ .sql =
+ "SELECT count(sessionkey) = 0 "
+ "FROM lastlog WHERE sessionkey = $1::VARCHAR"
+ },
+
+ {.prepid = PREPSQL_SESSIONKEY_REGISTER,
+ .name = "eurephia_sessionkey_register", .numargs = 2,
+ .sql =
+ "INSERT INTO sessionkeys (sessionseed, sessionkey) "
+ " VALUES($1::VARCHAR, $2::VARCHAR)"
+ },
+
+ {.prepid = PREPSQL_SESSIONKEY_REMOVE,
+ .name = "eurephia_sessionkey_remove", .numargs = 1,
+ .sql = "DELETE FROM sessionkeys WHERE sessionkey = $1::VARCHAR"
+ },
+
+ {.prepid = PREPSQL_SESSIONVARS_LOAD,
+ .name = "eurephia_sessionvars_load", .numargs = 1,
+ .sql =
+ "SELECT datakey, dataval"
+ " FROM sessions"
+ " WHERE sessionkey = $1::VARCHAR"
+ },
+
+ {.prepid = PREPSQL_SESSIONVARS_STORE_NEW,
+ .name = "eurephia_sessionvars_store_new", .numargs = 3,
+ .sql =
+ "INSERT INTO sessions (sessionkey, datakey, dataval) "
+ "VALUES ($1::VARCHAR,$2::VARCHAR,$3::VARCHAR)"
+ },
+
+ {.prepid = PREPSQL_SESSIONVARS_STORE_UPDATE,
+ .name = "eurephia_sessionvars_store_upd", .numargs = 3,
+ .sql =
+ "UPDATE sessions SET dataval = $3::VARCHAR "
+ " WHERE sessionkey = $1::VARCHAR"
+ " AND datakey = $2::VARCHAR"
+ },
+
+ {.prepid = PREPSQL_SESSIONVARS_STORE_DELETE,
+ .name = "eurephia_sessionvars_store_del", .numargs = 2,
+ .sql =
+ "DELETE FROM sessions "
+ " WHERE sessionkey = $1::VARCHAR"
+ " AND datakey = $2::VARCHAR"
+ },
+
+ {.prepid = PREPSQL_SESSIONS_DESTROY_LASTLOG,
+ .name = "eurephia_sessions_destr_lastlogupd", .numargs = 1,
+ .sql =
+ "UPDATE lastlog_update "
+ " SET sessionstatus = 4,"
+ " session_deleted = CURRENT_TIMESTAMP "
+ " WHERE sessionkey = $1::VARCHAR"
+ " AND sessionstatus = 3"
+ },
+
+ {.prepid = PREPSQL_SESSIONS_DESTROY_SESS,
+ .name = "eurephia_sessions_destr_sessions", .numargs = 1,
+ .sql = "DELETE FROM sessions WHERE sessionkey = $1::VARCHAR"
+ },
+
+ {.prepid = PREPSQL_REGISTER_LOGIN,
+ .name = "eurephia_register_login", .numargs = 8,
+ .sql = "INSERT INTO lastlog (uid, certid, "
+ " protocol, remotehost, remoteport,"
+ " vpnipaddr, vpnipmask,"
+ " sessionstatus, sessionkey, login) "
+ "VALUES ($1::INTEGER, $2::INTEGER, "
+ " $3::VARCHAR, $4::VARCHAR, $5::INTEGER,"
+ " $6::VARCHAR, $7::VARCHAR,"
+ " 1, $8::VARCHAR, CURRENT_TIMESTAMP)"
+ },
+
+ {.prepid = PREPSQL_REGISTER_LOGOUT,
+ .name = "eurephia_register_logout", .numargs = 4,
+ .sql =
+ "UPDATE lastlog_update "
+ " SET sessionstatus = 3, logout = CURRENT_TIMESTAMP, "
+ " bytes_sent=$2::INTEGER, bytes_received=$3::INTEGER,"
+ " session_duration = $4::INTERVAL "
+ " WHERE sessionkey = $1::VARCHAR AND sessionstatus = 2"
+ },
+
+ {.prepid = PREPSQL_MACHISTORY_REGISTER,
+ .name = "eurephia_machistory_reg", .numargs = 2,
+ .sql =
+ "INSERT INTO macaddr_history (sessionkey, macaddr)"
+ " VALUES ($1::VARCHAR, $2::VARCHAR)"
+ },
+
+ {.prepid = PREPSQL_MACHISTORY_LASTLOG,
+ .name = "eurephia_machistory_lastlog_upd", .numargs = 2,
+ .sql =
+ "UPDATE lastlog_update "
+ " SET sessionstatus = 2,macaddr = $2::VARCHAR"
+ " WHERE sessionkey = $1::VARCHAR AND sessionstatus = 1"
+ },
+
+ {.prepid = PREPSQL_FIREWALL_GETPROFILE,
+ .name = "eurephia_firewall_getprofile", .numargs = 0,
+ .sql =
+ "SELECT fw_profile "
+ " FROM lastlog "
+ " JOIN usercerts USING(certid, uid)"
+ " JOIN accesses USING(accessprofile)"
+ " WHERE sessionkey = $1::VARCHAR"
+ },
+
+ {.prepid = PREPSQL_NONE,
+ .name = NULL, .numargs = 0, .sql = ""}
+};
+
+
+static int _ePGprepStatement(eurephiaCTX *ctx, const _ePGprepStatements_t *prepst)
+{
+ PGresult *dbr = NULL;
+
+ /* statement found in lookup table, but not prepared in database */
+ dbr = PQprepare(ctx->dbc->dbhandle,
+ prepst->name, prepst->sql, prepst->numargs, NULL);
+ if( !dbr || (PQresultStatus(dbr) != PGRES_COMMAND_OK) ) {
+ ePGerrorMessage(ctx, dbr, LOG_FATAL, 0, prepst->prepid,
+ "Failed to prepare SQL query: %s", prepst->sql);
+ return 0;
+ }
+ PQclear(dbr);
+ return 1;
+};
+
+
+int ePGprepStatementGetID(ePG_prepID prepid)
+{
+ int i;
+ for( i = 0; _ePGprepStatements[i].prepid != PREPSQL_NONE; i++ ) {
+ if( _ePGprepStatements[i].prepid == prepid ) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+
+const char const * ePGprepStatementGetName(eurephiaCTX *ctx, ePG_prepID prepid)
+{
+ if( prepid != PREPSQL_NONE ) {
+ int id = ePGprepStatementGetID(prepid);
+ if( id < 0 ) {
+ eurephia_log(ctx, LOG_ERROR, 0,
+ "Failed to map prepared statement ID %i to "
+ "a valid statement", prepid);
+ return NULL;
+ }
+ return _ePGprepStatements[id].name;
+ }
+ return NULL;
+}
+
+/**
+ * Loads and registers all the prepared statements
+ *
+ * @param ctx eurephiaCTX
+ *
+ * @return Returns 1 on success, otherwise 0.
+ */
+int ePGprepLoadStatements(eurephiaCTX *ctx)
+{
+ const _ePGprepStatements_t * prep = NULL;
+ int i = 0;
+
+ prep = &_ePGprepStatements[i];
+ do {
+ eurephia_log(ctx, LOG_INFO, 3, "Preparing SQL query '%s'", prep->name);
+ DEBUG(ctx, 22, "SQL Query: %s", prep->sql);
+ if( !_ePGprepStatement(ctx, prep) ) {
+ return 0;
+ }
+ i++;
+ prep = &_ePGprepStatements[i];
+ } while (prep->prepid != PREPSQL_NONE);
+ return 1;
+}
+
+
+ePGprepParams * ePGprepParamsAlloc(eurephiaCTX *ctx, ePG_prepID prepid)
+{
+ int pid = -1;
+ ePGprepParams *ret = NULL;
+
+ pid = ePGprepStatementGetID(prepid);
+ if( pid < 0 ) {
+ eurephia_log(ctx, LOG_FATAL, 0,
+ "Invalid prepared statement ID %i", prepid);
+ return NULL;
+ }
+
+ ret = malloc_nullsafe(ctx, sizeof(ePGprepParams));
+ if( !ret ) {
+ return NULL;
+ }
+
+ ret->prepid = prepid;
+ ret->index = 0;
+ if( _ePGprepStatements[pid].numargs > 0 ) {
+ ret->params = calloc(_ePGprepStatements[pid].numargs, sizeof(char *));
+ if( !ret->params ) {
+ eurephia_log(ctx, LOG_FATAL, 0,
+ "Failed to allocate memory for SQL parameters (%s, %i args)",
+ _ePGprepStatements[pid].name, _ePGprepStatements[pid].numargs);
+ free_nullsafe(ctx, ret);
+ }
+ }
+ return ret;
+}
+
+
+int ePGprepParamsAddArgument(eurephiaCTX *ctx, ePGprepParams *prms, const char *arg)
+{
+ int pid = -1;
+
+ if( !prms ) {
+ eurephia_log(ctx, LOG_CRITICAL, 0,
+ "Not a valid parameter buffer");
+ return 0;
+ }
+
+ // TODO: Should a separate error indicator be set in ePGprepParams, to block further invocations?
+
+ pid = ePGprepStatementGetID(prms->prepid);
+ if( pid < 0 ) {
+ eurephia_log(ctx, LOG_FATAL, 0,
+ "Invalid prepared statement ID %i", prms->prepid);
+ return 0;
+ }
+
+ if( prms->index+1 > _ePGprepStatements[pid].numargs ) {
+ eurephia_log(ctx, LOG_FATAL, 0,
+ "Too many arguments provided to %s",
+ _ePGprepStatements[pid].name);
+ return 0;
+ }
+ prms->params[prms->index] = strdup_nullsafe(arg);
+ prms->index++;
+
+ return 1;
+}
+
+
+int ePGprepParamsAddArgumentInt(eurephiaCTX *ctx, ePGprepParams *prms, const int arg) {
+ char argstr[66];
+
+ memset(&argstr, 0, 66);
+ snprintf(argstr, 64, "%i", arg);
+ return ePGprepParamsAddArgument(ctx, prms, argstr);
+}
+
+
+PGresult * ePGprepExec(eurephiaCTX *ctx, ePGprepParams *qry_args)
+{
+ int i = 0, pid = -1;
+ PGresult *res = NULL;
+
+ if( !qry_args ) {
+ eurephia_log(ctx, LOG_FATAL, 0,
+ "Missing query arguments (cannot be NULL)");
+ }
+
+ pid = ePGprepStatementGetID(qry_args->prepid);
+ if( pid < 0 ) {
+ eurephia_log(ctx, LOG_FATAL, 0,
+ "Invalid prepared statement ID %i", qry_args->prepid);
+ return NULL;
+ }
+
+ if( qry_args->index != _ePGprepStatements[pid].numargs ) {
+ eurephia_log(ctx, LOG_FATAL, 0,
+ "Invalid number of arguments registered to %s query",
+ _ePGprepStatements[pid].name);
+ return NULL;
+ }
+
+ // TODO: Should a separate error indicator in ePGprepParams block further invocations?
+
+ res = PQexecPrepared(ctx->dbc->dbhandle,
+ _ePGprepStatements[pid].name,
+ _ePGprepStatements[pid].numargs,
+ ((qry_args && (qry_args->index > 0)) ? (const char **) qry_args->params : NULL),
+ NULL, NULL, 0);
+
+ // Free the memory used by the query arguments (ePGprepParams)
+ for( i = 0; i < qry_args->index; i++ ) {
+ free_nullsafe(ctx, qry_args->params[i]);
+ }
+ free_nullsafe(ctx, qry_args->params);
+ qry_args->index = -1;
+ free_nullsafe(ctx, qry_args);
+
+ return res;
+}
+
diff --git a/database/postgresql/prepared-sql.h b/database/postgresql/prepared-sql.h
new file mode 100644
index 0000000..0d09f20
--- /dev/null
+++ b/database/postgresql/prepared-sql.h
@@ -0,0 +1,72 @@
+/* prepared-sql.h -- PostgreSQL database driver for eurephia
+ *
+ * GPLv2 only - Copyright (C) 2012
+ * David Sommerseth <dazo@users.sourceforge.net>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/**
+ * @file prepared-sql.h
+ * @author David Sommerseth <dazo@users.sourceforge.net>
+ * @date 2012-01-15
+ *
+ * @brief eurephia database driver for the PostgreSQL database.
+ * The infrastructure needed for prepared SQL statements
+ */
+
+#ifndef _PREPARED_SQL_H
+#define _PREPARED_SQL_H
+
+#include <stdarg.h>
+#include <eurephia_context.h>
+
+typedef enum { PREPSQL_NONE = 0, PREPSQL_TLS_AUTH, PREPSQL_USERPWD_AUTH,
+ PREPSQL_BLACKLIST_ATTEMPTUPD, PREPSQL_USERS_LASTACC_UPD,
+ PREPSQL_USERS_GETUID, PREPSQL_ATTEMPTS_RESET, PREPSQL_ATTEMPTS_INCR,
+ PREPSQL_ATTEMPTS_REG_CERT, PREPSQL_ATTEMPTS_REG_USERNAME,
+ PREPSQL_ATTEMPTS_REG_IPADDR,
+ PREPSQL_BLACKLIST_CHECK_CERT, PREPSQL_BLACKLIST_CHECK_USERNAME,
+ PREPSQL_BLACKLIST_CHECK_IPADDR,
+ PREPSQL_BLACKLIST_REG_CERT, PREPSQL_BLACKLIST_REG_USERNAME,
+ PREPSQL_BLACKLIST_REG_IPADDR,
+ PREPSQL_SESSIONKEY_GETSEED_SESSION, PREPSQL_SESSIONKEY_GETSEED_AUTH,
+ PREPSQL_SESSIONKEY_GETMAC,
+ PREPSQL_SESSIONKEY_UNIQ_ADMIN, PREPSQL_SESSIONKEY_UNIQ_PLAUTH,
+ PREPSQL_SESSIONKEY_REGISTER, PREPSQL_SESSIONKEY_REMOVE,
+ PREPSQL_SESSIONVARS_LOAD, PREPSQL_SESSIONVARS_STORE_NEW,
+ PREPSQL_SESSIONVARS_STORE_UPDATE, PREPSQL_SESSIONVARS_STORE_DELETE,
+ PREPSQL_SESSIONS_DESTROY_LASTLOG, PREPSQL_SESSIONS_DESTROY_SESS,
+ PREPSQL_REGISTER_LOGIN, PREPSQL_REGISTER_LOGOUT,
+ PREPSQL_MACHISTORY_REGISTER, PREPSQL_MACHISTORY_LASTLOG,
+ PREPSQL_FIREWALL_GETPROFILE
+} ePG_prepID;
+
+typedef struct _ePGprepParam_s {
+ ePG_prepID prepid;
+ int index;
+ char **params;
+} ePGprepParams;
+
+int ePGprepStatementGetID(ePG_prepID prepid);
+const char const * ePGprepStatementGetName(eurephiaCTX *ctx, ePG_prepID prepid);
+int ePGprepLoadStatements(eurephiaCTX *ctx);
+ePGprepParams * ePGprepParamsAlloc(eurephiaCTX *ctx, ePG_prepID prepid);
+int ePGprepParamsAddArgument(eurephiaCTX *ctx, ePGprepParams *prms, const char *arg);
+int ePGprepParamsAddArgumentInt(eurephiaCTX *ctx, ePGprepParams *prms, const int arg);
+PGresult * ePGprepExec(eurephiaCTX *ctx, ePGprepParams *qry_args);
+
+#endif