From 1b87d8dad7fb59a3aff677660c9b9a0651e68b44 Mon Sep 17 00:00:00 2001 From: shenglian zhou Date: Fri, 8 Sep 2023 19:04:14 +0800 Subject: [PATCH 1/9] enhance: add hb whitelist version and notify taosadapter --- include/client/taos.h | 1 + include/common/tmsg.h | 2 ++ source/client/inc/clientInt.h | 7 +++++++ source/client/src/clientHb.c | 13 +++++++++++++ source/client/src/clientMsgHandler.c | 1 + source/common/src/tmsg.c | 13 ++++++++++++- source/dnode/mnode/impl/src/mndPrivilege.c | 2 ++ source/dnode/mnode/impl/src/mndProfile.c | 1 + 8 files changed, 39 insertions(+), 1 deletion(-) diff --git a/include/client/taos.h b/include/client/taos.h index 5b7946c9ad..dfa6ff43ec 100644 --- a/include/client/taos.h +++ b/include/client/taos.h @@ -125,6 +125,7 @@ typedef enum { typedef enum { TAOS_NOTIFY_PASSVER = 0, + TAOS_NOTIFY_WHITELIST_VER = 1 } TAOS_NOTIFY_TYPE; #define RET_MSG_LENGTH 1024 diff --git a/include/common/tmsg.h b/include/common/tmsg.h index 38d142c800..9d0bcfdab2 100644 --- a/include/common/tmsg.h +++ b/include/common/tmsg.h @@ -849,6 +849,7 @@ typedef struct { int32_t authVer; char sVer[TSDB_VERSION_LEN]; char sDetailVer[128]; + int64_t whiteListVer; } SConnectRsp; int32_t tSerializeSConnectRsp(void* buf, int32_t bufLen, SConnectRsp* pRsp); @@ -965,6 +966,7 @@ typedef struct { SHashObj* readTbs; SHashObj* writeTbs; SHashObj* useDbs; + int64_t whiteListVer; } SGetUserAuthRsp; int32_t tSerializeSGetUserAuthRsp(void* buf, int32_t bufLen, SGetUserAuthRsp* pRsp); diff --git a/source/client/inc/clientInt.h b/source/client/inc/clientInt.h index aa7caaaba3..9448634c5b 100644 --- a/source/client/inc/clientInt.h +++ b/source/client/inc/clientInt.h @@ -135,6 +135,12 @@ typedef struct { __taos_notify_fn_t fp; } SPassInfo; +typedef struct { + int64_t ver; + void* param; + __taos_notify_fn_t fp; +} SWhiteListInfo; + typedef struct STscObj { char user[TSDB_USER_LEN]; char pass[TSDB_PASSWORD_LEN]; @@ -152,6 +158,7 @@ typedef struct STscObj { SAppInstInfo* pAppInfo; SHashObj* pRequests; SPassInfo passInfo; + SWhiteListInfo whiteListInfo; } STscObj; typedef struct STscDbg { diff --git a/source/client/src/clientHb.c b/source/client/src/clientHb.c index 54e3a6ee48..e64f0d779c 100644 --- a/source/client/src/clientHb.c +++ b/source/client/src/clientHb.c @@ -116,6 +116,19 @@ static int32_t hbUpdateUserAuthInfo(SAppHbMgr *pAppHbMgr, SUserAuthBatchRsp *bat atomic_load_32(&passInfo->ver), pTscObj->id); } } + + if (pTscObj->whiteListInfo.fp) { + SWhiteListInfo *whiteListInfo = &pTscObj->whiteListInfo; + int64_t oldVer = atomic_load_64(&whiteListInfo->ver); + if (oldVer < pRsp->whiteListVer) { + atomic_store_64(&whiteListInfo->ver, pRsp->whiteListVer); + if (whiteListInfo->fp) { + (*whiteListInfo->fp)(whiteListInfo->param, &pRsp->whiteListVer, TAOS_NOTIFY_WHITELIST_VER); + } + tscDebug("update whitelist version of user %s from %"PRId64" to %"PRId64", tscRid:%" PRIi64, pRsp->user, oldVer, + atomic_load_64(&whiteListInfo->ver), pTscObj->id); + } + } releaseTscObj(pReq->connKey.tscRid); } } diff --git a/source/client/src/clientMsgHandler.c b/source/client/src/clientMsgHandler.c index 9f9809b227..8027a61b8f 100644 --- a/source/client/src/clientMsgHandler.c +++ b/source/client/src/clientMsgHandler.c @@ -139,6 +139,7 @@ int32_t processConnectRsp(void* param, SDataBuf* pMsg, int32_t code) { pTscObj->connType = connectRsp.connType; pTscObj->passInfo.ver = connectRsp.passVer; pTscObj->authVer = connectRsp.authVer; + pTscObj->whiteListInfo.ver = connectRsp.whiteListVer; hbRegisterConn(pTscObj->pAppInfo->pAppHbMgr, pTscObj->id, connectRsp.clusterId, connectRsp.connType); diff --git a/source/common/src/tmsg.c b/source/common/src/tmsg.c index 974e5e73dc..fe0b37c325 100644 --- a/source/common/src/tmsg.c +++ b/source/common/src/tmsg.c @@ -1721,7 +1721,7 @@ int32_t tSerializeSGetUserAuthRspImpl(SEncoder *pEncoder, SGetUserAuthRsp *pRsp) // since 3.0.7.0 if (tEncodeI32(pEncoder, pRsp->passVer) < 0) return -1; - + if (tEncodeI64(pEncoder, pRsp->whiteListVer) < 0) return -1; return 0; } @@ -1853,6 +1853,11 @@ int32_t tDeserializeSGetUserAuthRspImpl(SDecoder *pDecoder, SGetUserAuthRsp *pRs } else { pRsp->passVer = 0; } + if (!tDecodeIsEnd(pDecoder)) { + if (tDecodeI64(pDecoder, &pRsp->whiteListVer) < 0) goto _err; + } else { + pRsp->whiteListVer = 0; + } } return 0; _err: @@ -4357,6 +4362,7 @@ int32_t tSerializeSConnectRsp(void *buf, int32_t bufLen, SConnectRsp *pRsp) { if (tEncodeCStr(&encoder, pRsp->sDetailVer) < 0) return -1; if (tEncodeI32(&encoder, pRsp->passVer) < 0) return -1; if (tEncodeI32(&encoder, pRsp->authVer) < 0) return -1; + if (tEncodeI64(&encoder, pRsp->whiteListVer) < 0) return -1; tEndEncode(&encoder); int32_t tlen = encoder.pos; @@ -4393,6 +4399,11 @@ int32_t tDeserializeSConnectRsp(void *buf, int32_t bufLen, SConnectRsp *pRsp) { pRsp->authVer = 0; } + if (!tDecodeIsEnd(&decoder)) { + if (tDecodeI64(&decoder, &pRsp->whiteListVer) < 0) return -1; + } else { + pRsp->whiteListVer = 0; + } tEndDecode(&decoder); tDecoderClear(&decoder); diff --git a/source/dnode/mnode/impl/src/mndPrivilege.c b/source/dnode/mnode/impl/src/mndPrivilege.c index bec516b1ee..fa2be36bef 100644 --- a/source/dnode/mnode/impl/src/mndPrivilege.c +++ b/source/dnode/mnode/impl/src/mndPrivilege.c @@ -39,6 +39,8 @@ int32_t mndSetUserAuthRsp(SMnode *pMnode, SUserObj *pUser, SGetUserAuthRsp *pRsp pRsp->sysInfo = pUser->sysInfo; pRsp->version = pUser->authVersion; pRsp->passVer = pUser->passVersion; + pRsp->whiteListVer = mndGetIpWhiteVer(pMnode); + //TODO: mndSetUserAuthRsp in enterprise version return 0; } #endif \ No newline at end of file diff --git a/source/dnode/mnode/impl/src/mndProfile.c b/source/dnode/mnode/impl/src/mndProfile.c index 9847024bee..0a3e6c616a 100644 --- a/source/dnode/mnode/impl/src/mndProfile.c +++ b/source/dnode/mnode/impl/src/mndProfile.c @@ -290,6 +290,7 @@ _CONNECT: connectRsp.svrTimestamp = taosGetTimestampSec(); connectRsp.passVer = pUser->passVersion; connectRsp.authVer = pUser->authVersion; + connectRsp.whiteListVer = mndGetIpWhiteVer(pMnode); strcpy(connectRsp.sVer, version); snprintf(connectRsp.sDetailVer, sizeof(connectRsp.sDetailVer), "ver:%s\nbuild:%s\ngitinfo:%s", version, buildinfo, From 569283f806c40de1d9f2fa6c4eab4221449707cd Mon Sep 17 00:00:00 2001 From: shenglian zhou Date: Fri, 8 Sep 2023 19:04:14 +0800 Subject: [PATCH 2/9] enhance: add hb whitelist version and notify taosadapter --- include/client/taos.h | 1 + include/common/tmsg.h | 2 ++ source/client/inc/clientInt.h | 7 +++++++ source/client/src/clientHb.c | 13 +++++++++++++ source/client/src/clientMsgHandler.c | 1 + source/common/src/tmsg.c | 13 ++++++++++++- source/dnode/mnode/impl/src/mndPrivilege.c | 2 ++ source/dnode/mnode/impl/src/mndProfile.c | 1 + 8 files changed, 39 insertions(+), 1 deletion(-) diff --git a/include/client/taos.h b/include/client/taos.h index 5b7946c9ad..dfa6ff43ec 100644 --- a/include/client/taos.h +++ b/include/client/taos.h @@ -125,6 +125,7 @@ typedef enum { typedef enum { TAOS_NOTIFY_PASSVER = 0, + TAOS_NOTIFY_WHITELIST_VER = 1 } TAOS_NOTIFY_TYPE; #define RET_MSG_LENGTH 1024 diff --git a/include/common/tmsg.h b/include/common/tmsg.h index 38d142c800..9d0bcfdab2 100644 --- a/include/common/tmsg.h +++ b/include/common/tmsg.h @@ -849,6 +849,7 @@ typedef struct { int32_t authVer; char sVer[TSDB_VERSION_LEN]; char sDetailVer[128]; + int64_t whiteListVer; } SConnectRsp; int32_t tSerializeSConnectRsp(void* buf, int32_t bufLen, SConnectRsp* pRsp); @@ -965,6 +966,7 @@ typedef struct { SHashObj* readTbs; SHashObj* writeTbs; SHashObj* useDbs; + int64_t whiteListVer; } SGetUserAuthRsp; int32_t tSerializeSGetUserAuthRsp(void* buf, int32_t bufLen, SGetUserAuthRsp* pRsp); diff --git a/source/client/inc/clientInt.h b/source/client/inc/clientInt.h index aa7caaaba3..9448634c5b 100644 --- a/source/client/inc/clientInt.h +++ b/source/client/inc/clientInt.h @@ -135,6 +135,12 @@ typedef struct { __taos_notify_fn_t fp; } SPassInfo; +typedef struct { + int64_t ver; + void* param; + __taos_notify_fn_t fp; +} SWhiteListInfo; + typedef struct STscObj { char user[TSDB_USER_LEN]; char pass[TSDB_PASSWORD_LEN]; @@ -152,6 +158,7 @@ typedef struct STscObj { SAppInstInfo* pAppInfo; SHashObj* pRequests; SPassInfo passInfo; + SWhiteListInfo whiteListInfo; } STscObj; typedef struct STscDbg { diff --git a/source/client/src/clientHb.c b/source/client/src/clientHb.c index 54e3a6ee48..e64f0d779c 100644 --- a/source/client/src/clientHb.c +++ b/source/client/src/clientHb.c @@ -116,6 +116,19 @@ static int32_t hbUpdateUserAuthInfo(SAppHbMgr *pAppHbMgr, SUserAuthBatchRsp *bat atomic_load_32(&passInfo->ver), pTscObj->id); } } + + if (pTscObj->whiteListInfo.fp) { + SWhiteListInfo *whiteListInfo = &pTscObj->whiteListInfo; + int64_t oldVer = atomic_load_64(&whiteListInfo->ver); + if (oldVer < pRsp->whiteListVer) { + atomic_store_64(&whiteListInfo->ver, pRsp->whiteListVer); + if (whiteListInfo->fp) { + (*whiteListInfo->fp)(whiteListInfo->param, &pRsp->whiteListVer, TAOS_NOTIFY_WHITELIST_VER); + } + tscDebug("update whitelist version of user %s from %"PRId64" to %"PRId64", tscRid:%" PRIi64, pRsp->user, oldVer, + atomic_load_64(&whiteListInfo->ver), pTscObj->id); + } + } releaseTscObj(pReq->connKey.tscRid); } } diff --git a/source/client/src/clientMsgHandler.c b/source/client/src/clientMsgHandler.c index 9f9809b227..8027a61b8f 100644 --- a/source/client/src/clientMsgHandler.c +++ b/source/client/src/clientMsgHandler.c @@ -139,6 +139,7 @@ int32_t processConnectRsp(void* param, SDataBuf* pMsg, int32_t code) { pTscObj->connType = connectRsp.connType; pTscObj->passInfo.ver = connectRsp.passVer; pTscObj->authVer = connectRsp.authVer; + pTscObj->whiteListInfo.ver = connectRsp.whiteListVer; hbRegisterConn(pTscObj->pAppInfo->pAppHbMgr, pTscObj->id, connectRsp.clusterId, connectRsp.connType); diff --git a/source/common/src/tmsg.c b/source/common/src/tmsg.c index 974e5e73dc..fe0b37c325 100644 --- a/source/common/src/tmsg.c +++ b/source/common/src/tmsg.c @@ -1721,7 +1721,7 @@ int32_t tSerializeSGetUserAuthRspImpl(SEncoder *pEncoder, SGetUserAuthRsp *pRsp) // since 3.0.7.0 if (tEncodeI32(pEncoder, pRsp->passVer) < 0) return -1; - + if (tEncodeI64(pEncoder, pRsp->whiteListVer) < 0) return -1; return 0; } @@ -1853,6 +1853,11 @@ int32_t tDeserializeSGetUserAuthRspImpl(SDecoder *pDecoder, SGetUserAuthRsp *pRs } else { pRsp->passVer = 0; } + if (!tDecodeIsEnd(pDecoder)) { + if (tDecodeI64(pDecoder, &pRsp->whiteListVer) < 0) goto _err; + } else { + pRsp->whiteListVer = 0; + } } return 0; _err: @@ -4357,6 +4362,7 @@ int32_t tSerializeSConnectRsp(void *buf, int32_t bufLen, SConnectRsp *pRsp) { if (tEncodeCStr(&encoder, pRsp->sDetailVer) < 0) return -1; if (tEncodeI32(&encoder, pRsp->passVer) < 0) return -1; if (tEncodeI32(&encoder, pRsp->authVer) < 0) return -1; + if (tEncodeI64(&encoder, pRsp->whiteListVer) < 0) return -1; tEndEncode(&encoder); int32_t tlen = encoder.pos; @@ -4393,6 +4399,11 @@ int32_t tDeserializeSConnectRsp(void *buf, int32_t bufLen, SConnectRsp *pRsp) { pRsp->authVer = 0; } + if (!tDecodeIsEnd(&decoder)) { + if (tDecodeI64(&decoder, &pRsp->whiteListVer) < 0) return -1; + } else { + pRsp->whiteListVer = 0; + } tEndDecode(&decoder); tDecoderClear(&decoder); diff --git a/source/dnode/mnode/impl/src/mndPrivilege.c b/source/dnode/mnode/impl/src/mndPrivilege.c index bec516b1ee..fa2be36bef 100644 --- a/source/dnode/mnode/impl/src/mndPrivilege.c +++ b/source/dnode/mnode/impl/src/mndPrivilege.c @@ -39,6 +39,8 @@ int32_t mndSetUserAuthRsp(SMnode *pMnode, SUserObj *pUser, SGetUserAuthRsp *pRsp pRsp->sysInfo = pUser->sysInfo; pRsp->version = pUser->authVersion; pRsp->passVer = pUser->passVersion; + pRsp->whiteListVer = mndGetIpWhiteVer(pMnode); + //TODO: mndSetUserAuthRsp in enterprise version return 0; } #endif \ No newline at end of file diff --git a/source/dnode/mnode/impl/src/mndProfile.c b/source/dnode/mnode/impl/src/mndProfile.c index 9847024bee..0a3e6c616a 100644 --- a/source/dnode/mnode/impl/src/mndProfile.c +++ b/source/dnode/mnode/impl/src/mndProfile.c @@ -290,6 +290,7 @@ _CONNECT: connectRsp.svrTimestamp = taosGetTimestampSec(); connectRsp.passVer = pUser->passVersion; connectRsp.authVer = pUser->authVersion; + connectRsp.whiteListVer = mndGetIpWhiteVer(pMnode); strcpy(connectRsp.sVer, version); snprintf(connectRsp.sDetailVer, sizeof(connectRsp.sDetailVer), "ver:%s\nbuild:%s\ngitinfo:%s", version, buildinfo, From 9da204e5ff2b39bed6de62972e74e4b3ac151948 Mon Sep 17 00:00:00 2001 From: shenglian zhou Date: Mon, 11 Sep 2023 17:04:35 +0800 Subject: [PATCH 3/9] enhance: update notification and get user whitelist api --- include/client/taos.h | 3 + include/common/tmsg.h | 28 +++++++- include/common/tmsgdef.h | 1 + source/client/src/clientMain.c | 98 +++++++++++++++++++++++++++ source/common/src/tmsg.c | 68 +++++++++++++++++++ source/dnode/mnode/impl/src/mndUser.c | 57 ++++++++++++++++ 6 files changed, 252 insertions(+), 3 deletions(-) diff --git a/include/client/taos.h b/include/client/taos.h index dfa6ff43ec..252081bb0a 100644 --- a/include/client/taos.h +++ b/include/client/taos.h @@ -237,6 +237,9 @@ DLL_EXPORT void taos_set_hb_quit(int8_t quitByKill); DLL_EXPORT int taos_set_notify_cb(TAOS *taos, __taos_notify_fn_t fp, void *param, int type); +typedef void (*__taos_async_whitelist_fn_t)(void *param, int code, TAOS *taos, int numOfWhiteLists, uint64_t* pWhiteLists); +DLL_EXPORT void taos_fetch_whitelist_a(TAOS *taos, __taos_async_whitelist_fn_t fp, void *param); + /* --------------------------schemaless INTERFACE------------------------------- */ DLL_EXPORT TAOS_RES *taos_schemaless_insert(TAOS *taos, char *lines[], int numLines, int protocol, int precision); diff --git a/include/common/tmsg.h b/include/common/tmsg.h index 9d0bcfdab2..fbe7b45a68 100644 --- a/include/common/tmsg.h +++ b/include/common/tmsg.h @@ -876,9 +876,14 @@ typedef struct { int32_t tSerializeSDropUserReq(void* buf, int32_t bufLen, SDropUserReq* pReq); int32_t tDeserializeSDropUserReq(void* buf, int32_t bufLen, SDropUserReq* pReq); -typedef struct SIpV4Range { - uint32_t ip; - uint32_t mask; +typedef union { + struct { + uint64_t ip_mask; + }; + struct { + uint32_t ip; + uint32_t mask; + }; } SIpV4Range; typedef struct { @@ -973,6 +978,23 @@ int32_t tSerializeSGetUserAuthRsp(void* buf, int32_t bufLen, SGetUserAuthRsp* pR int32_t tDeserializeSGetUserAuthRsp(void* buf, int32_t bufLen, SGetUserAuthRsp* pRsp); void tFreeSGetUserAuthRsp(SGetUserAuthRsp* pRsp); +typedef struct { + char user[TSDB_USER_LEN]; +} SGetUserWhiteListReq; + +int32_t tSerializeSGetUserWhiteListReq(void* buf, int32_t bufLen, SGetUserWhiteListReq* pReq); +int32_t tDeserializeSGetUserWhiteListReq(void* buf, int32_t bufLen, SGetUserWhiteListReq* pReq); + +typedef struct { + char user[TSDB_USER_LEN]; + int32_t numWhiteLists; + SIpV4Range* pWhiteLists; +} SGetUserWhiteListRsp; + +int32_t tSerializeSGetUserWhiteListRsp(void* buf, int32_t bufLen, SGetUserWhiteListRsp* pRsp); +int32_t tDeserializeSGetUserWhiteListRsp(void* buf, int32_t bufLen, SGetUserWhiteListRsp* pRsp); +void tFreeSGetUserWhiteListRsp(SGetUserWhiteListRsp* pRsp); + /* * for client side struct, only column id, type, bytes are necessary * But for data in vnode side, we need all the following information. diff --git a/include/common/tmsgdef.h b/include/common/tmsgdef.h index 5abe45ac01..dd9a1af67c 100644 --- a/include/common/tmsgdef.h +++ b/include/common/tmsgdef.h @@ -178,6 +178,7 @@ enum { // WARN: new msg should be appended to segment tail TD_DEF_MSG_TYPE(TDMT_MND_TMQ_LOST_CONSUMER_CLEAR, "lost-consumer-clear", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_STREAM_HEARTBEAT, "stream-heartbeat", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_RETRIEVE_IP_WHITE, "retrieve-ip-white", NULL, NULL) + TD_DEF_MSG_TYPE(TDMT_MND_GET_USER_WHITELIST, "get-user-whitelist", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_MAX_MSG, "mnd-max", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_BALANCE_VGROUP_LEADER, "balance-vgroup-leader", NULL, NULL) diff --git a/source/client/src/clientMain.c b/source/client/src/clientMain.c index 73b4ec2a74..9db1c72e04 100644 --- a/source/client/src/clientMain.c +++ b/source/client/src/clientMain.c @@ -140,6 +140,13 @@ int taos_set_notify_cb(TAOS *taos, __taos_notify_fn_t fp, void *param, int type) taosThreadMutexUnlock(&pObj->mutex); break; } + case TAOS_NOTIFY_WHITELIST_VER: { + taosThreadMutexLock(&pObj->mutex); + pObj->whiteListInfo.fp = fp; + pObj->whiteListInfo.param = param; + taosThreadMutexUnlock(&pObj->mutex); + break; + } default: { terrno = TSDB_CODE_INVALID_PARA; releaseTscObj(*(int64_t *)taos); @@ -151,6 +158,97 @@ int taos_set_notify_cb(TAOS *taos, __taos_notify_fn_t fp, void *param, int type) return 0; } +typedef struct SFetchWhiteListInfo{ + int64_t connId; + __taos_async_whitelist_fn_t userCbFn; + void* userParam; +} SFetchWhiteListInfo; + +int32_t fetchWhiteListCallbackFn(void* param, SDataBuf* pMsg, int32_t code) { + SFetchWhiteListInfo* pInfo = (SFetchWhiteListInfo*)param; + TAOS* taos = &pInfo->connId; + if (code != TSDB_CODE_SUCCESS) { + pInfo->userCbFn(pInfo->userParam, code, taos, 0, NULL); + taosMemoryFree(pMsg->pData); + taosMemoryFree(pMsg->pEpSet); + taosMemoryFree(pInfo); + return code; + } + + SGetUserWhiteListRsp *pRsp = pMsg->pData; + pInfo->userCbFn(pInfo->userParam, code, taos, pRsp->numWhiteLists, &pRsp->pWhiteLists->ip_mask); + + taosMemoryFree(pMsg->pData); + taosMemoryFree(pMsg->pEpSet); + taosMemoryFree(pInfo); + return code; +} + +void taos_fetch_whitelist_a(TAOS *taos, __taos_async_whitelist_fn_t fp, void *param) { + if (NULL == taos) { + fp(param, TSDB_CODE_INVALID_PARA, taos, 0, NULL); + return; + } + + int64_t connId = *(int64_t*)taos; + + STscObj *pTsc = acquireTscObj(connId); + if (NULL == pTsc) { + fp(param, TSDB_CODE_TSC_DISCONNECTED, taos, 0, NULL); + return; + } + + SGetUserWhiteListReq req; + memcpy(req.user, pTsc->user, TSDB_USER_LEN); + int32_t msgLen = tSerializeSGetUserWhiteListReq(NULL, 0, &req); + void* pReq = taosMemoryMalloc(msgLen); + if (pReq == NULL) { + fp(param, TSDB_CODE_OUT_OF_MEMORY, taos, 0, NULL); + releaseTscObj(connId); + return; + } + + if (tSerializeSGetUserWhiteListReq(pReq, msgLen, &req) < 0) { + fp(param, TSDB_CODE_INVALID_PARA, taos, 0, NULL); + taosMemoryFree(pReq); + releaseTscObj(connId); + return; + } + + SFetchWhiteListInfo* pParam = taosMemoryMalloc(sizeof(SFetchWhiteListInfo)); + if (pParam == NULL) { + fp(param, TSDB_CODE_OUT_OF_MEMORY, taos, 0, NULL); + taosMemoryFree(pReq); + releaseTscObj(connId); + return; + } + + pParam->connId = connId; + pParam->userCbFn = fp; + pParam->userParam = param; + SMsgSendInfo* pSendInfo = taosMemoryCalloc(1, sizeof(SMsgSendInfo)); + if (pSendInfo == NULL) { + fp(param, TSDB_CODE_OUT_OF_MEMORY, taos, 0, NULL); + taosMemoryFree(pParam); + taosMemoryFree(pReq); + releaseTscObj(connId); + return; + } + + pSendInfo->msgInfo = (SDataBuf){.pData = pReq, .len = msgLen, .handle = NULL}; + pSendInfo->requestId = generateRequestId(); + pSendInfo->requestObjRefId = 0; + pSendInfo->param = pParam; + pSendInfo->fp = fetchWhiteListCallbackFn; + pSendInfo->msgType = TDMT_MND_GET_USER_WHITELIST; + + int64_t transportId = 0; + SEpSet epSet = getEpSet_s(&pTsc->pAppInfo->mgmtEp); + asyncSendMsgToServer(pTsc->pAppInfo->pTransporter, &epSet, &transportId, pSendInfo); + releaseTscObj(connId); + return; +} + void taos_close_internal(void *taos) { if (taos == NULL) { return; diff --git a/source/common/src/tmsg.c b/source/common/src/tmsg.c index fe0b37c325..f59feeff5e 100644 --- a/source/common/src/tmsg.c +++ b/source/common/src/tmsg.c @@ -1426,6 +1426,7 @@ int32_t tDeserializeSCreateUserReq(void *buf, int32_t bufLen, SCreateUserReq *pR } tEndDecode(&decoder); + tDecoderClear(&decoder); return 0; } @@ -1896,6 +1897,73 @@ void tFreeSGetUserAuthRsp(SGetUserAuthRsp *pRsp) { taosHashCleanup(pRsp->useDbs); } +int32_t tSerializeSGetWhiteListReq(void *buf, int32_t bufLen, SGetUserWhiteListReq *pReq) { + SEncoder encoder = {0}; + tEncoderInit(&encoder, buf, bufLen); + + if (tStartEncode(&encoder) < 0) return -1; + if (tEncodeCStr(&encoder, pReq->user) < 0) return -1; + tEndEncode(&encoder); + + int32_t tlen = encoder.pos; + tEncoderClear(&encoder); + return tlen; +} + +int32_t tDeserializeSGetUserWhiteListReq(void *buf, int32_t bufLen, SGetUserWhiteListReq *pReq) { + SDecoder decoder = {0}; + tDecoderInit(&decoder, buf, bufLen); + + if (tStartDecode(&decoder) < 0) return -1; + if (tDecodeCStrTo(&decoder, pReq->user) < 0) return -1; + tEndDecode(&decoder); + + tDecoderClear(&decoder); + return 0; +} + +int32_t tSerializeSGetUserWhiteListRsp(void* buf, int32_t bufLen, SGetUserWhiteListRsp* pRsp) { + SEncoder encoder = {0}; + tEncoderInit(&encoder, buf, bufLen); + + if (tStartEncode(&encoder) < 0) return -1; + if (tEncodeCStr(&encoder, pRsp->user) < 0) return -1; + if (tEncodeI32(&encoder, pRsp->numWhiteLists) < 0) return -1; + for (int i = 0; i < pRsp->numWhiteLists; ++i) { + if (tEncodeU32(&encoder, pRsp->pWhiteLists[i].ip) < 0) return -1; + if (tEncodeU32(&encoder, pRsp->pWhiteLists[i].mask) < 0) return -1; + } + tEndEncode(&encoder); + + int32_t tlen = encoder.pos; + tEncoderClear(&encoder); + return tlen; +} + +int32_t tDeserializeSGetUserWhiteListRsp(void* buf, int32_t bufLen, SGetUserWhiteListRsp* pRsp) { + SDecoder decoder = {0}; + tDecoderInit(&decoder, buf, bufLen); + + if (tStartDecode(&decoder) < 0) return -1; + if (tDecodeCStrTo(&decoder, pRsp->user) < 0) return -1; + + if (tDecodeI32(&decoder, &pRsp->numWhiteLists) < 0) return -1; + pRsp->pWhiteLists = taosMemoryMalloc(pRsp->numWhiteLists * sizeof(SIpV4Range)); + if (pRsp->pWhiteLists == NULL) return -1; + for (int32_t i = 0; i < pRsp->numWhiteLists; ++i) { + if (tDecodeU32(&decoder, &(pRsp->pWhiteLists[i].ip)) < 0) return -1; + if (tDecodeU32(&decoder, &(pRsp->pWhiteLists[i].mask)) < 0) return -1; + } + + tEndDecode(&decoder); + tDecoderClear(&decoder); + return 0; +} + +void tFreeSGetUserWhiteListRsp(SGetUserWhiteListRsp* pRsp) { + taosMemoryFree(pRsp->pWhiteLists); +} + int32_t tSerializeSCreateDropMQSNodeReq(void *buf, int32_t bufLen, SMCreateQnodeReq *pReq) { SEncoder encoder = {0}; tEncoderInit(&encoder, buf, bufLen); diff --git a/source/dnode/mnode/impl/src/mndUser.c b/source/dnode/mnode/impl/src/mndUser.c index 01aae39fae..ea9c0efd1d 100644 --- a/source/dnode/mnode/impl/src/mndUser.c +++ b/source/dnode/mnode/impl/src/mndUser.c @@ -49,6 +49,7 @@ static int32_t mndProcessCreateUserReq(SRpcMsg *pReq); static int32_t mndProcessAlterUserReq(SRpcMsg *pReq); static int32_t mndProcessDropUserReq(SRpcMsg *pReq); static int32_t mndProcessGetUserAuthReq(SRpcMsg *pReq); +static int32_t mndProcessGetUserWhiteListReq(SRpcMsg *pReq); static int32_t mndRetrieveUsers(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows); static void mndCancelGetNextUser(SMnode *pMnode, void *pIter); static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows); @@ -387,6 +388,8 @@ int32_t mndInitUser(SMnode *pMnode) { mndSetMsgHandle(pMnode, TDMT_MND_ALTER_USER, mndProcessAlterUserReq); mndSetMsgHandle(pMnode, TDMT_MND_DROP_USER, mndProcessDropUserReq); mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_AUTH, mndProcessGetUserAuthReq); + mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_WHITELIST, mndProcessGetUserWhiteListReq); + mndSetMsgHandle(pMnode, TDMT_MND_RETRIEVE_IP_WHITE, mndProcesSRetrieveIpWhiteReq); mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_USER, mndRetrieveUsers); @@ -1178,6 +1181,60 @@ _OVER: tFreeSCreateUserReq(&createReq); return code; } + +//TODO: this is enterpise version, or shared version between enterprise and community? +static int32_t mndSetUserWhiteListRsp(SMnode* pMnode, SUserObj* pUser, SGetUserWhiteListRsp* pWhiteListRsp) { + memcpy(pWhiteListRsp->user, pUser->user, TSDB_USER_LEN); + pWhiteListRsp->numWhiteLists = pUser->pIpWhiteList->num; + pWhiteListRsp->pWhiteLists = taosMemoryMalloc(pWhiteListRsp->numWhiteLists * sizeof(SIpV4Range)); + if (pWhiteListRsp->pWhiteLists == NULL) { + return TSDB_CODE_OUT_OF_MEMORY; + } + memcpy(pUser->pIpWhiteList->pIpRange, pUser->pIpWhiteList->pIpRange, pWhiteListRsp->numWhiteLists * sizeof(SIpV4Range)); + return 0; +} + +int32_t mndProcessGetUserWhiteListReq(SRpcMsg *pReq) { + SMnode *pMnode = pReq->info.node; + int32_t code = -1; + SUserObj *pUser = NULL; + SGetUserWhiteListReq wlReq = {0}; + SGetUserWhiteListRsp wlRsp = {0}; + + if (tDeserializeSGetUserWhiteListReq(pReq->pCont, pReq->contLen, &wlReq) != 0) { + terrno = TSDB_CODE_INVALID_MSG; + goto _OVER; + } + mTrace("user: %s, start to get whitelist", wlReq.user); + + pUser = mndAcquireUser(pMnode, wlReq.user); + if (pUser == NULL) { + terrno = TSDB_CODE_MND_USER_NOT_EXIST; + goto _OVER; + } + + code = mndSetUserWhiteListRsp(pMnode, pUser, &wlRsp); + if (code) { + goto _OVER; + } + int32_t contLen = tSerializeSGetUserWhiteListRsp(NULL, 0, &wlRsp); + void *pRsp = rpcMallocCont(contLen); + if (pRsp == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + goto _OVER; + } + + tSerializeSGetUserWhiteListRsp(pRsp, contLen, &wlRsp); + + pReq->info.rsp = pRsp; + pReq->info.rspLen = contLen; + code = 0; +_OVER: + mndReleaseUser(pMnode, pUser); + tFreeSGetUserWhiteListRsp(&wlRsp); + return code; +} + int32_t mndProcesSRetrieveIpWhiteReq(SRpcMsg *pReq) { // impl later SRetrieveIpWhiteReq req = {0}; From 64caae83fd386d377abd3760bbedaaea5e929f95 Mon Sep 17 00:00:00 2001 From: shenglian zhou Date: Fri, 8 Sep 2023 19:04:14 +0800 Subject: [PATCH 4/9] enhance: add hb whitelist version and notify taosadapter --- include/client/taos.h | 1 + include/common/tmsg.h | 2 ++ source/client/inc/clientInt.h | 7 +++++++ source/client/src/clientHb.c | 13 +++++++++++++ source/client/src/clientMsgHandler.c | 1 + source/common/src/tmsg.c | 13 ++++++++++++- source/dnode/mnode/impl/src/mndPrivilege.c | 2 ++ source/dnode/mnode/impl/src/mndProfile.c | 1 + 8 files changed, 39 insertions(+), 1 deletion(-) diff --git a/include/client/taos.h b/include/client/taos.h index 5b7946c9ad..dfa6ff43ec 100644 --- a/include/client/taos.h +++ b/include/client/taos.h @@ -125,6 +125,7 @@ typedef enum { typedef enum { TAOS_NOTIFY_PASSVER = 0, + TAOS_NOTIFY_WHITELIST_VER = 1 } TAOS_NOTIFY_TYPE; #define RET_MSG_LENGTH 1024 diff --git a/include/common/tmsg.h b/include/common/tmsg.h index 44c0b41784..ff3d07ae13 100644 --- a/include/common/tmsg.h +++ b/include/common/tmsg.h @@ -849,6 +849,7 @@ typedef struct { int32_t authVer; char sVer[TSDB_VERSION_LEN]; char sDetailVer[128]; + int64_t whiteListVer; } SConnectRsp; int32_t tSerializeSConnectRsp(void* buf, int32_t bufLen, SConnectRsp* pRsp); @@ -965,6 +966,7 @@ typedef struct { SHashObj* readTbs; SHashObj* writeTbs; SHashObj* useDbs; + int64_t whiteListVer; } SGetUserAuthRsp; int32_t tSerializeSGetUserAuthRsp(void* buf, int32_t bufLen, SGetUserAuthRsp* pRsp); diff --git a/source/client/inc/clientInt.h b/source/client/inc/clientInt.h index aa7caaaba3..9448634c5b 100644 --- a/source/client/inc/clientInt.h +++ b/source/client/inc/clientInt.h @@ -135,6 +135,12 @@ typedef struct { __taos_notify_fn_t fp; } SPassInfo; +typedef struct { + int64_t ver; + void* param; + __taos_notify_fn_t fp; +} SWhiteListInfo; + typedef struct STscObj { char user[TSDB_USER_LEN]; char pass[TSDB_PASSWORD_LEN]; @@ -152,6 +158,7 @@ typedef struct STscObj { SAppInstInfo* pAppInfo; SHashObj* pRequests; SPassInfo passInfo; + SWhiteListInfo whiteListInfo; } STscObj; typedef struct STscDbg { diff --git a/source/client/src/clientHb.c b/source/client/src/clientHb.c index 54e3a6ee48..e64f0d779c 100644 --- a/source/client/src/clientHb.c +++ b/source/client/src/clientHb.c @@ -116,6 +116,19 @@ static int32_t hbUpdateUserAuthInfo(SAppHbMgr *pAppHbMgr, SUserAuthBatchRsp *bat atomic_load_32(&passInfo->ver), pTscObj->id); } } + + if (pTscObj->whiteListInfo.fp) { + SWhiteListInfo *whiteListInfo = &pTscObj->whiteListInfo; + int64_t oldVer = atomic_load_64(&whiteListInfo->ver); + if (oldVer < pRsp->whiteListVer) { + atomic_store_64(&whiteListInfo->ver, pRsp->whiteListVer); + if (whiteListInfo->fp) { + (*whiteListInfo->fp)(whiteListInfo->param, &pRsp->whiteListVer, TAOS_NOTIFY_WHITELIST_VER); + } + tscDebug("update whitelist version of user %s from %"PRId64" to %"PRId64", tscRid:%" PRIi64, pRsp->user, oldVer, + atomic_load_64(&whiteListInfo->ver), pTscObj->id); + } + } releaseTscObj(pReq->connKey.tscRid); } } diff --git a/source/client/src/clientMsgHandler.c b/source/client/src/clientMsgHandler.c index 9f9809b227..8027a61b8f 100644 --- a/source/client/src/clientMsgHandler.c +++ b/source/client/src/clientMsgHandler.c @@ -139,6 +139,7 @@ int32_t processConnectRsp(void* param, SDataBuf* pMsg, int32_t code) { pTscObj->connType = connectRsp.connType; pTscObj->passInfo.ver = connectRsp.passVer; pTscObj->authVer = connectRsp.authVer; + pTscObj->whiteListInfo.ver = connectRsp.whiteListVer; hbRegisterConn(pTscObj->pAppInfo->pAppHbMgr, pTscObj->id, connectRsp.clusterId, connectRsp.connType); diff --git a/source/common/src/tmsg.c b/source/common/src/tmsg.c index 4d58335944..06a088a8ec 100644 --- a/source/common/src/tmsg.c +++ b/source/common/src/tmsg.c @@ -1730,7 +1730,7 @@ int32_t tSerializeSGetUserAuthRspImpl(SEncoder *pEncoder, SGetUserAuthRsp *pRsp) // since 3.0.7.0 if (tEncodeI32(pEncoder, pRsp->passVer) < 0) return -1; - + if (tEncodeI64(pEncoder, pRsp->whiteListVer) < 0) return -1; return 0; } @@ -1862,6 +1862,11 @@ int32_t tDeserializeSGetUserAuthRspImpl(SDecoder *pDecoder, SGetUserAuthRsp *pRs } else { pRsp->passVer = 0; } + if (!tDecodeIsEnd(pDecoder)) { + if (tDecodeI64(pDecoder, &pRsp->whiteListVer) < 0) goto _err; + } else { + pRsp->whiteListVer = 0; + } } return 0; _err: @@ -4366,6 +4371,7 @@ int32_t tSerializeSConnectRsp(void *buf, int32_t bufLen, SConnectRsp *pRsp) { if (tEncodeCStr(&encoder, pRsp->sDetailVer) < 0) return -1; if (tEncodeI32(&encoder, pRsp->passVer) < 0) return -1; if (tEncodeI32(&encoder, pRsp->authVer) < 0) return -1; + if (tEncodeI64(&encoder, pRsp->whiteListVer) < 0) return -1; tEndEncode(&encoder); int32_t tlen = encoder.pos; @@ -4402,6 +4408,11 @@ int32_t tDeserializeSConnectRsp(void *buf, int32_t bufLen, SConnectRsp *pRsp) { pRsp->authVer = 0; } + if (!tDecodeIsEnd(&decoder)) { + if (tDecodeI64(&decoder, &pRsp->whiteListVer) < 0) return -1; + } else { + pRsp->whiteListVer = 0; + } tEndDecode(&decoder); tDecoderClear(&decoder); diff --git a/source/dnode/mnode/impl/src/mndPrivilege.c b/source/dnode/mnode/impl/src/mndPrivilege.c index e5cc1fde5e..25b59f4a9a 100644 --- a/source/dnode/mnode/impl/src/mndPrivilege.c +++ b/source/dnode/mnode/impl/src/mndPrivilege.c @@ -40,6 +40,8 @@ int32_t mndSetUserAuthRsp(SMnode *pMnode, SUserObj *pUser, SGetUserAuthRsp *pRsp pRsp->sysInfo = pUser->sysInfo; pRsp->version = pUser->authVersion; pRsp->passVer = pUser->passVersion; + pRsp->whiteListVer = mndGetIpWhiteVer(pMnode); + //TODO: mndSetUserAuthRsp in enterprise version return 0; } diff --git a/source/dnode/mnode/impl/src/mndProfile.c b/source/dnode/mnode/impl/src/mndProfile.c index 9847024bee..0a3e6c616a 100644 --- a/source/dnode/mnode/impl/src/mndProfile.c +++ b/source/dnode/mnode/impl/src/mndProfile.c @@ -290,6 +290,7 @@ _CONNECT: connectRsp.svrTimestamp = taosGetTimestampSec(); connectRsp.passVer = pUser->passVersion; connectRsp.authVer = pUser->authVersion; + connectRsp.whiteListVer = mndGetIpWhiteVer(pMnode); strcpy(connectRsp.sVer, version); snprintf(connectRsp.sDetailVer, sizeof(connectRsp.sDetailVer), "ver:%s\nbuild:%s\ngitinfo:%s", version, buildinfo, From 8db96a0085b111358c03b5a9995e6ad4ea4d4141 Mon Sep 17 00:00:00 2001 From: shenglian zhou Date: Mon, 11 Sep 2023 17:04:35 +0800 Subject: [PATCH 5/9] enhance: update notification and get user whitelist api --- include/client/taos.h | 3 + include/common/tmsg.h | 28 +++++++- include/common/tmsgdef.h | 1 + source/client/src/clientMain.c | 98 +++++++++++++++++++++++++++ source/common/src/tmsg.c | 68 +++++++++++++++++++ source/dnode/mnode/impl/src/mndUser.c | 57 ++++++++++++++++ 6 files changed, 252 insertions(+), 3 deletions(-) diff --git a/include/client/taos.h b/include/client/taos.h index dfa6ff43ec..252081bb0a 100644 --- a/include/client/taos.h +++ b/include/client/taos.h @@ -237,6 +237,9 @@ DLL_EXPORT void taos_set_hb_quit(int8_t quitByKill); DLL_EXPORT int taos_set_notify_cb(TAOS *taos, __taos_notify_fn_t fp, void *param, int type); +typedef void (*__taos_async_whitelist_fn_t)(void *param, int code, TAOS *taos, int numOfWhiteLists, uint64_t* pWhiteLists); +DLL_EXPORT void taos_fetch_whitelist_a(TAOS *taos, __taos_async_whitelist_fn_t fp, void *param); + /* --------------------------schemaless INTERFACE------------------------------- */ DLL_EXPORT TAOS_RES *taos_schemaless_insert(TAOS *taos, char *lines[], int numLines, int protocol, int precision); diff --git a/include/common/tmsg.h b/include/common/tmsg.h index ff3d07ae13..2dd4af3441 100644 --- a/include/common/tmsg.h +++ b/include/common/tmsg.h @@ -876,9 +876,14 @@ typedef struct { int32_t tSerializeSDropUserReq(void* buf, int32_t bufLen, SDropUserReq* pReq); int32_t tDeserializeSDropUserReq(void* buf, int32_t bufLen, SDropUserReq* pReq); -typedef struct SIpV4Range { - uint32_t ip; - uint32_t mask; +typedef union { + struct { + uint64_t ip_mask; + }; + struct { + uint32_t ip; + uint32_t mask; + }; } SIpV4Range; typedef struct { @@ -973,6 +978,23 @@ int32_t tSerializeSGetUserAuthRsp(void* buf, int32_t bufLen, SGetUserAuthRsp* pR int32_t tDeserializeSGetUserAuthRsp(void* buf, int32_t bufLen, SGetUserAuthRsp* pRsp); void tFreeSGetUserAuthRsp(SGetUserAuthRsp* pRsp); +typedef struct { + char user[TSDB_USER_LEN]; +} SGetUserWhiteListReq; + +int32_t tSerializeSGetUserWhiteListReq(void* buf, int32_t bufLen, SGetUserWhiteListReq* pReq); +int32_t tDeserializeSGetUserWhiteListReq(void* buf, int32_t bufLen, SGetUserWhiteListReq* pReq); + +typedef struct { + char user[TSDB_USER_LEN]; + int32_t numWhiteLists; + SIpV4Range* pWhiteLists; +} SGetUserWhiteListRsp; + +int32_t tSerializeSGetUserWhiteListRsp(void* buf, int32_t bufLen, SGetUserWhiteListRsp* pRsp); +int32_t tDeserializeSGetUserWhiteListRsp(void* buf, int32_t bufLen, SGetUserWhiteListRsp* pRsp); +void tFreeSGetUserWhiteListRsp(SGetUserWhiteListRsp* pRsp); + /* * for client side struct, only column id, type, bytes are necessary * But for data in vnode side, we need all the following information. diff --git a/include/common/tmsgdef.h b/include/common/tmsgdef.h index 5abe45ac01..dd9a1af67c 100644 --- a/include/common/tmsgdef.h +++ b/include/common/tmsgdef.h @@ -178,6 +178,7 @@ enum { // WARN: new msg should be appended to segment tail TD_DEF_MSG_TYPE(TDMT_MND_TMQ_LOST_CONSUMER_CLEAR, "lost-consumer-clear", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_STREAM_HEARTBEAT, "stream-heartbeat", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_RETRIEVE_IP_WHITE, "retrieve-ip-white", NULL, NULL) + TD_DEF_MSG_TYPE(TDMT_MND_GET_USER_WHITELIST, "get-user-whitelist", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_MAX_MSG, "mnd-max", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_BALANCE_VGROUP_LEADER, "balance-vgroup-leader", NULL, NULL) diff --git a/source/client/src/clientMain.c b/source/client/src/clientMain.c index 73b4ec2a74..9db1c72e04 100644 --- a/source/client/src/clientMain.c +++ b/source/client/src/clientMain.c @@ -140,6 +140,13 @@ int taos_set_notify_cb(TAOS *taos, __taos_notify_fn_t fp, void *param, int type) taosThreadMutexUnlock(&pObj->mutex); break; } + case TAOS_NOTIFY_WHITELIST_VER: { + taosThreadMutexLock(&pObj->mutex); + pObj->whiteListInfo.fp = fp; + pObj->whiteListInfo.param = param; + taosThreadMutexUnlock(&pObj->mutex); + break; + } default: { terrno = TSDB_CODE_INVALID_PARA; releaseTscObj(*(int64_t *)taos); @@ -151,6 +158,97 @@ int taos_set_notify_cb(TAOS *taos, __taos_notify_fn_t fp, void *param, int type) return 0; } +typedef struct SFetchWhiteListInfo{ + int64_t connId; + __taos_async_whitelist_fn_t userCbFn; + void* userParam; +} SFetchWhiteListInfo; + +int32_t fetchWhiteListCallbackFn(void* param, SDataBuf* pMsg, int32_t code) { + SFetchWhiteListInfo* pInfo = (SFetchWhiteListInfo*)param; + TAOS* taos = &pInfo->connId; + if (code != TSDB_CODE_SUCCESS) { + pInfo->userCbFn(pInfo->userParam, code, taos, 0, NULL); + taosMemoryFree(pMsg->pData); + taosMemoryFree(pMsg->pEpSet); + taosMemoryFree(pInfo); + return code; + } + + SGetUserWhiteListRsp *pRsp = pMsg->pData; + pInfo->userCbFn(pInfo->userParam, code, taos, pRsp->numWhiteLists, &pRsp->pWhiteLists->ip_mask); + + taosMemoryFree(pMsg->pData); + taosMemoryFree(pMsg->pEpSet); + taosMemoryFree(pInfo); + return code; +} + +void taos_fetch_whitelist_a(TAOS *taos, __taos_async_whitelist_fn_t fp, void *param) { + if (NULL == taos) { + fp(param, TSDB_CODE_INVALID_PARA, taos, 0, NULL); + return; + } + + int64_t connId = *(int64_t*)taos; + + STscObj *pTsc = acquireTscObj(connId); + if (NULL == pTsc) { + fp(param, TSDB_CODE_TSC_DISCONNECTED, taos, 0, NULL); + return; + } + + SGetUserWhiteListReq req; + memcpy(req.user, pTsc->user, TSDB_USER_LEN); + int32_t msgLen = tSerializeSGetUserWhiteListReq(NULL, 0, &req); + void* pReq = taosMemoryMalloc(msgLen); + if (pReq == NULL) { + fp(param, TSDB_CODE_OUT_OF_MEMORY, taos, 0, NULL); + releaseTscObj(connId); + return; + } + + if (tSerializeSGetUserWhiteListReq(pReq, msgLen, &req) < 0) { + fp(param, TSDB_CODE_INVALID_PARA, taos, 0, NULL); + taosMemoryFree(pReq); + releaseTscObj(connId); + return; + } + + SFetchWhiteListInfo* pParam = taosMemoryMalloc(sizeof(SFetchWhiteListInfo)); + if (pParam == NULL) { + fp(param, TSDB_CODE_OUT_OF_MEMORY, taos, 0, NULL); + taosMemoryFree(pReq); + releaseTscObj(connId); + return; + } + + pParam->connId = connId; + pParam->userCbFn = fp; + pParam->userParam = param; + SMsgSendInfo* pSendInfo = taosMemoryCalloc(1, sizeof(SMsgSendInfo)); + if (pSendInfo == NULL) { + fp(param, TSDB_CODE_OUT_OF_MEMORY, taos, 0, NULL); + taosMemoryFree(pParam); + taosMemoryFree(pReq); + releaseTscObj(connId); + return; + } + + pSendInfo->msgInfo = (SDataBuf){.pData = pReq, .len = msgLen, .handle = NULL}; + pSendInfo->requestId = generateRequestId(); + pSendInfo->requestObjRefId = 0; + pSendInfo->param = pParam; + pSendInfo->fp = fetchWhiteListCallbackFn; + pSendInfo->msgType = TDMT_MND_GET_USER_WHITELIST; + + int64_t transportId = 0; + SEpSet epSet = getEpSet_s(&pTsc->pAppInfo->mgmtEp); + asyncSendMsgToServer(pTsc->pAppInfo->pTransporter, &epSet, &transportId, pSendInfo); + releaseTscObj(connId); + return; +} + void taos_close_internal(void *taos) { if (taos == NULL) { return; diff --git a/source/common/src/tmsg.c b/source/common/src/tmsg.c index 06a088a8ec..e47a9cbfcb 100644 --- a/source/common/src/tmsg.c +++ b/source/common/src/tmsg.c @@ -1435,6 +1435,7 @@ int32_t tDeserializeSCreateUserReq(void *buf, int32_t bufLen, SCreateUserReq *pR } tEndDecode(&decoder); + tDecoderClear(&decoder); return 0; } @@ -1905,6 +1906,73 @@ void tFreeSGetUserAuthRsp(SGetUserAuthRsp *pRsp) { taosHashCleanup(pRsp->useDbs); } +int32_t tSerializeSGetWhiteListReq(void *buf, int32_t bufLen, SGetUserWhiteListReq *pReq) { + SEncoder encoder = {0}; + tEncoderInit(&encoder, buf, bufLen); + + if (tStartEncode(&encoder) < 0) return -1; + if (tEncodeCStr(&encoder, pReq->user) < 0) return -1; + tEndEncode(&encoder); + + int32_t tlen = encoder.pos; + tEncoderClear(&encoder); + return tlen; +} + +int32_t tDeserializeSGetUserWhiteListReq(void *buf, int32_t bufLen, SGetUserWhiteListReq *pReq) { + SDecoder decoder = {0}; + tDecoderInit(&decoder, buf, bufLen); + + if (tStartDecode(&decoder) < 0) return -1; + if (tDecodeCStrTo(&decoder, pReq->user) < 0) return -1; + tEndDecode(&decoder); + + tDecoderClear(&decoder); + return 0; +} + +int32_t tSerializeSGetUserWhiteListRsp(void* buf, int32_t bufLen, SGetUserWhiteListRsp* pRsp) { + SEncoder encoder = {0}; + tEncoderInit(&encoder, buf, bufLen); + + if (tStartEncode(&encoder) < 0) return -1; + if (tEncodeCStr(&encoder, pRsp->user) < 0) return -1; + if (tEncodeI32(&encoder, pRsp->numWhiteLists) < 0) return -1; + for (int i = 0; i < pRsp->numWhiteLists; ++i) { + if (tEncodeU32(&encoder, pRsp->pWhiteLists[i].ip) < 0) return -1; + if (tEncodeU32(&encoder, pRsp->pWhiteLists[i].mask) < 0) return -1; + } + tEndEncode(&encoder); + + int32_t tlen = encoder.pos; + tEncoderClear(&encoder); + return tlen; +} + +int32_t tDeserializeSGetUserWhiteListRsp(void* buf, int32_t bufLen, SGetUserWhiteListRsp* pRsp) { + SDecoder decoder = {0}; + tDecoderInit(&decoder, buf, bufLen); + + if (tStartDecode(&decoder) < 0) return -1; + if (tDecodeCStrTo(&decoder, pRsp->user) < 0) return -1; + + if (tDecodeI32(&decoder, &pRsp->numWhiteLists) < 0) return -1; + pRsp->pWhiteLists = taosMemoryMalloc(pRsp->numWhiteLists * sizeof(SIpV4Range)); + if (pRsp->pWhiteLists == NULL) return -1; + for (int32_t i = 0; i < pRsp->numWhiteLists; ++i) { + if (tDecodeU32(&decoder, &(pRsp->pWhiteLists[i].ip)) < 0) return -1; + if (tDecodeU32(&decoder, &(pRsp->pWhiteLists[i].mask)) < 0) return -1; + } + + tEndDecode(&decoder); + tDecoderClear(&decoder); + return 0; +} + +void tFreeSGetUserWhiteListRsp(SGetUserWhiteListRsp* pRsp) { + taosMemoryFree(pRsp->pWhiteLists); +} + int32_t tSerializeSCreateDropMQSNodeReq(void *buf, int32_t bufLen, SMCreateQnodeReq *pReq) { SEncoder encoder = {0}; tEncoderInit(&encoder, buf, bufLen); diff --git a/source/dnode/mnode/impl/src/mndUser.c b/source/dnode/mnode/impl/src/mndUser.c index ff5bb90c81..97909472d4 100644 --- a/source/dnode/mnode/impl/src/mndUser.c +++ b/source/dnode/mnode/impl/src/mndUser.c @@ -49,6 +49,7 @@ static int32_t mndProcessCreateUserReq(SRpcMsg *pReq); static int32_t mndProcessAlterUserReq(SRpcMsg *pReq); static int32_t mndProcessDropUserReq(SRpcMsg *pReq); static int32_t mndProcessGetUserAuthReq(SRpcMsg *pReq); +static int32_t mndProcessGetUserWhiteListReq(SRpcMsg *pReq); static int32_t mndRetrieveUsers(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows); static void mndCancelGetNextUser(SMnode *pMnode, void *pIter); static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows); @@ -398,6 +399,8 @@ int32_t mndInitUser(SMnode *pMnode) { mndSetMsgHandle(pMnode, TDMT_MND_ALTER_USER, mndProcessAlterUserReq); mndSetMsgHandle(pMnode, TDMT_MND_DROP_USER, mndProcessDropUserReq); mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_AUTH, mndProcessGetUserAuthReq); + mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_WHITELIST, mndProcessGetUserWhiteListReq); + mndSetMsgHandle(pMnode, TDMT_MND_RETRIEVE_IP_WHITE, mndProcesSRetrieveIpWhiteReq); mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_USER, mndRetrieveUsers); @@ -1197,6 +1200,60 @@ _OVER: tFreeSCreateUserReq(&createReq); return code; } + +//TODO: this is enterpise version, or shared version between enterprise and community? +static int32_t mndSetUserWhiteListRsp(SMnode* pMnode, SUserObj* pUser, SGetUserWhiteListRsp* pWhiteListRsp) { + memcpy(pWhiteListRsp->user, pUser->user, TSDB_USER_LEN); + pWhiteListRsp->numWhiteLists = pUser->pIpWhiteList->num; + pWhiteListRsp->pWhiteLists = taosMemoryMalloc(pWhiteListRsp->numWhiteLists * sizeof(SIpV4Range)); + if (pWhiteListRsp->pWhiteLists == NULL) { + return TSDB_CODE_OUT_OF_MEMORY; + } + memcpy(pUser->pIpWhiteList->pIpRange, pUser->pIpWhiteList->pIpRange, pWhiteListRsp->numWhiteLists * sizeof(SIpV4Range)); + return 0; +} + +int32_t mndProcessGetUserWhiteListReq(SRpcMsg *pReq) { + SMnode *pMnode = pReq->info.node; + int32_t code = -1; + SUserObj *pUser = NULL; + SGetUserWhiteListReq wlReq = {0}; + SGetUserWhiteListRsp wlRsp = {0}; + + if (tDeserializeSGetUserWhiteListReq(pReq->pCont, pReq->contLen, &wlReq) != 0) { + terrno = TSDB_CODE_INVALID_MSG; + goto _OVER; + } + mTrace("user: %s, start to get whitelist", wlReq.user); + + pUser = mndAcquireUser(pMnode, wlReq.user); + if (pUser == NULL) { + terrno = TSDB_CODE_MND_USER_NOT_EXIST; + goto _OVER; + } + + code = mndSetUserWhiteListRsp(pMnode, pUser, &wlRsp); + if (code) { + goto _OVER; + } + int32_t contLen = tSerializeSGetUserWhiteListRsp(NULL, 0, &wlRsp); + void *pRsp = rpcMallocCont(contLen); + if (pRsp == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + goto _OVER; + } + + tSerializeSGetUserWhiteListRsp(pRsp, contLen, &wlRsp); + + pReq->info.rsp = pRsp; + pReq->info.rspLen = contLen; + code = 0; +_OVER: + mndReleaseUser(pMnode, pUser); + tFreeSGetUserWhiteListRsp(&wlRsp); + return code; +} + int32_t mndProcesSRetrieveIpWhiteReq(SRpcMsg *pReq) { // impl later SRetrieveIpWhiteReq req = {0}; From 53894f1182481944f48bd7810b164ef9cf200c46 Mon Sep 17 00:00:00 2001 From: shenglian zhou Date: Fri, 8 Sep 2023 19:04:14 +0800 Subject: [PATCH 6/9] enhance: add hb whitelist version and notify taosadapter --- source/dnode/mnode/impl/src/mndPrivilege.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/dnode/mnode/impl/src/mndPrivilege.c b/source/dnode/mnode/impl/src/mndPrivilege.c index 25b59f4a9a..c6871d6882 100644 --- a/source/dnode/mnode/impl/src/mndPrivilege.c +++ b/source/dnode/mnode/impl/src/mndPrivilege.c @@ -40,8 +40,7 @@ int32_t mndSetUserAuthRsp(SMnode *pMnode, SUserObj *pUser, SGetUserAuthRsp *pRsp pRsp->sysInfo = pUser->sysInfo; pRsp->version = pUser->authVersion; pRsp->passVer = pUser->passVersion; - pRsp->whiteListVer = mndGetIpWhiteVer(pMnode); - //TODO: mndSetUserAuthRsp in enterprise version + pRsp->whiteListVer = pUser->ipWhiteListVer; return 0; } From d5f1662bf56e78f015ae15de9f94947ce03252df Mon Sep 17 00:00:00 2001 From: shenglian zhou Date: Tue, 12 Sep 2023 14:35:01 +0800 Subject: [PATCH 7/9] enh: enterprise version and community version split --- source/dnode/mnode/impl/inc/mndPrivilege.h | 1 + source/dnode/mnode/impl/src/mndUser.c | 11 +++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/source/dnode/mnode/impl/inc/mndPrivilege.h b/source/dnode/mnode/impl/inc/mndPrivilege.h index 5ed65b2a5b..3aa8a3d2d5 100644 --- a/source/dnode/mnode/impl/inc/mndPrivilege.h +++ b/source/dnode/mnode/impl/inc/mndPrivilege.h @@ -33,6 +33,7 @@ int32_t mndCheckTopicPrivilegeByName(SMnode *pMnode, const char *user, EOperType int32_t mndCheckShowPrivilege(SMnode *pMnode, const char *user, EShowType showType, const char *dbname); int32_t mndCheckAlterUserPrivilege(SUserObj *pOperUser, SUserObj *pUser, SAlterUserReq *pAlter); int32_t mndSetUserAuthRsp(SMnode *pMnode, SUserObj *pUser, SGetUserAuthRsp *pRsp); +int32_t mndSetUserWhiteListRsp(SMnode* pMnode, SUserObj* pUser, SGetUserWhiteListRsp* pWhiteListRsp); int32_t mndEnableIpWhiteList(SMnode *pMnode); int32_t mndFetchIpWhiteList(SIpWhiteList *ipList, char **buf); diff --git a/source/dnode/mnode/impl/src/mndUser.c b/source/dnode/mnode/impl/src/mndUser.c index 97909472d4..36082b70b1 100644 --- a/source/dnode/mnode/impl/src/mndUser.c +++ b/source/dnode/mnode/impl/src/mndUser.c @@ -1201,15 +1201,22 @@ _OVER: return code; } -//TODO: this is enterpise version, or shared version between enterprise and community? -static int32_t mndSetUserWhiteListRsp(SMnode* pMnode, SUserObj* pUser, SGetUserWhiteListRsp* pWhiteListRsp) { +//TODO: for community version use the commented version +int32_t mndSetUserWhiteListRsp(SMnode* pMnode, SUserObj* pUser, SGetUserWhiteListRsp* pWhiteListRsp) { memcpy(pWhiteListRsp->user, pUser->user, TSDB_USER_LEN); +// pWhiteListRsp->numWhiteLists = 1; +// pWhiteListRsp->pWhiteLists = taosMemoryMalloc(pWhiteListRsp->numWhiteLists * sizeof(SIpV4Range)); +// if (pWhiteListRsp->pWhiteLists == NULL) { +// return TSDB_CODE_OUT_OF_MEMORY; +// } +// memset(pUser->pIpWhiteList->pIpRange, 0, pWhiteListRsp->numWhiteLists * sizeof(SIpV4Range)); pWhiteListRsp->numWhiteLists = pUser->pIpWhiteList->num; pWhiteListRsp->pWhiteLists = taosMemoryMalloc(pWhiteListRsp->numWhiteLists * sizeof(SIpV4Range)); if (pWhiteListRsp->pWhiteLists == NULL) { return TSDB_CODE_OUT_OF_MEMORY; } memcpy(pUser->pIpWhiteList->pIpRange, pUser->pIpWhiteList->pIpRange, pWhiteListRsp->numWhiteLists * sizeof(SIpV4Range)); + return 0; } From e3a6b92f4eaf69e848403261024339e212942ac4 Mon Sep 17 00:00:00 2001 From: shenglian zhou Date: Tue, 12 Sep 2023 15:00:08 +0800 Subject: [PATCH 8/9] fix: fix minior bugs --- source/client/src/clientMain.c | 7 +++++-- source/common/src/tmsg.c | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/source/client/src/clientMain.c b/source/client/src/clientMain.c index 9db1c72e04..1afbc65db0 100644 --- a/source/client/src/clientMain.c +++ b/source/client/src/clientMain.c @@ -175,12 +175,15 @@ int32_t fetchWhiteListCallbackFn(void* param, SDataBuf* pMsg, int32_t code) { return code; } - SGetUserWhiteListRsp *pRsp = pMsg->pData; - pInfo->userCbFn(pInfo->userParam, code, taos, pRsp->numWhiteLists, &pRsp->pWhiteLists->ip_mask); + SGetUserWhiteListRsp wlRsp; + tDeserializeSGetUserWhiteListRsp(pMsg->pData, pMsg->len, &wlRsp); + + pInfo->userCbFn(pInfo->userParam, code, taos, wlRsp.numWhiteLists, &wlRsp.pWhiteLists->ip_mask); taosMemoryFree(pMsg->pData); taosMemoryFree(pMsg->pEpSet); taosMemoryFree(pInfo); + tFreeSGetUserWhiteListRsp(&wlRsp); return code; } diff --git a/source/common/src/tmsg.c b/source/common/src/tmsg.c index e47a9cbfcb..2285d0df23 100644 --- a/source/common/src/tmsg.c +++ b/source/common/src/tmsg.c @@ -1906,7 +1906,7 @@ void tFreeSGetUserAuthRsp(SGetUserAuthRsp *pRsp) { taosHashCleanup(pRsp->useDbs); } -int32_t tSerializeSGetWhiteListReq(void *buf, int32_t bufLen, SGetUserWhiteListReq *pReq) { +int32_t tSerializeSGetUserWhiteListReq(void *buf, int32_t bufLen, SGetUserWhiteListReq *pReq) { SEncoder encoder = {0}; tEncoderInit(&encoder, buf, bufLen); From 65fe665939179b989167fd46a8538246dc77badb Mon Sep 17 00:00:00 2001 From: slzhou Date: Tue, 12 Sep 2023 16:27:07 +0800 Subject: [PATCH 9/9] fix: get user whitelist version from user object --- source/dnode/mnode/impl/src/mndProfile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/dnode/mnode/impl/src/mndProfile.c b/source/dnode/mnode/impl/src/mndProfile.c index 0a3e6c616a..6f67778615 100644 --- a/source/dnode/mnode/impl/src/mndProfile.c +++ b/source/dnode/mnode/impl/src/mndProfile.c @@ -290,7 +290,7 @@ _CONNECT: connectRsp.svrTimestamp = taosGetTimestampSec(); connectRsp.passVer = pUser->passVersion; connectRsp.authVer = pUser->authVersion; - connectRsp.whiteListVer = mndGetIpWhiteVer(pMnode); + connectRsp.whiteListVer = pUser->ipWhiteListVer; strcpy(connectRsp.sVer, version); snprintf(connectRsp.sDetailVer, sizeof(connectRsp.sDetailVer), "ver:%s\nbuild:%s\ngitinfo:%s", version, buildinfo,