mndUser.c 45.8 KB
Newer Older
H
refact  
Hongze Cheng 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
 *
 * This program is free software: you can use, redistribute, and/or modify
 * it under the terms of the GNU Affero General Public License, version 3
 * or later ("AGPL"), as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

S
Shengliang Guan 已提交
16
#define _DEFAULT_SOURCE
S
Shengliang Guan 已提交
17
#include "mndUser.h"
S
Shengliang Guan 已提交
18
#include "mndDb.h"
S
Shengliang Guan 已提交
19
#include "mndPrivilege.h"
S
Shengliang Guan 已提交
20
#include "mndShow.h"
21
#include "mndTopic.h"
S
Shengliang Guan 已提交
22
#include "mndTrans.h"
S
tbase64  
Shengliang Guan 已提交
23
#include "tbase64.h"
C
table  
cademfly 已提交
24
#include "mndStb.h"
S
Shengliang Guan 已提交
25

C
table  
cademfly 已提交
26
#define USER_VER_NUMBER   3
27
#define USER_RESERVE_SIZE 64
S
Shengliang Guan 已提交
28

S
Shengliang Guan 已提交
29 30 31 32
static int32_t  mndCreateDefaultUsers(SMnode *pMnode);
static SSdbRow *mndUserActionDecode(SSdbRaw *pRaw);
static int32_t  mndUserActionInsert(SSdb *pSdb, SUserObj *pUser);
static int32_t  mndUserActionDelete(SSdb *pSdb, SUserObj *pUser);
S
Shengliang Guan 已提交
33
static int32_t  mndUserActionUpdate(SSdb *pSdb, SUserObj *pOld, SUserObj *pNew);
S
Shengliang Guan 已提交
34 35 36 37 38 39
static int32_t  mndCreateUser(SMnode *pMnode, char *acct, SCreateUserReq *pCreate, SRpcMsg *pReq);
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  mndRetrieveUsers(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
S
Shengliang Guan 已提交
40
static void     mndCancelGetNextUser(SMnode *pMnode, void *pIter);
41 42
static int32_t  mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
static void     mndCancelGetNextPrivileges(SMnode *pMnode, void *pIter);
S
Shengliang Guan 已提交
43 44

int32_t mndInitUser(SMnode *pMnode) {
S
Shengliang Guan 已提交
45 46 47 48 49 50 51 52 53 54
  SSdbTable table = {
      .sdbType = SDB_USER,
      .keyType = SDB_KEY_BINARY,
      .deployFp = (SdbDeployFp)mndCreateDefaultUsers,
      .encodeFp = (SdbEncodeFp)mndUserActionEncode,
      .decodeFp = (SdbDecodeFp)mndUserActionDecode,
      .insertFp = (SdbInsertFp)mndUserActionInsert,
      .updateFp = (SdbUpdateFp)mndUserActionUpdate,
      .deleteFp = (SdbDeleteFp)mndUserActionDelete,
  };
S
Shengliang Guan 已提交
55

S
Shengliang Guan 已提交
56 57 58
  mndSetMsgHandle(pMnode, TDMT_MND_CREATE_USER, mndProcessCreateUserReq);
  mndSetMsgHandle(pMnode, TDMT_MND_ALTER_USER, mndProcessAlterUserReq);
  mndSetMsgHandle(pMnode, TDMT_MND_DROP_USER, mndProcessDropUserReq);
S
Shengliang Guan 已提交
59
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_AUTH, mndProcessGetUserAuthReq);
S
Shengliang Guan 已提交
60

S
Shengliang Guan 已提交
61 62
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_USER, mndRetrieveUsers);
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_USER, mndCancelGetNextUser);
S
Shengliang Guan 已提交
63 64
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_PRIVILEGES, mndRetrievePrivileges);
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_PRIVILEGES, mndCancelGetNextPrivileges);
S
Shengliang Guan 已提交
65 66 67 68 69 70 71
  return sdbSetTable(pMnode->pSdb, table);
}

void mndCleanupUser(SMnode *pMnode) {}

static int32_t mndCreateDefaultUser(SMnode *pMnode, char *acct, char *user, char *pass) {
  SUserObj userObj = {0};
S
Shengliang Guan 已提交
72
  taosEncryptPass_c((uint8_t *)pass, strlen(pass), userObj.pass);
S
Shengliang Guan 已提交
73 74 75 76
  tstrncpy(userObj.user, user, TSDB_USER_LEN);
  tstrncpy(userObj.acct, acct, TSDB_USER_LEN);
  userObj.createdTime = taosGetTimestampMs();
  userObj.updateTime = userObj.createdTime;
77 78
  userObj.sysInfo = 1;
  userObj.enable = 1;
S
Shengliang Guan 已提交
79 80

  if (strcmp(user, TSDB_DEFAULT_USER) == 0) {
81
    userObj.superUser = 1;
S
Shengliang Guan 已提交
82 83 84 85
  }

  SSdbRaw *pRaw = mndUserActionEncode(&userObj);
  if (pRaw == NULL) return -1;
S
Shengliang Guan 已提交
86
  (void)sdbSetRawStatus(pRaw, SDB_STATUS_READY);
S
Shengliang Guan 已提交
87

88
  mInfo("user:%s, will be created when deploying, raw:%p", userObj.user, pRaw);
89

90
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, NULL, "create-user");
91
  if (pTrans == NULL) {
S
Shengliang Guan 已提交
92
    sdbFreeRaw(pRaw);
93 94 95
    mError("user:%s, failed to create since %s", userObj.user, terrstr());
    return -1;
  }
96
  mInfo("trans:%d, used to create user:%s", pTrans->id, userObj.user);
97 98 99 100 101 102

  if (mndTransAppendCommitlog(pTrans, pRaw) != 0) {
    mError("trans:%d, failed to commit redo log since %s", pTrans->id, terrstr());
    mndTransDrop(pTrans);
    return -1;
  }
S
Shengliang Guan 已提交
103
  (void)sdbSetRawStatus(pRaw, SDB_STATUS_READY);
104 105 106 107 108 109 110 111 112

  if (mndTransPrepare(pMnode, pTrans) != 0) {
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
    mndTransDrop(pTrans);
    return -1;
  }

  mndTransDrop(pTrans);
  return 0;
S
Shengliang Guan 已提交
113 114 115 116 117 118 119 120 121 122
}

static int32_t mndCreateDefaultUsers(SMnode *pMnode) {
  if (mndCreateDefaultUser(pMnode, TSDB_DEFAULT_USER, TSDB_DEFAULT_USER, TSDB_DEFAULT_PASS) != 0) {
    return -1;
  }

  return 0;
}

123
SSdbRaw *mndUserActionEncode(SUserObj *pUser) {
124 125
  terrno = TSDB_CODE_OUT_OF_MEMORY;

S
Shengliang Guan 已提交
126 127
  int32_t numOfReadDbs = taosHashGetSize(pUser->readDbs);
  int32_t numOfWriteDbs = taosHashGetSize(pUser->writeDbs);
C
table  
cademfly 已提交
128 129
  int32_t numOfReadStbs = taosHashGetSize(pUser->readStbs);
  int32_t numOfWriteStbs = taosHashGetSize(pUser->writeStbs);
130
  int32_t numOfTopics = taosHashGetSize(pUser->topics);
C
table  
cademfly 已提交
131 132
  int32_t size = sizeof(SUserObj) + USER_RESERVE_SIZE + 
                (numOfReadDbs + numOfWriteDbs ) * TSDB_DB_FNAME_LEN +
133
                 numOfTopics * TSDB_TOPIC_FNAME_LEN;
S
Shengliang Guan 已提交
134

C
cademfly 已提交
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
  char *stb = taosHashIterate(pUser->readStbs, NULL);
  while (stb != NULL) {
    size_t keyLen = 0;
    void  *key = taosHashGetKey(stb, &keyLen);
    size += sizeof(int32_t);
    size += keyLen;

    size_t valueLen = 0;
    valueLen = strlen(stb);
    size += sizeof(int32_t);
    size += valueLen;
    stb = taosHashIterate(pUser->readStbs, stb);
  }

  stb = taosHashIterate(pUser->writeStbs, NULL);
  while (stb != NULL) {
    size_t keyLen = 0;
    void  *key = taosHashGetKey(stb, &keyLen);
    size += sizeof(int32_t);
    size += keyLen;
    
    size_t valueLen = 0;
    valueLen = strlen(stb);
    size += sizeof(int32_t);
    size += keyLen;
    stb = taosHashIterate(pUser->writeStbs, stb);
  }

163
  SSdbRaw *pRaw = sdbAllocRaw(SDB_USER, USER_VER_NUMBER, size);
164
  if (pRaw == NULL) goto _OVER;
S
Shengliang Guan 已提交
165 166

  int32_t dataPos = 0;
167 168 169 170 171 172
  SDB_SET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN, _OVER)
  SDB_SET_BINARY(pRaw, dataPos, pUser->pass, TSDB_PASSWORD_LEN, _OVER)
  SDB_SET_BINARY(pRaw, dataPos, pUser->acct, TSDB_USER_LEN, _OVER)
  SDB_SET_INT64(pRaw, dataPos, pUser->createdTime, _OVER)
  SDB_SET_INT64(pRaw, dataPos, pUser->updateTime, _OVER)
  SDB_SET_INT8(pRaw, dataPos, pUser->superUser, _OVER)
