• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

taosdata / TDengine / #4936

23 Jan 2026 09:40AM UTC coverage: 66.746% (+0.04%) from 66.708%
#4936

push

travis-ci

web-flow
fix: case failuer caused by the modification of the error description (#34391)

204023 of 305671 relevant lines covered (66.75%)

124768167.97 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

69.19
/source/dnode/mnode/impl/src/mndUser.c
1
/*
2
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
3
 *
4
 * This program is free software: you can use, redistribute, and/or modify
5
 * it under the terms of the GNU Affero General Public License, version 3
6
 * or later ("AGPL"), as published by the Free Software Foundation.
7
 *
8
 * This program is distributed in the hope that it will be useful, but WITHOUT
9
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
 * FITNESS FOR A PARTICULAR PURPOSE.
11
 *
12
 * You should have received a copy of the GNU Affero General Public License
13
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14
 */
15

16
#define _DEFAULT_SOURCE
17
// clang-format off
18
#ifndef TD_ASTRA
19
#include <uv.h>
20
#endif
21
#include "crypt.h"
22
#include "mndRole.h"
23
#include "mndUser.h"
24
#include "audit.h"
25
#include "mndDb.h"
26
#include "mndPrivilege.h"
27
#include "mndShow.h"
28
#include "mndStb.h"
29
#include "mndTopic.h"
30
#include "mndTrans.h"
31
#include "mndToken.h"
32
#include "tbase64.h"
33
#include "totp.h"
34

35
// clang-format on
36

37
#define USER_VER_SUPPORT_WHITELIST           5
38
#define USER_VER_SUPPORT_WHITELIT_DUAL_STACK 7
39
#define USER_VER_SUPPORT_ADVANCED_SECURITY   8
40
#define USER_VER_NUMBER                      USER_VER_SUPPORT_ADVANCED_SECURITY 
41

42
#define USER_RESERVE_SIZE                    63
43

44
#define BIT_FLAG_MASK(n)              (1 << n)
45
#define BIT_FLAG_SET_MASK(val, mask)  ((val) |= (mask))
46
#define BIT_FLAG_TEST_MASK(val, mask) (((val) & (mask)) != 0)
47

48
#if 0
49
#define PRIVILEGE_TYPE_ALL       BIT_FLAG_MASK(0)
50
#define PRIVILEGE_TYPE_READ      BIT_FLAG_MASK(1)
51
#define PRIVILEGE_TYPE_WRITE     BIT_FLAG_MASK(2)
52
#define PRIVILEGE_TYPE_SUBSCRIBE BIT_FLAG_MASK(3)
53
#define PRIVILEGE_TYPE_ALTER     BIT_FLAG_MASK(4)
54
#endif
55

56
#define ALTER_USER_ADD_PRIVS(_type) ((_type) == TSDB_ALTER_USER_ADD_PRIVILEGES)
57
#define ALTER_USER_DEL_PRIVS(_type) ((_type) == TSDB_ALTER_USER_DEL_PRIVILEGES)
58

59
#if 0
60
#define ALTER_USER_ALL_PRIV(_priv)       (PRIV_HAS((_priv), PRIV_CM_ALL))
61
#define ALTER_USER_READ_PRIV(_priv)      (PRIV_HAS((_priv), PRIV_CM_READ) || PRIV_HAS((_priv), PRIV_CM_ALL))
62
#define ALTER_USER_WRITE_PRIV(_priv)     (PRIV_HAS((_priv), PRIV_CM_WRITE) || PRIV_HAS((_priv), PRIV_CM_ALL))
63
#define ALTER_USER_ALTER_PRIV(_priv)     (PRIV_HAS((_priv), PRIV_CM_ALTER) || PRIV_HAS((_priv), PRIV_CM_ALL))
64
#define ALTER_USER_SUBSCRIBE_PRIV(_priv) (PRIV_HAS((_priv), PRIV_TOPIC_SUBSCRIBE))
65

66
#define ALTER_USER_TARGET_DB(_tbname) (0 == (_tbname)[0])
67
#define ALTER_USER_TARGET_TB(_tbname) (0 != (_tbname)[0])
68

69
#define ALTER_USER_ADD_READ_DB_PRIV(_type, _priv, _tbname) \
70
  (ALTER_USER_ADD_PRIVS(_type) && ALTER_USER_READ_PRIV(_priv) && ALTER_USER_TARGET_DB(_tbname))
71
#define ALTER_USER_DEL_READ_DB_PRIV(_type, _priv, _tbname) \
72
  (ALTER_USER_DEL_PRIVS(_type) && ALTER_USER_READ_PRIV(_priv) && ALTER_USER_TARGET_DB(_tbname))
73
#define ALTER_USER_ADD_WRITE_DB_PRIV(_type, _priv, _tbname) \
74
  (ALTER_USER_ADD_PRIVS(_type) && ALTER_USER_WRITE_PRIV(_priv) && ALTER_USER_TARGET_DB(_tbname))
75
#define ALTER_USER_DEL_WRITE_DB_PRIV(_type, _priv, _tbname) \
76
  (ALTER_USER_DEL_PRIVS(_type) && ALTER_USER_WRITE_PRIV(_priv) && ALTER_USER_TARGET_DB(_tbname))
77
#define ALTER_USER_ADD_ALTER_DB_PRIV(_type, _priv, _tbname) \
78
  (ALTER_USER_ADD_PRIVS(_type) && ALTER_USER_ALTER_PRIV(_priv) && ALTER_USER_TARGET_DB(_tbname))
79
#define ALTER_USER_DEL_ALTER_DB_PRIV(_type, _priv, _tbname) \
80
  (ALTER_USER_DEL_PRIVS(_type) && ALTER_USER_ALTER_PRIV(_priv) && ALTER_USER_TARGET_DB(_tbname))
81
#define ALTER_USER_ADD_ALL_DB_PRIV(_type, _priv, _tbname) \
82
  (ALTER_USER_ADD_PRIVS(_type) && ALTER_USER_ALL_PRIV(_priv) && ALTER_USER_TARGET_DB(_tbname))
83
#define ALTER_USER_DEL_ALL_DB_PRIV(_type, _priv, _tbname) \
84
  (ALTER_USER_DEL_PRIVS(_type) && ALTER_USER_ALL_PRIV(_priv) && ALTER_USER_TARGET_DB(_tbname))
85

86
#define ALTER_USER_ADD_READ_TB_PRIV(_type, _priv, _tbname) \
87
  (ALTER_USER_ADD_PRIVS(_type) && ALTER_USER_READ_PRIV(_priv) && ALTER_USER_TARGET_TB(_tbname))
88
#define ALTER_USER_DEL_READ_TB_PRIV(_type, _priv, _tbname) \
89
  (ALTER_USER_DEL_PRIVS(_type) && ALTER_USER_READ_PRIV(_priv) && ALTER_USER_TARGET_TB(_tbname))
90
#define ALTER_USER_ADD_WRITE_TB_PRIV(_type, _priv, _tbname) \
91
  (ALTER_USER_ADD_PRIVS(_type) && ALTER_USER_WRITE_PRIV(_priv) && ALTER_USER_TARGET_TB(_tbname))
92
#define ALTER_USER_DEL_WRITE_TB_PRIV(_type, _priv, _tbname) \
93
  (ALTER_USER_DEL_PRIVS(_type) && ALTER_USER_WRITE_PRIV(_priv) && ALTER_USER_TARGET_TB(_tbname))
94
#define ALTER_USER_ADD_ALTER_TB_PRIV(_type, _priv, _tbname) \
95
  (ALTER_USER_ADD_PRIVS(_type) && ALTER_USER_ALTER_PRIV(_priv) && ALTER_USER_TARGET_TB(_tbname))
96
#define ALTER_USER_DEL_ALTER_TB_PRIV(_type, _priv, _tbname) \
97
  (ALTER_USER_DEL_PRIVS(_type) && ALTER_USER_ALTER_PRIV(_priv) && ALTER_USER_TARGET_TB(_tbname))
98
#define ALTER_USER_ADD_ALL_TB_PRIV(_type, _priv, _tbname) \
99
  (ALTER_USER_ADD_PRIVS(_type) && ALTER_USER_ALL_PRIV(_priv) && ALTER_USER_TARGET_TB(_tbname))
100
#define ALTER_USER_DEL_ALL_TB_PRIV(_type, _priv, _tbname) \
101
  (ALTER_USER_DEL_PRIVS(_type) && ALTER_USER_ALL_PRIV(_priv) && ALTER_USER_TARGET_TB(_tbname))
102

103
#define ALTER_USER_ADD_SUBSCRIBE_TOPIC_PRIV(_type, _priv) \
104
  (ALTER_USER_ADD_PRIVS(_type) && ALTER_USER_SUBSCRIBE_PRIV(_priv))
105
#define ALTER_USER_DEL_SUBSCRIBE_TOPIC_PRIV(_type, _priv) \
106
  (ALTER_USER_DEL_PRIVS(_type) && ALTER_USER_SUBSCRIBE_PRIV(_priv))
107
#endif
108
static void generateSalt(char *salt, size_t len);
109

110
static int32_t createDefaultIpWhiteList(SIpWhiteListDual **ppWhiteList);
111
static int32_t createIpWhiteList(void *buf, int32_t len, SIpWhiteListDual **ppWhiteList, bool supportNeg);
112

113
static bool isIpWhiteListEqual(SIpWhiteListDual *a, SIpWhiteListDual *b);
114
static bool isIpRangeEqual(SIpRange *a, SIpRange *b);
115

116
#define MND_MAX_USER_IP_RANGE   (TSDB_PRIVILEDGE_HOST_LEN / 24)
117
#define MND_MAX_USER_TIME_RANGE 2048
118

119
static int32_t  mndCreateDefaultUsers(SMnode *pMnode);
120
static SSdbRow *mndUserActionDecode(SSdbRaw *pRaw);
121
static int32_t  mndUserActionInsert(SSdb *pSdb, SUserObj *pUser);
122
static int32_t  mndUserActionDelete(SSdb *pSdb, SUserObj *pUser);
123
static int32_t  mndUserActionUpdate(SSdb *pSdb, SUserObj *pOld, SUserObj *pNew);
124
static int32_t  mndCreateUser(SMnode *pMnode, char *acct, SCreateUserReq *pCreate, SRpcMsg *pReq);
125
static int32_t  mndProcessCreateUserReq(SRpcMsg *pReq);
126
static int32_t  mndProcessAlterUserReq(SRpcMsg *pReq);
127
static int32_t  mndProcessDropUserReq(SRpcMsg *pReq);
128
static int32_t  mndProcessGetUserAuthReq(SRpcMsg *pReq);
129
static int32_t  mndRetrieveUsers(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
130
static int32_t  mndRetrieveUsersFull(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
131
static void     mndCancelGetNextUser(SMnode *pMnode, void *pIter);
132
static int32_t  mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
133
static void     mndCancelGetNextPrivileges(SMnode *pMnode, void *pIter);
134

135
static int32_t  mndProcessGetUserIpWhiteListReq(SRpcMsg *pReq);
136
static int32_t  mndProcessRetrieveIpWhiteListReq(SRpcMsg *pReq);
137
static int32_t  mndProcessGetUserDateTimeWhiteListReq(SRpcMsg *pReq);
138
static int32_t  mndProcessRetrieveDateTimeWhiteListReq(SRpcMsg *pReq);
139
static int32_t mndProcessCreateTotpSecretReq(SRpcMsg *pReq);
140
static int32_t mndProcessDropTotpSecretReq(SRpcMsg *pReq);
141

142
static int32_t createIpWhiteListFromOldVer(void *buf, int32_t len, SIpWhiteList **ppList);
143
static int32_t tDerializeIpWhileListFromOldVer(void *buf, int32_t len, SIpWhiteList *pList);
144

145

146
typedef struct {
147
  SIpWhiteListDual   *wlIp;
148
  SDateTimeWhiteList *wlTime;
149
  SLoginInfo          loginInfo;
150
} SCachedUserInfo;
151

152
typedef struct {
153
  SHashObj      *users;  // key: user, value: SCachedUserInfo*
154
  int64_t        verIp;
155
  int64_t        verTime;
156
  TdThreadRwlock rw;
157
} SUserCache;
158

159
static SUserCache userCache;
160

161

162
static int32_t userCacheInit() {
396,246✔
163
  _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
396,246✔
164

165
  SHashObj *users = taosHashInit(8, hashFn, 1, HASH_ENTRY_LOCK);
396,246✔
166
  if (users == NULL) {
396,246✔
167
    TAOS_RETURN(terrno);
×
168
  }
169

170
  userCache.users = users;
396,246✔
171
  userCache.verIp = 0;
396,246✔
172
  userCache.verTime = 0;
396,246✔
173

174
  (void)taosThreadRwlockInit(&userCache.rw, NULL);
396,246✔
175
  TAOS_RETURN(0);
396,246✔
176
}
177

178

179

180
static void userCacheCleanup() {
396,186✔
181
  if (userCache.users == NULL) {
396,186✔
182
    return;
×
183
  }
184

185
  void *pIter = taosHashIterate(userCache.users, NULL);
396,186✔
186
  while (pIter) {
807,831✔
187
    SCachedUserInfo *pInfo = *(SCachedUserInfo **)pIter;
411,645✔
188
    if (pInfo != NULL) {
411,645✔
189
      taosMemoryFree(pInfo->wlIp);
411,645✔
190
      taosMemoryFree(pInfo->wlTime);
411,645✔
191
      taosMemoryFree(pInfo);
411,645✔
192
    }
193
    pIter = taosHashIterate(userCache.users, pIter);
411,645✔
194
  }
195
  taosHashCleanup(userCache.users);
396,186✔
196

197
  (void)taosThreadRwlockDestroy(&userCache.rw);
396,186✔
198
}
199

200

201

202
static void userCacheRemoveUser(const char *user) {
20,378✔
203
  size_t userLen = strlen(user);
20,378✔
204

205
  (void)taosThreadRwlockWrlock(&userCache.rw);
20,378✔
206

207
  SCachedUserInfo **ppInfo = taosHashGet(userCache.users, user, userLen);
20,378✔
208
  if (ppInfo != NULL) {
20,378✔
209
    if (*ppInfo != NULL) {
20,378✔
210
      taosMemoryFree((*ppInfo)->wlIp);
20,378✔
211
      taosMemoryFree((*ppInfo)->wlTime);
20,378✔
212
      taosMemoryFree(*ppInfo);
20,378✔
213
    }
214
    if (taosHashRemove(userCache.users, user, userLen) != 0) {
20,378✔
215
      mDebug("failed to remove user %s from user cache", user);
×
216
    }
217
    userCache.verIp++;
20,378✔
218
    userCache.verTime++;
20,378✔
219
  }
220

221
  (void)taosThreadRwlockUnlock(&userCache.rw);
20,378✔
222
}
20,378✔
223

224

225

226
static void userCacheResetLoginInfo(const char *user) {
776✔
227
  size_t userLen = strlen(user);
776✔
228

229
  (void)taosThreadRwlockWrlock(&userCache.rw);
776✔
230

231
  SCachedUserInfo **ppInfo = taosHashGet(userCache.users, user, userLen);
776✔
232
  if (ppInfo != NULL && *ppInfo != NULL) {
776✔
233
    (*ppInfo)->loginInfo.lastLoginTime = taosGetTimestampSec();
776✔
234
    (*ppInfo)->loginInfo.failedLoginCount = 0;
776✔
235
    (*ppInfo)->loginInfo.lastFailedLoginTime = 0;
776✔
236
  }
237

238
  (void)taosThreadRwlockUnlock(&userCache.rw);
776✔
239
}
776✔
240

241

242

243
static SCachedUserInfo* getCachedUserInfo(const char* user) {
3,643,152✔
244
  size_t userLen = strlen(user);
3,643,152✔
245
  SCachedUserInfo **ppInfo = taosHashGet(userCache.users, user, userLen);
3,643,152✔
246
  if (ppInfo != NULL) {
3,643,152✔
247
    return *ppInfo;
3,211,129✔
248
  }
249

250
  SCachedUserInfo  *pInfo = (SCachedUserInfo *)taosMemoryCalloc(1, sizeof(SCachedUserInfo));
432,023✔
251
  if (pInfo == NULL) {
432,023✔
252
    return NULL;
×
253
  }
254

255
  if (taosHashPut(userCache.users, user, userLen, &pInfo, sizeof(pInfo)) != 0) {
432,023✔
256
    taosMemoryFree(pInfo);
×
257
    return NULL;
×
258
  }
259

260
  return pInfo;
432,023✔
261
}
262

263

264

265
void mndGetUserLoginInfo(const char *user, SLoginInfo *pLoginInfo) {
2,241,769✔
266
  size_t userLen = strlen(user);
2,241,769✔
267

268
  (void)taosThreadRwlockRdlock(&userCache.rw);
2,241,769✔
269

270
  SCachedUserInfo **ppInfo = taosHashGet(userCache.users, user, userLen);
2,242,137✔
271
  if (ppInfo != NULL && *ppInfo != NULL) {
2,242,140✔
272
    pLoginInfo->lastLoginTime = (*ppInfo)->loginInfo.lastLoginTime;
1,967,570✔
273
    pLoginInfo->failedLoginCount = (*ppInfo)->loginInfo.failedLoginCount;
1,967,570✔
274
    pLoginInfo->lastFailedLoginTime = (*ppInfo)->loginInfo.lastFailedLoginTime;
1,967,541✔
275
  } else {
276
    pLoginInfo->lastLoginTime = taosGetTimestampSec();
274,570✔
277
    pLoginInfo->failedLoginCount = 0;
274,570✔
278
    pLoginInfo->lastFailedLoginTime = 0;
274,570✔
279
  }
280

281
  (void)taosThreadRwlockUnlock(&userCache.rw);
2,241,769✔
282

283
  if (pLoginInfo->lastLoginTime == 0) {
2,241,969✔
284
    pLoginInfo->lastLoginTime = taosGetTimestampSec();
32,301✔
285
  }
286
}
2,242,133✔
287

288

289

290
void mndSetUserLoginInfo(const char *user, const SLoginInfo *pLoginInfo) {
2,237,307✔
291
  size_t userLen = strlen(user);
2,237,307✔
292

293
  (void)taosThreadRwlockWrlock(&userCache.rw);
2,237,307✔
294

295
  SCachedUserInfo  *pInfo = getCachedUserInfo(user);
2,237,307✔
296
  if (pInfo != NULL) {
2,237,307✔
297
    pInfo->loginInfo.lastLoginTime = pLoginInfo->lastLoginTime;
2,237,307✔
298
    pInfo->loginInfo.failedLoginCount = pLoginInfo->failedLoginCount;
2,237,307✔
299
    pInfo->loginInfo.lastFailedLoginTime = pLoginInfo->lastFailedLoginTime;
2,237,307✔
300
  }
301

302
  (void)taosThreadRwlockUnlock(&userCache.rw);
2,237,307✔
303
}
2,237,307✔
304

305

306

307
static bool isDateTimeWhiteListEqual(SDateTimeWhiteList *a, SDateTimeWhiteList *b) {
1,042,297✔
308
  if (a == NULL && b == NULL) {
1,042,297✔
309
    return true;
×
310
  }
311

312
  if (a == NULL || b == NULL) {
1,042,297✔
313
    return false;
56,739✔
314
  }
315

316
  if (a->num != b->num) {
985,558✔
317
    return false;
252✔
318
  }
319

320
  for (int i = 0; i < a->num; i++) {
985,684✔
321
    if (a->ranges[i].start != b->ranges[i].start ||
630✔
322
        a->ranges[i].duration != b->ranges[i].duration ||
378✔
323
        a->ranges[i].neg != b->ranges[i].neg ||
378✔
324
        a->ranges[i].absolute != b->ranges[i].absolute) {
378✔
325
      return false;
252✔
326
    }
327
  }
328

329
  return true;
985,054✔
330
}
331

332

333

334
static int32_t userCacheUpdateWhiteList(SMnode* pMnode, SUserObj* pUser) {
1,042,297✔
335
  int32_t code = 0, lino = 0;
1,042,297✔
336

337
  (void)taosThreadRwlockWrlock(&userCache.rw);
1,042,297✔
338

339
  SCachedUserInfo *pInfo = getCachedUserInfo(pUser->user);
1,042,297✔
340
  if (pInfo == NULL) {
1,042,297✔
341
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
342
  }
343

344
  if (!isIpWhiteListEqual(pInfo->wlIp, pUser->pIpWhiteListDual)) {
1,042,297✔
345
    SIpWhiteListDual *p = cloneIpWhiteList(pUser->pIpWhiteListDual);
57,150✔
346
    if (p == NULL) {
57,150✔
347
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
348
    }
349
    taosMemoryFree(pInfo->wlIp);
57,150✔
350
    pInfo->wlIp = p;
57,150✔
351
    userCache.verIp++;
57,150✔
352
  }
353

354
  if (!isDateTimeWhiteListEqual(pInfo->wlTime, pUser->pTimeWhiteList)) {
1,042,297✔
355
    SDateTimeWhiteList *p = cloneDateTimeWhiteList(pUser->pTimeWhiteList);
57,243✔
356
    if (p == NULL) {
57,243✔
357
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
358
    }
359
    taosMemoryFree(pInfo->wlTime);
57,243✔
360
    pInfo->wlTime = p;
57,243✔
361
    userCache.verTime++;
57,243✔
362
  }
363

364
_OVER:
1,042,297✔
365
  (void)taosThreadRwlockUnlock(&userCache.rw);
1,042,297✔
366
  if (code < 0) {
1,042,297✔
367
    mError("failed to update white list for user: %s at line %d since %s", pUser->user, lino, tstrerror(code));
×
368
  }
369
  TAOS_RETURN(code);
1,042,297✔
370
}
371

372

373

374
static int32_t userCacheRebuildIpWhiteList(SMnode *pMnode) {
480,572✔
375
  int32_t   code = 0, lino = 0;
480,572✔
376

377
  SSdb     *pSdb = pMnode->pSdb;
480,572✔
378
  void     *pIter = NULL;
480,572✔
379
  while (1) {
185,966✔
380
    SUserObj *pUser = NULL;
666,538✔
381
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
666,538✔
382
    if (pIter == NULL) {
666,538✔
383
      break;
480,572✔
384
    }
385

386
    SCachedUserInfo *pInfo = getCachedUserInfo(pUser->user);
185,966✔
387
    if (pInfo == NULL) {
185,966✔
388
      sdbRelease(pSdb, pUser);
×
389
      sdbCancelFetch(pSdb, pIter);
×
390
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
391
    }
392

393
    SIpWhiteListDual *wl = cloneIpWhiteList(pUser->pIpWhiteListDual);
185,966✔
394
    if (wl == NULL) {
185,966✔
395
      sdbRelease(pSdb, pUser);
×
396
      sdbCancelFetch(pSdb, pIter);
×
397
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
398
    }
399

400
    taosMemoryFree(pInfo->wlIp);
185,966✔
401
    pInfo->wlIp = wl;
185,966✔
402

403
    sdbRelease(pSdb, pUser);
185,966✔
404
  }
405

406
  userCache.verIp++;
480,572✔
407

408
_OVER:
480,572✔
409
  if (code < 0) {
480,572✔
410
    mError("failed to rebuild ip white list at line %d since %s", lino, tstrerror(code));
×
411
  }
412
  TAOS_RETURN(code);
480,572✔
413
}
414

415

416

417
int64_t mndGetIpWhiteListVersion(SMnode *pMnode) {
40,257,318✔
418
  int64_t ver = 0;
40,257,318✔
419
  int32_t code = 0;
40,257,318✔
420

421
  if (mndEnableIpWhiteList(pMnode) != 0 && tsEnableWhiteList) {
40,257,318✔
422
    (void)taosThreadRwlockWrlock(&userCache.rw);
3,874✔
423

424
    if (userCache.verIp == 0) {
3,874✔
425
      // get user and dnode ip white list
426
      if ((code = userCacheRebuildIpWhiteList(pMnode)) != 0) {
×
427
        (void)taosThreadRwlockUnlock(&userCache.rw);
×
428
        mError("%s failed to update ip white list since %s", __func__, tstrerror(code));
×
429
        return ver;
×
430
      }
431
      userCache.verIp = taosGetTimestampMs();
×
432
    }
433
    ver = userCache.verIp;
3,874✔
434

435
    (void)taosThreadRwlockUnlock(&userCache.rw);
3,874✔
436
  }
437

438
  mDebug("ip-white-list on mnode ver: %" PRId64, ver);
40,257,318✔
439
  return ver;
40,257,318✔
440
}
441

442

443

444
int32_t mndRefreshUserIpWhiteList(SMnode *pMnode) {
480,572✔
445
  int32_t code = 0;
480,572✔
446
  (void)taosThreadRwlockWrlock(&userCache.rw);
480,572✔
447

448
  if ((code = userCacheRebuildIpWhiteList(pMnode)) != 0) {
480,572✔
449
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
450
    TAOS_RETURN(code);
×
451
  }
452
  userCache.verIp = taosGetTimestampMs();
480,572✔
453
  (void)taosThreadRwlockUnlock(&userCache.rw);
480,572✔
454

455
  TAOS_RETURN(code);
480,572✔
456
}
457

458

459

460
static int32_t userCacheRebuildTimeWhiteList(SMnode *pMnode) {
472,188✔
461
  int32_t   code = 0, lino = 0;
472,188✔
462

463
  SSdb     *pSdb = pMnode->pSdb;
472,188✔
464
  void     *pIter = NULL;
472,188✔
465
  while (1) {
177,582✔
466
    SUserObj *pUser = NULL;
649,770✔
467
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
649,770✔
468
    if (pIter == NULL) {
649,770✔
469
      break;
472,188✔
470
    }
471

472
    SCachedUserInfo *pInfo = getCachedUserInfo(pUser->user);
177,582✔
473
    if (pInfo == NULL) {
177,582✔
474
      sdbRelease(pSdb, pUser);
×
475
      sdbCancelFetch(pSdb, pIter);
×
476
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
477
    }
478

479
    SDateTimeWhiteList *wl = cloneDateTimeWhiteList(pUser->pTimeWhiteList);
177,582✔
480
    if (wl == NULL) {
177,582✔
481
      sdbRelease(pSdb, pUser);
×
482
      sdbCancelFetch(pSdb, pIter);
×
483
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
484
    }
485

486
    taosMemoryFree(pInfo->wlTime);
177,582✔
487
    pInfo->wlTime = wl;
177,582✔
488

489
    sdbRelease(pSdb, pUser);
177,582✔
490
  }
491

492
  userCache.verTime++;
472,188✔
493

494
_OVER:
472,188✔
495
  if (code < 0) {
472,188✔
496
    mError("failed to rebuild time white list at line %d since %s", lino, tstrerror(code));
×
497
  }
498
  TAOS_RETURN(code);
472,188✔
499
}
500

501

502

503
int32_t mndRefreshUserDateTimeWhiteList(SMnode *pMnode) {
472,188✔
504
  int32_t code = 0;
472,188✔
505
  (void)taosThreadRwlockWrlock(&userCache.rw);
472,188✔
506

507
  if ((code = userCacheRebuildTimeWhiteList(pMnode)) != 0) {
472,188✔
508
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
509
    TAOS_RETURN(code);
×
510
  }
511
  userCache.verTime = taosGetTimestampMs();
472,188✔
512
  (void)taosThreadRwlockUnlock(&userCache.rw);
472,188✔
513

514
  TAOS_RETURN(code);
472,188✔
515
}
516

517

518

519
int64_t mndGetTimeWhiteListVersion(SMnode *pMnode) {
40,257,318✔
520
  int64_t ver = 0;
40,257,318✔
521
  int32_t code = 0;
40,257,318✔
522

523
  if (mndEnableTimeWhiteList(pMnode) != 0 && tsEnableWhiteList) {
40,257,318✔
524
    (void)taosThreadRwlockWrlock(&userCache.rw);
3,874✔
525

526
    if (userCache.verIp == 0) {
3,874✔
527
      // get user and dnode datetime white list
528
      if ((code = userCacheRebuildTimeWhiteList(pMnode)) != 0) {
×
529
        (void)taosThreadRwlockUnlock(&userCache.rw);
×
530
        mError("%s failed to update datetime white list since %s", __func__, tstrerror(code));
×
531
        return ver;
×
532
      }
533
      userCache.verTime = taosGetTimestampMs();
×
534
    }
535
    ver = userCache.verTime;
3,874✔
536

537
    (void)taosThreadRwlockUnlock(&userCache.rw);
3,874✔
538
  }
539

540
  mDebug("datetime-white-list on mnode ver: %" PRId64, ver);
40,257,318✔
541
  return ver;
40,257,318✔
542
}
543

544

545

546
int32_t mndInitUser(SMnode *pMnode) {
396,246✔
547
  TAOS_CHECK_RETURN(userCacheInit());
396,246✔
548

549
  SSdbTable table = {
396,246✔
550
      .sdbType = SDB_USER,
551
      .keyType = SDB_KEY_BINARY,
552
      .deployFp = (SdbDeployFp)mndCreateDefaultUsers,
553
      // .redeployFp = (SdbDeployFp)mndCreateDefaultUsers, // TODO: upgrade user table(uid should be created)
554
      .encodeFp = (SdbEncodeFp)mndUserActionEncode,
555
      .decodeFp = (SdbDecodeFp)mndUserActionDecode,
556
      .insertFp = (SdbInsertFp)mndUserActionInsert,
557
      .updateFp = (SdbUpdateFp)mndUserActionUpdate,
558
      .deleteFp = (SdbDeleteFp)mndUserActionDelete,
559
  };
560

561
  mndSetMsgHandle(pMnode, TDMT_MND_CREATE_USER, mndProcessCreateUserReq);
396,246✔
562
  mndSetMsgHandle(pMnode, TDMT_MND_ALTER_USER, mndProcessAlterUserReq);
396,246✔
563
  mndSetMsgHandle(pMnode, TDMT_MND_DROP_USER, mndProcessDropUserReq);
396,246✔
564
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_AUTH, mndProcessGetUserAuthReq);
396,246✔
565

566
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_IP_WHITELIST, mndProcessGetUserIpWhiteListReq);
396,246✔
567
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_IP_WHITELIST_DUAL, mndProcessGetUserIpWhiteListReq);
396,246✔
568
  mndSetMsgHandle(pMnode, TDMT_MND_RETRIEVE_IP_WHITELIST, mndProcessRetrieveIpWhiteListReq);
396,246✔
569
  mndSetMsgHandle(pMnode, TDMT_MND_RETRIEVE_IP_WHITELIST_DUAL, mndProcessRetrieveIpWhiteListReq);
396,246✔
570
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_DATETIME_WHITELIST, mndProcessGetUserDateTimeWhiteListReq);
396,246✔
571
  mndSetMsgHandle(pMnode, TDMT_MND_RETRIEVE_DATETIME_WHITELIST, mndProcessRetrieveDateTimeWhiteListReq);
396,246✔
572

573
  mndSetMsgHandle(pMnode, TDMT_MND_CREATE_TOTP_SECRET, mndProcessCreateTotpSecretReq);
396,246✔
574
  mndSetMsgHandle(pMnode, TDMT_MND_DROP_TOTP_SECRET, mndProcessDropTotpSecretReq);
396,246✔
575

576
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_USER, mndRetrieveUsers);
396,246✔
577
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_USER, mndCancelGetNextUser);
396,246✔
578
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_USER_FULL, mndRetrieveUsersFull);
396,246✔
579
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_USER_FULL, mndCancelGetNextUser);
396,246✔
580
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_PRIVILEGES, mndRetrievePrivileges);
396,246✔
581
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_PRIVILEGES, mndCancelGetNextPrivileges);
396,246✔
582
  return sdbSetTable(pMnode->pSdb, table);
396,246✔
583
}
584

585

586

587
void mndCleanupUser(SMnode *pMnode) {
396,186✔
588
  userCacheCleanup();
396,186✔
589
}
396,186✔
590

591

592

593
static bool isDefaultRange(SIpRange *pRange) {
×
594
  int32_t code = 0;
×
595
  int32_t lino = 0;
×
596

597
  SIpRange range4 = {0};
×
598
  SIpRange range6 = {0};
×
599

600
  code = createDefaultIp4Range(&range4);
×
601
  TSDB_CHECK_CODE(code, lino, _error);
×
602

603
  code = createDefaultIp6Range(&range6);
×
604
  TSDB_CHECK_CODE(code, lino, _error);
×
605

606
  if (isIpRangeEqual(pRange, &range4) || (isIpRangeEqual(pRange, &range6))) {
×
607
    return true;
×
608
  }
609
_error:
×
610
  return false;
×
611
};
612

613

614

615
static int32_t ipRangeListToStr(SIpRange *range, int32_t num, char *buf, int64_t bufLen) {
1,426,089✔
616
  int32_t len = 0;
1,426,089✔
617
  for (int i = 0; i < num; i++) {
4,310,031✔
618
    SIpRange *pRange = &range[i];
2,883,942✔
619
    SIpAddr   addr = {0};
2,883,942✔
620
    int32_t code = tIpUintToStr(pRange, &addr);
2,883,942✔
621
    if (code != 0) {
2,883,942✔
622
      mError("%s failed to convert ip range to str, code: %d", __func__, code);
×
623
    }
624

625
    len += tsnprintf(buf + len, bufLen - len, "%c%s/%d, ", pRange->neg ? '-' : '+', IP_ADDR_STR(&addr), addr.mask);
2,883,942✔
626
  }
627
  if (len > 0) {
1,426,089✔
628
    len -= 2;
1,426,089✔
629
    buf[len] = 0; // remove last ", "
1,426,089✔
630
  }
631
  return len;
1,426,089✔
632
}
633

634

635

636
static bool isIpRangeEqual(SIpRange *a, SIpRange *b) {
1,970,957✔
637
  if (a->type != b->type || a->neg != b->neg) {
1,970,957✔
638
    return false;
×
639
  }
640

641
  if (a->type == 0) {
1,970,957✔
642
    SIpV4Range *a4 = &a->ipV4;
985,810✔
643
    SIpV4Range *b4 = &b->ipV4;
985,810✔
644
    return (a4->ip == b4->ip && a4->mask == b4->mask);
985,810✔
645
  }
646
  
647
  SIpV6Range *a6 = &a->ipV6;
985,147✔
648
  SIpV6Range *b6 = &b->ipV6;
985,147✔
649
  return (a6->addr[0] == b6->addr[0] && a6->addr[1] == b6->addr[1] && a6->mask == b6->mask);
985,147✔
650
}
651

652

653

654
static bool isIpWhiteListEqual(SIpWhiteListDual *a, SIpWhiteListDual *b) {
1,042,297✔
655
  if (a == NULL && b == NULL) {
1,042,297✔
656
    return true;
×
657
  }
658
  
659
  if (a == NULL || b == NULL) {
1,042,297✔
660
    return false;
56,739✔
661
  }
662

663
  if (a->num != b->num) {
985,558✔
664
    return false;
411✔
665
  }
666
  for (int i = 0; i < a->num; i++) {
2,956,104✔
667
    if (!isIpRangeEqual(&a->pIpRanges[i], &b->pIpRanges[i])) {
1,970,957✔
668
      return false;
×
669
    }
670
  }
671
  return true;
985,147✔
672
}
673

674

675
static int32_t compareIpRange(const void *a, const void *b, const void* arg) {
4,943✔
676
  SIpRange *ra = (SIpRange *)a;
4,943✔
677
  SIpRange *rb = (SIpRange *)b;
4,943✔
678

679
  if (ra->neg != rb->neg) {
4,943✔
680
    return (ra->neg) ? -1 : 1;
630✔
681
  }
682

683
  if (ra->type != rb->type) {
4,313✔
684
    return (ra->type == 0) ? -1 : 1;
1,556✔
685
  }
686

687
  if (ra->type == 0) {
2,757✔
688
    if (ra->ipV4.ip != rb->ipV4.ip) {
2,757✔
689
      return (ra->ipV4.ip < rb->ipV4.ip) ? -1 : 1;
2,439✔
690
    }
691
    return (ra->ipV4.mask < rb->ipV4.mask) ? -1 : 1;
318✔
692
  }
693

694
  if (ra->ipV6.addr[0] != rb->ipV6.addr[0]) {
×
695
    return (ra->ipV6.addr[0] < rb->ipV6.addr[0]) ? -1 : 1;
×
696
  }
697
  if (ra->ipV6.addr[1] != rb->ipV6.addr[1]) {
×
698
    return (ra->ipV6.addr[1] < rb->ipV6.addr[1]) ? -1 : 1;
×
699
  }
700
  return (ra->ipV6.mask < rb->ipV6.mask) ? -1 : 1;
×
701
}
702

