mndUser.c 21.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 "mndShow.h"
S
Shengliang Guan 已提交
20
#include "mndTrans.h"
S
Shengliang Guan 已提交
21
#include "tkey.h"
S
Shengliang Guan 已提交
22

S
Shengliang Guan 已提交
23
#define TSDB_USER_VER_NUMBER 1
S
Shengliang Guan 已提交
24
#define TSDB_USER_RESERVE_SIZE 64
S
Shengliang Guan 已提交
25

S
Shengliang Guan 已提交
26 27 28 29 30
static int32_t  mndCreateDefaultUsers(SMnode *pMnode);
static SSdbRaw *mndUserActionEncode(SUserObj *pUser);
static SSdbRow *mndUserActionDecode(SSdbRaw *pRaw);
static int32_t  mndUserActionInsert(SSdb *pSdb, SUserObj *pUser);
static int32_t  mndUserActionDelete(SSdb *pSdb, SUserObj *pUser);
S
Shengliang Guan 已提交
31
static int32_t  mndUserActionUpdate(SSdb *pSdb, SUserObj *pOld, SUserObj *pNew);
S
Shengliang Guan 已提交
32 33 34 35
static int32_t  mndCreateUser(SMnode *pMnode, char *acct, char *user, char *pass, SMnodeMsg *pReq);
static int32_t  mndProcessCreateUserReq(SMnodeMsg *pReq);
static int32_t  mndProcessAlterUserReq(SMnodeMsg *pReq);
static int32_t  mndProcessDropUserReq(SMnodeMsg *pReq);
S
Shengliang Guan 已提交
36
static int32_t  mndGetUserMeta(SMnodeMsg *pReq, SShowObj *pShow, STableMetaRsp *pMeta);
S
Shengliang Guan 已提交
37
static int32_t  mndRetrieveUsers(SMnodeMsg *pReq, SShowObj *pShow, char *data, int32_t rows);
S
Shengliang Guan 已提交
38
static void     mndCancelGetNextUser(SMnode *pMnode, void *pIter);
S
Shengliang Guan 已提交
39 40 41 42 43 44 45 46 47 48 49

int32_t mndInitUser(SMnode *pMnode) {
  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 已提交
50 51 52
  mndSetMsgHandle(pMnode, TDMT_MND_CREATE_USER, mndProcessCreateUserReq);
  mndSetMsgHandle(pMnode, TDMT_MND_ALTER_USER, mndProcessAlterUserReq);
  mndSetMsgHandle(pMnode, TDMT_MND_DROP_USER, mndProcessDropUserReq);
S
Shengliang Guan 已提交
53

S
Shengliang Guan 已提交
54 55 56
  mndAddShowMetaHandle(pMnode, TSDB_MGMT_TABLE_USER, mndGetUserMeta);
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_USER, mndRetrieveUsers);
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_USER, mndCancelGetNextUser);
S
Shengliang Guan 已提交
57 58 59 60 61 62 63
  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 已提交
64
  taosEncryptPass_c((uint8_t *)pass, strlen(pass), userObj.pass);
S
Shengliang Guan 已提交
65 66 67 68 69 70
  tstrncpy(userObj.user, user, TSDB_USER_LEN);
  tstrncpy(userObj.acct, acct, TSDB_USER_LEN);
  userObj.createdTime = taosGetTimestampMs();
  userObj.updateTime = userObj.createdTime;

  if (strcmp(user, TSDB_DEFAULT_USER) == 0) {
71
    userObj.superUser = 1;
S
Shengliang Guan 已提交
72 73 74 75 76 77
  }

  SSdbRaw *pRaw = mndUserActionEncode(&userObj);
  if (pRaw == NULL) return -1;
  sdbSetRawStatus(pRaw, SDB_STATUS_READY);

S
Shengliang Guan 已提交
78
  mDebug("user:%s, will be created while deploy sdb, raw:%p", userObj.user, pRaw);
S
Shengliang Guan 已提交
79 80 81 82 83 84 85 86
  return sdbWrite(pMnode->pSdb, pRaw);
}

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

S
Shengliang Guan 已提交
87
#if 0
S
Shengliang Guan 已提交
88 89 90
  if (mndCreateDefaultUser(pMnode, TSDB_DEFAULT_USER, "_" TSDB_DEFAULT_USER, TSDB_DEFAULT_PASS) != 0) {
    return -1;
  }