173 174 175
  SDB_SET_INT8(pRaw, dataPos, pUser->sysInfo, _OVER)
  SDB_SET_INT8(pRaw, dataPos, pUser->enable, _OVER)
  SDB_SET_INT8(pRaw, dataPos, pUser->reserve, _OVER)
176
  SDB_SET_INT32(pRaw, dataPos, pUser->authVersion, _OVER)
177 178
  SDB_SET_INT32(pRaw, dataPos, numOfReadDbs, _OVER)
  SDB_SET_INT32(pRaw, dataPos, numOfWriteDbs, _OVER)
179
  SDB_SET_INT32(pRaw, dataPos, numOfTopics, _OVER)
C
table  
cademfly 已提交
180 181
  SDB_SET_INT32(pRaw, dataPos, numOfReadStbs, _OVER)
  SDB_SET_INT32(pRaw, dataPos, numOfWriteStbs, _OVER)
182 183 184

  char *db = taosHashIterate(pUser->readDbs, NULL);
  while (db != NULL) {
185
    SDB_SET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER);
186 187 188 189 190
    db = taosHashIterate(pUser->readDbs, db);
  }

  db = taosHashIterate(pUser->writeDbs, NULL);
  while (db != NULL) {
191
    SDB_SET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER);
192 193 194
    db = taosHashIterate(pUser->writeDbs, db);
  }

195 196 197
  char *topic = taosHashIterate(pUser->topics, NULL);
  while (topic != NULL) {
    SDB_SET_BINARY(pRaw, dataPos, topic, TSDB_TOPIC_FNAME_LEN, _OVER);
198
    topic = taosHashIterate(pUser->topics, topic);
199 200
  }

C
cademfly 已提交
201
  stb = taosHashIterate(pUser->readStbs, NULL);
C
table  
cademfly 已提交
202
  while (stb != NULL) {
C
cademfly 已提交
203 204 205 206 207 208 209 210 211
    size_t keyLen = 0;
    void  *key = taosHashGetKey(stb, &keyLen);
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);

    size_t valueLen = 0;
    valueLen = strlen(stb);
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
C
table  
cademfly 已提交
212 213 214 215 216
    stb = taosHashIterate(pUser->readStbs, stb);
  }

  stb = taosHashIterate(pUser->writeStbs, NULL);
  while (stb != NULL) {
C
cademfly 已提交
217 218 219 220 221 222 223 224 225
    size_t keyLen = 0;
    void  *key = taosHashGetKey(stb, &keyLen);
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
    
    size_t valueLen = 0;
    valueLen = strlen(stb);
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
C
table  
cademfly 已提交
226 227 228
    stb = taosHashIterate(pUser->writeStbs, stb);
  }

229 230
  SDB_SET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
  SDB_SET_DATALEN(pRaw, dataPos, _OVER)
231 232 233

  terrno = 0;

234
_OVER:
235 236 237 238 239
  if (terrno != 0) {
    mError("user:%s, failed to encode to raw:%p since %s", pUser->user, pRaw, terrstr());
    sdbFreeRaw(pRaw);
    return NULL;
  }
S
Shengliang Guan 已提交
240

S
Shengliang Guan 已提交
241
  mTrace("user:%s, encode to raw:%p, row:%p", pUser->user, pRaw, pUser);
S
Shengliang Guan 已提交
242
  return pRaw;
S
Shengliang Guan 已提交
243 244
}

S
Shengliang Guan 已提交
245
static SSdbRow *mndUserActionDecode(SSdbRaw *pRaw) {
246
  terrno = TSDB_CODE_OUT_OF_MEMORY;
247 248
  SSdbRow  *pRow = NULL;
  SUserObj *pUser = NULL;
249

S
Shengliang Guan 已提交
250
  int8_t sver = 0;
251
  if (sdbGetRawSoftVer(pRaw, &sver) != 0) goto _OVER;
S
Shengliang Guan 已提交
252

C
table  
cademfly 已提交
253
  if (sver != 1 && sver != 2 && sver != 3) {
S
Shengliang Guan 已提交
254
    terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
255
    goto _OVER;
S
Shengliang Guan 已提交
256
  }
S
Shengliang Guan 已提交
257

258
  pRow = sdbAllocRow(sizeof(SUserObj));
259
  if (pRow == NULL) goto _OVER;
260

261
  pUser = sdbGetRowObj(pRow);
262
  if (pUser == NULL) goto _OVER;
263

S
Shengliang Guan 已提交
264
  int32_t dataPos = 0;
265 266 267 268 269 270
  SDB_GET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN, _OVER)
  SDB_GET_BINARY(pRaw, dataPos, pUser->pass, TSDB_PASSWORD_LEN, _OVER)
  SDB_GET_BINARY(pRaw, dataPos, pUser->acct, TSDB_USER_LEN, _OVER)
  SDB_GET_INT64(pRaw, dataPos, &pUser->createdTime, _OVER)
  SDB_GET_INT64(pRaw, dataPos, &pUser->updateTime, _OVER)
  SDB_GET_INT8(pRaw, dataPos, &pUser->superUser, _OVER)
271 272 273
  SDB_GET_INT8(pRaw, dataPos, &pUser->sysInfo, _OVER)
  SDB_GET_INT8(pRaw, dataPos, &pUser->enable, _OVER)
  SDB_GET_INT8(pRaw, dataPos, &pUser->reserve, _OVER)
274
  SDB_GET_INT32(pRaw, dataPos, &pUser->authVersion, _OVER)
275 276 277

  int32_t numOfReadDbs = 0;
  int32_t numOfWriteDbs = 0;
278
  int32_t numOfTopics = 0;
C
table  
cademfly 已提交
279 280
  int32_t numOfReadStbs = 0;
  int32_t numOfWriteStbs = 0;
281 282
  SDB_GET_INT32(pRaw, dataPos, &numOfReadDbs, _OVER)
  SDB_GET_INT32(pRaw, dataPos, &numOfWriteDbs, _OVER)
283 284 285
  if (sver >= 2) {
    SDB_GET_INT32(pRaw, dataPos, &numOfTopics, _OVER)
  }
C
table  
cademfly 已提交
286 287 288 289
  if(sver >= 3){
    SDB_GET_INT32(pRaw, dataPos, &numOfReadStbs, _OVER)
    SDB_GET_INT32(pRaw, dataPos, &numOfWriteStbs, _OVER)
  }
290

S
Shengliang Guan 已提交
291 292 293
  pUser->readDbs = taosHashInit(numOfReadDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
  pUser->writeDbs =
      taosHashInit(numOfWriteDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
294
  pUser->topics = taosHashInit(numOfTopics, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
C
table  
cademfly 已提交
295 296 297
  pUser->readStbs = taosHashInit(numOfReadStbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
  pUser->writeStbs =
      taosHashInit(numOfWriteStbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
298
  if (pUser->readDbs == NULL || pUser->writeDbs == NULL || pUser->topics == NULL) goto _OVER;
299 300 301

  for (int32_t i = 0; i < numOfReadDbs; ++i) {
    char db[TSDB_DB_FNAME_LEN] = {0};
302
    SDB_GET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER)
303 304 305 306 307 308
    int32_t len = strlen(db) + 1;
    taosHashPut(pUser->readDbs, db, len, db, TSDB_DB_FNAME_LEN);
  }

  for (int32_t i = 0; i < numOfWriteDbs; ++i) {
    char db[TSDB_DB_FNAME_LEN] = {0};
309
    SDB_GET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER)
310 311 312 313
    int32_t len = strlen(db) + 1;
    taosHashPut(pUser->writeDbs, db, len, db, TSDB_DB_FNAME_LEN);
  }

314 315 316 317 318 319 320 321 322
  if (sver >= 2) {
    for (int32_t i = 0; i < numOfTopics; ++i) {
      char topic[TSDB_TOPIC_FNAME_LEN] = {0};
      SDB_GET_BINARY(pRaw, dataPos, topic, TSDB_TOPIC_FNAME_LEN, _OVER)
      int32_t len = strlen(topic) + 1;
      taosHashPut(pUser->topics, topic, len, topic, TSDB_TOPIC_FNAME_LEN);
    }
  }

C
table  
cademfly 已提交
323 324
  if(sver >= 3){
    for (int32_t i = 0; i < numOfReadStbs; ++i) {
C
cademfly 已提交
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339
      int32_t keyLen = 0;
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);

      char *key = taosMemoryCalloc(keyLen + 1, sizeof(char));
      SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);

      int32_t valuelen = 0;
      SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
      char *value = taosMemoryCalloc(valuelen + 1, sizeof(char));
      SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)

      taosHashPut(pUser->readStbs, key, keyLen, value, valuelen);

      taosMemoryFree(key);
      taosMemoryFree(value);
C
table  
cademfly 已提交
340 341 342
    }

    for (int32_t i = 0; i < numOfWriteStbs; ++i) {
C
cademfly 已提交
343 344 345 346 347 348 349 350 351 352 353 354 355 356 357
      int32_t keyLen = 0;
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);

      char *key = taosMemoryCalloc(keyLen + 1, sizeof(char));
      SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);

      int32_t valuelen = 0;
      SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
      char *value = taosMemoryCalloc(valuelen + 1, sizeof(char));
      SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)

      taosHashPut(pUser->writeStbs, key, keyLen, value, valuelen);

      taosMemoryFree(key);
      taosMemoryFree(value);
