diff --git a/include/common/tmsg.h b/include/common/tmsg.h index a9923e4e48..3f8df42e1d 100644 --- a/include/common/tmsg.h +++ b/include/common/tmsg.h @@ -185,6 +185,8 @@ typedef enum _mgmt_table { #define TSDB_ALTER_USER_REMOVE_READ_TAG 0x12 #define TSDB_ALTER_USER_ADD_WRITE_TAG 0x13 #define TSDB_ALTER_USER_REMOVE_WRITE_TAG 0x14 +#define TSDB_ALTER_USER_ADD_ALL_TABLE 0x15 +#define TSDB_ALTER_USER_REMOVE_ALL_TABLE 0x16 #define TSDB_ALTER_USER_PRIVILEGES 0x2 diff --git a/source/dnode/mnode/impl/inc/mndUser.h b/source/dnode/mnode/impl/inc/mndUser.h index 8943ba703e..95d15f6e5a 100644 --- a/source/dnode/mnode/impl/inc/mndUser.h +++ b/source/dnode/mnode/impl/inc/mndUser.h @@ -31,6 +31,7 @@ void mndReleaseUser(SMnode *pMnode, SUserObj *pUser); // for trans test SSdbRaw *mndUserActionEncode(SUserObj *pUser); SHashObj *mndDupDbHash(SHashObj *pOld); +SHashObj *mndDupTableHash(SHashObj *pOld); SHashObj *mndDupTopicHash(SHashObj *pOld); int32_t mndValidateUserAuthInfo(SMnode *pMnode, SUserAuthVersion *pUsers, int32_t numOfUses, void **ppRsp, int32_t *pRspLen); diff --git a/source/dnode/mnode/impl/src/mndUser.c b/source/dnode/mnode/impl/src/mndUser.c index bebf57a55e..243053751e 100644 --- a/source/dnode/mnode/impl/src/mndUser.c +++ b/source/dnode/mnode/impl/src/mndUser.c @@ -685,8 +685,22 @@ static int32_t mndTablePriviledge(SMnode *pMnode, SHashObj *hash, SAlterUserReq snprintf(tbFName, sizeof(tbFName), "%s.%s", alterReq->objname, alterReq->tabName); int32_t len = strlen(tbFName) + 1; - if (taosHashPut(hash, tbFName, len, "t", 2) != 0) { - return -1; + if(alterReq->tagCond != NULL && alterReq->tagCondLen != 0){ + char *value = taosHashGet(hash, tbFName, len); + if(value != NULL){ + terrno = TSDB_CODE_MND_PRIVILEDGE_EXIST; + return -1; + } + + int32_t condLen = alterReq->tagCondLen + 1; + if (taosHashPut(hash, tbFName, len, alterReq->tagCond, condLen) != 0) { + return -1; + } + } + else{ + if (taosHashPut(hash, tbFName, len, "t", 2) != 0) { + return -1; + } } return 0; diff --git a/source/libs/parser/src/parAstParser.c b/source/libs/parser/src/parAstParser.c index cd4b455e02..fb6711ecb1 100644 --- a/source/libs/parser/src/parAstParser.c +++ b/source/libs/parser/src/parAstParser.c @@ -610,6 +610,13 @@ static int32_t collectMetaKeyFromCompactDatabase(SCollectMetaKeyCxt* pCxt, SComp return reserveDbCfgInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pCxt->pMetaCache); } +static int32_t collectMetaKeyFromGrant(SCollectMetaKeyCxt* pCxt, SGrantStmt* pStmt) { + if ('\0' == pStmt->tabName[0]) { + return TSDB_CODE_SUCCESS; + } + return reserveTableMetaInCache(pCxt->pParseCxt->acctId, pStmt->objName, pStmt->tabName, pCxt->pMetaCache); +} + static int32_t collectMetaKeyFromQuery(SCollectMetaKeyCxt* pCxt, SNode* pStmt) { pCxt->pStmt = pStmt; switch (nodeType(pStmt)) { @@ -645,6 +652,8 @@ static int32_t collectMetaKeyFromQuery(SCollectMetaKeyCxt* pCxt, SNode* pStmt) { return collectMetaKeyFromCompactDatabase(pCxt, (SCompactDatabaseStmt*)pStmt); case QUERY_NODE_CREATE_STREAM_STMT: return collectMetaKeyFromCreateStream(pCxt, (SCreateStreamStmt*)pStmt); + case QUERY_NODE_GRANT_STMT: + return collectMetaKeyFromGrant(pCxt, (SGrantStmt*)pStmt); case QUERY_NODE_SHOW_DNODES_STMT: return collectMetaKeyFromShowDnodes(pCxt, (SShowStmt*)pStmt); case QUERY_NODE_SHOW_MNODES_STMT: diff --git a/source/libs/parser/src/parAuthenticator.c b/source/libs/parser/src/parAuthenticator.c index a0ded97c5f..039b46d8b8 100644 --- a/source/libs/parser/src/parAuthenticator.c +++ b/source/libs/parser/src/parAuthenticator.c @@ -23,6 +23,11 @@ typedef struct SAuthCxt { int32_t errCode; } SAuthCxt; +typedef struct SSelectAuthCxt { + SAuthCxt* pAuthCxt; + SSelectStmt* pSelect; +} SSelectAuthCxt; + static int32_t authQuery(SAuthCxt* pCxt, SNode* pStmt); static int32_t checkAuth(SAuthCxt* pCxt, const char* pDbName, AUTH_TYPE type) { @@ -56,19 +61,60 @@ static EDealRes authSubquery(SAuthCxt* pCxt, SNode* pStmt) { return TSDB_CODE_SUCCESS == authQuery(pCxt, pStmt) ? DEAL_RES_CONTINUE : DEAL_RES_ERROR; } +static int32_t mergeStableTagCond(SNode** pWhere, SNode** pTagCond) { + SLogicConditionNode* pLogicCond = (SLogicConditionNode*)nodesMakeNode(QUERY_NODE_LOGIC_CONDITION); + if (NULL == pLogicCond) { + return TSDB_CODE_OUT_OF_MEMORY; + } + pLogicCond->node.resType.type = TSDB_DATA_TYPE_BOOL; + pLogicCond->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_BOOL].bytes; + pLogicCond->condType = LOGIC_COND_TYPE_AND; + int32_t code = nodesListMakeStrictAppend(&pLogicCond->pParameterList, *pTagCond); + if (TSDB_CODE_SUCCESS == code) { + code = nodesListMakeAppend(&pLogicCond->pParameterList, *pWhere); + } + if (TSDB_CODE_SUCCESS == code) { + *pWhere = (SNode*)pLogicCond; + } else { + nodesDestroyNode((SNode*)pLogicCond); + } + return code; +} + +static int32_t appendStableTagCond(SSelectStmt* pSelect, SNode* pTagCond) { + SNode* pTagCondCopy = nodesCloneNode(pTagCond); + if (NULL == pTagCondCopy) { + return TSDB_CODE_OUT_OF_MEMORY; + } + + if (NULL == pSelect->pWhere) { + pSelect->pWhere = pTagCondCopy; + return TSDB_CODE_SUCCESS; + } + + if (QUERY_NODE_LOGIC_CONDITION == nodeType(pSelect->pWhere) && + LOGIC_COND_TYPE_AND == ((SLogicConditionNode*)pSelect->pWhere)->condType) { + return nodesListStrictAppend(((SLogicConditionNode*)pSelect->pWhere)->pParameterList, pTagCondCopy); + } + + return mergeStableTagCond(&pSelect->pWhere, &pTagCondCopy); +} + static EDealRes authSelectImpl(SNode* pNode, void* pContext) { - SAuthCxt* pCxt = pContext; + SSelectAuthCxt* pCxt = pContext; + SAuthCxt* pAuthCxt = pCxt->pAuthCxt; if (QUERY_NODE_REAL_TABLE == nodeType(pNode)) { - pCxt->errCode = checkAuth(pCxt, ((SRealTableNode*)pNode)->table.dbName, AUTH_TYPE_READ); - return TSDB_CODE_SUCCESS == pCxt->errCode ? DEAL_RES_CONTINUE : DEAL_RES_ERROR; + pAuthCxt->errCode = checkAuth(pAuthCxt, ((SRealTableNode*)pNode)->table.dbName, AUTH_TYPE_READ); + return TSDB_CODE_SUCCESS == pAuthCxt->errCode ? DEAL_RES_CONTINUE : DEAL_RES_ERROR; } else if (QUERY_NODE_TEMP_TABLE == nodeType(pNode)) { - return authSubquery(pCxt, ((STempTableNode*)pNode)->pSubquery); + return authSubquery(pAuthCxt, ((STempTableNode*)pNode)->pSubquery); } return DEAL_RES_CONTINUE; } static int32_t authSelect(SAuthCxt* pCxt, SSelectStmt* pSelect) { - nodesWalkSelectStmt(pSelect, SQL_CLAUSE_FROM, authSelectImpl, pCxt); + SSelectAuthCxt cxt = {.pAuthCxt = pCxt, .pSelect = pSelect}; + nodesWalkSelectStmt(pSelect, SQL_CLAUSE_FROM, authSelectImpl, &cxt); return pCxt->errCode; } @@ -149,7 +195,7 @@ static int32_t authQuery(SAuthCxt* pCxt, SNode* pStmt) { case QUERY_NODE_SHOW_LICENCES_STMT: case QUERY_NODE_SHOW_VGROUPS_STMT: case QUERY_NODE_SHOW_DB_ALIVE_STMT: - case QUERY_NODE_SHOW_CLUSTER_ALIVE_STMT: + case QUERY_NODE_SHOW_CLUSTER_ALIVE_STMT: case QUERY_NODE_SHOW_CREATE_DATABASE_STMT: case QUERY_NODE_SHOW_TABLE_DISTRIBUTED_STMT: case QUERY_NODE_SHOW_VNODES_STMT: diff --git a/source/libs/parser/src/parInsertSql.c b/source/libs/parser/src/parInsertSql.c index dcc769624f..c97090dd48 100644 --- a/source/libs/parser/src/parInsertSql.c +++ b/source/libs/parser/src/parInsertSql.c @@ -15,6 +15,7 @@ #include "parInsertUtil.h" #include "parToken.h" +#include "scalar.h" #include "tglobal.h" #include "ttime.h" @@ -565,6 +566,120 @@ static int32_t checkAndTrimValue(SToken* pToken, char* tmpTokenBuf, SMsgBuf* pMs return TSDB_CODE_SUCCESS; } +typedef struct SRewriteTagCondCxt { + SArray* pTagVals; + SArray* pTagName; + int32_t code; +} SRewriteTagCondCxt; + +static int32_t rewriteTagCondColumnImpl(STagVal* pVal, SNode** pNode) { + SValueNode* pValue = (SValueNode*)nodesMakeNode(QUERY_NODE_VALUE); + if (NULL == pValue) { + return TSDB_CODE_OUT_OF_MEMORY; + } + pValue->node.resType.type = pVal->type; + switch (pVal->type) { + case TSDB_DATA_TYPE_BOOL: + pValue->datum.b = *(int8_t*)(&pVal->i64); + break; + case TSDB_DATA_TYPE_TINYINT: + pValue->datum.i = *(int8_t*)(&pVal->i64); + break; + case TSDB_DATA_TYPE_SMALLINT: + pValue->datum.i = *(int16_t*)(&pVal->i64); + break; + case TSDB_DATA_TYPE_INT: + pValue->datum.i = *(int32_t*)(&pVal->i64); + break; + case TSDB_DATA_TYPE_BIGINT: + pValue->datum.i = pVal->i64; + break; + case TSDB_DATA_TYPE_FLOAT: + pValue->datum.d = *(float*)(&pVal->i64); + break; + case TSDB_DATA_TYPE_DOUBLE: + pValue->datum.d = *(double*)(&pVal->i64); + break; + case TSDB_DATA_TYPE_VARCHAR: + case TSDB_DATA_TYPE_NCHAR: + pValue->datum.p = taosMemoryCalloc(1, pVal->nData + VARSTR_HEADER_SIZE); + if (NULL == pValue->datum.p) { + return TSDB_CODE_OUT_OF_MEMORY; + } + varDataSetLen(pValue->datum.p, pVal->nData); + memcpy(varDataVal(pValue->datum.p), pVal->pData, pVal->nData); + break; + case TSDB_DATA_TYPE_TIMESTAMP: + pValue->datum.i = pVal->i64; + break; + case TSDB_DATA_TYPE_UTINYINT: + pValue->datum.i = *(uint8_t*)(&pVal->i64); + break; + case TSDB_DATA_TYPE_USMALLINT: + pValue->datum.i = *(uint16_t*)(&pVal->i64); + break; + case TSDB_DATA_TYPE_UINT: + pValue->datum.i = *(uint32_t*)(&pVal->i64); + break; + case TSDB_DATA_TYPE_UBIGINT: + pValue->datum.i = *(uint64_t*)(&pVal->i64); + break; + case TSDB_DATA_TYPE_JSON: + case TSDB_DATA_TYPE_VARBINARY: + case TSDB_DATA_TYPE_DECIMAL: + case TSDB_DATA_TYPE_BLOB: + case TSDB_DATA_TYPE_MEDIUMBLOB: + default: + return TSDB_CODE_FAILED; + } + return TSDB_CODE_SUCCESS; +} + +static int32_t rewriteTagCondColumn(SArray* pTagVals, SArray* pTagName, SNode** pNode) { + SColumnNode* pCol = (SColumnNode*)*pNode; + int32_t ntags = taosArrayGetSize(pTagName); + for (int32_t i = 0; i < ntags; ++i) { + char* pTagColName = taosArrayGet(pTagName, i); + if (0 == strcmp(pTagColName, pCol->colName)) { + return rewriteTagCondColumnImpl(taosArrayGet(pTagVals, i), pNode); + } + } + return TSDB_CODE_PAR_PERMISSION_DENIED; +} + +static EDealRes rewriteTagCond(SNode** pNode, void* pContext) { + if (QUERY_NODE_COLUMN == nodeType(*pNode)) { + SRewriteTagCondCxt* pCxt = pContext; + pCxt->code = rewriteTagCondColumn(pCxt->pTagVals, pCxt->pTagName, pNode); + return (TSDB_CODE_SUCCESS == pCxt->code ? DEAL_RES_IGNORE_CHILD : DEAL_RES_ERROR); + } + return DEAL_RES_CONTINUE; +} + +static int32_t setTagVal(SArray* pTagVals, SArray* pTagName, SNode* pCond) { + SRewriteTagCondCxt cxt = {.code = TSDB_CODE_SUCCESS, .pTagVals = pTagVals, .pTagName = pTagName}; + nodesRewriteExpr(&pCond, rewriteTagCond, &cxt); + return cxt.code; +} + +static int32_t checkTagCondResult(SNode* pResult) { + return (QUERY_NODE_VALUE == nodeType(pResult) && ((SValueNode*)pResult)->datum.b) ? TSDB_CODE_SUCCESS + : TSDB_CODE_PAR_PERMISSION_DENIED; +} + +int32_t checkSubtablePrivilege(SArray* pTagVals, SArray* pTagName, SNode* pCond) { + int32_t code = setTagVal(pTagVals, pTagName, pCond); + SNode* pNew = NULL; + if (TSDB_CODE_SUCCESS == code) { + code = scalarCalculateConstants(pCond, &pNew); + } + if (TSDB_CODE_SUCCESS == code) { + code = checkTagCondResult(pNew); + } + nodesDestroyNode(pNew); + return code; +} + // pSql -> tag1_value, ...) static int32_t parseTagsClauseImpl(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) { int32_t code = TSDB_CODE_SUCCESS; diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 06bd666609..cf621ef166 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -6454,11 +6454,11 @@ static int32_t translateGrant(STranslateContext* pCxt, SGrantStmt* pStmt) { if (BIT_FLAG_TEST_MASK(pStmt->privileges, PRIVILEGE_TYPE_ALL) || (BIT_FLAG_TEST_MASK(pStmt->privileges, PRIVILEGE_TYPE_READ) && BIT_FLAG_TEST_MASK(pStmt->privileges, PRIVILEGE_TYPE_WRITE))) { - req.alterType = TSDB_ALTER_USER_ADD_ALL_DB; + req.alterType = ('\0' == pStmt->tabName[0] ? TSDB_ALTER_USER_ADD_ALL_DB : TSDB_ALTER_USER_ADD_ALL_TABLE); } else if (BIT_FLAG_TEST_MASK(pStmt->privileges, PRIVILEGE_TYPE_READ)) { - req.alterType = TSDB_ALTER_USER_ADD_READ_DB; + req.alterType = ('\0' == pStmt->tabName[0] ? TSDB_ALTER_USER_ADD_READ_DB : TSDB_ALTER_USER_ADD_READ_TABLE); } else if (BIT_FLAG_TEST_MASK(pStmt->privileges, PRIVILEGE_TYPE_WRITE)) { - req.alterType = TSDB_ALTER_USER_ADD_WRITE_DB; + req.alterType = ('\0' == pStmt->tabName[0] ? TSDB_ALTER_USER_ADD_WRITE_DB : TSDB_ALTER_USER_ADD_WRITE_TABLE); } else if (BIT_FLAG_TEST_MASK(pStmt->privileges, PRIVILEGE_TYPE_SUBSCRIBE)) { req.alterType = TSDB_ALTER_USER_ADD_SUBSCRIBE_TOPIC; } @@ -6480,11 +6480,11 @@ static int32_t translateRevoke(STranslateContext* pCxt, SRevokeStmt* pStmt) { if (BIT_FLAG_TEST_MASK(pStmt->privileges, PRIVILEGE_TYPE_ALL) || (BIT_FLAG_TEST_MASK(pStmt->privileges, PRIVILEGE_TYPE_READ) && BIT_FLAG_TEST_MASK(pStmt->privileges, PRIVILEGE_TYPE_WRITE))) { - req.alterType = TSDB_ALTER_USER_REMOVE_ALL_DB; + req.alterType = ('\0' == pStmt->tabName[0] ? TSDB_ALTER_USER_REMOVE_ALL_DB : TSDB_ALTER_USER_REMOVE_ALL_TABLE); } else if (BIT_FLAG_TEST_MASK(pStmt->privileges, PRIVILEGE_TYPE_READ)) { - req.alterType = TSDB_ALTER_USER_REMOVE_READ_DB; + req.alterType = ('\0' == pStmt->tabName[0] ? TSDB_ALTER_USER_REMOVE_READ_DB : TSDB_ALTER_USER_REMOVE_READ_TABLE); } else if (BIT_FLAG_TEST_MASK(pStmt->privileges, PRIVILEGE_TYPE_WRITE)) { - req.alterType = TSDB_ALTER_USER_REMOVE_WRITE_DB; + req.alterType = ('\0' == pStmt->tabName[0] ? TSDB_ALTER_USER_REMOVE_WRITE_DB : TSDB_ALTER_USER_REMOVE_WRITE_TABLE); } else if (BIT_FLAG_TEST_MASK(pStmt->privileges, PRIVILEGE_TYPE_SUBSCRIBE)) { req.alterType = TSDB_ALTER_USER_REMOVE_SUBSCRIBE_TOPIC; }