mndUser.c 35.1 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
  char *topic = taosHashIterate(pUser->topics, NULL);
  while (topic != NULL) {
    SDB_SET_BINARY(pRaw, dataPos, topic, TSDB_TOPIC_FNAME_LEN, _OVER);
164
    topic = taosHashIterate(pUser->topics, topic);
165 166
  }

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

288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305
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);
  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) {
306 307
  taosHashCleanup(pUser->readDbs);
  taosHashCleanup(pUser->writeDbs);
308
  taosHashCleanup(pUser->topics);
309 310
  pUser->readDbs = NULL;
  pUser->writeDbs = NULL;
311
  pUser->topics = NULL;
312 313 314 315 316
}

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

S
Shengliang Guan 已提交
320
static int32_t mndUserActionUpdate(SSdb *pSdb, SUserObj *pOld, SUserObj *pNew) {
S
Shengliang Guan 已提交
321
  mTrace("user:%s, perform update action, old row:%p new row:%p", pOld->user, pOld, pNew);
S
Shengliang Guan 已提交
322
  taosWLockLatch(&pOld->lock);
S
Shengliang Guan 已提交
323
  pOld->updateTime = pNew->updateTime;
D
dapan1121 已提交
324
  pOld->authVersion = pNew->authVersion;
325 326
  pOld->sysInfo = pNew->sysInfo;
  pOld->enable = pNew->enable;
S
Shengliang Guan 已提交
327
  memcpy(pOld->pass, pNew->pass, TSDB_PASSWORD_LEN);
wafwerar's avatar
wafwerar 已提交
328 329
  TSWAP(pOld->readDbs, pNew->readDbs);
  TSWAP(pOld->writeDbs, pNew->writeDbs);
330
  TSWAP(pOld->topics, pNew->topics);
S
Shengliang Guan 已提交
331
  taosWUnLockLatch(&pOld->lock);
332

S
Shengliang Guan 已提交
333 334 335
  return 0;
}

336
SUserObj *mndAcquireUser(SMnode *pMnode, const char *userName) {
S
Shengliang Guan 已提交
337 338 339
  SSdb     *pSdb = pMnode->pSdb;
  SUserObj *pUser = sdbAcquire(pSdb, SDB_USER, userName);
  if (pUser == NULL) {
dengyihao's avatar
dengyihao 已提交
340 341 342 343 344
    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 已提交
345 346
  }
  return pUser;
S
Shengliang Guan 已提交
347
}
S
Shengliang Guan 已提交
348

S
Shengliang Guan 已提交
349 350 351
void mndReleaseUser(SMnode *pMnode, SUserObj *pUser) {
  SSdb *pSdb = pMnode->pSdb;
  sdbRelease(pSdb, pUser);
S
Shengliang Guan 已提交
352 353
}

S
Shengliang Guan 已提交
354
static int32_t mndCreateUser(SMnode *pMnode, char *acct, SCreateUserReq *pCreate, SRpcMsg *pReq) {
S
Shengliang Guan 已提交
355
  SUserObj userObj = {0};
S
Shengliang Guan 已提交
356 357
  taosEncryptPass_c((uint8_t *)pCreate->pass, strlen(pCreate->pass), userObj.pass);
  tstrncpy(userObj.user, pCreate->user, TSDB_USER_LEN);
S
Shengliang Guan 已提交
358 359 360
  tstrncpy(userObj.acct, acct, TSDB_USER_LEN);
  userObj.createdTime = taosGetTimestampMs();
  userObj.updateTime = userObj.createdTime;
361
  userObj.superUser = 0;  // pCreate->superUser;
362 363
  userObj.sysInfo = pCreate->sysInfo;
  userObj.enable = pCreate->enable;
S
Shengliang Guan 已提交
364

365
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "create-user");
S
Shengliang Guan 已提交
366
  if (pTrans == NULL) {
S
Shengliang Guan 已提交
367
    mError("user:%s, failed to create since %s", pCreate->user, terrstr());
S
Shengliang Guan 已提交
368 369
    return -1;
  }
370
  mInfo("trans:%d, used to create user:%s", pTrans->id, pCreate->user);
S
Shengliang Guan 已提交
371

372 373 374
  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 已提交
375
    mndTransDrop(pTrans);
S
Shengliang Guan 已提交
376
    return -1;
