diff --git a/include/common/tglobal.h b/include/common/tglobal.h index 5fd174e8737d13155a524be3a55a88e3a912fe56..4e91ed90d01db9f542a6f5da3941f15aa09633f7 100644 --- a/include/common/tglobal.h +++ b/include/common/tglobal.h @@ -102,6 +102,11 @@ extern uint16_t tsMonitorPort; extern int32_t tsMonitorMaxLogs; extern bool tsMonitorComp; +// audit +extern bool tsEnableAudit; +extern char tsAuditFqdn[]; +extern uint16_t tsAuditPort; + // telem extern bool tsEnableTelem; extern int32_t tsTelemInterval; diff --git a/include/common/tmsg.h b/include/common/tmsg.h index c6bb599a7d8d4913b61751e4c9e32da1a8c49d08..d96e7bad8cc3f9b96bfff26e437bac0593893a52 100644 --- a/include/common/tmsg.h +++ b/include/common/tmsg.h @@ -2527,6 +2527,8 @@ typedef struct SVCreateTbReq { SSchemaWrapper schemaRow; } ntb; }; + int32_t sqlLen; + char* sql; } SVCreateTbReq; int tEncodeSVCreateTbReq(SEncoder* pCoder, const SVCreateTbReq* pReq); diff --git a/include/libs/audit/audit.h b/include/libs/audit/audit.h new file mode 100644 index 0000000000000000000000000000000000000000..7785a0912d95bdf52a3bde3af45002dace6cb51b --- /dev/null +++ b/include/libs/audit/audit.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#ifndef _TD_AUDIT_H_ +#define _TD_AUDIT_H_ + +#include "tarray.h" +#include "tdef.h" +#include "tlog.h" +#include "tmsg.h" +#include "tjson.h" +#include "tmsgcb.h" +#include "trpc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + const char *server; + uint16_t port; + int32_t maxLogs; + bool comp; +} SAuditCfg; + +int32_t auditInit(const SAuditCfg *pCfg); +void auditSend(SJson *pJson); +void auditRecord(SRpcMsg *pReq, char *oper, char *db, char *stable, char *detail); + +#ifdef __cplusplus +} +#endif + +#endif /*_TD_MONITOR_H_*/ diff --git a/source/common/src/tglobal.c b/source/common/src/tglobal.c index e080c2d2ec33d2e4b62a065146493dc02e78158c..b255095331875d9808a8edf28737cb05e94e9eed 100644 --- a/source/common/src/tglobal.c +++ b/source/common/src/tglobal.c @@ -95,6 +95,11 @@ uint16_t tsMonitorPort = 6043; int32_t tsMonitorMaxLogs = 100; bool tsMonitorComp = false; +// audit +bool tsEnableAudit = false; +char tsAuditFqdn[TSDB_FQDN_LEN] = {0}; +uint16_t tsAuditPort = 6043; + // telem bool tsEnableTelem = true; int32_t tsTelemInterval = 43200; @@ -594,6 +599,10 @@ static int32_t taosAddServerCfg(SConfig *pCfg) { if (cfgAddInt32(pCfg, "monitorMaxLogs", tsMonitorMaxLogs, 1, 1000000, CFG_SCOPE_SERVER) != 0) return -1; if (cfgAddBool(pCfg, "monitorComp", tsMonitorComp, CFG_SCOPE_SERVER) != 0) return -1; + if (cfgAddBool(pCfg, "audit", tsEnableAudit, CFG_SCOPE_SERVER) != 0) return -1; + if (cfgAddString(pCfg, "auditFqdn", tsAuditFqdn, CFG_SCOPE_SERVER) != 0) return -1; + if (cfgAddInt32(pCfg, "auditPort", tsAuditPort, 1, 65056, CFG_SCOPE_SERVER) != 0) return -1; + if (cfgAddBool(pCfg, "crashReporting", tsEnableCrashReport, CFG_SCOPE_BOTH) != 0) return -1; if (cfgAddBool(pCfg, "telemetryReporting", tsEnableTelem, CFG_SCOPE_BOTH) != 0) return -1; if (cfgAddInt32(pCfg, "telemetryInterval", tsTelemInterval, 1, 200000, CFG_SCOPE_BOTH) != 0) return -1; @@ -987,6 +996,10 @@ static int32_t taosSetServerCfg(SConfig *pCfg) { tsMonitorComp = cfgGetItem(pCfg, "monitorComp")->bval; tsQueryRspPolicy = cfgGetItem(pCfg, "queryRspPolicy")->i32; + tsEnableAudit = cfgGetItem(pCfg, "audit")->bval; + tstrncpy(tsAuditFqdn, cfgGetItem(pCfg, "auditFqdn")->str, TSDB_FQDN_LEN); + tsAuditPort = (uint16_t)cfgGetItem(pCfg, "auditPort")->i32; + tsEnableTelem = cfgGetItem(pCfg, "telemetryReporting")->bval; tsEnableCrashReport = cfgGetItem(pCfg, "crashReporting")->bval; tsTtlChangeOnWrite = cfgGetItem(pCfg, "ttlChangeOnWrite")->bval; diff --git a/source/dnode/mgmt/node_mgmt/src/dmEnv.c b/source/dnode/mgmt/node_mgmt/src/dmEnv.c index a34002161d820e2f7df4551b434df568be422f8a..bbf42210865bd9980a8984cb7d54cd177ca8b8dc 100644 --- a/source/dnode/mgmt/node_mgmt/src/dmEnv.c +++ b/source/dnode/mgmt/node_mgmt/src/dmEnv.c @@ -15,6 +15,7 @@ #define _DEFAULT_SOURCE #include "dmMgmt.h" +#include "audit.h" #define STR_CASE_CMP(s, d) (0 == strcasecmp((s), (d))) #define STR_STR_CMP(s, d) (strstr((s), (d))) @@ -34,6 +35,15 @@ } \ } while (0) +#define DM_INIT_AUDIT() \ + do { \ + auditCfg.port = tsAuditPort; \ + auditCfg.server = tsAuditFqdn; \ + if (auditInit(&auditCfg) != 0) { \ + return -1; \ + } \ + } while (0) + #define DM_ERR_RTN(c) \ do { \ code = (c); \ @@ -96,6 +106,14 @@ _exit: return code; } +static int32_t dmInitAudit() { + SAuditCfg auditCfg = {0}; + + DM_INIT_AUDIT(); + + return 0; +} + static bool dmDataSpaceAvailable() { SDnode *pDnode = dmInstance(); if (pDnode->pTfs) { @@ -176,6 +194,7 @@ int32_t dmInit() { if (dmCheckRepeatInit(dmInstance()) != 0) return -1; if (dmInitSystem() != 0) return -1; if (dmInitMonitor() != 0) return -1; + if (dmInitAudit() != 0) return -1; if (dmInitDnode(dmInstance()) != 0) return -1; dInfo("dnode env is initialized"); diff --git a/source/dnode/mnode/impl/CMakeLists.txt b/source/dnode/mnode/impl/CMakeLists.txt index 010067e99f04a9cc93d0bee018dd98c8690102e7..48dc71a12b2e15e1fdca6a1dfc3c6c04f7058751 100644 --- a/source/dnode/mnode/impl/CMakeLists.txt +++ b/source/dnode/mnode/impl/CMakeLists.txt @@ -16,7 +16,7 @@ target_include_directories( PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/inc" ) target_link_libraries( - mnode scheduler sdb wal transport cjson sync monitor executor qworker stream parser + mnode scheduler sdb wal transport cjson sync monitor executor qworker stream parser audit ) IF (TD_GRANT) diff --git a/source/dnode/mnode/impl/src/mndDb.c b/source/dnode/mnode/impl/src/mndDb.c index b0e3dc43311bcb8f6cdd746a5e9dc97269632d84..e160f388595fb017683a41dab88d92452036d2b1 100644 --- a/source/dnode/mnode/impl/src/mndDb.c +++ b/source/dnode/mnode/impl/src/mndDb.c @@ -29,6 +29,9 @@ #include "mndUser.h" #include "mndVgroup.h" #include "systable.h" +#include "tjson.h" +#include "thttp.h" +#include "audit.h" #define DB_VER_NUMBER 1 #define DB_RESERVE_SIZE 46 @@ -733,6 +736,14 @@ static int32_t mndProcessCreateDbReq(SRpcMsg *pReq) { code = mndCreateDb(pMnode, pReq, &createReq, pUser); if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS; + char detail[1000] = {0}; + sprintf(detail, "dbname:%s, buffer:%d, cacheLast:%d, cacheLastSize:%d, compression:%d, " + "daysPerFile:%d, daysToKeep0:%d, daysToKeep1:%d, daysToKeep2:%d", + createReq.db, createReq.buffer, createReq.cacheLast, createReq.cacheLastSize, createReq.compression, + createReq.daysPerFile, createReq.daysToKeep0, createReq.daysToKeep1, createReq.daysToKeep2); + + auditRecord(pReq, "createDB", createReq.db, "", detail); + _OVER: if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) { mError("db:%s, failed to create since %s", createReq.db, terrstr()); @@ -975,6 +986,14 @@ static int32_t mndProcessAlterDbReq(SRpcMsg *pReq) { if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS; } + char detail[1000] = {0}; + sprintf(detail, "dbname:%s, buffer:%d, cacheLast:%d, cacheLastSize:%d, " + "daysPerFile:%d, daysToKeep0:%d, daysToKeep1:%d, daysToKeep2:%d", + alterReq.db, alterReq.buffer, alterReq.cacheLast, alterReq.cacheLastSize, + alterReq.daysPerFile, alterReq.daysToKeep0, alterReq.daysToKeep1, alterReq.daysToKeep2); + + auditRecord(pReq, "alterDB", alterReq.db, "", detail); + _OVER: if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) { if (terrno != 0) code = terrno; @@ -1264,6 +1283,11 @@ static int32_t mndProcessDropDbReq(SRpcMsg *pReq) { code = TSDB_CODE_ACTION_IN_PROGRESS; } + char detail[1000] = {0}; + sprintf(detail, "dbname:%s, ignoreNotExists:%d", dropReq.db, dropReq.ignoreNotExists); + + auditRecord(pReq, "dropDB", dropReq.db, "", detail); + _OVER: if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_ACTION_IN_PROGRESS) { mError("db:%s, failed to drop since %s", dropReq.db, terrstr()); diff --git a/source/dnode/mnode/impl/src/mndDnode.c b/source/dnode/mnode/impl/src/mndDnode.c index 39285ced5d7967f03c8155691ed10e82098dbaa9..e1264c820c76f89935539f9266ce716e7df02d4d 100644 --- a/source/dnode/mnode/impl/src/mndDnode.c +++ b/source/dnode/mnode/impl/src/mndDnode.c @@ -26,6 +26,7 @@ #include "mndVgroup.h" #include "tmisce.h" #include "mndCluster.h" +#include "audit.h" #define TSDB_DNODE_VER_NUMBER 2 #define TSDB_DNODE_RESERVE_SIZE 64 @@ -907,6 +908,13 @@ static int32_t mndProcessCreateDnodeReq(SRpcMsg *pReq) { code = mndCreateDnode(pMnode, pReq, &createReq); if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS; tsGrantHBInterval = 5; + + char detail[1000] = {0}; + sprintf(detail, "%s:%d", + createReq.fqdn, createReq.port); + + auditRecord(pReq, "createDnode", detail, "", ""); + _OVER: if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) { mError("dnode:%s:%d, failed to create since %s", createReq.fqdn, createReq.port, terrstr()); @@ -1054,6 +1062,19 @@ static int32_t mndProcessDropDnodeReq(SRpcMsg *pReq) { code = mndDropDnode(pMnode, pReq, pDnode, pMObj, pQObj, pSObj, numOfVnodes, force, dropReq.unsafe); if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS; + char detail[1000] = {0}; + + char obj1[150] = {0}; + sprintf(obj1, "%s:%d", dropReq.fqdn, dropReq.port); + + char obj2[10] = {0}; + sprintf(obj2, "%d", dropReq.dnodeId); + + sprintf(detail, "dnodeId:%d, force:%d, unsafe:%d", + dropReq.dnodeId, dropReq.force, dropReq.unsafe); + + auditRecord(pReq, "dropDnode", obj1, obj2, detail); + _OVER: if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) { mError("dnode:%d, failed to drop since %s", dropReq.dnodeId, terrstr()); diff --git a/source/dnode/mnode/impl/src/mndMnode.c b/source/dnode/mnode/impl/src/mndMnode.c index 2757578d350119268baada07e66ba9343acad0e7..930ec0bc94975380ab71642dc8d68de235cd1134 100644 --- a/source/dnode/mnode/impl/src/mndMnode.c +++ b/source/dnode/mnode/impl/src/mndMnode.c @@ -22,6 +22,7 @@ #include "mndSync.h" #include "mndTrans.h" #include "tmisce.h" +#include "audit.h" #define MNODE_VER_NUMBER 2 #define MNODE_RESERVE_SIZE 64 @@ -652,6 +653,15 @@ static int32_t mndProcessCreateMnodeReq(SRpcMsg *pReq) { code = mndCreateMnode(pMnode, pReq, pDnode, &createReq); if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS; + char detail[1000] = {0}; + + char obj[20] = {0}; + sprintf(obj, "%d", createReq.dnodeId); + + sprintf(detail, "dnodeId:%d", createReq.dnodeId); + + auditRecord(pReq, "createMnode", obj, detail, ""); + _OVER: if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) { mError("mnode:%d, failed to create since %s", createReq.dnodeId, terrstr()); @@ -788,6 +798,15 @@ static int32_t mndProcessDropMnodeReq(SRpcMsg *pReq) { code = mndDropMnode(pMnode, pReq, pObj); if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS; + char detail[1000] = {0}; + + char obj[20] = {0}; + sprintf(obj, "%d", dropReq.dnodeId); + + sprintf(detail, "dnodeId:%d", dropReq.dnodeId); + + auditRecord(pReq, "dropMnode", obj, detail, ""); + _OVER: if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) { mError("mnode:%d, failed to drop since %s", dropReq.dnodeId, terrstr()); diff --git a/source/dnode/mnode/impl/src/mndProfile.c b/source/dnode/mnode/impl/src/mndProfile.c index 524ea1a06bdec94d6f77b9fcb8dcb524b9cdc0a9..17a0e39d3f60cd85adefdedd6a1fc85bc1c65a49 100644 --- a/source/dnode/mnode/impl/src/mndProfile.c +++ b/source/dnode/mnode/impl/src/mndProfile.c @@ -25,6 +25,7 @@ #include "mndUser.h" #include "tglobal.h" #include "tversion.h" +#include "audit.h" typedef struct { uint32_t id; @@ -308,6 +309,16 @@ _CONNECT: code = 0; + char detail[1000] = {0}; + + char obj[30] = {0}; + sprintf(obj, "%s:%d", ip, pConn->port); + + sprintf(detail, "user:%s, from:%s, connType%d", + connReq.user, obj, connReq.connType); + + auditRecord(pReq, "login", connReq.app, obj, detail); + _OVER: mndReleaseUser(pMnode, pUser); diff --git a/source/dnode/mnode/impl/src/mndStb.c b/source/dnode/mnode/impl/src/mndStb.c index c3899ec43320bd45a922d38ee927c566b5bfcc0a..3589b4525a4f20d604fa18a564bf4c372b7713c3 100644 --- a/source/dnode/mnode/impl/src/mndStb.c +++ b/source/dnode/mnode/impl/src/mndStb.c @@ -31,6 +31,7 @@ #include "mndUser.h" #include "mndVgroup.h" #include "tname.h" +#include "audit.h" #define STB_VER_NUMBER 1 #define STB_RESERVE_SIZE 64 @@ -1133,6 +1134,12 @@ static int32_t mndProcessCreateStbReq(SRpcMsg *pReq) { } if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS; + char detail[1000] = {0}; + sprintf(detail, "dbname:%s, stable:%s, igExists:%d, ttl:%d", + pDb->name, createReq.name, createReq.igExists, createReq.ttl); + + auditRecord(pReq, "createStb", pDb->name, createReq.name, detail); + _OVER: if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) { mError("stb:%s, failed to create since %s", createReq.name, terrstr()); @@ -2201,6 +2208,12 @@ static int32_t mndProcessAlterStbReq(SRpcMsg *pReq) { code = mndAlterStb(pMnode, pReq, &alterReq, pDb, pStb); if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS; + char detail[1000] = {0}; + sprintf(detail, "dbname:%s, stable:%s, alterType:%d, ttl:%d", + pDb->name, alterReq.name, alterReq.alterType, alterReq.ttl); + + auditRecord(pReq, "alterStb", pDb->name, alterReq.name, detail); + _OVER: if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) { mError("stb:%s, failed to alter since %s", alterReq.name, terrstr()); @@ -2461,6 +2474,12 @@ static int32_t mndProcessDropStbReq(SRpcMsg *pReq) { code = mndDropStb(pMnode, pReq, pDb, pStb); if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS; + char detail[1000] = {0}; + sprintf(detail, "dbname:%s, stable:%s, igNotExists:%d", + pDb->name, dropReq.name, dropReq.igNotExists); + + auditRecord(pReq, "dropStb", pDb->name, dropReq.name, detail); + _OVER: if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) { mError("stb:%s, failed to drop since %s", dropReq.name, terrstr()); diff --git a/source/dnode/mnode/impl/src/mndStream.c b/source/dnode/mnode/impl/src/mndStream.c index 427a52af3b1bb6f5eec5198d4c0847a561339f92..347722284e2f0b24aad1dca89ac16c2f8d675a2a 100644 --- a/source/dnode/mnode/impl/src/mndStream.c +++ b/source/dnode/mnode/impl/src/mndStream.c @@ -27,6 +27,7 @@ #include "mndVgroup.h" #include "parser.h" #include "tname.h" +#include "audit.h" #define MND_STREAM_VER_NUMBER 3 #define MND_STREAM_RESERVE_SIZE 64 @@ -828,6 +829,12 @@ static int32_t mndProcessCreateStreamReq(SRpcMsg *pReq) { code = TSDB_CODE_ACTION_IN_PROGRESS; + char detail[1000] = {0}; + sprintf(detail, "name:%s, igExists:%d", + createStreamReq.name, createStreamReq.igExists); + + auditRecord(pReq, "createStream", createStreamReq.name, "", detail); + _OVER: if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) { mError("stream:%s, failed to create since %s", createStreamReq.name, terrstr()); @@ -1073,6 +1080,12 @@ static int32_t mndProcessDropStreamReq(SRpcMsg *pReq) { return -1; } + char detail[1000] = {0}; + sprintf(detail, "name:%s, igNotExists:%d", + dropReq.name, dropReq.igNotExists); + + auditRecord(pReq, "dropStream", dropReq.name, "", detail); + sdbRelease(pMnode->pSdb, pStream); mndTransDrop(pTrans); diff --git a/source/dnode/mnode/impl/src/mndTopic.c b/source/dnode/mnode/impl/src/mndTopic.c index 621a80338d95c60d1e271888a404de6a14aa8ad9..25f7a7d9ada0865645749b1e783e68ff8a48ce65 100644 --- a/source/dnode/mnode/impl/src/mndTopic.c +++ b/source/dnode/mnode/impl/src/mndTopic.c @@ -27,6 +27,7 @@ #include "mndVgroup.h" #include "parser.h" #include "tname.h" +#include "audit.h" #define MND_TOPIC_VER_NUMBER 3 #define MND_TOPIC_RESERVE_SIZE 64 @@ -621,6 +622,12 @@ static int32_t mndProcessCreateTopicReq(SRpcMsg *pReq) { code = TSDB_CODE_ACTION_IN_PROGRESS; } + char detail[1000] = {0}; + sprintf(detail, "subDbName:%s, subStbName:%s", + createTopicReq.subDbName, createTopicReq.subStbName); + + auditRecord(pReq, "crateTopic", createTopicReq.name, createTopicReq.subDbName, detail); + _OVER: if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) { mError("failed to create topic:%s since %s", createTopicReq.name, terrstr()); @@ -812,6 +819,12 @@ static int32_t mndProcessDropTopicReq(SRpcMsg *pReq) { return -1; } + char detail[1000] = {0}; + sprintf(detail, "name:%s, igNotExists:%d", + dropReq.name, dropReq.igNotExists); + + auditRecord(pReq, "dropTopic", dropReq.name, "", detail); + return TSDB_CODE_ACTION_IN_PROGRESS; } diff --git a/source/dnode/mnode/impl/src/mndUser.c b/source/dnode/mnode/impl/src/mndUser.c index c59d23d252163dd964018b4ba0b31af024a8acde..735e4866e234aab5fe650cf854ab061f227088de 100644 --- a/source/dnode/mnode/impl/src/mndUser.c +++ b/source/dnode/mnode/impl/src/mndUser.c @@ -22,6 +22,7 @@ #include "mndTopic.h" #include "mndTrans.h" #include "tbase64.h" +#include "audit.h" #define USER_VER_NUMBER 4 #define USER_RESERVE_SIZE 64 @@ -655,6 +656,12 @@ static int32_t mndProcessCreateUserReq(SRpcMsg *pReq) { code = mndCreateUser(pMnode, pOperUser->acct, &createReq, pReq); if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS; + char detail[1000] = {0}; + sprintf(detail, "user:%s, createType:%d", + createReq.user, createReq.createType); + + auditRecord(pReq, "createUser", createReq.user, "", detail); + _OVER: if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) { mError("user:%s, failed to create since %s", createReq.user, terrstr()); @@ -970,6 +977,12 @@ static int32_t mndProcessAlterUserReq(SRpcMsg *pReq) { code = mndAlterUser(pMnode, pUser, &newUser, pReq); if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS; + char detail[1000] = {0}; + sprintf(detail, "user:%s, objname:%s, alterType:%d", + alterReq.user, alterReq.objname, alterReq.alterType); + + auditRecord(pReq, "alterUser", alterReq.user, alterReq.objname, detail); + _OVER: if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) { mError("user:%s, failed to alter since %s", alterReq.user, terrstr()); @@ -1039,6 +1052,8 @@ static int32_t mndProcessDropUserReq(SRpcMsg *pReq) { code = mndDropUser(pMnode, pReq, pUser); if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS; + auditRecord(pReq, "dropUser", dropReq.user, "", ""); + _OVER: if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) { mError("user:%s, failed to drop since %s", dropReq.user, terrstr()); diff --git a/source/dnode/vnode/CMakeLists.txt b/source/dnode/vnode/CMakeLists.txt index c70df86e20031ddb9eee8b292f66262c214f6f13..c2b41392e80e29bf4a357414444953178d2b4e0b 100644 --- a/source/dnode/vnode/CMakeLists.txt +++ b/source/dnode/vnode/CMakeLists.txt @@ -147,6 +147,7 @@ target_link_libraries( PUBLIC executor PUBLIC scheduler PUBLIC tdb + PUBLIC audit # PUBLIC bdb # PUBLIC scalar diff --git a/source/dnode/vnode/src/vnd/vnodeSvr.c b/source/dnode/vnode/src/vnd/vnodeSvr.c index 52c36fcb1bcdce18248f9bf37fa2b26fdc7945ea..bdc104b4fdf5e0d7332bf1863ecc8f14ae31034a 100644 --- a/source/dnode/vnode/src/vnd/vnodeSvr.c +++ b/source/dnode/vnode/src/vnd/vnodeSvr.c @@ -19,6 +19,7 @@ #include "vndCos.h" #include "vnode.h" #include "vnodeInt.h" +#include "audit.h" static int32_t vnodeProcessCreateStbReq(SVnode *pVnode, int64_t ver, void *pReq, int32_t len, SRpcMsg *pRsp); static int32_t vnodeProcessAlterStbReq(SVnode *pVnode, int64_t ver, void *pReq, int32_t len, SRpcMsg *pRsp); @@ -858,6 +859,8 @@ static int32_t vnodeProcessCreateTbReq(SVnode *pVnode, int64_t ver, void *pReq, } taosArrayPush(rsp.pArray, &cRsp); + + auditRecord(pReq, "createTable", pVnode->config.dbname, pCreateReq->name, "detail"); } vDebug("vgId:%d, add %d new created tables into query table list", TD_VID(pVnode), (int32_t)taosArrayGetSize(tbUids)); diff --git a/source/libs/CMakeLists.txt b/source/libs/CMakeLists.txt index 4a95629d59ec2ce34388814f2eb2b566cfd9a2b2..9f812517c101f57aea26635ef29703d0ce7e0e2d 100644 --- a/source/libs/CMakeLists.txt +++ b/source/libs/CMakeLists.txt @@ -7,6 +7,7 @@ add_subdirectory(sync) add_subdirectory(qcom) add_subdirectory(nodes) add_subdirectory(catalog) +add_subdirectory(audit) add_subdirectory(scalar) add_subdirectory(function) diff --git a/source/libs/audit/CMakeLists.txt b/source/libs/audit/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..8d561bb98eb47c334fe06f5a50a3a992b5c34648 --- /dev/null +++ b/source/libs/audit/CMakeLists.txt @@ -0,0 +1,9 @@ +aux_source_directory(src AUDIT_SRC) +add_library(audit STATIC ${AUDIT_SRC}) +target_include_directories( + audit + PUBLIC "${TD_SOURCE_DIR}/include/libs/audit" + PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/inc" +) + +target_link_libraries(audit os util common transport) diff --git a/source/libs/audit/inc/auditInt.h b/source/libs/audit/inc/auditInt.h new file mode 100644 index 0000000000000000000000000000000000000000..b6c6ec87e88d6147a65f089549a7df1601c1cf2f --- /dev/null +++ b/source/libs/audit/inc/auditInt.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#ifndef _TD_AUDIT_INT_H_ +#define _TD_AUDIT_INT_H_ + +#include "audit.h" + +typedef struct { + SAuditCfg cfg; +} SAudit; + +#endif /*_TD_AUDIT_INT_H_*/ diff --git a/source/libs/audit/src/auditMain.c b/source/libs/audit/src/auditMain.c new file mode 100644 index 0000000000000000000000000000000000000000..976bab7626a70595c69ad7cc4eedebf0487381d2 --- /dev/null +++ b/source/libs/audit/src/auditMain.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#define _DEFAULT_SOURCE +#include "auditInt.h" +#include "taoserror.h" +#include "thttp.h" +#include "ttime.h" +#include "tjson.h" +#include "tglobal.h" + +static SAudit tsAudit = {0}; +static char* tsAuditUri = "/audit"; + +int32_t auditInit(const SAuditCfg *pCfg) { + tsAudit.cfg = *pCfg; + return 0; +} + +void auditRecord(SRpcMsg *pReq, char *oper, char *db, char *stable, char *detail) { + char *user = pReq->info.conn.user; + + if (!tsEnableAudit || tsAuditFqdn[0] == 0 || tsAuditPort == 0) return; + SJson *pJson = tjsonCreateObject(); + if (pJson == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + return; + } + + char buf[40] = {0}; + int64_t curTime = taosGetTimestampMs(); + taosFormatUtcTime(buf, sizeof(buf), curTime, TSDB_TIME_PRECISION_MILLI); + + tjsonAddStringToObject(pJson, "ts", buf); + tjsonAddStringToObject(pJson, "user", user); + tjsonAddStringToObject(pJson, "operation", oper); + tjsonAddStringToObject(pJson, "target1", db); + tjsonAddStringToObject(pJson, "target2", stable); + tjsonAddStringToObject(pJson, "detail", detail); + + auditSend(pJson); +} + +void auditSend(SJson *pJson) { + char *pCont = tjsonToString(pJson); + uDebug("audit record cont:%s\n", pCont); + if (pCont != NULL) { + EHttpCompFlag flag = tsAudit.cfg.comp ? HTTP_GZIP : HTTP_FLAT; + if (taosSendHttpReport(tsAudit.cfg.server, tsAuditUri, tsAudit.cfg.port, pCont, strlen(pCont), flag) != 0) { + uError("failed to send audit msg"); + } + taosMemoryFree(pCont); + } +}