C
table  
cademfly 已提交
358 359 360
    }
  }

361
  SDB_GET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
S
Shengliang Guan 已提交
362
  taosInitRWLatch(&pUser->lock);
363 364 365

  terrno = 0;

366
_OVER:
367
  if (terrno != 0) {
368 369 370 371 372
    mError("user:%s, failed to decode from raw:%p since %s", pUser == NULL ? "null" : pUser->user, pRaw, terrstr());
    if (pUser != NULL) {
      taosHashCleanup(pUser->readDbs);
      taosHashCleanup(pUser->writeDbs);
      taosHashCleanup(pUser->topics);
C
table  
cademfly 已提交
373 374
      taosHashCleanup(pUser->readStbs);
      taosHashCleanup(pUser->writeStbs);
375
    }
wafwerar's avatar
wafwerar 已提交
376
    taosMemoryFreeClear(pRow);
377 378
    return NULL;
  }
S
Shengliang Guan 已提交
379

S
Shengliang Guan 已提交
380
  mTrace("user:%s, decode from raw:%p, row:%p", pUser->user, pRaw, pUser);
S
Shengliang Guan 已提交
381
  return pRow;
S
Shengliang Guan 已提交
382
}
S
Shengliang Guan 已提交
383

S
Shengliang Guan 已提交
384
static int32_t mndUserActionInsert(SSdb *pSdb, SUserObj *pUser) {
S
Shengliang Guan 已提交
385
  mTrace("user:%s, perform insert action, row:%p", pUser->user, pUser);
S
Shengliang Guan 已提交
386

S
Shengliang Guan 已提交
387 388
  SAcctObj *pAcct = sdbAcquire(pSdb, SDB_ACCT, pUser->acct);
  if (pAcct == NULL) {
S
Shengliang Guan 已提交
389
    terrno = TSDB_CODE_MND_ACCT_NOT_EXIST;
S
Shengliang Guan 已提交
390
    mError("user:%s, failed to perform insert action since %s", pUser->user, terrstr());
S
Shengliang Guan 已提交
391
    return -1;
S
Shengliang Guan 已提交
392
  }
S
Shengliang Guan 已提交
393 394
  pUser->acctId = pAcct->acctId;
  sdbRelease(pSdb, pAcct);
S
Shengliang Guan 已提交
395

S
Shengliang Guan 已提交
396 397
  return 0;
}
S
Shengliang Guan 已提交
398

399 400 401 402 403 404 405 406
static int32_t mndUserDupObj(SUserObj *pUser, SUserObj *pNew) {
  memcpy(pNew, pUser, sizeof(SUserObj));
  pNew->authVersion++;
  pNew->updateTime = taosGetTimestampMs();

  taosRLockLatch(&pUser->lock);
  pNew->readDbs = mndDupDbHash(pUser->readDbs);
  pNew->writeDbs = mndDupDbHash(pUser->writeDbs);
C
table  
cademfly 已提交
407 408
  pNew->readStbs = mndDupTopicHash(pUser->readStbs);
  pNew->writeStbs = mndDupTopicHash(pUser->writeStbs);
409 410 411 412 413 414 415 416 417 418
  pNew->topics = mndDupTopicHash(pUser->topics);
  taosRUnLockLatch(&pUser->lock);

  if (pNew->readDbs == NULL || pNew->writeDbs == NULL || pNew->topics == NULL) {
    return -1;
  }
  return 0;
}

static void mndUserFreeObj(SUserObj *pUser) {
419 420
  taosHashCleanup(pUser->readDbs);
  taosHashCleanup(pUser->writeDbs);
421
  taosHashCleanup(pUser->topics);
C
table  
cademfly 已提交
422 423
  taosHashCleanup(pUser->readStbs);
  taosHashCleanup(pUser->writeStbs);
424 425
  pUser->readDbs = NULL;
  pUser->writeDbs = NULL;
426
  pUser->topics = NULL;
C
table  
cademfly 已提交
427 428
  pUser->readStbs = NULL;
  pUser->writeStbs = NULL;
429 430 431 432 433
}

static int32_t mndUserActionDelete(SSdb *pSdb, SUserObj *pUser) {
  mTrace("user:%s, perform delete action, row:%p", pUser->user, pUser);
  mndUserFreeObj(pUser);
S
Shengliang Guan 已提交
434 435 436
  return 0;
}

S
Shengliang Guan 已提交
437
static int32_t mndUserActionUpdate(SSdb *pSdb, SUserObj *pOld, SUserObj *pNew) {
S
Shengliang Guan 已提交
438
  mTrace("user:%s, perform update action, old row:%p new row:%p", pOld->user, pOld, pNew);
S
Shengliang Guan 已提交
439
  taosWLockLatch(&pOld->lock);
S
Shengliang Guan 已提交
440
  pOld->updateTime = pNew->updateTime;
D
dapan1121 已提交
441
  pOld->authVersion = pNew->authVersion;
442 443
  pOld->sysInfo = pNew->sysInfo;
  pOld->enable = pNew->enable;
S
Shengliang Guan 已提交
444
  memcpy(pOld->pass, pNew->pass, TSDB_PASSWORD_LEN);
wafwerar's avatar
wafwerar 已提交
445 446
  TSWAP(pOld->readDbs, pNew->readDbs);
  TSWAP(pOld->writeDbs, pNew->writeDbs);
447
  TSWAP(pOld->topics, pNew->topics);
C
table  
cademfly 已提交
448 449
  TSWAP(pOld->readStbs, pNew->readStbs);
  TSWAP(pOld->writeStbs, pNew->writeStbs);
S
Shengliang Guan 已提交
450
  taosWUnLockLatch(&pOld->lock);
451

S
Shengliang Guan 已提交
452 453 454
  return 0;
}

455
SUserObj *mndAcquireUser(SMnode *pMnode, const char *userName) {
S
Shengliang Guan 已提交
456 457 458
  SSdb     *pSdb = pMnode->pSdb;
  SUserObj *pUser = sdbAcquire(pSdb, SDB_USER, userName);
  if (pUser == NULL) {
dengyihao's avatar
dengyihao 已提交
459 460 461 462 463
    if (terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
      terrno = TSDB_CODE_MND_USER_NOT_EXIST;
    } else {
      terrno = TSDB_CODE_MND_USER_NOT_AVAILABLE;
    }
S
Shengliang Guan 已提交
464 465
  }
  return pUser;
S
Shengliang Guan 已提交
466
}
S
Shengliang Guan 已提交
467

S
Shengliang Guan 已提交
468 469 470
void mndReleaseUser(SMnode *pMnode, SUserObj *pUser) {
  SSdb *pSdb = pMnode->pSdb;
  sdbRelease(pSdb, pUser);
S
Shengliang Guan 已提交
471 472
}

S
Shengliang Guan 已提交
473
static int32_t mndCreateUser(SMnode *pMnode, char *acct, SCreateUserReq *pCreate, SRpcMsg *pReq) {
S
Shengliang Guan 已提交
474
  SUserObj userObj = {0};
S
Shengliang Guan 已提交
475 476
  taosEncryptPass_c((uint8_t *)pCreate->pass, strlen(pCreate->pass), userObj.pass);
  tstrncpy(userObj.user, pCreate->user, TSDB_USER_LEN);
S
Shengliang Guan 已提交
477 478 479
  tstrncpy(userObj.acct, acct, TSDB_USER_LEN);
  userObj.createdTime = taosGetTimestampMs();
  userObj.updateTime = userObj.createdTime;
480
  userObj.superUser = 0;  // pCreate->superUser;
481 482
  userObj.sysInfo = pCreate->sysInfo;
  userObj.enable = pCreate->enable;
S
Shengliang Guan 已提交
483

484
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "create-user");
S
Shengliang Guan 已提交
485
  if (pTrans == NULL) {
S
Shengliang Guan 已提交
486
    mError("user:%s, failed to create since %s", pCreate->user, terrstr());
S
Shengliang Guan 已提交
487 488
    return -1;
  }