S
Shengliang Guan 已提交
377
  }
S
Shengliang Guan 已提交
378
  (void)sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
S
Shengliang Guan 已提交
379

S
Shengliang Guan 已提交
380
  if (mndTransPrepare(pMnode, pTrans) != 0) {
S
Shengliang Guan 已提交
381
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
S
Shengliang Guan 已提交
382
    mndTransDrop(pTrans);
S
Shengliang Guan 已提交
383
    return -1;
S
Shengliang Guan 已提交
384 385
  }

S
Shengliang Guan 已提交
386
  mndTransDrop(pTrans);
S
Shengliang Guan 已提交
387
  return 0;
S
Shengliang Guan 已提交
388 389
}

S
Shengliang Guan 已提交
390 391
static int32_t mndProcessCreateUserReq(SRpcMsg *pReq) {
  SMnode        *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
392 393 394 395 396
  int32_t        code = -1;
  SUserObj      *pUser = NULL;
  SUserObj      *pOperUser = NULL;
  SCreateUserReq createReq = {0};

S
Shengliang Guan 已提交
397
  if (tDeserializeSCreateUserReq(pReq->pCont, pReq->contLen, &createReq) != 0) {
S
Shengliang Guan 已提交
398
    terrno = TSDB_CODE_INVALID_MSG;
399
    goto _OVER;
S
Shengliang Guan 已提交
400
  }
S
Shengliang Guan 已提交
401

402
  mInfo("user:%s, start to create", createReq.user);
403 404 405
  if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CREATE_USER) != 0) {
    goto _OVER;
  }
S
Shengliang Guan 已提交
406

S
Shengliang Guan 已提交
407
  if (createReq.user[0] == 0) {
S
Shengliang Guan 已提交
408
    terrno = TSDB_CODE_MND_INVALID_USER_FORMAT;
409
    goto _OVER;
S
Shengliang Guan 已提交
410 411
  }

S
Shengliang Guan 已提交
412
  if (createReq.pass[0] == 0) {
S
Shengliang Guan 已提交
413
    terrno = TSDB_CODE_MND_INVALID_PASS_FORMAT;
414
    goto _OVER;
S
Shengliang Guan 已提交
415 416
  }

S
Shengliang Guan 已提交
417
  pUser = mndAcquireUser(pMnode, createReq.user);
S
Shengliang Guan 已提交
418
  if (pUser != NULL) {
S
Shengliang Guan 已提交
419
    terrno = TSDB_CODE_MND_USER_ALREADY_EXIST;
420
    goto _OVER;
S
Shengliang Guan 已提交
421 422
  }

423
  pOperUser = mndAcquireUser(pMnode, pReq->info.conn.user);
S
Shengliang Guan 已提交
424
  if (pOperUser == NULL) {
S
Shengliang Guan 已提交
425
    terrno = TSDB_CODE_MND_NO_USER_FROM_CONN;
426
    goto _OVER;
S
Shengliang Guan 已提交
427 428
  }

C
Cary Xu 已提交
429 430 431 432
  if ((terrno = grantCheck(TSDB_GRANT_USER)) != 0) {
    code = terrno;
    goto _OVER;
  }
433

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

437
_OVER:
S
Shengliang Guan 已提交
438
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
S
Shengliang Guan 已提交
439
    mError("user:%s, failed to create since %s", createReq.user, terrstr());
S
Shengliang Guan 已提交
440 441
  }

S
Shengliang Guan 已提交
442 443 444 445
  mndReleaseUser(pMnode, pUser);
  mndReleaseUser(pMnode, pOperUser);

  return code;
S
Shengliang Guan 已提交
446 447
}

S
Shengliang Guan 已提交
448
static int32_t mndAlterUser(SMnode *pMnode, SUserObj *pOld, SUserObj *pNew, SRpcMsg *pReq) {
449
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "alter-user");
S
Shengliang Guan 已提交
450
  if (pTrans == NULL) {
S
Shengliang Guan 已提交
451
    mError("user:%s, failed to alter since %s", pOld->user, terrstr());
S
Shengliang Guan 已提交
452 453
    return -1;
  }
454
  mInfo("trans:%d, used to alter user:%s", pTrans->id, pOld->user);
S
Shengliang Guan 已提交
455

456 457 458
  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 已提交
459 460 461
    mndTransDrop(pTrans);
    return -1;
  }
