Avoid using SQLITE_OPEN_URI
Centos6 uses a very old version of SQLite without support for URI filenames. PAM authenticator must use a file-based database. Commit cherry-picked to 2.4.0 from 2.3.
This commit is contained in:
@ -29,6 +29,9 @@ const string FIELD_AUTHSTR = "authentication_string";
|
|||||||
const string FIELD_PROXY = "proxy_grant";
|
const string FIELD_PROXY = "proxy_grant";
|
||||||
const int NUM_FIELDS = 6;
|
const int NUM_FIELDS = 6;
|
||||||
|
|
||||||
|
const char* SQLITE_OPEN_FAIL = "Failed to open SQLite3 handle for file '%s': '%s'";
|
||||||
|
const char* SQLITE_OPEN_OOM = "Failed to allocate memory for SQLite3 handle for file '%s'.";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize PAM authenticator
|
* Initialize PAM authenticator
|
||||||
*
|
*
|
||||||
|
@ -34,3 +34,6 @@ extern const string FIELD_ANYDB;
|
|||||||
extern const string FIELD_AUTHSTR;
|
extern const string FIELD_AUTHSTR;
|
||||||
extern const string FIELD_PROXY;
|
extern const string FIELD_PROXY;
|
||||||
extern const int NUM_FIELDS;
|
extern const int NUM_FIELDS;
|
||||||
|
|
||||||
|
extern const char* SQLITE_OPEN_FAIL;
|
||||||
|
extern const char* SQLITE_OPEN_OOM;
|
||||||
|
@ -91,18 +91,33 @@ PamClientSession* PamClientSession::create(const PamInstance& inst)
|
|||||||
{
|
{
|
||||||
// This handle is only used from one thread, can define no_mutex.
|
// This handle is only used from one thread, can define no_mutex.
|
||||||
sqlite3* dbhandle = NULL;
|
sqlite3* dbhandle = NULL;
|
||||||
int db_flags = SQLITE_OPEN_READONLY | SQLITE_OPEN_SHAREDCACHE | SQLITE_OPEN_NOMUTEX
|
bool error = false;
|
||||||
| SQLITE_OPEN_URI;
|
int db_flags = SQLITE_OPEN_READONLY | SQLITE_OPEN_SHAREDCACHE | SQLITE_OPEN_NOMUTEX;
|
||||||
if (sqlite3_open_v2(inst.m_dbname.c_str(), &dbhandle, db_flags, NULL) == SQLITE_OK)
|
const char* filename = inst.m_dbname.c_str();
|
||||||
|
if (sqlite3_open_v2(filename, &dbhandle, db_flags, NULL) == SQLITE_OK)
|
||||||
{
|
{
|
||||||
sqlite3_busy_timeout(dbhandle, 1000);
|
sqlite3_busy_timeout(dbhandle, 1000);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MXS_ERROR("Failed to open SQLite3 handle.");
|
if (dbhandle)
|
||||||
|
{
|
||||||
|
MXS_ERROR(SQLITE_OPEN_FAIL, filename, sqlite3_errmsg(dbhandle));
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MXS_ERROR(SQLITE_OPEN_OOM, filename);
|
||||||
|
}
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
|
||||||
PamClientSession* rval = NULL;
|
PamClientSession* rval = NULL;
|
||||||
if (!dbhandle || (rval = new(std::nothrow) PamClientSession(dbhandle, inst)) == NULL)
|
if (!error && ((rval = new (std::nothrow) PamClientSession(dbhandle, inst)) == NULL))
|
||||||
|
{
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error)
|
||||||
{
|
{
|
||||||
sqlite3_close_v2(dbhandle);
|
sqlite3_close_v2(dbhandle);
|
||||||
}
|
}
|
||||||
|
@ -16,11 +16,10 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <maxscale/jansson.hh>
|
#include <maxscale/jansson.hh>
|
||||||
|
#include <maxscale/paths.h>
|
||||||
#include <maxscale/secrets.h>
|
#include <maxscale/secrets.h>
|
||||||
#include <maxscale/mysql_utils.hh>
|
#include <maxscale/mysql_utils.hh>
|
||||||
|
|
||||||
#define DEFAULT_PAM_DATABASE_NAME "file:pam.db?mode=memory&cache=shared"
|
|
||||||
#define DEFAULT_PAM_TABLE_NAME "pam_users"
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -31,10 +30,12 @@ using std::string;
|
|||||||
*/
|
*/
|
||||||
PamInstance* PamInstance::create(char** options)
|
PamInstance* PamInstance::create(char** options)
|
||||||
{
|
{
|
||||||
/** Name of the in-memory database */
|
// Name of the in-memory database.
|
||||||
const string pam_db_name = DEFAULT_PAM_DATABASE_NAME;
|
// TODO: Once Centos6 is no longer needed and Sqlite version 3.7+ can be assumed,
|
||||||
/** The table name where we store the users */
|
// use a memory-only db with a URI filename (e.g. file:pam.db?mode=memory&cache=shared)
|
||||||
const string pam_table_name = DEFAULT_PAM_TABLE_NAME;
|
const string pam_db_fname = string(get_cachedir()) + "/pam_db.sqlite3";
|
||||||
|
// The table name where we store the users
|
||||||
|
const string pam_table_name = "pam_users";
|
||||||
/** Deletion statement for the in-memory table */
|
/** Deletion statement for the in-memory table */
|
||||||
const string drop_sql = string("DROP TABLE IF EXISTS ") + pam_table_name + ";";
|
const string drop_sql = string("DROP TABLE IF EXISTS ") + pam_table_name + ";";
|
||||||
/** CREATE TABLE statement for the in-memory table */
|
/** CREATE TABLE statement for the in-memory table */
|
||||||
@ -55,15 +56,25 @@ PamInstance* PamInstance::create(char** options)
|
|||||||
bool error = false;
|
bool error = false;
|
||||||
/* This handle may be used from multiple threads, set full mutex. */
|
/* This handle may be used from multiple threads, set full mutex. */
|
||||||
sqlite3* dbhandle = NULL;
|
sqlite3* dbhandle = NULL;
|
||||||
int db_flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE
|
int db_flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE |
|
||||||
| SQLITE_OPEN_SHAREDCACHE | SQLITE_OPEN_FULLMUTEX | SQLITE_OPEN_URI;
|
SQLITE_OPEN_SHAREDCACHE | SQLITE_OPEN_FULLMUTEX;
|
||||||
if (sqlite3_open_v2(pam_db_name.c_str(), &dbhandle, db_flags, NULL) != SQLITE_OK)
|
const char* filename = pam_db_fname.c_str();
|
||||||
|
if (sqlite3_open_v2(filename, &dbhandle, db_flags, NULL) != SQLITE_OK)
|
||||||
{
|
{
|
||||||
MXS_ERROR("Failed to open SQLite3 handle.");
|
// Even if the open failed, the handle may exist and an error message can be read.
|
||||||
|
if (dbhandle)
|
||||||
|
{
|
||||||
|
MXS_ERROR(SQLITE_OPEN_FAIL, filename, sqlite3_errmsg(dbhandle));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// This means memory allocation failed.
|
||||||
|
MXS_ERROR(SQLITE_OPEN_OOM, filename);
|
||||||
|
}
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* err;
|
char *err = NULL;
|
||||||
if (!error && sqlite3_exec(dbhandle, drop_sql.c_str(), NULL, NULL, &err) != SQLITE_OK)
|
if (!error && sqlite3_exec(dbhandle, drop_sql.c_str(), NULL, NULL, &err) != SQLITE_OK)
|
||||||
{
|
{
|
||||||
MXS_ERROR("Failed to drop table: '%s'", err);
|
MXS_ERROR("Failed to drop table: '%s'", err);
|
||||||
@ -77,10 +88,16 @@ PamInstance* PamInstance::create(char** options)
|
|||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
PamInstance* instance = NULL;
|
PamInstance *instance = NULL;
|
||||||
if (!error
|
if (!error &&
|
||||||
&& ((instance = new(std::nothrow) PamInstance(dbhandle, pam_db_name, pam_table_name)) == NULL))
|
((instance = new (std::nothrow) PamInstance(dbhandle, pam_db_fname, pam_table_name)) == NULL))
|
||||||
{
|
{
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
// Close the handle even if never opened.
|
||||||
sqlite3_close_v2(dbhandle);
|
sqlite3_close_v2(dbhandle);
|
||||||
}
|
}
|
||||||
return instance;
|
return instance;
|
||||||
|
Reference in New Issue
Block a user