mndUser.c 47.9 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
cademfly 已提交
128 129
  int32_t numOfReadStbs = taosHashGetSize(pUser->readTbs);
  int32_t numOfWriteStbs = taosHashGetSize(pUser->writeTbs);
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
  char *stb = taosHashIterate(pUser->readTbs, NULL);
C
cademfly 已提交
136 137 138 139 140 141 142 143 144 145
  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;
C
cademfly 已提交
146
    stb = taosHashIterate(pUser->readTbs, stb);
C
cademfly 已提交
147 148
  }

C
cademfly 已提交
149
  stb = taosHashIterate(pUser->writeTbs, NULL);
C
cademfly 已提交
150 151 152 153 154 155 156 157 158 159
  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;
C
cademfly 已提交
160
    stb = taosHashIterate(pUser->writeTbs, stb);
C
cademfly 已提交
161 162
  }

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->readTbs, NULL);
C
table  
cademfly 已提交
202
  while (stb != NULL) {
C
cademfly 已提交
203 204 205 206 207 208
    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;
C
cademfly 已提交
209
    valueLen = strlen(stb)+1;
C
cademfly 已提交
210 211
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
C
cademfly 已提交
212
    stb = taosHashIterate(pUser->readTbs, stb);
C
table  
cademfly 已提交
213 214
  }

C
cademfly 已提交
215
  stb = taosHashIterate(pUser->writeTbs, NULL);
C
table  
cademfly 已提交
216
  while (stb != NULL) {
C
cademfly 已提交
217 218 219 220 221 222
    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;
C
cademfly 已提交
223
    valueLen = strlen(stb)+1;
C
cademfly 已提交
224 225
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
C
cademfly 已提交
226
    stb = taosHashIterate(pUser->writeTbs, stb);
C
table  
cademfly 已提交
227 228
  }

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
cademfly 已提交
295 296
  pUser->readTbs = taosHashInit(numOfReadStbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
  pUser->writeTbs =
C
table  
cademfly 已提交
297
      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
      int32_t keyLen = 0;
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);

C
cademfly 已提交
328 329
      char *key = taosMemoryCalloc(keyLen, sizeof(char));
      memset(key, 0, keyLen);
C
cademfly 已提交
330 331 332 333
      SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);

      int32_t valuelen = 0;
      SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
C
cademfly 已提交
334 335
      char *value = taosMemoryCalloc(valuelen, sizeof(char));
      memset(value, 0, keyLen);
C
cademfly 已提交
336 337
      SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)

C
cademfly 已提交
338
      taosHashPut(pUser->readTbs, key, keyLen, value, valuelen);
C
cademfly 已提交
339 340 341

      taosMemoryFree(key);
      taosMemoryFree(value);
C
table  
cademfly 已提交
342 343 344
    }

    for (int32_t i = 0; i < numOfWriteStbs; ++i) {
C
cademfly 已提交
345 346 347
      int32_t keyLen = 0;
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);

C
cademfly 已提交
348 349
      char *key = taosMemoryCalloc(keyLen, sizeof(char));
      memset(key, 0, keyLen);
C
cademfly 已提交
350 351 352 353
      SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);

      int32_t valuelen = 0;
      SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
C
cademfly 已提交
354 355
      char *value = taosMemoryCalloc(valuelen, sizeof(char));
      memset(value, 0, keyLen);
C
cademfly 已提交
356 357
      SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)

C
cademfly 已提交
358
      taosHashPut(pUser->writeTbs, key, keyLen, value, valuelen);
C
cademfly 已提交
359 360 361

      taosMemoryFree(key);
      taosMemoryFree(value);
C
table  
cademfly 已提交
362 363 364
    }
  }

365
  SDB_GET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
S
Shengliang Guan 已提交
366
  taosInitRWLatch(&pUser->lock);
367 368 369

  terrno = 0;

370
_OVER:
371
  if (terrno != 0) {
372 373 374 375 376
    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
cademfly 已提交
377 378
      taosHashCleanup(pUser->readTbs);
      taosHashCleanup(pUser->writeTbs);
379
    }
wafwerar's avatar
wafwerar 已提交
380
    taosMemoryFreeClear(pRow);
381 382
    return NULL;
  }
S
Shengliang Guan 已提交
383

S
Shengliang Guan 已提交
384
  mTrace("user:%s, decode from raw:%p, row:%p", pUser->user, pRaw, pUser);
S
Shengliang Guan 已提交
385
  return pRow;
S
Shengliang Guan 已提交
386
}
S
Shengliang Guan 已提交
387

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

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

S
Shengliang Guan 已提交
400 401
  return 0;
}
S
Shengliang Guan 已提交
402

C
cademfly 已提交
403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428
SHashObj *mndDupTableHash(SHashObj *pOld) {
  SHashObj *pNew =
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
  if (pNew == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return NULL;
  }

  char *tb = taosHashIterate(pOld, NULL);
  while (tb != NULL) {
    size_t keyLen = 0;
    char *key = taosHashGetKey(tb, &keyLen);

    int32_t valueLen = strlen(tb) + 1;
    if (taosHashPut(pNew, key, keyLen, tb, valueLen) != 0) {
      taosHashCancelIterate(pOld, tb);
      taosHashCleanup(pNew);
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      return NULL;
    }
    tb = taosHashIterate(pOld, tb);
  }

  return pNew;
}