S
Shengliang Guan 已提交
462
  (void)sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
S
Shengliang Guan 已提交
463 464 465 466 467 468 469 470 471 472 473

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

  mndTransDrop(pTrans);
  return 0;
}

474
SHashObj *mndDupObjHash(SHashObj *pOld, int32_t dataLen) {
S
Shengliang Guan 已提交
475 476
  SHashObj *pNew =
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
S
Shengliang Guan 已提交
477 478 479 480 481 482 483 484
  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;
485
    if (taosHashPut(pNew, db, len, db, dataLen) != 0) {
S
Shengliang Guan 已提交
486 487
      taosHashCancelIterate(pOld, db);
      taosHashCleanup(pNew);
S
Shengliang Guan 已提交
488
      terrno = TSDB_CODE_OUT_OF_MEMORY;
S
Shengliang Guan 已提交
489 490 491 492 493 494 495 496
      return NULL;
    }
    db = taosHashIterate(pOld, db);
  }

  return pNew;
}

497 498 499 500
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 已提交
501 502
static int32_t mndProcessAlterUserReq(SRpcMsg *pReq) {
  SMnode       *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
503 504
  SSdb         *pSdb = pMnode->pSdb;
  void         *pIter = NULL;
S
Shengliang Guan 已提交
505 506 507
  int32_t       code = -1;
  SUserObj     *pUser = NULL;
  SUserObj     *pOperUser = NULL;
S
Shengliang Guan 已提交
508
  SUserObj      newUser = {0};
S
Shengliang Guan 已提交
509 510
  SAlterUserReq alterReq = {0};

S
Shengliang Guan 已提交
511
  if (tDeserializeSAlterUserReq(pReq->pCont, pReq->contLen, &alterReq) != 0) {
S
Shengliang Guan 已提交
512
    terrno = TSDB_CODE_INVALID_MSG;
513
    goto _OVER;
S
Shengliang Guan 已提交
514
  }
S
Shengliang Guan 已提交
515

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

S
Shengliang Guan 已提交
518
  if (alterReq.user[0] == 0) {
S
Shengliang Guan 已提交
519
    terrno = TSDB_CODE_MND_INVALID_USER_FORMAT;
520 521 522 523 524
    goto _OVER;
  }

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

S
Shengliang Guan 已提交
528
  pUser = mndAcquireUser(pMnode, alterReq.user);
S
Shengliang Guan 已提交
529 530
  if (pUser == NULL) {
    terrno = TSDB_CODE_MND_USER_NOT_EXIST;
531
    goto _OVER;
S
Shengliang Guan 已提交
532 533
  }

534
  pOperUser = mndAcquireUser(pMnode, pReq->info.conn.user);
S
Shengliang Guan 已提交
535 536
  if (pOperUser == NULL) {
    terrno = TSDB_CODE_MND_NO_USER_FROM_CONN;
537
    goto _OVER;
S
Shengliang Guan 已提交
538 539
  }

540
  if (mndCheckAlterUserPrivilege(pOperUser, pUser, &alterReq) != 0) {
S
Shengliang Guan 已提交
541 542 543
    goto _OVER;
  }

544
  if (mndUserDupObj(pUser, &newUser) != 0) goto _OVER;
S
Shengliang Guan 已提交
545 546 547 548

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

  if (alterReq.alterType == TSDB_ALTER_USER_SUPERUSER) {
S
Shengliang Guan 已提交
553
    newUser.superUser = alterReq.superUser;
S
Shengliang Guan 已提交
554 555
  }

556 557 558 559 560 561 562 563
  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 已提交
564
  if (alterReq.alterType == TSDB_ALTER_USER_ADD_READ_DB || alterReq.alterType == TSDB_ALTER_USER_ADD_ALL_DB) {
565 566 567
    if (strcmp(alterReq.objname, "1.*") != 0) {
      int32_t len = strlen(alterReq.objname) + 1;
      SDbObj *pDb = mndAcquireDb(pMnode, alterReq.objname);
S
Shengliang Guan 已提交
568 569 570 571
      if (pDb == NULL) {
        mndReleaseDb(pMnode, pDb);
        goto _OVER;
      }
572
      if (taosHashPut(newUser.readDbs, alterReq.objname, len, alterReq.objname, TSDB_DB_FNAME_LEN) != 0) {
S
Shengliang Guan 已提交
573 574 575 576 577 578 579 580 581 582 583 584
        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 已提交
585
    }
S
Shengliang Guan 已提交
586 587 588
  }

  if (alterReq.alterType == TSDB_ALTER_USER_ADD_WRITE_DB || alterReq.alterType == TSDB_ALTER_USER_ADD_ALL_DB) {
589 590 591
    if (strcmp(alterReq.objname, "1.*") != 0) {
      int32_t len = strlen(alterReq.objname) + 1;
      SDbObj *pDb = mndAcquireDb(pMnode, alterReq.objname);
S
Shengliang Guan 已提交
592 593 594 595
      if (pDb == NULL) {
        mndReleaseDb(pMnode, pDb);
        goto _OVER;
      }
596
      if (taosHashPut(newUser.writeDbs, alterReq.objname, len, alterReq.objname, TSDB_DB_FNAME_LEN) != 0) {
S
Shengliang Guan 已提交
597 598 599 600 601 602 603 604 605 606 607 608
        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 已提交
609 610 611
    }
  }

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

S
Shengliang Guan 已提交
626
  if (alterReq.alterType == TSDB_ALTER_USER_REMOVE_WRITE_DB || alterReq.alterType == TSDB_ALTER_USER_REMOVE_ALL_DB) {
627 628 629
    if (strcmp(alterReq.objname, "1.*") != 0) {
      int32_t len = strlen(alterReq.objname) + 1;
      SDbObj *pDb = mndAcquireDb(pMnode, alterReq.objname);
S
Shengliang Guan 已提交
630 631 632 633
      if (pDb == NULL) {
        mndReleaseDb(pMnode, pDb);
        goto _OVER;
      }
634
      taosHashRemove(newUser.writeDbs, alterReq.objname, len);
S
Shengliang Guan 已提交
635 636 637
    } else {
      taosHashClear(newUser.writeDbs);
    }
S
Shengliang Guan 已提交
638 639
  }

640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659
  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 已提交
660
  code = mndAlterUser(pMnode, pUser, &newUser, pReq);
S
Shengliang Guan 已提交
661
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
S
Shengliang Guan 已提交
662

663
_OVER:
S
Shengliang Guan 已提交
664
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
S
Shengliang Guan 已提交
665
    mError("user:%s, failed to alter since %s", alterReq.user, terrstr());
S
Shengliang Guan 已提交
666 667
  }

S
Shengliang Guan 已提交
668 669
  mndReleaseUser(pMnode, pOperUser);
  mndReleaseUser(pMnode, pUser);
670
  mndUserFreeObj(&newUser);
S
Shengliang Guan 已提交
671 672

  return code;
S
Shengliang Guan 已提交
673 674
}

S
Shengliang Guan 已提交
675
static int32_t mndDropUser(SMnode *pMnode, SRpcMsg *pReq, SUserObj *pUser) {
676
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "drop-user");
S
Shengliang Guan 已提交
677 678 679 680
  if (pTrans == NULL) {
    mError("user:%s, failed to drop since %s", pUser->user, terrstr());
    return -1;
  }
681
  mInfo("trans:%d, used to drop user:%s", pTrans->id, pUser->user);
S
Shengliang Guan 已提交
682

683 684 685
  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 已提交
686 687 688
    mndTransDrop(pTrans);
    return -1;
  }
