mndUser.c 23.4 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 "mndAuth.h"
S
Shengliang Guan 已提交
19
#include "mndDb.h"
S
Shengliang Guan 已提交
20
#include "mndShow.h"
S
Shengliang Guan 已提交
21
#include "mndTrans.h"
S
tbase64  
Shengliang Guan 已提交
22
#include "tbase64.h"
S
Shengliang Guan 已提交
23

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

S
Shengliang Guan 已提交
27 28 29 30 31
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 已提交
32
static int32_t  mndUserActionUpdate(SSdb *pSdb, SUserObj *pOld, SUserObj *pNew);
S
Shengliang Guan 已提交
33 34 35 36 37 38 39
static int32_t  mndCreateUser(SMnode *pMnode, char *acct, SCreateUserReq *pCreate, SNodeMsg *pReq);
static int32_t  mndProcessCreateUserReq(SNodeMsg *pReq);
static int32_t  mndProcessAlterUserReq(SNodeMsg *pReq);
static int32_t  mndProcessDropUserReq(SNodeMsg *pReq);
static int32_t  mndProcessGetUserAuthReq(SNodeMsg *pReq);
static int32_t  mndGetUserMeta(SNodeMsg *pReq, SShowObj *pShow, STableMetaRsp *pMeta);
static int32_t  mndRetrieveUsers(SNodeMsg *pReq, SShowObj *pShow, char *data, int32_t rows);
S
Shengliang Guan 已提交
40
static void     mndCancelGetNextUser(SMnode *pMnode, void *pIter);
S
Shengliang Guan 已提交
41 42 43 44 45 46 47 48 49 50 51

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 已提交
52 53 54
  mndSetMsgHandle(pMnode, TDMT_MND_CREATE_USER, mndProcessCreateUserReq);
  mndSetMsgHandle(pMnode, TDMT_MND_ALTER_USER, mndProcessAlterUserReq);
  mndSetMsgHandle(pMnode, TDMT_MND_DROP_USER, mndProcessDropUserReq);
S
Shengliang Guan 已提交
55
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_AUTH, mndProcessGetUserAuthReq);
S
Shengliang Guan 已提交
56

S
Shengliang Guan 已提交
57 58
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_USER, mndRetrieveUsers);
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_USER, mndCancelGetNextUser);
S
Shengliang Guan 已提交
59 60 61 62 63 64 65
  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 已提交
66
  taosEncryptPass_c((uint8_t *)pass, strlen(pass), userObj.pass);
S
Shengliang Guan 已提交
67 68 69 70 71 72
  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) {
73
    userObj.superUser = 1;
S
Shengliang Guan 已提交
74 75 76 77 78 79
  }

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

S
Shengliang Guan 已提交
80
  mDebug("user:%s, will be created while deploy sdb, raw:%p", userObj.user, pRaw);
S
Shengliang Guan 已提交
81 82 83 84 85 86 87 88 89 90 91
  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;
  }

  return 0;
}

S
Shengliang Guan 已提交
92
static SSdbRaw *mndUserActionEncode(SUserObj *pUser) {
93 94
  terrno = TSDB_CODE_OUT_OF_MEMORY;

S
Shengliang Guan 已提交
95 96 97 98 99
  int32_t numOfReadDbs = taosHashGetSize(pUser->readDbs);
  int32_t numOfWriteDbs = taosHashGetSize(pUser->writeDbs);
  int32_t size = sizeof(SUserObj) + TSDB_USER_RESERVE_SIZE + (numOfReadDbs + numOfWriteDbs) * TSDB_DB_FNAME_LEN;

  SSdbRaw *pRaw = sdbAllocRaw(SDB_USER, TSDB_USER_VER_NUMBER, 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
  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);
  }

124 125 126 127 128 129 130 131 132 133 134
  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 已提交
135

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