489
  mInfo("trans:%d, used to create user:%s", pTrans->id, pCreate->user);
S
Shengliang Guan 已提交
490

491 492 493
  SSdbRaw *pCommitRaw = mndUserActionEncode(&userObj);
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
    mError("trans:%d, failed to commit redo log since %s", pTrans->id, terrstr());
S
Shengliang Guan 已提交
494
    mndTransDrop(pTrans);
S
Shengliang Guan 已提交
495
    return -1;
S
Shengliang Guan 已提交
496
  }
S
Shengliang Guan 已提交
497
  (void)sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
S
Shengliang Guan 已提交
498

S
Shengliang Guan 已提交
499
  if (mndTransPrepare(pMnode, pTrans) != 0) {
S
Shengliang Guan 已提交
500
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
S
Shengliang Guan 已提交
501
    mndTransDrop(pTrans);
S
Shengliang Guan 已提交
502
    return -1;
S
Shengliang Guan 已提交
503 504
  }

S
Shengliang Guan 已提交
505
  mndTransDrop(pTrans);
S
Shengliang Guan 已提交
506
  return 0;
S
Shengliang Guan 已提交
507 508
}

S
Shengliang Guan 已提交
509 510
static int32_t mndProcessCreateUserReq(SRpcMsg *pReq) {
  SMnode        *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
511 512 513 514 515
  int32_t        code = -1;
  SUserObj      *pUser = NULL;
  SUserObj      *pOperUser = NULL;
  SCreateUserReq createReq = {0};

S
Shengliang Guan 已提交
516
  if (tDeserializeSCreateUserReq(pReq->pCont, pReq->contLen, &createReq) != 0) {
S
Shengliang Guan 已提交
517
    terrno = TSDB_CODE_INVALID_MSG;
518
    goto _OVER;
S
Shengliang Guan 已提交
519
  }
S
Shengliang Guan 已提交
520

521
  mInfo("user:%s, start to create", createReq.user);
522 523 524
  if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CREATE_USER) != 0) {
    goto _OVER;
  }
S
Shengliang Guan 已提交
525

S
Shengliang Guan 已提交
526
  if (createReq.user[0] == 0) {
S
Shengliang Guan 已提交
527
    terrno = TSDB_CODE_MND_INVALID_USER_FORMAT;
528
    goto _OVER;
S
Shengliang Guan 已提交
529 530
  }

S
Shengliang Guan 已提交
531
  if (createReq.pass[0] == 0) {
S
Shengliang Guan 已提交
532
    terrno = TSDB_CODE_MND_INVALID_PASS_FORMAT;
533
    goto _OVER;
S
Shengliang Guan 已提交
534 535
  }

S
Shengliang Guan 已提交
536
  pUser = mndAcquireUser(pMnode, createReq.user);
S
Shengliang Guan 已提交
537
  if (pUser != NULL) {
S
Shengliang Guan 已提交
538
    terrno = TSDB_CODE_MND_USER_ALREADY_EXIST;
539
    goto _OVER;
S
Shengliang Guan 已提交
540 541
  }

542
  pOperUser = mndAcquireUser(pMnode, pReq->info.conn.user);
S
Shengliang Guan 已提交
543
  if (pOperUser == NULL) {
S
Shengliang Guan 已提交
544
    terrno = TSDB_CODE_MND_NO_USER_FROM_CONN;
545
    goto _OVER;
S
Shengliang Guan 已提交
546 547
  }

C
Cary Xu 已提交
548 549 550 551
  if ((terrno = grantCheck(TSDB_GRANT_USER)) != 0) {
    code = terrno;
    goto _OVER;
  }
552

S
Shengliang Guan 已提交
553
  code = mndCreateUser(pMnode, pOperUser->acct, &createReq, pReq);
S
Shengliang Guan 已提交
554
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
S
Shengliang Guan 已提交
555

556
_OVER:
S
Shengliang Guan 已提交
557
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
S
Shengliang Guan 已提交
558
    mError("user:%s, failed to create since %s", createReq.user, terrstr());
S
Shengliang Guan 已提交
559 560
  }

S
Shengliang Guan 已提交
561 562 563 564
  mndReleaseUser(pMnode, pUser);
  mndReleaseUser(pMnode, pOperUser);

  return code;
S
Shengliang Guan 已提交
565 566
}

S
Shengliang Guan 已提交
567
static int32_t mndAlterUser(SMnode *pMnode, SUserObj *pOld, SUserObj *pNew, SRpcMsg *pReq) {
568
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "alter-user");
S
Shengliang Guan 已提交
569
  if (pTrans == NULL) {
S
Shengliang Guan 已提交
570
    mError("user:%s, failed to alter since %s", pOld->user, terrstr());
S
Shengliang Guan 已提交
571 572
    return -1;
  }
573
  mInfo("trans:%d, used to alter user:%s", pTrans->id, pOld->user);
S
Shengliang Guan 已提交
574

575 576 577
  SSdbRaw *pCommitRaw = mndUserActionEncode(pNew);
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
S
Shengliang Guan 已提交
578 579 580
    mndTransDrop(pTrans);
    return -1;
  }
S
Shengliang Guan 已提交
581
  (void)sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
S
Shengliang Guan 已提交
582 583 584 585 586 587 588 589 590 591 592

  if (mndTransPrepare(pMnode, pTrans) != 0) {
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
    mndTransDrop(pTrans);
    return -1;
  }

  mndTransDrop(pTrans);
  return 0;
}

593
SHashObj *mndDupObjHash(SHashObj *pOld, int32_t dataLen) {
S
Shengliang Guan 已提交
594 595
  SHashObj *pNew =
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
S
Shengliang Guan 已提交
596 597 598 599 600 601 602 603
  if (pNew == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return NULL;
  }

  char *db = taosHashIterate(pOld, NULL);
  while (db != NULL) {
    int32_t len = strlen(db) + 1;
604
    if (taosHashPut(pNew, db, len, db, dataLen) != 0) {
S
Shengliang Guan 已提交
605 606
      taosHashCancelIterate(pOld, db);
      taosHashCleanup(pNew);
S
Shengliang Guan 已提交
607
      terrno = TSDB_CODE_OUT_OF_MEMORY;
S
Shengliang Guan 已提交
608 609 610 611 612 613 614 615
      return NULL;
    }
    db = taosHashIterate(pOld, db);
  }

  return pNew;
}

616 617 618 619
SHashObj *mndDupDbHash(SHashObj *pOld) { return mndDupObjHash(pOld, TSDB_DB_FNAME_LEN); }

SHashObj *mndDupTopicHash(SHashObj *pOld) { return mndDupObjHash(pOld, TSDB_TOPIC_FNAME_LEN); }