S
Shengliang Guan 已提交
689
  (void)sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED);
S
Shengliang Guan 已提交
690 691 692 693 694 695 696 697 698 699 700

  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 已提交
701 702
static int32_t mndProcessDropUserReq(SRpcMsg *pReq) {
  SMnode      *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
703 704 705 706
  int32_t      code = -1;
  SUserObj    *pUser = NULL;
  SDropUserReq dropReq = {0};

S
Shengliang Guan 已提交
707
  if (tDeserializeSDropUserReq(pReq->pCont, pReq->contLen, &dropReq) != 0) {
S
Shengliang Guan 已提交
708
    terrno = TSDB_CODE_INVALID_MSG;
709
    goto _OVER;
S
Shengliang Guan 已提交
710
  }
S
Shengliang Guan 已提交
711

712
  mInfo("user:%s, start to drop", dropReq.user);
713 714 715
  if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_DROP_USER) != 0) {
    goto _OVER;
  }
S
Shengliang Guan 已提交
716

S
Shengliang Guan 已提交
717
  if (dropReq.user[0] == 0) {
S
Shengliang Guan 已提交
718
    terrno = TSDB_CODE_MND_INVALID_USER_FORMAT;
719
    goto _OVER;
S
Shengliang Guan 已提交
720 721
  }