703
static void sortIpWhiteList(SIpWhiteListDual *pList) {
1,934✔
704
  (void)taosqsort(pList->pIpRanges, pList->num, sizeof(SIpRange), NULL, compareIpRange);
1,934✔
705
}
1,934✔
706

707

708

709
static int32_t convertIpWhiteListToStr(SUserObj *pUser, char **buf) {
1,426,089✔
710
  SIpWhiteListDual *pList = pUser->pIpWhiteListDual;
1,426,089✔
711

712
  int64_t bufLen = pList->num * 128 + 8;
1,426,089✔
713
  *buf = taosMemoryCalloc(1, bufLen);
1,426,089✔
714
  if (*buf == NULL) {
1,426,089✔
715
    return 0;
×
716
  }
717

718
  if (pList->num == 0) {
1,426,089✔
719
    return tsnprintf(*buf, bufLen, "+ALL");
×
720
  }
721

722
  int32_t len = ipRangeListToStr(pList->pIpRanges, pList->num, *buf, bufLen - 2);
1,426,089✔
723
  if (len == 0) {
1,426,089✔
724
    taosMemoryFreeClear(*buf);
×
725
    return 0;
×
726
  }
727
  return len;
1,426,089✔
728
}
729

730

731

732
static int32_t tSerializeIpWhiteList(void *buf, int32_t len, SIpWhiteListDual *pList, uint32_t *pLen) {
2,254,966✔
733
  int32_t  code = 0;
2,254,966✔
734
  int32_t  lino = 0;
2,254,966✔
735
  int32_t  tlen = 0;
2,254,966✔
736
  SEncoder encoder = {0};
2,254,966✔
737
  tEncoderInit(&encoder, buf, len);
2,254,966✔
738

739
  TAOS_CHECK_GOTO(tStartEncode(&encoder), &lino, _OVER);
2,254,966✔
740
  TAOS_CHECK_GOTO(tEncodeI32(&encoder, pList->num), &lino, _OVER);
4,509,932✔
741

742
  for (int i = 0; i < pList->num; i++) {
6,768,915✔
743
    SIpRange *pRange = &(pList->pIpRanges[i]);
4,513,949✔
744
    TAOS_CHECK_GOTO(tSerializeIpRange(&encoder, pRange), &lino, _OVER);
4,513,949✔
745
  }
746

747
  tEndEncode(&encoder);
2,254,966✔
748

749
  tlen = encoder.pos;
2,254,966✔
750
_OVER:
2,254,966✔
751
  tEncoderClear(&encoder);
2,254,966✔
752
  if (code < 0) {
2,254,966✔
753
    mError("failed to serialize ip white list at line %d since %s", lino, tstrerror(code));
×
754
  }
755
  if (pLen) *pLen = tlen;
2,254,966✔
756
  TAOS_RETURN(code);
2,254,966✔
757
}
758

759
static int32_t tDerializeIpWhiteList(void *buf, int32_t len, SIpWhiteListDual *pList, bool supportNeg) {
1,505,423✔
760
  int32_t  code = 0;
1,505,423✔
761
  int32_t  lino = 0;
1,505,423✔
762
  SDecoder decoder = {0};
1,505,423✔
763
  tDecoderInit(&decoder, buf, len);
1,505,423✔
764

765
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
1,505,423✔
766
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &pList->num), &lino, _OVER);
3,010,846✔
767

768
  for (int i = 0; i < pList->num; i++) {
4,518,642✔
769
    SIpRange *pRange = &(pList->pIpRanges[i]);
3,013,219✔
770
    TAOS_CHECK_GOTO(tDeserializeIpRange(&decoder, pRange, supportNeg), &lino, _OVER);
3,013,219✔
771
  }
772

773
_OVER:
1,505,423✔
774
  tEndDecode(&decoder);
1,505,423✔
775
  tDecoderClear(&decoder);
1,505,423✔
776
  if (code < 0) {
1,505,423✔
777
    mError("failed to deserialize ip white list at line %d since %s", lino, tstrerror(code));
×
778
  }
779
  TAOS_RETURN(code);
1,505,423✔
780
}
781

782
static int32_t tDerializeIpWhileListFromOldVer(void *buf, int32_t len, SIpWhiteList *pList) {
×
783
  int32_t  code = 0;
×
784
  int32_t  lino = 0;
×
785
  SDecoder decoder = {0};
×
786
  tDecoderInit(&decoder, buf, len);
×
787

788
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
×
789
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &pList->num), &lino, _OVER);
×
790

791
  for (int i = 0; i < pList->num; i++) {
×
792
    SIpV4Range *pIp4 = &(pList->pIpRange[i]);
×
793
    TAOS_CHECK_GOTO(tDecodeU32(&decoder, &pIp4->ip), &lino, _OVER);
×
794
    TAOS_CHECK_GOTO(tDecodeU32(&decoder, &pIp4->mask), &lino, _OVER);
×
795
  }
796

797
_OVER:
×
798
  tEndDecode(&decoder);
×
799
  tDecoderClear(&decoder);
×
800
  if (code < 0) {
×
801
    mError("failed to deserialize ip white list at line %d since %s", lino, tstrerror(code));
×
802
  }
803
  TAOS_RETURN(code);
×
804
}
805

806
static int32_t createIpWhiteList(void *buf, int32_t len, SIpWhiteListDual **ppList, bool supportNeg) {
1,505,423✔
807
  int32_t           code = 0;
1,505,423✔
808
  int32_t           lino = 0;
1,505,423✔
809
  int32_t           num = 0;
1,505,423✔
810
  SIpWhiteListDual *p = NULL;
1,505,423✔
811
  SDecoder          decoder = {0};
1,505,423✔
812
  tDecoderInit(&decoder, buf, len);
1,505,423✔
813

814
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
1,505,423✔
815
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &num), &lino, _OVER);
1,505,423✔
816

817
  p = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + num * sizeof(SIpRange));
1,505,423✔
818
  if (p == NULL) {
1,505,423✔
819
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
820
  }
821
  TAOS_CHECK_GOTO(tDerializeIpWhiteList(buf, len, p, supportNeg), &lino, _OVER);
1,505,423✔
822

823
_OVER:
1,505,423✔
824
  tEndDecode(&decoder);
1,505,423✔
825
  tDecoderClear(&decoder);
1,505,423✔
826
  if (code < 0) {
1,505,423✔
827
    taosMemoryFreeClear(p);
×
828
    mError("failed to create ip white list at line %d since %s", lino, tstrerror(code));
×
829
  }
830
  *ppList = p;
1,505,423✔
831
  TAOS_RETURN(code);
1,505,423✔
832
}
833

834
static int32_t createIpWhiteListFromOldVer(void *buf, int32_t len, SIpWhiteList **ppList) {
×
835
  int32_t       code = 0;
×
836
  int32_t       lino = 0;
×
837
  int32_t       num = 0;
×
838
  SIpWhiteList *p = NULL;
×
839
  SDecoder      decoder = {0};
×
840
  tDecoderInit(&decoder, buf, len);
×
841

842
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
×
843
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &num), &lino, _OVER);
×
844

845
  p = taosMemoryCalloc(1, sizeof(SIpWhiteList) + num * sizeof(SIpV4Range));
×
846
  if (p == NULL) {
×
847
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
848
  }
849
  TAOS_CHECK_GOTO(tDerializeIpWhileListFromOldVer(buf, len, p), &lino, _OVER);
×
850

851
_OVER:
×
852
  tEndDecode(&decoder);
×
853
  tDecoderClear(&decoder);
×
854
  if (code < 0) {
×
855
    taosMemoryFreeClear(p);
×
856
    mError("failed to create ip white list at line %d since %s", lino, tstrerror(code));
×
857
  }
858
  *ppList = p;
×
859
  TAOS_RETURN(code);
×
860
}
861

862
static int32_t createDefaultIpWhiteList(SIpWhiteListDual **ppWhiteList) {
337,861✔
863
  int32_t code = 0;
337,861✔
864
  int32_t lino = 0;
337,861✔
865
  *ppWhiteList = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + sizeof(SIpRange) * 2);
337,861✔
866
  if (*ppWhiteList == NULL) {
337,861✔
867
    TAOS_RETURN(terrno);
×
868
  }
869
  (*ppWhiteList)->num = 2;
337,861✔
870

871
  SIpRange v4 = {0};
337,861✔
872
  SIpRange v6 = {0};
337,861✔
873

874
#ifndef TD_ASTRA
875
  code = createDefaultIp4Range(&v4);
337,861✔
876
  TSDB_CHECK_CODE(code, lino, _error);
337,861✔
877

878
  code = createDefaultIp6Range(&v6);
337,861✔
879
  TSDB_CHECK_CODE(code, lino, _error);
337,861✔
880

881
#endif
882

883
_error:
337,861✔
884
  if (code != 0) {
337,861✔
885
    taosMemoryFree(*ppWhiteList);
×
886
    *ppWhiteList = NULL;
×
887
    mError("failed to create default ip white list at line %d since %s", __LINE__, tstrerror(code));
×
888
  } else {
889
    memcpy(&(*ppWhiteList)->pIpRanges[0], &v4, sizeof(SIpRange));
337,861✔
890
    memcpy(&(*ppWhiteList)->pIpRanges[1], &v6, sizeof(SIpRange));
337,861✔
891
  }
892
  return 0;
337,861✔
893
}
894

895

896
static const char* weekdays[] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};
897

898
static int32_t convertTimeRangesToStr(SUserObj *pUser, char **buf) {
1,426,089✔
899
  int32_t bufLen = pUser->pTimeWhiteList->num * 32 + 8;
1,426,089✔
900
  *buf = taosMemoryCalloc(1, bufLen);
1,426,089✔
901
  if (*buf == NULL) {
1,426,089✔
902
    return 0;
×
903
  }
904

905
  int32_t pos = 0;
1,426,089✔
906
  if (pUser->pTimeWhiteList->num == 0) {
1,426,089✔
907
    pos += tsnprintf(*buf + pos, bufLen - pos, "+ALL");
1,357,545✔
908
    return pos;
1,357,545✔
909
  }
910

911
  for (int32_t i = 0; i < pUser->pTimeWhiteList->num; i++) {
156,240✔
912
    SDateTimeWhiteListItem *range = &pUser->pTimeWhiteList->ranges[i];
87,696✔
913
    int duration = range->duration / 60;
87,696✔
914

915
    if (range->absolute) {
87,696✔
916
      struct STm tm;
51,786✔
917
      (void)taosTs2Tm(range->start, TSDB_TIME_PRECISION_SECONDS, &tm, NULL);
51,786✔
918
      pos += tsnprintf(*buf + pos, bufLen - pos, "%c%04d-%02d-%02d %02d:%02d %dm, ", range->neg ? '-' : '+', tm.tm.tm_year + 1900, tm.tm.tm_mon + 1, tm.tm.tm_mday, tm.tm.tm_hour, tm.tm.tm_min, duration);
51,786✔
919
    } else {
920
      int day = range->start / 86400;
35,910✔
921
      int hour = (range->start % 86400) / 3600;
35,910✔
922
      int minute = (range->start % 3600) / 60;
35,910✔
923
      pos += tsnprintf(*buf + pos, bufLen - pos, "%c%s %02d:%02d %dm, ", range->neg ? '-' : '+', weekdays[day], hour, minute, duration);
35,910✔
924
    }
925
  }
926

927
  if (pos > 0) {
68,544✔
928
    pos -= 2;
68,544✔
929
    (*buf)[pos] = 0; // remove last ", "
68,544✔
930
  }
931

932
  return pos;
68,544✔
933
}
934

935

936
static int32_t compareDateTimeInterval(const void *a, const void *b, const void* arg) {
756✔
937
  SDateTimeWhiteListItem *pA = (SDateTimeWhiteListItem *)a;
756✔
938
  SDateTimeWhiteListItem *pB = (SDateTimeWhiteListItem *)b;
756✔
939

940
  if (pA->neg != pB->neg) {
756✔
941
    return pA->neg ? -1 : 1;
504✔
942
  }
943

944
  if (pA->absolute != pB->absolute) {
252✔
945
    return pA->absolute ? 1 : -1;
252✔
946
  }
947

948
  if (pA->start != pB->start) {
×
949
    return (pA->start < pB->start) ? -1 : 1;
×
950
  }
951

952
  if (pA->duration != pB->duration) {
×
953
    return (pA->duration < pB->duration) ? -1 : 1;
×
954
  }
955

956
  return 0;
×
957
}
958

959
static void sortTimeWhiteList(SDateTimeWhiteList *pList) {
2,142✔
960
  (void)taosqsort(pList->ranges, pList->num, sizeof(SDateTimeWhiteListItem), NULL, compareDateTimeInterval);
2,142✔
961
}
2,142✔
962

963

964

965

966
static void dropOldPasswords(SUserObj *pUser) {
4,781,429✔
967
  if (pUser->numOfPasswords <= pUser->passwordReuseMax) {
4,781,429✔
968
    return;
4,770,574✔
969
  }
970

971
  int32_t reuseMax = pUser->passwordReuseMax;
10,855✔
972
  if (reuseMax == 0) {
10,855✔
973
    reuseMax = 1; // keep at least one password
8,471✔
974
  }
975

976
  int32_t now = taosGetTimestampSec();
10,855✔
977
  int32_t index = reuseMax;
10,855✔
978
  while(index < pUser->numOfPasswords) {
16,431✔
979
    // the set time of the n-th password is the expire time of the n+1-th password
980
    int32_t expireTime = pUser->passwords[index - 1].setTime;
5,828✔
981
    if (now - expireTime >= pUser->passwordReuseTime) {
5,828✔
982
      break;
252✔
983
    }
984
    index++;
5,576✔
985
  }
986

987
  if (index == pUser->numOfPasswords) {
10,855✔
988
    return;
10,603✔
989
  }
990
  pUser->numOfPasswords = index;
252✔
991
  // this is a shrink operation, no need to check return value
992
  pUser->passwords = taosMemoryRealloc(pUser->passwords, sizeof(SUserPassword) * pUser->numOfPasswords);
252✔
993
}
994

995

996

997
static int32_t mndCreateDefaultUser(SMnode *pMnode, char *acct, char *user, char *pass) {
282,651✔
998
  int32_t  code = 0;
282,651✔
999
  int32_t  lino = 0;
282,651✔
1000
  SUserObj userObj = {0};
282,651✔
1001

1002
  userObj.passwords = taosMemCalloc(1, sizeof(SUserPassword));
282,651✔
1003
  if (userObj.passwords == NULL) {
282,651✔
1004
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _ERROR);
×
1005
  }
1006
  taosEncryptPass_c((uint8_t *)pass, strlen(pass), userObj.passwords[0].pass);
282,651✔
1007
  userObj.passwords[0].pass[sizeof(userObj.passwords[0].pass) - 1] = 0;
282,651✔
1008
  if (tsiEncryptPassAlgorithm == DND_CA_SM4 && strlen(tsDataKey) > 0) {
282,651✔
1009
    generateSalt(userObj.salt, sizeof(userObj.salt));
×
1010
    TAOS_CHECK_GOTO(mndEncryptPass(userObj.passwords[0].pass, userObj.salt, &userObj.passEncryptAlgorithm), &lino, _ERROR);
×
1011
  }
1012

1013
  userObj.passwords[0].setTime = taosGetTimestampSec();
282,651✔
1014
  userObj.numOfPasswords = 1;
282,651✔
1015

1016
  tstrncpy(userObj.user, user, TSDB_USER_LEN);
282,651✔
1017
  tstrncpy(userObj.acct, acct, TSDB_USER_LEN);
282,651✔
1018
  userObj.createdTime = taosGetTimestampMs();
282,651✔
1019
  userObj.updateTime = userObj.createdTime;
282,651✔
1020
  userObj.uid = mndGenerateUid(userObj.user, strlen(userObj.user));
282,651✔
1021
  userObj.sysInfo = 1;
282,651✔
1022
  userObj.enable = 1;
282,651✔
1023

1024
#ifdef TD_ENTERPRISE
1025

1026
  // 1: force user to change password
1027
  // 2: allow but not force user to change password
1028
  userObj.changePass = tsAllowDefaultPassword ? 2 : 1;
282,651✔
1029

1030
  userObj.ipWhiteListVer = taosGetTimestampMs();
282,651✔
1031
  userObj.timeWhiteListVer = userObj.ipWhiteListVer;
282,651✔
1032
  userObj.connectTime = TSDB_USER_CONNECT_TIME_DEFAULT;
282,651✔
1033
  userObj.connectIdleTime = TSDB_USER_CONNECT_IDLE_TIME_DEFAULT;
282,651✔
1034
  userObj.callPerSession = TSDB_USER_CALL_PER_SESSION_DEFAULT;
282,651✔
1035
  userObj.vnodePerCall = TSDB_USER_VNODE_PER_CALL_DEFAULT;
282,651✔
1036
  userObj.passwordReuseTime = TSDB_USER_PASSWORD_REUSE_TIME_DEFAULT;
282,651✔
1037
  userObj.passwordReuseMax = TSDB_USER_PASSWORD_REUSE_MAX_DEFAULT;
282,651✔
1038
  userObj.passwordLockTime = TSDB_USER_PASSWORD_LOCK_TIME_DEFAULT;
282,651✔
1039
  userObj.sessionPerUser = TSDB_USER_SESSION_PER_USER_DEFAULT;
282,651✔
1040
  userObj.failedLoginAttempts = TSDB_USER_FAILED_LOGIN_ATTEMPTS_DEFAULT;
282,651✔
1041
  userObj.passwordLifeTime = TSDB_USER_PASSWORD_LIFE_TIME_DEFAULT;
282,651✔
1042
  userObj.passwordGraceTime = TSDB_USER_PASSWORD_GRACE_TIME_DEFAULT;
282,651✔
1043
  userObj.inactiveAccountTime = TSDB_USER_INACTIVE_ACCOUNT_TIME_DEFAULT;
282,651✔
1044
  userObj.allowTokenNum = TSDB_USER_ALLOW_TOKEN_NUM_DEFAULT;
282,651✔
1045
  userObj.tokenNum = 0;
282,651✔
1046

1047
#else // TD_ENTERPRISE
1048

1049
  userObj.ipWhiteListVer = 0;
1050
  userObj.timeWhiteListVer = 0;
1051
  userObj.changePass = 2; // 2: allow but not force user to change password
1052
  userObj.connectTime = -1;
1053
  userObj.connectIdleTime = -1;
1054
  userObj.callPerSession = -1;
1055
  userObj.vnodePerCall = -1;
1056
  userObj.passwordReuseTime = 0;
1057
  userObj.passwordReuseMax = 0;
1058
  userObj.passwordLockTime = -1;
1059
  userObj.sessionPerUser = -1;
1060
  userObj.failedLoginAttempts = -1;
1061
  userObj.passwordLifeTime = -1;
1062
  userObj.passwordGraceTime = -1;
1063
  userObj.inactiveAccountTime = -1;
1064
  userObj.allowTokenNum = -1;
1065
  userObj.tokenNum = 0;
1066

1067
#endif // TD_ENTERPRISE
1068

1069
  userObj.pTimeWhiteList = taosMemoryCalloc(1, sizeof(SDateTimeWhiteList));
282,651✔
1070
  if (userObj.pTimeWhiteList == NULL) {
282,651✔
1071
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _ERROR);
×
1072
  }
1073
  
1074
  TAOS_CHECK_GOTO(createDefaultIpWhiteList(&userObj.pIpWhiteListDual), &lino, _ERROR);
282,651✔
1075
  // if this is the root user, change the value of some fields to allow the user login without restriction
1076
  if (strcmp(user, TSDB_DEFAULT_USER) == 0) {
282,651✔
1077
    userObj.superUser = 1;
282,651✔
1078
    userObj.createdb = 1;
282,651✔
1079
    userObj.sessionPerUser = -1;
282,651✔
1080
    userObj.callPerSession = -1;
282,651✔
1081
    userObj.vnodePerCall = -1;
282,651✔
1082
    userObj.failedLoginAttempts = -1;
282,651✔
1083
    userObj.passwordGraceTime = -1;
282,651✔
1084
    userObj.inactiveAccountTime = -1;
282,651✔
1085
    userObj.allowTokenNum = -1;
282,651✔
1086
  }
1087

1088
  userObj.roles = taosHashInit(1, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
282,651✔
1089
  if (userObj.roles == NULL) {
282,651✔
1090
    TAOS_CHECK_GOTO(terrno, &lino, _ERROR);
×
1091
  }
1092

1093
  if ((code = taosHashPut(userObj.roles, TSDB_ROLE_SYSDBA, strlen(TSDB_ROLE_SYSDBA) + 1, NULL, 0)) ||
565,302✔
1094
      (code = taosHashPut(userObj.roles, TSDB_ROLE_SYSSEC, strlen(TSDB_ROLE_SYSSEC) + 1, NULL, 0)) ||
565,302✔
1095
      (code = taosHashPut(userObj.roles, TSDB_ROLE_SYSAUDIT, strlen(TSDB_ROLE_SYSAUDIT) + 1, NULL, 0))) {
282,651✔
1096
    TAOS_CHECK_GOTO(code, &lino, _ERROR);
×
1097
  }
1098

1099
  SSdbRaw *pRaw = mndUserActionEncode(&userObj);
282,651✔
1100
  if (pRaw == NULL) goto _ERROR;
282,651✔
1101
  TAOS_CHECK_GOTO(sdbSetRawStatus(pRaw, SDB_STATUS_READY), &lino, _ERROR);
282,651✔
1102

1103
  mInfo("user:%s, will be created when deploying, raw:%p", userObj.user, pRaw);
282,651✔
1104

1105
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_ROLE, NULL, "create-user");
282,651✔
1106
  if (pTrans == NULL) {
282,651✔
1107
    sdbFreeRaw(pRaw);
×
1108
    mError("user:%s, failed to create since %s", userObj.user, terrstr());
×
1109
    goto _ERROR;
×
1110
  }
1111
  mInfo("trans:%d, used to create user:%s", pTrans->id, userObj.user);
282,651✔
1112

1113
  if (mndTransAppendCommitlog(pTrans, pRaw) != 0) {
282,651✔
1114
    mError("trans:%d, failed to commit redo log since %s", pTrans->id, terrstr());
×
1115
    mndTransDrop(pTrans);
×
1116
    goto _ERROR;
×
1117
  }
1118
  TAOS_CHECK_GOTO(sdbSetRawStatus(pRaw, SDB_STATUS_READY), &lino, _ERROR);
282,651✔
1119

1120
  if (mndTransPrepare(pMnode, pTrans) != 0) {
282,651✔
1121
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
1122
    mndTransDrop(pTrans);
×
1123
    goto _ERROR;
×
1124
  }
1125

1126
  mndTransDrop(pTrans);
282,651✔
1127
  mndUserFreeObj(&userObj);
282,651✔
1128
  return 0;
282,651✔
1129

1130
_ERROR:
×
1131
  mndUserFreeObj(&userObj);
×
1132
  if (code == 0) {
×
1133
    code = terrno ? terrno : TSDB_CODE_APP_ERROR;
×
1134
  }
1135
  mError("user:%s, failed to create default user since %s", user, tstrerror(code));
×
1136
  TAOS_RETURN(code);
×
1137
}
1138

1139
static int32_t mndCreateDefaultUsers(SMnode *pMnode) {
282,651✔
1140
  return mndCreateDefaultUser(pMnode, TSDB_DEFAULT_USER, TSDB_DEFAULT_USER, TSDB_DEFAULT_PASS);
282,651✔
1141
}
1142

1143
static int32_t tSerializeUserObjExt(void *buf, int32_t bufLen, SUserObj *pObj) {
4,509,932✔
1144
  int32_t  code = 0, lino = 0;
4,509,932✔
1145
  int32_t  tlen = 0;
4,509,932✔
1146
  void    *pIter = NULL;
4,509,932✔
1147
  SEncoder encoder = {0};
4,509,932✔
1148
  tEncoderInit(&encoder, buf, bufLen);
4,509,932✔
1149

1150
  TAOS_CHECK_EXIT(tStartEncode(&encoder));
4,509,932✔
1151
  TAOS_CHECK_EXIT(tEncodeI64v(&encoder, pObj->uid));
9,019,864✔
1152

1153
  TAOS_CHECK_EXIT(tSerializePrivSysObjPolicies(&encoder, &pObj->sysPrivs, pObj->objPrivs));
4,509,932✔
1154

1155
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->selectTbs));
4,509,932✔
1156
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->insertTbs));
4,509,932✔
1157
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->updateTbs));
4,509,932✔
1158
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->deleteTbs));
4,509,932✔
1159

1160
  int32_t nRoles = taosHashGetSize(pObj->roles);
4,509,932✔
1161
  TAOS_CHECK_EXIT(tEncodeI32v(&encoder, nRoles));
4,509,932✔
1162

1163
  while ((pIter = taosHashIterate(pObj->roles, pIter))) {
13,172,216✔
1164
    size_t keyLen = 0;
8,662,284✔
1165
    char  *key = taosHashGetKey(pIter, &keyLen);  // key: role name
8,662,284✔
1166
    TAOS_CHECK_EXIT(tEncodeCStr(&encoder, key));
8,662,284✔
1167

1168
    uint8_t flag = *(int8_t *)pIter;
8,662,284✔
1169
    TAOS_CHECK_EXIT(tEncodeU8(&encoder, flag));  // value: 0 reset, 1 set(default)
17,324,568✔
1170
  }
1171

1172
  tEndEncode(&encoder);
4,509,932✔
1173
  tlen = encoder.pos;
4,509,932✔
1174
_exit:
4,509,932✔
1175
  tEncoderClear(&encoder);
4,509,932✔
1176
  if (code < 0) {
4,509,932✔
1177
    mError("user:%s, %s failed at line %d since %s", pObj->user, __func__, lino, tstrerror(code));
×
1178
    TAOS_RETURN(code);
×
1179
  }
1180

1181
  return tlen;
4,509,932✔
1182
}
1183

1184
static int32_t tDeserializeUserObjExt(void *buf, int32_t bufLen, SUserObj *pObj) {
1,505,423✔
1185
  int32_t  code = 0, lino = 0;
1,505,423✔
1186
  SDecoder decoder = {0};
1,505,423✔
1187
  tDecoderInit(&decoder, buf, bufLen);
1,505,423✔
1188

1189
  TAOS_CHECK_EXIT(tStartDecode(&decoder));
1,505,423✔
1190
  TAOS_CHECK_EXIT(tDecodeI64v(&decoder, &pObj->uid));
3,010,846✔
1191
  TAOS_CHECK_EXIT(tDeserializePrivSysObjPolicies(&decoder, &pObj->sysPrivs, &pObj->objPrivs));
1,505,423✔
1192
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->selectTbs));
1,505,423✔
1193
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->insertTbs));
1,505,423✔
1194
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->updateTbs));
1,505,423✔
1195
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->deleteTbs));
1,505,423✔
1196
  int32_t nRoles = 0;
1,505,423✔
1197
  TAOS_CHECK_EXIT(tDecodeI32v(&decoder, &nRoles));
1,505,423✔
1198
  if (nRoles > 0) {
1,505,423✔
1199
    if (!pObj->roles &&
1,505,263✔
1200
        !(pObj->roles = taosHashInit(nRoles, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), 1, HASH_ENTRY_LOCK))) {
1,505,263✔
1201
      TAOS_CHECK_EXIT(terrno);
×
1202
    }
1203
    for (int32_t i = 0; i < nRoles; i++) {
3,808,896✔
1204
      int32_t keyLen = 0;
2,303,633✔
1205
      char   *key = NULL;
2,303,633✔
1206
      TAOS_CHECK_EXIT(tDecodeCStrAndLen(&decoder, &key, &keyLen));
2,303,633✔
1207
      uint8_t flag = 0;
2,303,633✔
1208
      TAOS_CHECK_EXIT(tDecodeU8(&decoder, &flag));
2,303,633✔
1209
      TAOS_CHECK_EXIT(taosHashPut(pObj->roles, key, keyLen + 1, &flag, sizeof(flag)));
2,303,633✔
1210
    }
1211
  }
1212

1213
_exit:
1,505,423✔
1214
  tEndDecode(&decoder);
1,505,423✔
1215
  tDecoderClear(&decoder);
1,505,423✔
1216
  if (code < 0) {
1,505,423✔
1217
    mError("user, %s failed at line %d since %s, row:%p", __func__, lino, tstrerror(code), pObj);
×
1218
  }
1219
  TAOS_RETURN(code);
1,505,423✔
1220
}
1221

1222
SSdbRaw *mndUserActionEncode(SUserObj *pUser) {
2,254,966✔
1223
  int32_t code = 0;
2,254,966✔
1224
  int32_t lino = 0;
2,254,966✔
1225
  int32_t passReserve = (sizeof(SUserPassword) + 8) * pUser->numOfPasswords + 4;
2,254,966✔
1226
  int32_t ipWhiteReserve = pUser->pIpWhiteListDual ? (sizeof(SIpRange) * pUser->pIpWhiteListDual->num + sizeof(SIpWhiteListDual) + 4) : 16;
2,254,966✔
1227
  int32_t timeWhiteReserve = pUser->pTimeWhiteList ? (sizeof(SDateTimeWhiteListItem) * pUser->pTimeWhiteList->num + sizeof(SDateTimeWhiteList) + 4) : 16;
2,254,966✔
1228
  int32_t numOfReadDbs = 0; //taosHashGetSize(pUser->readDbs);
2,254,966✔
1229
  int32_t numOfWriteDbs = 0; //taosHashGetSize(pUser->writeDbs);
2,254,966✔
1230
  int32_t numOfReadTbs = 0; //taosHashGetSize(pUser->readTbs);
2,254,966✔
1231
  int32_t numOfWriteTbs = 0; //taosHashGetSize(pUser->writeTbs);
2,254,966✔
1232
  int32_t numOfAlterTbs = 0; //taosHashGetSize(pUser->alterTbs);
2,254,966✔
1233
  int32_t numOfReadViews = 0; //taosHashGetSize(pUser->readViews);
2,254,966✔
1234
  int32_t numOfWriteViews = 0; //taosHashGetSize(pUser->writeViews);
2,254,966✔
1235
  int32_t numOfAlterViews = 0; //taosHashGetSize(pUser->alterViews);
2,254,966✔
1236
  int32_t numOfTopics = 0; // taosHashGetSize(pUser->topics);
2,254,966✔
1237
  int32_t numOfUseDbs = 0; // taosHashGetSize(pUser->useDbs);
2,254,966✔
1238
  int32_t numOfRoles = taosHashGetSize(pUser->roles);
2,254,966✔
1239
  int32_t size = sizeof(SUserObj) + USER_RESERVE_SIZE + (numOfReadDbs + numOfWriteDbs) * TSDB_DB_FNAME_LEN +
2,254,966✔
1240
                 numOfTopics * TSDB_TOPIC_FNAME_LEN + ipWhiteReserve + timeWhiteReserve + passReserve;
2,254,966✔
1241
  char    *buf = NULL;
2,254,966✔
1242
  SSdbRaw *pRaw = NULL;
2,254,966✔
1243

1244
  char *stb = NULL;
2,254,966✔
1245
#if 0
1246
  stb = taosHashIterate(pUser->readTbs, NULL);
1247
  while (stb != NULL) {
1248
    size_t keyLen = 0;
1249
    void  *key = taosHashGetKey(stb, &keyLen);
1250
    size += sizeof(int32_t);
1251
    size += keyLen;
1252

1253
    size_t valueLen = 0;
1254
    valueLen = strlen(stb) + 1;
1255
    size += sizeof(int32_t);
1256
    size += valueLen;
1257
    stb = taosHashIterate(pUser->readTbs, stb);
1258
  }
1259

1260
  stb = taosHashIterate(pUser->writeTbs, NULL);
1261
  while (stb != NULL) {
1262
    size_t keyLen = 0;
1263
    void  *key = taosHashGetKey(stb, &keyLen);
1264
    size += sizeof(int32_t);
1265
    size += keyLen;
1266

1267
    size_t valueLen = 0;
1268
    valueLen = strlen(stb) + 1;
1269
    size += sizeof(int32_t);
1270
    size += valueLen;
1271
    stb = taosHashIterate(pUser->writeTbs, stb);
1272
  }
1273
  stb = taosHashIterate(pUser->alterTbs, NULL);
1274
  while (stb != NULL) {
1275
    size_t keyLen = 0;
1276
    void  *key = taosHashGetKey(stb, &keyLen);
1277
    size += sizeof(int32_t);
1278
    size += keyLen;
1279

1280
    size_t valueLen = 0;
1281
    valueLen = strlen(stb) + 1;
1282
    size += sizeof(int32_t);
1283
    size += valueLen;
1284
    stb = taosHashIterate(pUser->alterTbs, stb);
1285
  }
1286

1287
  stb = taosHashIterate(pUser->readViews, NULL);
1288
  while (stb != NULL) {
1289
    size_t keyLen = 0;
1290
    void  *key = taosHashGetKey(stb, &keyLen);
1291
    size += sizeof(int32_t);
1292
    size += keyLen;
1293

1294
    size_t valueLen = 0;
1295
    valueLen = strlen(stb) + 1;
1296
    size += sizeof(int32_t);
1297
    size += valueLen;
1298
    stb = taosHashIterate(pUser->readViews, stb);
1299
  }
1300

1301
  stb = taosHashIterate(pUser->writeViews, NULL);
1302
  while (stb != NULL) {
1303
    size_t keyLen = 0;
1304
    void  *key = taosHashGetKey(stb, &keyLen);
1305
    size += sizeof(int32_t);
1306
    size += keyLen;
1307

1308
    size_t valueLen = 0;
1309
    valueLen = strlen(stb) + 1;
1310
    size += sizeof(int32_t);
1311
    size += valueLen;
1312
    stb = taosHashIterate(pUser->writeViews, stb);
1313
  }
1314

1315
  stb = taosHashIterate(pUser->alterViews, NULL);
1316
  while (stb != NULL) {
1317
    size_t keyLen = 0;
1318
    void  *key = taosHashGetKey(stb, &keyLen);
1319
    size += sizeof(int32_t);
1320
    size += keyLen;
1321

1322
    size_t valueLen = 0;
1323
    valueLen = strlen(stb) + 1;
1324
    size += sizeof(int32_t);
1325
    size += valueLen;
1326
    stb = taosHashIterate(pUser->alterViews, stb);
1327
  }
1328

1329
  int32_t *useDb = taosHashIterate(pUser->useDbs, NULL);
1330
  while (useDb != NULL) {
1331
    size_t keyLen = 0;
1332
    void  *key = taosHashGetKey(useDb, &keyLen);
1333
    size += sizeof(int32_t);
1334
    size += keyLen;
1335
    size += sizeof(int32_t);
1336
    useDb = taosHashIterate(pUser->useDbs, useDb);
1337
  }
1338
#endif
1339
  int32_t sizeExt = tSerializeUserObjExt(NULL, 0, pUser);
2,254,966✔
1340
  if (sizeExt < 0) {
2,254,966✔
1341
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1342
  }
1343
  size += sizeExt;
2,254,966✔
1344

1345
  pRaw = sdbAllocRaw(SDB_USER, USER_VER_NUMBER, size);
2,254,966✔
1346
  if (pRaw == NULL) {
2,254,966✔
1347
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1348
  }
1349

1350
  int32_t dataPos = 0;
2,254,966✔
1351
  SDB_SET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN, _OVER)
2,254,966✔
1352

1353
  dropOldPasswords(pUser);
2,254,966✔
1354
  SDB_SET_INT32(pRaw, dataPos, pUser->numOfPasswords, _OVER)
2,254,966✔
1355
  for (int32_t i = 0; i < pUser->numOfPasswords; i++) {
5,216,458✔
1356
    SDB_SET_BINARY(pRaw, dataPos, pUser->passwords[i].pass, sizeof(pUser->passwords[i].pass), _OVER)
2,961,492✔
1357
    SDB_SET_INT32(pRaw, dataPos, pUser->passwords[i].setTime, _OVER)
2,961,492✔
1358
  }
1359
  SDB_SET_BINARY(pRaw, dataPos, pUser->salt, sizeof(pUser->salt), _OVER)
2,254,966✔
1360

1361
  SDB_SET_BINARY(pRaw, dataPos, pUser->acct, TSDB_USER_LEN, _OVER)
2,254,966✔
1362
  SDB_SET_INT64(pRaw, dataPos, pUser->createdTime, _OVER)
2,254,966✔
1363
  SDB_SET_INT64(pRaw, dataPos, pUser->updateTime, _OVER)