S
Shengliang Guan 已提交
620 621
static int32_t mndProcessAlterUserReq(SRpcMsg *pReq) {
  SMnode       *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
622 623
  SSdb         *pSdb = pMnode->pSdb;
  void         *pIter = NULL;
S
Shengliang Guan 已提交
624 625 626
  int32_t       code = -1;
  SUserObj     *pUser = NULL;
  SUserObj     *pOperUser = NULL;
S
Shengliang Guan 已提交
627
  SUserObj      newUser = {0};
S
Shengliang Guan 已提交
628 629
  SAlterUserReq alterReq = {0};

S
Shengliang Guan 已提交
630
  if (tDeserializeSAlterUserReq(pReq->pCont, pReq->contLen, &alterReq) != 0) {
S
Shengliang Guan 已提交
631
    terrno = TSDB_CODE_INVALID_MSG;
632
    goto _OVER;
S
Shengliang Guan 已提交
633
  }
S
Shengliang Guan 已提交
634

635
  mInfo("user:%s, start to alter", alterReq.user);
S
Shengliang Guan 已提交
636

S
Shengliang Guan 已提交
637
  if (alterReq.user[0] == 0) {
S
Shengliang Guan 已提交
638
    terrno = TSDB_CODE_MND_INVALID_USER_FORMAT;
639 640 641 642 643
    goto _OVER;
  }

  if (TSDB_ALTER_USER_PASSWD == alterReq.alterType && alterReq.pass[0] == 0) {
    terrno = TSDB_CODE_MND_INVALID_PASS_FORMAT;
644
    goto _OVER;
S
Shengliang Guan 已提交
645 646
  }

S
Shengliang Guan 已提交
647
  pUser = mndAcquireUser(pMnode, alterReq.user);
S
Shengliang Guan 已提交
648 649
  if (pUser == NULL) {
    terrno = TSDB_CODE_MND_USER_NOT_EXIST;
650
    goto _OVER;
S
Shengliang Guan 已提交
651 652
  }

653
  pOperUser = mndAcquireUser(pMnode, pReq->info.conn.user);
S
Shengliang Guan 已提交
654 655
  if (pOperUser == NULL) {
    terrno = TSDB_CODE_MND_NO_USER_FROM_CONN;
656
    goto _OVER;
S
Shengliang Guan 已提交
657 658
  }

659
  if (mndCheckAlterUserPrivilege(pOperUser, pUser, &alterReq) != 0) {
S
Shengliang Guan 已提交
660 661 662
    goto _OVER;
  }

663
  if (mndUserDupObj(pUser, &newUser) != 0) goto _OVER;
S
Shengliang Guan 已提交
664 665 666 667

  if (alterReq.alterType == TSDB_ALTER_USER_PASSWD) {
    char pass[TSDB_PASSWORD_LEN + 1] = {0};
    taosEncryptPass_c((uint8_t *)alterReq.pass, strlen(alterReq.pass), pass);
668
    memcpy(newUser.pass, pass, TSDB_PASSWORD_LEN);
S
Shengliang Guan 已提交
669 670 671
  }

  if (alterReq.alterType == TSDB_ALTER_USER_SUPERUSER) {
S
Shengliang Guan 已提交
672
    newUser.superUser = alterReq.superUser;
S
Shengliang Guan 已提交
673 674
  }

675 676 677 678 679 680 681 682
  if (alterReq.alterType == TSDB_ALTER_USER_ENABLE) {
    newUser.enable = alterReq.enable;
  }

  if (alterReq.alterType == TSDB_ALTER_USER_SYSINFO) {
    newUser.sysInfo = alterReq.sysInfo;
  }

S
Shengliang Guan 已提交
683
  if (alterReq.alterType == TSDB_ALTER_USER_ADD_READ_DB || alterReq.alterType == TSDB_ALTER_USER_ADD_ALL_DB) {
684 685 686
    if (strcmp(alterReq.objname, "1.*") != 0) {
      int32_t len = strlen(alterReq.objname) + 1;
      SDbObj *pDb = mndAcquireDb(pMnode, alterReq.objname);
S
Shengliang Guan 已提交
687 688 689 690
      if (pDb == NULL) {
        mndReleaseDb(pMnode, pDb);
        goto _OVER;
      }
691
      if (taosHashPut(newUser.readDbs, alterReq.objname, len, alterReq.objname, TSDB_DB_FNAME_LEN) != 0) {
S
Shengliang Guan 已提交
692 693 694 695 696 697 698 699 700 701 702 703
        mndReleaseDb(pMnode, pDb);
        goto _OVER;
      }
    } else {
      while (1) {
        SDbObj *pDb = NULL;
        pIter = sdbFetch(pSdb, SDB_DB, pIter, (void **)&pDb);
        if (pIter == NULL) break;
        int32_t len = strlen(pDb->name) + 1;
        taosHashPut(newUser.readDbs, pDb->name, len, pDb->name, TSDB_DB_FNAME_LEN);
        sdbRelease(pSdb, pDb);
      }
S
Shengliang Guan 已提交
704
    }
S
Shengliang Guan 已提交
705 706 707
  }

  if (alterReq.alterType == TSDB_ALTER_USER_ADD_WRITE_DB || alterReq.alterType == TSDB_ALTER_USER_ADD_ALL_DB) {
708 709 710
    if (strcmp(alterReq.objname, "1.*") != 0) {
      int32_t len = strlen(alterReq.objname) + 1;
      SDbObj *pDb = mndAcquireDb(pMnode, alterReq.objname);
S
Shengliang Guan 已提交
711 712 713 714
      if (pDb == NULL) {
        mndReleaseDb(pMnode, pDb);
        goto _OVER;
      }
715
      if (taosHashPut(newUser.writeDbs, alterReq.objname, len, alterReq.objname, TSDB_DB_FNAME_LEN) != 0) {
S
Shengliang Guan 已提交
716 717 718 719 720 721 722 723 724 725 726 727
        mndReleaseDb(pMnode, pDb);
        goto _OVER;
      }
    } else {
      while (1) {
        SDbObj *pDb = NULL;
        pIter = sdbFetch(pSdb, SDB_DB, pIter, (void **)&pDb);
        if (pIter == NULL) break;
        int32_t len = strlen(pDb->name) + 1;
        taosHashPut(newUser.writeDbs, pDb->name, len, pDb->name, TSDB_DB_FNAME_LEN);
        sdbRelease(pSdb, pDb);
      }
S
Shengliang Guan 已提交
728 729 730
    }
  }

S
Shengliang Guan 已提交
731
  if (alterReq.alterType == TSDB_ALTER_USER_REMOVE_READ_DB || alterReq.alterType == TSDB_ALTER_USER_REMOVE_ALL_DB) {
732 733 734
    if (strcmp(alterReq.objname, "1.*") != 0) {
      int32_t len = strlen(alterReq.objname) + 1;
      SDbObj *pDb = mndAcquireDb(pMnode, alterReq.objname);
S
Shengliang Guan 已提交
735 736 737 738
      if (pDb == NULL) {
        mndReleaseDb(pMnode, pDb);
        goto _OVER;
      }
739
      taosHashRemove(newUser.readDbs, alterReq.objname, len);
S
Shengliang Guan 已提交
740 741 742 743
    } else {
      taosHashClear(newUser.readDbs);
    }
  }
S
Shengliang Guan 已提交
744

S
Shengliang Guan 已提交
745
  if (alterReq.alterType == TSDB_ALTER_USER_REMOVE_WRITE_DB || alterReq.alterType == TSDB_ALTER_USER_REMOVE_ALL_DB) {
746 747 748
    if (strcmp(alterReq.objname, "1.*") != 0) {
      int32_t len = strlen(alterReq.objname) + 1;
      SDbObj *pDb = mndAcquireDb(pMnode, alterReq.objname);
S
Shengliang Guan 已提交
749 750 751 752
      if (pDb == NULL) {
        mndReleaseDb(pMnode, pDb);
        goto _OVER;
      }
753
      taosHashRemove(newUser.writeDbs, alterReq.objname, len);
S
Shengliang Guan 已提交
754 755 756
    } else {
      taosHashClear(newUser.writeDbs);
    }
S
Shengliang Guan 已提交
757 758
  }

C
table  
cademfly 已提交
759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812
  if (alterReq.alterType == TSDB_ALTER_USER_ADD_READ_TABLE || alterReq.alterType == TSDB_ALTER_USER_ADD_ALL_TABLE) {
    if (strcmp(alterReq.tabName, "1.*") != 0) {
      char tbFName[TSDB_TABLE_FNAME_LEN] = {0};
      snprintf(tbFName, sizeof(tbFName), "%s.%s", alterReq.objname, alterReq.tabName);

      int32_t len = strlen(tbFName) + 1;
      SStbObj *pStb = mndAcquireStb(pMnode, tbFName);
      if (pStb == NULL) {
        mndReleaseStb(pMnode, pStb);
        goto _OVER;
      }
      if (taosHashPut(newUser.readStbs, tbFName, len, tbFName, TSDB_TABLE_NAME_LEN) != 0) {
        mndReleaseStb(pMnode, pStb);
        goto _OVER;
      }
    } else {
      while (1) {
        SStbObj *pStb = NULL;
        pIter = sdbFetch(pSdb, SDB_STB, pIter, (void **)&pStb);
        if (pIter == NULL) break;
        int32_t len = strlen(pStb->name) + 1;
        taosHashPut(newUser.readStbs, pStb->name, len, pStb->name, TSDB_TABLE_NAME_LEN);
        sdbRelease(pSdb, pStb);
      }
    }
  }

  if (alterReq.alterType == TSDB_ALTER_USER_ADD_WRITE_TABLE || alterReq.alterType == TSDB_ALTER_USER_ADD_ALL_TABLE) {
    if (strcmp(alterReq.tabName, "1.*") != 0) {
      char tbFName[TSDB_TABLE_FNAME_LEN] = {0};
      snprintf(tbFName, sizeof(tbFName), "%s.%s", alterReq.objname, alterReq.tabName);

      int32_t len = strlen(tbFName) + 1;
      SStbObj *pStb = mndAcquireStb(pMnode, tbFName);
      if (pStb == NULL) {
        mndReleaseStb(pMnode, pStb);
        goto _OVER;
      }
      if (taosHashPut(newUser.writeStbs, tbFName, len, tbFName, TSDB_TABLE_NAME_LEN) != 0) {
        mndReleaseStb(pMnode, pStb);
        goto _OVER;
      }
    } else {
      while (1) {
        SStbObj *pStb = NULL;
        pIter = sdbFetch(pSdb, SDB_STB, pIter, (void **)&pStb);
        if (pIter == NULL) break;
        int32_t len = strlen(pStb->name) + 1;
        taosHashPut(newUser.writeStbs, pStb->name, len, pStb->name, TSDB_DB_FNAME_LEN);
        sdbRelease(pSdb, pStb);
      }
    }
  }

813 814 815 816 817 818 819 820 821 822
  if (alterReq.alterType == TSDB_ALTER_USER_ADD_SUBSCRIBE_TOPIC) {
    int32_t      len = strlen(alterReq.objname) + 1;
    SMqTopicObj *pTopic = mndAcquireTopic(pMnode, alterReq.objname);
    if (pTopic == NULL) {
      mndReleaseTopic(pMnode, pTopic);
      goto _OVER;
    }
    taosHashPut(newUser.topics, pTopic->name, len, pTopic->name, TSDB_TOPIC_FNAME_LEN);
  }

C
cademfly 已提交
823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864
  if (alterReq.alterType == TSDB_ALTER_USER_ADD_READ_TAG) {
    char tbFName[TSDB_TABLE_FNAME_LEN] = {0};
    snprintf(tbFName, sizeof(tbFName), "%s.%s", alterReq.objname, alterReq.tabName);

    int32_t len = strlen(tbFName) + 1;
    SStbObj *pStb = mndAcquireStb(pMnode, tbFName);
    if (pStb == NULL) {
      mndReleaseStb(pMnode, pStb);
      goto _OVER;
    }
    if(alterReq.tagCond == NULL){
      mndReleaseStb(pMnode, pStb);
      goto _OVER;
    }
    int32_t condLen = strlen(alterReq.tagCond);
    if (taosHashPut(newUser.readStbs, tbFName, len, alterReq.tagCond, strlen(alterReq.tagCond)) != 0) {
      mndReleaseStb(pMnode, pStb);
      goto _OVER;
    }
  }

  if (alterReq.alterType == TSDB_ALTER_USER_ADD_WRITE_TAG) {
    char tbFName[TSDB_TABLE_FNAME_LEN] = {0};
    snprintf(tbFName, sizeof(tbFName), "%s.%s", alterReq.objname, alterReq.tabName);

    int32_t len = strlen(tbFName) + 1;
    SStbObj *pStb = mndAcquireStb(pMnode, tbFName);
    if (pStb == NULL) {
      mndReleaseStb(pMnode, pStb);
      goto _OVER;
    }
    if(alterReq.tagCond == NULL){
      mndReleaseStb(pMnode, pStb);
      goto _OVER;
    }
    int32_t condLen = strlen(alterReq.tagCond);
    if (taosHashPut(newUser.writeStbs, tbFName, len, alterReq.tagCond, condLen) != 0) {
      mndReleaseStb(pMnode, pStb);
      goto _OVER;
    }
  }

865 866 867 868 869 870 871 872 873 874
  if (alterReq.alterType == TSDB_ALTER_USER_REMOVE_SUBSCRIBE_TOPIC) {
    int32_t      len = strlen(alterReq.objname) + 1;
    SMqTopicObj *pTopic = mndAcquireTopic(pMnode, alterReq.objname);
    if (pTopic == NULL) {
      mndReleaseTopic(pMnode, pTopic);
      goto _OVER;
    }
    taosHashRemove(newUser.topics, alterReq.objname, len);
  }

S
Shengliang Guan 已提交
875
  code = mndAlterUser(pMnode, pUser, &newUser, pReq);
S
Shengliang Guan 已提交
876
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
S
Shengliang Guan 已提交
877

878
_OVER:
S
Shengliang Guan 已提交
879
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
S
Shengliang Guan 已提交
880
    mError("user:%s, failed to alter since %s", alterReq.user, terrstr());
S
Shengliang Guan 已提交
881 882
  }

