/* * UserBackendMysql.cpp * * Copyright (C) 2008 Matthias Schiffer * * 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, either version 3 of the License, or * (at your option) any later version. * * 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, see . */ #include #include "UserBackendMysql.h" #include #include #include #include #include #include #include #define init UserBackendMysql_LTX_init #define deinit UserBackendMysql_LTX_deinit namespace Mad { namespace Modules { UserBackendMysql *UserBackendMysql::backend; bool UserBackendMysql::handleConfigEntry(const Common::ConfigEntry &entry, bool handled) { if(handled) return false; if(entry[0].getKey().matches("UserBackendMysql")) { if(entry[1].getKey().matches("Host")) { if(entry[2].empty()) host = entry[1][0]; } else if(entry[1].getKey().matches("Username")) { if(entry[2].empty()) username = entry[1][0]; } else if(entry[1].getKey().matches("Password")) { if(entry[2].empty()) passwd = entry[1][0]; } else if(entry[1].getKey().matches("Database")) { if(entry[2].empty()) db = entry[1][0]; } else if(entry[1].getKey().matches("Port")) { if(entry[2].empty()) { char *endptr; long val; val = strtol(entry[1][0].c_str(), &endptr, 10); if(endptr != 0 || val < 0 || val > 65535) Common::Logger::log(Common::Logger::WARNING, "UserBackendMysql: Invalid port"); else port = val; } } else if(entry[1].getKey().matches("UnixSocket")) { if(entry[2].empty()) unixSocket = entry[1][0]; } else if(entry[1].getKey().matches("Queries")) { if(entry[2].getKey().matches("ListUsers")) { if(entry[3].empty()) queryListUsers = entry[2][0]; } else if(entry[2].getKey().matches("ListGroups")) { if(entry[3].empty()) queryListGroups = entry[2][0]; } else if(entry[2].getKey().matches("ListUserGroups")) { if(entry[3].empty()) queryListUserGroups = entry[2][0]; } else if(entry[2].getKey().matches("ListGroupUsers")) { if(entry[3].empty()) queryListGroupUsers = entry[2][0]; } else if(entry[2].getKey().matches("UserById")) { if(entry[3].empty()) queryUserById = entry[2][0]; } else if(entry[2].getKey().matches("UserByName")) { if(entry[3].empty()) queryUserByName = entry[2][0]; } else if(entry[2].getKey().matches("GroupById")) { if(entry[3].empty()) queryGroupById = entry[2][0]; } else if(entry[2].getKey().matches("GroupByName")) { if(entry[3].empty()) queryGroupByName = entry[2][0]; } else if(!entry[2].empty()) return false; } else if(!entry[1].empty()) return false; return true; } return false; } void UserBackendMysql::configFinished() { if(db.empty()) { Common::Logger::log(Common::Logger::ERROR, "UserBackendMysql: No database name given"); return; } mysql = mysql_init(0); mysql_real_connect(mysql, host.c_str(), username.c_str(), passwd.c_str(), db.c_str(), port, unixSocket.empty() ? 0 : unixSocket.c_str(), 0); Server::UserManager::get()->registerBackend(backend); } bool UserBackendMysql::getUserList(const boost::function1& > &callback) { mysql_ping(mysql); mysql_real_query(mysql, queryListUsers.c_str(), queryListUsers.length()); MYSQL_RES *result = mysql_use_result(mysql); if(mysql_num_fields(result) < 4) return true; // TODO Error std::map users; while(MYSQL_ROW row = mysql_fetch_row(result)) { Common::UserInfo user(strtoul(row[0], 0, 10), row[2]); user.setGid(strtoul(row[1], 0, 10)); user.setFullName(row[3]); users.insert(std::make_pair(user.getUid(), user)); } Common::ActionManager::get()->add(boost::bind(callback, users)); return true; } bool UserBackendMysql::getUserInfo(unsigned long uid, const boost::function1 &callback) { mysql_ping(mysql); std::string query = queryUserById; std::ostringstream tmp; tmp << '"'; tmp << uid; tmp << '"'; pcrecpp::RE("\\{ID\\}").GlobalReplace(tmp.str(), &query); mysql_real_query(mysql, query.c_str(), query.length()); MYSQL_RES *result = mysql_use_result(mysql); if(mysql_num_fields(result) < 4) return true; // TODO Error MYSQL_ROW row = mysql_fetch_row(result); if(row) { Common::UserInfo user(strtoul(row[0], 0, 10), row[2]); user.setGid(strtoul(row[1], 0, 10)); user.setFullName(row[3]); Common::ActionManager::get()->add(boost::bind(callback, user)); while((row = mysql_fetch_row(result)) != 0) {} } else { Common::ActionManager::get()->add(boost::bind(callback, Common::UserInfo())); } return true; } void UserBackendMysql::registerBackend() { if(backend) return; backend = new UserBackendMysql(); Common::ConfigManager::get()->registerConfigurable(backend); } void UserBackendMysql::unregisterBackend() { if(!backend) return; Common::ConfigManager::get()->unregisterConfigurable(backend); Server::UserManager::get()->unregisterBackend(backend); delete backend; backend = 0; } } } extern "C" { void init() { Mad::Modules::UserBackendMysql::registerBackend(); } void deinit() { Mad::Modules::UserBackendMysql::unregisterBackend(); } }