2,254,966✔
1364
  SDB_SET_INT8(pRaw, dataPos, pUser->superUser, _OVER)
2,254,966✔
1365
  SDB_SET_INT8(pRaw, dataPos, pUser->sysInfo, _OVER)
2,254,966✔
1366
  SDB_SET_INT8(pRaw, dataPos, pUser->enable, _OVER)
2,254,966✔
1367
  SDB_SET_UINT8(pRaw, dataPos, pUser->flag, _OVER)
2,254,966✔
1368
  SDB_SET_INT32(pRaw, dataPos, pUser->authVersion, _OVER)
2,254,966✔
1369
  SDB_SET_INT32(pRaw, dataPos, pUser->passVersion, _OVER)
2,254,966✔
1370
  SDB_SET_INT32(pRaw, dataPos, numOfReadDbs, _OVER)
2,254,966✔
1371
  SDB_SET_INT32(pRaw, dataPos, numOfWriteDbs, _OVER)
2,254,966✔
1372
  SDB_SET_INT32(pRaw, dataPos, numOfTopics, _OVER)
2,254,966✔
1373
#if 0
1374
  char *db = taosHashIterate(pUser->readDbs, NULL);
1375
  while (db != NULL) {
1376
    SDB_SET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER);
1377
    db = taosHashIterate(pUser->readDbs, db);
1378
  }
1379

1380
  db = taosHashIterate(pUser->writeDbs, NULL);
1381
  while (db != NULL) {
1382
    SDB_SET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER);
1383
    db = taosHashIterate(pUser->writeDbs, db);
1384
  }
1385
  char *topic = taosHashIterate(pUser->topics, NULL);
1386
  while (topic != NULL) {
1387
    SDB_SET_BINARY(pRaw, dataPos, topic, TSDB_TOPIC_FNAME_LEN, _OVER);
1388
    topic = taosHashIterate(pUser->topics, topic);
1389
  }
1390
#endif
1391
  SDB_SET_INT32(pRaw, dataPos, numOfReadTbs, _OVER)
2,254,966✔
1392
  SDB_SET_INT32(pRaw, dataPos, numOfWriteTbs, _OVER)
2,254,966✔
1393
  SDB_SET_INT32(pRaw, dataPos, numOfAlterTbs, _OVER)
2,254,966✔
1394
  SDB_SET_INT32(pRaw, dataPos, numOfReadViews, _OVER)
2,254,966✔
1395
  SDB_SET_INT32(pRaw, dataPos, numOfWriteViews, _OVER)
2,254,966✔
1396
  SDB_SET_INT32(pRaw, dataPos, numOfAlterViews, _OVER)
2,254,966✔
1397
  SDB_SET_INT32(pRaw, dataPos, numOfUseDbs, _OVER)
2,254,966✔
1398

1399
#if 0
1400
  stb = taosHashIterate(pUser->readTbs, NULL);
1401
  while (stb != NULL) {
1402
    size_t keyLen = 0;
1403
    void  *key = taosHashGetKey(stb, &keyLen);
1404
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1405
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1406

1407
    size_t valueLen = 0;
1408
    valueLen = strlen(stb) + 1;
1409
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
1410
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
1411
    stb = taosHashIterate(pUser->readTbs, stb);
1412
  }
1413

1414
  stb = taosHashIterate(pUser->writeTbs, NULL);
1415
  while (stb != NULL) {
1416
    size_t keyLen = 0;
1417
    void  *key = taosHashGetKey(stb, &keyLen);
1418
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1419
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1420

1421
    size_t valueLen = 0;
1422
    valueLen = strlen(stb) + 1;
1423
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
1424
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
1425
    stb = taosHashIterate(pUser->writeTbs, stb);
1426
  }
1427
  stb = taosHashIterate(pUser->alterTbs, NULL);
1428
  while (stb != NULL) {
1429
    size_t keyLen = 0;
1430
    void  *key = taosHashGetKey(stb, &keyLen);
1431
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1432
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1433

1434
    size_t valueLen = 0;
1435
    valueLen = strlen(stb) + 1;
1436
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
1437
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
1438
    stb = taosHashIterate(pUser->alterTbs, stb);
1439
  }
1440

1441
  stb = taosHashIterate(pUser->readViews, NULL);
1442
  while (stb != NULL) {
1443
    size_t keyLen = 0;
1444
    void  *key = taosHashGetKey(stb, &keyLen);
1445
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1446
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1447

1448
    size_t valueLen = 0;
1449
    valueLen = strlen(stb) + 1;
1450
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
1451
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
1452
    stb = taosHashIterate(pUser->readViews, stb);
1453
  }
1454

1455
  stb = taosHashIterate(pUser->writeViews, NULL);
1456
  while (stb != NULL) {
1457
    size_t keyLen = 0;
1458
    void  *key = taosHashGetKey(stb, &keyLen);
1459
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1460
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1461

1462
    size_t valueLen = 0;
1463
    valueLen = strlen(stb) + 1;
1464
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
1465
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
1466
    stb = taosHashIterate(pUser->writeViews, stb);
1467
  }
1468

1469
  stb = taosHashIterate(pUser->alterViews, NULL);
1470
  while (stb != NULL) {
1471
    size_t keyLen = 0;
1472
    void  *key = taosHashGetKey(stb, &keyLen);
1473
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1474
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1475

1476
    size_t valueLen = 0;
1477
    valueLen = strlen(stb) + 1;
1478
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
1479
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
1480
    stb = taosHashIterate(pUser->alterViews, stb);
1481
  }
1482

1483
  useDb = taosHashIterate(pUser->useDbs, NULL);
1484
  while (useDb != NULL) {
1485
    size_t keyLen = 0;
1486
    void  *key = taosHashGetKey(useDb, &keyLen);
1487
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1488
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1489

1490
    SDB_SET_INT32(pRaw, dataPos, *useDb, _OVER)
1491
    useDb = taosHashIterate(pUser->useDbs, useDb);
1492
  }
1493
#endif
1494
  // save white list
1495
  int32_t num = pUser->pIpWhiteListDual->num;
2,254,966✔
1496
  int32_t tlen = sizeof(SIpWhiteListDual) + num * sizeof(SIpRange) + 4;
2,254,966✔
1497
  int32_t maxBufLen = TMAX(tlen, sizeExt);
2,254,966✔
1498
  if ((buf = taosMemoryCalloc(1, maxBufLen)) == NULL) {
2,254,966✔
1499
    TAOS_CHECK_GOTO(terrno, NULL, _OVER);
×
1500
  }
1501
  int32_t len = 0;
2,254,966✔
1502
  TAOS_CHECK_GOTO(tSerializeIpWhiteList(buf, tlen, pUser->pIpWhiteListDual, &len), &lino, _OVER);
2,254,966✔
1503

1504
  SDB_SET_INT32(pRaw, dataPos, len, _OVER);
2,254,966✔
1505
  SDB_SET_BINARY(pRaw, dataPos, buf, len, _OVER);
2,254,966✔
1506

1507
  SDB_SET_INT64(pRaw, dataPos, pUser->ipWhiteListVer, _OVER);
2,254,966✔
1508
  SDB_SET_INT8(pRaw, dataPos, pUser->passEncryptAlgorithm, _OVER);
2,254,966✔
1509

1510
  SDB_SET_BINARY(pRaw, dataPos, pUser->totpsecret, sizeof(pUser->totpsecret), _OVER);
2,254,966✔
1511
  SDB_SET_INT8(pRaw, dataPos, pUser->changePass, _OVER);
2,254,966✔
1512
  SDB_SET_INT32(pRaw, dataPos, pUser->sessionPerUser, _OVER);
2,254,966✔
1513
  SDB_SET_INT32(pRaw, dataPos, pUser->connectTime, _OVER);
2,254,966✔
1514
  SDB_SET_INT32(pRaw, dataPos, pUser->connectIdleTime, _OVER);
2,254,966✔
1515
  SDB_SET_INT32(pRaw, dataPos, pUser->callPerSession, _OVER);
2,254,966✔
1516
  SDB_SET_INT32(pRaw, dataPos, pUser->vnodePerCall, _OVER);
2,254,966✔
1517
  SDB_SET_INT32(pRaw, dataPos, pUser->failedLoginAttempts, _OVER);
2,254,966✔
1518
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordLifeTime, _OVER);
2,254,966✔
1519
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordReuseTime, _OVER);
2,254,966✔
1520
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordReuseMax, _OVER);
2,254,966✔
1521
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordLockTime, _OVER);
2,254,966✔
1522
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordGraceTime, _OVER);
2,254,966✔
1523
  SDB_SET_INT32(pRaw, dataPos, pUser->inactiveAccountTime, _OVER);
2,254,966✔
1524
  SDB_SET_INT32(pRaw, dataPos, pUser->allowTokenNum, _OVER);
2,254,966✔
1525
  SDB_SET_INT32(pRaw, dataPos, pUser->tokenNum, _OVER);
2,254,966✔
1526

1527
  SDB_SET_INT32(pRaw, dataPos, pUser->pTimeWhiteList->num, _OVER);
2,254,966✔
1528
  for (int32_t i = 0; i < pUser->pTimeWhiteList->num; i++) {
2,261,266✔
1529
    SDateTimeWhiteListItem *range = &pUser->pTimeWhiteList->ranges[i];
6,300✔
1530
    SDB_SET_BOOL(pRaw, dataPos, range->absolute, _OVER);
6,300✔
1531
    SDB_SET_BOOL(pRaw, dataPos, range->neg, _OVER);
6,300✔
1532
    SDB_SET_INT64(pRaw, dataPos, range->start, _OVER);
6,300✔
1533
    SDB_SET_INT32(pRaw, dataPos, range->duration, _OVER);
6,300✔
1534
  }
1535

1536
  sizeExt = tSerializeUserObjExt(buf, sizeExt, pUser);
2,254,966✔
1537
  if (sizeExt < 0) {
2,254,966✔
1538
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1539
  }
1540
  SDB_SET_INT32(pRaw, dataPos, sizeExt, _OVER);
2,254,966✔
1541
  SDB_SET_BINARY(pRaw, dataPos, buf, sizeExt, _OVER);
2,254,966✔
1542

1543
  SDB_SET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
2,254,966✔
1544

1545
  SDB_SET_DATALEN(pRaw, dataPos, _OVER)
2,254,966✔
1546

1547
_OVER:
2,254,966✔
1548
  taosMemoryFree(buf);
2,254,966✔
1549
  if (code < 0) {
2,254,966✔
1550
    mError("user:%s, failed to encode user action to raw:%p at line %d since %s", pUser->user, pRaw, lino,
×
1551
           tstrerror(code));
1552
    sdbFreeRaw(pRaw);
×
1553
    pRaw = NULL;
×
1554
    terrno = code;
×
1555
  }
1556

1557
  mTrace("user:%s, encode user action to raw:%p, row:%p", pUser->user, pRaw, pUser);
2,254,966✔
1558
  return pRaw;
2,254,966✔
1559
}
1560

1561
static SSdbRow *mndUserActionDecode(SSdbRaw *pRaw) {
1,505,423✔
1562
  int32_t   code = 0;
1,505,423✔
1563
  int32_t   lino = 0;
1,505,423✔
1564
  SSdbRow  *pRow = NULL;
1,505,423✔
1565
  SUserObj *pUser = NULL;
1,505,423✔
1566
  char     *key = NULL;
1,505,423✔
1567
  char     *value = NULL;
1,505,423✔
1568

1569
  SHashObj *pReadDbs = NULL;
1,505,423✔
1570
  SHashObj *pWriteDbs = NULL;
1,505,423✔
1571
  SHashObj *pReadTbs = NULL;
1,505,423✔
1572
  SHashObj *pWriteTbs = NULL;
1,505,423✔
1573
  SHashObj *pTopics = NULL;
1,505,423✔
1574
  SHashObj *pAlterTbs = NULL;
1,505,423✔
1575
  SHashObj *pReadViews = NULL;
1,505,423✔
1576
  SHashObj *pWriteViews = NULL;
1,505,423✔
1577
  SHashObj *pAlterViews = NULL;
1,505,423✔
1578
  SHashObj *pUseDbs = NULL;
1,505,423✔
1579

1580
  int8_t sver = 0;
1,505,423✔
1581
  if (sdbGetRawSoftVer(pRaw, &sver) != 0) {
1,505,423✔
1582
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_PTR, &lino, _OVER);
×
1583
  }
1584

1585
  if (sver < 1 || sver > USER_VER_NUMBER) {
1,505,423✔
1586
    TAOS_CHECK_GOTO(TSDB_CODE_SDB_INVALID_DATA_VER, &lino, _OVER);
×
1587
  }
1588

1589
  pRow = sdbAllocRow(sizeof(SUserObj));
1,505,423✔
1590
  if (pRow == NULL) {
1,505,423✔
1591
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1592
  }
1593

1594
  pUser = sdbGetRowObj(pRow);
1,505,423✔
1595
  if (pUser == NULL) {
1,505,423✔
1596
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1597
  }
1598

1599
  int32_t dataPos = 0;
1,505,423✔
1600
  SDB_GET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN, _OVER)
1,505,423✔
1601

1602
  if (sver < USER_VER_SUPPORT_ADVANCED_SECURITY) {
1,505,423✔
1603
    pUser->passwords = taosMemoryCalloc(1, sizeof(SUserPassword));
×
1604
    if (pUser->passwords == NULL) {
×
1605
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
1606
    }
1607
    SDB_GET_BINARY(pRaw, dataPos, pUser->passwords[0].pass, TSDB_PASSWORD_LEN, _OVER)
×
1608
    pUser->numOfPasswords = 1;
×
1609
    memset(pUser->salt, 0, sizeof(pUser->salt));
×
1610
  } else {
1611
    SDB_GET_INT32(pRaw, dataPos, &pUser->numOfPasswords, _OVER)
1,505,423✔
1612
    pUser->passwords = taosMemoryCalloc(pUser->numOfPasswords, sizeof(SUserPassword));
1,505,423✔
1613
    if (pUser->passwords == NULL) {
1,505,423✔
1614
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
1615
    }
1616
    for (int32_t i = 0; i < pUser->numOfPasswords; ++i) {
3,677,985✔
1617
      SDB_GET_BINARY(pRaw, dataPos, pUser->passwords[i].pass, sizeof(pUser->passwords[i].pass), _OVER);
2,172,562✔
1618
      SDB_GET_INT32(pRaw, dataPos, &pUser->passwords[i].setTime, _OVER);
2,172,562✔
1619
    }
1620
    SDB_GET_BINARY(pRaw, dataPos, pUser->salt, sizeof(pUser->salt), _OVER)
1,505,423✔
1621
  }
1622
  
1623
  SDB_GET_BINARY(pRaw, dataPos, pUser->acct, TSDB_USER_LEN, _OVER)
1,505,423✔
1624
  SDB_GET_INT64(pRaw, dataPos, &pUser->createdTime, _OVER)
1,505,423✔
1625
  SDB_GET_INT64(pRaw, dataPos, &pUser->updateTime, _OVER)
1,505,423✔
1626
  if (sver < USER_VER_SUPPORT_ADVANCED_SECURITY) {
1,505,423✔
1627
    pUser->passwords[0].setTime = (int32_t)(pUser->updateTime / 1000);
×
1628
  }
1629

1630
  SDB_GET_INT8(pRaw, dataPos, &pUser->superUser, _OVER)
1,505,423✔
1631
  SDB_GET_INT8(pRaw, dataPos, &pUser->sysInfo, _OVER)
1,505,423✔
1632
  SDB_GET_INT8(pRaw, dataPos, &pUser->enable, _OVER)
1,505,423✔
1633
  SDB_GET_UINT8(pRaw, dataPos, &pUser->flag, _OVER)
1,505,423✔
1634
  if (pUser->superUser) pUser->createdb = 1;
1,505,423✔
1635
  SDB_GET_INT32(pRaw, dataPos, &pUser->authVersion, _OVER)
1,505,423✔
1636
  if (sver >= 4) {
1,505,423✔
1637
    SDB_GET_INT32(pRaw, dataPos, &pUser->passVersion, _OVER)
1,505,423✔
1638
  }
1639

1640
  int32_t numOfReadDbs = 0;
1,505,423✔
1641
  int32_t numOfWriteDbs = 0;
1,505,423✔
1642
  int32_t numOfTopics = 0;
1,505,423✔
1643
  SDB_GET_INT32(pRaw, dataPos, &numOfReadDbs, _OVER)
1,505,423✔
1644
  SDB_GET_INT32(pRaw, dataPos, &numOfWriteDbs, _OVER)
1,505,423✔
1645
  if (sver >= 2) {
1,505,423✔
1646
    SDB_GET_INT32(pRaw, dataPos, &numOfTopics, _OVER)
1,505,423✔
1647
  }
1648

1649
  if (numOfReadDbs > 0) {
1,505,423✔
1650
    pReadDbs = taosHashInit(numOfReadDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
1651
    if (pReadDbs == NULL) {
×
1652
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1653
    }
1654
  }
1655
  if (numOfWriteDbs > 0) {
1,505,423✔
1656
    pWriteDbs = taosHashInit(numOfWriteDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
1657
    if (pWriteDbs == NULL) {
×
1658
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1659
    }
1660
  }
1661
  if (numOfTopics > 0) {
1,505,423✔
1662
    pTopics = taosHashInit(numOfTopics, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
1663
    if (pTopics == NULL) {
×
1664
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1665
    }
1666
  }
1667
  for (int32_t i = 0; i < numOfReadDbs; ++i) {
1,505,423✔
1668
    char db[TSDB_DB_FNAME_LEN] = {0};
×
1669
    SDB_GET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER)
×
1670
    int32_t len = strlen(db) + 1;
×
1671
    TAOS_CHECK_GOTO(taosHashPut(pReadDbs, db, len, db, TSDB_DB_FNAME_LEN), &lino, _OVER);
×
1672
  }
1673

1674
  for (int32_t i = 0; i < numOfWriteDbs; ++i) {
1,505,423✔
1675
    char db[TSDB_DB_FNAME_LEN] = {0};
×
1676
    SDB_GET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER)
×
1677
    int32_t len = strlen(db) + 1;
×
1678
    TAOS_CHECK_GOTO(taosHashPut(pWriteDbs, db, len, db, TSDB_DB_FNAME_LEN), &lino, _OVER);
×
1679
  }
1680

1681
  if (sver >= 2) {
1,505,423✔
1682
    for (int32_t i = 0; i < numOfTopics; ++i) {
1,505,423✔
1683
      char topic[TSDB_TOPIC_FNAME_LEN] = {0};
×
1684
      SDB_GET_BINARY(pRaw, dataPos, topic, TSDB_TOPIC_FNAME_LEN, _OVER)
×
1685
      int32_t len = strlen(topic) + 1;
×
1686
      TAOS_CHECK_GOTO(taosHashPut(pTopics, topic, len, topic, TSDB_TOPIC_FNAME_LEN), &lino, _OVER);
×
1687
    }
1688
  }
1689

1690
  if (sver >= 3) {
1,505,423✔
1691
    int32_t numOfReadTbs = 0;
1,505,423✔
1692
    int32_t numOfWriteTbs = 0;
1,505,423✔
1693
    int32_t numOfAlterTbs = 0;
1,505,423✔
1694
    int32_t numOfReadViews = 0;
1,505,423✔
1695
    int32_t numOfWriteViews = 0;
1,505,423✔
1696
    int32_t numOfAlterViews = 0;
1,505,423✔
1697
    int32_t numOfUseDbs = 0;
1,505,423✔
1698
    SDB_GET_INT32(pRaw, dataPos, &numOfReadTbs, _OVER)
1,505,423✔
1699
    SDB_GET_INT32(pRaw, dataPos, &numOfWriteTbs, _OVER)
1,505,423✔
1700
    if (sver >= 6) {
1,505,423✔
1701
      SDB_GET_INT32(pRaw, dataPos, &numOfAlterTbs, _OVER)
1,505,423✔
1702
      SDB_GET_INT32(pRaw, dataPos, &numOfReadViews, _OVER)
1,505,423✔
1703
      SDB_GET_INT32(pRaw, dataPos, &numOfWriteViews, _OVER)
1,505,423✔
1704
      SDB_GET_INT32(pRaw, dataPos, &numOfAlterViews, _OVER)
1,505,423✔
1705
    }
1706
    SDB_GET_INT32(pRaw, dataPos, &numOfUseDbs, _OVER)
1,505,423✔
1707

1708
    if (numOfReadTbs > 0) {
1,505,423✔
1709
      pReadTbs = taosHashInit(numOfReadTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
1710
      if (pReadTbs == NULL) {
×
1711
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1712
      }
1713
    }
1714
    if (numOfWriteTbs > 0) {
1,505,423✔
1715
      pWriteTbs = taosHashInit(numOfWriteTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
1716
      if (pWriteTbs == NULL) {
×
1717
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1718
      }
1719
    }
1720
    pAlterTbs = taosHashInit(numOfAlterTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,505,423✔
1721
    pReadViews = taosHashInit(numOfReadViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,505,423✔
1722
    pWriteViews =
1723
        taosHashInit(numOfWriteViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,505,423✔
1724
    pAlterViews =
1725
        taosHashInit(numOfAlterViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,505,423✔
1726
    pUseDbs = taosHashInit(numOfUseDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,505,423✔
1727

1728
    if (pAlterTbs == NULL || pReadViews == NULL || pWriteViews == NULL || pAlterViews == NULL || pUseDbs == NULL) {
1,505,423✔
1729
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1730
      goto _OVER;
×
1731
    }
1732

1733
    for (int32_t i = 0; i < numOfReadTbs; ++i) {
1,505,423✔
1734
      int32_t keyLen = 0;
×
1735
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
1736

1737
      TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
1738
      if (key == NULL) {
×
1739
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1740
      }
1741
      (void)memset(key, 0, keyLen);
×
1742
      SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
1743

1744
      int32_t valuelen = 0;
×
1745
      SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
1746
      TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
1747
      if (value == NULL) {
×
1748
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1749
      }
1750
      (void)memset(value, 0, valuelen);
×
1751
      SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
1752

1753
      TAOS_CHECK_GOTO(taosHashPut(pReadTbs, key, keyLen, value, valuelen), &lino, _OVER);
×
1754
    }
1755

1756
    for (int32_t i = 0; i < numOfWriteTbs; ++i) {
1,505,423✔
1757
      int32_t keyLen = 0;
×
1758
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
1759

1760
      TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
1761
      if (key == NULL) {
×
1762
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1763
      }
1764
      (void)memset(key, 0, keyLen);
×
1765
      SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
1766

1767
      int32_t valuelen = 0;
×
1768
      SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
1769
      TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
1770
      if (value == NULL) {
×
1771
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1772
      }
1773
      (void)memset(value, 0, valuelen);
×
1774
      SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
1775

1776
      TAOS_CHECK_GOTO(taosHashPut(pWriteTbs, key, keyLen, value, valuelen), &lino, _OVER);
×
1777
    }
1778

1779
    if (sver >= 6) {
1,505,423✔
1780
      for (int32_t i = 0; i < numOfAlterTbs; ++i) {
1,505,423✔
1781
        int32_t keyLen = 0;
×
1782
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
1783

1784
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
1785
        if (key == NULL) {
×
1786
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1787
        }
1788
        (void)memset(key, 0, keyLen);
×
1789
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
1790

1791
        int32_t valuelen = 0;
×
1792
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
1793
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
1794
        if (value == NULL) {
×
1795
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1796
        }
1797
        (void)memset(value, 0, valuelen);
×
1798
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
1799

1800
        TAOS_CHECK_GOTO(taosHashPut(pAlterTbs, key, keyLen, value, valuelen), &lino, _OVER);
×
1801
      }
1802

1803
      for (int32_t i = 0; i < numOfReadViews; ++i) {
1,505,423✔
1804
        int32_t keyLen = 0;
×
1805
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
1806

1807
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
1808
        if (key == NULL) {
×
1809
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1810
        }
1811
        (void)memset(key, 0, keyLen);
×
1812
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
1813

1814
        int32_t valuelen = 0;
×
1815
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
1816
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
1817
        if (value == NULL) {
×
1818
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1819
        }
1820
        (void)memset(value, 0, valuelen);
×
1821
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
1822

1823
        TAOS_CHECK_GOTO(taosHashPut(pReadViews, key, keyLen, value, valuelen), &lino, _OVER);
×
1824
      }
1825

1826
      for (int32_t i = 0; i < numOfWriteViews; ++i) {
1,505,423✔
1827
        int32_t keyLen = 0;
×
1828
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
1829

1830
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
1831
        if (key == NULL) {
×
1832
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1833
        }
1834
        (void)memset(key, 0, keyLen);
×
1835
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
1836

1837
        int32_t valuelen = 0;
×
1838
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
1839
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
1840
        if (value == NULL) {
×
1841
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1842
        }
1843
        (void)memset(value, 0, valuelen);
×
1844
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
1845

1846
        TAOS_CHECK_GOTO(taosHashPut(pWriteViews, key, keyLen, value, valuelen), &lino, _OVER);
×
1847
      }
1848

1849
      for (int32_t i = 0; i < numOfAlterViews; ++i) {
1,505,423✔
1850
        int32_t keyLen = 0;
×
1851
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
1852

1853
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
1854
        if (key == NULL) {
×
1855
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1856
        }
1857
        (void)memset(key, 0, keyLen);
×
1858
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
1859

1860
        int32_t valuelen = 0;
×
1861
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
1862
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
1863
        if (value == NULL) {
×
1864
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1865
        }
1866
        (void)memset(value, 0, valuelen);
×
1867
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
1868

1869
        TAOS_CHECK_GOTO(taosHashPut(pAlterViews, key, keyLen, value, valuelen), &lino, _OVER);
×
1870
      }
1871
    }
1872

1873
    for (int32_t i = 0; i < numOfUseDbs; ++i) {
1,505,423✔
1874
      int32_t keyLen = 0;
×
1875
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
1876

1877
      TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
1878
      if (key == NULL) {
×
1879
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1880
      }
1881
      (void)memset(key, 0, keyLen);
×
1882
      SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
1883

1884
      int32_t ref = 0;
×
1885
      SDB_GET_INT32(pRaw, dataPos, &ref, _OVER);
×
1886

1887
      TAOS_CHECK_GOTO(taosHashPut(pUseDbs, key, keyLen, &ref, sizeof(ref)), &lino, _OVER);
×
1888
    }
1889
  }
1890
  // decoder white list
1891
  if (sver >= USER_VER_SUPPORT_WHITELIST) {
1,505,423✔
1892
    if (sver < USER_VER_SUPPORT_WHITELIT_DUAL_STACK) {
1,505,423✔
1893
      int32_t len = 0;
×
1894
      SDB_GET_INT32(pRaw, dataPos, &len, _OVER);
×
1895

1896
      TAOS_MEMORY_REALLOC(key, len);
×
1897
      if (key == NULL) {
×
1898
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1899
      }
1900
      SDB_GET_BINARY(pRaw, dataPos, key, len, _OVER);
×
1901

1902
      SIpWhiteList *pIpWhiteList = NULL;
×
1903
      TAOS_CHECK_GOTO(createIpWhiteListFromOldVer(key, len, &pIpWhiteList), &lino, _OVER);
×
1904

1905
      SDB_GET_INT64(pRaw, dataPos, &pUser->ipWhiteListVer, _OVER);
×
1906

1907
      code = cvtIpWhiteListToDual(pIpWhiteList, &pUser->pIpWhiteListDual);
×
1908
      if (code != 0) {
×
1909
        taosMemoryFreeClear(pIpWhiteList);
×
1910
      }
1911
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
1912

1913
      taosMemoryFreeClear(pIpWhiteList);
×
1914

1915
    } else if (sver >= USER_VER_SUPPORT_WHITELIT_DUAL_STACK) {
1,505,423✔
1916
      int32_t len = 0;
1,505,423✔
1917
      SDB_GET_INT32(pRaw, dataPos, &len, _OVER);
1,505,423✔
1918

1919
      TAOS_MEMORY_REALLOC(key, len);
1,505,423✔
1920
      if (key == NULL) {
1,505,423✔
1921
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1922
      }
1923
      SDB_GET_BINARY(pRaw, dataPos, key, len, _OVER);
1,505,423✔
1924

1925
      TAOS_CHECK_GOTO(createIpWhiteList(key, len, &pUser->pIpWhiteListDual, sver >= USER_VER_SUPPORT_ADVANCED_SECURITY), &lino, _OVER);
1,505,423✔
1926
      SDB_GET_INT64(pRaw, dataPos, &pUser->ipWhiteListVer, _OVER);
1,505,423✔
1927
    }
1928
  }
1929

1930
  if (pUser->pIpWhiteListDual == NULL) {
1,505,423✔
1931
    TAOS_CHECK_GOTO(createDefaultIpWhiteList(&pUser->pIpWhiteListDual), &lino, _OVER);
×
1932
    pUser->ipWhiteListVer = taosGetTimestampMs();
×
1933
  }
1934

1935
  SDB_GET_INT8(pRaw, dataPos, &pUser->passEncryptAlgorithm, _OVER);
1,505,423✔
1936

1937
  if (sver < USER_VER_SUPPORT_ADVANCED_SECURITY) {
1,505,423✔
1938
    memset(pUser->totpsecret, 0, sizeof(pUser->totpsecret));
×
1939
    pUser->changePass = 2;
×
1940
    pUser->sessionPerUser = pUser->superUser ? -1 : TSDB_USER_SESSION_PER_USER_DEFAULT;
×
1941
    pUser->connectTime = TSDB_USER_CONNECT_TIME_DEFAULT;
×
1942
    pUser->connectIdleTime = TSDB_USER_CONNECT_IDLE_TIME_DEFAULT;
×
1943
    pUser->callPerSession = pUser->superUser ? -1 : TSDB_USER_CALL_PER_SESSION_DEFAULT;
×
1944
    pUser->vnodePerCall = pUser->superUser ? -1 : TSDB_USER_VNODE_PER_CALL_DEFAULT;
×
1945
    pUser->failedLoginAttempts = pUser->superUser ? -1 : TSDB_USER_FAILED_LOGIN_ATTEMPTS_DEFAULT;
×
1946
    pUser->passwordLifeTime = TSDB_USER_PASSWORD_LIFE_TIME_DEFAULT;
×
1947
    pUser->passwordReuseTime = TSDB_USER_PASSWORD_REUSE_TIME_DEFAULT;
×
1948
    pUser->passwordReuseMax = TSDB_USER_PASSWORD_REUSE_MAX_DEFAULT;
×
1949
    pUser->passwordLockTime = TSDB_USER_PASSWORD_LOCK_TIME_DEFAULT;
×
1950
    pUser->passwordGraceTime = pUser->superUser ? -1 : TSDB_USER_PASSWORD_GRACE_TIME_DEFAULT;
×
1951
    pUser->inactiveAccountTime = pUser->superUser ? -1 : TSDB_USER_INACTIVE_ACCOUNT_TIME_DEFAULT;
×
1952
    pUser->allowTokenNum = pUser->superUser ? -1 : TSDB_USER_ALLOW_TOKEN_NUM_DEFAULT;
×
1953
    pUser->tokenNum = 0;
×
1954
    pUser->pTimeWhiteList = taosMemCalloc(1, sizeof(SDateTimeWhiteList));
×
1955
    if (pUser->pTimeWhiteList == NULL) {
×
1956
    }
1957
  } else {
1958
    SDB_GET_BINARY(pRaw, dataPos, pUser->totpsecret, sizeof(pUser->totpsecret), _OVER);
1,505,423✔
1959
    SDB_GET_INT8(pRaw, dataPos, &pUser->changePass, _OVER);
1,505,423✔
1960
    SDB_GET_INT32(pRaw, dataPos, &pUser->sessionPerUser, _OVER);
1,505,423✔
1961
    SDB_GET_INT32(pRaw, dataPos, &pUser->connectTime, _OVER);
1,505,423✔
1962
    SDB_GET_INT32(pRaw, dataPos, &pUser->connectIdleTime, _OVER);
1,505,423✔
1963
    SDB_GET_INT32(pRaw, dataPos, &pUser->callPerSession, _OVER);
1,505,423✔
1964
    SDB_GET_INT32(pRaw, dataPos, &pUser->vnodePerCall, _OVER);
1,505,423✔
1965
    SDB_GET_INT32(pRaw, dataPos, &pUser->failedLoginAttempts, _OVER);
1,505,423✔
1966
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordLifeTime, _OVER);
1,505,423✔
1967
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordReuseTime, _OVER);
1,505,423✔
1968
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordReuseMax, _OVER);
1,505,423✔
1969
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordLockTime, _OVER);
1,505,423✔
1970
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordGraceTime, _OVER);
1,505,423✔
1971
    SDB_GET_INT32(pRaw, dataPos, &pUser->inactiveAccountTime, _OVER);
1,505,423✔
1972
    SDB_GET_INT32(pRaw, dataPos, &pUser->allowTokenNum, _OVER);
1,505,423✔
1973
    SDB_GET_INT32(pRaw, dataPos, &pUser->tokenNum, _OVER);
1,505,423✔
1974

1975
    int32_t num = 0;
1,505,423✔
1976
    SDB_GET_INT32(pRaw, dataPos, &num, _OVER);
1,505,423✔
1977
    pUser->pTimeWhiteList = taosMemCalloc(1, sizeof(SDateTimeWhiteList) + num * sizeof(SDateTimeWhiteListItem));
1,505,423✔
1978
    if (pUser->pTimeWhiteList == NULL) {
1,505,423✔
1979
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1980
    }
1981

1982
    pUser->pTimeWhiteList->num = num;
1,505,423✔
1983
    for (int32_t i = 0; i < num; i++) {
1,508,195✔
1984
      SDateTimeWhiteListItem *range = &pUser->pTimeWhiteList->ranges[i];
2,772✔
1985
      SDB_GET_BOOL(pRaw, dataPos, &range->absolute, _OVER);
2,772✔
1986
      SDB_GET_BOOL(pRaw, dataPos, &range->neg, _OVER);
2,772✔
1987
      SDB_GET_INT64(pRaw, dataPos, &range->start, _OVER);
2,772✔
1988
      SDB_GET_INT32(pRaw, dataPos, &range->duration, _OVER);
2,772✔
1989
    }
1990

1991
    int32_t extLen = 0;
1,505,423✔
1992
    SDB_GET_INT32(pRaw, dataPos, &extLen, _OVER);
1,505,423✔
1993
    TAOS_MEMORY_REALLOC(key, extLen);
1,505,423✔
1994
    if (key == NULL) {
1,505,423✔
1995
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1996
    }
1997
    SDB_GET_BINARY(pRaw, dataPos, key, extLen, _OVER);
1,505,423✔
1998
    TAOS_CHECK_GOTO(tDeserializeUserObjExt(key, extLen, pUser), &lino, _OVER);
1,505,423✔
1999
  }
2000

2001
#ifndef TD_ENTERPRISE
2002
  // community users cannot modify these fields, and the default values may prevent
2003
  // the user from logging in, so we set them to different values here.
2004
  pUser->sessionPerUser = -1;
2005
  pUser->connectTime = -1;
2006
  pUser->connectIdleTime = -1;
2007
  pUser->callPerSession = -1;
2008
  pUser->vnodePerCall = -1;
2009
  pUser->failedLoginAttempts = -1;
2010
  pUser->passwordLifeTime = -1;
2011
  pUser->passwordReuseTime = 0;
2012
  pUser->passwordReuseMax = 0;
2013
  pUser->passwordLockTime = -1;
2014
  pUser->passwordGraceTime = -1;
2015
  pUser->inactiveAccountTime = -1;
2016
  pUser->allowTokenNum = -1;
2017
  pUser->tokenNum = 0;
2018
#endif // TD_ENTERPRISE
2019

2020
  SDB_GET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
1,505,423✔
2021

2022
  taosInitRWLatch(&pUser->lock);
1,505,423✔
2023
  dropOldPasswords(pUser);
1,505,423✔
2024
  // TODO: migrate legacy privileges to new hash tables
2025
_OVER:
1,505,423✔
2026
  taosMemoryFree(key);
1,505,423✔
2027
  taosMemoryFree(value);
1,505,423✔
2028
  taosHashCleanup(pReadDbs);
1,505,423✔
2029
  taosHashCleanup(pWriteDbs);
1,505,423✔
2030
  taosHashCleanup(pTopics);
1,505,423✔
2031
  taosHashCleanup(pReadTbs);
1,505,423✔
2032
  taosHashCleanup(pWriteTbs);
1,505,423✔
2033
  taosHashCleanup(pAlterTbs);
1,505,423✔
2034
  taosHashCleanup(pReadViews);
1,505,423✔
2035
  taosHashCleanup(pWriteViews);
1,505,423✔
2036
  taosHashCleanup(pAlterViews);
1,505,423✔
2037
  taosHashCleanup(pUseDbs);
1,505,423✔
2038
  if (code < 0) {
1,505,423✔
2039
    terrno = code;
×
2040
    mError("user:%s, failed to decode at line %d from raw:%p since %s", pUser == NULL ? "null" : pUser->user, lino,
×
2041
           pRaw, tstrerror(code));
2042
    if (pUser != NULL) {
×
2043
      mndUserFreeObj(pUser);
×
2044
    }
2045
    taosMemoryFreeClear(pRow);
×
2046
    return NULL;
×
2047
  }
2048

2049
  mTrace("user:%s, decode from raw:%p, row:%p", pUser->user, pRaw, pUser);
1,505,423✔
2050
  return pRow;
1,505,423✔
2051
}
2052

2053
static int32_t mndUserActionInsert(SSdb *pSdb, SUserObj *pUser) {
457,803✔
2054
  mTrace("user:%s, perform insert action, row:%p", pUser->user, pUser);
457,803✔
2055

2056
  SAcctObj *pAcct = sdbAcquire(pSdb, SDB_ACCT, pUser->acct);
457,803✔
2057
  if (pAcct == NULL) {
457,803✔
2058
    terrno = TSDB_CODE_MND_ACCT_NOT_EXIST;
×
2059
    mError("user:%s, failed to perform insert action since %s", pUser->user, terrstr());
×
2060
    TAOS_RETURN(terrno);
×
2061
  }
2062
  pUser->acctId = pAcct->acctId;
457,803✔
2063
  sdbRelease(pSdb, pAcct);
457,803✔
2064

2065
  return 0;
457,803✔
2066
}
2067

2068
int32_t mndDupTableHash(SHashObj *pOld, SHashObj **ppNew) {
×
2069
  int32_t code = 0;
×
2070
  *ppNew =
×
2071
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
2072
  if (*ppNew == NULL) {
×
2073
    TAOS_RETURN(terrno);
×
2074
  }
2075

2076
  char *tb = taosHashIterate(pOld, NULL);
×
2077
  while (tb != NULL) {
×
2078
    size_t keyLen = 0;
×
2079
    char  *key = taosHashGetKey(tb, &keyLen);
×
2080

2081
    int32_t valueLen = strlen(tb) + 1;
×
2082
    if ((code = taosHashPut(*ppNew, key, keyLen, tb, valueLen)) != 0) {
×
2083
      taosHashCancelIterate(pOld, tb);
×
2084
      taosHashCleanup(*ppNew);
×
2085
      TAOS_RETURN(code);
×
2086
    }
2087
    tb = taosHashIterate(pOld, tb);
×
2088
  }
2089

2090
  TAOS_RETURN(code);
×
2091
}
2092

2093
int32_t mndDupUseDbHash(SHashObj *pOld, SHashObj **ppNew) {
×
2094
  int32_t code = 0;
×
2095
  *ppNew =
×
2096
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
2097
  if (*ppNew == NULL) {
×
2098
    TAOS_RETURN(terrno);
×
2099
  }
2100

2101
  int32_t *db = taosHashIterate(pOld, NULL);
×
2102
  while (db != NULL) {
×
2103
    size_t keyLen = 0;
×
2104
    char  *key = taosHashGetKey(db, &keyLen);
×
2105

2106
    if ((code = taosHashPut(*ppNew, key, keyLen, db, sizeof(*db))) != 0) {
×
2107
      taosHashCancelIterate(pOld, db);
×
2108
      taosHashCleanup(*ppNew);
×
2109
      TAOS_RETURN(code);
×
2110
    }
2111
    db = taosHashIterate(pOld, db);
×
2112
  }
2113

2114
  TAOS_RETURN(code);
×
2115
}
2116

2117
int32_t mndDupRoleHash(SHashObj *pOld, SHashObj **ppNew) {
1,022,256✔
2118
  if (!(*ppNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true,
1,022,256✔
2119
                              HASH_ENTRY_LOCK))) {
2120
    TAOS_RETURN(terrno);
×
2121
  }
2122

2123
  int32_t  code = 0;
1,022,256✔
2124
  uint8_t *flag = NULL;
1,022,256✔
2125
  while ((flag = taosHashIterate(pOld, flag))) {
2,048,742✔
2126
    size_t keyLen = 0;
1,026,486✔
2127
    char  *key = taosHashGetKey(flag, &keyLen);
1,026,486✔
2128

2129
    if ((code = taosHashPut(*ppNew, key, keyLen, flag, sizeof(*flag))) != 0) {
1,026,486✔
2130
      taosHashCancelIterate(pOld, flag);
×
2131
      taosHashCleanup(*ppNew);
×
2132
      TAOS_RETURN(code);
×
2133
    }
2134
  }
2135

2136
  TAOS_RETURN(code);
1,022,256✔
2137
}
2138

2139
int32_t mndMergePrivObjHash(SHashObj *pOld, SHashObj **ppNew) {
76,532,125✔
2140
  if (!(*ppNew)) return mndDupPrivObjHash(pOld, ppNew);
76,532,125✔
2141

2142
  int32_t           code = 0, lino = 0;
76,532,125✔
2143
  SHashObj         *pNew = *ppNew;
76,532,125✔
2144
  SPrivObjPolicies *policies = NULL;
76,530,713✔
2145
  while ((policies = taosHashIterate(pOld, policies))) {
714,168,203✔
2146
    size_t klen = 0;
637,640,907✔
2147
    char  *key = taosHashGetKey(policies, &klen);
637,640,907✔
2148
    size_t vlen = taosHashGetValueSize(policies);
637,640,337✔
2149

2150
    SPrivObjPolicies *pNewPolicies = taosHashGet(pNew, key, klen);
637,640,057✔
2151
    if (pNewPolicies) {
637,640,298✔
2152
      size_t newVlen = taosHashGetValueSize(pNewPolicies);
406,104,844✔
2153
      if (newVlen > 0 && vlen > 0) {
406,104,844✔
2154
        privAddSet(&pNewPolicies->policy, &policies->policy);
406,105,136✔
2155
      }
2156
      continue;
406,102,899✔
2157
    }
2158

2159
    if ((code = taosHashPut(pNew, key, klen, vlen ? policies : NULL, vlen)) != 0) {
231,535,454✔
2160
      taosHashCancelIterate(pOld, policies);
1,604✔
2161
      taosHashCleanup(pNew);
×
2162
      *ppNew = NULL;
×
2163
      TAOS_RETURN(code);
×
2164
    }
2165
  }
2166

2167
  TAOS_RETURN(code);
76,532,110✔
2168
}
2169

2170
/**
2171
 * 1. Prefer to use SPrivTblPolicies from user object(the updateUs of policy in user object is INT64_MAX)
2172
 * 2. If two or more roles have SPrivTblPolicies, the policy with latest update time take effect.
2173
 */
2174
int32_t mndMergePrivTblHash(SHashObj *pOld, SHashObj **ppNew, bool updateWithLatest) {
229,594,157✔
2175
  if (!(*ppNew)) return mndDupPrivTblHash(pOld, ppNew, false);
229,594,157✔
2176

2177
  int32_t           code = 0, lino = 0;
229,594,449✔
2178
  SHashObj         *pNew = *ppNew;
229,594,449✔
2179
  SPrivTblPolicies *policies = NULL;
229,594,961✔
2180
  while ((policies = taosHashIterate(pOld, policies))) {
229,594,961✔
2181
    size_t klen = 0;
×
2182
    char  *key = taosHashGetKey(policies, &klen);
×
2183
    size_t vlen = taosHashGetValueSize(policies);
×
2184

2185
    SPrivTblPolicies *pNewPolicies = taosHashGet(pNew, key, klen);
×
2186
    if (pNewPolicies) {
×
2187
      size_t newVlen = taosHashGetValueSize(pNewPolicies);
×
2188
      if (newVlen > 0 && vlen > 0) {
×
2189
        TAOS_CHECK_EXIT(privTblPoliciesMerge(pNewPolicies, policies, updateWithLatest));
×
2190
      }
2191
      continue;
×
2192
    }
2193

2194
    SPrivTblPolicies tmpPolicies = {0};
×
2195
    if (vlen > 0) {
×
2196
      if ((code = privTblPoliciesMerge(&tmpPolicies, policies, updateWithLatest))) {
×
2197
        privTblPoliciesFree(&tmpPolicies);
2198
        goto _exit;
×
2199
      }
2200
    }
2201
    if ((code = taosHashPut(pNew, key, klen, vlen ? &tmpPolicies : NULL, vlen)) != 0) {
×
2202
      privTblPoliciesFree(&tmpPolicies);
2203
      taosHashCancelIterate(pOld, policies);
×
2204
      taosHashCleanup(pNew);
×
2205
      *ppNew = NULL;
×
2206
      TAOS_RETURN(code);
×
2207
    }
2208
  }
2209

2210
_exit:
229,595,765✔
2211
  TAOS_RETURN(code);
229,595,765✔
2212
}
2213

2214
int32_t mndDupPrivObjHash(SHashObj *pOld, SHashObj **ppNew) {
26,790,501✔
2215
  if (!(*ppNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true,
26,790,501✔
2216
                             HASH_ENTRY_LOCK))) {
2217
    TAOS_RETURN(terrno);
×
2218
  }
2219
  int32_t           code = 0;
26,790,015✔
2220
  SPrivObjPolicies *policies = NULL;
26,790,015✔
2221
  while ((policies = taosHashIterate(pOld, policies))) {
29,605,381✔
2222
    size_t klen = 0;
2,815,366✔
2223
    char  *key = taosHashGetKey(policies, &klen);
2,815,366✔
2224
    size_t vlen = taosHashGetValueSize(policies);
2,815,366✔
2225

2226
    if ((code = taosHashPut(*ppNew, key, klen, vlen > 0 ? policies : NULL, vlen)) != 0) {
2,815,366✔
2227
      taosHashCancelIterate(pOld, policies);
×
2228
      taosHashCleanup(*ppNew);
×
2229
      TAOS_RETURN(code);
×
2230
    }
2231
  }
2232

2233
  TAOS_RETURN(code);
26,790,631✔
2234
}
2235