S
Shengliang Guan 已提交
140
static SSdbRow *mndUserActionDecode(SSdbRaw *pRaw) {
141 142
  terrno = TSDB_CODE_OUT_OF_MEMORY;

S
Shengliang Guan 已提交
143
  int8_t sver = 0;
144
  if (sdbGetRawSoftVer(pRaw, &sver) != 0) goto USER_DECODE_OVER;
S
Shengliang Guan 已提交
145

S
Shengliang Guan 已提交
146
  if (sver != TSDB_USER_VER_NUMBER) {
S
Shengliang Guan 已提交
147
    terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
148
    goto USER_DECODE_OVER;
S
Shengliang Guan 已提交
149
  }
S
Shengliang Guan 已提交
150

151 152 153
  SSdbRow *pRow = sdbAllocRow(sizeof(SUserObj));
  if (pRow == NULL) goto USER_DECODE_OVER;

S
Shengliang Guan 已提交
154
  SUserObj *pUser = sdbGetRowObj(pRow);
155
  if (pUser == NULL) goto USER_DECODE_OVER;
S
Shengliang Guan 已提交
156

157 158 159 160
  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 已提交
161
  int32_t dataPos = 0;
162 163 164 165 166 167
  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)
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187

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

188 189 190 191 192 193 194
  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());
195 196
    taosHashCleanup(pUser->readDbs);
    taosHashCleanup(pUser->writeDbs);
wafwerar's avatar
wafwerar 已提交
197
    taosMemoryFreeClear(pRow);
198 199
    return NULL;
  }
S
Shengliang Guan 已提交
200

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

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

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

S
Shengliang Guan 已提交
217 218
  return 0;
}
S
Shengliang Guan 已提交
219

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

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

  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 已提交
240 241 242
  return 0;
}

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

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

S
Shengliang Guan 已提交
257
static int32_t mndCreateUser(SMnode *pMnode, char *acct, SCreateUserReq *pCreate, SNodeMsg *pReq) {
S
Shengliang Guan 已提交
258
  SUserObj userObj = {0};
S
Shengliang Guan 已提交
259 260
  taosEncryptPass_c((uint8_t *)pCreate->pass, strlen(pCreate->pass), userObj.pass);
  tstrncpy(userObj.user, pCreate->user, TSDB_USER_LEN);
S
Shengliang Guan 已提交
261 262 263
  tstrncpy(userObj.acct, acct, TSDB_USER_LEN);
  userObj.createdTime = taosGetTimestampMs();
  userObj.updateTime = userObj.createdTime;
S
Shengliang Guan 已提交
264
  userObj.superUser = pCreate->superUser;
S
Shengliang Guan 已提交
265

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

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

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

S
Shengliang Guan 已提交
287
  mndTransDrop(pTrans);
S
Shengliang Guan 已提交
288
  return 0;
S
Shengliang Guan 已提交
289 290
}

S
Shengliang Guan 已提交
291 292
static int32_t mndProcessCreateUserReq(SNodeMsg *pReq) {
  SMnode        *pMnode = pReq->pNode;
S
Shengliang Guan 已提交
293 294 295 296 297
  int32_t        code = -1;
  SUserObj      *pUser = NULL;
  SUserObj      *pOperUser = NULL;
  SCreateUserReq createReq = {0};

S
Shengliang Guan 已提交
298 299 300 301
  if (tDeserializeSCreateUserReq(pReq->rpcMsg.pCont, pReq->rpcMsg.contLen, &createReq) != 0) {
    terrno = TSDB_CODE_INVALID_MSG;
    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 329 330 331
  if (mndCheckCreateUserAuth(pOperUser) != 0) {
    goto CREATE_USER_OVER;
  }

  code = mndCreateUser(pMnode, pOperUser->acct, &createReq, pReq);
S
Shengliang Guan 已提交
332
  if (code == 0) code = TSDB_CODE_MND_ACTION_IN_PROGRESS;
S
Shengliang Guan 已提交
333

S
Shengliang Guan 已提交
334 335 336
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 已提交
337 338
  }

S
Shengliang Guan 已提交
339 340 341 342
  mndReleaseUser(pMnode, pUser);
  mndReleaseUser(pMnode, pOperUser);

  return code;
S
Shengliang Guan 已提交
343 344
}

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

S
Shengliang Guan 已提交
353
  SSdbRaw *pRedoRaw = mndUserActionEncode(pNew);
S
Shengliang Guan 已提交
354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370
  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 已提交
