/* Routine to escape the 'dangerous' characters that would otherwise * corrupt the INSERT string: ', \, and " */ static const char *log_sql_dbi_escape(request_rec *r,const char *from_str, apr_pool_t *p, logsql_dbconnection *db) { dbi_conn_rec *dblink = db->handle; if (!from_str) return NULL; else { char *to_str = strdup(from_str); char *retval; dbi_driver_quote_string(dbi_conn_get_driver(dblink->conn), &to_str); retval = apr_pstrdup(p, to_str); free(to_str); return retval; } }
dbi_result _db_rawquery(const char *file, int line, database *db, int log_dupes, char *qry) { dbi_result result; const char *errmsg; int tries = 0; if (debug > 4) { LOGRAW(LOG_DEBUG, qry); } if (!dbi_conn_ping(db->conn)) { if (db->conn) dbi_conn_close(db->conn); db->conn = dbi_conn_new(db->driver); if (db->conn == NULL) { perror(db->driver); exit(1); } dbi_conn_set_option(db->conn, "host", db->host); dbi_conn_set_option(db->conn, "port", db->port); dbi_conn_set_option(db->conn, "username", db->username); dbi_conn_set_option(db->conn, "password", db->password); dbi_conn_set_option(db->conn, "dbname", db->name); retry: if (++tries == 3) exit(1); if (dbi_conn_connect(db->conn) < 0) { dbi_conn_error(db->conn, &errmsg); _logsrce = file; _logline = line; _LOG(LOG_ERR, "%s connection failed to %s:%s:%s %s", db->driver, db->host, db->port, db->name, errmsg); sleep(3); goto retry; } { char versionstring[VERSIONSTRING_LENGTH]; dbi_driver driver; driver = dbi_conn_get_driver(db->conn); dbi_conn_get_engine_version_string(db->conn, versionstring); LOG(LOG_INFO, "using driver: %s, version %s, compiled %s", dbi_driver_get_filename(driver), dbi_driver_get_version(driver), dbi_driver_get_date_compiled(driver)); LOG(LOG_INFO, "connected to %s:%s:%s, server version %s", db->host, db->port, db->name, versionstring); } } if (debug > 2) { char *src, *dst, buf[4096]; for (dst = buf, src = qry; *src; src++, dst++) { if (*src == '%') *dst++ = '%'; *dst = *src; } *dst = 0; LOG(LOG_INFO, buf); } result = dbi_conn_query(db->conn, qry); if (result == NULL) { int ret = dbi_conn_error(db->conn, &errmsg); _logsrce = file; _logline = line; _LOG(LOG_ERR, "query failed: %s (%s)", errmsg, qry); if (ret == DBI_ERROR_NOCONN) { dbi_conn_close(db->conn); db->conn = NULL; sleep(3); goto retry; } } return(result); }
/* Connects to database */ static GSM_Error SMSDDBI_Connect(GSM_SMSDConfig * Config) { int rc; struct GSM_SMSDdbobj *db = Config->db; rc = dbi_initialize(Config->driverspath); if (rc == 0) { SMSD_Log(DEBUG_ERROR, Config, "DBI did not find any drivers, try using DriversPath option"); dbi_shutdown(); return ERR_DB_DRIVER; } else if (rc < 0) { SMSD_Log(DEBUG_ERROR, Config, "DBI failed to initialize!"); return ERR_DB_DRIVER; } Config->conn.dbi = dbi_conn_new(Config->driver); if (Config->conn.dbi == NULL) { SMSD_Log(DEBUG_ERROR, Config, "DBI failed to init %s driver!", Config->driver); dbi_shutdown(); return ERR_DB_DRIVER; } else { SMSD_Log(DEBUG_SQL, Config, "Using DBI driver '%s'", dbi_driver_get_name(dbi_conn_get_driver(Config->conn.dbi))); } dbi_conn_error_handler(Config->conn.dbi, SMSDDBI_Callback, Config); if (dbi_conn_set_option(Config->conn.dbi, "sqlite_dbdir", Config->dbdir) != 0) { SMSD_Log(DEBUG_ERROR, Config, "DBI failed to set sqlite_dbdir!"); SMSDDBI_Free(Config); return ERR_DB_CONFIG; } if (dbi_conn_set_option(Config->conn.dbi, "sqlite3_dbdir", Config->dbdir) != 0) { SMSD_Log(DEBUG_ERROR, Config, "DBI failed to set sqlite3_dbdir!"); SMSDDBI_Free(Config); return ERR_DB_CONFIG; } if (dbi_conn_set_option(Config->conn.dbi, "host", Config->host) != 0) { SMSD_Log(DEBUG_ERROR, Config, "DBI failed to set host!"); SMSDDBI_Free(Config); return ERR_DB_CONFIG; } if (dbi_conn_set_option(Config->conn.dbi, "username", Config->user) != 0) { SMSD_Log(DEBUG_ERROR, Config, "DBI failed to set username!"); SMSDDBI_Free(Config); return ERR_DB_CONFIG; } if (dbi_conn_set_option(Config->conn.dbi, "password", Config->password) != 0) { SMSD_Log(DEBUG_ERROR, Config, "DBI failed to set password!"); SMSDDBI_Free(Config); return ERR_DB_CONFIG; } if (dbi_conn_set_option(Config->conn.dbi, "dbname", Config->database) != 0) { SMSD_Log(DEBUG_ERROR, Config, "DBI failed to set dbname!"); SMSDDBI_Free(Config); return ERR_DB_CONFIG; } if (dbi_conn_set_option(Config->conn.dbi, "encoding", "UTF-8") != 0) { SMSD_Log(DEBUG_ERROR, Config, "DBI failed to set encoding!"); SMSDDBI_Free(Config); return ERR_DB_CONFIG; } if (dbi_conn_connect(Config->conn.dbi) != 0) { SMSD_Log(DEBUG_ERROR, Config, "DBI failed to connect!"); SMSDDBI_Free(Config); return ERR_DB_CONNECT; } Config->db = db; return ERR_NONE; }
/* with a little help from ap_resolve_env() ;) */ static const char *populate_querystring(const request_rec * r, const char *querystring, ftpd_dbi_config * conf, ftpd_dbi_dconfig * dconf, ftpd_dbi_rest * dbi_res, const char *user) { char tmp[MAX_STRING_LEN]; /* 8 KByte should be enough for everyone :) */ const char *s, *e; char *p; int written = 0; tmp[0] = '\0'; if (!(s = ap_strchr_c(querystring, QUERYSTRING_MAGIC_CHAR))) return querystring; do { written += (s - querystring); if (written >= MAX_STRING_LEN) { ap_log_perror(APLOG_MARK, APLOG_ERR, 0, r->pool, "[mod_ftpd_dbi.c] Populated string would exceed %d bytes", MAX_STRING_LEN); return NULL; } strncat(tmp, querystring, s - querystring); if ((s[1] == QUERYSTRING_LEFT_DELIM_CHAR) && (e = ap_strchr_c(s, QUERYSTRING_RIGHT_DELIM_CHAR))) { const char *e2 = e; char *var; p = NULL; querystring = e + 1; e = NULL; var = apr_pstrndup(r->pool, s + 2, e2 - (s + 2)); if (!strcasecmp(var, "GivenUsername")) { e = (user ? user : EMPTY_VAR); } else if (!strcasecmp(var, "RequestHostname")) { e = (r->hostname ? r->hostname : EMPTY_VAR); } else if (!strcasecmp(var, "Name")) { e = (conf->rec.dbi_name ? conf->rec.dbi_name : EMPTY_VAR); } else if (!strcasecmp(var, "ConfigHostname")) { e = (r->server->server_hostname ? r->server-> server_hostname : EMPTY_VAR); } /* Everything but the variable values representing fieldnames and tables gets * escaped according to the selected driver */ if (e != NULL) { p = strdup(e); dbi_driver_quote_string(dbi_conn_get_driver(dbi_res->conn), &p); } if (!strcasecmp(var, "UsernameField")) { e = (conf->rec.username_field ? conf->rec. username_field : EMPTY_VAR); } else if (!strcasecmp(var, "ChrootField")) { e = (conf->rec.chroot_field ? conf->rec. chroot_field : EMPTY_VAR); } else if (!strcasecmp(var, "IsActiveField")) { e = (conf->rec.isactive_field ? conf->rec. isactive_field : EMPTY_VAR); } else if (!strcasecmp(var, "Table")) { e = (conf->rec.dbi_table ? conf->rec.dbi_table : EMPTY_VAR); } if (e == NULL) { ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, r->pool, "[mod_ftpd_dbi.c] Unknown variable: %s", var); return NULL; } if (p == NULL) { p = strdup(e); } written += strlen(p); if (written >= MAX_STRING_LEN) { ap_log_perror(APLOG_MARK, APLOG_ERR, 0, r->pool, "[mod_ftpd_dbi.c] Populated string would exceed %d bytes", MAX_STRING_LEN); free(p); return NULL; } strcat(tmp, p); free(p); } else { ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, r->pool, "[mod_ftpd_dbi.c] Invalid querystring"); return NULL; }; } while ((s = ap_strchr_c(querystring, QUERYSTRING_MAGIC_CHAR))); strcat(tmp, querystring); written += strlen(querystring); ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, r->pool, "[mod_ftpd_dbi.c] Populated result: \"%s\" / %d chars written", apr_pstrdup(r->pool, tmp), written); return apr_pstrdup(r->pool, tmp); }