S
Shengliang Guan 已提交
883 884
  mndReleaseUser(pMnode, pOperUser);
  mndReleaseUser(pMnode, pUser);
885
  mndUserFreeObj(&newUser);
S
Shengliang Guan 已提交
886 887

  return code;
S
Shengliang Guan 已提交
888 889
}

S
Shengliang Guan 已提交
890
static int32_t mndDropUser(SMnode *pMnode, SRpcMsg *pReq, SUserObj *pUser) {
891
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "drop-user");
S
Shengliang Guan 已提交
892 893 894 895
  if (pTrans == NULL) {
    mError("user:%s, failed to drop since %s", pUser->user, terrstr());
    return -1;
  }
896
  mInfo("trans:%d, used to drop user:%s", pTrans->id, pUser->user);
S
Shengliang Guan 已提交
897

898 899 900
  SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
S
Shengliang Guan 已提交
901 902 903
    mndTransDrop(pTrans);
    return -1;
  }
S
Shengliang Guan 已提交
904
  (void)sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED);
S
Shengliang Guan 已提交
905 906 907 908 909 910 911 912 913 914 915

  if (mndTransPrepare(pMnode, pTrans) != 0) {
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
    mndTransDrop(pTrans);
    return -1;
  }

  mndTransDrop(pTrans);
  return 0;
}

S
Shengliang Guan 已提交
916 917
static int32_t mndProcessDropUserReq(SRpcMsg *pReq) {
  SMnode      *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
918 919 920 921
  int32_t      code = -1;
  SUserObj    *pUser = NULL;
  SDropUserReq dropReq = {0};

S
Shengliang Guan 已提交
922
  if (tDeserializeSDropUserReq(pReq->pCont, pReq->contLen, &dropReq) != 0) {
S
Shengliang Guan 已提交
923
    terrno = TSDB_CODE_INVALID_MSG;
924
    goto _OVER;
S
Shengliang Guan 已提交
925
  }
S
Shengliang Guan 已提交
926

927
  mInfo("user:%s, start to drop", dropReq.user);
928 929 930
  if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_DROP_USER) != 0) {
    goto _OVER;
  }
S
Shengliang Guan 已提交
931

S
Shengliang Guan 已提交
932
  if (dropReq.user[0] == 0) {
S
Shengliang Guan 已提交
933
    terrno = TSDB_CODE_MND_INVALID_USER_FORMAT;
934
    goto _OVER;
S
Shengliang Guan 已提交
935 936
  }

S
Shengliang Guan 已提交
937
  pUser = mndAcquireUser(pMnode, dropReq.user);
S
Shengliang Guan 已提交
938 939
  if (pUser == NULL) {
    terrno = TSDB_CODE_MND_USER_NOT_EXIST;
940
    goto _OVER;
S
Shengliang Guan 已提交
941 942
  }

S
Shengliang Guan 已提交
943
  code = mndDropUser(pMnode, pReq, pUser);
S
Shengliang Guan 已提交
944
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
S
Shengliang Guan 已提交
945

946
_OVER:
S
Shengliang Guan 已提交
947
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
S
Shengliang Guan 已提交
948
    mError("user:%s, failed to drop since %s", dropReq.user, terrstr());
S
Shengliang Guan 已提交
949 950
  }

S
Shengliang Guan 已提交
951 952
  mndReleaseUser(pMnode, pUser);
  return code;
S
Shengliang Guan 已提交
953 954
}

S
Shengliang Guan 已提交
955 956
static int32_t mndProcessGetUserAuthReq(SRpcMsg *pReq) {
  SMnode         *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
957 958 959 960 961
  int32_t         code = -1;
  SUserObj       *pUser = NULL;
  SGetUserAuthReq authReq = {0};
  SGetUserAuthRsp authRsp = {0};

S
Shengliang Guan 已提交
962
  if (tDeserializeSGetUserAuthReq(pReq->pCont, pReq->contLen, &authReq) != 0) {
S
Shengliang Guan 已提交
963
    terrno = TSDB_CODE_INVALID_MSG;
964
    goto _OVER;
S
Shengliang Guan 已提交
965
  }
S
Shengliang Guan 已提交
966 967 968 969 970 971

  mTrace("user:%s, start to get auth", authReq.user);

  pUser = mndAcquireUser(pMnode, authReq.user);
  if (pUser == NULL) {
    terrno = TSDB_CODE_MND_USER_NOT_EXIST;
972
    goto _OVER;
S
Shengliang Guan 已提交
973 974
  }

D
dapan 已提交
975 976 977
  code = mndSetUserAuthRsp(pMnode, pUser, &authRsp);
  if (code) {
    goto _OVER;
S
Shengliang Guan 已提交
978 979
  }

S
Shengliang Guan 已提交
980
  int32_t contLen = tSerializeSGetUserAuthRsp(NULL, 0, &authRsp);
S
Shengliang Guan 已提交
981 982 983
  void   *pRsp = rpcMallocCont(contLen);
  if (pRsp == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
984
    goto _OVER;
S
Shengliang Guan 已提交
985 986
  }

S
Shengliang Guan 已提交
987
  tSerializeSGetUserAuthRsp(pRsp, contLen, &authRsp);
S
Shengliang Guan 已提交
988

S
Shengliang Guan 已提交
989 990
  pReq->info.rsp = pRsp;
  pReq->info.rspLen = contLen;
S
Shengliang Guan 已提交
991 992
  code = 0;

993
_OVER:
994

S
Shengliang Guan 已提交
995
  mndReleaseUser(pMnode, pUser);
S
Shengliang Guan 已提交
996
  tFreeSGetUserAuthRsp(&authRsp);
S
Shengliang Guan 已提交
997 998 999 1000

  return code;
}