371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392
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 已提交
393 394
static int32_t mndProcessAlterUserReq(SNodeMsg *pReq) {
  SMnode       *pMnode = pReq->pNode;
S
Shengliang Guan 已提交
395 396 397
  int32_t       code = -1;
  SUserObj     *pUser = NULL;
  SUserObj     *pOperUser = NULL;
S
Shengliang Guan 已提交
398
  SUserObj      newUser = {0};
S
Shengliang Guan 已提交
399 400
  SAlterUserReq alterReq = {0};

S
Shengliang Guan 已提交
401 402 403 404
  if (tDeserializeSAlterUserReq(pReq->rpcMsg.pCont, pReq->rpcMsg.contLen, &alterReq) != 0) {
    terrno = TSDB_CODE_INVALID_MSG;
    goto ALTER_USER_OVER;
  }
S
Shengliang Guan 已提交
405

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

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

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

S
Shengliang Guan 已提交
418
  pUser = mndAcquireUser(pMnode, alterReq.user);
S
Shengliang Guan 已提交
419 420
  if (pUser == NULL) {
    terrno = TSDB_CODE_MND_USER_NOT_EXIST;
S
Shengliang Guan 已提交
421
    goto ALTER_USER_OVER;
S
Shengliang Guan 已提交
422 423
  }

S
Shengliang Guan 已提交
424
  pOperUser = mndAcquireUser(pMnode, pReq->user);
S
Shengliang Guan 已提交
425 426
  if (pOperUser == NULL) {
    terrno = TSDB_CODE_MND_NO_USER_FROM_CONN;
S
Shengliang Guan 已提交
427
    goto ALTER_USER_OVER;
S
Shengliang Guan 已提交
428 429 430
  }

  memcpy(&newUser, pUser, sizeof(SUserObj));
S
Shengliang Guan 已提交
431 432 433 434 435 436 437 438 439 440 441 442 443 444
  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);
S
Shengliang Guan 已提交
445
  } else if (alterReq.alterType == TSDB_ALTER_USER_SUPERUSER) {
S
Shengliang Guan 已提交
446
    newUser.superUser = alterReq.superUser;
S
Shengliang Guan 已提交
447
  } else if (alterReq.alterType == TSDB_ALTER_USER_ADD_READ_DB) {
S
Shengliang Guan 已提交
448 449 450 451 452 453 454 455
    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;
    }
S
Shengliang Guan 已提交
456
  } else if (alterReq.alterType == TSDB_ALTER_USER_REMOVE_READ_DB) {
S
Shengliang Guan 已提交
457 458 459 460
    if (taosHashRemove(newUser.readDbs, alterReq.dbname, len) != 0) {
      terrno = TSDB_CODE_MND_DB_NOT_EXIST;
      goto ALTER_USER_OVER;
    }
S
Shengliang Guan 已提交
461
  } else if (alterReq.alterType == TSDB_ALTER_USER_CLEAR_READ_DB) {
S
Shengliang Guan 已提交
462 463 464 465 466 467 468 469 470 471 472 473 474 475 476
    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;
    }
S
Shengliang Guan 已提交
477
  } else if (alterReq.alterType == TSDB_ALTER_USER_CLEAR_WRITE_DB) {
S
Shengliang Guan 已提交
478 479 480 481 482 483
    taosHashClear(newUser.writeDbs);
  } else {
    terrno = TSDB_CODE_MND_INVALID_ALTER_OPER;
    goto ALTER_USER_OVER;
  }

S
Shengliang Guan 已提交
484
  newUser.updateTime = taosGetTimestampMs();
S
Shengliang Guan 已提交
485

S
Shengliang Guan 已提交
486 487 488 489
  if (mndCheckAlterUserAuth(pOperUser, pUser, pDb, &alterReq) != 0) {
    goto ALTER_USER_OVER;
  }

S
Shengliang Guan 已提交
490 491
  code = mndUpdateUser(pMnode, pUser, &newUser, pReq);
  if (code == 0) code = TSDB_CODE_MND_ACTION_IN_PROGRESS;
S
Shengliang Guan 已提交
492

S
Shengliang Guan 已提交
493 494 495
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 已提交
496 497
  }

S
Shengliang Guan 已提交
498 499
  mndReleaseUser(pMnode, pOperUser);
  mndReleaseUser(pMnode, pUser);
S
Shengliang Guan 已提交
500 501
  taosHashCleanup(newUser.writeDbs);
  taosHashCleanup(newUser.readDbs);
S
Shengliang Guan 已提交
502 503

  return code;
S
Shengliang Guan 已提交
504 505
}

S
Shengliang Guan 已提交
506
static int32_t mndDropUser(SMnode *pMnode, SNodeMsg *pReq, SUserObj *pUser) {
S
Shengliang Guan 已提交
507
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_TYPE_DROP_USER, &pReq->rpcMsg);
S
Shengliang Guan 已提交
508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531
  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 已提交