H
Haojun Liao 已提交
91
#endif
S
Shengliang Guan 已提交
92 93 94 95

  return 0;
}

S
Shengliang Guan 已提交
96
static SSdbRaw *mndUserActionEncode(SUserObj *pUser) {
97 98
  terrno = TSDB_CODE_OUT_OF_MEMORY;

S
Shengliang Guan 已提交
99
  SSdbRaw *pRaw = sdbAllocRaw(SDB_USER, TSDB_USER_VER_NUMBER, sizeof(SUserObj) + TSDB_USER_RESERVE_SIZE);
100
  if (pRaw == NULL) goto USER_ENCODE_OVER;
S
Shengliang Guan 已提交
101 102

  int32_t dataPos = 0;
103 104 105 106 107 108
  SDB_SET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN, USER_ENCODE_OVER)
  SDB_SET_BINARY(pRaw, dataPos, pUser->pass, TSDB_PASSWORD_LEN, USER_ENCODE_OVER)
  SDB_SET_BINARY(pRaw, dataPos, pUser->acct, TSDB_USER_LEN, USER_ENCODE_OVER)
  SDB_SET_INT64(pRaw, dataPos, pUser->createdTime, USER_ENCODE_OVER)
  SDB_SET_INT64(pRaw, dataPos, pUser->updateTime, USER_ENCODE_OVER)
  SDB_SET_INT8(pRaw, dataPos, pUser->superUser, USER_ENCODE_OVER)
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126

  int32_t numOfReadDbs = taosHashGetSize(pUser->readDbs);
  int32_t numOfWriteDbs = taosHashGetSize(pUser->writeDbs);
  SDB_SET_INT32(pRaw, dataPos, numOfReadDbs, USER_ENCODE_OVER)
  SDB_SET_INT32(pRaw, dataPos, numOfWriteDbs, USER_ENCODE_OVER)

  char *db = taosHashIterate(pUser->readDbs, NULL);
  while (db != NULL) {
    SDB_SET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, USER_ENCODE_OVER);
    db = taosHashIterate(pUser->readDbs, db);
  }

  db = taosHashIterate(pUser->writeDbs, NULL);
  while (db != NULL) {
    SDB_SET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, USER_ENCODE_OVER);
    db = taosHashIterate(pUser->writeDbs, db);
  }

127 128 129 130 131 132 133 134 135 136 137
  SDB_SET_RESERVE(pRaw, dataPos, TSDB_USER_RESERVE_SIZE, USER_ENCODE_OVER)
  SDB_SET_DATALEN(pRaw, dataPos, USER_ENCODE_OVER)

  terrno = 0;

USER_ENCODE_OVER:
  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 已提交
138

S
Shengliang Guan 已提交
139
  mTrace("user:%s, encode to raw:%p, row:%p", pUser->user, pRaw, pUser);
S
Shengliang Guan 已提交
140
  return pRaw;
S
Shengliang Guan 已提交
141 142
}

S
Shengliang Guan 已提交
143
static SSdbRow *mndUserActionDecode(SSdbRaw *pRaw) {
144 145
  terrno = TSDB_CODE_OUT_OF_MEMORY;

S
Shengliang Guan 已提交
146
  int8_t sver = 0;
147
  if (sdbGetRawSoftVer(pRaw, &sver) != 0) goto USER_DECODE_OVER;
S
Shengliang Guan 已提交
148

S
Shengliang Guan 已提交
149
  if (sver != TSDB_USER_VER_NUMBER) {
S
Shengliang Guan 已提交
150
    terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
151
    goto USER_DECODE_OVER;
S
Shengliang Guan 已提交
152
  }
S
Shengliang Guan 已提交
153

154 155 156
  SSdbRow *pRow = sdbAllocRow(sizeof(SUserObj));
  if (pRow == NULL) goto USER_DECODE_OVER;

S
Shengliang Guan 已提交
157
  SUserObj *pUser = sdbGetRowObj(pRow);
158
  if (pUser == NULL) goto USER_DECODE_OVER;
S
Shengliang Guan 已提交
159

160 161 162 163
  pUser->readDbs = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, true);
  pUser->writeDbs = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, true);
  if (pUser->readDbs == NULL || pUser->writeDbs == NULL) goto USER_DECODE_OVER;