429 430 431 432 433 434 435 436
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
cademfly 已提交
437 438
  pNew->readTbs = mndDupTableHash(pUser->readTbs);
  pNew->writeTbs = mndDupTableHash(pUser->writeTbs);
439 440 441 442 443 444 445 446 447 448
  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) {
449 450
  taosHashCleanup(pUser->readDbs);
  taosHashCleanup(pUser->writeDbs);
451
  taosHashCleanup(pUser->topics);
C
cademfly 已提交
452 453
  taosHashCleanup(pUser->readTbs);
  taosHashCleanup(pUser->writeTbs);
454 455
  pUser->readDbs = NULL;
  pUser->writeDbs = NULL;
456
  pUser->topics = NULL;
C
cademfly 已提交
457 458
  pUser->readTbs = NULL;
  pUser->writeTbs = NULL;
459 460 461 462 463
}

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

S
Shengliang Guan 已提交
467
static int32_t mndUserActionUpdate(SSdb *pSdb, SUserObj *pOld, SUserObj *pNew) {
S
Shengliang Guan 已提交
468
  mTrace("user:%s, perform update action, old row:%p new row:%p", pOld->user, pOld, pNew);
S
Shengliang Guan 已提交
469
  taosWLockLatch(&pOld->lock);
S
Shengliang Guan 已提交
470
  pOld->updateTime = pNew->updateTime;
D
dapan1121 已提交
471
  pOld->authVersion = pNew->authVersion;
472 473
  pOld->sysInfo = pNew->sysInfo;
  pOld->enable = pNew->enable;
S
Shengliang Guan 已提交
474
  memcpy(pOld->pass, pNew->pass, TSDB_PASSWORD_LEN);
wafwerar's avatar
wafwerar 已提交
475 476
  TSWAP(pOld->readDbs, pNew->readDbs);
  TSWAP(pOld->writeDbs, pNew->writeDbs);
477
  TSWAP(pOld->topics, pNew->topics);
C
cademfly 已提交
478 479
  TSWAP(pOld->readTbs, pNew->readTbs);
  TSWAP(pOld->writeTbs, pNew->writeTbs);
S
Shengliang Guan 已提交
480
  taosWUnLockLatch(&pOld->lock);
481

S
Shengliang Guan 已提交
482 483 484
  return 0;
}

485
SUserObj *mndAcquireUser(SMnode *pMnode, const char *userName) {
S
Shengliang Guan 已提交
486 487 488
  SSdb     *pSdb = pMnode->pSdb;
  SUserObj *pUser = sdbAcquire(pSdb, SDB_USER, userName);
  if (pUser == NULL) {
dengyihao's avatar
dengyihao 已提交
489 490 491 492 493
    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 已提交
494 495
  }
  return pUser;
S
Shengliang Guan 已提交
496
}
S
Shengliang Guan 已提交
497

S
Shengliang Guan 已提交
498 499 500
void mndReleaseUser(SMnode *pMnode, SUserObj *pUser) {
  SSdb *pSdb = pMnode->pSdb;
  sdbRelease(pSdb, pUser);
S
Shengliang Guan 已提交
501 502
}

S
Shengliang Guan 已提交
503
static int32_t mndCreateUser(SMnode *pMnode, char *acct, SCreateUserReq *pCreate, SRpcMsg *pReq) {
S
Shengliang Guan 已提交
504
  SUserObj userObj = {0};
S
Shengliang Guan 已提交
505 506
  taosEncryptPass_c((uint8_t *)pCreate->pass, strlen(pCreate->pass), userObj.pass);
  tstrncpy(userObj.user, pCreate->user, TSDB_USER_LEN);
S
Shengliang Guan 已提交
507 508 509
  tstrncpy(userObj.acct, acct, TSDB_USER_LEN);
  userObj.createdTime = taosGetTimestampMs();
  userObj.updateTime = userObj.createdTime;
510
  userObj.superUser = 0;  // pCreate->superUser;
511 512
  userObj.sysInfo = pCreate->sysInfo;
  userObj.enable = pCreate->enable;
S
Shengliang Guan 已提交
513

514
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "create-user");
S
Shengliang Guan 已提交
515
  if (pTrans == NULL) {
S
Shengliang Guan 已提交
516
    mError("user:%s, failed to create since %s", pCreate->user, terrstr());
S
Shengliang Guan 已提交
517 518
    return -1;
  }
519
  mInfo("trans:%d, used to create user:%s", pTrans->id, pCreate->user);
S
Shengliang Guan 已提交
520

521 522 523
  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 已提交
524
    mndTransDrop(pTrans);
S
Shengliang Guan 已提交
525
    return -1;
S
Shengliang Guan 已提交
526
  }
S
Shengliang Guan 已提交
527
  (void)sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
S
Shengliang Guan 已提交
528

S
Shengliang Guan 已提交
529
  if (mndTransPrepare(pMnode, pTrans) != 0) {
S
Shengliang Guan 已提交
530
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
S
Shengliang Guan 已提交
531
    mndTransDrop(pTrans);
S
Shengliang Guan 已提交
532
    return -1;
S
Shengliang Guan 已提交
533 534
  }

S
Shengliang Guan 已提交
535
  mndTransDrop(pTrans);
S
Shengliang Guan 已提交
536
  return 0;
S
Shengliang Guan 已提交
537 538
}

S
Shengliang Guan 已提交
539 540
static int32_t mndProcessCreateUserReq(SRpcMsg *pReq) {
  SMnode        *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
541 542 543 544 545
  int32_t        code = -1;
  SUserObj      *pUser = NULL;
  SUserObj      *pOperUser = NULL;
  SCreateUserReq createReq = {0};

S
Shengliang Guan 已提交
546
  if (tDeserializeSCreateUserReq(pReq->pCont, pReq->contLen, &createReq) != 0) {
S
Shengliang Guan 已提交
547
    terrno = TSDB_CODE_INVALID_MSG;
548
    goto _OVER;
S
Shengliang Guan 已提交
549
  }
S
Shengliang Guan 已提交
550

551
  mInfo("user:%s, start to create", createReq.user);
552 553 554
  if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CREATE_USER) != 0) {
    goto _OVER;
  }
S
Shengliang Guan 已提交
555

S
Shengliang Guan 已提交
556
  if (createReq.user[0] == 0) {
S
Shengliang Guan 已提交
557
    terrno = TSDB_CODE_MND_INVALID_USER_FORMAT;
558
    goto _OVER;
S
Shengliang Guan 已提交
559 560
  }

S
Shengliang Guan 已提交
561
  if (createReq.pass[0] == 0) {
S
Shengliang Guan 已提交
562
    terrno = TSDB_CODE_MND_INVALID_PASS_FORMAT;
563
    goto _OVER;
S
Shengliang Guan 已提交
564 565
  }

S
Shengliang Guan 已提交
566
  pUser = mndAcquireUser(pMnode, createReq.user);
S
Shengliang Guan 已提交
567
  if (pUser != NULL) {
S
Shengliang Guan 已提交
568
    terrno = TSDB_CODE_MND_USER_ALREADY_EXIST;
569
    goto _OVER;
S
Shengliang Guan 已提交
570 571
  }

572
  pOperUser = mndAcquireUser(pMnode, pReq->info.conn.user);
S
Shengliang Guan 已提交
573
  if (pOperUser == NULL) {
S
Shengliang Guan 已提交
574
    terrno = TSDB_CODE_MND_NO_USER_FROM_CONN;
575
    goto _OVER;
S
Shengliang Guan 已提交
576 577
  }

C
Cary Xu 已提交
578 579 580 581
  if ((terrno = grantCheck(TSDB_GRANT_USER)) != 0) {
    code = terrno;
    goto _OVER;
  }
582

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

586
_OVER:
S
Shengliang Guan 已提交
587
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
S
Shengliang Guan 已提交
588
    mError("user:%s, failed to create since %s", createReq.user, terrstr());
S
Shengliang Guan 已提交
589 590
  }

S
Shengliang Guan 已提交
591 592 593 594
  mndReleaseUser(pMnode, pUser);
  mndReleaseUser(pMnode, pOperUser);

  return code;
S
Shengliang Guan 已提交
595 596
}

S
Shengliang Guan 已提交
597
static int32_t mndAlterUser(SMnode *pMnode, SUserObj *pOld, SUserObj *pNew, SRpcMsg *pReq) {
598
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "alter-user");
S
Shengliang Guan 已提交
599
  if (pTrans == NULL) {
S
Shengliang Guan 已提交
600
    mError("user:%s, failed to alter since %s", pOld->user, terrstr());
S
Shengliang Guan 已提交
601 602
    return -1;
  }
603
  mInfo("trans:%d, used to alter user:%s", pTrans->id, pOld->user);
S
Shengliang Guan 已提交
604

605 606 607
  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 已提交
608 609 610
    mndTransDrop(pTrans);
    return -1;
  }
S
Shengliang Guan 已提交
611
  (void)sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
S
Shengliang Guan 已提交
612 613 614 615 616 617 618 619 620 621 622

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

  mndTransDrop(pTrans);
  return 0;
}

623
SHashObj *mndDupObjHash(SHashObj *pOld, int32_t dataLen) {
S
Shengliang Guan 已提交
624 625
  SHashObj *pNew =
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
S
Shengliang Guan 已提交
626 627 628 629 630 631 632 633
  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;
634
    if (taosHashPut(pNew, db, len, db, dataLen) != 0) {
S
Shengliang Guan 已提交
635 636
      taosHashCancelIterate(pOld, db);
      taosHashCleanup(pNew);
S
Shengliang Guan 已提交
637
      terrno = TSDB_CODE_OUT_OF_MEMORY;
S
Shengliang Guan 已提交
638 639 640 641 642 643 644 645
      return NULL;
    }
    db = taosHashIterate(pOld, db);
  }

  return pNew;
}

646 647 648 649
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 已提交
650 651
static int32_t mndProcessAlterUserReq(SRpcMsg *pReq) {
  SMnode       *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
652 653
  SSdb         *pSdb = pMnode->pSdb;
  void         *pIter = NULL;
S
Shengliang Guan 已提交
654 655 656
  int32_t       code = -1;
  SUserObj     *pUser = NULL;
  SUserObj     *pOperUser = NULL;
S
Shengliang Guan 已提交
657
  SUserObj      newUser = {0};
S
Shengliang Guan 已提交
658 659
  SAlterUserReq alterReq = {0};

S
Shengliang Guan 已提交
660
  if (tDeserializeSAlterUserReq(pReq->pCont, pReq->contLen, &alterReq) != 0) {
S
Shengliang Guan 已提交
661
    terrno = TSDB_CODE_INVALID_MSG;
662
    goto _OVER;
S
Shengliang Guan 已提交
663
  }
S
Shengliang Guan 已提交
664

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

S
Shengliang Guan 已提交
667
  if (alterReq.user[0] == 0) {
S
Shengliang Guan 已提交
668
    terrno = TSDB_CODE_MND_INVALID_USER_FORMAT;
669 670 671 672 673
    goto _OVER;
  }

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

S
Shengliang Guan 已提交
677
  pUser = mndAcquireUser(pMnode, alterReq.user);
S
Shengliang Guan 已提交
678 679
  if (pUser == NULL) {
    terrno = TSDB_CODE_MND_USER_NOT_EXIST;
680
    goto _OVER;
S
Shengliang Guan 已提交
681 682
  }

683
  pOperUser = mndAcquireUser(pMnode, pReq->info.conn.user);
S
Shengliang Guan 已提交
684 685
  if (pOperUser == NULL) {
    terrno = TSDB_CODE_MND_NO_USER_FROM_CONN;
686
    goto _OVER;
S
Shengliang Guan 已提交
687 688
  }

689
  if (mndCheckAlterUserPrivilege(pOperUser, pUser, &alterReq) != 0) {
S
Shengliang Guan 已提交
690 691 692
    goto _OVER;
  }

693
  if (mndUserDupObj(pUser, &newUser) != 0) goto _OVER;
S
Shengliang Guan 已提交
694 695 696 697

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

  if (alterReq.alterType == TSDB_ALTER_USER_SUPERUSER) {
S
Shengliang Guan 已提交
702
    newUser.superUser = alterReq.superUser;
S
Shengliang Guan 已提交
703 704
  }

705 706 707 708 709 710 711 712
  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 已提交
713
  if (alterReq.alterType == TSDB_ALTER_USER_ADD_READ_DB || alterReq.alterType == TSDB_ALTER_USER_ADD_ALL_DB) {
714 715 716
    if (strcmp(alterReq.objname, "1.*") != 0) {
      int32_t len = strlen(alterReq.objname) + 1;
      SDbObj *pDb = mndAcquireDb(pMnode, alterReq.objname);
S
Shengliang Guan 已提交
717 718 719 720
      if (pDb == NULL) {
        mndReleaseDb(pMnode, pDb);
        goto _OVER;
      }
721
      if (taosHashPut(newUser.readDbs, alterReq.objname, len, alterReq.objname, TSDB_DB_FNAME_LEN) != 0) {
S
Shengliang Guan 已提交
722 723 724 725 726 727 728 729 730 731 732 733
        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 已提交
734
    }
S
Shengliang Guan 已提交
735 736 737
  }

  if (alterReq.alterType == TSDB_ALTER_USER_ADD_WRITE_DB || alterReq.alterType == TSDB_ALTER_USER_ADD_ALL_DB) {
738 739 740
    if (strcmp(alterReq.objname, "1.*") != 0) {
      int32_t len = strlen(alterReq.objname) + 1;
      SDbObj *pDb = mndAcquireDb(pMnode, alterReq.objname);
S
Shengliang Guan 已提交
741 742 743 744
      if (pDb == NULL) {
        mndReleaseDb(pMnode, pDb);
        goto _OVER;
      }
745
      if (taosHashPut(newUser.writeDbs, alterReq.objname, len, alterReq.objname, TSDB_DB_FNAME_LEN) != 0) {
S
Shengliang Guan 已提交
746 747 748 749 750 751 752 753 754 755 756 757
        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 已提交
758 759 760
    }
  }

S
Shengliang Guan 已提交
761
  if (alterReq.alterType == TSDB_ALTER_USER_REMOVE_READ_DB || alterReq.alterType == TSDB_ALTER_USER_REMOVE_ALL_DB) {
762 763 764
    if (strcmp(alterReq.objname, "1.*") != 0) {
      int32_t len = strlen(alterReq.objname) + 1;
      SDbObj *pDb = mndAcquireDb(pMnode, alterReq.objname);
S
Shengliang Guan 已提交
765 766 767 768
      if (pDb == NULL) {
        mndReleaseDb(pMnode, pDb);
        goto _OVER;
      }
769
      taosHashRemove(newUser.readDbs, alterReq.objname, len);
S
Shengliang Guan 已提交
770 771 772 773
    } else {
      taosHashClear(newUser.readDbs);
    }
  }
S
Shengliang Guan 已提交
774

S
Shengliang Guan 已提交
775
  if (alterReq.alterType == TSDB_ALTER_USER_REMOVE_WRITE_DB || alterReq.alterType == TSDB_ALTER_USER_REMOVE_ALL_DB) {
776 777 778
    if (strcmp(alterReq.objname, "1.*") != 0) {
      int32_t len = strlen(alterReq.objname) + 1;
      SDbObj *pDb = mndAcquireDb(pMnode, alterReq.objname);
S
Shengliang Guan 已提交
779 780 781 782
      if (pDb == NULL) {
        mndReleaseDb(pMnode, pDb);
        goto _OVER;
      }
783
      taosHashRemove(newUser.writeDbs, alterReq.objname, len);
S
Shengliang Guan 已提交
784 785 786
    } else {
      taosHashClear(newUser.writeDbs);
    }
S
Shengliang Guan 已提交
787 788
  }

C
table  
cademfly 已提交
789 790 791 792 793 794 795 796 797 798 799
  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;
      }
C
cademfly 已提交
800
      if (taosHashPut(newUser.readTbs, tbFName, len, tbFName, len) != 0) {
C
table  
cademfly 已提交
801 802 803 804 805 806 807 808 809
        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;
C
cademfly 已提交
810
        taosHashPut(newUser.readTbs, pStb->name, len, pStb->name, len);
C
table  
cademfly 已提交
811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826
        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;
      }
C
cademfly 已提交
827
      if (taosHashPut(newUser.writeTbs, tbFName, len, tbFName, len) != 0) {
C
table  
cademfly 已提交
828 829 830 831 832 833 834 835 836
        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;
C
cademfly 已提交
837
        taosHashPut(newUser.writeTbs, pStb->name, len, pStb->name, TSDB_DB_FNAME_LEN);
C
table  
cademfly 已提交
838 839 840 841 842
        sdbRelease(pSdb, pStb);
      }
    }
  }

C
cademfly 已提交
843 844 845 846 847 848 849 850 851 852 853 854
  if (alterReq.alterType == TSDB_ALTER_USER_REMOVE_READ_TABLE || 
      alterReq.alterType == TSDB_ALTER_USER_REMOVE_READ_TAG || 
      alterReq.alterType == TSDB_ALTER_USER_REMOVE_ALL_TABLE) {
    if (strcmp(alterReq.objname, "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;
C
cademfly 已提交
855 856
      }  

C
cademfly 已提交
857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916
      if (taosHashRemove(newUser.readTbs, tbFName, 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;

        if(strcmp(pStb->db, alterReq.objname) == 0){
          if (taosHashRemove(newUser.readTbs, pStb->name, len) != 0) {
            mndReleaseStb(pMnode, pStb);
            goto _OVER;
          }
        }

        //taosHashPut(newUser.writeStbs, pStb->name, len, pStb->name, TSDB_DB_FNAME_LEN);
        //sdbRelease(pSdb, pStb);
      }

      //taosHashClear(newUser.readStbs);
    }
  }

  if (alterReq.alterType == TSDB_ALTER_USER_REMOVE_WRITE_TABLE ||
      alterReq.alterType == TSDB_ALTER_USER_REMOVE_WRITE_TAG ||
      alterReq.alterType == TSDB_ALTER_USER_REMOVE_ALL_TABLE) {
    if (strcmp(alterReq.objname, "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 (taosHashRemove(newUser.writeTbs, tbFName, 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;

        if(strcmp(pStb->db, alterReq.objname) == 0){
          if (taosHashRemove(newUser.writeTbs, pStb->name, len) != 0) {
            mndReleaseStb(pMnode, pStb);
            goto _OVER;
          }
        }
      }
    }
  }

917 918 919 920 921 922 923 924 925 926
  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 已提交
927 928
  if (alterReq.alterType == TSDB_ALTER_USER_ADD_READ_TAG) {
    char tbFName[TSDB_TABLE_FNAME_LEN] = {0};
C
cademfly 已提交
929
    snprintf(tbFName, TSDB_TABLE_FNAME_LEN, "%s.%s", alterReq.objname, alterReq.tabName);
C
cademfly 已提交
930
    int32_t len = strlen(tbFName) + 1;
C
cademfly 已提交
931

C
cademfly 已提交
932 933 934 935 936 937 938 939 940
    SStbObj *pStb = mndAcquireStb(pMnode, tbFName);
    if (pStb == NULL) {
      mndReleaseStb(pMnode, pStb);
      goto _OVER;
    }
    if(alterReq.tagCond == NULL){
      mndReleaseStb(pMnode, pStb);
      goto _OVER;
    }
C
cademfly 已提交
941

C
cademfly 已提交
942
    int32_t condLen = alterReq.tagCondLen + 1;
C
cademfly 已提交
943
    if (taosHashPut(newUser.readTbs, tbFName, len, alterReq.tagCond, condLen) != 0) {
C
cademfly 已提交
944 945 946 947 948 949 950 951 952
      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;
C
cademfly 已提交
953

C
cademfly 已提交
954 955 956 957 958 959 960 961 962
    SStbObj *pStb = mndAcquireStb(pMnode, tbFName);
    if (pStb == NULL) {
      mndReleaseStb(pMnode, pStb);
      goto _OVER;
    }
    if(alterReq.tagCond == NULL){
      mndReleaseStb(pMnode, pStb);
      goto _OVER;
    }
C
cademfly 已提交
963
    int32_t condLen = alterReq.tagCondLen + 1;
C
cademfly 已提交
964
    if (taosHashPut(newUser.writeTbs, tbFName, len, alterReq.tagCond, condLen) != 0) {
C
cademfly 已提交
965 966 967 968 969
      mndReleaseStb(pMnode, pStb);
      goto _OVER;
    }
  }

970 971 972 973 974 975 976 977 978 979
  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 已提交
980
  code = mndAlterUser(pMnode, pUser, &newUser, pReq);
S
Shengliang Guan 已提交
981
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
S
Shengliang Guan 已提交
982

983
_OVER:
S
Shengliang Guan 已提交
984
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
S
Shengliang Guan 已提交
985
    mError("user:%s, failed to alter since %s", alterReq.user, terrstr());
S
Shengliang Guan 已提交
986 987
  }

S
Shengliang Guan 已提交
988 989
  mndReleaseUser(pMnode, pOperUser);
  mndReleaseUser(pMnode, pUser);
990
  mndUserFreeObj(&newUser);
S
Shengliang Guan 已提交
991 992

  return code;
S
Shengliang Guan 已提交
993 994
}

S
Shengliang Guan 已提交
995
static int32_t mndDropUser(SMnode *pMnode, SRpcMsg *pReq, SUserObj *pUser) {
996
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "drop-user");
S
Shengliang Guan 已提交
997 998 999 1000
  if (pTrans == NULL) {
    mError("user:%s, failed to drop since %s", pUser->user, terrstr());
    return -1;
  }
1001
  mInfo("trans:%d, used to drop user:%s", pTrans->id, pUser->user);
S
Shengliang Guan 已提交
1002

1003 1004 1005
  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 已提交
1006 1007 1008
    mndTransDrop(pTrans);
    return -1;
  }
S
Shengliang Guan 已提交
1009
  (void)sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED);
S
Shengliang Guan 已提交
1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020

  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 已提交
1021 1022
static int32_t mndProcessDropUserReq(SRpcMsg *pReq) {
  SMnode      *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
1023 1024 1025 1026
  int32_t      code = -1;
  SUserObj    *pUser = NULL;
  SDropUserReq dropReq = {0};

S
Shengliang Guan 已提交
1027
  if (tDeserializeSDropUserReq(pReq->pCont, pReq->contLen, &dropReq) != 0) {
S
Shengliang Guan 已提交
1028
    terrno = TSDB_CODE_INVALID_MSG;
1029
    goto _OVER;
S
Shengliang Guan 已提交
1030
  }
S
Shengliang Guan 已提交
1031

1032
  mInfo("user:%s, start to drop", dropReq.user);
1033 1034 1035
  if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_DROP_USER) != 0) {
    goto _OVER;
  }
S
Shengliang Guan 已提交
1036

S
Shengliang Guan 已提交
1037
  if (dropReq.user[0] == 0) {
S
Shengliang Guan 已提交
1038
    terrno = TSDB_CODE_MND_INVALID_USER_FORMAT;
1039
    goto _OVER;
S
Shengliang Guan 已提交
1040 1041
  }

S
Shengliang Guan 已提交
1042
  pUser = mndAcquireUser(pMnode, dropReq.user);
S
Shengliang Guan 已提交
1043 1044
  if (pUser == NULL) {
    terrno = TSDB_CODE_MND_USER_NOT_EXIST;
1045
    goto _OVER;
S
Shengliang Guan 已提交
1046 1047
  }

S
Shengliang Guan 已提交
1048
  code = mndDropUser(pMnode, pReq, pUser);
S
Shengliang Guan 已提交
1049
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
S
Shengliang Guan 已提交
1050

1051
_OVER:
S
Shengliang Guan 已提交
1052
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
S
Shengliang Guan 已提交
1053
    mError("user:%s, failed to drop since %s", dropReq.user, terrstr());
S
Shengliang Guan 已提交
1054 1055
  }

S
Shengliang Guan 已提交
1056 1057
  mndReleaseUser(pMnode, pUser);
  return code;
S
Shengliang Guan 已提交
1058 1059
}

S
Shengliang Guan 已提交
1060 1061
static int32_t mndProcessGetUserAuthReq(SRpcMsg *pReq) {
  SMnode         *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
1062 1063 1064 1065 1066
  int32_t         code = -1;
  SUserObj       *pUser = NULL;
  SGetUserAuthReq authReq = {0};
  SGetUserAuthRsp authRsp = {0};

S
Shengliang Guan 已提交
1067
  if (tDeserializeSGetUserAuthReq(pReq->pCont, pReq->contLen, &authReq) != 0) {
S
Shengliang Guan 已提交
1068
    terrno = TSDB_CODE_INVALID_MSG;
1069
    goto _OVER;
S
Shengliang Guan 已提交
1070
  }
S
Shengliang Guan 已提交
1071 1072 1073 1074 1075 1076

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

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

D
dapan 已提交
1080 1081 1082
  code = mndSetUserAuthRsp(pMnode, pUser, &authRsp);
  if (code) {
    goto _OVER;
S
Shengliang Guan 已提交
1083 1084
  }

S
Shengliang Guan 已提交
1085
  int32_t contLen = tSerializeSGetUserAuthRsp(NULL, 0, &authRsp);
S
Shengliang Guan 已提交
1086 1087 1088
  void   *pRsp = rpcMallocCont(contLen);
  if (pRsp == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
1089
    goto _OVER;
S
Shengliang Guan 已提交
1090 1091
  }

S
Shengliang Guan 已提交
1092
  tSerializeSGetUserAuthRsp(pRsp, contLen, &authRsp);
S
Shengliang Guan 已提交
1093

S
Shengliang Guan 已提交
1094 1095
  pReq->info.rsp = pRsp;
  pReq->info.rspLen = contLen;
S
Shengliang Guan 已提交
1096 1097
  code = 0;

1098
_OVER:
1099

S
Shengliang Guan 已提交
1100
  mndReleaseUser(pMnode, pUser);
S
Shengliang Guan 已提交
1101
  tFreeSGetUserAuthRsp(&authRsp);
S
Shengliang Guan 已提交
1102 1103 1104 1105

  return code;
}

S
Shengliang Guan 已提交
1106 1107
static int32_t mndRetrieveUsers(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
  SMnode   *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118
  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;
1119
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
1120
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
1121
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
1122
    colDataSetVal(pColInfo, numOfRows, (const char *)name, false);
1123

wafwerar's avatar
wafwerar 已提交
1124 1125
    cols++;
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
1126
    colDataSetVal(pColInfo, numOfRows, (const char *)&pUser->superUser, false);
1127

1128 1129
    cols++;
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
1130
    colDataSetVal(pColInfo, numOfRows, (const char *)&pUser->enable, false);
1131 1132 1133

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

wafwerar's avatar
wafwerar 已提交
1136 1137
    cols++;
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
1138
    colDataSetVal(pColInfo, numOfRows, (const char *)&pUser->createdTime, false);
S
Shengliang Guan 已提交
1139 1140 1141 1142 1143

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

1144
  pShow->numOfRows += numOfRows;
S
Shengliang Guan 已提交
1145 1146 1147 1148 1149 1150
  return numOfRows;
}

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

C
cademfly 已提交
1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217
static void mndLoopHash(SHashObj * hash, char *priType, SSDataBlock *pBlock, int32_t *numOfRows, char *user, SShowObj *pShow){
  char *value = taosHashIterate(hash, NULL);
  int32_t cols = 0;
  
  while (value != NULL) {
    cols = 0;
    char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
    STR_WITH_MAXSIZE_TO_VARSTR(userName, 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, priType, pShow->pMeta->pSchemas[cols].bytes);
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
    colDataSetVal(pColInfo, *numOfRows, (const char *)privilege, false);
    
    size_t keyLen = 0;
    void  *key = taosHashGetKey(value, &keyLen);
    char  tableName[TSDB_TABLE_NAME_LEN] = {0};
    mndExtractTbNameFromStbFullName(key, tableName, TSDB_TABLE_NAME_LEN);

    if(strcmp(key, value) == 0){
      char *obj = taosMemoryMalloc(TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE);
      STR_WITH_MAXSIZE_TO_VARSTR(obj, tableName, pShow->pMeta->pSchemas[cols].bytes);

      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
      colDataSetVal(pColInfo, *numOfRows, (const char *)obj, false);
      taosMemoryFree(obj);
    }
    else{
      SNode  *pAst = NULL;
      int32_t sqlLen = 0;
      char *sql = NULL;

      if(nodesStringToNode(value, &pAst) == 0) {
        sql = taosMemoryMalloc(TSDB_EXPLAIN_RESULT_ROW_SIZE);
        nodesNodeToSQL(pAst, sql, TSDB_EXPLAIN_RESULT_ROW_SIZE, &sqlLen);
      }
      else{
        sqlLen = 5;
        sql = taosMemoryMalloc(sqlLen + 1);
        sprintf(sql, "error");
      }

      int32_t contentLen = sqlLen + TSDB_TABLE_NAME_LEN + 3;
      char *content = taosMemoryMalloc(contentLen);

      if(sql != NULL){
        sprintf(content, "%s(%s)", tableName, sql);
        taosMemoryFree(sql);
      }

      char *obj = taosMemoryMalloc(contentLen + VARSTR_HEADER_SIZE);
      STR_WITH_MAXSIZE_TO_VARSTR(obj, content, pShow->pMeta->pSchemas[cols].bytes);
      taosMemoryFree(content);

      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
      colDataSetVal(pColInfo, *numOfRows, (const char *)obj, false);
      taosMemoryFree(obj);
    }
    (*numOfRows)++;
    value = taosHashIterate(hash, value);
  }
}

S
Shengliang Guan 已提交
1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234
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;

1235 1236
    if (pUser->superUser) {
      cols = 0;
X
Xiaoyu Wang 已提交
1237
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
1238
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
X
Xiaoyu Wang 已提交
1239
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1240
      colDataSetVal(pColInfo, numOfRows, (const char *)userName, false);
1241 1242 1243 1244

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

      char objName[20] = {0};
      STR_WITH_MAXSIZE_TO_VARSTR(objName, "all", pShow->pMeta->pSchemas[cols].bytes);
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1250
      colDataSetVal(pColInfo, numOfRows, (const char *)objName, false);
1251 1252 1253 1254

      numOfRows++;
    }

S
Shengliang Guan 已提交
1255 1256 1257
    char *db = taosHashIterate(pUser->readDbs, NULL);
    while (db != NULL) {
      cols = 0;
X
Xiaoyu Wang 已提交
1258
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
S
Shengliang Guan 已提交
1259
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
X
Xiaoyu Wang 已提交
1260
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1261
      colDataSetVal(pColInfo, numOfRows, (const char *)userName, false);
S
Shengliang Guan 已提交
1262 1263 1264 1265

      char privilege[20] = {0};
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "read", pShow->pMeta->pSchemas[cols].bytes);
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1266
      colDataSetVal(pColInfo, numOfRows, (const char *)privilege, false);
S
Shengliang Guan 已提交
1267 1268 1269 1270 1271 1272 1273

      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++);
1274
      colDataSetVal(pColInfo, numOfRows, (const char *)objName, false);
S
Shengliang Guan 已提交
1275 1276 1277 1278 1279 1280 1281 1282

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

    db = taosHashIterate(pUser->writeDbs, NULL);
    while (db != NULL) {
      cols = 0;
1283
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
S
Shengliang Guan 已提交
1284
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
1285
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1286
      colDataSetVal(pColInfo, numOfRows, (const char *)userName, false);
S
Shengliang Guan 已提交
1287 1288 1289 1290

      char privilege[20] = {0};
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "write", pShow->pMeta->pSchemas[cols].bytes);
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1291
      colDataSetVal(pColInfo, numOfRows, (const char *)privilege, false);
S
Shengliang Guan 已提交
1292 1293 1294 1295 1296 1297 1298

      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++);
1299
      colDataSetVal(pColInfo, numOfRows, (const char *)objName, false);
S
Shengliang Guan 已提交
1300 1301 1302 1303 1304

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

C
cademfly 已提交
1305
    mndLoopHash(pUser->readTbs, "read", pBlock, &numOfRows, pUser->user, pShow);
C
table  
cademfly 已提交
1306

C
cademfly 已提交
1307
    mndLoopHash(pUser->writeTbs, "write", pBlock, &numOfRows, pUser->user, pShow);
C
table  
cademfly 已提交
1308

S
Shengliang Guan 已提交
1309 1310 1311
    char *topic = taosHashIterate(pUser->topics, NULL);
    while (topic != NULL) {
      cols = 0;
1312
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
S
Shengliang Guan 已提交
1313
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
1314
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1315
      colDataSetVal(pColInfo, numOfRows, (const char *)userName, false);
S
Shengliang Guan 已提交
1316 1317 1318 1319

      char privilege[20] = {0};
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "subscribe", pShow->pMeta->pSchemas[cols].bytes);
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1320
      colDataSetVal(pColInfo, numOfRows, (const char *)privilege, false);
S
Shengliang Guan 已提交
1321 1322 1323 1324 1325

      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++);
1326
      colDataSetVal(pColInfo, numOfRows, (const char *)topicName, false);
S
Shengliang Guan 已提交
1327 1328

      numOfRows++;
1329
      topic = taosHashIterate(pUser->topics, topic);
S
Shengliang Guan 已提交
1330
    }
1331

S
Shengliang Guan 已提交
1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342
    sdbRelease(pSdb, pUser);
  }

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

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

1344 1345
int32_t mndValidateUserAuthInfo(SMnode *pMnode, SUserAuthVersion *pUsers, int32_t numOfUses, void **ppRsp,
                                int32_t *pRspLen) {
D
dapan 已提交
1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360
  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 已提交
1361
    pUsers[i].version = ntohl(pUsers[i].version);
D
dapan 已提交
1362 1363 1364 1365
    if (pUser->authVersion <= pUsers[i].version) {
      mndReleaseUser(pMnode, pUser);
      continue;
    }
1366

D
dapan 已提交
1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381
    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;
1382

D
dapan 已提交
1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405
    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;
1406

D
dapan 已提交
1407 1408 1409
  tFreeSUserAuthBatchRsp(&batchRsp);
  return code;
}
1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430

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
cademfly 已提交
1431 1432
      (void)taosHashRemove(newUser.readTbs, db, len);
      (void)taosHashRemove(newUser.writeTbs, db, len);
1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459

      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);
1460 1461 1462
    if (pIter == NULL) {
      break;
    }
1463 1464

    code = -1;
1465 1466 1467
    if (mndUserDupObj(pUser, &newUser) != 0) {
      break;
    }
1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486

    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;
}