532 533
static int32_t mndProcessDropUserReq(SNodeMsg *pReq) {
  SMnode      *pMnode = pReq->pNode;
S
Shengliang Guan 已提交
534 535 536 537 538
  int32_t      code = -1;
  SUserObj    *pUser = NULL;
  SUserObj    *pOperUser = NULL;
  SDropUserReq dropReq = {0};

S
Shengliang Guan 已提交
539 540 541 542
  if (tDeserializeSDropUserReq(pReq->rpcMsg.pCont, pReq->rpcMsg.contLen, &dropReq) != 0) {
    terrno = TSDB_CODE_INVALID_MSG;
    goto DROP_USER_OVER;
  }
S
Shengliang Guan 已提交
543

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

S
Shengliang Guan 已提交
546
  if (dropReq.user[0] == 0) {
S
Shengliang Guan 已提交
547
    terrno = TSDB_CODE_MND_INVALID_USER_FORMAT;
S
Shengliang Guan 已提交
548
    goto DROP_USER_OVER;
S
Shengliang Guan 已提交
549 550
  }

S
Shengliang Guan 已提交
551
  pUser = mndAcquireUser(pMnode, dropReq.user);
S
Shengliang Guan 已提交
552 553
  if (pUser == NULL) {
    terrno = TSDB_CODE_MND_USER_NOT_EXIST;
S
Shengliang Guan 已提交
554
    goto DROP_USER_OVER;
S
Shengliang Guan 已提交
555 556
  }

S
Shengliang Guan 已提交
557
  pOperUser = mndAcquireUser(pMnode, pReq->user);
S
Shengliang Guan 已提交
558 559
  if (pOperUser == NULL) {
    terrno = TSDB_CODE_MND_NO_USER_FROM_CONN;
S
Shengliang Guan 已提交
560
    goto DROP_USER_OVER;
S
Shengliang Guan 已提交
561 562
  }

S
Shengliang Guan 已提交
563 564 565 566
  if (mndCheckDropUserAuth(pOperUser) != 0) {
    goto DROP_USER_OVER;
  }

S
Shengliang Guan 已提交
567 568
  code = mndDropUser(pMnode, pReq, pUser);
  if (code == 0) code = TSDB_CODE_MND_ACTION_IN_PROGRESS;
S
Shengliang Guan 已提交
569

S
Shengliang Guan 已提交
570 571 572
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 已提交
573 574
  }

S
Shengliang Guan 已提交
575 576 577 578
  mndReleaseUser(pMnode, pOperUser);
  mndReleaseUser(pMnode, pUser);

  return code;
S
Shengliang Guan 已提交
579 580
}

S
Shengliang Guan 已提交
581 582
static int32_t mndProcessGetUserAuthReq(SNodeMsg *pReq) {
  SMnode         *pMnode = pReq->pNode;
S
Shengliang Guan 已提交
583 584 585 586 587
  int32_t         code = -1;
  SUserObj       *pUser = NULL;
  SGetUserAuthReq authReq = {0};
  SGetUserAuthRsp authRsp = {0};

S
Shengliang Guan 已提交
588 589 590 591
  if (tDeserializeSGetUserAuthReq(pReq->rpcMsg.pCont, pReq->rpcMsg.contLen, &authReq) != 0) {
    terrno = TSDB_CODE_INVALID_MSG;
    goto GET_AUTH_OVER;
  }
S
Shengliang Guan 已提交
592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621

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

  pUser = mndAcquireUser(pMnode, authReq.user);
  if (pUser == NULL) {
    terrno = TSDB_CODE_MND_USER_NOT_EXIST;
    goto GET_AUTH_OVER;
  }

  memcpy(authRsp.user, pUser->user, TSDB_USER_LEN);
  authRsp.superAuth = pUser->superUser;
  authRsp.readDbs = mndDupDbHash(pUser->readDbs);
  authRsp.writeDbs = mndDupDbHash(pUser->writeDbs);

  SSdb *pSdb = pMnode->pSdb;
  void *pIter = NULL;
  while (1) {
    SDbObj *pDb = NULL;
    pIter = sdbFetch(pSdb, SDB_DB, pIter, (void **)&pDb);
    if (pIter == NULL) break;

    if (strcmp(pDb->createUser, pUser->user) == 0) {
      int32_t len = strlen(pDb->name) + 1;
      taosHashPut(authRsp.readDbs, pDb->name, len, pDb->name, len);
      taosHashPut(authRsp.writeDbs, pDb->name, len, pDb->name, len);
    }

    sdbRelease(pSdb, pDb);
  }

S
Shengliang Guan 已提交
622
  int32_t contLen = tSerializeSGetUserAuthRsp(NULL, 0, &authRsp);
S
Shengliang Guan 已提交
623 624 625 626 627 628
  void   *pRsp = rpcMallocCont(contLen);
  if (pRsp == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    goto GET_AUTH_OVER;
  }

S
Shengliang Guan 已提交
629
  tSerializeSGetUserAuthRsp(pRsp, contLen, &authRsp);
S
Shengliang Guan 已提交
630

S
Shengliang Guan 已提交
631 632
  pReq->pRsp = pRsp;
  pReq->rspLen = contLen;
S
Shengliang Guan 已提交
633 634 635 636 637 638 639 640 641 642
  code = 0;

GET_AUTH_OVER:
  mndReleaseUser(pMnode, pUser);
  taosHashCleanup(authRsp.readDbs);
  taosHashCleanup(authRsp.writeDbs);

  return code;
}