S
Shengliang Guan 已提交
1001 1002
static int32_t mndRetrieveUsers(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
  SMnode   *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013
  SSdb     *pSdb = pMnode->pSdb;
  int32_t   numOfRows = 0;
  SUserObj *pUser = NULL;
  int32_t   cols = 0;
  char     *pWrite;

  while (numOfRows < rows) {
    pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
    if (pShow->pIter == NULL) break;

    cols = 0;
1014
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
1015
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
1016
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
1017
    colDataSetVal(pColInfo, numOfRows, (const char *)name, false);
1018

wafwerar's avatar
wafwerar 已提交
1019 1020
    cols++;
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
1021
    colDataSetVal(pColInfo, numOfRows, (const char *)&pUser->superUser, false);
1022

1023 1024
    cols++;
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
1025
    colDataSetVal(pColInfo, numOfRows, (const char *)&pUser->enable, false);
1026 1027 1028

    cols++;
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
1029
    colDataSetVal(pColInfo, numOfRows, (const char *)&pUser->sysInfo, false);
1030

wafwerar's avatar
wafwerar 已提交
1031 1032
    cols++;
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
1033
    colDataSetVal(pColInfo, numOfRows, (const char *)&pUser->createdTime, false);
S
Shengliang Guan 已提交
1034 1035 1036 1037 1038

    numOfRows++;
    sdbRelease(pSdb, pUser);
  }

1039
  pShow->numOfRows += numOfRows;
S
Shengliang Guan 已提交
1040 1041 1042 1043 1044 1045
  return numOfRows;
}

static void mndCancelGetNextUser(SMnode *pMnode, void *pIter) {
  SSdb *pSdb = pMnode->pSdb;
  sdbCancelFetch(pSdb, pIter);
S
Shengliang Guan 已提交
1046
}
D
dapan 已提交
1047

S
Shengliang Guan 已提交
1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064
static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
  SMnode   *pMnode = pReq->info.node;
  SSdb     *pSdb = pMnode->pSdb;
  int32_t   numOfRows = 0;
  SUserObj *pUser = NULL;
  int32_t   cols = 0;
  char     *pWrite;

  while (numOfRows < rows) {
    pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
    if (pShow->pIter == NULL) break;

    int32_t numOfReadDbs = taosHashGetSize(pUser->readDbs);
    int32_t numOfWriteDbs = taosHashGetSize(pUser->writeDbs);
    int32_t numOfTopics = taosHashGetSize(pUser->topics);
    if (numOfRows + numOfReadDbs + numOfWriteDbs + numOfTopics >= rows) break;

1065 1066
    if (pUser->superUser) {
      cols = 0;
X
Xiaoyu Wang 已提交
1067
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
1068
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
X
Xiaoyu Wang 已提交
1069
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1070
      colDataSetVal(pColInfo, numOfRows, (const char *)userName, false);
1071 1072 1073 1074

      char privilege[20] = {0};
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "all", pShow->pMeta->pSchemas[cols].bytes);
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1075
      colDataSetVal(pColInfo, numOfRows, (const char *)privilege, false);
1076 1077 1078 1079

      char objName[20] = {0};
      STR_WITH_MAXSIZE_TO_VARSTR(objName, "all", pShow->pMeta->pSchemas[cols].bytes);
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1080
      colDataSetVal(pColInfo, numOfRows, (const char *)objName, false);
1081 1082 1083 1084

      numOfRows++;
    }

S
Shengliang Guan 已提交
1085 1086 1087
    char *db = taosHashIterate(pUser->readDbs, NULL);
    while (db != NULL) {
      cols = 0;
X
Xiaoyu Wang 已提交
1088
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
S
Shengliang Guan 已提交
1089
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
X
Xiaoyu Wang 已提交
1090
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1091
      colDataSetVal(pColInfo, numOfRows, (const char *)userName, false);
S
Shengliang Guan 已提交
1092 1093 1094 1095

      char privilege[20] = {0};
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "read", pShow->pMeta->pSchemas[cols].bytes);
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1096
      colDataSetVal(pColInfo, numOfRows, (const char *)privilege, false);
S
Shengliang Guan 已提交
1097 1098 1099 1100 1101 1102 1103

      SName name = {0};
      char  objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
      tNameFromString(&name, db, T_NAME_ACCT | T_NAME_DB);
      tNameGetDbName(&name, varDataVal(objName));
      varDataSetLen(objName, strlen(varDataVal(objName)));
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1104
      colDataSetVal(pColInfo, numOfRows, (const char *)objName, false);
S
Shengliang Guan 已提交
1105 1106 1107 1108 1109 1110 1111 1112

      numOfRows++;
      db = taosHashIterate(pUser->readDbs, db);
    }

    db = taosHashIterate(pUser->writeDbs, NULL);
    while (db != NULL) {
      cols = 0;
1113
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
S
Shengliang Guan 已提交
1114
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
1115
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1116
      colDataSetVal(pColInfo, numOfRows, (const char *)userName, false);
S
Shengliang Guan 已提交
1117 1118 1119 1120

      char privilege[20] = {0};
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "write", pShow->pMeta->pSchemas[cols].bytes);
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1121
      colDataSetVal(pColInfo, numOfRows, (const char *)privilege, false);
S
Shengliang Guan 已提交
1122 1123 1124 1125 1126 1127 1128

      SName name = {0};
      char  objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
      tNameFromString(&name, db, T_NAME_ACCT | T_NAME_DB);
      tNameGetDbName(&name, varDataVal(objName));
      varDataSetLen(objName, strlen(varDataVal(objName)));
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1129
      colDataSetVal(pColInfo, numOfRows, (const char *)objName, false);
S
Shengliang Guan 已提交
1130 1131 1132 1133 1134

      numOfRows++;
      db = taosHashIterate(pUser->writeDbs, db);
    }

C
table  
cademfly 已提交
1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146
    char *stb = taosHashIterate(pUser->readStbs, NULL);
    while (stb != NULL) {
      cols = 0;
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
      colDataSetVal(pColInfo, numOfRows, (const char *)userName, false);

      char privilege[20] = {0};
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "read", pShow->pMeta->pSchemas[cols].bytes);
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
      colDataSetVal(pColInfo, numOfRows, (const char *)privilege, false);
C
cademfly 已提交
1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165
      
      size_t superTableLen = 0;
      void  *superTable = taosHashGetKey(stb, &superTableLen);
      char  objName[TSDB_TABLE_NAME_LEN] = {0};
      mndExtractTbNameFromStbFullName(superTable, objName, TSDB_TABLE_NAME_LEN);

      SNode  *pAst = NULL;
      int32_t code = nodesStringToNode(stb, &pAst);

      char *buf = taosMemoryCalloc(TSDB_EXPLAIN_RESULT_ROW_SIZE, sizeof(char));
      int32_t sqlLen = 0;
      nodesNodeToSQL(pAst, buf, TSDB_EXPLAIN_RESULT_ROW_SIZE * sizeof(char), &sqlLen);

      char *value = taosMemoryCalloc(sqlLen + TSDB_TABLE_NAME_LEN + 1, sizeof(char));

      sprintf(value, "%s(%s)", objName, buf);

      char *obj = taosMemoryCalloc(sqlLen + TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE + 1, sizeof(char));
      STR_WITH_MAXSIZE_TO_VARSTR(obj, value, pShow->pMeta->pSchemas[cols].bytes);
C
table  
cademfly 已提交
1166 1167

      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
C
cademfly 已提交
1168 1169 1170 1171 1172
      colDataSetVal(pColInfo, numOfRows, (const char *)obj, false);

      taosMemoryFree(value);
      taosMemoryFree(buf);
      taosMemoryFree(obj);
