未验证 提交 e1f63118 编写于 作者: D dapan1121 提交者: GitHub

Merge pull request #16804 from taosdata/feat/TS-1839-V26

Feat/TS-1839-V26  support limit user for query with tag filter
...@@ -336,6 +336,7 @@ typedef struct STscObj { ...@@ -336,6 +336,7 @@ typedef struct STscObj {
char user[TSDB_USER_LEN]; char user[TSDB_USER_LEN];
char pass[TSDB_PASS_LEN]; char pass[TSDB_PASS_LEN];
char acctId[TSDB_ACCT_ID_LEN]; char acctId[TSDB_ACCT_ID_LEN];
char tags[TSDB_TAGS_LEN];
char db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN]; char db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN];
char sversion[TSDB_VERSION_LEN]; char sversion[TSDB_VERSION_LEN];
char clusterId[TSDB_CLUSTER_ID_LEN]; char clusterId[TSDB_CLUSTER_ID_LEN];
......
...@@ -34,6 +34,320 @@ static void tscAsyncQueryRowsForNextVnode(void *param, TAOS_RES *tres, int numOf ...@@ -34,6 +34,320 @@ static void tscAsyncQueryRowsForNextVnode(void *param, TAOS_RES *tres, int numOf
*/ */
static void tscAsyncFetchRowsProxy(void *param, TAOS_RES *tres, int numOfRows); static void tscAsyncFetchRowsProxy(void *param, TAOS_RES *tres, int numOfRows);
// like select * from st1 , st2 where ... format
static inline int32_t likeBlanksCommaBlans(char * str) {
char *p = str;
int32_t cnt1 = 0; // ' ' count
int32_t cnt2 = 0; // ',' count
while (*p != 0) {
if(*p == ' ')
cnt1++;
else if(*p == ',')
cnt2++;
else
return cnt2 == 0 ? 0 : cnt1 + cnt2;
p++;
}
return 0;
}
// return tbname start , put tbname end to args pe
static char *searchTBName(char *from_end, char **pend) {
char *p = from_end;
// remove pre blanks
while(*p == ' ') {
++p;
}
char *tbname = p;
if(*p == 0)
return NULL;
// goto next blank
while(1) {
p++;
if(*p == ' ') {
// if following not have , this is end
// format like select * from stb1 , stb2 , stb3 where ...
int32_t len = likeBlanksCommaBlans(p);
if(len > 0) {
p += len;
continue;
}
// tbname is end
if(pend)
*pend = p;
return tbname;
} else if(*p == ';' || *p == 0) {
// sql end flag '\0' or ';' end
if(pend)
*pend = p;
return tbname;
}
}
return NULL;
}
// return names min pointer
static inline char *searchEndPart(char *tbname_end) {
char* names[] = {
" group ",
" order ",
" interval(",
" interval (",
" session(",
" session (",
" state_window(",
" state_window (",
" slimit ",
" slimit(",
" limit ",
" limit(",
" sliding ",
" fill(",
" fill ("
" >>",
";"
};
int32_t count = sizeof(names)/sizeof(char *);
char * p = NULL;
for(int32_t i = 0; i < count; i++) {
char * p1 = strstr(tbname_end, names[i]);
if (p1) {
if (p == NULL || p1 < p)
p = p1;
}
}
if(p == NULL) {
// move string end
p = tbname_end + strlen(tbname_end);
}
return p;
}
// get brackets context and set context to pend
static inline char *bracketsString(char *select, char **pend){
char *p = select;
int32_t cnt = 0;
while (*p) {
if(*p == '(') {
// left bracket
cnt++;
} else if(*p == ')') {
// right bracket
cnt--;
}
if(cnt < 0) {
// this is end
if(pend)
*pend = p;
// copy str to new
int len = p - 1 - select;
if(len == 0)
return NULL;
len += 1; // string end
char *str = (char *)malloc(len);
strncpy(str, select, len);
str[len] = 0;
return str;
}
++p;
}
return NULL;
}
//
// return new malloc buffer, NULL is need not insert or failed tags example is 'tags=3'
// sql part :
// select * from st where age=1 order by ts;
// ------------- --- ----------- -----------
// select part tbname part condition part end part
//
static inline char *insertTags(char *sql, char *tags) {
char *p = sql;
// remove pre blanks
while(*p == ' ') {
++p;
}
// filter not query sql
if(strncmp(p, "select ", 7) != 0) {
return NULL;
}
// specail check
char *from = strstr(p, " from ");
char *block = strstr(p, " _block_dist() ");
if (from == NULL || block != NULL) {
return NULL;
}
char *select = strstr(p + 7, "select "); // sub select sql
char *union_all = strstr(p + 7, " union all ");
// need append tags filter
int32_t bufLen = strlen(sql) + 1 + TSDB_TAGS_LEN;
char *buf = malloc(bufLen);
memset(buf, 0, bufLen);
// case1 if have sub select, tags only append to sub select sql
if(select && union_all) {
// union all like select * from t1 union all select * from t2 union all select * from ....
size_t len = strlen(sql) + 10;
// part1
char *part1 = (char *)malloc(len);
memset(part1, 0, len);
strncpy(part1, p, union_all - p);
char *p1 = insertTags(part1, tags);
free(part1);
if(p1 == NULL) {
free(buf);
return NULL;
}
// part2
char *part2 = union_all + sizeof(" union all ") - 1;
char *p2 = insertTags(part2, tags);
if(p2 == NULL) {
free(buf);
free(p1);
return NULL;
}
// combine p1 + union all + p2
len = strlen(p1) + strlen(p2) + 32;
char *all = (char *)malloc(len);
strcpy(all, p1);
strcat(all, " union all ");
strcat(all, p2);
free(p1);
free(p2);
free(buf);
return all;
}
else if(select) {
char *part1_end = select - 1;
char *part2 = NULL;
char *part3_start = 0;
char *sub_sql = bracketsString(select, &part3_start);
if (sub_sql == NULL) {
// unknown format, can not insert tags
tscError("TAGS found sub select sql but can not parse brackets format. select=%s sql=%s", select, sql);
free(buf);
return NULL;
}
// nest call
part2 = insertTags(sub_sql, tags);
free(sub_sql);
if (part2 == NULL) {
// unknown format, can not insert tags
tscError("TAGS insertTags sub select sql failed. subsql=%s sql=%s", sub_sql, sql);
free(buf);
return NULL;
}
// new string is part1 + part2 + part 3
strncpy(buf, p, part1_end - p + 1);
strcat(buf, part2);
strcat(buf, part3_start);
// return ok 1
// like select * from (select * from st where age>1) where age == 2;
// after-> select * from (select * from st where (tags=3) and (age>1) ) where age == 2;
return buf;
}
char *tbname_end = NULL;
char *tbname = searchTBName(from + sizeof(" from ") - 1, &tbname_end);
if(tbname == NULL || tbname_end == NULL) {
// unexpect string format
free(buf);
return NULL;
}
// condition part
char *where = strstr(tbname_end, " where ");
char *end_part = searchEndPart(tbname_end);
if(end_part == NULL) {
// invalid sql
free(buf);
return NULL;
}
// case2 no condition part
if(where == NULL) {
strncpy(buf, p, end_part - p);
strcat(buf, " where ");
strcat(buf, tags);
strcat(buf, end_part);
// return ok 2
// like select * from st order by ts;
// after-> select * from st where tags=3 order by ts;
return buf;
}
// case3 found condition part
char *cond_part = where + sizeof("where ");
strncpy(buf, p, cond_part - p); // where before part(include where )
strcat(buf, "(");
int32_t cond_len = end_part - cond_part;
// cat cond part
strncat(buf, cond_part, cond_len);
strcat(buf, ") and (");
// cat tags part
strcat(buf, tags);
strcat(buf, ")");
// cat end part
strcat(buf, end_part);
// return ok 3
// like select * from st where age=1 order by ts;
// after-> select * from st where (age=1) and (tags=3) order by ts;
return buf;
}
// if return true success, false is not append privilege sql
bool appendTagsFilter(SSqlObj* pSql) {
// valid tags
STscObj * pTscObj = pSql->pTscObj;
if(pTscObj->tags[0] == 0) {
tscDebug("TAGS 0x%" PRIx64 " tags empty. user=%s", pSql->self, pTscObj->user);
return false;
}
char * p = insertTags(pSql->sqlstr, pTscObj->tags);
if(p == NULL) {
return false;
}
// replace new
char * old = pSql->sqlstr;
pSql->sqlstr = p;
tscDebug("TAGS 0x%" PRIx64 " replace sqlstr ok. old=%s new=%s tags=%s", pSql->self, old, p, pTscObj->tags);
free(old);
return true;
}
void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, __async_cb_func_t fp, void* param, const char* sqlstr, size_t sqlLen) { void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, __async_cb_func_t fp, void* param, const char* sqlstr, size_t sqlLen) {
SSqlCmd* pCmd = &pSql->cmd; SSqlCmd* pCmd = &pSql->cmd;
...@@ -60,6 +374,8 @@ void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, __async_cb_func_t fp, void* para ...@@ -60,6 +374,8 @@ void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, __async_cb_func_t fp, void* para
strntolower(pSql->sqlstr, sqlstr, (int32_t)sqlLen); strntolower(pSql->sqlstr, sqlstr, (int32_t)sqlLen);
appendTagsFilter(pSql);
tscDebugL("0x%"PRIx64" SQL: %s", pSql->self, pSql->sqlstr); tscDebugL("0x%"PRIx64" SQL: %s", pSql->self, pSql->sqlstr);
pCmd->resColumnId = TSDB_RES_COL_ID; pCmd->resColumnId = TSDB_RES_COL_ID;
......
...@@ -862,6 +862,7 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { ...@@ -862,6 +862,7 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
const char* msg3 = "name too long"; const char* msg3 = "name too long";
const char* msg5 = "invalid user rights"; const char* msg5 = "invalid user rights";
const char* msg7 = "not support options"; const char* msg7 = "not support options";
const char* msg8 = "tags filter length must over 3 bytes.";
pCmd->command = pInfo->type; pCmd->command = pInfo->type;
...@@ -900,7 +901,11 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { ...@@ -900,7 +901,11 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
} else { } else {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5);
} }
} else { } else if (pUser->type == TSDB_ALTER_USER_TAGS) {
SStrToken* pTags = &pUser->tags;
if(pTags->n < 4)
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg8);
} else {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg7); return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg7);
} }
} }
...@@ -10471,6 +10476,7 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf ...@@ -10471,6 +10476,7 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf
const char* msg7 = "derivative/twa/rate/irate/diff/tail/stateCount/stateDuration requires timestamp column exists in subquery"; const char* msg7 = "derivative/twa/rate/irate/diff/tail/stateCount/stateDuration requires timestamp column exists in subquery";
const char* msg8 = "condition missing for join query"; const char* msg8 = "condition missing for join query";
const char* msg9 = "not support 3 level select"; const char* msg9 = "not support 3 level select";
const char* msg10 = "limit user forbid query normal or child table, you can query from stable.";
int32_t code = TSDB_CODE_SUCCESS; int32_t code = TSDB_CODE_SUCCESS;
SSqlCmd* pCmd = &pSql->cmd; SSqlCmd* pCmd = &pSql->cmd;
...@@ -10655,6 +10661,11 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf ...@@ -10655,6 +10661,11 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf
bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo); bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo);
// if have tags, only support query on super table
if( !isSTable && pSql->pTscObj->tags[0] !=0) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg10);
}
int32_t type = isSTable? TSDB_QUERY_TYPE_STABLE_QUERY:TSDB_QUERY_TYPE_TABLE_QUERY; int32_t type = isSTable? TSDB_QUERY_TYPE_STABLE_QUERY:TSDB_QUERY_TYPE_TABLE_QUERY;
TSDB_QUERY_SET_TYPE(pQueryInfo->type, type); TSDB_QUERY_SET_TYPE(pQueryInfo->type, type);
......
...@@ -1475,11 +1475,15 @@ int32_t tscBuildUserMsg(SSqlObj *pSql, SSqlInfo *pInfo) { ...@@ -1475,11 +1475,15 @@ int32_t tscBuildUserMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
pAlterMsg->privilege = (char)pCmd->count; pAlterMsg->privilege = (char)pCmd->count;
} else if (pUser->type == TSDB_ALTER_USER_PASSWD) { } else if (pUser->type == TSDB_ALTER_USER_PASSWD) {
strncpy(pAlterMsg->pass, pUser->passwd.z, pUser->passwd.n); strncpy(pAlterMsg->pass, pUser->passwd.z, pUser->passwd.n);
} else if (pUser->type == TSDB_ALTER_USER_TAGS) {
// copy tags
strncpy(pAlterMsg->tags, pUser->tags.z, pUser->tags.n);
} else { // create user password info } else { // create user password info
strncpy(pAlterMsg->pass, pUser->passwd.z, pUser->passwd.n); strncpy(pAlterMsg->pass, pUser->passwd.z, pUser->passwd.n);
strncpy(pAlterMsg->tags, pUser->tags.z, pUser->tags.n);
} }
if (pUser->type == TSDB_ALTER_USER_PASSWD || pUser->type == TSDB_ALTER_USER_PRIVILEGES) { if (pUser->type == TSDB_ALTER_USER_PASSWD || pUser->type == TSDB_ALTER_USER_PRIVILEGES || pUser->type == TSDB_ALTER_USER_TAGS) {
pCmd->msgType = TSDB_MSG_TYPE_CM_ALTER_USER; pCmd->msgType = TSDB_MSG_TYPE_CM_ALTER_USER;
} else { } else {
pCmd->msgType = TSDB_MSG_TYPE_CM_CREATE_USER; pCmd->msgType = TSDB_MSG_TYPE_CM_CREATE_USER;
...@@ -2866,7 +2870,11 @@ int tscProcessConnectRsp(SSqlObj *pSql) { ...@@ -2866,7 +2870,11 @@ int tscProcessConnectRsp(SSqlObj *pSql) {
pObj->writeAuth = pConnect->writeAuth; pObj->writeAuth = pConnect->writeAuth;
pObj->superAuth = pConnect->superAuth; pObj->superAuth = pConnect->superAuth;
pObj->connId = htonl(pConnect->connId); pObj->connId = htonl(pConnect->connId);
tstrncpy(pObj->clusterId, pConnect->clusterId, sizeof(pObj->clusterId)); tstrncpy(pObj->clusterId, pConnect->clusterId, sizeof(pObj->clusterId));
if (pConnect->tags[0] != 0) {
strcpy(pObj->tags, pConnect->tags);
tscInfo("TAGS client received . user=%s tags=%s", pObj->user, pObj->tags);
}
createHbObj(pObj); createHbObj(pObj);
......
...@@ -89,6 +89,9 @@ extern const int32_t TYPE_BYTES[16]; ...@@ -89,6 +89,9 @@ extern const int32_t TYPE_BYTES[16];
#define TSDB_PASS_LEN 16 #define TSDB_PASS_LEN 16
#define SHELL_MAX_PASSWORD_LEN 20 #define SHELL_MAX_PASSWORD_LEN 20
// user set query tags max len
#define TSDB_TAGS_LEN 256
#define TSDB_TRUE 1 #define TSDB_TRUE 1
#define TSDB_FALSE 0 #define TSDB_FALSE 0
#define TSDB_OK 0 #define TSDB_OK 0
......
...@@ -185,6 +185,7 @@ enum _mgmt_table { ...@@ -185,6 +185,7 @@ enum _mgmt_table {
#define TSDB_ALTER_USER_PASSWD 0x1 #define TSDB_ALTER_USER_PASSWD 0x1
#define TSDB_ALTER_USER_PRIVILEGES 0x2 #define TSDB_ALTER_USER_PRIVILEGES 0x2
#define TSDB_ALTER_USER_TAGS 0x4
#define TSDB_KILL_MSG_LEN 30 #define TSDB_KILL_MSG_LEN 30
...@@ -362,6 +363,7 @@ typedef struct { ...@@ -362,6 +363,7 @@ typedef struct {
char acctId[TSDB_ACCT_ID_LEN]; char acctId[TSDB_ACCT_ID_LEN];
char serverVersion[TSDB_VERSION_LEN]; char serverVersion[TSDB_VERSION_LEN];
char clusterId[TSDB_CLUSTER_ID_LEN]; char clusterId[TSDB_CLUSTER_ID_LEN];
char tags[TSDB_TAGS_LEN];
int8_t writeAuth; int8_t writeAuth;
int8_t superAuth; int8_t superAuth;
int8_t reserved1; int8_t reserved1;
...@@ -400,6 +402,7 @@ typedef struct { ...@@ -400,6 +402,7 @@ typedef struct {
int8_t extend; int8_t extend;
char user[TSDB_USER_LEN]; char user[TSDB_USER_LEN];
char pass[TSDB_PASS_LEN]; char pass[TSDB_PASS_LEN];
char tags[TSDB_TAGS_LEN];
int8_t privilege; int8_t privilege;
int8_t flag; int8_t flag;
} SCreateUserMsg, SAlterUserMsg; } SCreateUserMsg, SAlterUserMsg;
......
...@@ -100,42 +100,42 @@ ...@@ -100,42 +100,42 @@
#define TK_ALTER 82 #define TK_ALTER 82
#define TK_PASS 83 #define TK_PASS 83
#define TK_PRIVILEGE 84 #define TK_PRIVILEGE 84
#define TK_LOCAL 85 #define TK_TAGS 85
#define TK_COMPACT 86 #define TK_LOCAL 86
#define TK_LP 87 #define TK_COMPACT 87
#define TK_RP 88 #define TK_LP 88
#define TK_IF 89 #define TK_RP 89
#define TK_EXISTS 90 #define TK_IF 90
#define TK_AS 91 #define TK_EXISTS 91
#define TK_OUTPUTTYPE 92 #define TK_AS 92
#define TK_AGGREGATE 93 #define TK_OUTPUTTYPE 93
#define TK_BUFSIZE 94 #define TK_AGGREGATE 94
#define TK_PPS 95 #define TK_BUFSIZE 95
#define TK_TSERIES 96 #define TK_PPS 96
#define TK_DBS 97 #define TK_TSERIES 97
#define TK_STORAGE 98 #define TK_DBS 98
#define TK_QTIME 99 #define TK_STORAGE 99
#define TK_CONNS 100 #define TK_QTIME 100
#define TK_STATE 101 #define TK_CONNS 101
#define TK_COMMA 102 #define TK_STATE 102
#define TK_KEEP 103 #define TK_COMMA 103
#define TK_CACHE 104 #define TK_KEEP 104
#define TK_REPLICA 105 #define TK_CACHE 105
#define TK_QUORUM 106 #define TK_REPLICA 106
#define TK_DAYS 107 #define TK_QUORUM 107
#define TK_MINROWS 108 #define TK_DAYS 108
#define TK_MAXROWS 109 #define TK_MINROWS 109
#define TK_BLOCKS 110 #define TK_MAXROWS 110
#define TK_CTIME 111 #define TK_BLOCKS 111
#define TK_WAL 112 #define TK_CTIME 112
#define TK_FSYNC 113 #define TK_WAL 113
#define TK_COMP 114 #define TK_FSYNC 114
#define TK_PRECISION 115 #define TK_COMP 115
#define TK_UPDATE 116 #define TK_PRECISION 116
#define TK_CACHELAST 117 #define TK_UPDATE 117
#define TK_PARTITIONS 118 #define TK_CACHELAST 118
#define TK_UNSIGNED 119 #define TK_PARTITIONS 119
#define TK_TAGS 120 #define TK_UNSIGNED 120
#define TK_USING 121 #define TK_USING 121
#define TK_TO 122 #define TK_TO 122
#define TK_SPLIT 123 #define TK_SPLIT 123
...@@ -222,6 +222,7 @@ ...@@ -222,6 +222,7 @@
#define TK_VALUES 204 #define TK_VALUES 204
#define TK_FILE 205 #define TK_FILE 205
#define TK_SPACE 300 #define TK_SPACE 300
#define TK_COMMENT 301 #define TK_COMMENT 301
#define TK_ILLEGAL 302 #define TK_ILLEGAL 302
......
...@@ -74,6 +74,7 @@ SWords shellCommands[] = { ...@@ -74,6 +74,7 @@ SWords shellCommands[] = {
{"alter local tmrDebugFlag 143;", 0, 0, NULL}, {"alter local tmrDebugFlag 143;", 0, 0, NULL},
{"alter topic", 0, 0, NULL}, {"alter topic", 0, 0, NULL},
{"alter user <user_name> pass", 0, 0, NULL}, {"alter user <user_name> pass", 0, 0, NULL},
{"alter user <user_name> tags", 0, 0, NULL},
{"alter user <user_name> privilege read", 0, 0, NULL}, {"alter user <user_name> privilege read", 0, 0, NULL},
{"alter user <user_name> privilege write", 0, 0, NULL}, {"alter user <user_name> privilege write", 0, 0, NULL},
{"create table <anyword> using <stb_name> tags(", 0, 0, NULL}, {"create table <anyword> using <stb_name> tags(", 0, 0, NULL},
...@@ -82,7 +83,7 @@ SWords shellCommands[] = { ...@@ -82,7 +83,7 @@ SWords shellCommands[] = {
{"create dnode ", 0, 0, NULL}, {"create dnode ", 0, 0, NULL},
{"create topic", 0, 0, NULL}, {"create topic", 0, 0, NULL},
{"create function ", 0, 0, NULL}, {"create function ", 0, 0, NULL},
{"create user <anyword> pass", 0, 0, NULL}, {"create user <anyword> pass <anyword> tags", 0, 0, NULL},
{"compact vnode in", 0, 0, NULL}, {"compact vnode in", 0, 0, NULL},
{"describe <all_table>", 0, 0, NULL}, {"describe <all_table>", 0, 0, NULL},
#ifdef TD_ENTERPRISE #ifdef TD_ENTERPRISE
...@@ -124,7 +125,7 @@ SWords shellCommands[] = { ...@@ -124,7 +125,7 @@ SWords shellCommands[] = {
{"show variables;", 0, 0, NULL}, {"show variables;", 0, 0, NULL},
{"show vgroups;", 0, 0, NULL}, {"show vgroups;", 0, 0, NULL},
{"insert into <tb_name> values(", 0, 0, NULL}, {"insert into <tb_name> values(", 0, 0, NULL},
{"insert into <tb_name> using <stb_name> tags(", 0, 0, NULL}, {"insert into <tb_name> using <stb_name> tags( <anyword> ) values(", 0, 0, NULL},
{"use <db_name>", 0, 0, NULL}, {"use <db_name>", 0, 0, NULL},
{"quit", 0, 0, NULL} {"quit", 0, 0, NULL}
}; };
...@@ -359,7 +360,8 @@ void showHelp() { ...@@ -359,7 +360,8 @@ void showHelp() {
alter local resetlog; \n\ alter local resetlog; \n\
alter local DebugFlag 143; \n\ alter local DebugFlag 143; \n\
alter topic <topic_name>\n\ alter topic <topic_name>\n\
alter user <user_name> pass\n\ alter user <user_name> pass <password>;\n\
alter user <user_name> tags <privileges>;\n\
alter user <user_name> privilege read ;\n\ alter user <user_name> privilege read ;\n\
alter user <user_name> privilege write ;\n\ alter user <user_name> privilege write ;\n\
----- C ----- \n\ ----- C ----- \n\
...@@ -370,6 +372,7 @@ void showHelp() { ...@@ -370,6 +372,7 @@ void showHelp() {
create topic <top_name>\n\ create topic <top_name>\n\
create function <function_name>\n\ create function <function_name>\n\
create user <user_name> pass <password>;\n\ create user <user_name> pass <password>;\n\
create user <user_name> pass <password> tags <privileges>;\n\
compact vnode in (vgid,vgid,vgid);\n\ compact vnode in (vgid,vgid,vgid);\n\
----- D ----- \n\ ----- D ----- \n\
describe <all_table> ;\n\ describe <all_table> ;\n\
......
...@@ -202,6 +202,20 @@ typedef struct SDbObj { ...@@ -202,6 +202,20 @@ typedef struct SDbObj {
pthread_mutex_t mutex; pthread_mutex_t mutex;
} SDbObj; } SDbObj;
// old tags
typedef struct SUserObjOld {
char user[TSDB_USER_LEN];
char pass[TSDB_KEY_LEN];
char acct[TSDB_USER_LEN];
int64_t createdTime;
int8_t superAuth;
int8_t writeAuth;
int8_t reserved[10];
int8_t updateEnd[4];
int32_t refCount;
struct SAcctObj * pAcct;
} SUserObjOld;
typedef struct SUserObj { typedef struct SUserObj {
char user[TSDB_USER_LEN]; char user[TSDB_USER_LEN];
char pass[TSDB_KEY_LEN]; char pass[TSDB_KEY_LEN];
...@@ -210,6 +224,7 @@ typedef struct SUserObj { ...@@ -210,6 +224,7 @@ typedef struct SUserObj {
int8_t superAuth; int8_t superAuth;
int8_t writeAuth; int8_t writeAuth;
int8_t reserved[10]; int8_t reserved[10];
char tags[TSDB_TAGS_LEN];
int8_t updateEnd[4]; int8_t updateEnd[4];
int32_t refCount; int32_t refCount;
struct SAcctObj * pAcct; struct SAcctObj * pAcct;
......
...@@ -30,7 +30,7 @@ void mnodeIncUserRef(SUserObj *pUser); ...@@ -30,7 +30,7 @@ void mnodeIncUserRef(SUserObj *pUser);
void mnodeDecUserRef(SUserObj *pUser); void mnodeDecUserRef(SUserObj *pUser);
SUserObj *mnodeGetUserFromConn(void *pConn); SUserObj *mnodeGetUserFromConn(void *pConn);
char * mnodeGetUserFromMsg(void *pMnodeMsg); char * mnodeGetUserFromMsg(void *pMnodeMsg);
int32_t mnodeCreateUser(SAcctObj *pAcct, char *name, char *pass, void *pMsg); int32_t mnodeCreateUser(SAcctObj *pAcct, char *name, char *pass, char* tags, void *pMsg);
void mnodeDropAllUsers(SAcctObj *pAcct); void mnodeDropAllUsers(SAcctObj *pAcct);
int32_t mnodeCompactUsers(); int32_t mnodeCompactUsers();
......
...@@ -343,6 +343,9 @@ static int32_t mnodeProcessConnectMsg(SMnodeMsg *pMsg) { ...@@ -343,6 +343,9 @@ static int32_t mnodeProcessConnectMsg(SMnodeMsg *pMsg) {
memcpy(pConnectRsp->serverVersion, version, TSDB_VERSION_LEN); memcpy(pConnectRsp->serverVersion, version, TSDB_VERSION_LEN);
pConnectRsp->writeAuth = pUser->writeAuth; pConnectRsp->writeAuth = pUser->writeAuth;
pConnectRsp->superAuth = pUser->superAuth; pConnectRsp->superAuth = pUser->superAuth;
strcpy(pConnectRsp->tags, pUser->tags);
if(pUser->tags[0])
mInfo("TAGS server response to client. user=%s tags=%s", pUser->user, pUser->tags);
mnodeGetMnodeEpSetForShell(&pConnectRsp->epSet, false); mnodeGetMnodeEpSetForShell(&pConnectRsp->epSet, false);
......
...@@ -132,9 +132,9 @@ static int32_t mnodeUserActionRestored() { ...@@ -132,9 +132,9 @@ static int32_t mnodeUserActionRestored() {
if (numOfRows <= 0 && dnodeIsFirstDeploy()) { if (numOfRows <= 0 && dnodeIsFirstDeploy()) {
mInfo("dnode first deploy, create root user"); mInfo("dnode first deploy, create root user");
SAcctObj *pAcct = mnodeGetAcct(TSDB_DEFAULT_USER); SAcctObj *pAcct = mnodeGetAcct(TSDB_DEFAULT_USER);
mnodeCreateUser(pAcct, TSDB_DEFAULT_USER, TSDB_DEFAULT_PASS, NULL); mnodeCreateUser(pAcct, TSDB_DEFAULT_USER, TSDB_DEFAULT_PASS, NULL, NULL);
mnodeCreateUser(pAcct, "monitor", tsInternalPass, NULL); mnodeCreateUser(pAcct, "monitor", tsInternalPass, NULL, NULL);
mnodeCreateUser(pAcct, "_"TSDB_DEFAULT_USER, tsInternalPass, NULL); mnodeCreateUser(pAcct, "_"TSDB_DEFAULT_USER, tsInternalPass, NULL, NULL);
mnodeDecAcctRef(pAcct); mnodeDecAcctRef(pAcct);
} }
...@@ -229,7 +229,7 @@ static int32_t mnodeUpdateUser(SUserObj *pUser, void *pMsg) { ...@@ -229,7 +229,7 @@ static int32_t mnodeUpdateUser(SUserObj *pUser, void *pMsg) {
return code; return code;
} }
int32_t mnodeCreateUser(SAcctObj *pAcct, char *name, char *pass, void *pMsg) { int32_t mnodeCreateUser(SAcctObj *pAcct, char *name, char *pass, char *tags, void *pMsg) {
int32_t code = acctCheck(pAcct, ACCT_GRANT_USER); int32_t code = acctCheck(pAcct, ACCT_GRANT_USER);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
return code; return code;
...@@ -259,6 +259,10 @@ int32_t mnodeCreateUser(SAcctObj *pAcct, char *name, char *pass, void *pMsg) { ...@@ -259,6 +259,10 @@ int32_t mnodeCreateUser(SAcctObj *pAcct, char *name, char *pass, void *pMsg) {
tstrncpy(pUser->user, name, TSDB_USER_LEN); tstrncpy(pUser->user, name, TSDB_USER_LEN);
taosEncryptPass((uint8_t*) pass, strlen(pass), pUser->pass); taosEncryptPass((uint8_t*) pass, strlen(pass), pUser->pass);
strcpy(pUser->acct, pAcct->user); strcpy(pUser->acct, pAcct->user);
if (tags) {
strcpy(pUser->tags, tags);
}
pUser->createdTime = taosGetTimestampMs(); pUser->createdTime = taosGetTimestampMs();
pUser->superAuth = 0; pUser->superAuth = 0;
pUser->writeAuth = 1; pUser->writeAuth = 1;
...@@ -336,6 +340,14 @@ static int32_t mnodeGetUserMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pCo ...@@ -336,6 +340,14 @@ static int32_t mnodeGetUserMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pCo
pSchema[cols].bytes = htons(pShow->bytes[cols]); pSchema[cols].bytes = htons(pShow->bytes[cols]);
cols++; cols++;
// tags
pShow->bytes[cols] = TSDB_USER_LEN + VARSTR_HEADER_SIZE;
pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
strcpy(pSchema[cols].name, "tags");
pSchema[cols].bytes = htons(pShow->bytes[cols]);
cols++;
pMeta->numOfColumns = htons(cols); pMeta->numOfColumns = htons(cols);
strcpy(pMeta->tableFname, "show users"); strcpy(pMeta->tableFname, "show users");
pShow->numOfColumns = cols; pShow->numOfColumns = cols;
...@@ -417,6 +429,11 @@ static int32_t mnodeRetrieveUsers(SShowObj *pShow, char *data, int32_t rows, voi ...@@ -417,6 +429,11 @@ static int32_t mnodeRetrieveUsers(SShowObj *pShow, char *data, int32_t rows, voi
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pUser->acct, pShow->bytes[cols]); STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pUser->acct, pShow->bytes[cols]);
cols++; cols++;
// tags
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pUser->tags, pShow->bytes[cols]);
cols++;
numOfRows++; numOfRows++;
mnodeDecUserRef(pUser); mnodeDecUserRef(pUser);
} }
...@@ -450,7 +467,7 @@ static int32_t mnodeProcessCreateUserMsg(SMnodeMsg *pMsg) { ...@@ -450,7 +467,7 @@ static int32_t mnodeProcessCreateUserMsg(SMnodeMsg *pMsg) {
if (pOperUser->superAuth) { if (pOperUser->superAuth) {
SCreateUserMsg *pCreate = pMsg->rpcMsg.pCont; SCreateUserMsg *pCreate = pMsg->rpcMsg.pCont;
return mnodeCreateUser(pOperUser->pAcct, pCreate->user, pCreate->pass, pMsg); return mnodeCreateUser(pOperUser->pAcct, pCreate->user, pCreate->pass, pCreate->tags, pMsg);
} else { } else {
mError("user:%s, no rights to create user", pOperUser->user); mError("user:%s, no rights to create user", pOperUser->user);
return TSDB_CODE_MND_NO_RIGHTS; return TSDB_CODE_MND_NO_RIGHTS;
...@@ -536,6 +553,36 @@ static int32_t mnodeProcessAlterUserMsg(SMnodeMsg *pMsg) { ...@@ -536,6 +553,36 @@ static int32_t mnodeProcessAlterUserMsg(SMnodeMsg *pMsg) {
mError("user:%s, no rights to alter user", pOperUser->user); mError("user:%s, no rights to alter user", pOperUser->user);
code = TSDB_CODE_MND_NO_RIGHTS; code = TSDB_CODE_MND_NO_RIGHTS;
} }
// ALTER TAGS
} else if ((pAlter->flag & TSDB_ALTER_USER_TAGS) != 0) {
// check has right
bool hasRight = false;
if (strcmp(pUser->user, TSDB_DEFAULT_USER) == 0) {
hasRight = false;
} else if (strcmp(pUser->user, pUser->acct) == 0) {
hasRight = false;
} else if (strcmp(pOperUser->user, TSDB_DEFAULT_USER) == 0) {
hasRight = true;
} else if (strcmp(pUser->user, pOperUser->user) == 0) {
hasRight = false;
} else if (pOperUser->superAuth) {
if (strcmp(pUser->user, TSDB_DEFAULT_USER) == 0) {
hasRight = false;
} else if (strcmp(pOperUser->acct, pUser->acct) != 0) {
hasRight = false;
} else {
hasRight = true;
}
}
// set tags new values
if (hasRight) {
strcpy(pUser->tags, pAlter->tags);
code = mnodeUpdateUser(pUser, pMsg);
} else {
mError("user:%s, no rights to alter user tags", pOperUser->user);
code = TSDB_CODE_MND_NO_RIGHTS;
}
} else { } else {
mError("user:%s, no rights to alter user", pOperUser->user); mError("user:%s, no rights to alter user", pOperUser->user);
code = TSDB_CODE_MND_NO_RIGHTS; code = TSDB_CODE_MND_NO_RIGHTS;
......
...@@ -235,6 +235,7 @@ typedef struct SShowInfo { ...@@ -235,6 +235,7 @@ typedef struct SShowInfo {
typedef struct SUserInfo { typedef struct SUserInfo {
SStrToken user; SStrToken user;
SStrToken passwd; SStrToken passwd;
SStrToken tags; // format like tag1,tag2,tag3 ... splite with ','
SStrToken privilege; SStrToken privilege;
int16_t type; int16_t type;
} SUserInfo; } SUserInfo;
...@@ -358,9 +359,9 @@ void setShowOptions(SSqlInfo *pInfo, int32_t type, SStrToken* prefix, SStrToken* ...@@ -358,9 +359,9 @@ void setShowOptions(SSqlInfo *pInfo, int32_t type, SStrToken* prefix, SStrToken*
void setCreateDbInfo(SSqlInfo *pInfo, int32_t type, SStrToken *pToken, SCreateDbInfo *pDB, SStrToken *pIgExists); void setCreateDbInfo(SSqlInfo *pInfo, int32_t type, SStrToken *pToken, SCreateDbInfo *pDB, SStrToken *pIgExists);
void setCreateAcctSql(SSqlInfo *pInfo, int32_t type, SStrToken *pName, SStrToken *pPwd, SCreateAcctInfo *pAcctInfo); void setCreateAcctSql(SSqlInfo *pInfo, int32_t type, SStrToken *pName, SStrToken *pPwd, SCreateAcctInfo *pAcctInfo);
void setCreateUserSql(SSqlInfo *pInfo, SStrToken *pName, SStrToken *pPasswd); void setCreateUserSql(SSqlInfo *pInfo, SStrToken *pName, SStrToken *pPasswd, SStrToken *pTags);
void setKillSql(SSqlInfo *pInfo, int32_t type, SStrToken *ip); void setKillSql(SSqlInfo *pInfo, int32_t type, SStrToken *ip);
void setAlterUserSql(SSqlInfo *pInfo, int16_t type, SStrToken *pName, SStrToken* pPwd, SStrToken *pPrivilege); void setAlterUserSql(SSqlInfo *pInfo, int16_t type, SStrToken *pName, SStrToken* pPwd, SStrToken *pPrivilege, SStrToken *pTags);
void setCompactVnodeSql(SSqlInfo *pInfo, int32_t type, SArray *pParam); void setCompactVnodeSql(SSqlInfo *pInfo, int32_t type, SArray *pParam);
......
...@@ -161,8 +161,9 @@ cmd ::= DESC ids(X) cpxName(Y). { ...@@ -161,8 +161,9 @@ cmd ::= DESC ids(X) cpxName(Y). {
setDCLSqlElems(pInfo, TSDB_SQL_DESCRIBE_TABLE, 1, &X); setDCLSqlElems(pInfo, TSDB_SQL_DESCRIBE_TABLE, 1, &X);
} }
/////////////////////////////////THE ALTER STATEMENT//////////////////////////////////////// /////////////////////////////////THE ALTER STATEMENT////////////////////////////////////////
cmd ::= ALTER USER ids(X) PASS ids(Y). { setAlterUserSql(pInfo, TSDB_ALTER_USER_PASSWD, &X, &Y, NULL); } cmd ::= ALTER USER ids(X) PASS ids(Y). { setAlterUserSql(pInfo, TSDB_ALTER_USER_PASSWD, &X, &Y, NULL, NULL);}
cmd ::= ALTER USER ids(X) PRIVILEGE ids(Y). { setAlterUserSql(pInfo, TSDB_ALTER_USER_PRIVILEGES, &X, NULL, &Y);} cmd ::= ALTER USER ids(X) PRIVILEGE ids(Y). { setAlterUserSql(pInfo, TSDB_ALTER_USER_PRIVILEGES, &X, NULL, &Y, NULL);}
cmd ::= ALTER USER ids(X) TAGS ids(Y). { setAlterUserSql(pInfo, TSDB_ALTER_USER_TAGS, &X, NULL, NULL, &Y);}
cmd ::= ALTER DNODE ids(X) ids(Y). { setDCLSqlElems(pInfo, TSDB_SQL_CFG_DNODE, 2, &X, &Y); } cmd ::= ALTER DNODE ids(X) ids(Y). { setDCLSqlElems(pInfo, TSDB_SQL_CFG_DNODE, 2, &X, &Y); }
cmd ::= ALTER DNODE ids(X) ids(Y) ids(Z). { setDCLSqlElems(pInfo, TSDB_SQL_CFG_DNODE, 3, &X, &Y, &Z); } cmd ::= ALTER DNODE ids(X) ids(Y) ids(Z). { setDCLSqlElems(pInfo, TSDB_SQL_CFG_DNODE, 3, &X, &Y, &Z); }
cmd ::= ALTER LOCAL ids(X). { setDCLSqlElems(pInfo, TSDB_SQL_CFG_LOCAL, 1, &X); } cmd ::= ALTER LOCAL ids(X). { setDCLSqlElems(pInfo, TSDB_SQL_CFG_LOCAL, 1, &X); }
...@@ -201,7 +202,8 @@ cmd ::= CREATE DATABASE ifnotexists(Z) ids(X) db_optr(Y). { setCreateDbInfo(pIn ...@@ -201,7 +202,8 @@ cmd ::= CREATE DATABASE ifnotexists(Z) ids(X) db_optr(Y). { setCreateDbInfo(pIn
cmd ::= CREATE TOPIC ifnotexists(Z) ids(X) topic_optr(Y). { setCreateDbInfo(pInfo, TSDB_SQL_CREATE_DB, &X, &Y, &Z);} cmd ::= CREATE TOPIC ifnotexists(Z) ids(X) topic_optr(Y). { setCreateDbInfo(pInfo, TSDB_SQL_CREATE_DB, &X, &Y, &Z);}
cmd ::= CREATE FUNCTION ids(X) AS ids(Y) OUTPUTTYPE typename(Z) bufsize(B). { setCreateFuncInfo(pInfo, TSDB_SQL_CREATE_FUNCTION, &X, &Y, &Z, &B, 1);} cmd ::= CREATE FUNCTION ids(X) AS ids(Y) OUTPUTTYPE typename(Z) bufsize(B). { setCreateFuncInfo(pInfo, TSDB_SQL_CREATE_FUNCTION, &X, &Y, &Z, &B, 1);}
cmd ::= CREATE AGGREGATE FUNCTION ids(X) AS ids(Y) OUTPUTTYPE typename(Z) bufsize(B). { setCreateFuncInfo(pInfo, TSDB_SQL_CREATE_FUNCTION, &X, &Y, &Z, &B, 2);} cmd ::= CREATE AGGREGATE FUNCTION ids(X) AS ids(Y) OUTPUTTYPE typename(Z) bufsize(B). { setCreateFuncInfo(pInfo, TSDB_SQL_CREATE_FUNCTION, &X, &Y, &Z, &B, 2);}
cmd ::= CREATE USER ids(X) PASS ids(Y). { setCreateUserSql(pInfo, &X, &Y);} cmd ::= CREATE USER ids(X) PASS ids(Y). { setCreateUserSql(pInfo, &X, &Y, NULL);}
cmd ::= CREATE USER ids(X) PASS ids(Y) TAGS ids(Z). { setCreateUserSql(pInfo, &X, &Y, &Z);}
bufsize(Y) ::= . { Y.n = 0; } bufsize(Y) ::= . { Y.n = 0; }
bufsize(Y) ::= BUFSIZE INTEGER(X). { Y = X; } bufsize(Y) ::= BUFSIZE INTEGER(X). { Y = X; }
......
...@@ -1473,7 +1473,19 @@ void setCompactVnodeSql(SSqlInfo *pInfo, int32_t type, SArray *pParam) { ...@@ -1473,7 +1473,19 @@ void setCompactVnodeSql(SSqlInfo *pInfo, int32_t type, SArray *pParam) {
pInfo->list = pParam; pInfo->list = pParam;
} }
void setCreateUserSql(SSqlInfo *pInfo, SStrToken *pName, SStrToken *pPasswd) { bool removeSingleQuota(SStrToken* pStr) {
char * p1 = pStr->z;
char * p2 = pStr->z + pStr->n - 1;
if (pStr->n > 2 && *p1 == '\'' && *p2 == '\'') {
pStr->z ++;
pStr->n -= 2;
return true;
}
return false;
}
void setCreateUserSql(SSqlInfo *pInfo, SStrToken *pName, SStrToken *pPasswd, SStrToken *pTags) {
pInfo->type = TSDB_SQL_CREATE_USER; pInfo->type = TSDB_SQL_CREATE_USER;
if (pInfo->pMiscInfo == NULL) { if (pInfo->pMiscInfo == NULL) {
pInfo->pMiscInfo = calloc(1, sizeof(SMiscInfo)); pInfo->pMiscInfo = calloc(1, sizeof(SMiscInfo));
...@@ -1483,9 +1495,14 @@ void setCreateUserSql(SSqlInfo *pInfo, SStrToken *pName, SStrToken *pPasswd) { ...@@ -1483,9 +1495,14 @@ void setCreateUserSql(SSqlInfo *pInfo, SStrToken *pName, SStrToken *pPasswd) {
pInfo->pMiscInfo->user.user = *pName; pInfo->pMiscInfo->user.user = *pName;
pInfo->pMiscInfo->user.passwd = *pPasswd; pInfo->pMiscInfo->user.passwd = *pPasswd;
// set tags if have
if (pTags) {
pInfo->pMiscInfo->user.tags = *pTags;
removeSingleQuota(&pInfo->pMiscInfo->user.tags);
}
} }
void setAlterUserSql(SSqlInfo *pInfo, int16_t type, SStrToken *pName, SStrToken* pPwd, SStrToken *pPrivilege) { void setAlterUserSql(SSqlInfo *pInfo, int16_t type, SStrToken *pName, SStrToken* pPwd, SStrToken *pPrivilege, SStrToken *pTags) {
pInfo->type = TSDB_SQL_ALTER_USER; pInfo->type = TSDB_SQL_ALTER_USER;
if (pInfo->pMiscInfo == NULL) { if (pInfo->pMiscInfo == NULL) {
pInfo->pMiscInfo = calloc(1, sizeof(SMiscInfo)); pInfo->pMiscInfo = calloc(1, sizeof(SMiscInfo));
...@@ -1508,6 +1525,14 @@ void setAlterUserSql(SSqlInfo *pInfo, int16_t type, SStrToken *pName, SStrToken* ...@@ -1508,6 +1525,14 @@ void setAlterUserSql(SSqlInfo *pInfo, int16_t type, SStrToken *pName, SStrToken*
} else { } else {
pUser->privilege.type = TSDB_DATA_TYPE_NULL; pUser->privilege.type = TSDB_DATA_TYPE_NULL;
} }
// tags
if (pTags != NULL) {
pUser->tags = *pTags;
removeSingleQuota(&pUser->tags);
} else {
pUser->tags.type = TSDB_DATA_TYPE_NULL;
}
} }
void setKillSql(SSqlInfo *pInfo, int32_t type, SStrToken *id) { void setKillSql(SSqlInfo *pInfo, int32_t type, SStrToken *id) {
......
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册