S
Shengliang Guan 已提交
643 644
static int32_t mndGetUserMeta(SNodeMsg *pReq, SShowObj *pShow, STableMetaRsp *pMeta) {
  SMnode *pMnode = pReq->pNode;
S
Shengliang Guan 已提交
645 646 647
  SSdb   *pSdb = pMnode->pSdb;

  int32_t  cols = 0;
S
Shengliang Guan 已提交
648
  SSchema *pSchema = pMeta->pSchemas;
S
Shengliang Guan 已提交
649 650 651 652

  pShow->bytes[cols] = TSDB_USER_LEN + VARSTR_HEADER_SIZE;
  pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
  strcpy(pSchema[cols].name, "name");
S
Shengliang Guan 已提交
653
  pSchema[cols].bytes = pShow->bytes[cols];
S
Shengliang Guan 已提交
654 655 656 657 658
  cols++;

  pShow->bytes[cols] = 10 + VARSTR_HEADER_SIZE;
  pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
  strcpy(pSchema[cols].name, "privilege");
S
Shengliang Guan 已提交
659
  pSchema[cols].bytes = pShow->bytes[cols];
S
Shengliang Guan 已提交
660 661 662 663
  cols++;

  pShow->bytes[cols] = 8;
  pSchema[cols].type = TSDB_DATA_TYPE_TIMESTAMP;
664
  strcpy(pSchema[cols].name, "create_time");
S
Shengliang Guan 已提交
665
  pSchema[cols].bytes = pShow->bytes[cols];
S
Shengliang Guan 已提交
666 667 668 669 670
  cols++;

  pShow->bytes[cols] = TSDB_USER_LEN + VARSTR_HEADER_SIZE;
  pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
  strcpy(pSchema[cols].name, "account");
S
Shengliang Guan 已提交
671
  pSchema[cols].bytes = pShow->bytes[cols];
S
Shengliang Guan 已提交
672 673
  cols++;

S
Shengliang Guan 已提交
674
  pMeta->numOfColumns = cols;
S
Shengliang Guan 已提交
675 676 677 678 679 680 681 682 683
  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 已提交
684
  strcpy(pMeta->tbName, mndShowStr(pShow->type));
S
Shengliang Guan 已提交
685

S
Shengliang Guan 已提交
686 687 688
  return 0;
}

S
Shengliang Guan 已提交
689 690
static int32_t mndRetrieveUsers(SNodeMsg *pReq, SShowObj *pShow, char *data, int32_t rows) {
  SMnode   *pMnode = pReq->pNode;
S
Shengliang Guan 已提交
691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707
  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;
708
    if (pUser->superUser) {
S
Shengliang Guan 已提交
709 710 711
      const char *src = "super";
      STR_WITH_SIZE_TO_VARSTR(pWrite, src, strlen(src));
    } else {
S
Shengliang Guan 已提交
712
      const char *src = "normal";
S
Shengliang Guan 已提交
713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728
      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 已提交
729
  mndVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow);
730
  pShow->numOfRows += numOfRows;
S
Shengliang Guan 已提交
731 732 733 734 735 736
  return numOfRows;
}

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