2236
int32_t mndDupPrivTblHash(SHashObj *pOld, SHashObj **ppNew, bool setUpdateTimeMax) {
81,391,061✔
2237
  if (!(*ppNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true,
81,391,061✔
2238
                              HASH_ENTRY_LOCK))) {
2239
    TAOS_RETURN(terrno);
×
2240
  }
2241
  taosHashSetFreeFp(*ppNew, privTblPoliciesFree);
81,394,417✔
2242

2243
  int32_t           code = 0, lino = 0;
81,393,395✔
2244
  SPrivTblPolicies *policies = NULL, *pTmpPolicies = NULL;
81,393,395✔
2245
  SPrivTblPolicies  tmpPolicies = {0};
81,393,395✔
2246
  while ((policies = taosHashIterate(pOld, policies))) {
81,459,437✔
2247
    size_t klen = 0;
65,750✔
2248
    char  *key = taosHashGetKey(policies, &klen);
65,750✔
2249
    size_t vlen = taosHashGetValueSize(policies);
65,750✔
2250
    memset(&tmpPolicies, 0, sizeof(tmpPolicies));
65,750✔
2251
    pTmpPolicies = &tmpPolicies;
65,750✔
2252
    if (vlen > 0) {
65,750✔
2253
      TAOS_CHECK_EXIT(privTblPoliciesAdd(&tmpPolicies, policies, true, setUpdateTimeMax));
65,750✔
2254
    }
2255
    TAOS_CHECK_EXIT(taosHashPut(*ppNew, key, klen, vlen > 0 ? &tmpPolicies : NULL, vlen));
65,750✔
2256
    pTmpPolicies = NULL;
65,750✔
2257
  }
2258

2259
_exit:
81,394,125✔
2260
  if (code != 0) {
81,394,125✔
2261
    if (!pTmpPolicies) {
×
2262
      privTblPoliciesFree(pTmpPolicies);
2263
      pTmpPolicies = NULL;
×
2264
    }
2265
    if (policies) taosHashCancelIterate(pOld, policies);
×
2266
    taosHashCleanup(*ppNew);
×
2267
    *ppNew = NULL;
×
2268
  }
2269
  TAOS_RETURN(code);
81,394,125✔
2270
}
2271

2272
int32_t mndUserDupObj(SUserObj *pUser, SUserObj *pNew) {
1,021,040✔
2273
  int32_t code = 0;
1,021,040✔
2274
  (void)memcpy(pNew, pUser, sizeof(SUserObj));
1,021,040✔
2275
  pNew->authVersion++;
1,021,040✔
2276
  pNew->updateTime = taosGetTimestampMs();
1,021,040✔
2277
  taosInitRWLatch(&pNew->lock);
1,021,040✔
2278

2279
  pNew->passwords = NULL;
1,021,040✔
2280
  pNew->pIpWhiteListDual = NULL;
1,021,040✔
2281
  pNew->passwords = NULL;
1,021,040✔
2282
  pNew->objPrivs = NULL;
1,021,040✔
2283
  pNew->selectTbs = NULL;
1,021,040✔
2284
  pNew->insertTbs = NULL;
1,021,040✔
2285
  pNew->updateTbs = NULL;
1,021,040✔
2286
  pNew->deleteTbs = NULL;
1,021,040✔
2287
  pNew->pTimeWhiteList = NULL;
1,021,040✔
2288
  pNew->roles = NULL;
1,021,040✔
2289

2290
  taosRLockLatch(&pUser->lock);
1,021,040✔
2291
  pNew->passwords = taosMemoryCalloc(pUser->numOfPasswords, sizeof(SUserPassword));
1,021,040✔
2292
  if (pNew->passwords == NULL) {
1,021,040✔
2293
    code = TSDB_CODE_OUT_OF_MEMORY;
×
2294
    goto _OVER;
×
2295
  }
2296
  (void)memcpy(pNew->passwords, pUser->passwords, pUser->numOfPasswords * sizeof(SUserPassword));
1,021,040✔
2297
  TAOS_CHECK_GOTO(mndDupPrivObjHash(pUser->objPrivs, &pNew->objPrivs), NULL, _OVER);
1,021,040✔
2298
  TAOS_CHECK_GOTO(mndDupPrivTblHash(pUser->selectTbs, &pNew->selectTbs, false), NULL, _OVER);
1,021,040✔
2299
  TAOS_CHECK_GOTO(mndDupPrivTblHash(pUser->insertTbs, &pNew->insertTbs, false), NULL, _OVER);
1,021,040✔
2300
  TAOS_CHECK_GOTO(mndDupPrivTblHash(pUser->updateTbs, &pNew->updateTbs, false), NULL, _OVER);
1,021,040✔
2301
  TAOS_CHECK_GOTO(mndDupPrivTblHash(pUser->deleteTbs, &pNew->deleteTbs, false), NULL, _OVER);
1,021,040✔
2302
  TAOS_CHECK_GOTO(mndDupRoleHash(pUser->roles, &pNew->roles), NULL, _OVER);
1,021,040✔
2303
  pNew->pIpWhiteListDual = cloneIpWhiteList(pUser->pIpWhiteListDual);
1,021,040✔
2304
  if (pNew->pIpWhiteListDual == NULL) {
1,021,040✔
2305
    code = TSDB_CODE_OUT_OF_MEMORY;
×
2306
    goto _OVER;
×
2307
  }
2308

2309
  pNew->pTimeWhiteList = cloneDateTimeWhiteList(pUser->pTimeWhiteList);
1,021,040✔
2310
  if (pNew->pTimeWhiteList == NULL) {
1,021,040✔
2311
    code = TSDB_CODE_OUT_OF_MEMORY;
×
2312
    goto _OVER;
×
2313
  }
2314

2315
_OVER:
1,021,040✔
2316
  taosRUnLockLatch(&pUser->lock);
1,021,040✔
2317
  if (code == 0) {
1,021,040✔
2318
    dropOldPasswords(pNew);
1,021,040✔
2319
  }
2320
  TAOS_RETURN(code);
1,021,040✔
2321
}
2322

2323
void mndUserFreeObj(SUserObj *pUser) {
5,092,101✔
2324
  taosHashCleanup(pUser->objPrivs);
5,092,101✔
2325
  taosHashCleanup(pUser->selectTbs);
5,092,101✔
2326
  taosHashCleanup(pUser->insertTbs);
5,092,101✔
2327
  taosHashCleanup(pUser->updateTbs);
5,092,101✔
2328
  taosHashCleanup(pUser->deleteTbs);
5,092,101✔
2329
  taosHashCleanup(pUser->roles);
5,092,101✔
2330
  taosMemoryFreeClear(pUser->passwords);
5,092,101✔
2331
  taosMemoryFreeClear(pUser->pIpWhiteListDual);
5,092,101✔
2332
  taosMemoryFreeClear(pUser->pTimeWhiteList);
5,092,101✔
2333
  pUser->objPrivs = NULL;
5,092,101✔
2334
  pUser->selectTbs = NULL;
5,092,101✔
2335
  pUser->insertTbs = NULL;
5,092,101✔
2336
  pUser->updateTbs = NULL;
5,092,101✔
2337
  pUser->deleteTbs = NULL;
5,092,101✔
2338
  pUser->roles = NULL;
5,092,101✔
2339
}
5,092,101✔
2340

2341
static int32_t mndUserActionDelete(SSdb *pSdb, SUserObj *pUser) {
1,505,379✔
2342
  mTrace("user:%s, perform delete action, row:%p", pUser->user, pUser);
1,505,379✔
2343
  mndUserFreeObj(pUser);
1,505,379✔
2344
  return 0;
1,505,379✔
2345
}
2346

2347
static int32_t mndUserActionUpdate(SSdb *pSdb, SUserObj *pOld, SUserObj *pNew) {
1,023,952✔
2348
  mTrace("user:%s, perform update action, old row:%p new row:%p", pOld->user, pOld, pNew);
1,023,952✔
2349
  taosWLockLatch(&pOld->lock);
1,023,952✔
2350
  pOld->updateTime = pNew->updateTime;
1,023,952✔
2351
  pOld->authVersion = pNew->authVersion;
1,023,952✔
2352
  pOld->passVersion = pNew->passVersion;
1,023,952✔
2353
  pOld->sysInfo = pNew->sysInfo;
1,023,952✔
2354
  pOld->enable = pNew->enable;
1,023,952✔
2355
  pOld->flag = pNew->flag;
1,023,952✔
2356
  pOld->changePass = pNew->changePass;
1,023,952✔
2357
  pOld->uid = pNew->uid;
1,023,952✔
2358

2359
  pOld->sessionPerUser = pNew->sessionPerUser;
1,023,952✔
2360
  pOld->connectTime = pNew->connectTime;
1,023,952✔
2361
  pOld->connectIdleTime = pNew->connectIdleTime;
1,023,952✔
2362
  pOld->callPerSession = pNew->callPerSession;
1,023,952✔
2363
  pOld->vnodePerCall = pNew->vnodePerCall;
1,023,952✔
2364
  pOld->failedLoginAttempts = pNew->failedLoginAttempts;
1,023,952✔
2365
  pOld->passwordLifeTime = pNew->passwordLifeTime;
1,023,952✔
2366
  pOld->passwordReuseTime = pNew->passwordReuseTime;
1,023,952✔
2367
  pOld->passwordReuseMax = pNew->passwordReuseMax;
1,023,952✔
2368
  pOld->passwordLockTime = pNew->passwordLockTime;
1,023,952✔
2369
  pOld->passwordGraceTime = pNew->passwordGraceTime;
1,023,952✔
2370
  pOld->inactiveAccountTime = pNew->inactiveAccountTime;
1,023,952✔
2371
  pOld->allowTokenNum = pNew->allowTokenNum;
1,023,952✔
2372
  pOld->tokenNum = pNew->tokenNum;
1,023,952✔
2373

2374
  pOld->numOfPasswords = pNew->numOfPasswords;
1,023,952✔
2375
  TSWAP(pOld->passwords, pNew->passwords);
1,023,952✔
2376
  (void)memcpy(pOld->salt, pNew->salt, sizeof(pOld->salt));
1,023,952✔
2377
  (void)memcpy(pOld->totpsecret, pNew->totpsecret, sizeof(pOld->totpsecret));
1,023,952✔
2378
  pOld->sysPrivs = pNew->sysPrivs;
1,023,952✔
2379
  TSWAP(pOld->objPrivs, pNew->objPrivs);
1,023,952✔
2380
  TSWAP(pOld->selectTbs, pNew->selectTbs);
1,023,952✔
2381
  TSWAP(pOld->insertTbs, pNew->insertTbs);
1,023,952✔
2382
  TSWAP(pOld->updateTbs, pNew->updateTbs);
1,023,952✔
2383
  TSWAP(pOld->deleteTbs, pNew->deleteTbs);
1,023,952✔
2384
  TSWAP(pOld->roles, pNew->roles);
1,023,952✔
2385

2386
  TSWAP(pOld->pIpWhiteListDual, pNew->pIpWhiteListDual);
1,023,952✔
2387
  pOld->ipWhiteListVer = pNew->ipWhiteListVer;
1,023,952✔
2388
  TSWAP(pOld->pTimeWhiteList, pNew->pTimeWhiteList);
1,023,952✔
2389
  pOld->timeWhiteListVer = pNew->timeWhiteListVer;
1,023,952✔
2390
  pOld->passEncryptAlgorithm = pNew->passEncryptAlgorithm;
1,023,952✔
2391

2392
  taosWUnLockLatch(&pOld->lock);
1,023,952✔
2393

2394
  return 0;
1,023,952✔
2395
}
2396

2397
int32_t mndAcquireUser(SMnode *pMnode, const char *userName, SUserObj **ppUser) {
83,358,978✔
2398
  int32_t code = 0;
83,358,978✔
2399
  SSdb   *pSdb = pMnode->pSdb;
83,358,978✔
2400

2401
  *ppUser = sdbAcquire(pSdb, SDB_USER, userName);
83,359,140✔
2402
  if (*ppUser == NULL) {
83,359,540✔
2403
    if (terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
61,418✔
2404
      code = TSDB_CODE_MND_USER_NOT_EXIST;
61,418✔
2405
    } else {
2406
      code = TSDB_CODE_MND_USER_NOT_AVAILABLE;
×
2407
    }
2408
  }
2409
  TAOS_RETURN(code);
83,359,835✔
2410
}
2411

2412
void mndReleaseUser(SMnode *pMnode, SUserObj *pUser) {
90,387,492✔
2413
  SSdb *pSdb = pMnode->pSdb;
90,387,492✔
2414
  sdbRelease(pSdb, pUser);
90,387,847✔
2415
}
90,387,847✔
2416

2417
int32_t mndAcquireUserById(SMnode *pMnode, int64_t userId, SUserObj **ppUser) {
×
2418
  void     *pIter = NULL;
×
2419
  SUserObj *pObj;
×
2420
  SSdb     *pSdb = pMnode->pSdb;
×
2421
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pObj))) {
×
2422
    if (pObj->uid == userId) {
×
2423
      return mndAcquireUser(pMnode, pObj->user, ppUser);
×
2424
    }
2425
  }
2426
  return 0;
×
2427
}
2428

2429
int32_t mndBuildUidNamesHash(SMnode *pMnode, SSHashObj **ppHash) {
476,213✔
2430
  int32_t    code = 0;
476,213✔
2431
  void      *pIter = NULL;
476,213✔
2432
  SUserObj  *pObj;
476,213✔
2433
  SSHashObj *pHash = NULL;
476,213✔
2434

2435
  int32_t nUser = sdbGetSize(pMnode->pSdb, SDB_USER);
476,213✔
2436

2437
  pHash = tSimpleHashInit(nUser, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT));
476,213✔
2438
  if (pHash == NULL) {
476,213✔
2439
    TAOS_RETURN(terrno);
×
2440
  }
2441

2442
  while ((pIter = sdbFetch(pMnode->pSdb, SDB_USER, pIter, (void **)&pObj))) {
1,123,122✔
2443
    code = tSimpleHashPut(pHash, &pObj->uid, sizeof(pObj->uid), pObj->name, strlen(pObj->name) + 1);
646,909✔
2444
    if (code != 0) {
646,909✔
2445
      sdbRelease(pMnode->pSdb, pObj);
×
2446
      sdbCancelFetch(pMnode->pSdb, pIter);
×
2447
      tSimpleHashCleanup(pHash);
×
2448
      TAOS_RETURN(code);
×
2449
    }
2450
    sdbRelease(pMnode->pSdb, pObj);
646,909✔
2451
  }
2452

2453
  *ppHash = pHash;
476,213✔
2454
  TAOS_RETURN(code);
476,213✔
2455
}
2456

2457
int32_t mndEncryptPass(char *pass, const char* salt, int8_t *algo) {
75,088✔
2458
  int32_t code = 0;
75,088✔
2459
  if (tsMetaKey[0] == '\0') {
75,088✔
2460
    return 0;
75,021✔
2461
  }
2462

2463
  if (salt[0] != 0) {
67✔
2464
    char passAndSalt[TSDB_PASSWORD_LEN - 1 + TSDB_PASSWORD_SALT_LEN];
67✔
2465
    (void)memcpy(passAndSalt, pass, TSDB_PASSWORD_LEN - 1);
67✔
2466
    (void)memcpy(passAndSalt + TSDB_PASSWORD_LEN - 1, salt, TSDB_PASSWORD_SALT_LEN);
67✔
2467
    taosEncryptPass_c((uint8_t *)passAndSalt, sizeof(passAndSalt), pass);
2468
  }
2469

2470
  unsigned char packetData[TSDB_PASSWORD_LEN] = {0};
67✔
2471
  SCryptOpts opts = {0};
67✔
2472
  opts.len = TSDB_PASSWORD_LEN;
67✔
2473
  opts.source = pass;
67✔
2474
  opts.result = packetData;
67✔
2475
  opts.unitLen = TSDB_PASSWORD_LEN;
67✔
2476
  tstrncpy(opts.key, tsDataKey, ENCRYPT_KEY_LEN + 1);
67✔
2477
  int newLen = Builtin_CBC_Encrypt(&opts);
67✔
2478
  if (newLen <= 0) return terrno;
67✔
2479

2480
  memcpy(pass, packetData, newLen);
67✔
2481
  if (algo != NULL) {
67✔
2482
    *algo = DND_CA_SM4;
67✔
2483
  }
2484

2485
  return 0;
67✔
2486
}
2487

2488

2489

2490
static void generateSalt(char *salt, size_t len) {
56,739✔
2491
  const char* set = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
56,739✔
2492
  int32_t     setLen = 62;
56,739✔
2493
  for (int32_t i = 0; i < len - 1; ++i) {
1,815,648✔
2494
    salt[i] = set[taosSafeRand() % setLen];
1,758,909✔
2495
  }
2496
  salt[len - 1] = 0;
56,739✔
2497
}
56,739✔
2498

2499

2500

2501
static int32_t addDefaultIpToTable(SHashObj *pUniqueTab) {
986✔
2502
  int32_t code = 0;
986✔
2503
  int32_t lino = 0;
986✔
2504
  int32_t dummy = 0;
986✔
2505

2506
  SIpRange ipv4 = {0}, ipv6 = {0};
986✔
2507
  code = createDefaultIp4Range(&ipv4);
986✔
2508
  TSDB_CHECK_CODE(code, lino, _error);
986✔
2509

2510
  code = taosHashPut(pUniqueTab, &ipv4, sizeof(ipv4), &dummy, sizeof(dummy));
986✔
2511
  TSDB_CHECK_CODE(code, lino, _error);
986✔
2512

2513
  code = createDefaultIp6Range(&ipv6);
986✔
2514
  TSDB_CHECK_CODE(code, lino, _error);
986✔
2515

2516
  code = taosHashPut(pUniqueTab, &ipv6, sizeof(ipv6), &dummy, sizeof(dummy));
986✔
2517
  TSDB_CHECK_CODE(code, lino, _error);
986✔
2518
    
2519
_error:
986✔
2520
  if (code != 0) {
986✔
2521
    mError("failed to add default ip range to table since %s", tstrerror(code));
×
2522
  }
2523
  return code;
986✔
2524
}
2525

2526
static int32_t mndCreateUser(SMnode *pMnode, char *acct, SCreateUserReq *pCreate, SRpcMsg *pReq) {
56,574✔
2527
  int32_t  code = 0;
56,574✔
2528
  int32_t  lino = 0;
56,574✔
2529
  SUserObj userObj = {0};
56,574✔
2530

2531
  userObj.passwords = taosMemoryCalloc(1, sizeof(SUserPassword));
56,574✔
2532
  if (userObj.passwords == NULL) {
56,574✔
2533
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2534
  }
2535
  userObj.numOfPasswords = 1;
56,574✔
2536

2537
  if (pCreate->isImport == 1) {
56,574✔
2538
    memset(userObj.salt, 0, sizeof(userObj.salt));
×
2539
    memcpy(userObj.passwords[0].pass, pCreate->pass, TSDB_PASSWORD_LEN);
×
2540
  } else {
2541
    generateSalt(userObj.salt, sizeof(userObj.salt));
56,574✔
2542
    taosEncryptPass_c((uint8_t *)pCreate->pass, strlen(pCreate->pass), userObj.passwords[0].pass);
56,574✔
2543
    userObj.passwords[0].pass[sizeof(userObj.passwords[0].pass) - 1] = 0;
56,574✔
2544
    TAOS_CHECK_GOTO(mndEncryptPass(userObj.passwords[0].pass, userObj.salt, &userObj.passEncryptAlgorithm), &lino, _OVER);
56,574✔
2545
  }
2546
  userObj.passwords[0].setTime = taosGetTimestampSec();
56,574✔
2547

2548
  tstrncpy(userObj.user, pCreate->user, TSDB_USER_LEN);
56,574✔
2549
  tstrncpy(userObj.acct, acct, TSDB_USER_LEN);
56,574✔
2550
  if (pCreate->totpseed[0] != 0) {
56,574✔
2551
    int len = taosGenerateTotpSecret(pCreate->totpseed, 0, userObj.totpsecret, sizeof(userObj.totpsecret));
×
2552
    if (len < 0) {
×
2553
      TAOS_CHECK_GOTO(TSDB_CODE_PAR_INVALID_OPTION_VALUE, &lino, _OVER);
×
2554
    }
2555
  }
2556

2557
  userObj.createdTime = taosGetTimestampMs();
56,574✔
2558
  userObj.updateTime = userObj.createdTime;
56,574✔
2559
  userObj.superUser = 0;  // pCreate->superUser;
56,574✔
2560
  userObj.sysInfo = pCreate->sysInfo;
56,574✔
2561
  userObj.enable = pCreate->enable;
56,574✔
2562
  userObj.createdb = pCreate->createDb;
56,574✔
2563
  userObj.uid = mndGenerateUid(userObj.user, strlen(userObj.user));
56,574✔
2564

2565
#ifdef TD_ENTERPRISE
2566

2567
  userObj.changePass = pCreate->changepass;
56,574✔
2568
  userObj.sessionPerUser = pCreate->sessionPerUser;
56,574✔
2569
  userObj.connectTime = pCreate->connectTime;
56,574✔
2570
  userObj.connectIdleTime = pCreate->connectIdleTime;
56,574✔
2571
  userObj.callPerSession = pCreate->callPerSession;
56,574✔
2572
  userObj.vnodePerCall = pCreate->vnodePerCall;
56,574✔
2573
  userObj.failedLoginAttempts = pCreate->failedLoginAttempts;
56,574✔
2574
  userObj.passwordLifeTime = pCreate->passwordLifeTime;
56,574✔
2575
  userObj.passwordReuseTime = pCreate->passwordReuseTime;
56,574✔
2576
  userObj.passwordReuseMax = pCreate->passwordReuseMax;
56,574✔
2577
  userObj.passwordLockTime = pCreate->passwordLockTime;
56,574✔
2578
  userObj.passwordGraceTime = pCreate->passwordGraceTime;
56,574✔
2579
  userObj.inactiveAccountTime = pCreate->inactiveAccountTime;
56,574✔
2580
  userObj.allowTokenNum = pCreate->allowTokenNum;
56,574✔
2581
  userObj.tokenNum = 0;
56,574✔
2582

2583
  if (pCreate->numIpRanges == 0) {
56,574✔
2584
    TAOS_CHECK_GOTO(createDefaultIpWhiteList(&userObj.pIpWhiteListDual), &lino, _OVER);
55,210✔
2585
  } else {
2586
    SHashObj *pUniqueTab = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
1,364✔
2587
    if (pUniqueTab == NULL) {
1,364✔
2588
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2589
    }
2590
    
2591
    bool hasPositive = false;
1,364✔
2592
    for (int i = 0; i < pCreate->numIpRanges; i++) {
3,424✔
2593
      SIpRange range = {0};
2,060✔
2594
      copyIpRange(&range, pCreate->pIpDualRanges + i);
2,060✔
2595
      hasPositive = hasPositive || !range.neg;
2,060✔
2596
      int32_t dummy = 0;
2,060✔
2597
      if ((code = taosHashPut(pUniqueTab, &range, sizeof(range), &dummy, sizeof(dummy))) != 0) {
2,060✔
2598
        taosHashCleanup(pUniqueTab);
×
2599
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2600
      }
2601
    }
2602

2603
    // add local ip if there is any positive range
2604
    if (hasPositive) {
1,364✔
2605
      code = addDefaultIpToTable(pUniqueTab);
986✔
2606
      if (code != 0) {
986✔
2607
        taosHashCleanup(pUniqueTab);
×
2608
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2609
      }
2610
    }
2611

2612
    if (taosHashGetSize(pUniqueTab) > MND_MAX_USER_IP_RANGE) {
1,364✔
2613
      taosHashCleanup(pUniqueTab);
×
2614
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_IP_RANGE, &lino, _OVER);
×
2615
    }
2616

2617
    int32_t           numOfRanges = taosHashGetSize(pUniqueTab);
1,364✔
2618
    SIpWhiteListDual *p = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + numOfRanges * sizeof(SIpRange));
1,364✔
2619
    if (p == NULL) {
1,364✔
2620
      taosHashCleanup(pUniqueTab);
×
2621
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2622
    }
2623

2624
    void   *pIter = taosHashIterate(pUniqueTab, NULL);
1,364✔
2625
    for (int32_t i = 0; i < numOfRanges; i++) {
5,073✔
2626
      size_t    len = 0;
3,709✔
2627
      SIpRange *key = taosHashGetKey(pIter, &len);
3,709✔
2628
      memcpy(&p->pIpRanges[i], key, sizeof(SIpRange));
3,709✔
2629
      pIter = taosHashIterate(pUniqueTab, pIter);
3,709✔
2630
    }
2631

2632
    taosHashCleanup(pUniqueTab);
1,364✔
2633
    p->num = numOfRanges;
1,364✔
2634
    sortIpWhiteList(p);
1,364✔
2635
    userObj.pIpWhiteListDual = p;
1,364✔
2636
  }
2637

2638
  if (pCreate->numTimeRanges == 0) {
56,574✔
2639
    userObj.pTimeWhiteList = (SDateTimeWhiteList*)taosMemoryCalloc(1, sizeof(SDateTimeWhiteList));
54,936✔
2640
    if (userObj.pTimeWhiteList == NULL) {
54,936✔
2641
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2642
    }
2643
  } else {
2644
    SHashObj *pUniqueTab = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
1,638✔
2645
    if (pUniqueTab == NULL) {
1,638✔
2646
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2647
    }
2648
    
2649
    for (int i = 0; i < pCreate->numTimeRanges; i++) {
3,654✔
2650
      SDateTimeRange* src = pCreate->pTimeRanges + i;
2,016✔
2651
      SDateTimeWhiteListItem range = {0};
2,016✔
2652
      DateTimeRangeToWhiteListItem(&range, src);
2,016✔
2653

2654
      // no need to add expired range
2655
      if (isDateTimeWhiteListItemExpired(&range)) {
2,016✔
2656
        continue;
252✔
2657
      }
2658

2659
      int32_t dummy = 0;
1,764✔
2660
      if ((code = taosHashPut(pUniqueTab, &range, sizeof(range), &dummy, sizeof(dummy))) != 0) {
1,764✔
2661
        taosHashCleanup(pUniqueTab);
×
2662
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2663
      }
2664
    }
2665

2666
    if (taosHashGetSize(pUniqueTab) > MND_MAX_USER_TIME_RANGE) {
1,638✔
2667
      taosHashCleanup(pUniqueTab);
×
2668
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_TIME_RANGE, &lino, _OVER);
×
2669
    }
