// ******************************************************************************************************* // Servicio: ogAdmServer // Autor: José Manuel Alonso (E.T.S.I.I.) Universidad de Sevilla // Fecha Creación: Marzo-2010 // Fecha Última modificación: Marzo-2010 // Nombre del fichero: ogAdmServer.cpp // Descripción :Este fichero implementa el servicio de administración general del sistema // ******************************************************************************************************* #include "ogAdmServer.h" #include "dbi.h" #include "utils.h" #include "list.h" #include "rest.h" #include "client.h" #include "json.h" #include "wol.h" #include #include #include #include #include #include #include // ________________________________________________________________________________________________________ // Función: checkDato // // Descripción: // Esta función comprueba si existe un dato en una tabla y si no es así lo incluye. devuelve en // cualquier caso el identificador del registro existenet o del insertado // Parámetros: // - db: Objeto base de datos (ya operativo) // - tbl: Objeto tabla // - dato: Dato // - tabla: Nombre de la tabla // - nomdato: Nombre del dato en la tabla // - nomidentificador: Nombre del identificador en la tabla // Devuelve: // El identificador del registro existente o el del insertado // // Especificaciones: // En caso de producirse algún error se devuelve el valor 0 // ________________________________________________________________________________________________________ int checkDato(struct og_dbi *dbi, char *dato, const char *tabla, const char *nomdato, const char *nomidentificador) { const char *msglog; int identificador; dbi_result result; if (strlen(dato) == 0) return (0); // EL dato no tiene valor result = dbi_conn_queryf(dbi->conn, "SELECT %s FROM %s WHERE %s ='%s'", nomidentificador, tabla, nomdato, dato); // Ejecuta consulta if (!result) { dbi_conn_error(dbi->conn, &msglog); syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", __func__, __LINE__, msglog); return (0); } if (!dbi_result_next_row(result)) { // Software NO existente dbi_result_free(result); result = dbi_conn_queryf(dbi->conn, "INSERT INTO %s (%s) VALUES('%s')", tabla, nomdato, dato); if (!result) { dbi_conn_error(dbi->conn, &msglog); syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", __func__, __LINE__, msglog); return (0); } // Recupera el identificador del software identificador = dbi_conn_sequence_last(dbi->conn, NULL); } else { identificador = dbi_result_get_uint(result, nomidentificador); } dbi_result_free(result); return (identificador); } // ________________________________________________________________________________________________________ // Función: actualizaHardware // // Descripción: // Actualiza la base de datos con la configuracion hardware del cliente // Parámetros: // - db: Objeto base de datos (ya operativo) // - tbl: Objeto tabla // - hrd: cadena con el inventario hardware // - ido: Identificador del ordenador // - npc: Nombre del ordenador // - idc: Identificador del centro o Unidad organizativa // ________________________________________________________________________________________________________ // bool actualizaHardware(struct og_dbi *dbi, char *hrd, char *ido, char *npc, char *idc) { const char *msglog; int idtipohardware, idperfilhard; int lon, i, j, aux; bool retval; char *whard; int tbidhardware[MAXHARDWARE]; char *tbHardware[MAXHARDWARE],*dualHardware[2], strInt[LONINT], *idhardwares; dbi_result result; /* Toma Centro (Unidad Organizativa) */ result = dbi_conn_queryf(dbi->conn, "SELECT idperfilhard FROM ordenadores WHERE idordenador=%s", ido); if (!result) { dbi_conn_error(dbi->conn, &msglog); syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", __func__, __LINE__, msglog); return false; } if (!dbi_result_next_row(result)) { syslog(LOG_ERR, "client does not exist in database (%s:%d)\n", __func__, __LINE__); dbi_result_free(result); return false; } idperfilhard = dbi_result_get_uint(result, "idperfilhard"); dbi_result_free(result); whard=escaparCadena(hrd); // Codificar comillas simples if(!whard) return false; /* Recorre componentes hardware*/ lon = splitCadena(tbHardware, whard, '\n'); if (lon > MAXHARDWARE) lon = MAXHARDWARE; // Limita el número de componentes hardware /* for (i=0;iconn, &msglog); syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", __func__, __LINE__, msglog); return false; } if (!dbi_result_next_row(result)) { // Tipo de Hardware NO existente dbi_result_free(result); return false; } else { // Tipo de Hardware Existe idtipohardware = dbi_result_get_uint(result, "idtipohardware"); dbi_result_free(result); result = dbi_conn_queryf(dbi->conn, "SELECT idhardware FROM hardwares WHERE idtipohardware=%d AND descripcion='%s'", idtipohardware, dualHardware[1]); if (!result) { dbi_conn_error(dbi->conn, &msglog); syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", __func__, __LINE__, msglog); return false; } if (!dbi_result_next_row(result)) { // Hardware NO existente dbi_result_free(result); result = dbi_conn_queryf(dbi->conn, "INSERT hardwares (idtipohardware,descripcion,idcentro,grupoid) " " VALUES(%d,'%s',%s,0)", idtipohardware, dualHardware[1], idc); if (!result) { dbi_conn_error(dbi->conn, &msglog); syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", __func__, __LINE__, msglog); return false; } // Recupera el identificador del hardware tbidhardware[i] = dbi_conn_sequence_last(dbi->conn, NULL); } else { tbidhardware[i] = dbi_result_get_uint(result, "idhardware"); } dbi_result_free(result); } } // Ordena tabla de identificadores para cosultar si existe un pefil con esas especificaciones for (i = 0; i < lon - 1; i++) { for (j = i + 1; j < lon; j++) { if (tbidhardware[i] > tbidhardware[j]) { aux = tbidhardware[i]; tbidhardware[i] = tbidhardware[j]; tbidhardware[j] = aux; } } } /* Crea cadena de identificadores de componentes hardware separados por coma */ sprintf(strInt, "%d", tbidhardware[lon - 1]); // Pasa a cadena el último identificador que es de mayor longitud aux = strlen(strInt); // Calcula longitud de cadena para reservar espacio a todos los perfiles idhardwares = calloc(1, sizeof(aux) * lon + lon); if (idhardwares == NULL) { syslog(LOG_ERR, "%s:%d OOM\n", __FILE__, __LINE__); return false; } aux = sprintf(idhardwares, "%d", tbidhardware[0]); for (i = 1; i < lon; i++) aux += sprintf(idhardwares + aux, ",%d", tbidhardware[i]); if (!cuestionPerfilHardware(dbi, idc, ido, idperfilhard, idhardwares, npc, tbidhardware, lon)) { syslog(LOG_ERR, "Problem updating client hardware\n"); retval=false; } else { retval=true; } free(whard); free(idhardwares); return (retval); } // ________________________________________________________________________________________________________ // Función: cuestionPerfilHardware // // Descripción: // Comprueba existencia de perfil hardware y actualización de éste para el ordenador // Parámetros: // - db: Objeto base de datos (ya operativo) // - tbl: Objeto tabla // - idc: Identificador de la Unidad organizativa donde se encuentra el cliente // - ido: Identificador del ordenador // - tbidhardware: Identificador del tipo de hardware // - con: Número de componentes detectados para configurar un el perfil hardware // - npc: Nombre del cliente // ________________________________________________________________________________________________________ bool cuestionPerfilHardware(struct og_dbi *dbi, char *idc, char *ido, int idperfilhardware, char *idhardwares, char *npc, int *tbidhardware, int lon) { const char *msglog; dbi_result result; int i; int nwidperfilhard; // Busca perfil hard del ordenador que contenga todos los componentes hardware encontrados result = dbi_conn_queryf(dbi->conn, "SELECT idperfilhard FROM" " (SELECT perfileshard_hardwares.idperfilhard as idperfilhard," " group_concat(cast(perfileshard_hardwares.idhardware AS char( 11) )" " ORDER BY perfileshard_hardwares.idhardware SEPARATOR ',' ) AS idhardwares" " FROM perfileshard_hardwares" " GROUP BY perfileshard_hardwares.idperfilhard) AS temp" " WHERE idhardwares LIKE '%s'", idhardwares); if (!result) { dbi_conn_error(dbi->conn, &msglog); syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", __func__, __LINE__, msglog); return false; } if (!dbi_result_next_row(result)) { // No existe un perfil hardware con esos componentes de componentes hardware, lo crea dbi_result_free(result); result = dbi_conn_queryf(dbi->conn, "INSERT perfileshard (descripcion,idcentro,grupoid)" " VALUES('Perfil hardware (%s) ',%s,0)", npc, idc); if (!result) { dbi_conn_error(dbi->conn, &msglog); syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", __func__, __LINE__, msglog); return false; } dbi_result_free(result); // Recupera el identificador del nuevo perfil hardware nwidperfilhard = dbi_conn_sequence_last(dbi->conn, NULL); // Crea la relación entre perfiles y componenetes hardware for (i = 0; i < lon; i++) { result = dbi_conn_queryf(dbi->conn, "INSERT perfileshard_hardwares (idperfilhard,idhardware)" " VALUES(%d,%d)", nwidperfilhard, tbidhardware[i]); if (!result) { dbi_conn_error(dbi->conn, &msglog); syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", __func__, __LINE__, msglog); return false; } dbi_result_free(result); } } else { // Existe un perfil con todos esos componentes nwidperfilhard = dbi_result_get_uint(result, "idperfilhard"); dbi_result_free(result); } if (idperfilhardware != nwidperfilhard) { // No coinciden los perfiles // Actualiza el identificador del perfil hardware del ordenador result = dbi_conn_queryf(dbi->conn, "UPDATE ordenadores SET idperfilhard=%d" " WHERE idordenador=%s", nwidperfilhard, ido); if (!result) { dbi_conn_error(dbi->conn, &msglog); syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", __func__, __LINE__, msglog); return false; } dbi_result_free(result); } /* Eliminar Relación de hardwares con Perfiles hardware que quedan húerfanos */ result = dbi_conn_queryf(dbi->conn, "DELETE FROM perfileshard_hardwares WHERE idperfilhard IN " " (SELECT idperfilhard FROM perfileshard WHERE idperfilhard NOT IN" " (SELECT DISTINCT idperfilhard from ordenadores))"); if (!result) { dbi_conn_error(dbi->conn, &msglog); syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", __func__, __LINE__, msglog); return false; } dbi_result_free(result); /* Eliminar Perfiles hardware que quedan húerfanos */ result = dbi_conn_queryf(dbi->conn, "DELETE FROM perfileshard WHERE idperfilhard NOT IN" " (SELECT DISTINCT idperfilhard FROM ordenadores)"); if (!result) { dbi_conn_error(dbi->conn, &msglog); syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", __func__, __LINE__, msglog); return false; } dbi_result_free(result); /* Eliminar Relación de hardwares con Perfiles hardware que quedan húerfanos */ result = dbi_conn_queryf(dbi->conn, "DELETE FROM perfileshard_hardwares WHERE idperfilhard NOT IN" " (SELECT idperfilhard FROM perfileshard)"); if (!result) { dbi_conn_error(dbi->conn, &msglog); syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", __func__, __LINE__, msglog); return false; } dbi_result_free(result); return true; } // ________________________________________________________________________________________________________ // Función: actualizaSoftware // // Descripción: // Actualiza la base de datos con la configuración software del cliente // Parámetros: // - db: Objeto base de datos (ya operativo) // - tbl: Objeto tabla // - sft: cadena con el inventario software // - par: Número de la partición // - ido: Identificador del ordenador del cliente en la tabla // - npc: Nombre del ordenador // - idc: Identificador del centro o Unidad organizativa // Devuelve: // true: Si el proceso es correcto // false: En caso de ocurrir algún error // // Versión 1.1.0: Se incluye el sistema operativo. Autora: Irina Gómez - ETSII Universidad Sevilla // ________________________________________________________________________________________________________ bool actualizaSoftware(struct og_dbi *dbi, char *sft, char *par,char *ido, char *npc, char *idc) { int i, j, lon, aux, idperfilsoft, idnombreso; bool retval; char *wsft; int tbidsoftware[MAXSOFTWARE]; char *tbSoftware[MAXSOFTWARE], strInt[LONINT], *idsoftwares; const char *msglog; dbi_result result; /* Toma Centro (Unidad Organizativa) y perfil software */ result = dbi_conn_queryf(dbi->conn, "SELECT idperfilsoft,numpar" " FROM ordenadores_particiones" " WHERE idordenador=%s", ido); if (!result) { dbi_conn_error(dbi->conn, &msglog); syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", __func__, __LINE__, msglog); return false; } idperfilsoft = 0; // Por defecto se supone que el ordenador no tiene aún detectado el perfil software while (dbi_result_next_row(result)) { aux = dbi_result_get_uint(result, "numpar"); if (aux == atoi(par)) { // Se encuentra la partición idperfilsoft = dbi_result_get_uint(result, "idperfilsoft"); break; } } dbi_result_free(result); wsft=escaparCadena(sft); // Codificar comillas simples if(!wsft) return false; /* Recorre componentes software*/ lon = splitCadena(tbSoftware, wsft, '\n'); if (lon == 0) return true; // No hay lineas que procesar if (lon > MAXSOFTWARE) lon = MAXSOFTWARE; // Limita el número de componentes software idnombreso = 0; for (i = 0; i < lon; i++) { // Primera línea es el sistema operativo: se obtiene identificador if (i == 0) { idnombreso = checkDato(dbi, rTrim(tbSoftware[i]), "nombresos", "nombreso", "idnombreso"); continue; } result = dbi_conn_queryf(dbi->conn, "SELECT idsoftware FROM softwares WHERE descripcion ='%s'", rTrim(tbSoftware[i])); if (!result) { dbi_conn_error(dbi->conn, &msglog); syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", __func__, __LINE__, msglog); return false; } if (!dbi_result_next_row(result)) { dbi_result_free(result); result = dbi_conn_queryf(dbi->conn, "INSERT INTO softwares (idtiposoftware,descripcion,idcentro,grupoid)" " VALUES(2,'%s',%s,0)", tbSoftware[i], idc); if (!result) { // Error al insertar dbi_conn_error(dbi->conn, &msglog); syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", __func__, __LINE__, msglog); return false; } // Recupera el identificador del software tbidsoftware[i - 1] = dbi_conn_sequence_last(dbi->conn, NULL); } else { tbidsoftware[i - 1] = dbi_result_get_uint(result, "idsoftware"); } dbi_result_free(result); } lon--; // Ordena tabla de identificadores para cosultar si existe un pefil con esas especificaciones for (i = 0; i < lon - 1; i++) { for (j = i + 1; j < lon; j++) { if (tbidsoftware[i] > tbidsoftware[j]) { aux = tbidsoftware[i]; tbidsoftware[i] = tbidsoftware[j]; tbidsoftware[j] = aux; } } } /* Crea cadena de identificadores de componentes software separados por coma */ sprintf(strInt, "%d", tbidsoftware[lon - 1]); // Pasa a cadena el último identificador que es de mayor longitud aux = strlen(strInt); // Calcula longitud de cadena para reservar espacio a todos los perfiles idsoftwares = calloc(1, (sizeof(aux)+1) * lon + lon); if (idsoftwares == NULL) { syslog(LOG_ERR, "%s:%d OOM\n", __FILE__, __LINE__); return false; } aux = sprintf(idsoftwares, "%d", tbidsoftware[0]); for (i = 1; i < lon; i++) aux += sprintf(idsoftwares + aux, ",%d", tbidsoftware[i]); // Comprueba existencia de perfil software y actualización de éste para el ordenador if (!cuestionPerfilSoftware(dbi, idc, ido, idperfilsoft, idnombreso, idsoftwares, npc, par, tbidsoftware, lon)) { syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", __func__, __LINE__, msglog); retval=false; } else { retval=true; } free(wsft); free(idsoftwares); return retval; } // ________________________________________________________________________________________________________ // Función: CuestionPerfilSoftware // // Parámetros: // - db: Objeto base de datos (ya operativo) // - tbl: Objeto tabla // - idcentro: Identificador del centro en la tabla // - ido: Identificador del ordenador del cliente en la tabla // - idnombreso: Identificador del sistema operativo // - idsoftwares: Cadena con los identificadores de componentes software separados por comas // - npc: Nombre del ordenador del cliente // - particion: Número de la partición // - tbidsoftware: Array con los identificadores de componentes software // - lon: Número de componentes // Devuelve: // true: Si el proceso es correcto // false: En caso de ocurrir algún error // // Versión 1.1.0: Se incluye el sistema operativo. Autora: Irina Gómez - ETSII Universidad Sevilla //_________________________________________________________________________________________________________ bool cuestionPerfilSoftware(struct og_dbi *dbi, char *idc, char *ido, int idperfilsoftware, int idnombreso, char *idsoftwares, char *npc, char *par, int *tbidsoftware, int lon) { int i, nwidperfilsoft; const char *msglog; dbi_result result; // Busca perfil soft del ordenador que contenga todos los componentes software encontrados result = dbi_conn_queryf(dbi->conn, "SELECT idperfilsoft FROM" " (SELECT perfilessoft_softwares.idperfilsoft as idperfilsoft," " group_concat(cast(perfilessoft_softwares.idsoftware AS char( 11) )" " ORDER BY perfilessoft_softwares.idsoftware SEPARATOR ',' ) AS idsoftwares" " FROM perfilessoft_softwares" " GROUP BY perfilessoft_softwares.idperfilsoft) AS temp" " WHERE idsoftwares LIKE '%s'", idsoftwares); if (!result) { dbi_conn_error(dbi->conn, &msglog); syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", __func__, __LINE__, msglog); return false; } if (!dbi_result_next_row(result)) { // No existe un perfil software con esos componentes de componentes software, lo crea dbi_result_free(result); result = dbi_conn_queryf(dbi->conn, "INSERT perfilessoft (descripcion, idcentro, grupoid, idnombreso)" " VALUES('Perfil Software (%s, Part:%s) ',%s,0,%i)", npc, par, idc,idnombreso); if (!result) { dbi_conn_error(dbi->conn, &msglog); syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", __func__, __LINE__, msglog); return false; } dbi_result_free(result); // Recupera el identificador del nuevo perfil software nwidperfilsoft = dbi_conn_sequence_last(dbi->conn, NULL); // Crea la relación entre perfiles y componenetes software for (i = 0; i < lon; i++) { result = dbi_conn_queryf(dbi->conn, "INSERT perfilessoft_softwares (idperfilsoft,idsoftware)" " VALUES(%d,%d)", nwidperfilsoft, tbidsoftware[i]); if (!result) { dbi_conn_error(dbi->conn, &msglog); syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", __func__, __LINE__, msglog); return false; } dbi_result_free(result); } } else { // Existe un perfil con todos esos componentes nwidperfilsoft = dbi_result_get_uint(result, "idperfilsoft"); dbi_result_free(result); } if (idperfilsoftware != nwidperfilsoft) { // No coinciden los perfiles // Actualiza el identificador del perfil software del ordenador result = dbi_conn_queryf(dbi->conn, "UPDATE ordenadores_particiones SET idperfilsoft=%d,idimagen=0" " WHERE idordenador=%s AND numpar=%s", nwidperfilsoft, ido, par); if (!result) { // Error al insertar dbi_conn_error(dbi->conn, &msglog); syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", __func__, __LINE__, msglog); return false; } dbi_result_free(result); } /* DEPURACIÓN DE PERFILES SOFTWARE */ /* Eliminar Perfiles software que quedan húerfanos */ result = dbi_conn_queryf(dbi->conn, "DELETE FROM perfilessoft WHERE idperfilsoft NOT IN" " (SELECT DISTINCT idperfilsoft from ordenadores_particiones)"\ " AND idperfilsoft NOT IN"\ " (SELECT DISTINCT idperfilsoft from imagenes)"); if (!result) { dbi_conn_error(dbi->conn, &msglog); syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", __func__, __LINE__, msglog); return false; } dbi_result_free(result), /* Eliminar Relación de softwares con Perfiles software que quedan húerfanos */ result = dbi_conn_queryf(dbi->conn, "DELETE FROM perfilessoft_softwares WHERE idperfilsoft NOT IN" " (SELECT idperfilsoft from perfilessoft)"); if (!result) { dbi_conn_error(dbi->conn, &msglog); syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", __func__, __LINE__, msglog); return false; } dbi_result_free(result); return true; }