summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am3
-rw-r--r--src/json.h6
-rw-r--r--src/legacy.c269
-rw-r--r--src/legacy.h6
-rw-r--r--src/rest.c219
-rw-r--r--src/rest.h4
6 files changed, 497 insertions, 10 deletions
diff --git a/Makefile.am b/Makefile.am
index bf93816..2dc6fbb 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -14,4 +14,5 @@ ogserver_SOURCES= src/ogAdmServer.c \
src/client.c \
src/json.c \
src/ogAdmLib.c \
- src/wol.c
+ src/wol.c \
+ src/legacy.c
diff --git a/src/json.h b/src/json.h
index 193544a..08a78d0 100644
--- a/src/json.h
+++ b/src/json.h
@@ -92,4 +92,10 @@ struct og_msg_params {
uint64_t flags;
};
+struct og_cmd_json {
+ const char *type;
+ json_t *json;
+ uint32_t flags;
+};
+
#endif
diff --git a/src/legacy.c b/src/legacy.c
new file mode 100644
index 0000000..b1f1084
--- /dev/null
+++ b/src/legacy.c
@@ -0,0 +1,269 @@
+#include <jansson.h>
+#include <netinet/in.h>
+#include <stdlib.h>
+#include <syslog.h>
+
+#include "json.h"
+#include "rest.h"
+#include "legacy.h"
+
+#define LEGACY_CMD_MAX 4096
+
+static const char *og_cmd_wol_to_legacy(struct og_cmd_json *cmd)
+{
+ char legacy_cmd[LEGACY_CMD_MAX + 1] = {};
+ const json_t *root = cmd->json;
+ const char *wol_type;
+ uint32_t type;
+ int len;
+
+ wol_type = json_string_value(json_object_get(root, "type"));
+ if (!wol_type)
+ return NULL;
+
+ if (!strcmp(wol_type, "broadcast"))
+ type = 1;
+ else
+ type = 2;
+
+ len = snprintf(legacy_cmd, sizeof(legacy_cmd), "nfn=Arrancar\rmar=%u", type);
+ if (len >= (int)sizeof(legacy_cmd))
+ return NULL;
+
+ return strdup(legacy_cmd);
+}
+
+static const char *og_cmd_poweroff_to_legacy(struct og_cmd_json *cmd)
+{
+ char legacy_cmd[LEGACY_CMD_MAX + 1] = {};
+ int len;
+
+ len = snprintf(legacy_cmd, sizeof(legacy_cmd), "nfn=Apagar");
+ if (len >= (int)sizeof(legacy_cmd))
+ return NULL;
+
+ return strdup(legacy_cmd);
+}
+
+static const char *og_cmd_reboot_to_legacy(struct og_cmd_json *cmd)
+{
+ char legacy_cmd[LEGACY_CMD_MAX + 1] = {};
+ int len;
+
+ len = snprintf(legacy_cmd, sizeof(legacy_cmd), "nfn=Reiniciar");
+ if (len >= (int)sizeof(legacy_cmd))
+ return NULL;
+
+ return strdup(legacy_cmd);
+}
+
+static const char *og_cmd_session_to_legacy(struct og_cmd_json *cmd)
+{
+ char legacy_cmd[LEGACY_CMD_MAX + 1] = {};
+ const json_t *root = cmd->json;
+ const char *dsk, *par;
+ int len;
+
+ dsk = json_string_value(json_object_get(root, "disk"));
+ if (!dsk)
+ return NULL;
+ par = json_string_value(json_object_get(root, "part"));
+ if (!par)
+ return NULL;
+
+ len = snprintf(legacy_cmd, sizeof(legacy_cmd),
+ "nfn=IniciarSesion\rdsk=%s\rpar=%s",
+ dsk, par);
+ if (len >= (int)sizeof(legacy_cmd))
+ return NULL;
+
+ return strdup(legacy_cmd);
+}
+
+static const char *og_cmd_software_to_legacy(struct og_cmd_json *cmd)
+{
+ char legacy_cmd[LEGACY_CMD_MAX + 1] = {};
+ const json_t *root = cmd->json;
+ const char *dsk, *par;
+ int len;
+
+ dsk = json_string_value(json_object_get(root, "disk"));
+ if (!dsk)
+ return NULL;
+ par = json_string_value(json_object_get(root, "partition"));
+ if (!par)
+ return NULL;
+
+ len = snprintf(legacy_cmd, sizeof(legacy_cmd),
+ "nfn=InventarioSoftware\rdsk=%s\rpar=%s",
+ dsk, par);
+ if (len >= (int)sizeof(legacy_cmd))
+ return NULL;
+
+ return strdup(legacy_cmd);
+}
+
+static const char *og_cmd_hardware_to_legacy(struct og_cmd_json *cmd)
+{
+ char legacy_cmd[LEGACY_CMD_MAX + 1] = {};
+ int len;
+
+ len = snprintf(legacy_cmd, sizeof(legacy_cmd),
+ "nfn=InventarioHardware");
+ if (len >= (int)sizeof(legacy_cmd))
+ return NULL;
+
+ return strdup(legacy_cmd);
+}
+
+static const char *og_cmd_shell_run_to_legacy(struct og_cmd_json *cmd)
+{
+ const json_t *root = cmd->json;
+ char legacy_cmd[LEGACY_CMD_MAX + 1] = {};
+ const char *scp;
+ int len;
+
+ scp = json_string_value(json_object_get(root, "run"));
+ if (!scp)
+ return NULL;
+
+ len = snprintf(legacy_cmd, sizeof(legacy_cmd),
+ "nfn=EjecutarScript\rscp=%s", scp);
+ if (len >= (int)sizeof(legacy_cmd)) {
+ syslog(LOG_ERR, "script payload too large (%s:%d)\n",
+ __func__, __LINE__);
+ return NULL;
+ }
+
+ return strdup(legacy_cmd);
+}
+
+static char *og_cmd_image_create_to_legacy(struct og_cmd_json *cmd)
+{
+ char legacy_cmd[LEGACY_CMD_MAX + 1] = {};
+ struct og_msg_params params = {};
+ json_t *root = cmd->json;
+ int len;
+
+ if (og_json_parse_create_image(root, &params) < 0)
+ return NULL;
+
+ len = snprintf(legacy_cmd, sizeof(legacy_cmd),
+ "nfn=CrearImagen\rdsk=%s\rpar=%s\rcpt=%s\ridi=%s\rnci=%s\ripr=%s",
+ params.disk, params.partition, params.code, params.id,
+ params.name, params.repository);
+ if (len >= (int)sizeof(legacy_cmd))
+ return NULL;
+
+ return strdup(legacy_cmd);
+}
+
+static const char *og_cmd_image_restore_to_legacy(struct og_cmd_json *cmd)
+{
+ char legacy_cmd[LEGACY_CMD_MAX + 1] = {};
+ struct og_msg_params params = {};
+ json_t *root = cmd->json;
+ int len;
+
+ if (og_json_parse_restore_image(root, &params) < 0)
+ return NULL;
+
+ len = snprintf(legacy_cmd, sizeof(legacy_cmd),
+ "nfn=RestaurarImagen\rdsk=%s\rpar=%s\ridi=%s\rnci=%s\ripr=%s\rifs=%s\rptc=%s",
+ params.disk, params.partition, params.id, params.name,
+ params.repository, params.profile, params.type);
+ if (len >= (int)sizeof(legacy_cmd)) {
+ return NULL;
+ }
+
+ return strdup(legacy_cmd);
+}
+
+static const char *og_cmd_setup_to_legacy(struct og_cmd_json *cmd)
+{
+ char legacy_cmd[LEGACY_CMD_MAX + 1] = {};
+ uint32_t bufsiz = sizeof(legacy_cmd);
+ const char *dsk, *ttp, *che, *tch;
+ struct og_msg_params params = {};
+ json_t *partition_setup, *value;
+ const json_t *root = cmd->json;
+ uint32_t consumed = 0;
+ size_t index;
+ int len;
+
+ dsk = json_string_value(json_object_get(root, "disk"));
+ if (!dsk)
+ return NULL;
+ ttp = json_string_value(json_object_get(root, "type"));
+ if (!ttp)
+ return NULL;
+ che = json_string_value(json_object_get(root, "cache"));
+ if (!che)
+ return NULL;
+ tch = json_string_value(json_object_get(root, "cache_size"));
+ if (!tch)
+ return NULL;
+
+ len = snprintf(legacy_cmd + consumed, bufsiz, "nfn=Configurar\rttp=%s\rdsk=%s\rcfg=dis=%s*che=%s*tch=%s!",
+ ttp, dsk, dsk, che, tch);
+ if (len >= bufsiz)
+ return NULL;
+ consumed += len;
+ if (consumed < bufsiz)
+ bufsiz -= len;
+
+ partition_setup = json_object_get(root, "partition_setup");
+ if (!partition_setup)
+ return NULL;
+ if (og_json_parse_partition_setup(partition_setup, &params) < 0)
+ return NULL;
+
+ json_array_foreach(partition_setup, index, value) {
+ len = snprintf(legacy_cmd + consumed, bufsiz, "par=%s*cpt=%s*sfi=%s*tam=%s*ope=%s%%",
+ params.partition_setup[index].number,
+ params.partition_setup[index].code,
+ params.partition_setup[index].filesystem,
+ params.partition_setup[index].size,
+ params.partition_setup[index].format);
+ if (len >= bufsiz)
+ return NULL;
+ consumed += len;
+ if (consumed < bufsiz)
+ bufsiz -= len;
+ }
+
+ return strdup(legacy_cmd);
+}
+
+const char *og_msg_params_to_legacy(struct og_cmd_json *cmd)
+{
+ const char *legacy_cmd = NULL;
+
+ if (!strncmp(cmd->type, "wol", strlen("wol")))
+ legacy_cmd = og_cmd_wol_to_legacy(cmd);
+ else if (!strncmp(cmd->type, "poweroff", strlen("poweroff")))
+ legacy_cmd = og_cmd_poweroff_to_legacy(cmd);
+ else if (!strncmp(cmd->type, "reboot", strlen("reboot")))
+ legacy_cmd = og_cmd_reboot_to_legacy(cmd);
+ else if (!strncmp(cmd->type, "session", strlen("session")))
+ legacy_cmd = og_cmd_session_to_legacy(cmd);
+ else if (!strncmp(cmd->type, "software", strlen("software")))
+ legacy_cmd = og_cmd_software_to_legacy(cmd);
+ else if (!strncmp(cmd->type, "hardware", strlen("hardware")))
+ legacy_cmd = og_cmd_hardware_to_legacy(cmd);
+ else if (!strncmp(cmd->type, "run", strlen("run")))
+ legacy_cmd = og_cmd_shell_run_to_legacy(cmd);
+ else if (!strncmp(cmd->type, "image_create", strlen("image_create")))
+ legacy_cmd = og_cmd_image_create_to_legacy(cmd);
+ else if (!strncmp(cmd->type, "image_restore", strlen("image_restore")))
+ legacy_cmd = og_cmd_image_restore_to_legacy(cmd);
+ else if (!strncmp(cmd->type, "setup", strlen("setup")))
+ legacy_cmd = og_cmd_setup_to_legacy(cmd);
+
+ if (!legacy_cmd) {
+ syslog(LOG_ERR, "failed to translate command %s (%s:%d)\n",
+ cmd->type, __func__, __LINE__);
+ }
+
+ return legacy_cmd;
+}
diff --git a/src/legacy.h b/src/legacy.h
new file mode 100644
index 0000000..d72963c
--- /dev/null
+++ b/src/legacy.h
@@ -0,0 +1,6 @@
+#ifndef _OG_LEGACY_H
+#define _OG_LEGACY_H
+
+const char *og_msg_params_to_legacy(struct og_cmd_json *cmd);
+
+#endif
diff --git a/src/rest.c b/src/rest.c
index e9eb7ca..feeb306 100644
--- a/src/rest.c
+++ b/src/rest.c
@@ -15,6 +15,7 @@
#include "wol.h"
#include "cfg.h"
#include "schedule.h"
+#include "legacy.h"
#include <ev.h>
#include <syslog.h>
#include <sys/ioctl.h>
@@ -162,8 +163,7 @@ static int og_json_parse_clients(json_t *element, struct og_msg_params *params)
return 0;
}
-static int og_json_parse_partition_setup(json_t *element,
- struct og_msg_params *params)
+int og_json_parse_partition_setup(json_t *element, struct og_msg_params *params)
{
unsigned int i;
json_t *k;
@@ -2041,12 +2041,11 @@ static int og_cmd_images(char *buffer_reply)
return 0;
}
-static int og_cmd_create_image(json_t *element, struct og_msg_params *params)
+int og_json_parse_create_image(json_t *element,
+ struct og_msg_params *params)
{
- char new_image_id[OG_DB_INT_MAXLEN + 1];
struct og_image image = {};
- json_t *value, *clients;
- struct og_dbi *dbi;
+ json_t *value;
const char *key;
int err = 0;
@@ -2088,6 +2087,21 @@ static int og_cmd_create_image(json_t *element, struct og_msg_params *params)
return err;
}
+ return 0;
+}
+
+static int og_cmd_create_image(json_t *element, struct og_msg_params *params)
+{
+ char new_image_id[OG_DB_INT_MAXLEN + 1];
+ struct og_image image = {};
+ struct og_dbi *dbi;
+ json_t *clients;
+ int err = 0;
+
+ err = og_json_parse_create_image(element, params);
+ if (err < 0)
+ return err;
+
if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
OG_REST_PARAM_DISK |
OG_REST_PARAM_PARTITION |
@@ -2126,10 +2140,10 @@ static int og_cmd_create_image(json_t *element, struct og_msg_params *params)
clients);
}
-static int og_cmd_restore_image(json_t *element, struct og_msg_params *params)
+int og_json_parse_restore_image(json_t *element, struct og_msg_params *params)
{
- json_t *clients, *value;
const char *key;
+ json_t *value;
int err = 0;
if (json_typeof(element) != JSON_OBJECT)
@@ -2165,6 +2179,18 @@ static int og_cmd_restore_image(json_t *element, struct og_msg_params *params)
return err;
}
+ return 0;
+}
+
+static int og_cmd_restore_image(json_t *element, struct og_msg_params *params)
+{
+ json_t *clients;
+ int err = 0;
+
+ err = og_json_parse_restore_image(element, params);
+ if (err < 0)
+ return err;
+
if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
OG_REST_PARAM_DISK |
OG_REST_PARAM_PARTITION |
@@ -2953,7 +2979,7 @@ static int og_dbi_queue_command(struct og_dbi *dbi, uint32_t task_id,
result = dbi_conn_queryf(dbi->conn,
"SELECT idaccion, idcentro, idordenador, parametros "
"FROM acciones "
- "WHERE sesion = %u", task_id);
+ "WHERE idaccion = %u", task_id);
if (!result) {
dbi_conn_error(dbi->conn, &msglog);
syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
@@ -4282,6 +4308,168 @@ static int og_cmd_post_room_delete(json_t *element,
return 0;
}
+enum {
+ OG_SCHEDULE_CMD_TYPE = 0,
+ OG_SCHEDULE_CMD_PARAMS,
+};
+
+static bool og_cmd_validate(const struct og_cmd_json *cmd,
+ const uint64_t flags)
+{
+ return (cmd->flags & flags) == flags;
+}
+
+
+static int og_cmd_post_schedule_command(json_t *element,
+ struct og_msg_params *params)
+{
+ char *centerid_query = "SELECT o.idordenador, c.idcentro "
+ "FROM `ordenadores` AS o "
+ "INNER JOIN aulas AS a ON o.idaula = a.idaula "
+ "INNER JOIN centros AS c ON a.idcentro = c.idcentro "
+ "WHERE o.ip = '%s';";
+ int center_id, client_id, len;
+ struct og_cmd_json cmd = {};
+ const char *legacy_params;
+ const char *key, *msglog;
+ struct og_dbi *dbi;
+ char task_id[128];
+ uint32_t sequence;
+ bool when = false;
+ dbi_result result;
+ json_t *value;
+ int err = 0, i;
+
+ json_object_foreach(element, key, value) {
+ if (!strcmp(key, "clients")) {
+ err = og_json_parse_clients(value, params);
+ } else if (!strcmp(key, "command")) {
+ err = og_json_parse_string(value, &cmd.type);
+ cmd.flags |= OG_SCHEDULE_CMD_TYPE;
+ } else if (!strcmp(key, "params")) {
+ cmd.json = value;
+ cmd.flags |= OG_SCHEDULE_CMD_PARAMS;
+ } else if (!strcmp(key, "when")) {
+ err = og_json_parse_time_params(value, params);
+ when = true;
+ }
+
+ if (err < 0)
+ return err;
+ }
+
+ if (!og_cmd_validate(&cmd, OG_SCHEDULE_CMD_TYPE |
+ OG_SCHEDULE_CMD_PARAMS))
+ return -1;
+
+ if (!when) {
+ params->time.check_stale = false;
+ og_schedule_time_now(&params->time);
+ params->flags |= OG_REST_PARAM_TIME_YEARS |
+ OG_REST_PARAM_TIME_MONTHS |
+ OG_REST_PARAM_TIME_WEEKS |
+ OG_REST_PARAM_TIME_WEEK_DAYS |
+ OG_REST_PARAM_TIME_DAYS |
+ OG_REST_PARAM_TIME_HOURS |
+ OG_REST_PARAM_TIME_AM_PM |
+ OG_REST_PARAM_TIME_MINUTES;
+ } else {
+ params->time.check_stale = true;
+ }
+
+ if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
+ OG_REST_PARAM_TIME_YEARS |
+ OG_REST_PARAM_TIME_MONTHS |
+ OG_REST_PARAM_TIME_WEEKS |
+ OG_REST_PARAM_TIME_WEEK_DAYS |
+ OG_REST_PARAM_TIME_DAYS |
+ OG_REST_PARAM_TIME_HOURS |
+ OG_REST_PARAM_TIME_MINUTES |
+ OG_REST_PARAM_TIME_AM_PM))
+ return -1;
+
+ params->type = "command";
+ dbi = og_dbi_open(&ogconfig.db);
+ if (!dbi) {
+ syslog(LOG_ERR, "cannot open conection database (%s:%d)\n",
+ __func__, __LINE__);
+ goto err_dbi_open;
+ }
+
+ legacy_params = og_msg_params_to_legacy(&cmd);
+ if (!legacy_params)
+ goto err_legacy_params;
+
+ /* ips_array -> ids */
+ for (i = 0; i < params->ips_array_len; i++) {
+
+ result = dbi_conn_queryf(dbi->conn, centerid_query, params->ips_array[i]);
+ if (!result) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ goto err_dbi_result;
+ }
+ if (dbi_result_get_numrows(result) != 1) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "client not found (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ goto err_dbi;
+ }
+
+ if (!dbi_result_next_row(result)) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to get idcentro (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ goto err_dbi;
+ }
+ center_id = dbi_result_get_uint(result, "idcentro");
+ if (!center_id) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to get idcentro (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ goto err_dbi;
+ }
+ client_id = dbi_result_get_uint(result, "idordenador");
+ dbi_result_free(result);
+
+ result = dbi_conn_queryf(dbi->conn, "INSERT INTO acciones (idordenador, "
+ "idcentro, parametros)"
+ "VALUES (%d, %d, '%s')",
+ client_id, center_id, legacy_params);
+ if (!result) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ goto err_dbi_result;
+ }
+ dbi_result_free(result);
+
+ sequence = dbi_conn_sequence_last(dbi->conn, NULL);
+ len = snprintf(task_id, sizeof(sequence), "%d", sequence);
+ if (len >= (int)sizeof(task_id)) {
+ syslog(LOG_ERR, "truncated snprintf (%s:%d)\n",
+ __func__, __LINE__);
+ goto err_dbi;
+ }
+ params->task_id = task_id;
+ og_task_schedule_create(params);
+ }
+
+ free((char *)legacy_params);
+ og_dbi_close(dbi);
+ return 0;
+
+err_dbi:
+ dbi_result_free(result);
+err_dbi_result:
+ free((char *)legacy_params);
+err_legacy_params:
+ og_dbi_close(dbi);
+err_dbi_open:
+ return -1;
+}
+
static int og_client_method_not_found(struct og_client *cli)
{
/* To meet RFC 7231, this function MUST generate an Allow header field
@@ -4823,6 +5011,19 @@ int og_client_state_process_payload_rest(struct og_client *cli)
goto err_process_rest_payload;
}
err = og_cmd_post_procedure_add(root, &params);
+ } else if (!strncmp(cmd, "schedule/command", strlen("schedule/command"))) {
+ if (method != OG_METHOD_POST) {
+ err = og_client_method_not_found(cli);
+ goto err_process_rest_payload;
+ }
+
+ if (!root) {
+ syslog(LOG_ERR,
+ "command schedule action with no payload\n");
+ err = og_client_bad_request(cli);
+ goto err_process_rest_payload;
+ }
+ err = og_cmd_post_schedule_command(root, &params);
} else {
syslog(LOG_ERR, "unknown command: %.32s ...\n", cmd);
err = og_client_not_found(cli);
diff --git a/src/rest.h b/src/rest.h
index 43ddd66..508a234 100644
--- a/src/rest.h
+++ b/src/rest.h
@@ -94,4 +94,8 @@ struct og_cmd {
const struct og_cmd *og_cmd_find(const char *client_ip);
void og_cmd_free(const struct og_cmd *cmd);
+int og_json_parse_partition_setup(json_t *element, struct og_msg_params *params);
+int og_json_parse_create_image(json_t *element, struct og_msg_params *params);
+int og_json_parse_restore_image(json_t *element, struct og_msg_params *params);
+
#endif