S
Shengliang Guan 已提交
164
  int32_t dataPos = 0;
165 166 167 168 169 170
  SDB_GET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN, USER_DECODE_OVER)
  SDB_GET_BINARY(pRaw, dataPos, pUser->pass, TSDB_PASSWORD_LEN, USER_DECODE_OVER)
  SDB_GET_BINARY(pRaw, dataPos, pUser->acct, TSDB_USER_LEN, USER_DECODE_OVER)
  SDB_GET_INT64(pRaw, dataPos, &pUser->createdTime, USER_DECODE_OVER)
  SDB_GET_INT64(pRaw, dataPos, &pUser->updateTime, USER_DECODE_OVER)
  SDB_GET_INT8(pRaw, dataPos, &pUser->superUser, USER_DECODE_OVER)
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190

  int32_t numOfReadDbs = 0;
  int32_t numOfWriteDbs = 0;
  SDB_GET_INT32(pRaw, dataPos, &numOfReadDbs, USER_DECODE_OVER)
  SDB_GET_INT32(pRaw, dataPos, &numOfWriteDbs, USER_DECODE_OVER)

  for (int32_t i = 0; i < numOfReadDbs; ++i) {
    char db[TSDB_DB_FNAME_LEN] = {0};
    SDB_GET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, USER_DECODE_OVER)
    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};
    SDB_GET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, USER_DECODE_OVER)
    int32_t len = strlen(db) + 1;
    taosHashPut(pUser->writeDbs, db, len, db, TSDB_DB_FNAME_LEN);
  }

191 192 193 194 195 196 197
  SDB_GET_RESERVE(pRaw, dataPos, TSDB_USER_RESERVE_SIZE, USER_DECODE_OVER)

  terrno = 0;

USER_DECODE_OVER:
  if (terrno != 0) {
    mError("user:%s, failed to decode from raw:%p since %s", pUser->user, pRaw, terrstr());
198 199
    taosHashCleanup(pUser->readDbs);
    taosHashCleanup(pUser->writeDbs);
200 201 202
    tfree(pRow);
    return NULL;
  }
S
Shengliang Guan 已提交
203

S
Shengliang Guan 已提交
204
  mTrace("user:%s, decode from raw:%p, row:%p", pUser->user, pRaw, pUser);
S
Shengliang Guan 已提交
205
  return pRow;
S
Shengliang Guan 已提交
206
}
S
Shengliang Guan 已提交
207

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

S
Shengliang Guan 已提交
211 212
  SAcctObj *pAcct = sdbAcquire(pSdb, SDB_ACCT, pUser->acct);
  if (pAcct == NULL) {
S
Shengliang Guan 已提交
213
    terrno = TSDB_CODE_MND_ACCT_NOT_EXIST;
S
Shengliang Guan 已提交
214
    mError("user:%s, failed to perform insert action since %s", pUser->user, terrstr());
S
Shengliang Guan 已提交
215
    return -1;
S
Shengliang Guan 已提交
216
  }
S
Shengliang Guan 已提交
217 218
  pUser->acctId = pAcct->acctId;
  sdbRelease(pSdb, pAcct);
S
Shengliang Guan 已提交
219

S
Shengliang Guan 已提交
220 221
  return 0;
}
S
Shengliang Guan 已提交
222

S
Shengliang Guan 已提交
223
static int32_t mndUserActionDelete(SSdb *pSdb, SUserObj *pUser) {
S
Shengliang Guan 已提交
224
  mTrace("user:%s, perform delete action, row:%p", pUser->user, pUser);
225 226
  taosHashCleanup(pUser->readDbs);
  taosHashCleanup(pUser->writeDbs);
S
Shengliang Guan 已提交
227 228 229
  return 0;
}

S
Shengliang Guan 已提交
230
static int32_t mndUserActionUpdate(SSdb *pSdb, SUserObj *pOld, SUserObj *pNew) {
S
Shengliang Guan 已提交
231
  mTrace("user:%s, perform update action, old row:%p new row:%p", pOld->user, pOld, pNew);
S
Shengliang Guan 已提交
232 233
  memcpy(pOld->pass, pNew->pass, TSDB_PASSWORD_LEN);
  pOld->updateTime = pNew->updateTime;
234 235 236 237 238 239 240 241 242

  void *tmp1 = pOld->readDbs;
  pOld->readDbs = pNew->readDbs;
  pNew->readDbs = tmp1;

  void *tmp2 = pOld->writeDbs;
  pOld->writeDbs = pNew->writeDbs;
  pNew->writeDbs = tmp2;

S
Shengliang Guan 已提交
243 244 245
  return 0;
}