2670

2671
    int32_t           numOfRanges = taosHashGetSize(pUniqueTab);
1,638✔
2672
    SDateTimeWhiteList *p = taosMemoryCalloc(1, sizeof(SDateTimeWhiteList) + numOfRanges * sizeof(SDateTimeWhiteListItem));
1,638✔
2673
    if (p == NULL) {
1,638✔
2674
      taosHashCleanup(pUniqueTab);
×
2675
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2676
    }
2677

2678
    void   *pIter = taosHashIterate(pUniqueTab, NULL);
1,638✔
2679
    for (int32_t i = 0; i < numOfRanges; i++) {
3,402✔
2680
      size_t    len = 0;
1,764✔
2681
      SDateTimeWhiteListItem *key = taosHashGetKey(pIter, &len);
1,764✔
2682
      memcpy(p->ranges + i, key, sizeof(SDateTimeWhiteListItem));
1,764✔
2683
      pIter = taosHashIterate(pUniqueTab, pIter);
1,764✔
2684
    }
2685

2686
    taosHashCleanup(pUniqueTab);
1,638✔
2687
    p->num = numOfRanges;
1,638✔
2688
    sortTimeWhiteList(p);
1,638✔
2689
    userObj.pTimeWhiteList = p;
1,638✔
2690
  }
2691

2692
  userObj.ipWhiteListVer = taosGetTimestampMs();
56,574✔
2693
  userObj.timeWhiteListVer = userObj.ipWhiteListVer;
56,574✔
2694

2695
#else // TD_ENTERPRISE
2696

2697
  userObj.changePass = 1;
2698
  userObj.sessionPerUser = -1;
2699
  userObj.connectTime = -1;
2700
  userObj.connectIdleTime = -1;
2701
  userObj.callPerSession = -1;
2702
  userObj.vnodePerCall = -1;
2703
  userObj.failedLoginAttempts = -1;
2704
  userObj.passwordLifeTime = -1;
2705
  userObj.passwordReuseTime = 0;
2706
  userObj.passwordReuseMax = 0;
2707
  userObj.passwordLockTime = -1;
2708
  userObj.passwordGraceTime = -1;
2709
  userObj.inactiveAccountTime = -1;
2710
  userObj.allowTokenNum = -1;
2711
  userObj.tokenNum = 0;
2712

2713
  TAOS_CHECK_GOTO(createDefaultIpWhiteList(&userObj.pIpWhiteListDual), &lino, _OVER);
2714
  userObj.pTimeWhiteList = (SDateTimeWhiteList*)taosMemoryCalloc(1, sizeof(SDateTimeWhiteList));
2715
  if (userObj.pTimeWhiteList == NULL) {
2716
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
2717
  }
2718

2719
  userObj.ipWhiteListVer = 0;
2720
  userObj.timeWhiteListVer = 0;
2721

2722
#endif // TD_ENTERPRISE
2723

2724
  userObj.roles = taosHashInit(1, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
56,574✔
2725
  if (userObj.roles == NULL) {
56,574✔
2726
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2727
  }
2728

2729
  if ((code = taosHashPut(userObj.roles, TSDB_ROLE_SYSINFO_1, strlen(TSDB_ROLE_SYSINFO_1) + 1, NULL, 0)) != 0) {
56,574✔
2730
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2731
  }
2732

2733
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "create-user");
56,574✔
2734
  if (pTrans == NULL) {
56,574✔
2735
    mError("user:%s, failed to create since %s", pCreate->user, terrstr());
×
2736
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2737
  }
2738
  mInfo("trans:%d, used to create user:%s", pTrans->id, pCreate->user);
56,574✔
2739

2740
  SSdbRaw *pCommitRaw = mndUserActionEncode(&userObj);
56,574✔
2741
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
56,574✔
2742
    mError("trans:%d, failed to commit redo log since %s", pTrans->id, terrstr());
×
2743
    mndTransDrop(pTrans);
×
2744
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2745
  }
2746
  TAOS_CHECK_GOTO(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY), &lino, _OVER);
56,574✔
2747

2748
  if (mndTransPrepare(pMnode, pTrans) != 0) {
56,574✔
2749
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
2750
    mndTransDrop(pTrans);
×
2751
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2752
  }
2753

2754
  if ((code = userCacheUpdateWhiteList(pMnode, &userObj)) != 0) {
56,574✔
2755
    mndTransDrop(pTrans);
×
2756
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2757
  }
2758

2759
  mndTransDrop(pTrans);
56,574✔
2760

2761
_OVER:
56,574✔
2762
  mndUserFreeObj(&userObj);
56,574✔
2763
  TAOS_RETURN(code);
56,574✔
2764
}
2765

2766

2767
static int32_t mndCheckPasswordFmt(const char *pwd) {
75,088✔
2768
  if (tsEnableStrongPassword == 0) {
75,088✔
2769
    for (char c = *pwd; c != 0; c = *(++pwd)) {
44,936✔
2770
      if (c == ' ' || c == '\'' || c == '\"' || c == '`' || c == '\\') {
44,444✔
2771
        return TSDB_CODE_MND_INVALID_PASS_FORMAT;
×
2772
      }
2773
    }
2774
    return 0;
492✔
2775
  }
2776

2777
  int32_t len = strlen(pwd);
74,596✔
2778
  if (len < TSDB_PASSWORD_MIN_LEN) {
74,596✔
2779
    return TSDB_CODE_PAR_PASSWD_TOO_SHORT_OR_EMPTY;
×
2780
  }
2781

2782
  if (len > TSDB_PASSWORD_MAX_LEN) {
74,596✔
2783
    return TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG;
×
2784
  }
2785

2786
  if (taosIsComplexString(pwd)) {
74,596✔
2787
    return 0;
74,596✔
2788
  }
2789

2790
  return TSDB_CODE_MND_INVALID_PASS_FORMAT;
×
2791
}
2792

2793

2794

2795
static int32_t mndCheckTotpSeedFmt(const char *seed) {
×
2796
  int32_t len = strlen(seed);
×
2797
  if (len < TSDB_USER_TOTPSEED_MIN_LEN) {
×
2798
    return TSDB_CODE_PAR_OPTION_VALUE_TOO_SHORT;
×
2799
  }
2800

2801
  if (taosIsComplexString(seed)) {
×
2802
    return 0;
×
2803
  }
2804

2805
  return TSDB_CODE_PAR_INVALID_OPTION_VALUE;
×
2806
}
2807

2808

2809

2810
static int32_t mndProcessGetUserDateTimeWhiteListReq(SRpcMsg *pReq) {
×
2811
  SMnode              *pMnode = pReq->info.node;
×
2812
  int32_t              code = 0;
×
2813
  int32_t              lino = 0;
×
2814
  int32_t              contLen = 0;
×
2815
  void                *pRsp = NULL;
×
2816
  SUserObj            *pUser = NULL;
×
2817
  SGetUserWhiteListReq wlReq = {0};
×
2818
  SUserDateTimeWhiteList wlRsp = {0};
×
2819

2820
  if (tDeserializeSGetUserWhiteListReq(pReq->pCont, pReq->contLen, &wlReq) != 0) {
×
2821
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
2822
  }
2823
  mTrace("user: %s, start to get date time whitelist", wlReq.user);
×
2824

2825
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, wlReq.user, &pUser), &lino, _OVER);
×
2826
  TAOS_CHECK_GOTO(mndSetUserDateTimeWhiteListRsp(pMnode, pUser, &wlRsp), &lino, _OVER);
×
2827

2828
  contLen = tSerializeSUserDateTimeWhiteList(NULL, 0, &wlRsp);
×
2829
  if (contLen < 0) {
×
2830
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2831
  }
2832
  pRsp = rpcMallocCont(contLen);
×
2833
  if (pRsp == NULL) {
×
2834
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2835
  }
2836
  
2837
  contLen = tSerializeSUserDateTimeWhiteList(pRsp, contLen, &wlRsp);
×
2838
  if (contLen < 0) {
×
2839
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2840
  }
2841

2842
_OVER:
×
2843
  mndReleaseUser(pMnode, pUser);
×
2844
  tFreeSUserDateTimeWhiteList(&wlRsp);
×
2845
  if (code < 0) {
×
2846
    mError("user:%s, failed to get whitelist at line %d since %s", wlReq.user, lino, tstrerror(code));
×
2847
    rpcFreeCont(pRsp);
×
2848
    pRsp = NULL;
×
2849
    contLen = 0;
×
2850
  }
2851
  pReq->code = code;
×
2852
  pReq->info.rsp = pRsp;
×
2853
  pReq->info.rspLen = contLen;
×
2854

2855
  TAOS_RETURN(code);
×
2856
  return 0;
2857
}
2858

2859

2860

2861
static int32_t buildRetrieveDateTimeWhiteListRsp(SRetrieveDateTimeWhiteListRsp *pRsp) {
462✔
2862
  (void)taosThreadRwlockRdlock(&userCache.rw);
462✔
2863
  
2864
  int32_t count = taosHashGetSize(userCache.users);
462✔
2865
  pRsp->pUsers = taosMemoryCalloc(count, sizeof(SUserDateTimeWhiteList));
462✔
2866
  if (pRsp->pUsers == NULL) {
462✔
2867
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
2868
    TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
2869
  }
2870

2871
  count = 0;
462✔
2872
  void   *pIter = taosHashIterate(userCache.users, NULL);
462✔
2873
  while (pIter) {
924✔
2874
    SDateTimeWhiteList *wl = (*(SCachedUserInfo **)pIter)->wlTime;
462✔
2875
    if (wl == NULL || wl->num <= 0) {
462✔
2876
      pIter = taosHashIterate(userCache.users, pIter);
462✔
2877
      continue;
462✔
2878
    }
2879

2880
    SUserDateTimeWhiteList *pUser = &pRsp->pUsers[count];
×
2881
    pUser->ver = userCache.verTime;
×
2882

2883
    size_t klen;
×
2884
    char  *key = taosHashGetKey(pIter, &klen);
×
2885
    (void)memcpy(pUser->user, key, klen);
×
2886

2887
    pUser->numWhiteLists = wl->num;
×
2888
    pUser->pWhiteLists = taosMemoryCalloc(wl->num, sizeof(SDateTimeWhiteListItem));
×
2889
    if (pUser->pWhiteLists == NULL) {
×
2890
      (void)taosThreadRwlockUnlock(&userCache.rw);
×
2891
      TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
2892
    }
2893

2894
    (void)memcpy(pUser->pWhiteLists, wl->ranges, wl->num * sizeof(SDateTimeWhiteListItem));
×
2895
    count++;
×
2896
    pIter = taosHashIterate(userCache.users, pIter);
×
2897
  }
2898

2899
  pRsp->numOfUser = count;
462✔
2900
  pRsp->ver = userCache.verTime;
462✔
2901
  (void)taosThreadRwlockUnlock(&userCache.rw);
462✔
2902
  TAOS_RETURN(0);
462✔
2903
}
2904

2905

2906

2907
static int32_t mndProcessRetrieveDateTimeWhiteListReq(SRpcMsg *pReq) {
462✔
2908
  int32_t        code = 0;
462✔
2909
  int32_t        lino = 0;
462✔
2910
  int32_t        len = 0;
462✔
2911
  void          *pRsp = NULL;
462✔
2912
  SRetrieveDateTimeWhiteListRsp wlRsp = {0};
462✔
2913

2914
  // impl later
2915
  SRetrieveWhiteListReq req = {0};
462✔
2916
  if (tDeserializeRetrieveWhiteListReq(pReq->pCont, pReq->contLen, &req) != 0) {
462✔
2917
    code = TSDB_CODE_INVALID_MSG;
×
2918
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2919
  }
2920

2921
  TAOS_CHECK_GOTO(buildRetrieveDateTimeWhiteListRsp(&wlRsp), &lino, _OVER);
462✔
2922

2923
  len = tSerializeSRetrieveDateTimeWhiteListRsp(NULL, 0, &wlRsp);
462✔
2924
  if (len < 0) {
462✔
2925
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
2926
  }
2927

2928
  pRsp = rpcMallocCont(len);
462✔
2929
  if (!pRsp) {
462✔
2930
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2931
  }
2932
  len = tSerializeSRetrieveDateTimeWhiteListRsp(pRsp, len, &wlRsp);
462✔
2933
  if (len < 0) {
462✔
2934
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
2935
  }
2936

2937
_OVER:
462✔
2938
  if (code < 0) {
462✔
2939
    mError("failed to process retrieve ip white request at line %d since %s", lino, tstrerror(code));
×
2940
    rpcFreeCont(pRsp);
×
2941
    pRsp = NULL;
×
2942
    len = 0;
×
2943
  }
2944
  pReq->code = code;
462✔
2945
  pReq->info.rsp = pRsp;
462✔
2946
  pReq->info.rspLen = len;
462✔
2947

2948
  tFreeSRetrieveDateTimeWhiteListRsp(&wlRsp);
462✔
2949
  TAOS_RETURN(code);
462✔
2950
}
2951

2952

2953

2954
static int32_t mndProcessCreateUserReq(SRpcMsg *pReq) {
56,574✔
2955
  SMnode        *pMnode = pReq->info.node;
56,574✔
2956
  int32_t        code = 0;
56,574✔
2957
  int32_t        lino = 0;
56,574✔
2958
  SRoleObj      *pRole = NULL;
56,574✔
2959
  SUserObj      *pUser = NULL;
56,574✔
2960
  SUserObj      *pOperUser = NULL;
56,574✔
2961
  SCreateUserReq createReq = {0};
56,574✔
2962
  int64_t        tss = taosGetTimestampMs();
56,574✔
2963

2964
  if (tDeserializeSCreateUserReq(pReq->pCont, pReq->contLen, &createReq) != 0) {
56,574✔
2965
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
2966
  }
2967

2968
  mInfo("user:%s, start to create, createdb:%d, is_import:%d", createReq.user, createReq.createDb, createReq.isImport);
56,574✔
2969

2970
#ifndef TD_ENTERPRISE
2971
  if (createReq.isImport == 1) {
2972
    TAOS_CHECK_GOTO(TSDB_CODE_OPS_NOT_SUPPORT, &lino, _OVER);  // enterprise feature
2973
  }
2974
#endif
2975
  code = mndAcquireUser(pMnode, RPC_MSG_USER(pReq), &pOperUser);
56,574✔
2976
  if (pOperUser == NULL) {
56,574✔
2977
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_USER_FROM_CONN, &lino, _OVER);
×
2978
  }
2979

2980
  if (createReq.isImport != 1) {
56,574✔
2981
    // TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, RPC_MSG_USER(pReq), MND_OPER_CREATE_USER), &lino, _OVER);
2982
    TAOS_CHECK_GOTO(mndCheckSysObjPrivilege(pMnode, pOperUser, PRIV_USER_CREATE, 0, 0, NULL, NULL), &lino, _OVER);
56,574✔
2983
  } else if (strcmp(RPC_MSG_USER(pReq), "root") != 0) {
×
2984
    mError("The operation is not permitted to create user:%s", RPC_MSG_USER(pReq));
×
2985
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_RIGHTS, &lino, _OVER);
×
2986
  }
2987

2988
  if (createReq.user[0] == 0) {
56,574✔
2989
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
2990
  }
2991

2992
  if (createReq.isImport != 1) {
56,574✔
2993
    code = mndCheckPasswordFmt(createReq.pass);
56,574✔
2994
    TAOS_CHECK_GOTO(code, &lino, _OVER);
56,574✔
2995
  }
2996

2997
  if (createReq.totpseed[0] != 0) {
56,574✔
2998
    code = mndCheckTotpSeedFmt(createReq.totpseed);
×
2999
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3000
  }
3001

3002
  code = mndAcquireUser(pMnode, createReq.user, &pUser);
56,574✔
3003
  if (pUser != NULL) {
56,574✔
3004
    TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_ALREADY_EXIST, &lino, _OVER);
×
3005
  }
3006

3007
  code = mndAcquireRole(pMnode, createReq.user, &pRole);
56,574✔
3008
  if (pRole != NULL) {
56,574✔
3009
    TAOS_CHECK_GOTO(TSDB_CODE_MND_ROLE_ALREADY_EXIST, &lino, _OVER);
×
3010
  }
3011

3012
  TAOS_CHECK_GOTO(grantCheck(TSDB_GRANT_USER), &lino, _OVER);
56,574✔
3013

3014
  code = mndCreateUser(pMnode, pOperUser->acct, &createReq, pReq);
56,574✔
3015
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
56,574✔
3016

3017
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
56,574✔
3018
    char detail[1000] = {0};
56,574✔
3019
    (void)tsnprintf(detail, sizeof(detail), "enable:%d, superUser:%d, sysInfo:%d, password:xxx", createReq.enable,
56,574✔
3020
                    createReq.superUser, createReq.sysInfo);
56,574✔
3021
    char operation[15] = {0};
56,574✔
3022
    if (createReq.isImport == 1) {
56,574✔
3023
      tstrncpy(operation, "importUser", sizeof(operation));
×
3024
    } else {
3025
      tstrncpy(operation, "createUser", sizeof(operation));
56,574✔
3026
    }
3027

3028
    int64_t tse = taosGetTimestampMs();
56,574✔
3029
    double  duration = (double)(tse - tss);
56,574✔
3030
    duration = duration / 1000;
56,574✔
3031
    auditRecord(pReq, pMnode->clusterId, operation, "", createReq.user, detail, strlen(detail), duration, 0);
56,574✔
3032
  }
3033

3034
_OVER:
56,574✔
3035
  if (code == TSDB_CODE_MND_USER_ALREADY_EXIST && createReq.ignoreExists) {
56,574✔
3036
    code = 0;
×
3037
  } else if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
56,574✔
3038
    mError("user:%s, failed to create at line %d since %s", createReq.user, lino, tstrerror(code));
×
3039
  }
3040

3041
  mndReleaseRole(pMnode, pRole);
56,574✔
3042
  mndReleaseUser(pMnode, pUser);
56,574✔
3043
  mndReleaseUser(pMnode, pOperUser);
56,574✔
3044
  tFreeSCreateUserReq(&createReq);
56,574✔
3045

3046
  TAOS_RETURN(code);
56,574✔
3047
}
3048

3049

3050

3051
static int32_t mndProcessGetUserIpWhiteListReq(SRpcMsg *pReq) {
9,304✔
3052
  SMnode              *pMnode = pReq->info.node;
9,304✔
3053
  int32_t              code = 0;
9,304✔
3054
  int32_t              lino = 0;
9,304✔
3055
  int32_t              contLen = 0;
9,304✔
3056
  void                *pRsp = NULL;
9,304✔
3057
  SUserObj            *pUser = NULL;
9,304✔
3058
  SGetUserWhiteListReq wlReq = {0};
9,304✔
3059
  SGetUserIpWhiteListRsp wlRsp = {0};
9,304✔
3060

3061
  int32_t (*serialFn)(void *, int32_t, SGetUserIpWhiteListRsp *) = NULL;
9,304✔
3062
  int32_t (*setRspFn)(SMnode * pMnode, SUserObj * pUser, SGetUserIpWhiteListRsp * pRsp) = NULL;
9,304✔
3063

3064
  if (pReq->msgType == TDMT_MND_GET_USER_IP_WHITELIST_DUAL) {
9,304✔
3065
    serialFn = tSerializeSGetUserIpWhiteListDualRsp;
9,304✔
3066
    setRspFn = mndSetUserIpWhiteListDualRsp;
9,304✔
3067
  } else {
3068
    serialFn = tSerializeSGetUserIpWhiteListRsp;
×
3069
    setRspFn = mndSetUserIpWhiteListRsp;
×
3070
  }
3071
  if (tDeserializeSGetUserWhiteListReq(pReq->pCont, pReq->contLen, &wlReq) != 0) {
9,304✔
3072
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
3073
  }
3074
  mTrace("user: %s, start to get ip whitelist", wlReq.user);
9,304✔
3075

3076
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, wlReq.user, &pUser), &lino, _OVER);
9,304✔
3077
  TAOS_CHECK_GOTO(setRspFn(pMnode, pUser, &wlRsp), &lino, _OVER);
9,304✔
3078

3079
  contLen = serialFn(NULL, 0, &wlRsp);
9,304✔
3080
  if (contLen < 0) {
9,304✔
3081
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3082
  }
3083
  pRsp = rpcMallocCont(contLen);
9,304✔
3084
  if (pRsp == NULL) {
9,304✔
3085
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3086
  }
3087

3088
  contLen = serialFn(pRsp, contLen, &wlRsp);
9,304✔
3089
  if (contLen < 0) {
9,304✔
3090
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3091
  }
3092

3093
_OVER:
9,304✔
3094
  mndReleaseUser(pMnode, pUser);
9,304✔
3095
  tFreeSGetUserIpWhiteListDualRsp(&wlRsp);
9,304✔
3096
  if (code < 0) {
9,304✔
3097
    mError("user:%s, failed to get whitelist at line %d since %s", wlReq.user, lino, tstrerror(code));
×
3098
    rpcFreeCont(pRsp);
×
3099
    pRsp = NULL;
×
3100
    contLen = 0;
×
3101
  }
3102
  pReq->code = code;
9,304✔
3103
  pReq->info.rsp = pRsp;
9,304✔
3104
  pReq->info.rspLen = contLen;
9,304✔
3105

3106
  TAOS_RETURN(code);
9,304✔
3107
}
3108

3109

3110

3111
static int32_t buildRetrieveIpWhiteListRsp(SUpdateIpWhite *pUpdate) {
462✔
3112
  (void)taosThreadRwlockRdlock(&userCache.rw);
462✔
3113

3114
  int32_t count = taosHashGetSize(userCache.users);
462✔
3115
  pUpdate->pUserIpWhite = taosMemoryCalloc(count, sizeof(SUpdateUserIpWhite));
462✔
3116
  if (pUpdate->pUserIpWhite == NULL) {
462✔
3117
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
3118
    TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
3119
  }
3120

3121
  count = 0;
462✔
3122
  void   *pIter = taosHashIterate(userCache.users, NULL);
462✔
3123
  while (pIter) {
924✔
3124
    SIpWhiteListDual   *wl = (*(SCachedUserInfo**)pIter)->wlIp;
462✔
3125
    if (wl == NULL || wl->num <= 0) {
462✔
3126
      pIter = taosHashIterate(userCache.users, pIter);
×
3127
      continue;
×
3128
    }
3129

3130
    SUpdateUserIpWhite *pUser = &pUpdate->pUserIpWhite[count];
462✔
3131
    pUser->ver = userCache.verIp;
462✔
3132

3133
    size_t klen;
462✔
3134
    char  *key = taosHashGetKey(pIter, &klen);
462✔
3135
    (void)memcpy(pUser->user, key, klen);
462✔
3136

3137
    pUser->numOfRange = wl->num;
462✔
3138
    pUser->pIpRanges = taosMemoryCalloc(wl->num, sizeof(SIpRange));
462✔
3139
    if (pUser->pIpRanges == NULL) {
462✔
3140
      (void)taosThreadRwlockUnlock(&userCache.rw);
×
3141
      TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
3142
    }
3143

3144
    (void)memcpy(pUser->pIpRanges, wl->pIpRanges, wl->num * sizeof(SIpRange));
462✔
3145
    count++;
462✔
3146
    pIter = taosHashIterate(userCache.users, pIter);
462✔
3147
  }
3148

3149
  pUpdate->numOfUser = count;
462✔
3150
  pUpdate->ver = userCache.verIp;
462✔
3151
  (void)taosThreadRwlockUnlock(&userCache.rw);
462✔
3152
  TAOS_RETURN(0);
462✔
3153
}
3154

3155

3156

3157
int32_t mndProcessRetrieveIpWhiteListReq(SRpcMsg *pReq) {
462✔
3158
  int32_t        code = 0;
462✔
3159
  int32_t        lino = 0;
462✔
3160
  int32_t        len = 0;
462✔
3161
  void          *pRsp = NULL;
462✔
3162
  SUpdateIpWhite ipWhite = {0};
462✔
3163

3164
  // impl later
3165
  SRetrieveWhiteListReq req = {0};
462✔
3166
  if (tDeserializeRetrieveWhiteListReq(pReq->pCont, pReq->contLen, &req) != 0) {
462✔
3167
    code = TSDB_CODE_INVALID_MSG;
×
3168
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3169
  }
3170

3171
  int32_t (*fn)(void *, int32_t, SUpdateIpWhite *) = NULL;
462✔
3172
  if (pReq->msgType == TDMT_MND_RETRIEVE_IP_WHITELIST) {
462✔
3173
    fn = tSerializeSUpdateIpWhite;
×
3174
  } else if (pReq->msgType == TDMT_MND_RETRIEVE_IP_WHITELIST_DUAL) {
462✔
3175
    fn = tSerializeSUpdateIpWhiteDual;
462✔
3176
  }
3177

3178
  TAOS_CHECK_GOTO(buildRetrieveIpWhiteListRsp(&ipWhite), &lino, _OVER);
462✔
3179

3180
  len = fn(NULL, 0, &ipWhite);
462✔
3181
  if (len < 0) {
462✔
3182
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
3183
  }
3184

3185
  pRsp = rpcMallocCont(len);
462✔
3186
  if (!pRsp) {
462✔
3187
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3188
  }
3189
  len = fn(pRsp, len, &ipWhite);
462✔
3190
  if (len < 0) {
462✔
3191
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
3192
  }
3193

3194
_OVER:
462✔
3195
  if (code < 0) {
462✔
3196
    mError("failed to process retrieve ip white request at line %d since %s", lino, tstrerror(code));
×
3197
    rpcFreeCont(pRsp);
×
3198
    pRsp = NULL;
×
3199
    len = 0;
×
3200
  }
3201
  pReq->code = code;
462✔
3202
  pReq->info.rsp = pRsp;
462✔
3203
  pReq->info.rspLen = len;
462✔
3204

3205
  tFreeSUpdateIpWhiteReq(&ipWhite);
462✔
3206
  TAOS_RETURN(code);
462✔
3207
}
3208

3209
static int32_t mndAlterUser(SMnode *pMnode, SUserObj *pNew, SRpcMsg *pReq) {
985,723✔
3210
  int32_t code = 0, lino = 0;
985,723✔
3211
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "alter-user");
985,723✔
3212
  if (pTrans == NULL) {
985,723✔
3213
    mError("user:%s, failed to alter since %s", pNew->user, terrstr());
×
3214
    TAOS_RETURN(terrno);
×
3215
  }
3216
  mInfo("trans:%d, used to alter user:%s", pTrans->id, pNew->user);
985,723✔
3217

3218
  SSdbRaw *pCommitRaw = mndUserActionEncode(pNew);
985,723✔
3219
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
985,723✔
3220
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
3221
    mndTransDrop(pTrans);
×
3222
    TAOS_RETURN(terrno);
×
3223
  }
3224
  TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
985,723✔
3225

3226
  if (mndTransPrepare(pMnode, pTrans) != 0) {
985,723✔
3227
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
3228
    mndTransDrop(pTrans);
×
3229
    TAOS_RETURN(terrno);
×
3230
  }
3231
  if ((code = userCacheUpdateWhiteList(pMnode, pNew)) != 0) {
985,723✔
3232
    mndTransDrop(pTrans);
×
3233
    TAOS_RETURN(code);
×
3234
  }
3235
_exit:
985,723✔
3236
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
985,723✔
3237
    mError("user:%s, failed to alter at line %d since %s", pNew->user, lino, tstrerror(code));
×
3238
  }
3239
  mndTransDrop(pTrans);
985,723✔
3240
  TAOS_RETURN(code);
985,723✔
3241
}
3242

3243
static int32_t mndDupObjHash(SHashObj *pOld, int32_t dataLen, SHashObj **ppNew) {
×
3244
  int32_t code = 0;
×
3245

3246
  *ppNew =
×
3247
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
3248
  if (*ppNew == NULL) {
×
3249
    code = terrno ? terrno : TSDB_CODE_OUT_OF_MEMORY;
×
3250
    TAOS_RETURN(code);
×
3251
  }
3252

3253
  char *db = taosHashIterate(pOld, NULL);
×
3254
  while (db != NULL) {
×
3255
    int32_t len = strlen(db) + 1;
×
3256
    if ((code = taosHashPut(*ppNew, db, len, db, dataLen)) != 0) {
×
3257
      taosHashCancelIterate(pOld, db);
×
3258
      taosHashCleanup(*ppNew);
×
3259
      TAOS_RETURN(code);
×
3260
    }
3261
    db = taosHashIterate(pOld, db);
×
3262
  }
3263

3264
  TAOS_RETURN(code);
×
3265
}
3266

3267
int32_t mndDupDbHash(SHashObj *pOld, SHashObj **ppNew) { return mndDupObjHash(pOld, TSDB_DB_FNAME_LEN, ppNew); }
×
3268

3269
int32_t mndDupTopicHash(SHashObj *pOld, SHashObj **ppNew) { return mndDupObjHash(pOld, TSDB_TOPIC_FNAME_LEN, ppNew); }
×
3270

3271
static int32_t mndTablePriviledge(SMnode *pMnode, SHashObj *hash, SHashObj *useDbHash, SAlterUserReq *alterReq,
×
3272
                                  SSdb *pSdb) {
3273
  void *pIter = NULL;
×
3274
  char  tbFName[TSDB_TABLE_FNAME_LEN] = {0};
×
3275

3276
  (void)snprintf(tbFName, sizeof(tbFName), "%s.%s", alterReq->objname, alterReq->tabName);
×
3277
  int32_t len = strlen(tbFName) + 1;
×
3278

3279
  if (alterReq->tagCond != NULL && alterReq->tagCondLen != 0) {
×
3280
    char *value = taosHashGet(hash, tbFName, len);
×
3281
    if (value != NULL) {
×
3282
      TAOS_RETURN(TSDB_CODE_MND_PRIVILEGE_EXIST);
×
3283
    }
3284

3285
    int32_t condLen = alterReq->tagCondLen;
×
3286
    TAOS_CHECK_RETURN(taosHashPut(hash, tbFName, len, alterReq->tagCond, condLen));
×
3287
  } else {
3288
    TAOS_CHECK_RETURN(taosHashPut(hash, tbFName, len, alterReq->isView ? "v" : "t", 2));
×
3289
  }
3290

3291
  int32_t  dbKeyLen = strlen(alterReq->objname) + 1;
×
3292
  int32_t  ref = 1;
×
3293
  int32_t *currRef = taosHashGet(useDbHash, alterReq->objname, dbKeyLen);
×
3294
  if (NULL != currRef) {
×
3295
    ref = (*currRef) + 1;
×
3296
  }
3297
  TAOS_CHECK_RETURN(taosHashPut(useDbHash, alterReq->objname, dbKeyLen, &ref, sizeof(ref)));
×
3298

3299
  TAOS_RETURN(0);
×
3300
}
3301

3302
static int32_t mndRemoveTablePriviledge(SMnode *pMnode, SHashObj *hash, SHashObj *useDbHash, SAlterUserReq *alterReq,
×
3303
                                        SSdb *pSdb) {
3304
  void *pIter = NULL;
×
3305
  char  tbFName[TSDB_TABLE_FNAME_LEN] = {0};
×
3306
  (void)snprintf(tbFName, sizeof(tbFName), "%s.%s", alterReq->objname, alterReq->tabName);
×
3307
  int32_t len = strlen(tbFName) + 1;
×
3308

3309
  if (taosHashRemove(hash, tbFName, len) != 0) {
×
3310
    TAOS_RETURN(0);  // not found
×
3311
  }
3312

3313
  int32_t  dbKeyLen = strlen(alterReq->objname) + 1;
×
3314
  int32_t *currRef = taosHashGet(useDbHash, alterReq->objname, dbKeyLen);
×
3315
  if (NULL == currRef) {
×
3316
    return 0;
×
3317
  }
3318

3319
  if (1 == *currRef) {
×
3320
    if (taosHashRemove(useDbHash, alterReq->objname, dbKeyLen) != 0) {
×
3321
      TAOS_RETURN(0);  // not found
×
3322
    }
3323
    return 0;
×
3324
  }
3325
  int32_t ref = (*currRef) - 1;
×
3326
  TAOS_CHECK_RETURN(taosHashPut(useDbHash, alterReq->objname, dbKeyLen, &ref, sizeof(ref)));
×
3327

3328
  return 0;
×
3329
}
3330

3331

3332
#if 0
3333
static int32_t mndProcessAlterUserPrivilegesReq(SRpcMsg* pReq, SAlterUserReq *pAlterReq) {
3334
  SMnode   *pMnode = pReq->info.node;
3335
  SSdb     *pSdb = pMnode->pSdb;
3336
  int32_t   code = 0, lino = 0;
3337
  SUserObj *pUser = NULL;
3338
  SUserObj  newUser = {0};
3339
  int64_t   tss = taosGetTimestampMs();
3340

3341
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, pAlterReq->user, &pUser), &lino, _OVER);
3342
  TAOS_CHECK_GOTO(mndCheckAlterUserPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser, pAlterReq), &lino, _OVER);
3343
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
3344

3345
#if 0
3346
  if (ALTER_USER_ADD_READ_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName) ||
3347
      ALTER_USER_ADD_ALL_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName)) {
3348
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
3349
      int32_t len = strlen(pAlterReq->objname) + 1;
3350
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
3351
      if (pDb == NULL) {
3352
        mndReleaseDb(pMnode, pDb);
3353
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
3354
      }
3355
      if ((code = taosHashPut(newUser.readDbs, pAlterReq->objname, len, pAlterReq->objname, TSDB_DB_FNAME_LEN)) !=
3356
          0) {
3357
        mndReleaseDb(pMnode, pDb);
3358
        TAOS_CHECK_GOTO(code, &lino, _OVER);
3359
      }
3360
      mndReleaseDb(pMnode, pDb);
3361
    } else {
3362
      void   *pIter = NULL;
3363
      while (1) {
3364
        SDbObj *pDb = NULL;
3365
        pIter = sdbFetch(pSdb, SDB_DB, pIter, (void **)&pDb);
3366
        if (pIter == NULL) break;
3367
        int32_t len = strlen(pDb->name) + 1;
3368
        if ((code = taosHashPut(newUser.readDbs, pDb->name, len, pDb->name, TSDB_DB_FNAME_LEN)) != 0) {
3369
          sdbRelease(pSdb, pDb);
3370
          sdbCancelFetch(pSdb, pIter);
3371
          TAOS_CHECK_GOTO(code, &lino, _OVER);
3372
        }
3373
        sdbRelease(pSdb, pDb);
3374
      }
3375
    }
3376
  }
3377

3378
  if (ALTER_USER_ADD_WRITE_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName) ||
3379
      ALTER_USER_ADD_ALL_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName)) {
3380
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
3381
      int32_t len = strlen(pAlterReq->objname) + 1;
3382
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
3383
      if (pDb == NULL) {
3384
        mndReleaseDb(pMnode, pDb);
3385
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
3386
      }
3387
      if ((code = taosHashPut(newUser.writeDbs, pAlterReq->objname, len, pAlterReq->objname, TSDB_DB_FNAME_LEN)) !=
3388
          0) {
3389
        mndReleaseDb(pMnode, pDb);
3390
        TAOS_CHECK_GOTO(code, &lino, _OVER);
3391
      }
3392
      mndReleaseDb(pMnode, pDb);
3393
    } else {
3394
      void   *pIter = NULL;
3395
      while (1) {
3396
        SDbObj *pDb = NULL;
3397
        pIter = sdbFetch(pSdb, SDB_DB, pIter, (void **)&pDb);
3398
        if (pIter == NULL) break;
3399
        int32_t len = strlen(pDb->name) + 1;
3400
        if ((code = taosHashPut(newUser.writeDbs, pDb->name, len, pDb->name, TSDB_DB_FNAME_LEN)) != 0) {
3401
          sdbRelease(pSdb, pDb);
3402
          sdbCancelFetch(pSdb, pIter);
3403
          TAOS_CHECK_GOTO(code, &lino, _OVER);
3404
        }
3405
        sdbRelease(pSdb, pDb);
3406
      }
3407
    }
3408
  }
3409

3410
  if (ALTER_USER_DEL_READ_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName) ||
3411
      ALTER_USER_DEL_ALL_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName)) {
3412
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
3413
      int32_t len = strlen(pAlterReq->objname) + 1;
3414
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
3415
      if (pDb == NULL) {
3416
        mndReleaseDb(pMnode, pDb);
3417
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
3418
      }
3419
      code = taosHashRemove(newUser.readDbs, pAlterReq->objname, len);
3420
      if (code < 0) {
3421
        mError("read db:%s, failed to remove db:%s since %s", newUser.user, pAlterReq->objname, terrstr());
3422
      }
3423
      mndReleaseDb(pMnode, pDb);
3424
    } else {
3425
      taosHashClear(newUser.readDbs);
3426
    }
