usercerts.c

Go to the documentation of this file.
00001 /* usercerts.c  --  Admin functions - user-certificate table
00002  *
00003  *  GPLv2 only - Copyright (C) 2008 - 2010
00004  *               David Sommerseth <dazo@users.sourceforge.net>
00005  *
00006  *  This program is free software; you can redistribute it and/or
00007  *  modify it under the terms of the GNU General Public License
00008  *  as published by the Free Software Foundation; version 2
00009  *  of the License.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00019  *
00020  */
00021 
00031 #include <string.h>
00032 #include <unistd.h>
00033 #include <assert.h>
00034 
00035 #include <libxml/tree.h>
00036 
00037 #include <sqlite3.h>
00038 
00039 #include <eurephia_nullsafe.h>
00040 #include <eurephia_context.h>
00041 #include <eurephia_log.h>
00042 #include <eurephia_xml.h>
00043 #include <eurephia_values.h>
00044 #include <eurephiadb_session_struct.h>
00045 #include <eurephiadb_mapping.h>
00046 
00047 #include "../sqlite.h"
00048 
00049 #define FMAP_USERCERTS
00050 #include "../fieldmapping.h"
00051 
00052 
00062 xmlDoc *usercerts_search(eurephiaCTX *ctx, eDBfieldMap *where_m, const char *sortkeys) {
00063         xmlDoc *list_xml = NULL;
00064         xmlNode *link_root_n = NULL, *link_n = NULL, *tmp_n = NULL;
00065         dbresult *res = NULL;
00066         xmlChar tmp[2050];
00067         const char *dbsort = NULL;
00068         int i;
00069 
00070         DEBUG(ctx, 21, "Function call: usercerts_search(ctx, eDBfieldMap, '%s')", sortkeys);
00071         assert( ctx != NULL );
00072 
00073         if( (ctx->context_type != ECTX_ADMIN_CONSOLE) && (ctx->context_type != ECTX_ADMIN_WEB) ) {
00074                 eurephia_log(ctx, LOG_CRITICAL, 0,
00075                              "eurephia admin function call attempted with wrong context type");
00076                 return NULL;
00077         }
00078 
00079         if( sortkeys != NULL ) {
00080                 dbsort = eDBmkSortKeyString(where_m, sortkeys);
00081         }
00082 
00083         res = sqlite_query_mapped(ctx, SQL_SELECT,
00084                                   "SELECT uicid, ucs.uid AS uid, certid, ucs.registered AS registered,"
00085                                   "       ucs.accessprofile AS accessprofile, access_descr,"
00086                                   "       username, "
00087                                   "       common_name, organisation, email, lower(digest), depth "
00088                                   "  FROM openvpn_usercerts ucs"
00089                                   "  LEFT JOIN openvpn_certificates USING(certid)"
00090                                   "  LEFT JOIN openvpn_accesses acc ON(ucs.accessprofile = acc.accessprofile)"
00091                                   "  LEFT JOIN openvpn_users u ON(u.uid = ucs.uid)",
00092                                   NULL, // values (not used for SELECT)
00093                                   where_m, // fields and values for the WHERE clause
00094                                   dbsort);
00095         if( res == NULL ) {
00096                 eurephia_log(ctx, LOG_ERROR, 0, "Could not query the usercerts table");
00097                 return NULL;
00098         }
00099 
00100         memset(&tmp, 0, 2050);
00101         eurephiaXML_CreateDoc(ctx, 1, "usercerts", &list_xml, &link_root_n);
00102         xmlStrPrintf(tmp, 64, (xmlChar *) "%i", sqlite_get_numtuples(res));
00103         xmlNewProp(link_root_n, (xmlChar *) "link_count", (xmlChar *) tmp);
00104 
00105         for( i = 0; i < sqlite_get_numtuples(res); i++ ) {
00106                 link_n = xmlNewChild(link_root_n, NULL, (xmlChar *) "usercert_link", NULL);
00107 
00108                 sqlite_xml_value(link_n, XML_ATTR, "uicid", res, i, 0);
00109                 sqlite_xml_value(link_n, XML_ATTR, "registered", res, i, 3);
00110 
00111                 tmp_n = sqlite_xml_value(link_n, XML_NODE, "username", res, i, 6);
00112                 sqlite_xml_value(tmp_n, XML_ATTR, "uid", res, i, 1);
00113 
00114                 tmp_n = xmlNewChild(link_n, NULL, (xmlChar *) "certificate", NULL);
00115                 sqlite_xml_value(tmp_n, XML_ATTR, "certid", res, i, 2);
00116                 sqlite_xml_value(tmp_n, XML_ATTR, "depth", res, i, 11);
00117 
00118                 xmlStrPrintf(tmp, 2048, (xmlChar *) "%.2048s", sqlite_get_value(res, i, 7));
00119                 xmlReplaceChars(tmp, '_', ' ');
00120                 xmlNewChild(tmp_n, NULL, (xmlChar *) "common_name", tmp);
00121 
00122                 xmlStrPrintf(tmp, 2048, (xmlChar *) "%.2048s", sqlite_get_value(res, i, 8));
00123                 xmlReplaceChars(tmp, '_', ' ');
00124                 xmlNewChild(tmp_n, NULL, (xmlChar *) "organisation", tmp);
00125 
00126                 sqlite_xml_value(tmp_n, XML_NODE, "email", res, i, 9);
00127                 sqlite_xml_value(tmp_n, XML_NODE, "digest", res, i, 10);
00128 
00129                 tmp_n = sqlite_xml_value(link_n, XML_NODE, "access_profile", res, i, 5);
00130                 sqlite_xml_value(tmp_n, XML_ATTR, "accessprofile", res, i, 4);
00131         }
00132         sqlite_free_results(res);
00133 
00134         return list_xml;
00135 }
00136 
00137 
00147 xmlDoc *usercerts_add_del(eurephiaCTX *ctx, const char *mode, eDBfieldMap *usrcrt_m) {
00148         xmlDoc *res = NULL;
00149         dbresult *dbres = NULL;
00150 
00151         DEBUG(ctx, 21, "Function call: usercerts_add_del(ctx, xmlDoc)");
00152         assert( (ctx != NULL) && (usrcrt_m != NULL) );
00153 
00154         if( strcmp(mode, "register") == 0 ) {
00155                 dbres = sqlite_query_mapped(ctx, SQL_INSERT,
00156                                             "INSERT INTO openvpn_usercerts", usrcrt_m, NULL, NULL);
00157                 if( dbres ) {
00158                         res = eurephiaXML_ResultMsg(ctx, exmlRESULT, NULL,
00159                                                     "Registered new user-cert link with id %i",
00160                                                     dbres->last_insert_id);
00161                 }
00162         } else if( strcmp(mode, "remove") == 0 ) {
00163                 dbres = sqlite_query_mapped(ctx, SQL_DELETE,
00164                                             "DELETE FROM openvpn_usercerts", NULL, usrcrt_m, NULL);
00165                 if( dbres ) {
00166                         int num_rows = sqlite_get_affected_rows(dbres);
00167                         if( num_rows > 0 ) {
00168                                 res = eurephiaXML_ResultMsg(ctx, exmlRESULT, NULL,
00169                                                             "Removed %i user-cert %s successfully",
00170                                                             num_rows, (num_rows == 1 ? "link" : "links"));
00171                         } else {
00172                                 res = eurephiaXML_ResultMsg(ctx, exmlERROR, NULL,
00173                                                             "No user-cert links where removed");
00174                         }
00175                 }
00176         }
00177 
00178         if( dbres == NULL ) {
00179                 eurephia_log(ctx, LOG_ERROR, 0, "Failed to %s user-cert link.", mode);
00180                 res = eurephiaXML_ResultMsg(ctx, exmlERROR, NULL, "Failed to %s user-cert link", mode);
00181         } else {
00182                 sqlite_free_results(dbres);
00183         }
00184 
00185         return res;
00186 }
00187 
00188 
00199 xmlDoc *usercerts_update(eurephiaCTX *ctx, const char *uicid, eDBfieldMap *usrcrt_m) {
00200         xmlNode *where_n = NULL;
00201         eDBfieldMap *where_m = NULL;
00202         dbresult *dbres = NULL;
00203         xmlDoc *where_d = NULL, *res = NULL;
00204 
00205         DEBUG(ctx, 21, "Function call: usercerts_update(ctx, '%s', eDBfieldMap)", uicid);
00206         assert( ctx != NULL && uicid != NULL && usrcrt_m != NULL );
00207 
00208         // Create a eDBfieldMap which will contain the uicid value
00209         eurephiaXML_CreateDoc(ctx, 1, "usercerts", &where_d, &where_n);
00210         assert( (where_d != NULL) && (where_n != NULL) );
00211 
00212         where_n = xmlNewChild(where_n, NULL, (xmlChar *) "fieldMapping", NULL);
00213         xmlNewProp(where_n, (xmlChar *) "table", (xmlChar *) "usercerts");
00214         xmlNewChild(where_n, NULL, (xmlChar *) "uicid", (xmlChar *) uicid);
00215 
00216         // Convert xmlNode with fieldMapping into a eDBfieldMap
00217         where_m = eDBxmlMapping(ctx, tbl_sqlite_usercerts, NULL, where_n);
00218         assert( where_m != NULL );
00219 
00220         // Send update query to the database
00221         dbres = sqlite_query_mapped(ctx, SQL_UPDATE, "UPDATE openvpn_usercerts",
00222                                     usrcrt_m, where_m, NULL);
00223         if( dbres ) {
00224                 int num_rows = sqlite_get_affected_rows(dbres);
00225                 if( num_rows > 0 ) {
00226                         res = eurephiaXML_ResultMsg(ctx, exmlRESULT, NULL,
00227                                                     "Updated firewall access profile on %i user-cert %s.",
00228                                                     num_rows, (num_rows == 1 ? "link" : "links"));
00229                 } else {
00230                         res = eurephiaXML_ResultMsg(ctx, exmlERROR, NULL,
00231                                                     "No user-cert links where updated");
00232                 }
00233                 sqlite_free_results(dbres);
00234         } else {
00235                 eurephia_log(ctx, LOG_ERROR, 0, "Failed to update user-cert link.(uicid: %s)", uicid);
00236                 res = eurephiaXML_ResultMsg(ctx, exmlERROR, NULL,
00237                                             "Failed to update user-cert link for uicid %s", uicid);
00238         }
00239         eDBfreeMapping(where_m);
00240         xmlFreeDoc(where_d);
00241 
00242         return res;
00243 }
00244 
00245 
00249 xmlDoc *eDBadminUserCertsLink(eurephiaCTX *ctx, xmlDoc *usrcrt_xml) {
00250         xmlNode *usrcrt_n = NULL, *tmp_n = NULL;
00251         xmlDoc *resxml = NULL;
00252         eDBfieldMap *usrcrt_m = NULL;
00253         const char *mode = NULL, *sortfields = NULL, *uicid = NULL;
00254 
00255         DEBUG(ctx, 20, "Function call: eDBadminUserCertsLink(ctx, xmlDoc)");
00256         assert( (ctx != NULL) && (usrcrt_xml != NULL) );
00257 
00258         if( (ctx->context_type != ECTX_ADMIN_CONSOLE) && (ctx->context_type != ECTX_ADMIN_WEB) ) {
00259                 eurephia_log(ctx, LOG_CRITICAL, 0,
00260                              "eurephia admin function call attempted with wrong context type");
00261                 return 0;
00262         }
00263 
00264         usrcrt_n = eurephiaXML_getRoot(ctx, usrcrt_xml, "usercerts", 1);
00265         if( usrcrt_n == NULL ) {
00266                 eurephia_log(ctx, LOG_ERROR, 0, "Could not find a valid XML for the user-certs link request");
00267                 return 0;
00268         }
00269         mode = xmlGetAttrValue(usrcrt_n->properties, "mode");
00270         if( mode == NULL ) {
00271                 eurephia_log(ctx, LOG_ERROR, 0, "Invalid user-cert link request (1).");
00272                 return 0;
00273         }
00274 
00275         tmp_n = xmlFindNode(usrcrt_n, "sortfields");
00276         if( tmp_n ) {
00277                 sortfields = xmlExtractContent(tmp_n);
00278         }
00279 
00280         tmp_n = xmlFindNode(usrcrt_n, "fieldMapping");
00281         if( tmp_n == NULL ) {
00282                 eurephia_log(ctx, LOG_ERROR, 0, "Invalid user-cert link request (2).");
00283                 return 0;
00284         }
00285         usrcrt_m = eDBxmlMapping(ctx, tbl_sqlite_usercerts, NULL, tmp_n);
00286         assert(usrcrt_m != NULL);
00287 
00288 
00289         if( strcmp(mode, "search") == 0 ) {
00290                 resxml = usercerts_search(ctx, usrcrt_m, sortfields);
00291         } else if( strcmp(mode, "register") == 0 ) {
00292                 resxml = usercerts_add_del(ctx, mode, usrcrt_m);
00293         } else if( strcmp(mode, "remove") == 0 ) {
00294                 resxml = usercerts_add_del(ctx, mode, usrcrt_m);
00295         } else if( strcmp(mode, "update") == 0 ) {
00296                 uicid = xmlGetAttrValue(usrcrt_n->properties, "uicid");
00297                 if( uicid == NULL ) {
00298                         eurephia_log(ctx, LOG_ERROR, 0, "Missing required attribute, uicid, for updates");
00299                         resxml = eurephiaXML_ResultMsg(ctx, exmlERROR, NULL,
00300                                                        "Can not set firewall access profile without uicid");
00301                         goto exit;
00302                 }
00303                 resxml = usercerts_update(ctx, uicid, usrcrt_m);
00304         }
00305 
00306  exit:
00307         eDBfreeMapping(usrcrt_m);
00308         return resxml;
00309 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines