mndUser.c 31.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"
S
Shengliang Guan 已提交
24

25
#define USER_VER_NUMBER   2
26
#define USER_RESERVE_SIZE 64
S
Shengliang Guan 已提交
27

S
Shengliang Guan 已提交
28 29 30 31
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 已提交
32
static int32_t  mndUserActionUpdate(SSdb *pSdb, SUserObj *pOld, SUserObj *pNew);
S
Shengliang Guan 已提交
33 34 35 36 37 38
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 已提交
39
static void     mndCancelGetNextUser(SMnode *pMnode, void *pIter);
40 41
static int32_t  mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
static void     mndCancelGetNextPrivileges(SMnode *pMnode, void *pIter);
S
Shengliang Guan 已提交
42 43

int32_t mndInitUser(SMnode *pMnode) {
S
Shengliang Guan 已提交
44 45 46 47 48 49 50 51 52 53
  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 已提交
54

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

S
Shengliang Guan 已提交
60 61
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_USER, mndRetrieveUsers);
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_USER, mndCancelGetNextUser);
S
Shengliang Guan 已提交
62 63
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_PRIVILEGES, mndRetrievePrivileges);
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_PRIVILEGES, mndCancelGetNextPrivileges);
S
Shengliang Guan 已提交
64 65 66 67 68 69 70
  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 已提交
71
  taosEncryptPass_c((uint8_t *)pass, strlen(pass), userObj.pass);
S
Shengliang Guan 已提交
72 73 74 75
  tstrncpy(userObj.user, user, TSDB_USER_LEN);
  tstrncpy(userObj.acct, acct, TSDB_USER_LEN);
  userObj.createdTime = taosGetTimestampMs();
  userObj.updateTime = userObj.createdTime;
76 77
  userObj.sysInfo = 1;
  userObj.enable = 1;
S
Shengliang Guan 已提交
78 79

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

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

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

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

  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 已提交
102
  (void)sdbSetRawStatus(pRaw, SDB_STATUS_READY);
103 104 105 106 107 108 109 110 111

  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 已提交
112 113 114 115 116 117 118 119 120 121
}

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

  return 0;
}

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

S
Shengliang Guan 已提交
125 126
  int32_t numOfReadDbs = taosHashGetSize(pUser->readDbs);
  int32_t numOfWriteDbs = taosHashGetSize(pUser->writeDbs);
127 128 129
  int32_t numOfTopics = taosHashGetSize(pUser->topics);
  int32_t size = sizeof(SUserObj) + USER_RESERVE_SIZE + (numOfReadDbs + numOfWriteDbs) * TSDB_DB_FNAME_LEN +
                 numOfTopics * TSDB_TOPIC_FNAME_LEN;
S
Shengliang Guan 已提交
130

131
  SSdbRaw *pRaw = sdbAllocRaw(SDB_USER, USER_VER_NUMBER, size);
132
  if (pRaw == NULL) goto _OVER;
S
Shengliang Guan 已提交
133 134

  int32_t dataPos = 0;
135 136 137 138 139 140
  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)
141 142 143
  SDB_SET_INT8(pRaw, dataPos, pUser->sysInfo, _OVER)
  SDB_SET_INT8(pRaw, dataPos, pUser->enable, _OVER)
  SDB_SET_INT8(pRaw, dataPos, pUser->reserve, _OVER)
144
  SDB_SET_INT32(pRaw, dataPos, pUser->authVersion, _OVER)
145 146
  SDB_SET_INT32(pRaw, dataPos, numOfReadDbs, _OVER)
  SDB_SET_INT32(pRaw, dataPos, numOfWriteDbs, _OVER)
147
  SDB_SET_INT32(pRaw, dataPos, numOfTopics, _OVER)
148 149 150

  char *db = taosHashIterate(pUser->readDbs, NULL);
  while (db != NULL) {
151
    SDB_SET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER);
152 153 154 155 156
    db = taosHashIterate(pUser->readDbs, db);
  }

  db = taosHashIterate(pUser->writeDbs, NULL);
  while (db != NULL) {
157
    SDB_SET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER);
158 159 160
    db = taosHashIterate(pUser->writeDbs, db);
  }

161 162 163 164 165 166
  char *topic = taosHashIterate(pUser->topics, NULL);
  while (topic != NULL) {
    SDB_SET_BINARY(pRaw, dataPos, topic, TSDB_TOPIC_FNAME_LEN, _OVER);
    db = taosHashIterate(pUser->topics, topic);
  }

167 168
  SDB_SET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
  SDB_SET_DATALEN(pRaw, dataPos, _OVER)
169 170 171

  terrno = 0;

172
_OVER:
173 174 175 176 177
  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 已提交
178

S
Shengliang Guan 已提交
179
  mTrace("user:%s, encode to raw:%p, row:%p", pUser->user, pRaw, pUser);
S
Shengliang Guan 已提交
180
  return pRaw;
S
Shengliang Guan 已提交
181 182
}

S
Shengliang Guan 已提交
183
static SSdbRow *mndUserActionDecode(SSdbRaw *pRaw) {
184
  terrno = TSDB_CODE_OUT_OF_MEMORY;
185 186
  SSdbRow  *pRow = NULL;
  SUserObj *pUser = NULL;
187

S
Shengliang Guan 已提交
188
  int8_t sver = 0;
189
  if (sdbGetRawSoftVer(pRaw, &sver) != 0) goto _OVER;
S
Shengliang Guan 已提交
190

191
  if (sver != 1 && sver != 2) {
S
Shengliang Guan 已提交
192
    terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
193
    goto _OVER;
S
Shengliang Guan 已提交
194
  }
S
Shengliang Guan 已提交
195

196
  pRow = sdbAllocRow(sizeof(SUserObj));
197
  if (pRow == NULL) goto _OVER;
198

199
  pUser = sdbGetRowObj(pRow);
200
  if (pUser == NULL) goto _OVER;
201

S
Shengliang Guan 已提交
202
  int32_t dataPos = 0;
203 204 205 206 207 208
  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)
209 210 211
  SDB_GET_INT8(pRaw, dataPos, &pUser->sysInfo, _OVER)
  SDB_GET_INT8(pRaw, dataPos, &pUser->enable, _OVER)
  SDB_GET_INT8(pRaw, dataPos, &pUser->reserve, _OVER)
212
  SDB_GET_INT32(pRaw, dataPos, &pUser->authVersion, _OVER)
213 214 215

  int32_t numOfReadDbs = 0;
  int32_t numOfWriteDbs = 0;
216
  int32_t numOfTopics = 0;
217 218
  SDB_GET_INT32(pRaw, dataPos, &numOfReadDbs, _OVER)
  SDB_GET_INT32(pRaw, dataPos, &numOfWriteDbs, _OVER)
219 220 221 222
  if (sver >= 2) {
    SDB_GET_INT32(pRaw, dataPos, &numOfTopics, _OVER)
  }

S
Shengliang Guan 已提交
223 224 225
  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);
226 227
  pUser->topics = taosHashInit(numOfTopics, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
  if (pUser->readDbs == NULL || pUser->writeDbs == NULL || pUser->topics == NULL) goto _OVER;
228 229 230

  for (int32_t i = 0; i < numOfReadDbs; ++i) {
    char db[TSDB_DB_FNAME_LEN] = {0};
231
    SDB_GET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER)
232 233 234 235 236 237
    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};
238
    SDB_GET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER)
239 240 241 242
    int32_t len = strlen(db) + 1;
    taosHashPut(pUser->writeDbs, db, len, db, TSDB_DB_FNAME_LEN);
  }

243 244 245 246 247 248 249 250 251
  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);
    }
  }

252
  SDB_GET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
S
Shengliang Guan 已提交
253
  taosInitRWLatch(&pUser->lock);
254 255 256

  terrno = 0;

257
_OVER:
258
  if (terrno != 0) {
259 260 261 262 263 264
    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);
    }
wafwerar's avatar
wafwerar 已提交
265
    taosMemoryFreeClear(pRow);
266 267
    return NULL;
  }
S
Shengliang Guan 已提交
268

S
Shengliang Guan 已提交
269
  mTrace("user:%s, decode from raw:%p, row:%p", pUser->user, pRaw, pUser);
S
Shengliang Guan 已提交
270
  return pRow;
S
Shengliang Guan 已提交
271
}
S
Shengliang Guan 已提交
272

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