C
table  
cademfly 已提交
1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190

      numOfRows++;
      stb = taosHashIterate(pUser->readStbs, stb);
    }

    stb = taosHashIterate(pUser->writeStbs, NULL);
    while (stb != NULL) {
      cols = 0;
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
      colDataSetVal(pColInfo, numOfRows, (const char *)userName, false);

      char privilege[20] = {0};
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "write", pShow->pMeta->pSchemas[cols].bytes);
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
      colDataSetVal(pColInfo, numOfRows, (const char *)privilege, false);

C
cademfly 已提交
1191 1192
      size_t superTableLen = 0;
      void  *superTable = taosHashGetKey(stb, &superTableLen);
C
table  
cademfly 已提交
1193
      char  objName[TSDB_TABLE_NAME_LEN] = {0};
C
cademfly 已提交
1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209
      mndExtractTbNameFromStbFullName(superTable, objName, TSDB_TABLE_NAME_LEN);

      SNode  *pAst = NULL;
      int32_t code = nodesStringToNode(stb, &pAst);

      char *buf = taosMemoryCalloc(TSDB_EXPLAIN_RESULT_ROW_SIZE, sizeof(char));
      int32_t sqlLen = 0;
      nodesNodeToSQL(pAst, buf, TSDB_EXPLAIN_RESULT_ROW_SIZE * sizeof(char), &sqlLen);

      char *value = taosMemoryCalloc(sqlLen + TSDB_TABLE_NAME_LEN + 1, sizeof(char));

      sprintf(value, "%s(%s)", objName, buf);

      char *obj = taosMemoryCalloc(sqlLen + TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE + 1, sizeof(char));
      STR_WITH_MAXSIZE_TO_VARSTR(obj, value, pShow->pMeta->pSchemas[cols].bytes);

C
table  
cademfly 已提交
1210
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
C
cademfly 已提交
1211 1212 1213 1214 1215
      colDataSetVal(pColInfo, numOfRows, (const char *)obj, false);

      taosMemoryFree(value);
      taosMemoryFree(buf);
      taosMemoryFree(obj);
C
table  
cademfly 已提交
1216 1217 1218 1219 1220

      numOfRows++;
      stb = taosHashIterate(pUser->writeStbs, stb);
    }

S
Shengliang Guan 已提交
1221 1222 1223
    char *topic = taosHashIterate(pUser->topics, NULL);
    while (topic != NULL) {
      cols = 0;
1224
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
S
Shengliang Guan 已提交
1225
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
1226
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1227
      colDataSetVal(pColInfo, numOfRows, (const char *)userName, false);
S
Shengliang Guan 已提交
1228 1229 1230 1231

      char privilege[20] = {0};
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "subscribe", pShow->pMeta->pSchemas[cols].bytes);
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1232
      colDataSetVal(pColInfo, numOfRows, (const char *)privilege, false);
S
Shengliang Guan 已提交
1233 1234 1235 1236 1237

      char topicName[TSDB_TOPIC_NAME_LEN + VARSTR_HEADER_SIZE + 5] = {0};
      tstrncpy(varDataVal(topicName), mndGetDbStr(topic), TSDB_TOPIC_NAME_LEN - 2);
      varDataSetLen(topicName, strlen(varDataVal(topicName)));
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1238
      colDataSetVal(pColInfo, numOfRows, (const char *)topicName, false);
S
Shengliang Guan 已提交
1239 1240

      numOfRows++;
1241
      topic = taosHashIterate(pUser->topics, topic);
S
Shengliang Guan 已提交
1242
    }
1243

S
Shengliang Guan 已提交
1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254
    sdbRelease(pSdb, pUser);
  }

  pShow->numOfRows += numOfRows;
  return numOfRows;
}

static void mndCancelGetNextPrivileges(SMnode *pMnode, void *pIter) {
  SSdb *pSdb = pMnode->pSdb;
  sdbCancelFetch(pSdb, pIter);
}
1255

1256 1257
int32_t mndValidateUserAuthInfo(SMnode *pMnode, SUserAuthVersion *pUsers, int32_t numOfUses, void **ppRsp,
                                int32_t *pRspLen) {
D
dapan 已提交
1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272
  SUserAuthBatchRsp batchRsp = {0};
  batchRsp.pArray = taosArrayInit(numOfUses, sizeof(SGetUserAuthRsp));
  if (batchRsp.pArray == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }

  int32_t code = 0;
  for (int32_t i = 0; i < numOfUses; ++i) {
    SUserObj *pUser = mndAcquireUser(pMnode, pUsers[i].user);
    if (pUser == NULL) {
      mError("user:%s, failed to auth user since %s", pUsers[i].user, terrstr());
      continue;
    }

D
dapan1121 已提交
1273
    pUsers[i].version = ntohl(pUsers[i].version);
D
dapan 已提交
1274 1275 1276 1277
    if (pUser->authVersion <= pUsers[i].version) {
      mndReleaseUser(pMnode, pUser);
      continue;
    }
1278

D
dapan 已提交
1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293
    SGetUserAuthRsp rsp = {0};
    code = mndSetUserAuthRsp(pMnode, pUser, &rsp);
    if (code) {
      mndReleaseUser(pMnode, pUser);
      tFreeSGetUserAuthRsp(&rsp);
      goto _OVER;
    }

    taosArrayPush(batchRsp.pArray, &rsp);
    mndReleaseUser(pMnode, pUser);
  }

  if (taosArrayGetSize(batchRsp.pArray) <= 0) {
    *ppRsp = NULL;
    *pRspLen = 0;
1294

D
dapan 已提交
1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317
    tFreeSUserAuthBatchRsp(&batchRsp);
    return 0;
  }

  int32_t rspLen = tSerializeSUserAuthBatchRsp(NULL, 0, &batchRsp);
  void   *pRsp = taosMemoryMalloc(rspLen);
  if (pRsp == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    tFreeSUserAuthBatchRsp(&batchRsp);
    return -1;
  }
  tSerializeSUserAuthBatchRsp(pRsp, rspLen, &batchRsp);

  *ppRsp = pRsp;
  *pRspLen = rspLen;

  tFreeSUserAuthBatchRsp(&batchRsp);
  return 0;

_OVER:

  *ppRsp = NULL;
  *pRspLen = 0;
1318

D
dapan 已提交
1319 1320 1321
  tFreeSUserAuthBatchRsp(&batchRsp);
  return code;
}
1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342

int32_t mndUserRemoveDb(SMnode *pMnode, STrans *pTrans, char *db) {
  int32_t   code = 0;
  SSdb     *pSdb = pMnode->pSdb;
  int32_t   len = strlen(db) + 1;
  void     *pIter = NULL;
  SUserObj *pUser = NULL;
  SUserObj  newUser = {0};

  while (1) {
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
    if (pIter == NULL) break;

    code = -1;
    if (mndUserDupObj(pUser, &newUser) != 0) break;

    bool inRead = (taosHashGet(newUser.readDbs, db, len) != NULL);
    bool inWrite = (taosHashGet(newUser.writeDbs, db, len) != NULL);
    if (inRead || inWrite) {
      (void)taosHashRemove(newUser.readDbs, db, len);
      (void)taosHashRemove(newUser.writeDbs, db, len);
C
table  
cademfly 已提交
1343 1344
      (void)taosHashRemove(newUser.readStbs, db, len);
      (void)taosHashRemove(newUser.writeStbs, db, len);
1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371

      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
      if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) break;
      (void)sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
    }

    mndUserFreeObj(&newUser);
    sdbRelease(pSdb, pUser);
    code = 0;
  }

  if (pUser != NULL) sdbRelease(pSdb, pUser);
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
  mndUserFreeObj(&newUser);
  return code;
}

int32_t mndUserRemoveTopic(SMnode *pMnode, STrans *pTrans, char *topic) {
  int32_t   code = 0;
  SSdb     *pSdb = pMnode->pSdb;
  int32_t   len = strlen(topic) + 1;
  void     *pIter = NULL;
  SUserObj *pUser = NULL;
  SUserObj  newUser = {0};

  while (1) {
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
1372 1373 1374
    if (pIter == NULL) {
      break;
    }
1375 1376

    code = -1;
1377 1378 1379
    if (mndUserDupObj(pUser, &newUser) != 0) {
      break;
    }
1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398

    bool inTopic = (taosHashGet(newUser.topics, topic, len) != NULL);
    if (inTopic) {
      (void)taosHashRemove(newUser.topics, topic, len);
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
      if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) break;
      (void)sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
    }

    mndUserFreeObj(&newUser);
    sdbRelease(pSdb, pUser);
    code = 0;
  }

  if (pUser != NULL) sdbRelease(pSdb, pUser);
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
  mndUserFreeObj(&newUser);
  return code;
}