3427
  }
3428

3429
  if (ALTER_USER_DEL_WRITE_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName) ||
3430
      ALTER_USER_DEL_ALL_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName)) {
3431
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
3432
      int32_t len = strlen(pAlterReq->objname) + 1;
3433
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
3434
      if (pDb == NULL) {
3435
        mndReleaseDb(pMnode, pDb);
3436
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
3437
      }
3438
      code = taosHashRemove(newUser.writeDbs, pAlterReq->objname, len);
3439
      if (code < 0) {
3440
        mError("user:%s, failed to remove db:%s since %s", newUser.user, pAlterReq->objname, terrstr());
3441
      }
3442
      mndReleaseDb(pMnode, pDb);
3443
    } else {
3444
      taosHashClear(newUser.writeDbs);
3445
    }
3446
  }
3447

3448
  SHashObj *pReadTbs = newUser.readTbs;
3449
  SHashObj *pWriteTbs = newUser.writeTbs;
3450
  SHashObj *pAlterTbs = newUser.alterTbs;
3451

3452
#ifdef TD_ENTERPRISE
3453
  if (pAlterReq->isView) {
3454
    pReadTbs = newUser.readViews;
3455
    pWriteTbs = newUser.writeViews;
3456
    pAlterTbs = newUser.alterViews;
3457
  }
3458
#endif
3459

3460
  if (ALTER_USER_ADD_READ_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3461
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3462
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pReadTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3463
  }
3464

3465
  if (ALTER_USER_ADD_WRITE_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3466
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3467
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pWriteTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3468
  }
3469

3470
  if (ALTER_USER_ADD_ALTER_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3471
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3472
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pAlterTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3473
  }
3474

3475
  if (ALTER_USER_DEL_READ_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3476
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3477
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pReadTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3478
  }
3479

3480
  if (ALTER_USER_DEL_WRITE_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3481
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3482
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pWriteTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3483
  }
3484

3485
  if (ALTER_USER_DEL_ALTER_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3486
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3487
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pAlterTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3488
  }
3489
#endif
3490

3491
#if 0
3492
// #ifdef USE_TOPIC
3493
  if (ALTER_USER_ADD_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, &pAlterReq->privileges)) {
3494
    int32_t      len = strlen(pAlterReq->objname) + 1;
3495
    SMqTopicObj *pTopic = NULL;
3496
    if ((code = mndAcquireTopic(pMnode, pAlterReq->objname, &pTopic)) != 0) {
3497
      TAOS_CHECK_GOTO(code, &lino, _OVER);
3498
    }
3499
    taosRLockLatch(&pTopic->lock);
3500
    code = taosHashPut(newUser.topics, pTopic->name, len, pTopic->name, TSDB_TOPIC_FNAME_LEN);
3501
    taosRUnLockLatch(&pTopic->lock);
3502
    mndReleaseTopic(pMnode, pTopic);
3503
    TAOS_CHECK_GOTO(code, &lino, _OVER);
3504
  }
3505

3506
  if (ALTER_USER_DEL_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, &pAlterReq->privileges)) {
3507
    int32_t      len = strlen(pAlterReq->objname) + 1;
3508
    SMqTopicObj *pTopic = NULL;
3509
    if ((code = mndAcquireTopic(pMnode, pAlterReq->objname, &pTopic)) != 0) {
3510
      TAOS_CHECK_GOTO(code, &lino, _OVER);
3511
    }
3512
    taosRLockLatch(&pTopic->lock);
3513
    code = taosHashRemove(newUser.topics, pAlterReq->objname, len);
3514
    if (code < 0) {
3515
      mError("user:%s, failed to remove topic:%s since %s", newUser.user, pAlterReq->objname, tstrerror(code));
3516
    }
3517
    taosRUnLockLatch(&pTopic->lock);
3518
    mndReleaseTopic(pMnode, pTopic);
3519
  }
3520
#endif
3521

3522
  TAOS_CHECK_GOTO(mndAlterUser(pMnode, &newUser, pReq), &lino, _OVER);
3523
  code = TSDB_CODE_ACTION_IN_PROGRESS;
3524

3525
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
3526
    int64_t tse = taosGetTimestampMs();
3527
    double  duration = (double)(tse - tss);
3528
    duration = duration / 1000;
3529
    if (ALTER_USER_ADD_READ_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3530
              ALTER_USER_ADD_WRITE_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3531
              ALTER_USER_ADD_ALL_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3532
              ALTER_USER_ADD_READ_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3533
              ALTER_USER_ADD_WRITE_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3534
              ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3535
      if (strcmp(pAlterReq->objname, "1.*") != 0) {
3536
        SName name = {0};
3537
        TAOS_CHECK_GOTO(tNameFromString(&name, pAlterReq->objname, T_NAME_ACCT | T_NAME_DB), &lino, _OVER);
3538
        auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", name.dbname, pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
3539
      } else {
3540
        auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", "", pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
3541
      }
3542
    } else if (ALTER_USER_ADD_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, pAlterReq->privileges)) {
3543
      auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", pAlterReq->objname, pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
3544
    } else if (ALTER_USER_DEL_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, pAlterReq->privileges)) {
3545
      auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", pAlterReq->objname, pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
3546
    } else {
3547
      if (strcmp(pAlterReq->objname, "1.*") != 0) {
3548
        SName name = {0};
3549
        TAOS_CHECK_GOTO(tNameFromString(&name, pAlterReq->objname, T_NAME_ACCT | T_NAME_DB), &lino, _OVER);
3550
        auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", name.dbname, pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
3551
      } else {
3552
        auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", "", pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
3553
      }
3554
    }
3555
  }
3556
  
3557
_OVER:
3558
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
3559
    mError("user:%s, failed to alter user privileges at line %d since %s", pAlterReq->user, lino, tstrerror(code));
3560
  }
3561
  mndReleaseUser(pMnode, pUser);
3562
  mndUserFreeObj(&newUser);
3563
  TAOS_RETURN(code);
3564
}
3565
#endif
3566

3567
#ifdef TD_ENTERPRISE
3568
extern int32_t mndAlterUserPrivInfo(SMnode *pMnode, SUserObj *pOperUser, SUserObj *pOld, SUserObj *pNew, SAlterRoleReq *pAlterReq);
3569
extern int32_t mndAlterUserRoleInfo(SMnode *pMnode, SUserObj *pOperUser, SUserObj *pOld, SUserObj *pNew, SAlterRoleReq *pAlterReq);
3570
#endif
3571

3572
int32_t mndAlterUserFromRole(SRpcMsg *pReq, SUserObj *pOperUser, SAlterRoleReq *pAlterReq) {
960,797✔
3573
  SMnode   *pMnode = pReq->info.node;
960,797✔
3574
  SSdb     *pSdb = pMnode->pSdb;
960,797✔
3575
  void     *pIter = NULL;
960,797✔
3576
  int32_t   code = 0, lino = 0;
960,797✔
3577
  SUserObj *pUser = NULL;
960,797✔
3578
  SUserObj  newUser = {0};
960,797✔
3579

3580
  TAOS_CHECK_EXIT(mndAcquireUser(pMnode, pAlterReq->principal, &pUser));
960,797✔
3581

3582
  if (pUser->enable == 0) {
959,817✔
3583
    TAOS_CHECK_EXIT(TSDB_CODE_MND_USER_DISABLED);
×
3584
  }
3585

3586
  if (pAlterReq->alterType == TSDB_ALTER_ROLE_PRIVILEGES) {
959,817✔
3587
#ifdef TD_ENTERPRISE
3588
    TAOS_CHECK_EXIT(mndUserDupObj(pUser, &newUser));
956,361✔
3589
    if ((code = mndAlterUserPrivInfo(pMnode, pOperUser, pUser, &newUser, pAlterReq)) == TSDB_CODE_QRY_DUPLICATED_OPERATION) {
956,361✔
3590
      code = 0;
×
3591
      goto _exit;
×
3592
    } else {
3593
      TAOS_CHECK_EXIT(code);
956,361✔
3594
    }
3595
  } else if (pAlterReq->alterType == TSDB_ALTER_ROLE_ROLE) {
3,456✔
3596
    if ((code = mndAlterUserRoleInfo(pMnode, pOperUser, pUser, &newUser, pAlterReq)) == TSDB_CODE_QRY_DUPLICATED_OPERATION) {
3,456✔
3597
      code = 0;
152✔
3598
      goto _exit;
152✔
3599
    } else {
3600
      TAOS_CHECK_EXIT(code);
3,304✔
3601
    }
3602
#endif
3603
  } else {
3604
    TAOS_CHECK_EXIT(TSDB_CODE_INVALID_MSG);
×
3605
  }
3606
  code = mndAlterUser(pMnode, &newUser, pReq);
959,209✔
3607
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
959,209✔
3608

3609
_exit:
960,797✔
3610
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
960,797✔
3611
    mError("user:%s, failed to alter user at line %d since %s", pAlterReq->principal, lino, tstrerror(code));
1,436✔
3612
  }
3613
  mndReleaseUser(pMnode, pUser);
960,797✔
3614
  mndUserFreeObj(&newUser);
960,797✔
3615
  TAOS_RETURN(code);
960,797✔
3616
}
3617

3618

3619
static int32_t mndProcessAlterUserBasicInfoReq(SRpcMsg *pReq, SAlterUserReq *pAlterReq) {
29,049✔
3620
  SMnode       *pMnode = pReq->info.node;
29,049✔
3621
  int32_t       code = 0, lino = 0;
29,049✔
3622
  SUserObj     *pUser = NULL;
29,049✔
3623
  SUserObj      newUser = {0};
29,049✔
3624
  char          auditLog[1000] = {0};
29,049✔
3625
  int32_t       auditLen = 0;
29,049✔
3626
  int64_t       tss = taosGetTimestampMs();
29,049✔
3627

3628
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, pAlterReq->user, &pUser), &lino, _OVER);
29,049✔
3629
  TAOS_CHECK_GOTO(mndCheckAlterUserPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser, pAlterReq), &lino, _OVER);
28,364✔
3630
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
26,608✔
3631

3632
  if (pAlterReq->hasPassword) {
26,608✔
3633
    auditLen += tsnprintf(auditLog, sizeof(auditLog), "password,");
18,514✔
3634

3635
    TAOS_CHECK_GOTO(mndCheckPasswordFmt(pAlterReq->pass), &lino, _OVER);
18,514✔
3636
    if (newUser.salt[0] == 0) {
18,514✔
3637
      generateSalt(newUser.salt, sizeof(newUser.salt));
165✔
3638
    }
3639
    char pass[TSDB_PASSWORD_LEN] = {0};
18,514✔
3640
    taosEncryptPass_c((uint8_t *)pAlterReq->pass, strlen(pAlterReq->pass), pass);
18,514✔
3641
    pass[sizeof(pass) - 1] = 0;
18,514✔
3642
    TAOS_CHECK_GOTO(mndEncryptPass(pass, newUser.salt, &newUser.passEncryptAlgorithm), &lino, _OVER);
18,514✔
3643

3644
    if (newUser.passwordReuseMax > 0 || newUser.passwordReuseTime > 0) {
18,514✔
3645
      for(int32_t i = 0; i < newUser.numOfPasswords; ++i) {
686,932✔
3646
        if (0 == strncmp(newUser.passwords[i].pass, pass, TSDB_PASSWORD_LEN)) {
670,401✔
3647
          TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_PASSWORD_REUSE, &lino, _OVER);
378✔
3648
        }
3649
      }
3650
      SUserPassword *passwords = taosMemoryCalloc(newUser.numOfPasswords + 1, sizeof(SUserPassword));
16,531✔
3651
      if (passwords == NULL) {
16,531✔
3652
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3653
      }
3654
      memcpy(passwords + 1, newUser.passwords, newUser.numOfPasswords * sizeof(SUserPassword));
16,531✔
3655
      memcpy(passwords[0].pass, pass, TSDB_PASSWORD_LEN);
16,531✔
3656
      passwords[0].setTime = taosGetTimestampSec();
16,531✔
3657
      taosMemoryFree(newUser.passwords);
16,531✔
3658
      newUser.passwords = passwords;
16,531✔
3659
      ++newUser.numOfPasswords;
16,531✔
3660
      ++newUser.passVersion;
16,531✔
3661
      newUser.changePass = 2;
16,531✔
3662
    } else if (0 != strncmp(newUser.passwords[0].pass, pass, TSDB_PASSWORD_LEN)) {
1,605✔
3663
      memcpy(newUser.passwords[0].pass, pass, TSDB_PASSWORD_LEN);
1,412✔
3664
      newUser.passwords[0].setTime = taosGetTimestampSec();
1,412✔
3665
      ++newUser.passVersion;
1,412✔
3666
      newUser.changePass = 2;
1,412✔
3667
    }
3668
  }
3669

3670
  if (pAlterReq->hasTotpseed) {
26,230✔
3671
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "totpseed,");
×
3672

3673
    if (pAlterReq->totpseed[0] == 0) { // clear totp secret
×
3674
      memset(newUser.totpsecret, 0, sizeof(newUser.totpsecret));
×
3675
    } else if (taosGenerateTotpSecret(pAlterReq->totpseed, 0, newUser.totpsecret, sizeof(newUser.totpsecret)) < 0) {
×
3676
      TAOS_CHECK_GOTO(TSDB_CODE_PAR_INVALID_OPTION_VALUE, &lino, _OVER);
×
3677
    }
3678
  }
3679

3680
  if (pAlterReq->hasEnable) {
26,230✔
3681
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "enable:%d,", pAlterReq->enable);
941✔
3682

3683
    newUser.enable = pAlterReq->enable; // lock or unlock user manually
941✔
3684
    if (newUser.enable) {
941✔
3685
      // reset login info to allow login immediately
3686
      userCacheResetLoginInfo(newUser.user);
776✔
3687
    }
3688
  }
3689

3690
  if (pAlterReq->hasSysinfo) {
26,230✔
3691
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "sysinfo:%d,", pAlterReq->sysinfo);
3,577✔
3692
    newUser.sysInfo = pAlterReq->sysinfo;
3,577✔
3693
  }
3694

3695
  if (pAlterReq->hasCreatedb) {
26,230✔
3696
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "createdb:%d,", pAlterReq->createdb);
1,620✔
3697
    newUser.createdb = pAlterReq->createdb;
1,620✔
3698
  }
3699

3700
#ifdef TD_ENTERPRISE
3701
  if (pAlterReq->hasChangepass) {
26,230✔
3702
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "changepass:%d,", pAlterReq->changepass);
×
3703
    newUser.changePass = pAlterReq->changepass;
×
3704
  }
3705

3706
  if (pAlterReq->hasSessionPerUser) {
26,230✔
3707
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "sessionPerUser:%d,", pAlterReq->sessionPerUser);
252✔
3708
    newUser.sessionPerUser = pAlterReq->sessionPerUser;
252✔
3709
  }
3710

3711
  if (pAlterReq->hasConnectTime) {
26,230✔
3712
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "connectTime:%d,", pAlterReq->connectTime);
126✔
3713
    newUser.connectTime = pAlterReq->connectTime;
126✔
3714
  }
3715
  
3716
  if (pAlterReq->hasConnectIdleTime) {
26,230✔
3717
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "connectIdleTime:%d,", pAlterReq->connectIdleTime);
126✔
3718
    newUser.connectIdleTime = pAlterReq->connectIdleTime;
126✔
3719
  }
3720

3721
  if (pAlterReq->hasCallPerSession) {
26,230✔
3722
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "callPerSession:%d,", pAlterReq->callPerSession);
378✔
3723
    newUser.callPerSession = pAlterReq->callPerSession;
378✔
3724
  }
3725

3726
  if (pAlterReq->hasVnodePerCall) {
26,230✔
3727
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "vnodePerCall:%d,", pAlterReq->vnodePerCall);
252✔
3728
    newUser.vnodePerCall = pAlterReq->vnodePerCall;
252✔
3729
  }
3730

3731
  if (pAlterReq->hasFailedLoginAttempts) {
26,230✔
3732
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "failedLoginAttempts:%d,", pAlterReq->failedLoginAttempts);
378✔
3733
    newUser.failedLoginAttempts = pAlterReq->failedLoginAttempts;
378✔
3734
  }
3735

3736
  if (pAlterReq->hasPasswordLifeTime) {
26,230✔
3737
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordLifeTime:%d,", pAlterReq->passwordLifeTime);
126✔
3738
    newUser.passwordLifeTime = pAlterReq->passwordLifeTime;
126✔
3739
  }
3740

3741
  if (pAlterReq->hasPasswordReuseTime) {
26,230✔
3742
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordReuseTime:%d,", pAlterReq->passwordReuseTime);
378✔
3743
    newUser.passwordReuseTime = pAlterReq->passwordReuseTime;
378✔
3744
  }
3745

3746
  if (pAlterReq->hasPasswordReuseMax) {
26,230✔
3747
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordReuseMax:%d,", pAlterReq->passwordReuseMax);
378✔
3748
    newUser.passwordReuseMax = pAlterReq->passwordReuseMax;
378✔
3749
  }
3750

3751
  if (pAlterReq->hasPasswordLockTime) {
26,230✔
3752
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordLockTime:%d,", pAlterReq->passwordLockTime);
126✔
3753
    newUser.passwordLockTime = pAlterReq->passwordLockTime;
126✔
3754
  }
3755

3756
  if (pAlterReq->hasPasswordGraceTime) {
26,230✔
3757
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordGraceTime:%d,", pAlterReq->passwordGraceTime);
126✔
3758
    newUser.passwordGraceTime = pAlterReq->passwordGraceTime;
126✔
3759
  }
3760

3761
  if (pAlterReq->hasInactiveAccountTime) {
26,230✔
3762
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "inactiveAccountTime:%d,", pAlterReq->inactiveAccountTime);
126✔
3763
    newUser.inactiveAccountTime = pAlterReq->inactiveAccountTime;
126✔
3764
  }
3765

3766
  if (pAlterReq->hasAllowTokenNum) {
26,230✔
3767
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "allowTokenNum:%d,", pAlterReq->allowTokenNum);
252✔
3768
    newUser.allowTokenNum = pAlterReq->allowTokenNum;
252✔
3769
  }
3770

3771
  if (pAlterReq->numDropIpRanges > 0 || pAlterReq->numIpRanges > 0) {
26,230✔
3772
    int32_t dummy = 0;
570✔
3773

3774
    // put previous ip whitelist into hash table
3775
    SHashObj *m = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
570✔
3776
    if (m == NULL) {
570✔
3777
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3778
    }
3779

3780
    for (int32_t i = 0; i < newUser.pIpWhiteListDual->num; i++) {
2,439✔
3781
      SIpRange range;
1,869✔
3782
      copyIpRange(&range, newUser.pIpWhiteListDual->pIpRanges + i);
1,869✔
3783
      code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
1,869✔
3784
      if (code != 0) {
1,869✔
3785
        taosHashCleanup(m);
×
3786
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3787
      }
3788
    }
3789

3790
    if (pAlterReq->numDropIpRanges > 0) {
570✔
3791
      auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "dropIpRanges:%d,", pAlterReq->numDropIpRanges);
285✔
3792

3793
      for (int32_t i = 0; i < pAlterReq->numDropIpRanges; i++) {
696✔
3794
        if (taosHashGetSize(m) == 0) {
411✔
3795
          break;
×
3796
        }
3797

3798
        SIpRange range;
411✔
3799
        copyIpRange(&range, pAlterReq->pDropIpRanges + i);
411✔
3800

3801
        // for white list, drop default ip ranges is allowed, otherwise, we can never
3802
        // convert white list to black list.
3803

3804
        code = taosHashRemove(m, &range, sizeof(range));
411✔
3805
        if (code == TSDB_CODE_NOT_FOUND) {
411✔
3806
          // treat not exist as success
3807
          code = 0;
159✔
3808
        }
3809
        if (code != 0) {
411✔
3810
          taosHashCleanup(m);
×
3811
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3812
        }
3813
      }
3814
    }
3815

3816
    if (pAlterReq->numIpRanges > 0) {
570✔
3817
      auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "addIpRanges:%d,", pAlterReq->numIpRanges);
285✔
3818
      for (int32_t i = 0; i < pAlterReq->numIpRanges; i++) {
696✔
3819
        SIpRange range;
411✔
3820
        copyIpRange(&range, pAlterReq->pIpRanges + i);
411✔
3821
        code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
411✔
3822
        if (code != 0) {
411✔
3823
          taosHashCleanup(m);
×
3824
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3825
        }
3826
      }
3827
    }
3828

3829
    int32_t numOfRanges = taosHashGetSize(m);
570✔
3830
    if (numOfRanges > MND_MAX_USER_IP_RANGE) {
570✔
3831
      taosHashCleanup(m);
×
3832
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_IP_RANGE, &lino, _OVER);
×
3833
    }
3834

3835
    SIpWhiteListDual *p = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + numOfRanges * sizeof(SIpRange));
570✔
3836
    if (p == NULL) {
570✔
3837
      taosHashCleanup(m);
×
3838
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3839
    }
3840

3841
    void *pIter = taosHashIterate(m, NULL);
570✔
3842
    int32_t i = 0;
570✔
3843
    while (pIter) {
2,598✔
3844
      size_t len = 0;
2,028✔
3845
      SIpRange *key = taosHashGetKey(pIter, &len);
2,028✔
3846
      memcpy(p->pIpRanges + i, key, sizeof(SIpRange));
2,028✔
3847
      pIter = taosHashIterate(m, pIter);
2,028✔
3848
      i++;
2,028✔
3849
    }
3850

3851
    taosHashCleanup(m);
570✔
3852
    p->num = numOfRanges;
570✔
3853
    taosMemoryFreeClear(newUser.pIpWhiteListDual);
570✔
3854
    sortIpWhiteList(p);
570✔
3855
    newUser.pIpWhiteListDual = p;
570✔
3856

3857
    newUser.ipWhiteListVer++;
570✔
3858
  }
3859

3860

3861
  if (pAlterReq->numTimeRanges > 0 || pAlterReq->numDropTimeRanges) {
26,230✔
3862
    int32_t dummy = 0;
504✔
3863

3864
    // put previous ip whitelist into hash table
3865
    SHashObj *m = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
504✔
3866
    if (m == NULL) {
504✔
3867
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3868
    }
3869

3870
    for (int32_t i = 0; i < newUser.pTimeWhiteList->num; i++) {
1,260✔
3871
      SDateTimeWhiteListItem *range = &newUser.pTimeWhiteList->ranges[i];
756✔
3872
      if (isDateTimeWhiteListItemExpired(range)) {
756✔
3873
        continue;
×
3874
      }
3875
      code = taosHashPut(m, range, sizeof(*range), &dummy, sizeof(dummy));
756✔
3876
      if (code != 0) {
756✔
3877
        taosHashCleanup(m);
×
3878
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3879
      }
3880
    }
3881

3882
    if (pAlterReq->numDropTimeRanges > 0) {
504✔
3883
      auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "dropTimeRanges:%d,", pAlterReq->numDropTimeRanges);
378✔
3884
      for (int32_t i = 0; i < pAlterReq->numDropTimeRanges; i++) {
882✔
3885
        if (taosHashGetSize(m) == 0) {
504✔
3886
          break;
×
3887
        }
3888
        SDateTimeWhiteListItem range = { 0 };
504✔
3889
        DateTimeRangeToWhiteListItem(&range, pAlterReq->pDropTimeRanges + i);
504✔
3890

3891
        code = taosHashRemove(m, &range, sizeof(range));
504✔
3892
        if (code == TSDB_CODE_NOT_FOUND) {
504✔
3893
          // treat not exist as success
3894
          code = 0;
×
3895
        }
3896
        if (code != 0) {
504✔
3897
          taosHashCleanup(m);
×
3898
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3899
        }
3900
      }
3901
    }
3902

3903
    if (pAlterReq->numTimeRanges > 0) {
504✔
3904
      auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "addTimeRanges:%d,", pAlterReq->numTimeRanges);
378✔
3905
      for (int32_t i = 0; i < pAlterReq->numTimeRanges; i++) {
882✔
3906
        SDateTimeWhiteListItem range = { 0 };
504✔
3907
        DateTimeRangeToWhiteListItem(&range, pAlterReq->pTimeRanges + i);
504✔
3908
        if (isDateTimeWhiteListItemExpired(&range)) {
504✔
3909
          continue;
×
3910
        }
3911
        code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
504✔
3912
        if (code != 0) {
504✔
3913
          taosHashCleanup(m);
×
3914
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3915
        }
3916
      }
3917
    }
3918

3919
    int32_t numOfRanges = taosHashGetSize(m);
504✔
3920
    if (numOfRanges > MND_MAX_USER_TIME_RANGE) {
504✔
3921
      taosHashCleanup(m);
×
3922
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_TIME_RANGE, &lino, _OVER);
×
3923
    }
3924

3925
    SDateTimeWhiteList *p = taosMemoryCalloc(1, sizeof(SDateTimeWhiteList) + numOfRanges * sizeof(SDateTimeWhiteListItem));
504✔
3926
    if (p == NULL) {
504✔
3927
      taosHashCleanup(m);
×
3928
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3929
    }
3930

3931
    void *pIter = taosHashIterate(m, NULL);
504✔
3932
    int32_t i = 0;
504✔
3933
    while (pIter) {
1,260✔
3934
      size_t len = 0;
756✔
3935
      SDateTimeWhiteListItem *key = taosHashGetKey(pIter, &len);
756✔
3936
      memcpy(&p->ranges[i], key, sizeof(SDateTimeWhiteListItem));
756✔
3937
      pIter = taosHashIterate(m, pIter);
756✔
3938
      i++;
756✔
3939
    }
3940

3941
    taosHashCleanup(m);
504✔
3942
    p->num = numOfRanges;
504✔
3943
    taosMemoryFreeClear(newUser.pTimeWhiteList);
504✔
3944
    sortTimeWhiteList(p);
504✔
3945
    newUser.pTimeWhiteList = p;
504✔
3946
    newUser.timeWhiteListVer++;
504✔
3947
  }
3948
#endif // TD_ENTERPRISE
3949

3950
  TAOS_CHECK_GOTO(mndAlterUser(pMnode, &newUser, pReq), &lino, _OVER);
26,230✔
3951
  code = TSDB_CODE_ACTION_IN_PROGRESS;
26,230✔
3952

3953
  if (auditLen > 0) {
26,230✔
3954
    auditLog[--auditLen] = 0; // remove last ','
26,230✔
3955
  }
3956
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
26,230✔
3957
    int64_t tse = taosGetTimestampMs();
26,230✔
3958
    double  duration = (double)(tse - tss);
26,230✔
3959
    duration = duration / 1000;
26,230✔
3960
    auditRecord(pReq, pMnode->clusterId, "alterUser", "", pAlterReq->user, auditLog, auditLen, duration, 0);
26,230✔
3961
  }
3962

3963
_OVER:
29,049✔
3964
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
29,049✔
3965
    mError("user:%s, failed to alter at line %d since %s", pAlterReq->user, lino, tstrerror(code));
2,819✔
3966
  }
3967

3968
  mndReleaseUser(pMnode, pUser);
29,049✔
3969
  mndUserFreeObj(&newUser);
29,049✔
3970
  return code;
29,049✔
3971
}
3972

3973

3974

3975
static int32_t mndProcessAlterUserReq(SRpcMsg *pReq) {
29,049✔
3976
  SAlterUserReq alterReq = {0};
29,049✔
3977

3978
  int32_t code = tDeserializeSAlterUserReq(pReq->pCont, pReq->contLen, &alterReq);
29,049✔
3979
  if (code != 0) {
29,049✔
3980
    mError("failed to deserialize alter user request at line %d since %s", __LINE__, tstrerror(code));
×
3981
    TAOS_RETURN(code);
×
3982
  }
3983

3984
  if (alterReq.user[0] == 0) {
29,049✔
3985
    tFreeSAlterUserReq(&alterReq);
×
3986
    mError("failed to alter user at line %d since invalid user format", __LINE__);
×
3987
    TAOS_RETURN(TSDB_CODE_MND_INVALID_USER_FORMAT);
×
3988
  }
3989

3990
  mInfo("user:%s, start to alter", alterReq.user);
29,049✔
3991
  if (alterReq.alterType == TSDB_ALTER_USER_BASIC_INFO) {
29,049✔
3992
    code = mndProcessAlterUserBasicInfoReq(pReq, &alterReq);
29,049✔
3993
  } else {
3994
    // code = mndProcessAlterUserPrivilegesReq(pReq, &alterReq); // obsolete
3995
  }
3996

3997
  tFreeSAlterUserReq(&alterReq);
29,049✔
3998
  TAOS_RETURN(code);
29,049✔
3999
}
4000

4001
int32_t mndGetAuditUser(SMnode *pMnode, char* user){
40,257,318✔
4002
  (void)tsnprintf(user, TSDB_USER_LEN, "audit");
40,257,318✔
4003
  return 0;
40,257,318✔
4004
}
4005

4006
static int32_t mndDropUser(SMnode *pMnode, SRpcMsg *pReq, SUserObj *pUser) {
20,378✔
4007
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "drop-user");
20,378✔
4008
  if (pTrans == NULL) {
20,378✔
4009
    mError("user:%s, failed to drop since %s", pUser->user, terrstr());
×
4010
    TAOS_RETURN(terrno);
×
4011
  }
4012
  mInfo("trans:%d, used to drop user:%s", pTrans->id, pUser->user);
20,378✔
4013

4014
  SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
20,378✔
4015
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
20,378✔
4016
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
4017
    mndTransDrop(pTrans);
×
4018
    TAOS_RETURN(terrno);
×
4019
  }
4020
  if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED) < 0) {
20,378✔
4021
    mndTransDrop(pTrans);
×
4022
    TAOS_RETURN(terrno);
×
4023
  }
4024

4025
  if (mndDropTokensByUser(pMnode, pTrans, pUser->user) != 0) {
20,378✔
4026
    mndTransDrop(pTrans);
×
4027
    TAOS_RETURN(terrno);
×
4028
  }
4029

4030
  if (mndTransPrepare(pMnode, pTrans) != 0) {
20,378✔
4031
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
4032
    mndTransDrop(pTrans);
×
4033
    TAOS_RETURN(terrno);
×
4034
  }
4035

4036
  userCacheRemoveUser(pUser->user);
20,378✔
4037
  mndDropCachedTokensByUser(pUser->user);
20,378✔
4038

4039
  mndTransDrop(pTrans);
20,378✔
4040
  TAOS_RETURN(0);
20,378✔
4041
}
4042

4043
static int32_t mndProcessDropUserReq(SRpcMsg *pReq) {
20,975✔
4044
  SMnode      *pMnode = pReq->info.node;
20,975✔
4045
  int32_t      code = 0;
20,975✔
4046
  int32_t      lino = 0;
20,975✔
4047
  SUserObj    *pOperUser = NULL;
20,975✔
4048
  SUserObj    *pUser = NULL;
20,975✔
4049
  SDropUserReq dropReq = {0};
20,975✔
4050
  int64_t      tss = taosGetTimestampMs();
20,975✔
4051

4052
  TAOS_CHECK_GOTO(tDeserializeSDropUserReq(pReq->pCont, pReq->contLen, &dropReq), &lino, _OVER);
20,975✔
4053

4054
  mInfo("user:%s, start to drop", dropReq.user);
20,975✔
4055

4056
  if (dropReq.user[0] == 0) {
20,975✔
4057
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
4058
  }
4059

4060
  if (0 == strcmp(dropReq.user, TSDB_DEFAULT_USER)) {
20,975✔
4061
    return TSDB_CODE_MND_NO_RIGHTS;
×
4062
  }
4063

4064
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, dropReq.user, &pUser), &lino, _OVER);
20,975✔
4065

4066
  code = mndAcquireUser(pMnode, RPC_MSG_USER(pReq), &pOperUser);
20,378✔
4067
  if (pOperUser == NULL) {
20,378✔
4068
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_USER_FROM_CONN, &lino, _OVER);
×
4069
  }
4070

4071
  // TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, RPC_MSG_USER(pReq), MND_OPER_DROP_USER), &lino, _OVER);
4072
  TAOS_CHECK_GOTO(mndCheckSysObjPrivilege(pMnode, pOperUser, PRIV_USER_DROP, 0, 0, NULL, NULL), &lino, _OVER);
20,378✔
4073

4074
  TAOS_CHECK_GOTO(mndDropUser(pMnode, pReq, pUser), &lino, _OVER);
20,378✔
4075
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
20,378✔
4076

4077
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
20,378✔
4078
    int64_t tse = taosGetTimestampMs();
20,378✔
4079
    double  duration = (double)(tse - tss);
20,378✔
4080
    duration = duration / 1000;
20,378✔
4081
    auditRecord(pReq, pMnode->clusterId, "dropUser", "", dropReq.user, dropReq.sql, dropReq.sqlLen, duration, 0);
20,378✔
4082
  }
4083

4084
_OVER:
20,975✔
4085
  if (dropReq.ignoreNotExists && code == TSDB_CODE_MND_USER_NOT_EXIST) {
20,975✔
4086
    code = 0;
471✔
4087
  } else if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
20,504✔
4088
    mError("user:%s, failed to drop at line %d since %s", dropReq.user, lino, tstrerror(code));
126✔
4089
  }
4090

4091
  mndReleaseUser(pMnode, pUser);
20,975✔
4092
  mndReleaseUser(pMnode, pOperUser);
20,975✔
4093
  tFreeSDropUserReq(&dropReq);
20,975✔
4094
  TAOS_RETURN(code);
20,975✔
4095
}
4096

4097
static int32_t mndProcessGetUserAuthReq(SRpcMsg *pReq) {
5,559,875✔
4098
  SMnode         *pMnode = pReq->info.node;
5,559,875✔
4099
  int32_t         code = 0;
5,559,875✔
4100
  int32_t         lino = 0;
5,559,875✔
4101
  int32_t         contLen = 0;
5,559,875✔
4102
  void           *pRsp = NULL;
5,559,875✔
4103
  SUserObj       *pUser = NULL;
5,559,875✔
4104
  SGetUserAuthReq authReq = {0};
5,559,875✔
4105
  SGetUserAuthRsp authRsp = {0};
5,559,875✔
4106

4107
  TAOS_CHECK_EXIT(tDeserializeSGetUserAuthReq(pReq->pCont, pReq->contLen, &authReq));
5,559,875✔
4108
  mTrace("user:%s, start to get auth", authReq.user);
5,559,875✔
4109

4110
  TAOS_CHECK_EXIT(mndAcquireUser(pMnode, authReq.user, &pUser));
5,559,875✔
4111

4112
  TAOS_CHECK_EXIT(mndSetUserAuthRsp(pMnode, pUser, &authRsp));
5,559,875✔
4113

4114
  contLen = tSerializeSGetUserAuthRsp(NULL, 0, &authRsp);
5,559,875✔
4115
  if (contLen < 0) {
5,559,875✔
4116
    TAOS_CHECK_EXIT(contLen);
×
4117
  }
4118
  pRsp = rpcMallocCont(contLen);
5,559,875✔
4119
  if (pRsp == NULL) {
5,559,875✔
4120
    TAOS_CHECK_EXIT(terrno);
×
4121
  }
4122

4123
  contLen = tSerializeSGetUserAuthRsp(pRsp, contLen, &authRsp);
5,559,875✔
4124
  if (contLen < 0) {
5,559,875✔
4125
    TAOS_CHECK_EXIT(contLen);
×
4126
  }
4127

4128
_exit:
5,559,875✔
4129
  mndReleaseUser(pMnode, pUser);
5,559,875✔
4130
  tFreeSGetUserAuthRsp(&authRsp);
5,559,875✔
4131
  if (code < 0) {
5,559,179✔
4132
    mError("user:%s, failed to get auth at line %d since %s", authReq.user, lino, tstrerror(code));
×
4133
    rpcFreeCont(pRsp);
×
4134
    pRsp = NULL;
×
4135
    contLen = 0;
×
4136
  }
4137
  pReq->info.rsp = pRsp;
5,559,179✔
4138
  pReq->info.rspLen = contLen;
5,559,875✔
4139
  pReq->code = code;
5,559,179✔
4140

4141
  TAOS_RETURN(code);
5,559,875✔
4142
}
4143

4144

4145