S
Shengliang Guan 已提交
276 277
  SAcctObj *pAcct = sdbAcquire(pSdb, SDB_ACCT, pUser->acct);
  if (pAcct == NULL) {
S
Shengliang Guan 已提交
278
    terrno = TSDB_CODE_MND_ACCT_NOT_EXIST;
S
Shengliang Guan 已提交
279
    mError("user:%s, failed to perform insert action since %s", pUser->user, terrstr());
S
Shengliang Guan 已提交
280
    return -1;
S
Shengliang Guan 已提交
281
  }
S
Shengliang Guan 已提交
282 283
  pUser->acctId = pAcct->acctId;
  sdbRelease(pSdb, pAcct);
S
Shengliang Guan 已提交
284

S
Shengliang Guan 已提交
285 286
  return 0;
}
S
Shengliang Guan 已提交
287

S
Shengliang Guan 已提交
288
static int32_t mndUserActionDelete(SSdb *pSdb, SUserObj *pUser) {
S
Shengliang Guan 已提交
289
  mTrace("user:%s, perform delete action, row:%p", pUser->user, pUser);
290 291
  taosHashCleanup(pUser->readDbs);
  taosHashCleanup(pUser->writeDbs);
292
  taosHashCleanup(pUser->topics);
293 294
  pUser->readDbs = NULL;
  pUser->writeDbs = NULL;
295
  pUser->topics = NULL;
S
Shengliang Guan 已提交
296 297 298
  return 0;
}

S
Shengliang Guan 已提交
299
static int32_t mndUserActionUpdate(SSdb *pSdb, SUserObj *pOld, SUserObj *pNew) {
S
Shengliang Guan 已提交
300
  mTrace("user:%s, perform update action, old row:%p new row:%p", pOld->user, pOld, pNew);
S
Shengliang Guan 已提交
301
  taosWLockLatch(&pOld->lock);
S
Shengliang Guan 已提交
302
  pOld->updateTime = pNew->updateTime;
D
dapan1121 已提交
303
  pOld->authVersion = pNew->authVersion;
304 305
  pOld->sysInfo = pNew->sysInfo;
  pOld->enable = pNew->enable;
S
Shengliang Guan 已提交
306
  memcpy(pOld->pass, pNew->pass, TSDB_PASSWORD_LEN);
wafwerar's avatar
wafwerar 已提交
307 308
  TSWAP(pOld->readDbs, pNew->readDbs);
  TSWAP(pOld->writeDbs, pNew->writeDbs);
309
  TSWAP(pOld->topics, pNew->topics);
S
Shengliang Guan 已提交
310
  taosWUnLockLatch(&pOld->lock);
311

S
Shengliang Guan 已提交
312 313 314
  return 0;
}

315
SUserObj *mndAcquireUser(SMnode *pMnode, const char *userName) {
S
Shengliang Guan 已提交
316 317 318
  SSdb     *pSdb = pMnode->pSdb;
  SUserObj *pUser = sdbAcquire(pSdb, SDB_USER, userName);
  if (pUser == NULL) {
S
Shengliang Guan 已提交
319
    terrno = TSDB_CODE_MND_USER_NOT_EXIST;
S
Shengliang Guan 已提交
320 321
  }
  return pUser;
S
Shengliang Guan 已提交
322
}
S
Shengliang Guan 已提交
323

S
Shengliang Guan 已提交
324 325 326
void mndReleaseUser(SMnode *pMnode, SUserObj *pUser) {
  SSdb *pSdb = pMnode->pSdb;
  sdbRelease(pSdb, pUser);
S
Shengliang Guan 已提交
327 328
}

S
Shengliang Guan 已提交
329
static int32_t mndCreateUser(SMnode *pMnode, char *acct, SCreateUserReq *pCreate, SRpcMsg *pReq) {
S
Shengliang Guan 已提交
330
  SUserObj userObj = {0};
S
Shengliang Guan 已提交
331 332
  taosEncryptPass_c((uint8_t *)pCreate->pass, strlen(pCreate->pass), userObj.pass);
  tstrncpy(userObj.user, pCreate->user, TSDB_USER_LEN);
S
Shengliang Guan 已提交
333 334 335
  tstrncpy(userObj.acct, acct, TSDB_USER_LEN);
  userObj.createdTime = taosGetTimestampMs();
  userObj.updateTime = userObj.createdTime;
336
  userObj.superUser = 0;  // pCreate->superUser;
337 338
  userObj.sysInfo = pCreate->sysInfo;
  userObj.enable = pCreate->enable;
S
Shengliang Guan 已提交
339

340
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "create-user");
S
Shengliang Guan 已提交
341
  if (pTrans == NULL) {
S
Shengliang Guan 已提交
342
    mError("user:%s, failed to create since %s", pCreate->user, terrstr());
S
Shengliang Guan 已提交
343 344
    return -1;
  }