S
Shengliang Guan 已提交
246
SUserObj *mndAcquireUser(SMnode *pMnode, char *userName) {
S
Shengliang Guan 已提交
247 248 249
  SSdb     *pSdb = pMnode->pSdb;
  SUserObj *pUser = sdbAcquire(pSdb, SDB_USER, userName);
  if (pUser == NULL) {
S
Shengliang Guan 已提交
250
    terrno = TSDB_CODE_MND_USER_NOT_EXIST;
S
Shengliang Guan 已提交
251 252
  }
  return pUser;
S
Shengliang Guan 已提交
253
}
S
Shengliang Guan 已提交
254

S
Shengliang Guan 已提交
255 256 257
void mndReleaseUser(SMnode *pMnode, SUserObj *pUser) {
  SSdb *pSdb = pMnode->pSdb;
  sdbRelease(pSdb, pUser);
S
Shengliang Guan 已提交
258 259
}

S
Shengliang Guan 已提交
260
static int32_t mndCreateUser(SMnode *pMnode, char *acct, char *user, char *pass, SMnodeMsg *pReq) {
S
Shengliang Guan 已提交
261
  SUserObj userObj = {0};
S
Shengliang Guan 已提交
262
  taosEncryptPass_c((uint8_t *)pass, strlen(pass), userObj.pass);
S
Shengliang Guan 已提交
263 264 265 266
  tstrncpy(userObj.user, user, TSDB_USER_LEN);
  tstrncpy(userObj.acct, acct, TSDB_USER_LEN);
  userObj.createdTime = taosGetTimestampMs();
  userObj.updateTime = userObj.createdTime;
267
  userObj.superUser = 0;
S
Shengliang Guan 已提交
268

S
Shengliang Guan 已提交
269
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, &pReq->rpcMsg);
S
Shengliang Guan 已提交
270 271 272 273 274
  if (pTrans == NULL) {
    mError("user:%s, failed to create since %s", user, terrstr());
    return -1;
  }
  mDebug("trans:%d, used to create user:%s", pTrans->id, user);
S
Shengliang Guan 已提交
275

S
Shengliang Guan 已提交
276
  SSdbRaw *pRedoRaw = mndUserActionEncode(&userObj);
S
Shengliang Guan 已提交
277
  if (pRedoRaw == NULL || mndTransAppendRedolog(pTrans, pRedoRaw) != 0) {
S
Shengliang Guan 已提交
278
    mError("trans:%d, failed to append redo log since %s", pTrans->id, terrstr());
S
Shengliang Guan 已提交
279
    mndTransDrop(pTrans);
S
Shengliang Guan 已提交
280
    return -1;
S
Shengliang Guan 已提交
281
  }
S
Shengliang Guan 已提交
282 283
  sdbSetRawStatus(pRedoRaw, SDB_STATUS_READY);

S
Shengliang Guan 已提交
284
  if (mndTransPrepare(pMnode, pTrans) != 0) {
S
Shengliang Guan 已提交
285
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
S
Shengliang Guan 已提交
286
    mndTransDrop(pTrans);
S
Shengliang Guan 已提交
287
    return -1;
S
Shengliang Guan 已提交
288 289
  }

S
Shengliang Guan 已提交
290
  mndTransDrop(pTrans);
S
Shengliang Guan 已提交
291
  return 0;
S
Shengliang Guan 已提交
292 293
}