S
Shengliang Guan 已提交
722
  pUser = mndAcquireUser(pMnode, dropReq.user);
S
Shengliang Guan 已提交
723 724
  if (pUser == NULL) {
    terrno = TSDB_CODE_MND_USER_NOT_EXIST;
725
    goto _OVER;
S
Shengliang Guan 已提交
726 727
  }

S
Shengliang Guan 已提交
728
  code = mndDropUser(pMnode, pReq, pUser);
S
Shengliang Guan 已提交
729
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
S
Shengliang Guan 已提交
730

731
_OVER:
S
Shengliang Guan 已提交
732
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
S
Shengliang Guan 已提交
733
    mError("user:%s, failed to drop since %s", dropReq.user, terrstr());
S
Shengliang Guan 已提交
734 735
  }

S
Shengliang Guan 已提交
736 737
  mndReleaseUser(pMnode, pUser);
  return code;
S
Shengliang Guan 已提交
738 739
}

S
Shengliang Guan 已提交
740 741
static int32_t mndProcessGetUserAuthReq(SRpcMsg *pReq) {
  SMnode         *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
742 743 744 745 746
  int32_t         code = -1;
  SUserObj       *pUser = NULL;
  SGetUserAuthReq authReq = {0};
  SGetUserAuthRsp authRsp = {0};

S
Shengliang Guan 已提交
747
  if (tDeserializeSGetUserAuthReq(pReq->pCont, pReq->contLen, &authReq) != 0) {
S
Shengliang Guan 已提交
748
    terrno = TSDB_CODE_INVALID_MSG;
749
    goto _OVER;
S
Shengliang Guan 已提交
750
  }
S
Shengliang Guan 已提交
751 752 753 754 755 756

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

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

D
dapan 已提交
760 761 762
  code = mndSetUserAuthRsp(pMnode, pUser, &authRsp);
  if (code) {
    goto _OVER;
S
Shengliang Guan 已提交
763 764
  }

S
Shengliang Guan 已提交
765
  int32_t contLen = tSerializeSGetUserAuthRsp(NULL, 0, &authRsp);
S
Shengliang Guan 已提交
766 767 768
  void   *pRsp = rpcMallocCont(contLen);
  if (pRsp == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
769
    goto _OVER;
S
Shengliang Guan 已提交
770 771
  }

S
Shengliang Guan 已提交
772
  tSerializeSGetUserAuthRsp(pRsp, contLen, &authRsp);
S
Shengliang Guan 已提交
773

S
Shengliang Guan 已提交
774 775
  pReq->info.rsp = pRsp;
  pReq->info.rspLen = contLen;
S
Shengliang Guan 已提交
776 777
  code = 0;

778
_OVER:
779

S
Shengliang Guan 已提交
780
  mndReleaseUser(pMnode, pUser);
S
Shengliang Guan 已提交
781
  tFreeSGetUserAuthRsp(&authRsp);
S
Shengliang Guan 已提交
782 783 784 785

  return code;
}

S
Shengliang Guan 已提交
786 787
static int32_t mndRetrieveUsers(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
  SMnode   *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
788 789 790 791 792 793 794 795 796 797 798
  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;
799
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
800
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
801
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
802
    colDataSetVal(pColInfo, numOfRows, (const char *)name, false);
803

wafwerar's avatar
wafwerar 已提交
804 805
    cols++;
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
806
    colDataSetVal(pColInfo, numOfRows, (const char *)&pUser->superUser, false);
807

808 809
    cols++;
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
810
    colDataSetVal(pColInfo, numOfRows, (const char *)&pUser->enable, false);
811 812 813

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

wafwerar's avatar
wafwerar 已提交
816 817
    cols++;
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
818
    colDataSetVal(pColInfo, numOfRows, (const char *)&pUser->createdTime, false);
S
Shengliang Guan 已提交
819 820 821 822 823

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

824
  pShow->numOfRows += numOfRows;
S
Shengliang Guan 已提交
825 826 827 828 829 830
  return numOfRows;
}

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