345
  mInfo("trans:%d, used to create user:%s", pTrans->id, pCreate->user);
S
Shengliang Guan 已提交
346

347 348 349
  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 已提交
350
    mndTransDrop(pTrans);
S
Shengliang Guan 已提交
351
    return -1;
S
Shengliang Guan 已提交
352
  }
S
Shengliang Guan 已提交
353
  (void)sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
S
Shengliang Guan 已提交
354

S
Shengliang Guan 已提交
355
  if (mndTransPrepare(pMnode, pTrans) != 0) {
S
Shengliang Guan 已提交
356
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
S
Shengliang Guan 已提交
357
    mndTransDrop(pTrans);
S
Shengliang Guan 已提交
358
    return -1;
S
Shengliang Guan 已提交
359 360
  }

S
Shengliang Guan 已提交
361
  mndTransDrop(pTrans);
S
Shengliang Guan 已提交
362
  return 0;
S
Shengliang Guan 已提交
363 364
}

S
Shengliang Guan 已提交
365 366
static int32_t mndProcessCreateUserReq(SRpcMsg *pReq) {
  SMnode        *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
367 368 369 370 371
  int32_t        code = -1;
  SUserObj      *pUser = NULL;
  SUserObj      *pOperUser = NULL;
  SCreateUserReq createReq = {0};

S
Shengliang Guan 已提交
372
  if (tDeserializeSCreateUserReq(pReq->pCont, pReq->contLen, &createReq) != 0) {
S
Shengliang Guan 已提交
373
    terrno = TSDB_CODE_INVALID_MSG;
374
    goto _OVER;
S
Shengliang Guan 已提交
375
  }
S
Shengliang Guan 已提交
376

377
  mInfo("user:%s, start to create", createReq.user);
378 379 380
  if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CREATE_USER) != 0) {
    goto _OVER;
  }
S
Shengliang Guan 已提交
381

S
Shengliang Guan 已提交
382
  if (createReq.user[0] == 0) {
S
Shengliang Guan 已提交
383
    terrno = TSDB_CODE_MND_INVALID_USER_FORMAT;
384
    goto _OVER;
S
Shengliang Guan 已提交
385 386
  }

S
Shengliang Guan 已提交
387
  if (createReq.pass[0] == 0) {
S
Shengliang Guan 已提交
388
    terrno = TSDB_CODE_MND_INVALID_PASS_FORMAT;
389
    goto _OVER;
S
Shengliang Guan 已提交
390 391
  }

S
Shengliang Guan 已提交
392
  pUser = mndAcquireUser(pMnode, createReq.user);
S
Shengliang Guan 已提交
393
  if (pUser != NULL) {
S
Shengliang Guan 已提交
394
    terrno = TSDB_CODE_MND_USER_ALREADY_EXIST;
395
    goto _OVER;
S
Shengliang Guan 已提交
396 397
  }

398
  pOperUser = mndAcquireUser(pMnode, pReq->info.conn.user);
S
Shengliang Guan 已提交
399
  if (pOperUser == NULL) {
S
Shengliang Guan 已提交
400
    terrno = TSDB_CODE_MND_NO_USER_FROM_CONN;
401
    goto _OVER;
S
Shengliang Guan 已提交
402 403
  }

C
Cary Xu 已提交
404 405 406 407
  if ((terrno = grantCheck(TSDB_GRANT_USER)) != 0) {
    code = terrno;
    goto _OVER;
  }
408

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

412
_OVER:
S
Shengliang Guan 已提交
413
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
S
Shengliang Guan 已提交
414
    mError("user:%s, failed to create since %s", createReq.user, terrstr());
S
Shengliang Guan 已提交
415 416
  }

S
Shengliang Guan 已提交
417 418 419 420
  mndReleaseUser(pMnode, pUser);
  mndReleaseUser(pMnode, pOperUser);

  return code;
S
Shengliang Guan 已提交
421 422
}