S
Shengliang Guan 已提交
294
static int32_t mndProcessCreateUserReq(SMnodeMsg *pReq) {
S
Shengliang Guan 已提交
295 296 297 298 299 300 301
  SMnode        *pMnode = pReq->pMnode;
  int32_t        code = -1;
  SUserObj      *pUser = NULL;
  SUserObj      *pOperUser = NULL;
  SCreateUserReq createReq = {0};

  if (tDeserializeSCreateUserReq(pReq->rpcMsg.pCont, &createReq) == NULL) goto CREATE_USER_OVER;
S
Shengliang Guan 已提交
302

S
Shengliang Guan 已提交
303
  mDebug("user:%s, start to create", createReq.user);
S
Shengliang Guan 已提交
304

S
Shengliang Guan 已提交
305
  if (createReq.user[0] == 0) {
S
Shengliang Guan 已提交
306
    terrno = TSDB_CODE_MND_INVALID_USER_FORMAT;
S
Shengliang Guan 已提交
307
    goto CREATE_USER_OVER;
S
Shengliang Guan 已提交
308 309
  }

S
Shengliang Guan 已提交
310
  if (createReq.pass[0] == 0) {
S
Shengliang Guan 已提交
311
    terrno = TSDB_CODE_MND_INVALID_PASS_FORMAT;
S
Shengliang Guan 已提交
312
    goto CREATE_USER_OVER;
S
Shengliang Guan 已提交
313 314
  }

S
Shengliang Guan 已提交
315
  pUser = mndAcquireUser(pMnode, createReq.user);
S
Shengliang Guan 已提交
316
  if (pUser != NULL) {
S
Shengliang Guan 已提交
317
    terrno = TSDB_CODE_MND_USER_ALREADY_EXIST;
S
Shengliang Guan 已提交
318
    goto CREATE_USER_OVER;
S
Shengliang Guan 已提交
319 320
  }

S
Shengliang Guan 已提交
321
  pOperUser = mndAcquireUser(pMnode, pReq->user);
S
Shengliang Guan 已提交
322
  if (pOperUser == NULL) {
S
Shengliang Guan 已提交
323
    terrno = TSDB_CODE_MND_NO_USER_FROM_CONN;
S
Shengliang Guan 已提交
324
    goto CREATE_USER_OVER;
S
Shengliang Guan 已提交
325 326
  }

S
Shengliang Guan 已提交
327 328
  code = mndCreateUser(pMnode, pOperUser->acct, createReq.user, createReq.pass, pReq);
  if (code == 0) code = TSDB_CODE_MND_ACTION_IN_PROGRESS;
S
Shengliang Guan 已提交
329

S
Shengliang Guan 已提交
330 331 332
CREATE_USER_OVER:
  if (code != 0 && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) {
    mError("user:%s, failed to create since %s", createReq.user, terrstr());
S
Shengliang Guan 已提交
333 334
  }

S
Shengliang Guan 已提交
335 336 337 338
  mndReleaseUser(pMnode, pUser);
  mndReleaseUser(pMnode, pOperUser);

  return code;
S
Shengliang Guan 已提交
339 340
}

S
Shengliang Guan 已提交
341 342
static int32_t mndUpdateUser(SMnode *pMnode, SUserObj *pOld, SUserObj *pNew, SMnodeMsg *pReq) {
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, &pReq->rpcMsg);
S
Shengliang Guan 已提交
343
  if (pTrans == NULL) {
S
Shengliang Guan 已提交
344
    mError("user:%s, failed to update since %s", pOld->user, terrstr());
S
Shengliang Guan 已提交
345 346
    return -1;
  }
S
Shengliang Guan 已提交
347
  mDebug("trans:%d, used to update user:%s", pTrans->id, pOld->user);
S
Shengliang Guan 已提交
348

S
Shengliang Guan 已提交
349
  SSdbRaw *pRedoRaw = mndUserActionEncode(pNew);
S
Shengliang Guan 已提交
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366
  if (pRedoRaw == NULL || mndTransAppendRedolog(pTrans, pRedoRaw) != 0) {
    mError("trans:%d, failed to append redo log since %s", pTrans->id, terrstr());
    mndTransDrop(pTrans);
    return -1;
  }
  sdbSetRawStatus(pRedoRaw, SDB_STATUS_READY);

  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 已提交
367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388
static SHashObj *mndDupDbHash(SHashObj *pOld) {
  SHashObj *pNew = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, true);
  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);
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      taosHashCleanup(pNew);
      return NULL;
    }
    db = taosHashIterate(pOld, db);
  }

  return pNew;
}

S
Shengliang Guan 已提交
389
static int32_t mndProcessAlterUserReq(SMnodeMsg *pReq) {
S
Shengliang Guan 已提交
390 391 392 393 394 395 396
  SMnode       *pMnode = pReq->pMnode;
  int32_t       code = -1;
  SUserObj     *pUser = NULL;
  SUserObj     *pOperUser = NULL;
  SAlterUserReq alterReq = {0};

  if (tDeserializeSAlterUserReq(pReq->rpcMsg.pCont, &alterReq) == NULL) goto ALTER_USER_OVER;
S
Shengliang Guan 已提交
397

S
Shengliang Guan 已提交
398
  mDebug("user:%s, start to alter", alterReq.user);
S
Shengliang Guan 已提交
399

S
Shengliang Guan 已提交
400
  if (alterReq.user[0] == 0) {
S
Shengliang Guan 已提交
401
    terrno = TSDB_CODE_MND_INVALID_USER_FORMAT;
S
Shengliang Guan 已提交
402
    goto ALTER_USER_OVER;
S
Shengliang Guan 已提交
403 404
  }

S
Shengliang Guan 已提交
405
  if (alterReq.pass[0] == 0) {
S
Shengliang Guan 已提交
406
    terrno = TSDB_CODE_MND_INVALID_PASS_FORMAT;
S
Shengliang Guan 已提交
407
    goto ALTER_USER_OVER;
S
Shengliang Guan 已提交
408 409
  }

S
Shengliang Guan 已提交
410
  pUser = mndAcquireUser(pMnode, alterReq.user);
S
Shengliang Guan 已提交
411 412
  if (pUser == NULL) {
    terrno = TSDB_CODE_MND_USER_NOT_EXIST;
S
Shengliang Guan 已提交
413
    goto ALTER_USER_OVER;
S
Shengliang Guan 已提交
414 415
  }

S
Shengliang Guan 已提交
416
  pOperUser = mndAcquireUser(pMnode, pReq->user);
S
Shengliang Guan 已提交
417 418
  if (pOperUser == NULL) {
    terrno = TSDB_CODE_MND_NO_USER_FROM_CONN;
S
Shengliang Guan 已提交
419
    goto ALTER_USER_OVER;
S
Shengliang Guan 已提交
420 421 422 423
  }

  SUserObj newUser = {0};
  memcpy(&newUser, pUser, sizeof(SUserObj));
S
Shengliang Guan 已提交
424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476
  newUser.readDbs = mndDupDbHash(pUser->readDbs);
  newUser.writeDbs = mndDupDbHash(pUser->writeDbs);
  if (newUser.readDbs == NULL || newUser.writeDbs == NULL) {
    goto ALTER_USER_OVER;
  }

  int32_t len = strlen(alterReq.dbname) + 1;
  SDbObj *pDb = mndAcquireDb(pMnode, alterReq.dbname);
  mndReleaseDb(pMnode, pDb);

  if (alterReq.alterType == TSDB_ALTER_USER_PASSWD) {
    char pass[TSDB_PASSWORD_LEN + 1] = {0};
    taosEncryptPass_c((uint8_t *)alterReq.pass, strlen(alterReq.pass), pass);
    memcpy(pUser->pass, pass, TSDB_PASSWORD_LEN);
  } else if (alterReq.alterType == TSDB_ALTER_USER_SUPERUSER) { 
    newUser.superUser = alterReq.superUser;
  } else if (alterReq.alterType == TSDB_ALTER_USER_ADD_READ_DB) { 
    if (pDb == NULL) {
      terrno = TSDB_CODE_MND_DB_NOT_EXIST;
      goto ALTER_USER_OVER;
    }
    if (taosHashPut(newUser.readDbs, alterReq.dbname, len, alterReq.dbname, TSDB_DB_FNAME_LEN) != 0) {
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      goto ALTER_USER_OVER;
    }
  } else if (alterReq.alterType == TSDB_ALTER_USER_REMOVE_READ_DB) { 
    if (taosHashRemove(newUser.readDbs, alterReq.dbname, len) != 0) {
      terrno = TSDB_CODE_MND_DB_NOT_EXIST;
      goto ALTER_USER_OVER;
    }
  } else if (alterReq.alterType == TSDB_ALTER_USER_CLEAR_READ_DB) { 
    taosHashClear(newUser.readDbs);
  } else if (alterReq.alterType == TSDB_ALTER_USER_ADD_WRITE_DB) {
    if (pDb == NULL) {
      terrno = TSDB_CODE_MND_DB_NOT_EXIST;
      goto ALTER_USER_OVER;
    }
    if (taosHashPut(newUser.writeDbs, alterReq.dbname, len, alterReq.dbname, TSDB_DB_FNAME_LEN) != 0) {
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      goto ALTER_USER_OVER;
    }
  } else if (alterReq.alterType == TSDB_ALTER_USER_REMOVE_WRITE_DB) {
    if (taosHashRemove(newUser.writeDbs, alterReq.dbname, len) != 0) {
      terrno = TSDB_CODE_MND_DB_NOT_EXIST;
      goto ALTER_USER_OVER;
    }
  } else if (alterReq.alterType == TSDB_ALTER_USER_CLEAR_WRITE_DB) { 
    taosHashClear(newUser.writeDbs);
  } else {
    terrno = TSDB_CODE_MND_INVALID_ALTER_OPER;
    goto ALTER_USER_OVER;
  }

S
Shengliang Guan 已提交
477
  newUser.updateTime = taosGetTimestampMs();
S
Shengliang Guan 已提交
478

S
Shengliang Guan 已提交
479 480
  code = mndUpdateUser(pMnode, pUser, &newUser, pReq);
  if (code == 0) code = TSDB_CODE_MND_ACTION_IN_PROGRESS;
S
Shengliang Guan 已提交
481

S
Shengliang Guan 已提交
482 483 484 485
ALTER_USER_OVER:

  if (code != 0 && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) {
    mError("user:%s, failed to alter since %s", alterReq.user, terrstr());
S
Shengliang Guan 已提交
486 487
  }

S
Shengliang Guan 已提交
488 489 490 491
  mndReleaseUser(pMnode, pOperUser);
  mndReleaseUser(pMnode, pUser);

  return code;
S
Shengliang Guan 已提交
492 493
}

S
Shengliang Guan 已提交
494 495
static int32_t mndDropUser(SMnode *pMnode, SMnodeMsg *pReq, SUserObj *pUser) {
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, &pReq->rpcMsg);
S
Shengliang Guan 已提交
496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519
  if (pTrans == NULL) {
    mError("user:%s, failed to drop since %s", pUser->user, terrstr());
    return -1;
  }
  mDebug("trans:%d, used to drop user:%s", pTrans->id, pUser->user);

  SSdbRaw *pRedoRaw = mndUserActionEncode(pUser);
  if (pRedoRaw == NULL || mndTransAppendRedolog(pTrans, pRedoRaw) != 0) {
    mError("trans:%d, failed to append redo log since %s", pTrans->id, terrstr());
    mndTransDrop(pTrans);
    return -1;
  }
  sdbSetRawStatus(pRedoRaw, SDB_STATUS_DROPPED);

  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 已提交
520
static int32_t mndProcessDropUserReq(SMnodeMsg *pReq) {
S
Shengliang Guan 已提交
521 522 523 524 525 526 527
  SMnode      *pMnode = pReq->pMnode;
  int32_t      code = -1;
  SUserObj    *pUser = NULL;
  SUserObj    *pOperUser = NULL;
  SDropUserReq dropReq = {0};

  if (tDeserializeSDropUserReq(pReq->rpcMsg.pCont, &dropReq) == NULL) goto DROP_USER_OVER;
S
Shengliang Guan 已提交
528

S
Shengliang Guan 已提交
529
  mDebug("user:%s, start to drop", dropReq.user);
S
Shengliang Guan 已提交
530

S
Shengliang Guan 已提交
531
  if (dropReq.user[0] == 0) {
S
Shengliang Guan 已提交
532
    terrno = TSDB_CODE_MND_INVALID_USER_FORMAT;
S
Shengliang Guan 已提交
533
    goto DROP_USER_OVER;
S
Shengliang Guan 已提交
534 535
  }

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

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

S
Shengliang Guan 已提交
548 549
  code = mndDropUser(pMnode, pReq, pUser);
  if (code == 0) code = TSDB_CODE_MND_ACTION_IN_PROGRESS;
S
Shengliang Guan 已提交
550

S
Shengliang Guan 已提交
551 552 553
DROP_USER_OVER:
  if (code != 0 && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) {
    mError("user:%s, failed to drop since %s", dropReq.user, terrstr());
S
Shengliang Guan 已提交
554 555
  }

S
Shengliang Guan 已提交
556 557 558 559
  mndReleaseUser(pMnode, pOperUser);
  mndReleaseUser(pMnode, pUser);

  return code;
S
Shengliang Guan 已提交
560 561
}

S
Shengliang Guan 已提交
562
static int32_t mndGetUserMeta(SMnodeMsg *pReq, SShowObj *pShow, STableMetaRsp *pMeta) {
S
Shengliang Guan 已提交
563
  SMnode *pMnode = pReq->pMnode;
S
Shengliang Guan 已提交
564 565 566
  SSdb   *pSdb = pMnode->pSdb;

  int32_t  cols = 0;
S
Shengliang Guan 已提交
567
  SSchema *pSchema = pMeta->pSchema;
S
Shengliang Guan 已提交
568 569 570 571

  pShow->bytes[cols] = TSDB_USER_LEN + VARSTR_HEADER_SIZE;
  pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
  strcpy(pSchema[cols].name, "name");
H
Haojun Liao 已提交
572
  pSchema[cols].bytes = htonl(pShow->bytes[cols]);
S
Shengliang Guan 已提交
573 574 575 576 577
  cols++;

  pShow->bytes[cols] = 10 + VARSTR_HEADER_SIZE;
  pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
  strcpy(pSchema[cols].name, "privilege");
H
Haojun Liao 已提交
578
  pSchema[cols].bytes = htonl(pShow->bytes[cols]);
S
Shengliang Guan 已提交
579 580 581 582
  cols++;

  pShow->bytes[cols] = 8;
  pSchema[cols].type = TSDB_DATA_TYPE_TIMESTAMP;
583
  strcpy(pSchema[cols].name, "create_time");
H
Haojun Liao 已提交
584
  pSchema[cols].bytes = htonl(pShow->bytes[cols]);
S
Shengliang Guan 已提交
585 586 587 588 589
  cols++;

  pShow->bytes[cols] = TSDB_USER_LEN + VARSTR_HEADER_SIZE;
  pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
  strcpy(pSchema[cols].name, "account");
H
Haojun Liao 已提交
590
  pSchema[cols].bytes = htonl(pShow->bytes[cols]);
S
Shengliang Guan 已提交
591 592
  cols++;

593
  pMeta->numOfColumns = htonl(cols);
S
Shengliang Guan 已提交
594 595 596 597 598 599 600 601 602
  pShow->numOfColumns = cols;

  pShow->offset[0] = 0;
  for (int32_t i = 1; i < cols; ++i) {
    pShow->offset[i] = pShow->offset[i - 1] + pShow->bytes[i - 1];
  }

  pShow->numOfRows = sdbGetSize(pSdb, SDB_USER);
  pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1];
D
dapan1121 已提交
603
  strcpy(pMeta->tbName, mndShowStr(pShow->type));
S
Shengliang Guan 已提交
604

S
Shengliang Guan 已提交
605 606 607
  return 0;
}

S
Shengliang Guan 已提交
608 609
static int32_t mndRetrieveUsers(SMnodeMsg *pReq, SShowObj *pShow, char *data, int32_t rows) {
  SMnode   *pMnode = pReq->pMnode;
S
Shengliang Guan 已提交
610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626
  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;

    pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
    STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pUser->user, pShow->bytes[cols]);
    cols++;

    pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
627
    if (pUser->superUser) {
S
Shengliang Guan 已提交
628 629 630
      const char *src = "super";
      STR_WITH_SIZE_TO_VARSTR(pWrite, src, strlen(src));
    } else {
S
Shengliang Guan 已提交
631
      const char *src = "normal";
S
Shengliang Guan 已提交
632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647
      STR_WITH_SIZE_TO_VARSTR(pWrite, src, strlen(src));
    }
    cols++;

    pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
    *(int64_t *)pWrite = pUser->createdTime;
    cols++;

    pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
    STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pUser->acct, pShow->bytes[cols]);
    cols++;

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

S
Shengliang Guan 已提交
648
  mndVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow);
S
Shengliang Guan 已提交
649 650 651 652 653 654 655
  pShow->numOfReads += numOfRows;
  return numOfRows;
}

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