00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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,
00093 where_m,
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
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
00217 where_m = eDBxmlMapping(ctx, tbl_sqlite_usercerts, NULL, where_n);
00218 assert( where_m != NULL );
00219
00220
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 }