S
Shengliang Guan 已提交
423
static int32_t mndAlterUser(SMnode *pMnode, SUserObj *pOld, SUserObj *pNew, SRpcMsg *pReq) {
424
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "alter-user");
S
Shengliang Guan 已提交
425
  if (pTrans == NULL) {
S
Shengliang Guan 已提交
426
    mError("user:%s, failed to alter since %s", pOld->user, terrstr());
S
Shengliang Guan 已提交
427 428
    return -1;
  }
429
  mInfo("trans:%d, used to alter user:%s", pTrans->id, pOld->user);
S
Shengliang Guan 已提交
430

431 432 433
  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 已提交
434 435 436
    mndTransDrop(pTrans);
    return -1;
  }
S
Shengliang Guan 已提交
437
  (void)sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
S
Shengliang Guan 已提交
438 439 440 441 442 443 444 445 446 447 448

  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 已提交
449
SHashObj *mndDupDbHash(SHashObj *pOld) {
S
Shengliang Guan 已提交
450 451
  SHashObj *pNew =
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
S
Shengliang Guan 已提交
452 453 454 455 456 457 458 459 460 461 462
  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;
    if (taosHashPut(pNew, db, len, db, TSDB_DB_FNAME_LEN) != 0) {
      taosHashCancelIterate(pOld, db);
      taosHashCleanup(pNew);
S
Shengliang Guan 已提交
463
      terrno = TSDB_CODE_OUT_OF_MEMORY;
S
Shengliang Guan 已提交
464 465 466 467 468 469 470 471
      return NULL;
    }
    db = taosHashIterate(pOld, db);
  }

  return pNew;
}