4146
static void base32Encode(const uint8_t *in, int32_t inLen, char *out) {
15,658✔
4147
  int buffer = 0, bits = 0;
15,658✔
4148
  int outLen = 0;
15,658✔
4149

4150
  // process all input bytes
4151
  for (int i = 0; i < inLen; i++) {
516,714✔
4152
    buffer = (buffer << 8) | in[i];
501,056✔
4153
    bits += 8;
501,056✔
4154

4155
    while (bits >= 5) {
1,299,614✔
4156
      int v = (buffer >> (bits - 5)) & 0x1F;
798,558✔
4157
      out[outLen++] = (v >= 26) ? (v - 26 + '2') : (v + 'A');
798,558✔
4158
      bits -= 5;
798,558✔
4159
    }
4160
  }
4161

4162
  // process remaining bits
4163
  if (bits > 0) {
15,658✔
4164
    int v = (buffer << (5 - bits)) & 0x1F;
15,658✔
4165
    out[outLen++] = (v >= 26) ? (v - 26 + '2') : (v + 'A');
15,658✔
4166
  }
4167

4168
  out[outLen] = '\0';
15,658✔
4169
}
15,658✔
4170

4171

4172
static int32_t mndCreateTotpSecret(SMnode *pMnode, SUserObj *pUser, SRpcMsg *pReq) {
15,658✔
4173
  SCreateTotpSecretRsp rsp = {0};
15,658✔
4174

4175
  base32Encode((uint8_t *)pUser->totpsecret, sizeof(pUser->totpsecret), rsp.totpSecret);
15,658✔
4176
  tstrncpy(rsp.user, pUser->user, sizeof(rsp.user));
15,658✔
4177

4178
  int32_t len = tSerializeSCreateTotpSecretRsp(NULL, 0, &rsp);
15,658✔
4179
  if (len < 0) {
15,658✔
4180
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
4181
  }
4182

4183
  void *pData = taosMemoryMalloc(len);
15,658✔
4184
  if (pData == NULL) {
15,658✔
4185
    TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
4186
  }
4187

4188
  if (tSerializeSCreateTotpSecretRsp(pData, len, &rsp) != len) {
15,658✔
4189
    taosMemoryFree(pData);
×
4190
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
4191
  }
4192

4193
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "create-totp-secret");
15,658✔
4194
  if (pTrans == NULL) {
15,658✔
4195
    mError("user:%s, failed to create totp secret since %s", pUser->user, terrstr());
×
4196
    taosMemoryFree(pData);
×
4197
    TAOS_RETURN(terrno);
×
4198
  }
4199
  mInfo("trans:%d, used to create totp secret for user:%s", pTrans->id, pUser->user);
15,658✔
4200

4201
  mndTransSetUserData(pTrans, pData, len);
15,658✔
4202

4203
  SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
15,658✔
4204
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
15,658✔
4205
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
4206
    mndTransDrop(pTrans);
×
4207
    TAOS_RETURN(terrno);
×
4208
  }
4209
  if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY) < 0) {
15,658✔
4210
    mndTransDrop(pTrans);
×
4211
    TAOS_RETURN(terrno);
×
4212
  }
4213

4214
  if (mndTransPrepare(pMnode, pTrans) != 0) {
15,658✔
4215
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
4216
    mndTransDrop(pTrans);
×
4217
    TAOS_RETURN(terrno);
×
4218
  }
4219

4220
  mndTransDrop(pTrans);
15,658✔
4221
  TAOS_RETURN(0);
15,658✔
4222
}
4223

4224

4225
static int32_t mndProcessCreateTotpSecretReq(SRpcMsg *pReq) {
15,800✔
4226
  SMnode              *pMnode = pReq->info.node;
15,800✔
4227
  int32_t              code = 0;
15,800✔
4228
  int32_t              lino = 0;
15,800✔
4229
  SUserObj            *pUser = NULL;
15,800✔
4230
  SUserObj             newUser = {0};
15,800✔
4231
  SCreateTotpSecretReq req = {0};
15,800✔
4232
  int64_t              tss = taosGetTimestampMs();
15,800✔
4233

4234
  TAOS_CHECK_GOTO(tDeserializeSCreateTotpSecretReq(pReq->pCont, pReq->contLen, &req), &lino, _OVER);
15,800✔
4235
  mTrace("user:%s, start to create/update totp secret", req.user);
15,800✔
4236

4237
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, req.user, &pUser), &lino, _OVER);
15,800✔
4238
  TAOS_CHECK_GOTO(mndCheckTotpSecretPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser), &lino, _OVER);
15,658✔
4239
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
15,658✔
4240
  taosSafeRandBytes((uint8_t *)newUser.totpsecret, sizeof(newUser.totpsecret));
15,658✔
4241
  TAOS_CHECK_GOTO(mndCreateTotpSecret(pMnode, &newUser, pReq), &lino, _OVER); 
15,658✔
4242

4243
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
15,658✔
4244
    double  duration = (double)(taosGetTimestampMs()- tss) / 1000.0;
15,658✔
4245
    auditRecord(pReq, pMnode->clusterId, "createTotpSecret", "", req.user, req.sql, req.sqlLen, duration, 0);
15,658✔
4246
  }
4247

4248
_OVER:
15,800✔
4249
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
15,800✔
4250
    mError("user:%s, failed to create totp secret at line %d since %s", req.user, lino, tstrerror(code));
142✔
4251
  }
4252
  mndReleaseUser(pMnode, pUser);
15,800✔
4253
  mndUserFreeObj(&newUser);
15,800✔
4254
  tFreeSCreateTotpSecretReq(&req);
15,800✔
4255
  TAOS_RETURN(code);
15,800✔
4256
}
4257

4258

4259

4260
int32_t mndBuildSMCreateTotpSecretResp(STrans *pTrans, void **ppResp, int32_t *pRespLen) {
15,658✔
4261
  // user data is the response
4262
  *ppResp = pTrans->userData;
15,658✔
4263
  *pRespLen = pTrans->userDataLen;
15,658✔
4264
  pTrans->userData = NULL;
15,658✔
4265
  pTrans->userDataLen = 0;
15,658✔
4266
  return 0;
15,658✔
4267
}
4268

4269

4270

4271
static int32_t mndProcessDropTotpSecretReq(SRpcMsg *pReq) {
5,964✔
4272
  SMnode            *pMnode = pReq->info.node;
5,964✔
4273
  int32_t            code = 0;
5,964✔
4274
  int32_t            lino = 0;
5,964✔
4275
  SUserObj          *pUser = NULL;
5,964✔
4276
  SUserObj           newUser = {0};
5,964✔
4277
  SDropTotpSecretReq req = {0};
5,964✔
4278
  int64_t            tss = taosGetTimestampMs();
5,964✔
4279

4280
  TAOS_CHECK_GOTO(tDeserializeSDropTotpSecretReq(pReq->pCont, pReq->contLen, &req), &lino, _OVER);
5,964✔
4281
  mTrace("user:%s, start to drop totp secret", req.user);
5,964✔
4282

4283
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, req.user, &pUser), &lino, _OVER);
5,964✔
4284
  TAOS_CHECK_GOTO(mndCheckTotpSecretPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser), &lino, _OVER);
4,544✔
4285

4286
  if (!mndIsTotpEnabledUser(pUser)) {
4,544✔
4287
    TAOS_CHECK_GOTO(TSDB_CODE_MND_TOTP_SECRET_NOT_EXIST, &lino, _OVER);
4,260✔
4288
  }
4289

4290
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
284✔
4291
  (void)memset(newUser.totpsecret, 0, sizeof(newUser.totpsecret));
284✔
4292
  TAOS_CHECK_GOTO(mndAlterUser(pMnode, &newUser, pReq), &lino, _OVER); 
284✔
4293

4294
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
284✔
4295
    double  duration = (double)(taosGetTimestampMs()- tss) / 1000.0;
284✔
4296
    auditRecord(pReq, pMnode->clusterId, "dropTotpSecret", "", req.user, req.sql, req.sqlLen, duration, 0);
284✔
4297
  }
4298

4299
_OVER:
5,964✔
4300
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
5,964✔
4301
    mError("user:%s, failed to drop totp secret at line %d since %s", req.user, lino, tstrerror(code));
5,680✔
4302
  }
4303
  mndReleaseUser(pMnode, pUser);
5,964✔
4304
  mndUserFreeObj(&newUser);
5,964✔
4305
  tFreeSDropTotpSecretReq(&req);
5,964✔
4306
  TAOS_RETURN(code);
5,964✔
4307
}
4308

4309

4310

4311
bool mndIsTotpEnabledUser(SUserObj *pUser) {
3,664,497✔
4312
  for (int32_t i = 0; i < sizeof(pUser->totpsecret); i++) {
119,307,533✔
4313
    if (pUser->totpsecret[i] != 0) {
115,690,277✔
4314
      return true;
49,776✔
4315
    }
4316
  }
4317
  return false;
3,617,256✔
4318
}
4319

4320

4321
static int32_t mndRetrieveUsers(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
124,778✔
4322
  SMnode   *pMnode = pReq->info.node;
124,778✔
4323
  SSdb     *pSdb = pMnode->pSdb;
124,778✔
4324
  int32_t   code = 0;
124,778✔
4325
  int32_t   lino = 0;
124,778✔
4326
  int32_t   numOfRows = 0;
124,778✔
4327
  SUserObj *pUser = NULL;
124,778✔
4328
  int32_t   cols = 0;
124,778✔
4329
  int8_t    flag = 0;
124,778✔
4330
  char     *pWrite = NULL;
124,778✔
4331
  char     *buf = NULL;
124,778✔
4332
  char     *varstr = NULL;
124,778✔
4333
  char      tBuf[TSDB_MAX_SUBROLE * TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
124,778✔
4334
  int32_t   bufSize = sizeof(tBuf) - VARSTR_HEADER_SIZE;
124,778✔
4335

4336
  while (numOfRows < rows) {
1,056,191✔
4337
    pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
1,056,191✔
4338
    if (pShow->pIter == NULL) break;
1,056,191✔
4339

4340
    cols = 0;
931,413✔
4341
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
931,413✔
4342
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
931,413✔
4343
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
931,413✔
4344
    COL_DATA_SET_VAL_GOTO((const char *)name, false, pUser, pShow->pIter, _exit);
931,413✔
4345

4346
    cols++;
931,413✔
4347
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
931,413✔
4348
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->superUser, false, pUser, pShow->pIter, _exit);
931,413✔
4349

4350
    cols++;
931,413✔
4351
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
931,413✔
4352
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->enable, false, pUser, pShow->pIter, _exit);
931,413✔
4353

4354
    cols++;
931,413✔
4355
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
931,413✔
4356
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sysInfo, false, pUser, pShow->pIter, _exit);
931,413✔
4357

4358
    cols++;
931,413✔
4359
    flag = pUser->createdb ? 1 : 0;
931,413✔
4360
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
931,413✔
4361
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
931,413✔
4362

4363
    cols++;
931,413✔
4364
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
931,413✔
4365
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->createdTime, false, pUser, pShow->pIter, _exit);
931,413✔
4366

4367
    cols++;
931,413✔
4368
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
931,413✔
4369
    flag = mndIsTotpEnabledUser(pUser) ? 1 : 0;
931,413✔
4370
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
931,413✔
4371

4372
    cols++;
931,413✔
4373

4374
    int32_t tlen = convertIpWhiteListToStr(pUser, &buf);
931,413✔
4375
    if (tlen != 0) {
931,413✔
4376
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
931,413✔
4377
      if (varstr == NULL) {
931,413✔
4378
        sdbRelease(pSdb, pUser);
×
4379
        sdbCancelFetch(pSdb, pShow->pIter);
×
4380
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
4381
      }
4382
      varDataSetLen(varstr, tlen);
931,413✔
4383
      (void)memcpy(varDataVal(varstr), buf, tlen);
931,413✔
4384

4385
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
931,413✔
4386
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
931,413✔
4387

4388
      taosMemoryFreeClear(buf);
931,413✔
4389
    } else {
4390
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4391
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
4392
    }
4393

4394
    cols++;
931,413✔
4395
    tlen = convertTimeRangesToStr(pUser, &buf);
931,413✔
4396
    if (tlen != 0) {
931,413✔
4397
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
931,413✔
4398
      if (varstr == NULL) {
931,413✔
4399
        sdbRelease(pSdb, pUser);
×
4400
        sdbCancelFetch(pSdb, pShow->pIter);
×
4401
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
4402
      }
4403
      varDataSetLen(varstr, tlen);
931,413✔
4404
      (void)memcpy(varDataVal(varstr), buf, tlen);
931,413✔
4405

4406
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
931,413✔
4407
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
931,413✔
4408

4409
      taosMemoryFreeClear(buf);
931,413✔
4410
    } else {
4411
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4412
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
4413
    }
4414

4415
    if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
931,413✔
4416
      void  *pIter = NULL;
931,413✔
4417
      size_t klen = 0, tlen = 0;
931,413✔
4418
      char  *pBuf = POINTER_SHIFT(tBuf, VARSTR_HEADER_SIZE);
931,413✔
4419
      while ((pIter = taosHashIterate(pUser->roles, pIter))) {
2,112,686✔
4420
        char *roleName = taosHashGetKey(pIter, &klen);
1,181,273✔
4421
        tlen += snprintf(pBuf + tlen, bufSize - tlen, "%s,", roleName);
1,181,273✔
4422
      }
4423
      if (tlen > 0) {
931,413✔
4424
        pBuf[tlen - 1] = 0;  // remove last ','
931,413✔
4425
      } else {
4426
        pBuf[0] = 0;
×
4427
      }
4428
      varDataSetLen(tBuf, tlen);
931,413✔
4429
      COL_DATA_SET_VAL_GOTO((const char *)tBuf, false, pUser, pShow->pIter, _exit);
931,413✔
4430
    }
4431

4432
    numOfRows++;
931,413✔
4433
    sdbRelease(pSdb, pUser);
931,413✔
4434
  }
4435

4436
  pShow->numOfRows += numOfRows;
124,778✔
4437
_exit:
124,778✔
4438
  taosMemoryFreeClear(buf);
124,778✔
4439
  taosMemoryFreeClear(varstr);
124,778✔
4440
  if (code < 0) {
124,778✔
4441
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4442
    TAOS_RETURN(code);
×
4443
  }
4444
  return numOfRows;
124,778✔
4445
}
4446

4447
static int32_t mndRetrieveUsersFull(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
11,340✔
4448
  int32_t numOfRows = 0;
11,340✔
4449
#ifdef TD_ENTERPRISE
4450
  SMnode   *pMnode = pReq->info.node;
11,340✔
4451
  SSdb     *pSdb = pMnode->pSdb;
11,340✔
4452
  SUserObj *pUser = NULL;
11,340✔
4453
  int32_t   code = 0;
11,340✔
4454
  int32_t   lino = 0;
11,340✔
4455
  int32_t   cols = 0;
11,340✔
4456
  int8_t    flag = 0;
11,340✔
4457
  char     *pWrite = NULL;
11,340✔
4458
  char     *buf = NULL;
11,340✔
4459
  char     *varstr = NULL;
11,340✔
4460
  char     *pBuf = NULL;
11,340✔
4461
  char      tBuf[TSDB_MAX_SUBROLE * TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
11,340✔
4462
  int32_t   bufSize = sizeof(tBuf) - VARSTR_HEADER_SIZE;
11,340✔
4463

4464
  while (numOfRows < rows) {
506,016✔
4465
    pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
506,016✔
4466
    if (pShow->pIter == NULL) break;
506,016✔
4467

4468
    cols = 0;
494,676✔
4469
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
494,676✔
4470
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
494,676✔
4471
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
494,676✔
4472
    COL_DATA_SET_VAL_GOTO((const char *)name, false, pUser, pShow->pIter, _exit);
494,676✔
4473

4474
    cols++;
494,676✔
4475
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
494,676✔
4476
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->superUser, false, pUser, pShow->pIter, _exit);
494,676✔
4477

4478
    cols++;
494,676✔
4479
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
494,676✔
4480
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->enable, false, pUser, pShow->pIter, _exit);
494,676✔
4481

4482
    cols++;
494,676✔
4483
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
494,676✔
4484
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sysInfo, false, pUser, pShow->pIter, _exit);
494,676✔
4485

4486
    cols++;
494,676✔
4487
    flag = pUser->createdb ? 1 : 0;
494,676✔
4488
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
494,676✔
4489
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
494,676✔
4490

4491
    cols++;
494,676✔
4492
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
494,676✔
4493
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->createdTime, false, pUser, pShow->pIter, _exit);
494,676✔
4494

4495
    cols++;
494,676✔
4496
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
494,676✔
4497
    flag = mndIsTotpEnabledUser(pUser) ? 1 : 0;
494,676✔
4498
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
494,676✔
4499

4500
    cols++;
494,676✔
4501
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
494,676✔
4502
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->changePass, false, pUser, pShow->pIter, _exit);
494,676✔
4503

4504
    cols++;
494,676✔
4505
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
494,676✔
4506
    char pass[TSDB_PASSWORD_LEN + VARSTR_HEADER_SIZE] = {0};
494,676✔
4507
    STR_WITH_MAXSIZE_TO_VARSTR(pass, pUser->passwords[0].pass, pShow->pMeta->pSchemas[cols].bytes);
494,676✔
4508
    COL_DATA_SET_VAL_GOTO((const char *)pass, false, pUser, pShow->pIter, _exit);
494,676✔
4509

4510
    cols++;
494,676✔
4511
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
494,676✔
4512
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sessionPerUser, false, pUser, pShow->pIter, _exit);
494,676✔
4513

4514
    cols++;
494,676✔
4515
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
494,676✔
4516
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->connectTime, false, pUser, pShow->pIter, _exit);
494,676✔
4517

4518
    cols++;
494,676✔
4519
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
494,676✔
4520
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->connectIdleTime, false, pUser, pShow->pIter, _exit);
494,676✔
4521

4522
    cols++;
494,676✔
4523
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
494,676✔
4524
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->callPerSession, false, pUser, pShow->pIter, _exit);
494,676✔
4525

4526
    cols++;
494,676✔
4527
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
494,676✔
4528
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->vnodePerCall, false, pUser, pShow->pIter, _exit);
494,676✔
4529

4530
    cols++;
494,676✔
4531
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
494,676✔
4532
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->failedLoginAttempts, false, pUser, pShow->pIter, _exit);
494,676✔
4533

4534
    cols++;
494,676✔
4535
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
494,676✔
4536
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordLifeTime, false, pUser, pShow->pIter, _exit);
494,676✔
4537

4538
    cols++;
494,676✔
4539
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
494,676✔
4540
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordReuseTime, false, pUser, pShow->pIter, _exit);
494,676✔
4541

4542
    cols++;
494,676✔
4543
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
494,676✔
4544
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordReuseMax, false, pUser, pShow->pIter, _exit);
494,676✔
4545

4546
    cols++;
494,676✔
4547
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
494,676✔
4548
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordLockTime, false, pUser, pShow->pIter, _exit);
494,676✔
4549

4550
    cols++;
494,676✔
4551
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
494,676✔
4552
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordGraceTime, false, pUser, pShow->pIter, _exit);
494,676✔
4553

4554
    cols++;
494,676✔
4555
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
494,676✔
4556
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->inactiveAccountTime, false, pUser, pShow->pIter, _exit);
494,676✔
4557

4558
    cols++;
494,676✔
4559
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
494,676✔
4560
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->allowTokenNum, false, pUser, pShow->pIter, _exit);
494,676✔
4561

4562
    cols++;
494,676✔
4563
    int32_t tlen = convertIpWhiteListToStr(pUser, &buf);
494,676✔
4564
    if (tlen != 0) {
494,676✔
4565
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
494,676✔
4566
      if (varstr == NULL) {
494,676✔
4567
        sdbRelease(pSdb, pUser);
×
4568
        sdbCancelFetch(pSdb, pShow->pIter);
×
4569
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
4570
      }
4571
      varDataSetLen(varstr, tlen);
494,676✔
4572
      (void)memcpy(varDataVal(varstr), buf, tlen);
494,676✔
4573

4574
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
494,676✔
4575
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
494,676✔
4576

4577
      taosMemoryFreeClear(buf);
494,676✔
4578
    } else {
4579
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4580
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
4581
    }
4582

4583
    cols++;
494,676✔
4584
    tlen = convertTimeRangesToStr(pUser, &buf);
494,676✔
4585
    if (tlen != 0) {
494,676✔
4586
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
494,676✔
4587
      if (varstr == NULL) {
494,676✔
4588
        sdbRelease(pSdb, pUser);
×
4589
        sdbCancelFetch(pSdb, pShow->pIter);
×
4590
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
4591
      }
4592
      varDataSetLen(varstr, tlen);
494,676✔
4593
      (void)memcpy(varDataVal(varstr), buf, tlen);
494,676✔
4594

4595
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
494,676✔
4596
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
494,676✔
4597

4598
      taosMemoryFreeClear(buf);
494,676✔
4599
    } else {
4600
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4601
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
4602
    }
4603

4604
    if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
494,676✔
4605
      void  *pIter = NULL;
494,676✔
4606
      size_t klen = 0, tlen = 0;
494,676✔
4607
      char  *pBuf = POINTER_SHIFT(tBuf, VARSTR_HEADER_SIZE);
494,676✔
4608
      while ((pIter = taosHashIterate(pUser->roles, pIter))) {
1,012,032✔
4609
        char *roleName = taosHashGetKey(pIter, &klen);
517,356✔
4610
        tlen += snprintf(pBuf + tlen, bufSize - tlen, "%s,", roleName);
517,356✔
4611
      }
4612
      if (tlen > 0) {
494,676✔
4613
        pBuf[tlen - 1] = 0;  // remove last ','
494,676✔
4614
      } else {
4615
        pBuf[0] = 0;
×
4616
      }
4617
      varDataSetLen(tBuf, tlen);
494,676✔
4618
      COL_DATA_SET_VAL_GOTO((const char *)tBuf, false, pUser, pShow->pIter, _exit);
494,676✔
4619
    }
4620

4621
    numOfRows++;
494,676✔
4622
    sdbRelease(pSdb, pUser);
494,676✔
4623
  }
4624

4625
  pShow->numOfRows += numOfRows;
11,340✔
4626
_exit:
11,340✔
4627
  taosMemoryFreeClear(buf);
11,340✔
4628
  taosMemoryFreeClear(varstr);
11,340✔
4629
  if (code < 0) {
11,340✔
4630
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4631
    TAOS_RETURN(code);
×
4632
  }
4633
#endif
4634
  return numOfRows;
11,340✔
4635
}
4636

4637
static void mndCancelGetNextUser(SMnode *pMnode, void *pIter) {
×
4638
  SSdb *pSdb = pMnode->pSdb;
×
4639
  sdbCancelFetchByType(pSdb, pIter, SDB_USER);
×
4640
}
×
4641

4642
static int32_t mndLoopHash(SHashObj *hash, char *priType, SSDataBlock *pBlock, int32_t *pNumOfRows, SSdb *pSdb,
×
4643
                           SUserObj *pUser, SShowObj *pShow, char **condition, char **sql) {
4644
  char   *value = taosHashIterate(hash, NULL);
×
4645
  char   *user = pUser->user;
×
4646
  int32_t code = 0;
×
4647
  int32_t lino = 0;
×
4648
  int32_t cols = 0;
×
4649
  int32_t numOfRows = *pNumOfRows;
×
4650

4651
  while (value != NULL) {
×
4652
    cols = 0;
×
4653
    char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
×
4654
    STR_WITH_MAXSIZE_TO_VARSTR(userName, user, pShow->pMeta->pSchemas[cols].bytes);
×
4655
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4656
    COL_DATA_SET_VAL_GOTO((const char *)userName, false, NULL, NULL, _exit);
×
4657

4658
    char privilege[20] = {0};
×
4659
    STR_WITH_MAXSIZE_TO_VARSTR(privilege, priType, pShow->pMeta->pSchemas[cols].bytes);
×
4660
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4661
    COL_DATA_SET_VAL_GOTO((const char *)privilege, false, NULL, NULL, _exit);
×
4662

4663
    size_t keyLen = 0;
×
4664
    void  *key = taosHashGetKey(value, &keyLen);
×
4665

4666
    char dbName[TSDB_DB_NAME_LEN] = {0};
×
4667
    (void)mndExtractShortDbNameFromStbFullName(key, dbName);
×
4668
    char dbNameContent[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
×
4669
    STR_WITH_MAXSIZE_TO_VARSTR(dbNameContent, dbName, pShow->pMeta->pSchemas[cols].bytes);
×
4670
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4671
    COL_DATA_SET_VAL_GOTO((const char *)dbNameContent, false, NULL, NULL, _exit);
×
4672

4673
    char tableName[TSDB_TABLE_NAME_LEN] = {0};
×
4674
    mndExtractTbNameFromStbFullName(key, tableName, TSDB_TABLE_NAME_LEN);
×
4675
    char tableNameContent[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
×
4676
    STR_WITH_MAXSIZE_TO_VARSTR(tableNameContent, tableName, pShow->pMeta->pSchemas[cols].bytes);
×
4677
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4678
    COL_DATA_SET_VAL_GOTO((const char *)tableNameContent, false, NULL, NULL, _exit);
×
4679

4680
    if (strcmp("t", value) != 0 && strcmp("v", value) != 0) {
×
4681
      SNode  *pAst = NULL;
×
4682
      int32_t sqlLen = 0;
×
4683
      size_t  bufSz = strlen(value) + 1;
×
4684
      if (bufSz < 6) bufSz = 6;
×
4685
      TAOS_MEMORY_REALLOC(*sql, bufSz);
×
4686
      if (*sql == NULL) {
×
4687
        code = terrno;
×
4688
        goto _exit;
×
4689
      }
4690
      TAOS_MEMORY_REALLOC(*condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
×
4691
      if ((*condition) == NULL) {
×
4692
        code = terrno;
×
4693
        goto _exit;
×
4694
      }
4695

4696
      if (nodesStringToNode(value, &pAst) == 0) {
×
4697
        if (nodesNodeToSQLFormat(pAst, *sql, bufSz, &sqlLen, true) != 0) {
×
4698
          sqlLen = tsnprintf(*sql, bufSz, "error");
×
4699
        }
4700
        nodesDestroyNode(pAst);
×
4701
      }
4702

4703
      if (sqlLen == 0) {
×
4704
        sqlLen = tsnprintf(*sql, bufSz, "error");
×
4705
      }
4706

4707
      STR_WITH_MAXSIZE_TO_VARSTR((*condition), (*sql), pShow->pMeta->pSchemas[cols].bytes);
×
4708

4709
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4710
      COL_DATA_SET_VAL_GOTO((const char *)(*condition), false, NULL, NULL, _exit);
×
4711

4712
      char notes[2] = {0};
×
4713
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
×
4714
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4715
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, NULL, NULL, _exit);
×
4716
    } else {
4717
      TAOS_MEMORY_REALLOC(*condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
×
4718
      if ((*condition) == NULL) {
×
4719
        code = terrno;
×
4720
        goto _exit;
×
4721
      }
4722
      STR_WITH_MAXSIZE_TO_VARSTR((*condition), "", pShow->pMeta->pSchemas[cols].bytes);
×
4723
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4724
      COL_DATA_SET_VAL_GOTO((const char *)(*condition), false, NULL, NULL, _exit);
×
4725

4726
      char notes[64 + VARSTR_HEADER_SIZE] = {0};
×
4727
      STR_WITH_MAXSIZE_TO_VARSTR(notes, value[0] == 'v' ? "view" : "", sizeof(notes));
×
4728
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4729
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, NULL, NULL, _exit);
×
4730
    }
4731

4732
    numOfRows++;
×
4733
    value = taosHashIterate(hash, value);
×
4734
  }
4735
  *pNumOfRows = numOfRows;
×
4736
_exit:
×
4737
  if (code < 0) {
×
4738
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4739
    sdbRelease(pSdb, pUser);
×
4740
    sdbCancelFetch(pSdb, pShow->pIter);
×
4741
  }
4742
  TAOS_RETURN(code);
×
4743
}
4744

4745
#if 0
4746
static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
4747
  int32_t   code = 0;
4748
  int32_t   lino = 0;
4749
  SMnode   *pMnode = pReq->info.node;
4750
  SSdb     *pSdb = pMnode->pSdb;
4751
  int32_t   numOfRows = 0;
4752
  SUserObj *pUser = NULL;
4753
  int32_t   cols = 0;
4754
  char     *pWrite = NULL;
4755
  char     *condition = NULL;
4756
  char     *sql = NULL;
4757

4758
  bool fetchNextUser = pShow->restore ? false : true;
4759
  pShow->restore = false;
4760

4761
  while (numOfRows < rows) {
4762
    if (fetchNextUser) {
4763
      pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
4764
      if (pShow->pIter == NULL) break;
4765
    } else {
4766
      fetchNextUser = true;
4767
      void *pKey = taosHashGetKey(pShow->pIter, NULL);
4768
      pUser = sdbAcquire(pSdb, SDB_USER, pKey);
4769
      if (!pUser) {
4770
        continue;
4771
      }
4772
    }
4773

4774
    int32_t numOfReadDbs = 0; //taosHashGetSize(pUser->readDbs);
4775
    int32_t numOfWriteDbs = 0; //taosHashGetSize(pUser->writeDbs);
4776
    int32_t numOfTopics = taosHashGetSize(pUser->topics);
4777
    int32_t numOfReadTbs = taosHashGetSize(pUser->selectTbs);
4778
    int32_t numOfWriteTbs = taosHashGetSize(pUser->insertTbs);
4779
    int32_t numOfAlterTbs = taosHashGetSize(pUser->alterTbs);
4780
    int32_t numOfReadViews = taosHashGetSize(pUser->readViews);
4781
    int32_t numOfWriteViews = taosHashGetSize(pUser->writeViews);
4782
    int32_t numOfAlterViews = taosHashGetSize(pUser->alterViews);
4783
    if (numOfRows + numOfReadDbs + numOfWriteDbs + numOfTopics + numOfReadTbs + numOfWriteTbs + numOfAlterTbs +
4784
            numOfReadViews + numOfWriteViews + numOfAlterViews >=
4785
        rows) {
4786
      mInfo(
4787
          "will restore. current num of rows: %d, read dbs %d, write dbs %d, topics %d, read tables %d, write tables "
4788
          "%d, alter tables %d, select views %d, write views %d, alter views %d",
4789
          numOfRows, numOfReadDbs, numOfWriteDbs, numOfTopics, numOfReadTbs, numOfWriteTbs, numOfAlterTbs,
4790
          numOfReadViews, numOfWriteViews, numOfAlterViews);
4791
      pShow->restore = true;
4792
      sdbRelease(pSdb, pUser);
4793
      break;
4794
    }
4795

4796
    if (pUser->superUser) {
4797
      cols = 0;
4798
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
4799
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
4800
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4801
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
4802

4803
      char privilege[20] = {0};
4804
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "all", pShow->pMeta->pSchemas[cols].bytes);
4805
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4806
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
4807

4808
      char objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4809
      STR_WITH_MAXSIZE_TO_VARSTR(objName, "all", pShow->pMeta->pSchemas[cols].bytes);
4810
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4811
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
4812

4813
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4814
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
4815
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4816
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
4817

4818
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
4819
      if (condition == NULL) {
4820
        sdbRelease(pSdb, pUser);
4821
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
4822
      }
4823
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
4824
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4825
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
4826

4827
      char notes[2] = {0};
4828
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
4829
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4830
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
4831

4832
      numOfRows++;
4833
    }
4834
#if 0
4835
    char *db = taosHashIterate(pUser->readDbs, NULL);
4836
    while (db != NULL) {
4837
      cols = 0;
4838
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
4839
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
4840
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4841
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
4842

4843
      char privilege[20] = {0};
4844
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "read", pShow->pMeta->pSchemas[cols].bytes);
4845
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4846
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
4847

4848
      SName name = {0};
4849
      char  objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4850
      code = tNameFromString(&name, db, T_NAME_ACCT | T_NAME_DB);
4851
      if (code < 0) {
4852
        sdbRelease(pSdb, pUser);
4853
        sdbCancelFetch(pSdb, pShow->pIter);
4854
        TAOS_CHECK_GOTO(code, &lino, _exit);
4855
      }
4856
      (void)tNameGetDbName(&name, varDataVal(objName));
4857
      varDataSetLen(objName, strlen(varDataVal(objName)));
4858
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4859
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
4860

4861
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4862
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
4863
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4864
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
4865

4866
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
4867
      if (condition == NULL) {
4868
        sdbRelease(pSdb, pUser);
4869
        sdbCancelFetch(pSdb, pShow->pIter);
4870
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
4871
      }
4872
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
4873
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4874
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
4875

4876
      char notes[2] = {0};
4877
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
4878
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4879
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
4880

4881
      numOfRows++;
4882
      db = taosHashIterate(pUser->readDbs, db);
4883
    }
4884

4885
    db = taosHashIterate(pUser->writeDbs, NULL);
4886
    while (db != NULL) {
4887
      cols = 0;
4888
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
4889
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
4890
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4891
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
4892

4893
      char privilege[20] = {0};
4894
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "write", pShow->pMeta->pSchemas[cols].bytes);
4895
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4896
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
4897

4898
      SName name = {0};
4899
      char  objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4900
      code = tNameFromString(&name, db, T_NAME_ACCT | T_NAME_DB);
4901
      if (code < 0) {
4902
        sdbRelease(pSdb, pUser);
4903
        sdbCancelFetch(pSdb, pShow->pIter);
4904
        TAOS_CHECK_GOTO(code, &lino, _exit);
4905
      }
4906
      (void)tNameGetDbName(&name, varDataVal(objName));
4907
      varDataSetLen(objName, strlen(varDataVal(objName)));
4908
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4909
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
4910

4911
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4912
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
4913
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4914
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
4915

4916
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
4917
      if (condition == NULL) {
4918
        sdbRelease(pSdb, pUser);
4919
        sdbCancelFetch(pSdb, pShow->pIter);
4920
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
4921
      }
4922
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
4923
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4924
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
4925

4926
      char notes[2] = {0};
4927
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
4928
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4929
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
4930

4931
      numOfRows++;
4932
      db = taosHashIterate(pUser->writeDbs, db);
4933
    }
