/* configuration.c -- Functions for setting and deleting * configuration parameters in the database * * GPLv2 only - Copyright (C) 2008 - 2010 * David Sommerseth * * 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 sqlite/administration/configuration.c * @author David Sommerseth * @date 2009-09-13 * * @brief Functions for setting and deleting configuration * parameters in the database * */ #include #include #include #include #include #include #include #include #include #include "../sqlite.h" /** * Internal function. Sets a configuration parameter in the database. If the key already * exists, it will be replaced. This operation will immediately update the in-memory copy * of the setting. * * @param ctx eurephiaCTX * @param key String (char *) containing the key name of the value * @param val String (char *) with the value to be stored * * @return Returns 1 on success, otherwise 0 */ static int config_set(eurephiaCTX *ctx, const char *key, const char *val) { dbresult *res = NULL; int found = 0; DEBUG(ctx, 20, "Function call: eDBadminConfigSet(ctx, '%s', '%s')", key, val); assert((ctx != NULL) && (ctx->dbc != NULL)); if( (ctx->context_type != ECTX_ADMIN_CONSOLE) && (ctx->context_type != ECTX_ADMIN_WEB) ) { eurephia_log(ctx, LOG_CRITICAL, 0, "eurephia admin function call attempted with wrong context type"); return 0; } res = sqlite_query(ctx, "SELECT count(*) FROM openvpn_config WHERE datakey = '%q'", key); if( !res ) { eurephia_log(ctx, LOG_ERROR, 0, "Could not query configuration table"); return 0; } found = atoi_nullsafe(sqlite_get_value(res, 0, 0)); sqlite_free_results(res); if( found == 0 ) { res = sqlite_query(ctx, "INSERT INTO openvpn_config (datakey, dataval) VALUES ('%q','%q')", key, val); } else { res = sqlite_query(ctx, "UPDATE openvpn_config SET dataval = '%q' WHERE datakey = '%q'", val, key); } if( res == NULL ) { eurephia_log(ctx, LOG_ERROR, 0, "Could not register configuration entry (%s = '%s'", key, val); return 0; } sqlite_free_results(res); eAdd_value(ctx, ctx->dbc->config, key, val); return 1; } /** * Internal function. Deletes a configuration parameter from the database. * * @param ctx eurephiaCTX * @param key String (char *) containing the key to be deleted. * * @return Returns 1 on success, otherwise 0 */ static int config_delete(eurephiaCTX *ctx, const char *key) { dbresult *res = NULL; eurephiaVALUES *cfgptr = NULL; DEBUG(ctx, 20, "Function call: eDBadminConfigDelete(ctx, '%s') ", key); assert((ctx != NULL) && (ctx->dbc != NULL)); if( (ctx->context_type != ECTX_ADMIN_CONSOLE) && (ctx->context_type != ECTX_ADMIN_WEB) ) { eurephia_log(ctx, LOG_CRITICAL, 0, "eurephia admin function call attempted with wrong context type"); return 0; } // Find the config parameter in the in-memory stack cfgptr = eGet_valuestruct(ctx->dbc->config, key); if( cfgptr == NULL ) { eurephia_log(ctx, LOG_WARNING, 0, "Could not find the configuration parameter '%s'", key); return 0; } // Delete the config parameter from the database res = sqlite_query(ctx, "DELETE FROM openvpn_config WHERE datakey = '%q'", key); if( !res ) { eurephia_log(ctx, LOG_ERROR, 0, "Could delete config configuration entry (%s)", key); return 0; } sqlite_free_results(res); // Since the database call worked, remove it from memory as well ctx->dbc->config = eRemove_value(ctx, ctx->dbc->config, cfgptr->evgid, cfgptr->evid); return 1; } /** * Internal function. Validates if key or value strings are NULL or not. * * @param ctx eurephiaCTX * @param key char pointer to the key string * @param value char pointer to the value string * * @return Returns NULL if key and value is not NULL. Otherwise an eurephia XML document with an error * description will be returned. */ xmlDoc *validate_key_value(eurephiaCTX *ctx, const char *key, const char *value) { int k_null = 0, v_null = 0; k_null = (key == NULL ? 1 : 0); v_null = (value == NULL ? 1 : 0); if( k_null || v_null ) { return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL, "%s%s%s", (k_null ? "The key attribute was not set" : ""), (k_null && v_null ? " and " : ""), (v_null ? "The value tag was not set" : "") ); } return NULL; } /** * @copydoc eDBadminConfiguration() */ xmlDoc *eDBadminConfiguration(eurephiaCTX *ctx, xmlDoc *cfgxml) { xmlDoc *resxml = NULL; xmlNode *root_n = NULL, *cfg_n = NULL; char *key = NULL, *value = NULL; DEBUG(ctx, 20, "Function call: eDBadminConfiguration(ctx, {xmlDoc})"); assert( (ctx != NULL) && (cfgxml != NULL) ); if( (ctx->context_type != ECTX_ADMIN_CONSOLE) && (ctx->context_type != ECTX_ADMIN_WEB) ) { eurephia_log(ctx, LOG_CRITICAL, 0, "eurephia admin function call attempted with wrong context type"); return NULL; } root_n = eurephiaXML_getRoot(ctx, cfgxml, "configuration", 1); if( root_n == NULL ) { eurephia_log(ctx, LOG_CRITICAL, 0, "Invalid XML input."); return NULL; } // Look if we recevied a tag cfg_n = xmlFindNode(root_n, "set"); if( cfg_n != NULL ) { key = xmlGetAttrValue(cfg_n->properties, "key"); value = xmlExtractContent(cfg_n); resxml = validate_key_value(ctx, key, value); if( resxml ) { // Input data was not approved, and we have an error message return resxml; } if( config_set(ctx, key, value) ) { resxml = eurephiaXML_ResultMsg(ctx, exmlRESULT, NULL, "Configuration key '%s' was set to '%s'", key, value); } else { resxml = eurephiaXML_ResultMsg(ctx, exmlERROR, NULL, "Failed to set the key '%s' to '%s'", key, value); } return resxml; }; // If not, look if we recevied a tag cfg_n = xmlFindNode(root_n, "delete"); if( cfg_n != NULL ) { key = xmlGetAttrValue(cfg_n->properties, "key"); resxml = validate_key_value(ctx, key, ""); // Do not use NULL for value if( resxml ) { // Input data was not approved, and we have an error message return resxml; } if( config_delete(ctx, key) ) { resxml = eurephiaXML_ResultMsg(ctx, exmlRESULT, NULL, "Configuration key '%s' was deleted", key); } else { resxml = eurephiaXML_ResultMsg(ctx, exmlERROR, NULL, "Failed to delete the key '%s'", key); } return resxml; } // If not, it's an invalid input return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL, "Unknown XML tag received"); }