S
Shengliang Guan 已提交
472 473
static int32_t mndProcessAlterUserReq(SRpcMsg *pReq) {
  SMnode       *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
474 475
  SSdb         *pSdb = pMnode->pSdb;
  void         *pIter = NULL;
S
Shengliang Guan 已提交
476 477 478
  int32_t       code = -1;
  SUserObj     *pUser = NULL;
  SUserObj     *pOperUser = NULL;
S
Shengliang Guan 已提交
479
  SUserObj      newUser = {0};
S
Shengliang Guan 已提交
480 481
  SAlterUserReq alterReq = {0};

S
Shengliang Guan 已提交
482
  if (tDeserializeSAlterUserReq(pReq->pCont, pReq->contLen, &alterReq) != 0) {
S
Shengliang Guan 已提交
483
    terrno = TSDB_CODE_INVALID_MSG;
484
    goto _OVER;
S
Shengliang Guan 已提交
485
  }
S
Shengliang Guan 已提交
486

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

S
Shengliang Guan 已提交
489
  if (alterReq.user[0] == 0) {
S
Shengliang Guan 已提交
490
    terrno = TSDB_CODE_MND_INVALID_USER_FORMAT;
491 492 493 494 495
    goto _OVER;
  }

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

S
Shengliang Guan 已提交
499
  pUser = mndAcquireUser(pMnode, alterReq.user);
S
Shengliang Guan 已提交
500 501
  if (pUser == NULL) {
    terrno = TSDB_CODE_MND_USER_NOT_EXIST;
502
    goto _OVER;
S
Shengliang Guan 已提交
503 504
  }

505
  pOperUser = mndAcquireUser(pMnode, pReq->info.conn.user);
S
Shengliang Guan 已提交
506 507
  if (pOperUser == NULL) {
    terrno = TSDB_CODE_MND_NO_USER_FROM_CONN;
508
    goto _OVER;
S
Shengliang Guan 已提交
509 510
  }

511
  if (mndCheckAlterUserPrivilege(pOperUser, pUser, &alterReq) != 0) {
S
Shengliang Guan 已提交
512 513 514
    goto _OVER;
  }

S
Shengliang Guan 已提交
515
  memcpy(&newUser, pUser, sizeof(SUserObj));
S
Shengliang Guan 已提交
516 517
  newUser.authVersion++;
  newUser.updateTime = taosGetTimestampMs();
S
Shengliang Guan 已提交
518 519

  taosRLockLatch(&pUser->lock);
S
Shengliang Guan 已提交
520 521
  newUser.readDbs = mndDupDbHash(pUser->readDbs);
  newUser.writeDbs = mndDupDbHash(pUser->writeDbs);
522
  newUser.topics = mndDupDbHash(pUser->topics);
S
Shengliang Guan 已提交
523 524
  taosRUnLockLatch(&pUser->lock);

525
  if (newUser.readDbs == NULL || newUser.writeDbs == NULL || newUser.topics == NULL) {
526
    goto _OVER;
S
Shengliang Guan 已提交
527 528 529 530 531
  }

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

  if (alterReq.alterType == TSDB_ALTER_USER_SUPERUSER) {
S
Shengliang Guan 已提交
536
    newUser.superUser = alterReq.superUser;
S
Shengliang Guan 已提交
537 538
  }

539 540 541 542 543 544 545 546
  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 已提交
547
  if (alterReq.alterType == TSDB_ALTER_USER_ADD_READ_DB || alterReq.alterType == TSDB_ALTER_USER_ADD_ALL_DB) {
548 549 550
    if (strcmp(alterReq.objname, "1.*") != 0) {
      int32_t len = strlen(alterReq.objname) + 1;
      SDbObj *pDb = mndAcquireDb(pMnode, alterReq.objname);
S
Shengliang Guan 已提交
551 552 553 554
      if (pDb == NULL) {
        mndReleaseDb(pMnode, pDb);
        goto _OVER;
      }
555
      if (taosHashPut(newUser.readDbs, alterReq.objname, len, alterReq.objname, TSDB_DB_FNAME_LEN) != 0) {
S
Shengliang Guan 已提交
556 557 558 559 560 561 562 563 564 565 566 567
        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 已提交
568
    }
S
Shengliang Guan 已提交
569 570 571
  }

  if (alterReq.alterType == TSDB_ALTER_USER_ADD_WRITE_DB || alterReq.alterType == TSDB_ALTER_USER_ADD_ALL_DB) {
572 573 574
    if (strcmp(alterReq.objname, "1.*") != 0) {
      int32_t len = strlen(alterReq.objname) + 1;
      SDbObj *pDb = mndAcquireDb(pMnode, alterReq.objname);
S
Shengliang Guan 已提交
575 576 577 578
      if (pDb == NULL) {
        mndReleaseDb(pMnode, pDb);
        goto _OVER;
      }
579
      if (taosHashPut(newUser.writeDbs, alterReq.objname, len, alterReq.objname, TSDB_DB_FNAME_LEN) != 0) {
S
Shengliang Guan 已提交
580 581 582 583 584 585 586 587 588 589 590 591
        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 已提交
592 593 594
    }
  }

S
Shengliang Guan 已提交
595
  if (alterReq.alterType == TSDB_ALTER_USER_REMOVE_READ_DB || alterReq.alterType == TSDB_ALTER_USER_REMOVE_ALL_DB) {
596 597 598
    if (strcmp(alterReq.objname, "1.*") != 0) {
      int32_t len = strlen(alterReq.objname) + 1;
      SDbObj *pDb = mndAcquireDb(pMnode, alterReq.objname);
S
Shengliang Guan 已提交
599 600 601 602
      if (pDb == NULL) {
        mndReleaseDb(pMnode, pDb);
        goto _OVER;
      }
603
      taosHashRemove(newUser.readDbs, alterReq.objname, len);
S
Shengliang Guan 已提交
604 605 606 607
    } else {
      taosHashClear(newUser.readDbs);
    }
  }
S
Shengliang Guan 已提交
608

S
Shengliang Guan 已提交
609
  if (alterReq.alterType == TSDB_ALTER_USER_REMOVE_WRITE_DB || alterReq.alterType == TSDB_ALTER_USER_REMOVE_ALL_DB) {
610 611 612
    if (strcmp(alterReq.objname, "1.*") != 0) {
      int32_t len = strlen(alterReq.objname) + 1;
      SDbObj *pDb = mndAcquireDb(pMnode, alterReq.objname);
S
Shengliang Guan 已提交
613 614 615 616
      if (pDb == NULL) {
        mndReleaseDb(pMnode, pDb);
        goto _OVER;
      }
617
      taosHashRemove(newUser.writeDbs, alterReq.objname, len);
S
Shengliang Guan 已提交
618 619 620
    } else {
      taosHashClear(newUser.writeDbs);
    }
S
Shengliang Guan 已提交
621 622
  }

623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642
  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);
  }

  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 已提交
643
  code = mndAlterUser(pMnode, pUser, &newUser, pReq);
S
Shengliang Guan 已提交
644
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
S
Shengliang Guan 已提交
645

646
_OVER:
S
Shengliang Guan 已提交
647
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
S
Shengliang Guan 已提交
648
    mError("user:%s, failed to alter since %s", alterReq.user, terrstr());
S
Shengliang Guan 已提交
649 650
  }

S
Shengliang Guan 已提交
651 652
  mndReleaseUser(pMnode, pOperUser);
  mndReleaseUser(pMnode, pUser);
S
Shengliang Guan 已提交
653 654
  taosHashCleanup(newUser.writeDbs);
  taosHashCleanup(newUser.readDbs);
655
  taosHashCleanup(newUser.topics);
S
Shengliang Guan 已提交
656 657

  return code;
S
Shengliang Guan 已提交
658 659
}

S
Shengliang Guan 已提交
660
static int32_t mndDropUser(SMnode *pMnode, SRpcMsg *pReq, SUserObj *pUser) {
661
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "drop-user");
S
Shengliang Guan 已提交
662 663 664 665
  if (pTrans == NULL) {
    mError("user:%s, failed to drop since %s", pUser->user, terrstr());
    return -1;
  }
666
  mInfo("trans:%d, used to drop user:%s", pTrans->id, pUser->user);
S
Shengliang Guan 已提交
667

668 669 670
  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 已提交
671 672 673
    mndTransDrop(pTrans);
    return -1;
  }
S
Shengliang Guan 已提交
674
  (void)sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED);
S
Shengliang Guan 已提交
675 676 677 678 679 680 681 682 683 684 685

  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 已提交
686 687
static int32_t mndProcessDropUserReq(SRpcMsg *pReq) {
  SMnode      *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
688 689 690 691
  int32_t      code = -1;
  SUserObj    *pUser = NULL;
  SDropUserReq dropReq = {0};

S
Shengliang Guan 已提交
692
  if (tDeserializeSDropUserReq(pReq->pCont, pReq->contLen, &dropReq) != 0) {
S
Shengliang Guan 已提交
693
    terrno = TSDB_CODE_INVALID_MSG;
694
    goto _OVER;
S
Shengliang Guan 已提交
695
  }
S
Shengliang Guan 已提交
696

697
  mInfo("user:%s, start to drop", dropReq.user);
698 699 700
  if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_DROP_USER) != 0) {
    goto _OVER;
  }
S
Shengliang Guan 已提交
701

S
Shengliang Guan 已提交
702
  if (dropReq.user[0] == 0) {
S
Shengliang Guan 已提交
703
    terrno = TSDB_CODE_MND_INVALID_USER_FORMAT;
704
    goto _OVER;
S
Shengliang Guan 已提交
705 706
  }

S
Shengliang Guan 已提交
707
  pUser = mndAcquireUser(pMnode, dropReq.user);
S
Shengliang Guan 已提交
708 709
  if (pUser == NULL) {
    terrno = TSDB_CODE_MND_USER_NOT_EXIST;
710
    goto _OVER;
S
Shengliang Guan 已提交
711 712
  }

S
Shengliang Guan 已提交
713
  code = mndDropUser(pMnode, pReq, pUser);
S
Shengliang Guan 已提交
714
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
S
Shengliang Guan 已提交
715

716
_OVER:
S
Shengliang Guan 已提交
717
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
S
Shengliang Guan 已提交
718
    mError("user:%s, failed to drop since %s", dropReq.user, terrstr());
S
Shengliang Guan 已提交
719 720
  }

S
Shengliang Guan 已提交
721 722
  mndReleaseUser(pMnode, pUser);
  return code;
S
Shengliang Guan 已提交
723 724
}