4934
#endif
4935
    TAOS_CHECK_EXIT(mndLoopHash(pUser->selectTbs, "select", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
4936

4937
    TAOS_CHECK_EXIT(mndLoopHash(pUser->insertTbs, "insert", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
4938

4939
    TAOS_CHECK_EXIT(mndLoopHash(pUser->alterTbs, "alter", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
4940

4941
    TAOS_CHECK_EXIT(mndLoopHash(pUser->readViews, "read", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
4942

4943
    TAOS_CHECK_EXIT(mndLoopHash(pUser->writeViews, "write", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
4944

4945
    TAOS_CHECK_EXIT(mndLoopHash(pUser->alterViews, "alter", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
4946

4947
    char *topic = taosHashIterate(pUser->topics, NULL);
4948
    while (topic != NULL) {
4949
      cols = 0;
4950
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
4951
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
4952
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4953
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
4954

4955
      char privilege[20] = {0};
4956
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "subscribe", pShow->pMeta->pSchemas[cols].bytes);
4957
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4958
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
4959

4960
      char topicName[TSDB_TOPIC_NAME_LEN + VARSTR_HEADER_SIZE + 5] = {0};
4961
      tstrncpy(varDataVal(topicName), mndGetDbStr(topic), TSDB_TOPIC_NAME_LEN - 2);
4962
      varDataSetLen(topicName, strlen(varDataVal(topicName)));
4963
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4964
      COL_DATA_SET_VAL_GOTO((const char *)topicName, false, pUser, pShow->pIter, _exit);
4965

4966
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4967
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
4968
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4969
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
4970

4971
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
4972
      if (condition == NULL) {
4973
        sdbRelease(pSdb, pUser);
4974
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
4975
      }
4976
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
4977
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4978
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
4979

4980
      char notes[2] = {0};
4981
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
4982
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4983
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
4984

4985
      numOfRows++;
4986
      topic = taosHashIterate(pUser->topics, topic);
4987
    }
4988

4989
    sdbRelease(pSdb, pUser);
4990
  }
4991

4992
  pShow->numOfRows += numOfRows;
4993
_exit:
4994
  taosMemoryFreeClear(condition);
4995
  taosMemoryFreeClear(sql);
4996
  if (code < 0) {
4997
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
4998
    TAOS_RETURN(code);
4999
  }
5000
  return numOfRows;
5001
}
5002
#endif
5003

5004
static int32_t mndShowTablePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows, SUserObj *pObj,
136,884✔
5005
                                      SHashObj *privTbs, EPrivType privType, char *pBuf, int32_t bufSize, int32_t *pNumOfRows) {
5006
  int32_t     code = 0, lino = 0;
136,884✔
5007
  SMnode     *pMnode = pReq->info.node;
136,884✔
5008
  SSdb       *pSdb = pMnode->pSdb;
136,884✔
5009
  int32_t     cols = 0, qBufSize = bufSize - VARSTR_HEADER_SIZE;
136,884✔
5010
  int32_t     numOfRows = *pNumOfRows;
136,884✔
5011
  char       *qBuf = NULL;
136,884✔
5012
  char       *sql = NULL;
136,884✔
5013
  char        roleName[TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
136,884✔
5014
  const char *privName = privInfoGetName(privType);
136,884✔
5015

5016
  STR_WITH_MAXSIZE_TO_VARSTR(roleName, pObj->name, pShow->pMeta->pSchemas[cols].bytes);
136,884✔
5017

5018
  void *pIter = NULL;
136,884✔
5019
  while ((pIter = taosHashIterate(privTbs, pIter))) {
171,416✔
5020
    SPrivTblPolicies *pPolices = (SPrivTblPolicies *)pIter;
34,532✔
5021
    SArray           *tblPolicies = pPolices->policy;
34,532✔
5022

5023
    char   *key = taosHashGetKey(pPolices, NULL);
34,532✔
5024
    int32_t objType = PRIV_OBJ_UNKNOWN;
34,532✔
5025
    char    dbName[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
34,532✔
5026
    char    tblName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
34,532✔
5027
    if ((code = privObjKeyParse(key, &objType, dbName, sizeof(dbName), tblName, sizeof(tblName), false))) {
34,532✔
5028
      sdbRelease(pSdb, pObj);
×
5029
      sdbCancelFetch(pSdb, pShow->pIter);
×
5030
      TAOS_CHECK_EXIT(code);
×
5031
    }
5032

5033
    int32_t nTbPolicies = taosArrayGetSize(tblPolicies);
34,532✔
5034
    for (int32_t i = 0; i < nTbPolicies; ++i) {
69,064✔
5035
      SPrivTblPolicy *tbPolicy = (SPrivTblPolicy *)TARRAY_GET_ELEM(tblPolicies, i);
34,532✔
5036
      cols = 0;
34,532✔
5037
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
34,532✔
5038
      COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
34,532✔
5039

5040
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
34,532✔
5041
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privName, pShow->pMeta->pSchemas[cols].bytes);
34,532✔
5042
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
34,532✔
5043
      }
5044

5045
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
34,532✔
5046
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privObjGetName(objType), pShow->pMeta->pSchemas[cols].bytes);
34,532✔
5047
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
34,532✔
5048
      }
5049

5050
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
34,532✔
5051
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, dbName, pShow->pMeta->pSchemas[cols].bytes);
34,532✔
5052
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
34,532✔
5053
      }
5054

5055
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
34,532✔
5056
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, tblName, pShow->pMeta->pSchemas[cols].bytes);
34,532✔
5057
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
34,532✔
5058
      }
5059
      // condition
5060
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
34,532✔
5061
        SNode  *pAst = NULL;
34,532✔
5062
        int32_t sqlLen = 0;
34,532✔
5063
        qBuf = POINTER_SHIFT(pBuf, VARSTR_HEADER_SIZE);
34,532✔
5064
        if (tbPolicy->condLen > 0) {
34,532✔
5065
          if (nodesStringToNode(tbPolicy->cond, &pAst) == 0) {
34,532✔
5066
            if (nodesNodeToSQLFormat(pAst, qBuf, qBufSize, &sqlLen, true) != 0) {
34,532✔
5067
              sqlLen = tsnprintf(qBuf, qBufSize, "error");
×
5068
            }
5069
            nodesDestroyNode(pAst);
34,532✔
5070
          }
5071
          if (sqlLen == 0) {
34,532✔
5072
            sqlLen = tsnprintf(qBuf, qBufSize, "error");
×
5073
          }
5074
        } else {
5075
          sqlLen = tsnprintf(qBuf, qBufSize, "");
×
5076
        }
5077
        varDataSetLen(pBuf, sqlLen);
34,532✔
5078
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
34,532✔
5079
      }
5080
      // notes
5081
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
34,532✔
5082
        STR_WITH_MAXSIZE_TO_VARSTR((pBuf), "", 2);
34,532✔
5083
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
34,532✔
5084
      }
5085
      // columns
5086
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
34,532✔
5087
        SArray *pCols = tbPolicy->cols;
34,532✔
5088
        int32_t nCols = taosArrayGetSize(pCols);
34,532✔
5089
        int32_t totalLen = 0;
34,532✔
5090
        qBuf = POINTER_SHIFT(pBuf, VARSTR_HEADER_SIZE);
34,532✔
5091
        for (int32_t j = 0; j < nCols; ++j) {
34,532✔
5092
          SColNameFlag *pCol = (SColNameFlag *)TARRAY_GET_ELEM(pCols, j);
×
5093
          char          tmpBuf[TSDB_COL_NAME_LEN + 16] = {0};
×
5094
          int32_t       tmpLen = 0;
×
5095
          if (IS_MASK_ON(pCol)) {
×
5096
            tmpLen = snprintf(tmpBuf, sizeof(tmpBuf), "mask(%s)%s", pCol->colName, j == nCols - 1 ? "" : ",");
×
5097
          } else {
5098
            tmpLen = snprintf(tmpBuf, sizeof(tmpBuf), "%s%s", pCol->colName, j == nCols - 1 ? "" : ",");
×
5099
          }
5100
          if(totalLen + tmpLen > qBufSize) {
×
5101
            break;
×
5102
          }
5103
          (void)memcpy(POINTER_SHIFT(qBuf, totalLen), tmpBuf, tmpLen);
×
5104
          totalLen += tmpLen;
×
5105
        }
5106
        varDataSetLen(pBuf, totalLen);
34,532✔
5107
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
34,532✔
5108
      }
5109
      // update_time
5110
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
34,532✔
5111
        char updateTime[40] = {0};
34,532✔
5112
        (void)formatTimestampLocal(updateTime, tbPolicy->updateUs, TSDB_TIME_PRECISION_MICRO);
34,532✔
5113
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, updateTime, pShow->pMeta->pSchemas[cols].bytes);
34,532✔
5114
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
34,532✔
5115
      }
5116
      ++numOfRows;
34,532✔
5117
    }
5118
  }
5119
  *pNumOfRows = numOfRows;
136,884✔
5120
_exit:
136,884✔
5121
  TAOS_RETURN(code);
136,884✔
5122
}
5123

5124
static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
5,168✔
5125
  int32_t   code = 0, lino = 0;
5,168✔
5126
  SMnode   *pMnode = pReq->info.node;
5,168✔
5127
  SSdb     *pSdb = pMnode->pSdb;
5,168✔
5128
  int32_t   numOfRows = 0;
5,168✔
5129
  int32_t   cols = 0;
5,168✔
5130
  SUserObj *pObj = NULL;
5,168✔
5131
  char     *pBuf = NULL, *qBuf = NULL;
5,168✔
5132
  char     *sql = NULL;
5,168✔
5133
  char      roleName[TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
5,168✔
5134
  int32_t   bufSize = TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE;
5,168✔
5135

5136
  bool fetchNextInstance = pShow->restore ? false : true;
5,168✔
5137
  pShow->restore = false;
5,168✔
5138

5139
  while (numOfRows < rows) {
39,389✔
5140
    if (fetchNextInstance) {
39,389✔
5141
      pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pObj);
39,389✔
5142
      if (pShow->pIter == NULL) break;
39,389✔
5143
    } else {
5144
      fetchNextInstance = true;
×
5145
      void *pKey = taosHashGetKey(pShow->pIter, NULL);
×
5146
      if (!(pObj = sdbAcquire(pSdb, SDB_USER, pKey))) {
×
5147
        continue;
×
5148
      }
5149
    }
5150

5151
    int32_t nSysPrivileges = 0, nObjPrivileges = 0;
34,221✔
5152
    if (nSysPrivileges + nObjPrivileges >= rows) {
34,221✔
5153
      pShow->restore = true;
×
5154
      sdbRelease(pSdb, pObj);
×
5155
      break;
×
5156
    }
5157

5158
    if (!pBuf && !(pBuf = taosMemoryMalloc(bufSize))) {
34,221✔
5159
      sdbCancelFetch(pSdb, pShow->pIter);
×
5160
      sdbRelease(pSdb, pObj);
×
5161
      TAOS_CHECK_EXIT(terrno);
×
5162
    }
5163

5164
    cols = 0;
34,221✔
5165
    STR_WITH_MAXSIZE_TO_VARSTR(roleName, pObj->name, pShow->pMeta->pSchemas[cols].bytes);
34,221✔
5166

5167
    // system privileges
5168
    SPrivIter privIter = {0};
34,221✔
5169
    privIterInit(&privIter, &pObj->sysPrivs);
34,221✔
5170
    SPrivInfo *pPrivInfo = NULL;
34,221✔
5171
    while (privIterNext(&privIter, &pPrivInfo)) {
36,159✔
5172
      cols = 0;
1,938✔
5173
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
1,938✔
5174
      COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
1,938✔
5175

5176
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
1,938✔
5177
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, pPrivInfo->name, pShow->pMeta->pSchemas[cols].bytes);
1,938✔
5178
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
1,938✔
5179
      }
5180
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
1,938✔
5181
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privObjGetName(PRIV_OBJ_CLUSTER), pShow->pMeta->pSchemas[cols].bytes);
1,938✔
5182
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
1,938✔
5183
      }
5184
      // skip db, table, condition, notes, columns, update_time
5185
      COL_DATA_SET_EMPTY_VARCHAR(pBuf, 6);
13,566✔
5186
      numOfRows++;
1,938✔
5187
    }
5188

5189
    // object privileges
5190
    void *pIter = NULL;
34,221✔
5191
    while ((pIter = taosHashIterate(pObj->objPrivs, pIter))) {
54,088✔
5192
      SPrivObjPolicies *pPolices = (SPrivObjPolicies *)pIter;
19,867✔
5193

5194
      char   *key = taosHashGetKey(pPolices, NULL);
19,867✔
5195
      int32_t objType = PRIV_OBJ_UNKNOWN;
19,867✔
5196
      char    dbName[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
19,867✔
5197
      char    tblName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
19,867✔
5198
      if ((code = privObjKeyParse(key, &objType, dbName, sizeof(dbName), tblName, sizeof(tblName), false))) {
19,867✔
5199
        sdbRelease(pSdb, pObj);
×
5200
        sdbCancelFetch(pSdb, pShow->pIter);
×
5201
        TAOS_CHECK_EXIT(code);
×
5202
      }
5203

5204
      SPrivIter privIter = {0};
19,867✔
5205
      privIterInit(&privIter, &pPolices->policy);
19,867✔
5206
      SPrivInfo *pPrivInfo = NULL;
19,867✔
5207
      while (privIterNext(&privIter, &pPrivInfo)) {
110,395✔
5208
        cols = 0;
90,528✔
5209
        SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
90,528✔
5210
        COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
90,528✔
5211

5212
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
90,528✔
5213
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, pPrivInfo->name, pShow->pMeta->pSchemas[cols].bytes);
90,528✔
5214
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
90,528✔
5215
        }
5216

5217
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
90,528✔
5218
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privObjGetName(objType), pShow->pMeta->pSchemas[cols].bytes);
90,528✔
5219
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
90,528✔
5220
        }
5221

5222
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
90,528✔
5223
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, dbName, pShow->pMeta->pSchemas[cols].bytes);
90,528✔
5224
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
90,528✔
5225
        }
5226

5227
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
90,528✔
5228
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, tblName, pShow->pMeta->pSchemas[cols].bytes);
90,528✔
5229
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
90,528✔
5230
        }
5231

5232
        // skip condition, notes, columns, update_time
5233
        COL_DATA_SET_EMPTY_VARCHAR(pBuf, 4);
452,640✔
5234

5235
        numOfRows++;
90,528✔
5236
      }
5237
    }
5238

5239
    // table level privileges
5240
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->selectTbs,
34,221✔
5241
                                           PRIV_TBL_SELECT, pBuf, bufSize, &numOfRows));
5242
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->insertTbs,
34,221✔
5243
                                           PRIV_TBL_INSERT, pBuf, bufSize, &numOfRows));
5244
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->updateTbs,
34,221✔
5245
                                           PRIV_TBL_UPDATE, pBuf, bufSize, &numOfRows));
5246
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->deleteTbs,
34,221✔
5247
                                           PRIV_TBL_DELETE, pBuf, bufSize, &numOfRows));
5248
#if 0
5249
    while ((pIter = taosHashIterate(pObj->selectTbs, pIter))) {
5250
      SPrivTblPolicies *pPolices = (SPrivTblPolicies *)pIter;
5251
      SArray           *tblPolicies = pPolices->policy;
5252

5253
      char   *key = taosHashGetKey(pPolices, NULL);
5254
      int32_t objType = PRIV_OBJ_UNKNOWN;
5255
      char    dbName[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
5256
      char    tblName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
5257
      if ((code = privObjKeyParse(key, &objType, dbName, sizeof(dbName), tblName, sizeof(tblName), false))) {
5258
        sdbRelease(pSdb, pObj);
5259
        sdbCancelFetch(pSdb, pShow->pIter);
5260
        TAOS_CHECK_EXIT(code);
5261
      }
5262

5263
      int32_t nTbPolicies = taosArrayGetSize(tblPolicies);
5264
      for (int32_t i = 0; i < nTbPolicies; ++i) {
5265
        SPrivTblPolicy *tbPolicy = (SPrivTblPolicy *)TARRAY_GET_ELEM(tblPolicies, i);
5266
        cols = 0;
5267
        SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
5268
        COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
5269

5270
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
5271
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privInfoGetName(PRIV_TBL_SELECT), pShow->pMeta->pSchemas[cols].bytes);
5272
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
5273
        }
5274

5275
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
5276
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, dbName, pShow->pMeta->pSchemas[cols].bytes);
5277
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
5278
        }
5279

5280
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
5281
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, tblName, pShow->pMeta->pSchemas[cols].bytes);
5282
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
5283
        }
5284

5285
        // skip condition, notes, columns, update_time
5286
        COL_DATA_SET_EMPTY_VARCHAR(pBuf, 4);
5287

5288
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
5289
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privObjGetName(objType), pShow->pMeta->pSchemas[cols].bytes);
5290
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
5291
        }
5292
        numOfRows++;
5293
      }
5294
    }
5295
#endif
5296
    sdbRelease(pSdb, pObj);
34,221✔
5297
  }
5298

5299
  pShow->numOfRows += numOfRows;
5,168✔
5300
_exit:
5,168✔
5301
  taosMemoryFreeClear(pBuf);
5,168✔
5302
  taosMemoryFreeClear(sql);
5,168✔
5303
  if (code < 0) {
5,168✔
5304
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
5305
    TAOS_RETURN(code);
×
5306
  }
5307
  return numOfRows;
5,168✔
5308
}
5309

5310
static void mndCancelGetNextPrivileges(SMnode *pMnode, void *pIter) {
×
5311
  SSdb *pSdb = pMnode->pSdb;
×
5312
  sdbCancelFetchByType(pSdb, pIter, SDB_USER);
×
5313
}
×
5314

5315
int32_t mndValidateUserAuthInfo(SMnode *pMnode, SUserAuthVersion *pUsers, int32_t numOfUses, void **ppRsp,
19,968,214✔
5316
                                int32_t *pRspLen, int64_t ipWhiteListVer) {
5317
  int32_t           code = 0;
19,968,214✔
5318
  int32_t           lino = 0;
19,968,214✔
5319
  int32_t           rspLen = 0;
19,968,214✔
5320
  void             *pRsp = NULL;
19,968,214✔
5321
  SUserAuthBatchRsp batchRsp = {0};
19,968,214✔
5322

5323
  batchRsp.pArray = taosArrayInit(numOfUses, sizeof(SGetUserAuthRsp));
19,968,214✔
5324
  if (batchRsp.pArray == NULL) {
19,967,716✔
5325
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
5326
  }
5327
  int64_t now = taosGetTimestampMs();
19,967,716✔
5328
  for (int32_t i = 0; i < numOfUses; ++i) {
40,177,448✔
5329
    SUserObj *pUser = NULL;
20,209,310✔
5330
    code = mndAcquireUser(pMnode, pUsers[i].user, &pUser);
20,209,440✔
5331
    if (pUser == NULL) {
20,209,310✔
5332
      if (TSDB_CODE_MND_USER_NOT_EXIST == code) {
332✔
5333
        SGetUserAuthRsp rsp = {.dropped = 1};
332✔
5334
        (void)memcpy(rsp.user, pUsers[i].user, TSDB_USER_LEN);
332✔
5335
        TSDB_CHECK_NULL(taosArrayPush(batchRsp.pArray, &rsp), code, lino, _OVER, TSDB_CODE_OUT_OF_MEMORY);
664✔
5336
      }
5337
      mError("user:%s, failed to auth user since %s", pUsers[i].user, tstrerror(code));
332✔
5338
      code = 0;
332✔
5339
      continue;
332✔
5340
    }
5341

5342
    pUsers[i].version = ntohl(pUsers[i].version);
20,208,978✔
5343
    if ((pUser->authVersion <= pUsers[i].version) && (ipWhiteListVer == pMnode->ipWhiteVer) &&
20,208,772✔
5344
        !mndNeedRetrieveRole(pUser)) {
×
5345
      mndReleaseUser(pMnode, pUser);
×
5346
      continue;
×
5347
    }
5348

5349
    SGetUserAuthRsp rsp = {0};
20,209,108✔
5350
    code = mndSetUserAuthRsp(pMnode, pUser, &rsp);
20,209,400✔
5351
    if (code) {
20,208,785✔
5352
      mndReleaseUser(pMnode, pUser);
×
5353
      tFreeSGetUserAuthRsp(&rsp);
×
5354
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
5355
    }
5356

5357
    if (!(taosArrayPush(batchRsp.pArray, &rsp))) {
40,418,185✔
5358
      code = terrno;
×
5359
      mndReleaseUser(pMnode, pUser);
×
5360
      tFreeSGetUserAuthRsp(&rsp);
×
5361
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
5362
    }
5363
    pUser->lastRoleRetrieve = now;  // update user's last retrieve time
20,209,400✔
5364
    mndReleaseUser(pMnode, pUser);
20,208,785✔
5365
  }
5366

5367
  if (taosArrayGetSize(batchRsp.pArray) <= 0) {
19,968,138✔
5368
    *ppRsp = NULL;
×
5369
    *pRspLen = 0;
×
5370

5371
    tFreeSUserAuthBatchRsp(&batchRsp);
×
5372
    return 0;
×
5373
  }
5374

5375
  rspLen = tSerializeSUserAuthBatchRsp(NULL, 0, &batchRsp);
19,968,214✔
5376
  if (rspLen < 0) {
19,967,251✔
5377
    TAOS_CHECK_GOTO(rspLen, &lino, _OVER);
×
5378
  }
5379
  pRsp = taosMemoryMalloc(rspLen);
19,967,251✔
5380
  if (pRsp == NULL) {
19,965,445✔
5381
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
5382
  }
5383
  rspLen = tSerializeSUserAuthBatchRsp(pRsp, rspLen, &batchRsp);
19,965,445✔
5384
  if (rspLen < 0) {
19,966,979✔
5385
    TAOS_CHECK_GOTO(rspLen, &lino, _OVER);
×
5386
  }
5387
_OVER:
19,966,979✔
5388
  tFreeSUserAuthBatchRsp(&batchRsp);
19,967,251✔
5389
  if (code < 0) {
19,967,615✔
5390
    for (int32_t i = 0; i < numOfUses; ++i) {
×
5391
      SUserObj *pUser = NULL;
×
5392
      if (mndAcquireUser(pMnode, pUsers[i].user, &pUser) != 0) {
×
5393
        continue;
×
5394
      }
5395
      pUser->lastRoleRetrieve = 0;  // reset last retrieve time on error
×
5396
      mndReleaseUser(pMnode, pUser);
×
5397
    }
5398
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
5399
    taosMemoryFreeClear(pRsp);
×
5400
    rspLen = 0;
×
5401
  }
5402
  *ppRsp = pRsp;
19,967,615✔
5403
  *pRspLen = rspLen;
19,966,944✔
5404

5405
  TAOS_RETURN(code);
19,965,571✔
5406
}
5407

5408
static int32_t mndRemoveDbPrivileges(SHashObj *pHash, const char *dbFName, int32_t dbFNameLen, int32_t *nRemoved) {
×
5409
  void *pVal = NULL;
×
5410
  while ((pVal = taosHashIterate(pHash, pVal))) {
×
5411
    size_t keyLen = 0;
×
5412
    char  *pKey = (char *)taosHashGetKey(pVal, &keyLen);
×
5413
    if (pKey == NULL || keyLen <= dbFNameLen) continue;
×
5414
    if ((*(pKey + dbFNameLen) == '.') && strncmp(pKey, dbFName, dbFNameLen) == 0) {
×
5415
      TAOS_CHECK_RETURN(taosHashRemove(pHash, pKey, keyLen));
×
5416
      if (nRemoved) ++(*nRemoved);
×
5417
    }
5418
  }
5419
  TAOS_RETURN(0);
×
5420
}
5421

5422
int32_t mndUserDropRole(SMnode *pMnode, STrans *pTrans, SRoleObj *pObj) {
×
5423
  int32_t   code = 0, lino = 0;
×
5424
  SSdb     *pSdb = pMnode->pSdb;
×
5425
  SUserObj *pUser = NULL;
×
5426
  void     *pIter = NULL;
×
5427

5428
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser))) {
×
5429
    SHashObj *pRole = taosHashGet(pUser->roles, pObj->name, strlen(pObj->name) + 1);
×
5430
    if (!pRole) {
×
5431
      sdbRelease(pSdb, pUser);
×
5432
      pUser = NULL;
×
5433
      continue;
×
5434
    }
5435

5436
    SUserObj newUser = {0};
×
5437
    TAOS_CHECK_EXIT(mndUserDupObj(pUser, &newUser));
×
5438
    code = taosHashRemove(newUser.roles, pObj->name, strlen(pObj->name) + 1);
×
5439
    if (code == TSDB_CODE_NOT_FOUND) {
×
5440
      sdbRelease(pSdb, pUser);
×
5441
      pUser = NULL;
×
5442
      mndUserFreeObj(&newUser);
×
5443
      continue;
×
5444
    }
5445
    if (code != 0) {
×
5446
      mndUserFreeObj(&newUser);
×
5447
      TAOS_CHECK_EXIT(code);
×
5448
    }
5449
    SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
×
5450
    if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
×
5451
      mndUserFreeObj(&newUser);
×
5452
      TAOS_CHECK_EXIT(TSDB_CODE_OUT_OF_MEMORY);
×
5453
    }
5454
    if ((code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY))) {
×
5455
      mndUserFreeObj(&newUser);
×
5456
      TAOS_CHECK_EXIT(code);
×
5457
    }
5458
    sdbRelease(pSdb, pUser);
×
5459
    pUser = NULL;
×
5460
    mndUserFreeObj(&newUser);
×
5461
  }
5462
_exit:
×
5463
  if (pIter) sdbCancelFetch(pSdb, pIter);
×
5464
  if (pUser) sdbRelease(pSdb, pUser);
×
5465
  if (code < 0) {
×
5466
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
5467
  }
5468
  TAOS_RETURN(code);
×
5469
}
5470

5471
int32_t mndUserRemoveDb(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SSHashObj **ppUsers) {
595,409✔
5472
  int32_t    code = 0, lino = 0;
595,409✔
5473
  SSdb      *pSdb = pMnode->pSdb;
595,409✔
5474
  int32_t    dbLen = strlen(pDb->name);
595,409✔
5475
  void      *pIter = NULL;
595,409✔
5476
  SUserObj  *pUser = NULL;
595,409✔
5477
  SUserObj   newUser = {0};
595,409✔
5478
  SSHashObj *pUsers = ppUsers ? *ppUsers : NULL;
595,409✔
5479
  bool       output = (ppUsers != NULL);
595,409✔
5480
#ifdef PRIV_TODO
5481
  while (1) {
5482
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
5483
    if (pIter == NULL) break;
5484

5485
    bool update = false;
5486
    bool inReadDb = false; //(taosHashGet(pUser->readDbs, pDb->name, dbLen + 1) != NULL);
5487
    bool inWriteDb = false; //(taosHashGet(pUser->writeDbs, pDb->name, dbLen + 1) != NULL);
5488
    bool inUseDb = (taosHashGet(pUser->useDbs, pDb->name, dbLen + 1) != NULL);
5489
    bool inReadTbs = taosHashGetSize(pUser->selectTbs) > 0;
5490
    bool inWriteTbs = taosHashGetSize(pUser->insertTbs) > 0;
5491
    bool inAlterTbs = taosHashGetSize(pUser->alterTbs) > 0;
5492
    bool inReadViews = taosHashGetSize(pUser->readViews) > 0;
5493
    bool inWriteViews = taosHashGetSize(pUser->writeViews) > 0;
5494
    bool inAlterViews = taosHashGetSize(pUser->alterViews) > 0;
5495
    // no need remove pUser->topics since topics must be dropped ahead of db
5496
    if (!inReadDb && !inWriteDb && !inReadTbs && !inWriteTbs && !inAlterTbs && !inReadViews && !inWriteViews &&
5497
        !inAlterViews) {
5498
      sdbRelease(pSdb, pUser);
5499
      continue;
5500
    }
5501
    SUserObj *pTargetUser = &newUser;
5502
    if (output) {
5503
      if (!pUsers) {
5504
        TSDB_CHECK_NULL(pUsers = tSimpleHashInit(32, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY)), code, lino,
5505
                        _exit, TSDB_CODE_OUT_OF_MEMORY);
5506
        *ppUsers = pUsers;
5507
      }
5508
      void   *pVal = NULL;
5509
      int32_t userLen = strlen(pUser->user) + 1;
5510
      if ((pVal = tSimpleHashGet(pUsers, pUser->user, userLen)) != NULL) {
5511
        pTargetUser = (SUserObj *)pVal;
5512
      } else {
5513
        TAOS_CHECK_EXIT(mndUserDupObj(pUser, &newUser));
5514
        TAOS_CHECK_EXIT(tSimpleHashPut(pUsers, pUser->user, userLen, &newUser, sizeof(SUserObj)));
5515
        TSDB_CHECK_NULL((pVal = tSimpleHashGet(pUsers, pUser->user, userLen)), code, lino, _exit,
5516
                        TSDB_CODE_OUT_OF_MEMORY);
5517
        pTargetUser = (SUserObj *)pVal;
5518
      }
5519
    } else {
5520
      TAOS_CHECK_EXIT(mndUserDupObj(pUser, &newUser));
5521
    }
5522
    if (inReadDb) {
5523
      // TAOS_CHECK_EXIT(taosHashRemove(pTargetUser->readDbs, pDb->name, dbLen + 1));
5524
    }
5525
    if (inWriteDb) {
5526
      // TAOS_CHECK_EXIT(taosHashRemove(pTargetUser->writeDbs, pDb->name, dbLen + 1));
5527
    }
5528
    if (inUseDb) {
5529
      TAOS_CHECK_EXIT(taosHashRemove(pTargetUser->useDbs, pDb->name, dbLen + 1));
5530
    }
5531
    update = inReadDb || inWriteDb || inUseDb;
5532

5533
    int32_t nRemovedReadTbs = 0;
5534
    int32_t nRemovedWriteTbs = 0;
5535
    int32_t nRemovedAlterTbs = 0;
5536
    if (inReadTbs || inWriteTbs || inAlterTbs) {
5537
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->selectTbs, pDb->name, dbLen, &nRemovedReadTbs));
5538
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->insertTbs, pDb->name, dbLen, &nRemovedWriteTbs));
5539
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->alterTbs, pDb->name, dbLen, &nRemovedAlterTbs));
5540
      if (!update) update = nRemovedReadTbs > 0 || nRemovedWriteTbs > 0 || nRemovedAlterTbs > 0;
5541
    }
5542

5543
    int32_t nRemovedReadViews = 0;
5544
    int32_t nRemovedWriteViews = 0;
5545
    int32_t nRemovedAlterViews = 0;
5546
    if (inReadViews || inWriteViews || inAlterViews) {
5547
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->readViews, pDb->name, dbLen, &nRemovedReadViews));
5548
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->writeViews, pDb->name, dbLen, &nRemovedWriteViews));
5549
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->alterViews, pDb->name, dbLen, &nRemovedAlterViews));
5550
      if (!update) update = nRemovedReadViews > 0 || nRemovedWriteViews > 0 || nRemovedAlterViews > 0;
5551
    }
5552

5553
    if (!output) {
5554
      if (update) {
5555
        SSdbRaw *pCommitRaw = mndUserActionEncode(pTargetUser);
5556
        if (pCommitRaw == NULL) {
5557
          TAOS_CHECK_EXIT(terrno);
5558
        }
5559
        TAOS_CHECK_EXIT(mndTransAppendCommitlog(pTrans, pCommitRaw));
5560
        TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
5561
      }
5562
      mndUserFreeObj(&newUser);
5563
    }
5564
    sdbRelease(pSdb, pUser);
5565
  }
5566
#endif
5567
_exit:
595,409✔
5568
  if (code < 0) {
595,409✔
5569
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
5570
    mndUserFreeObj(&newUser);
×
5571
  }
5572
  if (pUser != NULL) sdbRelease(pSdb, pUser);
595,409✔
5573
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
595,409✔
5574
  if (!output) mndUserFreeObj(&newUser);
595,409✔
5575
  TAOS_RETURN(code);
595,409✔
5576
}
5577

5578
int32_t mndUserRemoveStb(SMnode *pMnode, STrans *pTrans, char *stb) {
433,484✔
5579
  int32_t   code = 0;
433,484✔
5580
  SSdb     *pSdb = pMnode->pSdb;
433,484✔
5581
  int32_t   len = strlen(stb) + 1;
433,484✔
5582
  void     *pIter = NULL;
433,484✔
5583
  SUserObj *pUser = NULL;
433,484✔
5584
  SUserObj  newUser = {0};
433,484✔
5585
#ifdef PRIV_TODO
5586
  while (1) {
5587
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
5588
    if (pIter == NULL) break;
5589

5590
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
5591
      break;
5592
    }
5593

5594
    bool inRead = (taosHashGet(newUser.selectTbs, stb, len) != NULL);
5595
    bool inWrite = (taosHashGet(newUser.insertTbs, stb, len) != NULL);
5596
    bool inAlter = (taosHashGet(newUser.alterTbs, stb, len) != NULL);
5597
    if (inRead || inWrite || inAlter) {
5598
      code = taosHashRemove(newUser.selectTbs, stb, len);
5599
      if (code < 0) {
5600
        mError("failed to remove selectTbs:%s from user:%s", stb, pUser->user);
5601
      }
5602
      code = taosHashRemove(newUser.insertTbs, stb, len);
5603
      if (code < 0) {
5604
        mError("failed to remove insertTbs:%s from user:%s", stb, pUser->user);
5605
      }
5606
      code = taosHashRemove(newUser.alterTbs, stb, len);
5607
      if (code < 0) {
5608
        mError("failed to remove alterTbs:%s from user:%s", stb, pUser->user);
5609
      }
5610

5611
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
5612
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
5613
        code = TSDB_CODE_OUT_OF_MEMORY;
5614
        break;
5615
      }
5616
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
5617
      if (code != 0) {
5618
        mndUserFreeObj(&newUser);
5619
        sdbRelease(pSdb, pUser);
5620
        TAOS_RETURN(code);
5621
      }
5622
    }
5623

5624
    mndUserFreeObj(&newUser);
5625
    sdbRelease(pSdb, pUser);
5626
  }
5627
#endif
5628
  if (pUser != NULL) sdbRelease(pSdb, pUser);
433,484✔
5629
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
433,484✔
5630
  mndUserFreeObj(&newUser);
433,484✔
5631
  TAOS_RETURN(code);
433,484✔
5632
}
5633

5634
int32_t mndUserRemoveView(SMnode *pMnode, STrans *pTrans, char *view) {
×
5635
  int32_t   code = 0;
×
5636
  SSdb     *pSdb = pMnode->pSdb;
×
5637
  int32_t   len = strlen(view) + 1;
×
5638
  void     *pIter = NULL;
×
5639
  SUserObj *pUser = NULL;
×
5640
  SUserObj  newUser = {0};
×
5641
#ifdef PRIV_TODO
5642
  while (1) {
5643
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
5644
    if (pIter == NULL) break;
5645

5646
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
5647
      break;
5648
    }
5649

5650
    bool inRead = (taosHashGet(newUser.readViews, view, len) != NULL);
5651
    bool inWrite = (taosHashGet(newUser.writeViews, view, len) != NULL);
5652
    bool inAlter = (taosHashGet(newUser.alterViews, view, len) != NULL);
5653
    if (inRead || inWrite || inAlter) {
5654
      code = taosHashRemove(newUser.readViews, view, len);
5655
      if (code < 0) {
5656
        mError("failed to remove readViews:%s from user:%s", view, pUser->user);
5657
      }
5658
      code = taosHashRemove(newUser.writeViews, view, len);
5659
      if (code < 0) {
5660
        mError("failed to remove writeViews:%s from user:%s", view, pUser->user);
5661
      }
5662
      code = taosHashRemove(newUser.alterViews, view, len);
5663
      if (code < 0) {
5664
        mError("failed to remove alterViews:%s from user:%s", view, pUser->user);
5665
      }
5666

5667
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
5668
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
5669
        code = TSDB_CODE_OUT_OF_MEMORY;
5670
        break;
5671
      }
5672
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
5673
      if (code < 0) {
5674
        mndUserFreeObj(&newUser);
5675
        sdbRelease(pSdb, pUser);
5676
        TAOS_RETURN(code);
5677
      }
5678
    }
5679

5680
    mndUserFreeObj(&newUser);
5681
    sdbRelease(pSdb, pUser);
5682
  }
5683
#endif
5684
  if (pUser != NULL) sdbRelease(pSdb, pUser);
×
5685
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
×
5686
  mndUserFreeObj(&newUser);
×
5687
  TAOS_RETURN(code);
×
5688
}
5689

5690
int32_t mndUserRemoveTopic(SMnode *pMnode, STrans *pTrans, char *topic) {
94,242✔
5691
  int32_t   code = 0;
94,242✔
5692
  SSdb     *pSdb = pMnode->pSdb;
94,242✔
5693
  int32_t   len = strlen(topic) + 1;
94,242✔
5694
  void     *pIter = NULL;
94,242✔
5695
  SUserObj *pUser = NULL;
94,242✔
5696
  SUserObj  newUser = {0};
94,242✔
5697
#ifdef PRIV_TODO
5698
  while (1) {
5699
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
5700
    if (pIter == NULL) {
5701
      break;
5702
    }
5703

5704
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
5705
      break;
5706
    }
5707

5708
    bool inTopic = (taosHashGet(newUser.topics, topic, len) != NULL);
5709
    if (inTopic) {
5710
      code = taosHashRemove(newUser.topics, topic, len);
5711
      if (code < 0) {
5712
        mError("failed to remove topic:%s from user:%s", topic, pUser->user);
5713
      }
5714
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
5715
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
5716
        code = TSDB_CODE_OUT_OF_MEMORY;
5717
        break;
5718
      }
5719
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
5720
      if (code < 0) {
5721
        mndUserFreeObj(&newUser);
5722
        sdbRelease(pSdb, pUser);
5723
        TAOS_RETURN(code);
5724
      }
5725
    }
5726

5727
    mndUserFreeObj(&newUser);
5728
    sdbRelease(pSdb, pUser);
5729
  }
5730
#endif
5731
  if (pUser != NULL) sdbRelease(pSdb, pUser);
94,242✔
5732
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
94,242✔
5733
  mndUserFreeObj(&newUser);
94,242✔
5734
  TAOS_RETURN(code);
94,242✔
5735
}
5736

5737
int64_t mndGetUserIpWhiteListVer(SMnode *pMnode, SUserObj *pUser) {
×
5738
  // ver = 0, disable ip white list
5739
  // ver > 0, enable ip white list
5740
  return tsEnableWhiteList ? pUser->ipWhiteListVer : 0;
×
5741
}
5742

5743
int64_t mndGetUserTimeWhiteListVer(SMnode *pMnode, SUserObj *pUser) {
×
5744
  // ver = 0, disable datetime white list
5745
  // ver > 0, enable datetime white list
5746
  return tsEnableWhiteList ? pUser->timeWhiteListVer : 0;
×
5747
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc