From: Victor Julien Date: Sat, 14 Mar 2015 19:23:13 +0000 (+0100) Subject: multi-detect: add reload-tenant command X-Git-Tag: suricata-3.0RC1~202 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d8181802d375e50dff5f15a6532a20861c5b0b23;p=thirdparty%2Fsuricata.git multi-detect: add reload-tenant command Allow for a tenant to be reloaded. The command is the same as the register-tenant command, so with a yaml and tenant-id as argument. However this replaces an existing tenant. --- diff --git a/src/runmode-unix-socket.c b/src/runmode-unix-socket.c index a08a335c29..bc3e2955c3 100644 --- a/src/runmode-unix-socket.c +++ b/src/runmode-unix-socket.c @@ -655,6 +655,108 @@ TmEcode UnixSocketRegisterTenant(json_t *cmd, json_t* answer, void *data) return TM_ECODE_OK; } +static int reload_cnt = 1; +/** + * \brief Command to reload a tenant + * + * \param cmd the content of command Arguments as a json_t object + * \param answer the json_t object that has to be used to answer + * \param data pointer to data defining the context here a PcapCommand:: + */ +TmEcode UnixSocketReloadTenant(json_t *cmd, json_t* answer, void *data) +{ + const char *filename; +#ifdef OS_WIN32 + struct _stat st; +#else + struct stat st; +#endif /* OS_WIN32 */ + + if (!(DetectEngineMultiTenantEnabled())) { + SCLogInfo("error: multi-tenant support not enabled"); + json_object_set_new(answer, "message", json_string("multi-tenant support not enabled")); + return TM_ECODE_FAILED; + } + + /* 1 get tenant id */ + json_t *jarg = json_object_get(cmd, "id"); + if (!json_is_integer(jarg)) { + json_object_set_new(answer, "message", json_string("id is not an integer")); + return TM_ECODE_FAILED; + } + int tenant_id = json_integer_value(jarg); + + /* 2 get tenant yaml */ + jarg = json_object_get(cmd, "filename"); + if (!json_is_string(jarg)) { + json_object_set_new(answer, "message", json_string("command is not a string")); + return TM_ECODE_FAILED; + } + filename = json_string_value(jarg); +#ifdef OS_WIN32 + if(_stat(filename, &st) != 0) { +#else + if(stat(filename, &st) != 0) { +#endif /* OS_WIN32 */ + json_object_set_new(answer, "message", json_string("file does not exist")); + return TM_ECODE_FAILED; + } + + SCLogDebug("reload-tenant: %d %s", tenant_id, filename); + + DetectEngineCtx *old_de_ctx = DetectEngineGetByTenantId(tenant_id); + if (old_de_ctx == NULL) { + json_object_set_new(answer, "message", json_string("tenant detect engine not found")); + return TM_ECODE_FAILED; + } + + char prefix[64]; + snprintf(prefix, sizeof(prefix), "multi-detect.%d.reload.%d", tenant_id, reload_cnt); + reload_cnt++; + SCLogInfo("prefix %s", prefix); + + if (ConfYamlLoadFileWithPrefix(filename, prefix) != 0) { + json_object_set_new(answer, "message", json_string("failed to load yaml")); + return TM_ECODE_FAILED; + } + + ConfNode *node = ConfGetNode(prefix); + if (node == NULL) { + json_object_set_new(answer, "message", json_string("failed to properly setup yaml")); + return TM_ECODE_FAILED; + } + + DetectEngineCtx *new_de_ctx = DetectEngineCtxInitWithPrefix(prefix); + if (new_de_ctx == NULL) { + json_object_set_new(answer, "message", json_string("initializing detection engine failed")); + return TM_ECODE_FAILED; + } + SCLogDebug("de_ctx %p with prefix %s", new_de_ctx, new_de_ctx->config_prefix); + + new_de_ctx->tenant_id = tenant_id; + + if (SigLoadSignatures(new_de_ctx, NULL, 0) < 0) { + json_object_set_new(answer, "message", json_string("loading rules failed")); + return TM_ECODE_FAILED; + } + + DetectEngineAddToMaster(new_de_ctx); + + /* move to free list */ + DetectEngineMoveToFreeList(old_de_ctx); + DetectEngineDeReference(&old_de_ctx); + + /* apply to the running system */ + if (DetectEngineMTApply() < 0) { + json_object_set_new(answer, "message", json_string("couldn't apply settings")); + // TODO cleanup + return TM_ECODE_FAILED; + } + + json_object_set_new(answer, "message", json_string("reloading tenant succeeded")); + return TM_ECODE_OK; +} + /** * \brief Command to remove a tenant * diff --git a/src/runmode-unix-socket.h b/src/runmode-unix-socket.h index af74e51533..20b0fea496 100644 --- a/src/runmode-unix-socket.h +++ b/src/runmode-unix-socket.h @@ -35,6 +35,7 @@ void UnixSocketPcapFile(TmEcode tm); TmEcode UnixSocketRegisterTenantHandler(json_t *cmd, json_t* answer, void *data); TmEcode UnixSocketUnregisterTenantHandler(json_t *cmd, json_t* answer, void *data); TmEcode UnixSocketRegisterTenant(json_t *cmd, json_t* answer, void *data); +TmEcode UnixSocketReloadTenant(json_t *cmd, json_t* answer, void *data); TmEcode UnixSocketUnregisterTenant(json_t *cmd, json_t* answer, void *data); #endif diff --git a/src/unix-manager.c b/src/unix-manager.c index 43a7949ec0..1960df5699 100644 --- a/src/unix-manager.c +++ b/src/unix-manager.c @@ -902,6 +902,7 @@ static TmEcode UnixManager(ThreadVars *th_v, void *thread_data) UnixManagerRegisterCommand("register-tenant-handler", UnixSocketRegisterTenantHandler, &command, UNIX_CMD_TAKE_ARGS); UnixManagerRegisterCommand("unregister-tenant-handler", UnixSocketUnregisterTenantHandler, &command, UNIX_CMD_TAKE_ARGS); UnixManagerRegisterCommand("register-tenant", UnixSocketRegisterTenant, &command, UNIX_CMD_TAKE_ARGS); + UnixManagerRegisterCommand("reload-tenant", UnixSocketReloadTenant, &command, UNIX_CMD_TAKE_ARGS); UnixManagerRegisterCommand("unregister-tenant", UnixSocketUnregisterTenant, &command, UNIX_CMD_TAKE_ARGS);