S
Shengliang Guan 已提交
725 726
static int32_t mndProcessGetUserAuthReq(SRpcMsg *pReq) {
  SMnode         *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
727 728 729 730 731
  int32_t         code = -1;
  SUserObj       *pUser = NULL;
  SGetUserAuthReq authReq = {0};
  SGetUserAuthRsp authRsp = {0};

S
Shengliang Guan 已提交
732
  if (tDeserializeSGetUserAuthReq(pReq->pCont, pReq->contLen, &authReq) != 0) {
S
Shengliang Guan 已提交
733
    terrno = TSDB_CODE_INVALID_MSG;
734
    goto _OVER;
S
Shengliang Guan 已提交
735
  }
S
Shengliang Guan 已提交
736 737 738 739 740 741

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

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

D
dapan 已提交
745 746 747
  code = mndSetUserAuthRsp(pMnode, pUser, &authRsp);
  if (code) {
    goto _OVER;
S
Shengliang Guan 已提交
748 749
  }

S
Shengliang Guan 已提交
750
  int32_t contLen = tSerializeSGetUserAuthRsp(NULL, 0, &authRsp);
S
Shengliang Guan 已提交
751 752 753
  void   *pRsp = rpcMallocCont(contLen);
  if (pRsp == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
754
    goto _OVER;
S
Shengliang Guan 已提交
755 756
  }

S
Shengliang Guan 已提交
757
  tSerializeSGetUserAuthRsp(pRsp, contLen, &authRsp);
S
Shengliang Guan 已提交
758

S
Shengliang Guan 已提交
759 760
  pReq->info.rsp = pRsp;
  pReq->info.rspLen = contLen;
S
Shengliang Guan 已提交
761 762
  code = 0;

763
_OVER:
764

S
Shengliang Guan 已提交
765
  mndReleaseUser(pMnode, pUser);
S
Shengliang Guan 已提交
766
  tFreeSGetUserAuthRsp(&authRsp);
S
Shengliang Guan 已提交
767 768 769 770

  return code;
}

S
Shengliang Guan 已提交
771 772
static int32_t mndRetrieveUsers(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
  SMnode   *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
773 774 775 776 777 778 779 780 781 782 783
  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;
784
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
785
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
786
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
787
    colDataAppend(pColInfo, numOfRows, (const char *)name, false);
788

wafwerar's avatar
wafwerar 已提交
789 790
    cols++;
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
791
    colDataAppend(pColInfo, numOfRows, (const char *)&pUser->superUser, false);
792

793 794 795 796 797 798 799
    cols++;
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
    colDataAppend(pColInfo, numOfRows, (const char *)&pUser->enable, false);

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

wafwerar's avatar
wafwerar 已提交
801 802
    cols++;
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
803
    colDataAppend(pColInfo, numOfRows, (const char *)&pUser->createdTime, false);
S
Shengliang Guan 已提交
804 805 806 807 808

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

809
  pShow->numOfRows += numOfRows;
S
Shengliang Guan 已提交
810 811 812 813 814 815
  return numOfRows;
}

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

S
Shengliang Guan 已提交
818 819 820 821 822 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 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
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;

    char *db = taosHashIterate(pUser->readDbs, NULL);
    while (db != NULL) {
      cols = 0;
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
      char             userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
      colDataAppend(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++);
      colDataAppend(pColInfo, numOfRows, (const char *)privilege, false);

      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++);
      colDataAppend(pColInfo, numOfRows, (const char *)objName, false);

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

    db = taosHashIterate(pUser->writeDbs, NULL);
    while (db != NULL) {
      cols = 0;
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
      char             userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
      colDataAppend(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++);
      colDataAppend(pColInfo, numOfRows, (const char *)privilege, false);

      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++);
      colDataAppend(pColInfo, numOfRows, (const char *)objName, false);

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

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

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

      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++);
      colDataAppend(pColInfo, numOfRows, (const char *)topicName, false);

      numOfRows++;
      db = taosHashIterate(pUser->topics, topic);
    }
907

S
Shengliang Guan 已提交
908 909 910 911 912 913 914 915 916 917 918
    sdbRelease(pSdb, pUser);
  }

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

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

920 921
int32_t mndValidateUserAuthInfo(SMnode *pMnode, SUserAuthVersion *pUsers, int32_t numOfUses, void **ppRsp,
                                int32_t *pRspLen) {
D
dapan 已提交
922 923 924 925 926 927 928 929 930 931 932 933 934 935 936
  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 已提交
937
    pUsers[i].version = ntohl(pUsers[i].version);
D
dapan 已提交
938 939 940 941
    if (pUser->authVersion <= pUsers[i].version) {
      mndReleaseUser(pMnode, pUser);
      continue;
    }
942

D
dapan 已提交
943 944 945 946 947 948 949 950 951 952 953 954 955 956 957
    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;
958

D
dapan 已提交
959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981
    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;
982

D
dapan 已提交
983 984 985
  tFreeSUserAuthBatchRsp(&batchRsp);
  return code;
}