S
Shengliang Guan 已提交
833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849
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;

850 851
    if (pUser->superUser) {
      cols = 0;
X
Xiaoyu Wang 已提交
852
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
853
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
X
Xiaoyu Wang 已提交
854
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
855
      colDataSetVal(pColInfo, numOfRows, (const char *)userName, false);
856 857 858 859

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

      char objName[20] = {0};
      STR_WITH_MAXSIZE_TO_VARSTR(objName, "all", pShow->pMeta->pSchemas[cols].bytes);
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
865
      colDataSetVal(pColInfo, numOfRows, (const char *)objName, false);
866 867 868 869

      numOfRows++;
    }

S
Shengliang Guan 已提交
870 871 872
    char *db = taosHashIterate(pUser->readDbs, NULL);
    while (db != NULL) {
      cols = 0;
X
Xiaoyu Wang 已提交
873
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
S
Shengliang Guan 已提交
874
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
X
Xiaoyu Wang 已提交
875
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
876
      colDataSetVal(pColInfo, numOfRows, (const char *)userName, false);
S
Shengliang Guan 已提交
877 878 879 880

      char privilege[20] = {0};
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "read", pShow->pMeta->pSchemas[cols].bytes);
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
881
      colDataSetVal(pColInfo, numOfRows, (const char *)privilege, false);
S
Shengliang Guan 已提交
882 883 884 885 886 887 888

      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++);
889
      colDataSetVal(pColInfo, numOfRows, (const char *)objName, false);
S
Shengliang Guan 已提交
890 891 892 893 894 895 896 897

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

    db = taosHashIterate(pUser->writeDbs, NULL);
    while (db != NULL) {
      cols = 0;
898
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
S
Shengliang Guan 已提交
899
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
900
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
901
      colDataSetVal(pColInfo, numOfRows, (const char *)userName, false);
S
Shengliang Guan 已提交
902 903 904 905

      char privilege[20] = {0};
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "write", pShow->pMeta->pSchemas[cols].bytes);
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
906
      colDataSetVal(pColInfo, numOfRows, (const char *)privilege, false);
S
Shengliang Guan 已提交
907 908 909 910 911 912 913

      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++);
914
      colDataSetVal(pColInfo, numOfRows, (const char *)objName, false);
S
Shengliang Guan 已提交
915 916 917 918 919 920 921 922

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

    char *topic = taosHashIterate(pUser->topics, NULL);
    while (topic != NULL) {
      cols = 0;
923
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
S
Shengliang Guan 已提交
924
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
925
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
926
      colDataSetVal(pColInfo, numOfRows, (const char *)userName, false);
S
Shengliang Guan 已提交
927 928 929 930

      char privilege[20] = {0};
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "subscribe", pShow->pMeta->pSchemas[cols].bytes);
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
931
      colDataSetVal(pColInfo, numOfRows, (const char *)privilege, false);
S
Shengliang Guan 已提交
932 933 934 935 936

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

      numOfRows++;
940
      topic = taosHashIterate(pUser->topics, topic);
S
Shengliang Guan 已提交
941
    }
942

S
Shengliang Guan 已提交
943 944 945 946 947 948 949 950 951 952 953
    sdbRelease(pSdb, pUser);
  }

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

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

955 956
int32_t mndValidateUserAuthInfo(SMnode *pMnode, SUserAuthVersion *pUsers, int32_t numOfUses, void **ppRsp,
                                int32_t *pRspLen) {
D
dapan 已提交
957 958 959 960 961 962 963 964 965 966 967 968 969 970 971
  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 已提交
972
    pUsers[i].version = ntohl(pUsers[i].version);
D
dapan 已提交
973 974 975 976
    if (pUser->authVersion <= pUsers[i].version) {
      mndReleaseUser(pMnode, pUser);
      continue;
    }
977

D
dapan 已提交
978 979 980 981 982 983 984 985 986 987 988 989 990 991 992
    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;
993

D
dapan 已提交
994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016
    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;
1017

D
dapan 已提交
1018 1019 1020
  tFreeSUserAuthBatchRsp(&batchRsp);
  return code;
}
1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068

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

      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);
1069 1070 1071
    if (pIter == NULL) {
      break;
    }
1072 1073

    code = -1;
1074 1075 1076
    if (mndUserDupObj(pUser, &newUser) != 0) {
      break;
    }
1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095

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