diff options
author | David Sommerseth <dazo@users.sourceforge.net> | 2012-01-15 23:53:12 +0100 |
---|---|---|
committer | David Sommerseth <dazo@users.sourceforge.net> | 2013-06-13 01:01:55 +0200 |
commit | 6ce2be3d09484d393c894a291dc9429525d3d914 (patch) | |
tree | df9680acfeac526974173445341d25afdc144476 | |
parent | 6c1f8ff4f7966f0d1f9cb1b2ff447f0dfc5f8aeb (diff) | |
download | eurephia-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.txt | 6 | ||||
-rw-r--r-- | database/postgresql/edb-pgsql.c | 980 | ||||
-rw-r--r-- | database/postgresql/pgsql-common.c | 93 | ||||
-rw-r--r-- | database/postgresql/pgsql-common.h | 47 | ||||
-rw-r--r-- | database/postgresql/prepared-sql.c | 526 | ||||
-rw-r--r-- | database/postgresql/prepared-sql.h | 72 |
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 |