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

taosdata / TDengine / #5013

03 Apr 2026 03:59PM UTC coverage: 72.317% (+0.01%) from 72.305%
#5013

push

travis-ci

web-flow
merge: from main to 3.0 branch #35067

4053 of 5985 new or added lines in 68 files covered. (67.72%)

13131 existing lines in 160 files now uncovered.

257489 of 356056 relevant lines covered (72.32%)

129893134.08 hits per line

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

64.8
/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 "mndMnode.h"
27
#include "mndPrivilege.h"
28
#include "mndShow.h"
29
#include "mndStb.h"
30
#include "mndSync.h" 
31
#include "mndTopic.h"
32
#include "mndTrans.h"
33
#include "mndToken.h"
34
#include "tbase64.h"
35
#include "totp.h"
36
#include "mndDnode.h"
37
#include "mndVgroup.h"
38

39
// clang-format on
40

41
#define USER_VER_SUPPORT_WHITELIST           5
42
#define USER_VER_SUPPORT_WHITELIT_DUAL_STACK 7
43
#define USER_VER_SUPPORT_ADVANCED_SECURITY   8
44
#define USER_VER_NUMBER                      USER_VER_SUPPORT_ADVANCED_SECURITY
45

46
#define USER_RESERVE_SIZE 63
47

48
#define BIT_FLAG_MASK(n)              (1 << n)
49
#define BIT_FLAG_SET_MASK(val, mask)  ((val) |= (mask))
50
#define BIT_FLAG_TEST_MASK(val, mask) (((val) & (mask)) != 0)
51

52
#if 0
53
#define PRIVILEGE_TYPE_ALL       BIT_FLAG_MASK(0)
54
#define PRIVILEGE_TYPE_READ      BIT_FLAG_MASK(1)
55
#define PRIVILEGE_TYPE_WRITE     BIT_FLAG_MASK(2)
56
#define PRIVILEGE_TYPE_SUBSCRIBE BIT_FLAG_MASK(3)
57
#define PRIVILEGE_TYPE_ALTER     BIT_FLAG_MASK(4)
58
#endif
59

60
#define ALTER_USER_ADD_PRIVS(_type) ((_type) == TSDB_ALTER_USER_ADD_PRIVILEGES)
61
#define ALTER_USER_DEL_PRIVS(_type) ((_type) == TSDB_ALTER_USER_DEL_PRIVILEGES)
62

63
#if 0
64
#define ALTER_USER_ALL_PRIV(_priv)       (PRIV_HAS((_priv), PRIV_CM_ALL))
65
#define ALTER_USER_READ_PRIV(_priv)      (PRIV_HAS((_priv), PRIV_CM_READ) || PRIV_HAS((_priv), PRIV_CM_ALL))
66
#define ALTER_USER_WRITE_PRIV(_priv)     (PRIV_HAS((_priv), PRIV_CM_WRITE) || PRIV_HAS((_priv), PRIV_CM_ALL))
67
#define ALTER_USER_ALTER_PRIV(_priv)     (PRIV_HAS((_priv), PRIV_CM_ALTER) || PRIV_HAS((_priv), PRIV_CM_ALL))
68
#define ALTER_USER_SUBSCRIBE_PRIV(_priv) (PRIV_HAS((_priv), PRIV_TOPIC_SUBSCRIBE))
69

70
#define ALTER_USER_TARGET_DB(_tbname) (0 == (_tbname)[0])
71
#define ALTER_USER_TARGET_TB(_tbname) (0 != (_tbname)[0])
72

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

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

107
#define ALTER_USER_ADD_SUBSCRIBE_TOPIC_PRIV(_type, _priv) \
108
  (ALTER_USER_ADD_PRIVS(_type) && ALTER_USER_SUBSCRIBE_PRIV(_priv))
109
#define ALTER_USER_DEL_SUBSCRIBE_TOPIC_PRIV(_type, _priv) \
110
  (ALTER_USER_DEL_PRIVS(_type) && ALTER_USER_SUBSCRIBE_PRIV(_priv))
111
#endif
112

113
#ifdef TD_ENTERPRISE
114
extern int32_t mndAlterUserPrivInfo(SMnode *pMnode, SUserObj *pNew, SAlterRoleReq *pAlterReq);
115
extern int32_t mndAlterUserRoleInfo(SMnode *pMnode, SUserObj *pOperUser, const char *token, SUserObj *pOld,
116
                                    SUserObj *pNew, SAlterRoleReq *pAlterReq);
117
#endif
118

119
static void generateSalt(char *salt, size_t len);
120

121
static int32_t createDefaultIpWhiteList(SIpWhiteListDual **ppWhiteList);
122
static int32_t createIpWhiteList(void *buf, int32_t len, SIpWhiteListDual **ppWhiteList, bool supportNeg);
123

124
static bool isIpWhiteListEqual(SIpWhiteListDual *a, SIpWhiteListDual *b);
125
static bool isIpRangeEqual(SIpRange *a, SIpRange *b);
126

127
#define MND_MAX_USER_IP_RANGE   (TSDB_PRIVILEDGE_HOST_LEN / 24)
128
#define MND_MAX_USER_TIME_RANGE 2048
129

130
static int32_t  mndCreateDefaultUsers(SMnode *pMnode);
131
static int32_t  mndUpgradeUsers(SMnode *pMnode, int32_t version);
132
static SSdbRow *mndUserActionDecode(SSdbRaw *pRaw);
133
static int32_t  mndUserActionInsert(SSdb *pSdb, SUserObj *pUser);
134
static int32_t  mndUserActionDelete(SSdb *pSdb, SUserObj *pUser);
135
static int32_t  mndUserActionUpdate(SSdb *pSdb, SUserObj *pOld, SUserObj *pNew);
136
static int32_t  mndCreateUser(SMnode *pMnode, char *acct, SCreateUserReq *pCreate, SRpcMsg *pReq);
137
static int32_t  mndAlterUser(SMnode *pMnode, SUserObj *pNew, SRpcMsg *pReq);
138
static int32_t  mndProcessCreateUserReq(SRpcMsg *pReq);
139
static int32_t  mndProcessAlterUserReq(SRpcMsg *pReq);
140
static int32_t  mndProcessDropUserReq(SRpcMsg *pReq);
141
static int32_t  mndProcessGetUserAuthReq(SRpcMsg *pReq);
142
static int32_t  mndProcessUpgradeUserReq(SRpcMsg *pReq);
143
static int32_t  mndProcessUpgradeUserRsp(SRpcMsg *pReq);
144
static int32_t  mndRetrieveUsers(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
145
static int32_t  mndRetrieveUsersFull(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
146
static void     mndCancelGetNextUser(SMnode *pMnode, void *pIter);
147
static int32_t  mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
148
static void     mndCancelGetNextPrivileges(SMnode *pMnode, void *pIter);
149
static int32_t  mndPrincipalRemoveObjPrivs(SMnode *pMnode, STrans *pTrans, char *objFName, int32_t objType);
150

151
static int32_t mndProcessGetUserIpWhiteListReq(SRpcMsg *pReq);
152
static int32_t mndProcessRetrieveIpWhiteListReq(SRpcMsg *pReq);
153
static int32_t mndProcessGetUserDateTimeWhiteListReq(SRpcMsg *pReq);
154
static int32_t mndProcessRetrieveDateTimeWhiteListReq(SRpcMsg *pReq);
155
static int32_t mndProcessCreateTotpSecretReq(SRpcMsg *pReq);
156
static int32_t mndProcessDropTotpSecretReq(SRpcMsg *pReq);
157

158
static int32_t createIpWhiteListFromOldVer(void *buf, int32_t len, SIpWhiteList **ppList);
159
static int32_t tDerializeIpWhileListFromOldVer(void *buf, int32_t len, SIpWhiteList *pList);
160

161
typedef struct {
162
  SIpWhiteListDual   *wlIp;
163
  SDateTimeWhiteList *wlTime;
164
  SLoginInfo          loginInfo;
165
} SCachedUserInfo;
166

167
typedef struct {
168
  SHashObj      *users;  // key: user, value: SCachedUserInfo*
169
  int64_t        verIp;
170
  int64_t        verTime;
171
  char           auditLogUser[TSDB_USER_LEN];
172
  TdThreadRwlock rw;
173
} SUserCache;
174

175
static SUserCache userCache;
176
static int8_t     upgradeSecurity = 0;
177

178
static int32_t userCacheInit() {
458,154✔
179
  _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
458,154✔
180

181
  SHashObj *users = taosHashInit(8, hashFn, 1, HASH_ENTRY_LOCK);
458,154✔
182
  if (users == NULL) {
458,154✔
183
    TAOS_RETURN(terrno);
×
184
  }
185

186
  userCache.users = users;
458,154✔
187
  userCache.verIp = 0;
458,154✔
188
  userCache.verTime = 0;
458,154✔
189
  userCache.auditLogUser[0] = '\0';
458,154✔
190

191
  (void)taosThreadRwlockInit(&userCache.rw, NULL);
458,154✔
192
  TAOS_RETURN(0);
458,154✔
193
}
194

195
static void userCacheCleanup() {
458,093✔
196
  if (userCache.users == NULL) {
458,093✔
197
    return;
×
198
  }
199

200
  void *pIter = taosHashIterate(userCache.users, NULL);
458,093✔
201
  while (pIter) {
935,064✔
202
    SCachedUserInfo *pInfo = *(SCachedUserInfo **)pIter;
476,971✔
203
    if (pInfo != NULL) {
476,971✔
204
      taosMemoryFree(pInfo->wlIp);
476,971✔
205
      taosMemoryFree(pInfo->wlTime);
476,971✔
206
      taosMemoryFree(pInfo);
476,971✔
207
    }
208
    pIter = taosHashIterate(userCache.users, pIter);
476,971✔
209
  }
210
  taosHashCleanup(userCache.users);
458,093✔
211

212
  (void)taosThreadRwlockDestroy(&userCache.rw);
458,093✔
213
}
214

215
static void userCacheRemoveUser(const char *user) {
46,149✔
216
  size_t userLen = strlen(user);
46,149✔
217

218
  (void)taosThreadRwlockWrlock(&userCache.rw);
46,149✔
219

220
  SCachedUserInfo **ppInfo = taosHashGet(userCache.users, user, userLen);
46,149✔
221
  if (ppInfo != NULL) {
46,149✔
222
    if (*ppInfo != NULL) {
46,149✔
223
      taosMemoryFree((*ppInfo)->wlIp);
46,149✔
224
      taosMemoryFree((*ppInfo)->wlTime);
46,149✔
225
      taosMemoryFree(*ppInfo);
46,149✔
226
    }
227
    if (taosHashRemove(userCache.users, user, userLen) != 0) {
46,149✔
228
      mDebug("failed to remove user %s from user cache", user);
×
229
    }
230
    userCache.verIp++;
46,149✔
231
    userCache.verTime++;
46,149✔
232
  }
233

234
  (void)taosThreadRwlockUnlock(&userCache.rw);
46,149✔
235
}
46,149✔
236

237
static void userCacheResetLoginInfo(const char *user) {
993✔
238
  size_t userLen = strlen(user);
993✔
239

240
  (void)taosThreadRwlockWrlock(&userCache.rw);
993✔
241

242
  SCachedUserInfo **ppInfo = taosHashGet(userCache.users, user, userLen);
993✔
243
  if (ppInfo != NULL && *ppInfo != NULL) {
993✔
244
    (*ppInfo)->loginInfo.lastLoginTime = taosGetTimestampSec();
993✔
245
    (*ppInfo)->loginInfo.failedLoginCount = 0;
993✔
246
    (*ppInfo)->loginInfo.lastFailedLoginTime = 0;
993✔
247
  }
248

249
  (void)taosThreadRwlockUnlock(&userCache.rw);
993✔
250
}
993✔
251

252
static SCachedUserInfo *getCachedUserInfo(const char *user) {
4,577,385✔
253
  size_t            userLen = strlen(user);
4,577,385✔
254
  SCachedUserInfo **ppInfo = taosHashGet(userCache.users, user, userLen);
4,577,385✔
255
  if (ppInfo != NULL) {
4,577,385✔
256
    return *ppInfo;
4,054,265✔
257
  }
258

259
  SCachedUserInfo *pInfo = (SCachedUserInfo *)taosMemoryCalloc(1, sizeof(SCachedUserInfo));
523,120✔
260
  if (pInfo == NULL) {
523,120✔
261
    return NULL;
×
262
  }
263

264
  if (taosHashPut(userCache.users, user, userLen, &pInfo, sizeof(pInfo)) != 0) {
523,120✔
265
    taosMemoryFree(pInfo);
×
266
    return NULL;
×
267
  }
268

269
  return pInfo;
523,120✔
270
}
271

272
void mndGetUserLoginInfo(const char *user, SLoginInfo *pLoginInfo) {
2,683,793✔
273
  size_t userLen = strlen(user);
2,683,793✔
274

275
  (void)taosThreadRwlockRdlock(&userCache.rw);
2,683,793✔
276

277
  SCachedUserInfo **ppInfo = taosHashGet(userCache.users, user, userLen);
2,683,793✔
278
  if (ppInfo != NULL && *ppInfo != NULL) {
2,683,739✔
279
    pLoginInfo->lastLoginTime = (*ppInfo)->loginInfo.lastLoginTime;
2,361,740✔
280
    pLoginInfo->failedLoginCount = (*ppInfo)->loginInfo.failedLoginCount;
2,361,980✔
281
    pLoginInfo->lastFailedLoginTime = (*ppInfo)->loginInfo.lastFailedLoginTime;
2,361,980✔
282
  } else {
283
    pLoginInfo->lastLoginTime = taosGetTimestampSec();
321,999✔
284
    pLoginInfo->failedLoginCount = 0;
321,250✔
285
    pLoginInfo->lastFailedLoginTime = 0;
321,250✔
286
  }
287

288
  (void)taosThreadRwlockUnlock(&userCache.rw);
2,683,793✔
289

290
  if (pLoginInfo->lastLoginTime == 0) {
2,683,765✔
291
    pLoginInfo->lastLoginTime = taosGetTimestampSec();
60,769✔
292
  }
293
}
2,683,621✔
294

295
void mndSetUserLoginInfo(const char *user, const SLoginInfo *pLoginInfo) {
2,677,548✔
296
  size_t userLen = strlen(user);
2,677,548✔
297

298
  (void)taosThreadRwlockWrlock(&userCache.rw);
2,677,548✔
299

300
  SCachedUserInfo *pInfo = getCachedUserInfo(user);
2,678,054✔
301
  if (pInfo != NULL) {
2,678,054✔
302
    pInfo->loginInfo.lastLoginTime = pLoginInfo->lastLoginTime;
2,678,054✔
303
    pInfo->loginInfo.failedLoginCount = pLoginInfo->failedLoginCount;
2,678,054✔
304
    pInfo->loginInfo.lastFailedLoginTime = pLoginInfo->lastFailedLoginTime;
2,678,054✔
305
  }
306

307
  (void)taosThreadRwlockUnlock(&userCache.rw);
2,678,054✔
308
}
2,678,054✔
309

310
static bool isDateTimeWhiteListEqual(SDateTimeWhiteList *a, SDateTimeWhiteList *b) {
1,483,100✔
311
  if (a == NULL && b == NULL) {
1,483,100✔
312
    return true;
×
313
  }
314

315
  if (a == NULL || b == NULL) {
1,483,100✔
316
    return false;
87,275✔
317
  }
318

319
  if (a->num != b->num) {
1,395,825✔
320
    return false;
288✔
321
  }
322

323
  for (int i = 0; i < a->num; i++) {
1,395,969✔
324
    if (a->ranges[i].start != b->ranges[i].start || a->ranges[i].duration != b->ranges[i].duration ||
720✔
325
        a->ranges[i].neg != b->ranges[i].neg || a->ranges[i].absolute != b->ranges[i].absolute) {
432✔
326
      return false;
288✔
327
    }
328
  }
329

330
  return true;
1,395,249✔
331
}
332

333
static int32_t userCacheUpdateWhiteList(SMnode *pMnode, SUserObj *pUser) {
1,483,100✔
334
  int32_t code = 0, lino = 0;
1,483,100✔
335

336
  (void)taosThreadRwlockWrlock(&userCache.rw);
1,483,100✔
337

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

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

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

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

371
static int32_t userCacheRebuildIpWhiteList(SMnode *pMnode) {
554,324✔
372
  int32_t code = 0, lino = 0;
554,324✔
373

374
  SSdb *pSdb = pMnode->pSdb;
554,324✔
375
  void *pIter = NULL;
554,324✔
376
  while (1) {
212,699✔
377
    SUserObj *pUser = NULL;
767,023✔
378
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
767,023✔
379
    if (pIter == NULL) {
767,023✔
380
      break;
554,324✔
381
    }
382

383
    SCachedUserInfo *pInfo = getCachedUserInfo(pUser->user);
212,699✔
384
    if (pInfo == NULL) {
212,699✔
385
      sdbRelease(pSdb, pUser);
×
386
      sdbCancelFetch(pSdb, pIter);
×
387
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
388
    }
389

390
    SIpWhiteListDual *wl = cloneIpWhiteList(pUser->pIpWhiteListDual);
212,699✔
391
    if (wl == NULL) {
212,699✔
392
      sdbRelease(pSdb, pUser);
×
393
      sdbCancelFetch(pSdb, pIter);
×
394
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
395
    }
396

397
    taosMemoryFree(pInfo->wlIp);
212,699✔
398
    pInfo->wlIp = wl;
212,699✔
399

400
    sdbRelease(pSdb, pUser);
212,699✔
401
  }
402

403
  userCache.verIp++;
554,324✔
404

405
_OVER:
554,324✔
406
  if (code < 0) {
554,324✔
407
    mError("failed to rebuild ip white list at line %d since %s", lino, tstrerror(code));
×
408
  }
409
  TAOS_RETURN(code);
554,324✔
410
}
411

412
int64_t mndGetIpWhiteListVersion(SMnode *pMnode) {
48,196,974✔
413
  int64_t ver = 0;
48,196,974✔
414
  int32_t code = 0;
48,196,974✔
415

416
  if (mndEnableIpWhiteList(pMnode) != 0 && tsEnableWhiteList) {
48,196,974✔
417
    (void)taosThreadRwlockWrlock(&userCache.rw);
3,862✔
418

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

430
    (void)taosThreadRwlockUnlock(&userCache.rw);
3,862✔
431
  }
432

433
  mDebug("ip-white-list on mnode ver: %" PRId64, ver);
48,196,974✔
434
  return ver;
48,196,974✔
435
}
436

437
int32_t mndRefreshUserIpWhiteList(SMnode *pMnode) {
554,324✔
438
  int32_t code = 0;
554,324✔
439
  (void)taosThreadRwlockWrlock(&userCache.rw);
554,324✔
440

441
  if ((code = userCacheRebuildIpWhiteList(pMnode)) != 0) {
554,324✔
442
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
443
    TAOS_RETURN(code);
×
444
  }
445
  userCache.verIp = taosGetTimestampMs();
554,324✔
446
  (void)taosThreadRwlockUnlock(&userCache.rw);
554,324✔
447

448
  TAOS_RETURN(code);
554,324✔
449
}
450

451
static int32_t userCacheRebuildTimeWhiteList(SMnode *pMnode) {
545,157✔
452
  int32_t code = 0, lino = 0;
545,157✔
453

454
  SSdb *pSdb = pMnode->pSdb;
545,157✔
455
  void *pIter = NULL;
545,157✔
456
  while (1) {
203,532✔
457
    SUserObj *pUser = NULL;
748,689✔
458
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
748,689✔
459
    if (pIter == NULL) {
748,689✔
460
      break;
545,157✔
461
    }
462

463
    SCachedUserInfo *pInfo = getCachedUserInfo(pUser->user);
203,532✔
464
    if (pInfo == NULL) {
203,532✔
465
      sdbRelease(pSdb, pUser);
×
466
      sdbCancelFetch(pSdb, pIter);
×
467
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
468
    }
469

470
    SDateTimeWhiteList *wl = cloneDateTimeWhiteList(pUser->pTimeWhiteList);
203,532✔
471
    if (wl == NULL) {
203,532✔
472
      sdbRelease(pSdb, pUser);
×
473
      sdbCancelFetch(pSdb, pIter);
×
474
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
475
    }
476

477
    taosMemoryFree(pInfo->wlTime);
203,532✔
478
    pInfo->wlTime = wl;
203,532✔
479

480
    sdbRelease(pSdb, pUser);
203,532✔
481
  }
482

483
  userCache.verTime++;
545,157✔
484

485
_OVER:
545,157✔
486
  if (code < 0) {
545,157✔
487
    mError("failed to rebuild time white list at line %d since %s", lino, tstrerror(code));
×
488
  }
489
  TAOS_RETURN(code);
545,157✔
490
}
491

492
int32_t mndRefreshUserDateTimeWhiteList(SMnode *pMnode) {
545,157✔
493
  int32_t code = 0;
545,157✔
494
  (void)taosThreadRwlockWrlock(&userCache.rw);
545,157✔
495

496
  if ((code = userCacheRebuildTimeWhiteList(pMnode)) != 0) {
545,157✔
497
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
498
    TAOS_RETURN(code);
×
499
  }
500
  userCache.verTime = taosGetTimestampMs();
545,157✔
501
  (void)taosThreadRwlockUnlock(&userCache.rw);
545,157✔
502

503
  TAOS_RETURN(code);
545,157✔
504
}
505

506
int64_t mndGetTimeWhiteListVersion(SMnode *pMnode) {
48,196,974✔
507
  int64_t ver = 0;
48,196,974✔
508
  int32_t code = 0;
48,196,974✔
509

510
  if (mndEnableTimeWhiteList(pMnode) != 0 && tsEnableWhiteList) {
48,196,974✔
511
    (void)taosThreadRwlockWrlock(&userCache.rw);
3,862✔
512

513
    if (userCache.verIp == 0) {
3,862✔
514
      // get user and dnode datetime white list
515
      if ((code = userCacheRebuildTimeWhiteList(pMnode)) != 0) {
×
516
        (void)taosThreadRwlockUnlock(&userCache.rw);
×
517
        mError("%s failed to update datetime white list since %s", __func__, tstrerror(code));
×
518
        return ver;
×
519
      }
520
      userCache.verTime = taosGetTimestampMs();
×
521
    }
522
    ver = userCache.verTime;
3,862✔
523

524
    (void)taosThreadRwlockUnlock(&userCache.rw);
3,862✔
525
  }
526

527
  mDebug("datetime-white-list on mnode ver: %" PRId64, ver);
48,196,974✔
528
  return ver;
48,196,974✔
529
}
530

531
int32_t mndInitUser(SMnode *pMnode) {
458,154✔
532
  TAOS_CHECK_RETURN(userCacheInit());
458,154✔
533

534
  SSdbTable table = {
458,154✔
535
      .sdbType = SDB_USER,
536
      .keyType = SDB_KEY_BINARY,
537
      .deployFp = (SdbDeployFp)mndCreateDefaultUsers,
538
      .upgradeFp = (SdbUpgradeFp)mndUpgradeUsers,
539
      .encodeFp = (SdbEncodeFp)mndUserActionEncode,
540
      .decodeFp = (SdbDecodeFp)mndUserActionDecode,
541
      .insertFp = (SdbInsertFp)mndUserActionInsert,
542
      .updateFp = (SdbUpdateFp)mndUserActionUpdate,
543
      .deleteFp = (SdbDeleteFp)mndUserActionDelete,
544
  };
545

546
  mndSetMsgHandle(pMnode, TDMT_MND_CREATE_USER, mndProcessCreateUserReq);
458,154✔
547
  mndSetMsgHandle(pMnode, TDMT_MND_ALTER_USER, mndProcessAlterUserReq);
458,154✔
548
  mndSetMsgHandle(pMnode, TDMT_MND_DROP_USER, mndProcessDropUserReq);
458,154✔
549
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_AUTH, mndProcessGetUserAuthReq);
458,154✔
550
  mndSetMsgHandle(pMnode, TDMT_MND_UPGRADE_USER, mndProcessUpgradeUserReq);
458,154✔
551
  mndSetMsgHandle(pMnode, TDMT_MND_UPGRADE_USER_RSP, mndProcessUpgradeUserRsp);
458,154✔
552

553
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_IP_WHITELIST, mndProcessGetUserIpWhiteListReq);
458,154✔
554
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_IP_WHITELIST_DUAL, mndProcessGetUserIpWhiteListReq);
458,154✔
555
  mndSetMsgHandle(pMnode, TDMT_MND_RETRIEVE_IP_WHITELIST, mndProcessRetrieveIpWhiteListReq);
458,154✔
556
  mndSetMsgHandle(pMnode, TDMT_MND_RETRIEVE_IP_WHITELIST_DUAL, mndProcessRetrieveIpWhiteListReq);
458,154✔
557
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_DATETIME_WHITELIST, mndProcessGetUserDateTimeWhiteListReq);
458,154✔
558
  mndSetMsgHandle(pMnode, TDMT_MND_RETRIEVE_DATETIME_WHITELIST, mndProcessRetrieveDateTimeWhiteListReq);
458,154✔
559

560
  mndSetMsgHandle(pMnode, TDMT_MND_CREATE_TOTP_SECRET, mndProcessCreateTotpSecretReq);
458,154✔
561
  mndSetMsgHandle(pMnode, TDMT_MND_DROP_TOTP_SECRET, mndProcessDropTotpSecretReq);
458,154✔
562

563
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_USER, mndRetrieveUsers);
458,154✔
564
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_USER, mndCancelGetNextUser);
458,154✔
565
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_USER_FULL, mndRetrieveUsersFull);
458,154✔
566
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_USER_FULL, mndCancelGetNextUser);
458,154✔
567
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_PRIVILEGES, mndRetrievePrivileges);
458,154✔
568
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_PRIVILEGES, mndCancelGetNextPrivileges);
458,154✔
569
  return sdbSetTable(pMnode->pSdb, table);
458,154✔
570
}
571

572
void mndCleanupUser(SMnode *pMnode) { userCacheCleanup(); }
458,093✔
573

574
static bool isDefaultRange(SIpRange *pRange) {
×
575
  int32_t code = 0;
×
576
  int32_t lino = 0;
×
577

578
  SIpRange range4 = {0};
×
579
  SIpRange range6 = {0};
×
580

581
  code = createDefaultIp4Range(&range4);
×
582
  TSDB_CHECK_CODE(code, lino, _error);
×
583

584
  code = createDefaultIp6Range(&range6);
×
585
  TSDB_CHECK_CODE(code, lino, _error);
×
586

587
  if (isIpRangeEqual(pRange, &range4) || (isIpRangeEqual(pRange, &range6))) {
×
588
    return true;
×
589
  }
590
_error:
×
591
  return false;
×
592
};
593

594
static int32_t ipRangeListToStr(SIpRange *range, int32_t num, char *buf, int64_t bufLen) {
1,487,468✔
595
  int32_t len = 0;
1,487,468✔
596
  for (int i = 0; i < num; i++) {
4,498,580✔
597
    SIpRange *pRange = &range[i];
3,011,112✔
598
    SIpAddr   addr = {0};
3,011,112✔
599
    int32_t   code = tIpUintToStr(pRange, &addr);
3,011,112✔
600
    if (code != 0) {
3,011,112✔
601
      mError("%s failed to convert ip range to str, code: %d", __func__, code);
×
602
    }
603

604
    len += snprintf(buf + len, bufLen - len, "%c%s/%d, ", pRange->neg ? '-' : '+', IP_ADDR_STR(&addr), addr.mask);
3,011,112✔
605
  }
606
  if (len > 0) {
1,487,468✔
607
    len -= 2;
1,487,468✔
608
    buf[len] = 0; // remove last ", "
1,487,468✔
609
  }
610
  return len;
1,487,468✔
611
}
612

613
static bool isIpRangeEqual(SIpRange *a, SIpRange *b) {
2,791,484✔
614
  if (a->type != b->type || a->neg != b->neg) {
2,791,484✔
615
    return false;
×
616
  }
617

618
  if (a->type == 0) {
2,791,484✔
619
    SIpV4Range *a4 = &a->ipV4;
1,396,113✔
620
    SIpV4Range *b4 = &b->ipV4;
1,396,113✔
621
    return (a4->ip == b4->ip && a4->mask == b4->mask);
1,396,113✔
622
  }
623

624
  SIpV6Range *a6 = &a->ipV6;
1,395,371✔
625
  SIpV6Range *b6 = &b->ipV6;
1,395,371✔
626
  return (a6->addr[0] == b6->addr[0] && a6->addr[1] == b6->addr[1] && a6->mask == b6->mask);
1,395,371✔
627
}
628

629
static bool isIpWhiteListEqual(SIpWhiteListDual *a, SIpWhiteListDual *b) {
1,483,100✔
630
  if (a == NULL && b == NULL) {
1,483,100✔
631
    return true;
×
632
  }
633

634
  if (a == NULL || b == NULL) {
1,483,100✔
635
    return false;
87,275✔
636
  }
637

638
  if (a->num != b->num) {
1,395,825✔
639
    return false;
454✔
640
  }
641
  for (int i = 0; i < a->num; i++) {
4,186,855✔
642
    if (!isIpRangeEqual(&a->pIpRanges[i], &b->pIpRanges[i])) {
2,791,484✔
643
      return false;
×
644
    }
645
  }
646
  return true;
1,395,371✔
647
}
648

649
static int32_t compareIpRange(const void *a, const void *b, const void *arg) {
5,399✔
650
  SIpRange *ra = (SIpRange *)a;
5,399✔
651
  SIpRange *rb = (SIpRange *)b;
5,399✔
652

653
  if (ra->neg != rb->neg) {
5,399✔
654
    return (ra->neg) ? -1 : 1;
720✔
655
  }
656

657
  if (ra->type != rb->type) {
4,679✔
658
    return (ra->type == 0) ? -1 : 1;
1,701✔
659
  }
660

661
  if (ra->type == 0) {
2,978✔
662
    if (ra->ipV4.ip != rb->ipV4.ip) {
2,978✔
663
      return (ra->ipV4.ip < rb->ipV4.ip) ? -1 : 1;
2,646✔
664
    }
665
    return (ra->ipV4.mask < rb->ipV4.mask) ? -1 : 1;
332✔
666
  }
667

668
  if (ra->ipV6.addr[0] != rb->ipV6.addr[0]) {
×
669
    return (ra->ipV6.addr[0] < rb->ipV6.addr[0]) ? -1 : 1;
×
670
  }
671
  if (ra->ipV6.addr[1] != rb->ipV6.addr[1]) {
×
672
    return (ra->ipV6.addr[1] < rb->ipV6.addr[1]) ? -1 : 1;
×
673
  }
674
  return (ra->ipV6.mask < rb->ipV6.mask) ? -1 : 1;
×
675
}
676

677
static void sortIpWhiteList(SIpWhiteListDual *pList) {
2,133✔
678
  (void)taosqsort(pList->pIpRanges, pList->num, sizeof(SIpRange), NULL, compareIpRange);
2,133✔
679
}
2,133✔
680

681
static int32_t convertIpWhiteListToStr(SUserObj *pUser, char **buf) {
1,487,468✔
682
  SIpWhiteListDual *pList = pUser->pIpWhiteListDual;
1,487,468✔
683

684
  int64_t bufLen = pList->num * 128 + 8;
1,487,468✔
685
  *buf = taosMemoryCalloc(1, bufLen);
1,487,468✔
686
  if (*buf == NULL) {
1,487,468✔
687
    return 0;
×
688
  }
689

690
  if (pList->num == 0) {
1,487,468✔
691
    return snprintf(*buf, bufLen, "+ALL");
×
692
  }
693

694
  int32_t len = ipRangeListToStr(pList->pIpRanges, pList->num, *buf, bufLen - 2);
1,487,468✔
695
  if (len == 0) {
1,487,468✔
696
    taosMemoryFreeClear(*buf);
×
697
    return 0;
×
698
  }
699
  return len;
1,487,468✔
700
}
701

702
static int32_t tSerializeIpWhiteList(void *buf, int32_t len, SIpWhiteListDual *pList, uint32_t *pLen) {
4,224,735✔
703
  int32_t  code = 0;
4,224,735✔
704
  int32_t  lino = 0;
4,224,735✔
705
  int32_t  tlen = 0;
4,224,735✔
706
  SEncoder encoder = {0};
4,224,735✔
707
  tEncoderInit(&encoder, buf, len);
4,224,735✔
708

709
  TAOS_CHECK_GOTO(tStartEncode(&encoder), &lino, _OVER);
4,224,735✔
710
  TAOS_CHECK_GOTO(tEncodeI32(&encoder, pList->num), &lino, _OVER);
8,449,470✔
711

712
  for (int i = 0; i < pList->num; i++) {
12,678,623✔
713
    SIpRange *pRange = &(pList->pIpRanges[i]);
8,453,888✔
714
    TAOS_CHECK_GOTO(tSerializeIpRange(&encoder, pRange), &lino, _OVER);
8,453,888✔
715
  }
716

717
  tEndEncode(&encoder);
4,224,735✔
718

719
  tlen = encoder.pos;
4,224,735✔
720
_OVER:
4,224,735✔
721
  tEncoderClear(&encoder);
4,224,735✔
722
  if (code < 0) {
4,224,735✔
723
    mError("failed to serialize ip white list at line %d since %s", lino, tstrerror(code));
×
724
  }
725
  if (pLen) *pLen = tlen;
4,224,735✔
726
  TAOS_RETURN(code);
4,224,735✔
727
}
728

729
static int32_t tDerializeIpWhiteList(void *buf, int32_t len, SIpWhiteListDual *pList, bool supportNeg) {
3,385,135✔
730
  int32_t  code = 0;
3,385,135✔
731
  int32_t  lino = 0;
3,385,135✔
732
  SDecoder decoder = {0};
3,385,135✔
733
  tDecoderInit(&decoder, buf, len);
3,385,135✔
734

735
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
3,385,135✔
736
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &pList->num), &lino, _OVER);
6,770,270✔
737

738
  for (int i = 0; i < pList->num; i++) {
10,158,007✔
739
    SIpRange *pRange = &(pList->pIpRanges[i]);
6,772,872✔
740
    TAOS_CHECK_GOTO(tDeserializeIpRange(&decoder, pRange, supportNeg), &lino, _OVER);
6,772,872✔
741
  }
742

743
_OVER:
3,385,135✔
744
  tEndDecode(&decoder);
3,385,135✔
745
  tDecoderClear(&decoder);
3,385,135✔
746
  if (code < 0) {
3,385,135✔
747
    mError("failed to deserialize ip white list at line %d since %s", lino, tstrerror(code));
×
748
  }
749
  TAOS_RETURN(code);
3,385,135✔
750
}
751

752
static int32_t tDerializeIpWhileListFromOldVer(void *buf, int32_t len, SIpWhiteList *pList) {
×
753
  int32_t  code = 0;
×
754
  int32_t  lino = 0;
×
755
  SDecoder decoder = {0};
×
756
  tDecoderInit(&decoder, buf, len);
×
757

758
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
×
759
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &pList->num), &lino, _OVER);
×
760

761
  for (int i = 0; i < pList->num; i++) {
×
762
    SIpV4Range *pIp4 = &(pList->pIpRange[i]);
×
763
    TAOS_CHECK_GOTO(tDecodeU32(&decoder, &pIp4->ip), &lino, _OVER);
×
764
    TAOS_CHECK_GOTO(tDecodeU32(&decoder, &pIp4->mask), &lino, _OVER);
×
765
  }
766

767
_OVER:
×
768
  tEndDecode(&decoder);
×
769
  tDecoderClear(&decoder);
×
770
  if (code < 0) {
×
771
    mError("failed to deserialize ip white list at line %d since %s", lino, tstrerror(code));
×
772
  }
773
  TAOS_RETURN(code);
×
774
}
775

776
static int32_t createIpWhiteList(void *buf, int32_t len, SIpWhiteListDual **ppList, bool supportNeg) {
3,385,135✔
777
  int32_t           code = 0;
3,385,135✔
778
  int32_t           lino = 0;
3,385,135✔
779
  int32_t           num = 0;
3,385,135✔
780
  SIpWhiteListDual *p = NULL;
3,385,135✔
781
  SDecoder          decoder = {0};
3,385,135✔
782
  tDecoderInit(&decoder, buf, len);
3,385,135✔
783

784
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
3,385,135✔
785
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &num), &lino, _OVER);
3,385,135✔
786

787
  p = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + num * sizeof(SIpRange));
3,385,135✔
788
  if (p == NULL) {
3,385,135✔
789
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
790
  }
791
  TAOS_CHECK_GOTO(tDerializeIpWhiteList(buf, len, p, supportNeg), &lino, _OVER);
3,385,135✔
792

793
_OVER:
3,385,135✔
794
  tEndDecode(&decoder);
3,385,135✔
795
  tDecoderClear(&decoder);
3,385,135✔
796
  if (code < 0) {
3,385,135✔
797
    taosMemoryFreeClear(p);
×
798
    mError("failed to create ip white list at line %d since %s", lino, tstrerror(code));
×
799
  }
800
  *ppList = p;
3,385,135✔
801
  TAOS_RETURN(code);
3,385,135✔
802
}
803

804
static int32_t createIpWhiteListFromOldVer(void *buf, int32_t len, SIpWhiteList **ppList) {
×
805
  int32_t       code = 0;
×
806
  int32_t       lino = 0;
×
807
  int32_t       num = 0;
×
808
  SIpWhiteList *p = NULL;
×
809
  SDecoder      decoder = {0};
×
810
  tDecoderInit(&decoder, buf, len);
×
811

812
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
×
813
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &num), &lino, _OVER);
×
814

815
  p = taosMemoryCalloc(1, sizeof(SIpWhiteList) + num * sizeof(SIpV4Range));
×
816
  if (p == NULL) {
×
817
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
818
  }
819
  TAOS_CHECK_GOTO(tDerializeIpWhileListFromOldVer(buf, len, p), &lino, _OVER);
×
820

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

832
static int32_t createDefaultIpWhiteList(SIpWhiteListDual **ppWhiteList) {
416,194✔
833
  int32_t code = 0;
416,194✔
834
  int32_t lino = 0;
416,194✔
835
  *ppWhiteList = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + sizeof(SIpRange) * 2);
416,194✔
836
  if (*ppWhiteList == NULL) {
416,194✔
837
    TAOS_RETURN(terrno);
×
838
  }
839
  (*ppWhiteList)->num = 2;
416,194✔
840

841
  SIpRange v4 = {0};
416,194✔
842
  SIpRange v6 = {0};
416,194✔
843

844
#ifndef TD_ASTRA
845
  code = createDefaultIp4Range(&v4);
416,194✔
846
  TSDB_CHECK_CODE(code, lino, _error);
416,194✔
847

848
  code = createDefaultIp6Range(&v6);
416,194✔
849
  TSDB_CHECK_CODE(code, lino, _error);
416,194✔
850

851
#endif
852

853
_error:
416,194✔
854
  if (code != 0) {
416,194✔
855
    taosMemoryFree(*ppWhiteList);
×
856
    *ppWhiteList = NULL;
×
857
    mError("failed to create default ip white list at line %d since %s", __LINE__, tstrerror(code));
×
858
  } else {
859
    memcpy(&(*ppWhiteList)->pIpRanges[0], &v4, sizeof(SIpRange));
416,194✔
860
    memcpy(&(*ppWhiteList)->pIpRanges[1], &v6, sizeof(SIpRange));
416,194✔
861
  }
862
  return 0;
416,194✔
863
}
864

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

867
static int32_t convertTimeRangesToStr(SUserObj *pUser, char **buf) {
1,487,468✔
868
  int32_t bufLen = pUser->pTimeWhiteList->num * 32 + 8;
1,487,468✔
869
  *buf = taosMemoryCalloc(1, bufLen);
1,487,468✔
870
  if (*buf == NULL) {
1,487,468✔
871
    return 0;
×
872
  }
873

874
  int32_t pos = 0;
1,487,468✔
875
  if (pUser->pTimeWhiteList->num == 0) {
1,487,468✔
876
    pos += snprintf(*buf + pos, bufLen - pos, "+ALL");
1,409,132✔
877
    return pos;
1,409,132✔
878
  }
879

880
  for (int32_t i = 0; i < pUser->pTimeWhiteList->num; i++) {
178,560✔
881
    SDateTimeWhiteListItem *range = &pUser->pTimeWhiteList->ranges[i];
100,224✔
882
    int                     duration = range->duration / 60;
100,224✔
883

884
    if (range->absolute) {
100,224✔
885
      struct STm tm;
59,184✔
886
      (void)taosTs2Tm(range->start, TSDB_TIME_PRECISION_SECONDS, &tm, NULL);
59,184✔
887
      pos += tsnprintf(*buf + pos, bufLen - pos, "%c%04d-%02d-%02d %02d:%02d %dm, ", range->neg ? '-' : '+',
59,184✔
888
                       tm.tm.tm_year + 1900, tm.tm.tm_mon + 1, tm.tm.tm_mday, tm.tm.tm_hour, tm.tm.tm_min, duration);
59,184✔
889
    } else {
890
      int day = range->start / 86400;
41,040✔
891
      int hour = (range->start % 86400) / 3600;
41,040✔
892
      int minute = (range->start % 3600) / 60;
41,040✔
893
      pos += tsnprintf(*buf + pos, bufLen - pos, "%c%s %02d:%02d %dm, ", range->neg ? '-' : '+', weekdays[day], hour,
41,040✔
894
                       minute, duration);
895
    }
896
  }
897

898
  if (pos > 0) {
78,336✔
899
    pos -= 2;
78,336✔
900
    (*buf)[pos] = 0; // remove last ", "
78,336✔
901
  }
902

903
  return pos;
78,336✔
904
}
905

906
static int32_t compareDateTimeInterval(const void *a, const void *b, const void *arg) {
864✔
907
  SDateTimeWhiteListItem *pA = (SDateTimeWhiteListItem *)a;
864✔
908
  SDateTimeWhiteListItem *pB = (SDateTimeWhiteListItem *)b;
864✔
909

910
  if (pA->neg != pB->neg) {
864✔
911
    return pA->neg ? -1 : 1;
576✔
912
  }
913

914
  if (pA->absolute != pB->absolute) {
288✔
915
    return pA->absolute ? 1 : -1;
288✔
916
  }
917

918
  if (pA->start != pB->start) {
×
919
    return (pA->start < pB->start) ? -1 : 1;
×
920
  }
921

922
  if (pA->duration != pB->duration) {
×
923
    return (pA->duration < pB->duration) ? -1 : 1;
×
924
  }
925

926
  return 0;
×
927
}
928

929
static void sortTimeWhiteList(SDateTimeWhiteList *pList) {
2,448✔
930
  (void)taosqsort(pList->ranges, pList->num, sizeof(SDateTimeWhiteListItem), NULL, compareDateTimeInterval);
2,448✔
931
}
2,448✔
932

933
static void dropOldPasswords(SUserObj *pUser) {
10,346,991✔
934
  if (pUser->numOfPasswords <= pUser->passwordReuseMax) {
10,346,991✔
935
    return;
542,113✔
936
  }
937

938
  int32_t reuseMax = pUser->passwordReuseMax;
9,804,878✔
939
  if (reuseMax == 0) {
9,804,878✔
940
    reuseMax = 1;  // keep at least one password
9,804,590✔
941
  }
942

943
  int32_t now = taosGetTimestampSec();
9,804,878✔
944
  int32_t index = reuseMax;
9,804,878✔
945
  while(index < pUser->numOfPasswords) {
9,804,878✔
946
    // the set time of the n-th password is the expire time of the n+1-th password
947
    int32_t expireTime = pUser->passwords[index - 1].setTime;
288✔
948
    if (now - expireTime >= pUser->passwordReuseTime) {
288✔
949
      break;
288✔
950
    }
951
    index++;
×
952
  }
953

954
  if (index == pUser->numOfPasswords) {
9,804,878✔
955
    return;
9,804,590✔
956
  }
957
  pUser->numOfPasswords = index;
288✔
958
  // this is a shrink operation, no need to check return value
959
  pUser->passwords = taosMemoryRealloc(pUser->passwords, sizeof(SUserPassword) * pUser->numOfPasswords);
288✔
960
}
961

962
static int32_t mndCreateDefaultUser(SMnode *pMnode, char *acct, char *user, char *pass) {
330,616✔
963
  int32_t  code = 0;
330,616✔
964
  int32_t  lino = 0;
330,616✔
965
  SUserObj userObj = {0};
330,616✔
966

967
  userObj.passwords = taosMemCalloc(1, sizeof(SUserPassword));
330,616✔
968
  if (userObj.passwords == NULL) {
330,616✔
969
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _ERROR);
×
970
  }
971
  taosEncryptPass_c((uint8_t *)pass, strlen(pass), userObj.passwords[0].pass);
330,616✔
972
  userObj.passwords[0].pass[sizeof(userObj.passwords[0].pass) - 1] = 0;
330,616✔
973
  if (tsiEncryptPassAlgorithm == DND_CA_SM4 && strlen(tsDataKey) > 0) {
330,616✔
974
    generateSalt(userObj.salt, sizeof(userObj.salt));
×
975
    TAOS_CHECK_GOTO(mndEncryptPass(userObj.passwords[0].pass, userObj.salt, &userObj.passEncryptAlgorithm), &lino,
×
976
                    _ERROR);
977
  }
978

979
  userObj.passwords[0].setTime = taosGetTimestampSec();
330,616✔
980
  userObj.numOfPasswords = 1;
330,616✔
981

982
  tstrncpy(userObj.user, user, TSDB_USER_LEN);
330,616✔
983
  tstrncpy(userObj.acct, acct, TSDB_USER_LEN);
330,616✔
984
  userObj.createdTime = taosGetTimestampMs();
330,616✔
985
  userObj.updateTime = userObj.createdTime;
330,616✔
986
  userObj.uid = mndGenerateUid(userObj.user, strlen(userObj.user));
330,616✔
987
  userObj.sysInfo = 1;
330,616✔
988
  userObj.enable = 1;
330,616✔
989

990
#ifdef TD_ENTERPRISE
991

992
  userObj.ipWhiteListVer = taosGetTimestampMs();
330,616✔
993
  userObj.timeWhiteListVer = userObj.ipWhiteListVer;
330,616✔
994

995
  if (tsEnableAdvancedSecurity) {
330,616✔
996
    userObj.changePass = 1;  // force user to change password
×
997
    userObj.connectTime = TSDB_USER_CONNECT_TIME_DEFAULT;
×
998
    userObj.connectIdleTime = TSDB_USER_CONNECT_IDLE_TIME_DEFAULT;
×
999
    userObj.callPerSession = TSDB_USER_CALL_PER_SESSION_DEFAULT;
×
1000
    userObj.vnodePerCall = TSDB_USER_VNODE_PER_CALL_DEFAULT;
×
1001
    userObj.passwordReuseTime = TSDB_USER_PASSWORD_REUSE_TIME_DEFAULT;
×
1002
    userObj.passwordReuseMax = TSDB_USER_PASSWORD_REUSE_MAX_DEFAULT;
×
1003
    userObj.passwordLockTime = TSDB_USER_PASSWORD_LOCK_TIME_DEFAULT;
×
1004
    userObj.sessionPerUser = TSDB_USER_SESSION_PER_USER_DEFAULT;
×
1005
    userObj.failedLoginAttempts = TSDB_USER_FAILED_LOGIN_ATTEMPTS_DEFAULT;
×
1006
    userObj.passwordLifeTime = TSDB_USER_PASSWORD_LIFE_TIME_DEFAULT;
×
1007
    userObj.passwordGraceTime = TSDB_USER_PASSWORD_GRACE_TIME_DEFAULT;
×
1008
    userObj.inactiveAccountTime = TSDB_USER_INACTIVE_ACCOUNT_TIME_DEFAULT;
×
1009
  } else {
1010
    userObj.changePass = 2;  // allow but not force user to change password
330,616✔
1011
    userObj.connectTime = -1;
330,616✔
1012
    userObj.connectIdleTime = -1;
330,616✔
1013
    userObj.callPerSession = -1;
330,616✔
1014
    userObj.vnodePerCall = -1;
330,616✔
1015
    userObj.passwordReuseTime = 0;
330,616✔
1016
    userObj.passwordReuseMax = 0;
330,616✔
1017
    userObj.passwordLockTime = 1;
330,616✔
1018
    userObj.sessionPerUser = -1;
330,616✔
1019
    userObj.failedLoginAttempts = -1;
330,616✔
1020
    userObj.passwordLifeTime = -1;
330,616✔
1021
    userObj.passwordGraceTime = -1;
330,616✔
1022
    userObj.inactiveAccountTime = -1;
330,616✔
1023
  }
1024

1025
  userObj.allowTokenNum = TSDB_USER_ALLOW_TOKEN_NUM_DEFAULT;
330,616✔
1026
  userObj.tokenNum = 0;
330,616✔
1027

1028
#else  // TD_ENTERPRISE
1029

1030
  userObj.ipWhiteListVer = 0;
1031
  userObj.timeWhiteListVer = 0;
1032
  userObj.changePass = 2;  // 2: allow but not force user to change password
1033
  userObj.connectTime = -1;
1034
  userObj.connectIdleTime = -1;
1035
  userObj.callPerSession = -1;
1036
  userObj.vnodePerCall = -1;
1037
  userObj.passwordReuseTime = 0;
1038
  userObj.passwordReuseMax = 0;
1039
  userObj.passwordLockTime = 1;
1040
  userObj.sessionPerUser = -1;
1041
  userObj.failedLoginAttempts = -1;
1042
  userObj.passwordLifeTime = -1;
1043
  userObj.passwordGraceTime = -1;
1044
  userObj.inactiveAccountTime = -1;
1045
  userObj.allowTokenNum = -1;
1046
  userObj.tokenNum = 0;
1047

1048
#endif  // TD_ENTERPRISE
1049

1050
  userObj.pTimeWhiteList = taosMemoryCalloc(1, sizeof(SDateTimeWhiteList));
330,616✔
1051
  if (userObj.pTimeWhiteList == NULL) {
330,616✔
1052
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _ERROR);
×
1053
  }
1054

1055
  TAOS_CHECK_GOTO(createDefaultIpWhiteList(&userObj.pIpWhiteListDual), &lino, _ERROR);
330,616✔
1056
  // if this is the root user, change the value of some fields to allow the user login without restriction
1057
  if (strcmp(user, TSDB_DEFAULT_USER) == 0) {
330,616✔
1058
    userObj.superUser = 1;
330,616✔
1059
    userObj.createdb = 1;
330,616✔
1060
    userObj.sessionPerUser = -1;
330,616✔
1061
    userObj.callPerSession = -1;
330,616✔
1062
    userObj.vnodePerCall = -1;
330,616✔
1063
    userObj.failedLoginAttempts = -1;
330,616✔
1064
    userObj.passwordGraceTime = -1;
330,616✔
1065
    userObj.inactiveAccountTime = -1;
330,616✔
1066
  }
1067

1068
  userObj.roles = taosHashInit(1, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
330,616✔
1069
  if (userObj.roles == NULL) {
330,616✔
1070
    TAOS_CHECK_GOTO(terrno, &lino, _ERROR);
×
1071
  }
1072

1073
  if ((code = taosHashPut(userObj.roles, TSDB_ROLE_SYSDBA, strlen(TSDB_ROLE_SYSDBA) + 1, NULL, 0)) ||
661,232✔
1074
      (code = taosHashPut(userObj.roles, TSDB_ROLE_SYSSEC, strlen(TSDB_ROLE_SYSSEC) + 1, NULL, 0)) ||
661,232✔
1075
      (code = taosHashPut(userObj.roles, TSDB_ROLE_SYSAUDIT, strlen(TSDB_ROLE_SYSAUDIT) + 1, NULL, 0))) {
330,616✔
1076
    TAOS_CHECK_GOTO(code, &lino, _ERROR);
×
1077
  }
1078

1079
  SSdbRaw *pRaw = mndUserActionEncode(&userObj);
330,616✔
1080
  if (pRaw == NULL) goto _ERROR;
330,616✔
1081
  TAOS_CHECK_GOTO(sdbSetRawStatus(pRaw, SDB_STATUS_READY), &lino, _ERROR);
330,616✔
1082

1083
  mInfo("user:%s, will be created when deploying, raw:%p", userObj.user, pRaw);
330,616✔
1084

1085
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_ROLE, NULL, "create-user");
330,616✔
1086
  if (pTrans == NULL) {
330,616✔
1087
    sdbFreeRaw(pRaw);
×
1088
    mError("user:%s, failed to create since %s", userObj.user, terrstr());
×
1089
    goto _ERROR;
×
1090
  }
1091
  mInfo("trans:%d, used to create user:%s", pTrans->id, userObj.user);
330,616✔
1092

1093
  if (mndTransAppendCommitlog(pTrans, pRaw) != 0) {
330,616✔
1094
    mError("trans:%d, failed to commit redo log since %s", pTrans->id, terrstr());
×
1095
    mndTransDrop(pTrans);
×
1096
    goto _ERROR;
×
1097
  }
1098
  TAOS_CHECK_GOTO(sdbSetRawStatus(pRaw, SDB_STATUS_READY), &lino, _ERROR);
330,616✔
1099

1100
  if (mndTransPrepare(pMnode, pTrans) != 0) {
330,616✔
1101
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
1102
    mndTransDrop(pTrans);
×
1103
    goto _ERROR;
×
1104
  }
1105

1106
  mndTransDrop(pTrans);
330,616✔
1107
  mndUserFreeObj(&userObj);
330,616✔
1108
  return 0;
330,616✔
1109

1110
_ERROR:
×
1111
  mndUserFreeObj(&userObj);
×
1112
  if (code == 0) {
×
1113
    code = terrno ? terrno : TSDB_CODE_APP_ERROR;
×
1114
  }
1115
  mError("user:%s, failed to create default user since %s", user, tstrerror(code));
×
1116
  TAOS_RETURN(code);
×
1117
}
1118

1119
static int32_t mndCreateDefaultUsers(SMnode *pMnode) {
330,616✔
1120
  return mndCreateDefaultUser(pMnode, TSDB_DEFAULT_USER, TSDB_DEFAULT_USER, TSDB_DEFAULT_PASS);
330,616✔
1121
}
1122

1123
static int32_t mndUserPrivUpgradeDbOwners(SMnode *pMnode, SRpcMsg *pReq) {
×
1124
  int32_t code = 0, lino = 0;
×
1125
  SSdb   *pSdb = pMnode->pSdb;
×
1126
  SDbObj *pObj = NULL;
×
1127
  void   *pIter = NULL;
×
1128

1129
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "upgrade-db");
×
1130
  if (pTrans == NULL) {
×
1131
    TAOS_CHECK_EXIT(terrno);
×
1132
  }
1133

1134
  while ((pIter = sdbFetch(pSdb, SDB_DB, pIter, (void **)&pObj))) {
×
1135
    if (pObj->cfg.isMount) {
×
1136
      sdbRelease(pSdb, pObj);
×
1137
      continue;
×
1138
    }
1139
    if (pObj->ownerId != 0) {
×
1140
      sdbRelease(pSdb, pObj);
×
1141
      continue;
×
1142
    }
1143
    SUserObj *pUser = NULL;
×
1144
    (void)mndAcquireUser(pMnode, pObj->createUser, &pUser);
×
1145
    if (pUser == NULL) {
×
1146
      mWarn("db:%s, owner user:%s not found, skip upgrade owner uid", pObj->name, pObj->createUser);
×
1147
      sdbRelease(pSdb, pObj);
×
1148
      continue;
×
1149
    }
1150
    if (pUser->uid == 0) {
×
1151
      mndReleaseUser(pMnode, pUser);
×
1152
      sdbRelease(pSdb, pObj);
×
1153
      continue;
×
1154
    }
1155
    SDbObj newObj = {0};
×
1156
    memcpy(&newObj, pObj, sizeof(SDbObj));
×
1157
    ++newObj.cfgVersion;
×
1158
    newObj.updateTime = taosGetTimestampMs();
×
1159
    newObj.ownerId = pUser->uid;
×
1160
    mInfo("db:%s, owner uid upgraded to %" PRId64, pObj->name, pUser->uid);
×
1161
    mndReleaseUser(pMnode, pUser);
×
1162
    if ((code = mndSetAlterDbCommitLogs(pMnode, pTrans, pObj, &newObj))) {
×
1163
      sdbCancelFetch(pSdb, pIter);
×
1164
      sdbRelease(pSdb, pObj);
×
1165
      TAOS_CHECK_EXIT(code);
×
1166
    }
1167
    sdbRelease(pSdb, pObj);
×
1168
  }
1169

1170
  TAOS_CHECK_EXIT(mndTransPrepare(pMnode, pTrans));
×
1171

1172
_exit:
×
1173
  mndTransDrop(pTrans);
×
1174
  if (code < 0) {
×
1175
    mError("failed at line %d to upgrade db owner uid since %s", lino, tstrerror(code));
×
1176
  }
1177
  TAOS_RETURN(code);
×
1178
}
1179

1180
static int32_t mndUserPrivUpgradeOwnedDbs(SMnode *pMnode, SUserObj *pUser) {
×
1181
  int32_t code = 0, lino = 0;
×
1182
  SSdb   *pSdb = pMnode->pSdb;
×
1183
  SDbObj *pObj = NULL;
×
1184
  void   *pIter = NULL;
×
1185
  char   *key = NULL;
×
1186
  while ((pIter = sdbFetch(pSdb, SDB_DB, pIter, (void **)&pObj))) {
×
1187
    if (strncmp(pObj->createUser, pUser->name, sizeof(pObj->createUser)) != 0) {
×
1188
      sdbRelease(pSdb, pObj);
×
1189
      pObj = NULL;
×
1190
      continue;
×
1191
    }
1192
    TAOS_CHECK_EXIT(taosHashPut(pUser->ownedDbs, pObj->name, strlen(pObj->name) + 1, NULL, 0));
×
1193
    sdbRelease(pSdb, pObj);
×
1194
    pObj = NULL;
×
1195
  }
1196
_exit:
×
1197
  if (pIter) sdbCancelFetch(pSdb, pIter);
×
1198
  if (pObj) sdbRelease(pSdb, pObj);
×
1199
  TAOS_RETURN(code);
×
1200
}
1201

1202
#ifdef TD_ENTERPRISE
1203
static int32_t mndUserPrivUpgradeTbViews(SMnode *pMnode, SUserObj *pUser, SHashObj **ppTblHash, SHashObj *pTbs, int32_t privType,
×
1204
                                         uint8_t objType) {
1205
  int32_t code = 0, lino = 0;
×
1206
  void   *pIter = NULL;
×
1207
  char   *key = NULL;
×
1208
  char   *value = NULL;
×
1209

1210
  SAlterRoleReq alterReq = {.alterType = TSDB_ALTER_ROLE_PRIVILEGES, .add = 1, .objType = objType, .objLevel = 1};
×
1211

1212
  while ((pIter = taosHashIterate(pTbs, pIter))) {
×
1213
    size_t keyLen = 0;
×
1214
    key = taosHashGetKey(pIter, &keyLen);
×
1215

1216
    SName name = {0};
×
1217
    TAOS_CHECK_EXIT(tNameFromString(&name, key, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE));
×
1218

1219
    snprintf(alterReq.objFName, TSDB_OBJ_FNAME_LEN, "%d.%s", name.acctId, name.dbname);
×
1220
    snprintf(alterReq.tblName, TSDB_TABLE_NAME_LEN, "%s", name.tname);
×
1221

1222
    privAddType(&alterReq.privileges.privSet, privType);
1223

1224
    if ((objType == PRIV_OBJ_TBL) && (((char *)pIter)[0] != 0) && (((char *)pIter)[1] != 0)) {
×
1225
      alterReq.privileges.cond = taosStrdup(pIter);
×
1226
      if (alterReq.privileges.cond == NULL) {
×
1227
        TAOS_CHECK_EXIT(terrno);
×
1228
      }
1229
      alterReq.privileges.condLen = strlen(pIter) + 1;  // include '\0'
×
1230
      if (ppTblHash && !*ppTblHash) {
×
1231
        *ppTblHash = taosHashInit(1, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), true, HASH_ENTRY_LOCK);
×
1232
        if (!*ppTblHash) {
×
1233
          TAOS_CHECK_EXIT(terrno);
×
1234
        }
1235
        taosHashSetFreeFp(*ppTblHash, privTblPoliciesFree);
×
1236
      }
1237
    }
1238

1239
    TAOS_CHECK_EXIT(mndAlterUserPrivInfo(pMnode, pUser, &alterReq));
×
1240
    tFreeSAlterRoleReq(&alterReq);
×
1241
  }
1242
_exit:
×
1243
  tFreeSAlterRoleReq(&alterReq);
×
1244
  TAOS_RETURN(code);
×
1245
}
1246

1247
/**
1248
 * @brief upgrade read/write db privileges from 3.3.x.y to 3.4.x.y
1249
 * @param rwType 0x01 read, 0x02 write
1250
 */
1251
static int32_t mndUserPrivUpgradeRwDbs(SMnode *pMnode, SUserObj *pUser, SHashObj *pDbs, int8_t rwType) {
×
1252
  int32_t code = 0, lino = 0;
×
1253
  void   *pIter = NULL;
×
1254
  char   *key = NULL;
×
1255
  while ((pIter = taosHashIterate(pDbs, pIter))) {
×
1256
    key = taosHashGetKey(pIter, NULL);
×
1257
    TAOS_CHECK_EXIT(privUpgradeRwDb(pUser->objPrivs, key, "*", rwType));
×
1258
  }
1259
_exit:
×
1260
  TAOS_RETURN(code);
×
1261
}
1262

1263
static int32_t mndUserPrivUpgradeUsedDbs(SMnode *pMnode, SUserObj *pUser, SHashObj *pDbs) {
×
1264
  int32_t code = 0, lino = 0;
×
1265
  void   *pIter = NULL;
×
1266
  char   *key = NULL;
×
1267
  char   *value = NULL;
×
1268

1269
  SAlterRoleReq alterReq = {.alterType = TSDB_ALTER_ROLE_PRIVILEGES, .add = 1, .objType = PRIV_OBJ_DB};
×
1270

1271
  while ((pIter = taosHashIterate(pDbs, pIter))) {
×
1272
    key = taosHashGetKey(pIter, NULL);
×
1273

1274
    SName name = {0};
×
1275
    TAOS_CHECK_EXIT(tNameFromString(&name, key, T_NAME_ACCT | T_NAME_DB));
×
1276

1277
    snprintf(alterReq.objFName, TSDB_OBJ_FNAME_LEN, "%d.%s", name.acctId, name.dbname);
×
1278

1279
    privAddType(&alterReq.privileges.privSet, PRIV_DB_USE);
1280

1281
    TAOS_CHECK_EXIT(mndAlterUserPrivInfo(pMnode, pUser, &alterReq));
×
1282
  }
1283
_exit:
×
1284
  tFreeSAlterRoleReq(&alterReq);
×
1285
  TAOS_RETURN(code);
×
1286
}
1287

1288
static int32_t mndUserPrivUpgradeTopics(SMnode *pMnode, SUserObj *pUser, SHashObj *pTopics) {
×
1289
  int32_t code = 0, lino = 0;
×
1290
  void   *pIter = NULL;
×
1291
  char   *key = NULL;
×
1292
  char   *value = NULL;
×
1293

1294
  SAlterRoleReq alterReq = {.alterType = TSDB_ALTER_ROLE_PRIVILEGES,
×
1295
                            .add = 1,
1296
                            .objType = PRIV_OBJ_TOPIC,
1297
                            .objLevel = 1,
1298
                            .ignoreNotExists = 1};
1299

1300
  while ((pIter = taosHashIterate(pTopics, pIter))) {
×
1301
    size_t keyLen = 0;
×
1302
    key = taosHashGetKey(pIter, &keyLen);
×
1303

1304
    SName name = {0};
×
1305
    if (tNameFromString(&name, key, T_NAME_ACCT | T_NAME_DB)) {  // 1.topicName
×
1306
      continue;
×
1307
    }
1308
    snprintf(alterReq.tblName, TSDB_TABLE_NAME_LEN, "%s", name.dbname);
×
1309

1310
    SMqTopicObj *pTopic = NULL;
×
1311
    if (mndAcquireTopic(pMnode, key, &pTopic)) {
×
1312
      continue;  // no topic exists
×
1313
    }
1314
    snprintf(alterReq.objFName, TSDB_OBJ_FNAME_LEN, "%s", pTopic->db);
×
1315
    mndReleaseTopic(pMnode, pTopic);
×
1316

1317
    privAddType(&alterReq.privileges.privSet, PRIV_CM_SUBSCRIBE);
1318

1319
    TAOS_CHECK_EXIT(mndAlterUserPrivInfo(pMnode, pUser, &alterReq));
×
1320
  }
1321
_exit:
×
1322
  tFreeSAlterRoleReq(&alterReq);
×
1323
  TAOS_RETURN(code);
×
1324
}
1325
#endif
1326

1327
/**
1328
 * @brief migrate from 3.3.x.y to 3.4.x.y
1329
 * @return int32_t
1330
 */
1331
static int32_t mndUserPrivUpgradeUser(SMnode *pMnode, SUserObj *pObj) {
×
1332
  int32_t          code = 0, lino = 0;
×
1333
  SPrivHashObjSet *pPrivSet = pObj->legacyPrivs;
×
1334

1335
  if (pObj->uid == 0) {
×
1336
    pObj->uid = mndGenerateUid(pObj->name, strlen(pObj->name));
×
1337
  }
1338

1339
  if (!pObj->objPrivs &&
×
1340
      !(pObj->objPrivs = taosHashInit(1, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK))) {
×
1341
    TAOS_CHECK_EXIT(terrno);
×
1342
  }
1343

1344
  if (!pObj->roles &&
×
1345
      !(pObj->roles = taosHashInit(1, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK))) {
×
1346
    TAOS_CHECK_EXIT(terrno);
×
1347
  }
1348

1349
  // assign roles and system privileges
1350
  uint8_t flag = 0x01;
×
1351
  if (pObj->superUser) {
×
1352
    TAOS_CHECK_EXIT(taosHashPut(pObj->roles, TSDB_ROLE_SYSDBA, strlen(TSDB_ROLE_SYSDBA) + 1, &flag, sizeof(flag)));
×
1353
    TAOS_CHECK_EXIT(taosHashPut(pObj->roles, TSDB_ROLE_SYSSEC, strlen(TSDB_ROLE_SYSSEC) + 1, &flag, sizeof(flag)));
×
1354
    TAOS_CHECK_EXIT(taosHashPut(pObj->roles, TSDB_ROLE_SYSAUDIT, strlen(TSDB_ROLE_SYSAUDIT) + 1, &flag, sizeof(flag)));
×
1355
  } else {
1356
    if (pObj->sysInfo == 1) {
×
1357
      TAOS_CHECK_EXIT(
×
1358
          taosHashPut(pObj->roles, TSDB_ROLE_SYSINFO_1, strlen(TSDB_ROLE_SYSINFO_1) + 1, &flag, sizeof(flag)));
1359
    } else {
1360
      TAOS_CHECK_EXIT(
×
1361
          taosHashPut(pObj->roles, TSDB_ROLE_SYSINFO_0, strlen(TSDB_ROLE_SYSINFO_0) + 1, &flag, sizeof(flag)));
1362
    }
1363
    if (pObj->createdb == 1) {
×
1364
      privAddType(&pObj->sysPrivs, PRIV_DB_CREATE);
×
1365
    }
1366
  }
1367
#ifdef TD_ENTERPRISE
1368
  if (pPrivSet) {
×
1369
    // read db: db.*
1370
    TAOS_CHECK_EXIT(mndUserPrivUpgradeRwDbs(pMnode, pObj, pPrivSet->pReadDbs, 0x01));
×
1371
    // write db: db.*
1372
    TAOS_CHECK_EXIT(mndUserPrivUpgradeRwDbs(pMnode, pObj, pPrivSet->pWriteDbs, 0x02));
×
1373
    // tables/views
1374
    TAOS_CHECK_EXIT(
×
1375
        mndUserPrivUpgradeTbViews(pMnode, pObj, &pObj->selectTbs, pPrivSet->pReadTbs, PRIV_TBL_SELECT, PRIV_OBJ_TBL));
1376
    TAOS_CHECK_EXIT(
×
1377
        mndUserPrivUpgradeTbViews(pMnode, pObj, &pObj->insertTbs, pPrivSet->pWriteTbs, PRIV_TBL_INSERT, PRIV_OBJ_TBL));
1378
    TAOS_CHECK_EXIT(mndUserPrivUpgradeTbViews(pMnode, pObj, NULL, pPrivSet->pAlterTbs, PRIV_CM_ALTER, PRIV_OBJ_TBL));
×
1379
    TAOS_CHECK_EXIT(
×
1380
        mndUserPrivUpgradeTbViews(pMnode, pObj, NULL, pPrivSet->pReadViews, PRIV_VIEW_SELECT, PRIV_OBJ_VIEW));
1381
    TAOS_CHECK_EXIT(mndUserPrivUpgradeTbViews(pMnode, pObj, NULL, pPrivSet->pAlterViews, PRIV_CM_ALTER, PRIV_OBJ_VIEW));
×
1382
    TAOS_CHECK_EXIT(mndUserPrivUpgradeTbViews(pMnode, pObj, NULL, pPrivSet->pAlterViews, PRIV_CM_DROP, PRIV_OBJ_VIEW));
×
1383
    // used dbs
1384
    TAOS_CHECK_EXIT(mndUserPrivUpgradeUsedDbs(pMnode, pObj, pPrivSet->pUseDbs));
×
1385
    // subscribe
1386
    TAOS_CHECK_EXIT(mndUserPrivUpgradeTopics(pMnode, pObj, pPrivSet->pTopics));
×
1387
  }
1388
#endif
1389
  // owned dbs
1390
  TAOS_CHECK_EXIT(mndUserPrivUpgradeOwnedDbs(pMnode, pObj));
×
1391
  mInfo("user:%s, upgraded with uid:%" PRId64, pObj->name, pObj->uid);
×
1392
_exit:
×
1393
  TAOS_RETURN(code);
×
1394
}
1395

1396
static int32_t mndUserPrivUpgradeUsers(SMnode *pMnode, SRpcMsg *pReq) {
×
1397
  int32_t   code = 0, lino = 0;
×
1398
  SSdb     *pSdb = pMnode->pSdb;
×
1399
  SUserObj *pObj = NULL;
×
1400
  void     *pIter = NULL;
×
1401
  SUserObj  newObj = {0};
×
1402
  SUserObj *pRoot = NULL;
×
1403
  bool      forceUpgrade = false;
×
1404

1405
  if (0 == mndAcquireUser(pMnode, TSDB_DEFAULT_USER, &pRoot)) {
×
1406
    if (taosHashGetSize(pRoot->roles) == 0) {
×
1407
      forceUpgrade = true;
×
1408
    }
1409
    mndReleaseUser(pMnode, pRoot);
×
1410
  }
1411

1412
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pObj))) {
×
1413
    if (pObj->uid != 0 && pObj->legacyPrivs == NULL && !forceUpgrade) {
×
1414
      sdbRelease(pSdb, pObj);
×
1415
      pObj = NULL;
×
1416
      continue;
×
1417
    }
1418
    if (pObj->uid == 0) {
×
1419
      // Assign uid firstly because the transactions in mndUserPrivUpgradeUsers may not finish when
1420
      // mndUserPrivUpgradeDbOwners is called
1421
      pObj->uid = mndGenerateUid(pObj->name, strlen(pObj->name));
×
1422
    }
1423
    memset(&newObj, 0, sizeof(SUserObj));
×
1424
    TAOS_CHECK_EXIT(mndUserDupObj(pObj, &newObj));
×
1425
    TAOS_CHECK_EXIT(mndUserPrivUpgradeUser(pMnode, &newObj));
×
1426
    TAOS_CHECK_EXIT(mndAlterUser(pMnode, &newObj, pReq));
×
1427
    mndUserFreeObj(&newObj);
×
1428
    sdbRelease(pSdb, pObj);
×
1429
    pObj = NULL;
×
1430
  }
1431
_exit:
×
1432
  sdbCancelFetch(pSdb, pIter);
×
1433
  sdbRelease(pSdb, pObj);
×
1434
  mndUserFreeObj(&newObj);
×
1435
  if (code < 0) {
×
1436
    mError("failed at line %d to upgrade db owner uid since %s", lino, tstrerror(code));
×
1437
  }
1438
  TAOS_RETURN(code);
×
1439
}
1440

1441
static int32_t mndProcessUpgradeUserReq(SRpcMsg *pReq) {
×
1442
  SMnode *pMnode = pReq->info.node;
×
1443
  int32_t code = 0, lino = 0;
×
1444

1445
  TAOS_CHECK_EXIT(mndUserPrivUpgradeUsers(pMnode, pReq));
×
1446
  TAOS_CHECK_EXIT(mndUserPrivUpgradeDbOwners(pMnode, pReq));
×
1447
_exit:
×
1448
  if (code < 0) {
×
1449
    mError("failed at line %d to upgrade users since %s", lino, tstrerror(code));
×
1450
  }
1451
  TAOS_RETURN(code);
×
1452
}
1453

1454
static int32_t mndProcessUpgradeUserRsp(SRpcMsg *pReq) { return 0;}
×
1455

1456
static int32_t mndUpgradeUsers(SMnode *pMnode, int32_t version) {
415,263✔
1457
  int32_t code = 0, lino = 0;
415,263✔
1458
  if (upgradeSecurity == 0) return code;
415,263✔
1459
  if (!mndIsLeader(pMnode)) return code;
×
1460

1461
  SRpcMsg rpcMsg = {.msgType = TDMT_MND_UPGRADE_USER, .info.ahandle = 0, .info.notFreeAhandle = 1};
×
1462
  SEpSet  epSet = {0};
×
1463
  mndGetMnodeEpSet(pMnode, &epSet);
×
1464
  TAOS_CHECK_EXIT(tmsgSendReq(&epSet, &rpcMsg));
×
1465
_exit:
×
1466
  if (code < 0) {
×
1467
    mError("failed at line %d to upgrade users since %s", lino, tstrerror(code));
×
1468
  }
1469
  TAOS_RETURN(code);
×
1470
}
1471

1472
static int32_t tSerializeUserObjExt(void *buf, int32_t bufLen, SUserObj *pObj) {
8,449,470✔
1473
  int32_t  code = 0, lino = 0;
8,449,470✔
1474
  int32_t  tlen = 0;
8,449,470✔
1475
  void    *pIter = NULL;
8,449,470✔
1476
  SEncoder encoder = {0};
8,449,470✔
1477
  tEncoderInit(&encoder, buf, bufLen);
8,449,470✔
1478

1479
  TAOS_CHECK_EXIT(tStartEncode(&encoder));
8,449,470✔
1480
  TAOS_CHECK_EXIT(tEncodeI64v(&encoder, pObj->uid));
16,898,940✔
1481

1482
  TAOS_CHECK_EXIT(tSerializePrivSysObjPolicies(&encoder, &pObj->sysPrivs, pObj->objPrivs));
8,449,470✔
1483

1484
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->selectTbs));
8,449,470✔
1485
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->insertTbs));
8,449,470✔
1486
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->updateTbs));
8,449,470✔
1487
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->deleteTbs));
8,449,470✔
1488

1489
  int32_t nRoles = taosHashGetSize(pObj->roles);
8,449,470✔
1490
  TAOS_CHECK_EXIT(tEncodeI32v(&encoder, nRoles));
8,449,470✔
1491

1492
  while ((pIter = taosHashIterate(pObj->roles, pIter))) {
26,836,062✔
1493
    size_t keyLen = 0;
18,386,592✔
1494
    char  *key = taosHashGetKey(pIter, &keyLen);  // key: role name
18,386,592✔
1495
    TAOS_CHECK_EXIT(tEncodeCStr(&encoder, key));
18,386,592✔
1496

1497
    uint8_t flag = *(uint8_t *)pIter;
18,386,592✔
1498
    TAOS_CHECK_EXIT(tEncodeU8(&encoder, flag));  // value: 0 reset, 1 set(default)
36,773,184✔
1499
  }
1500

1501
  int32_t nOwnedDbs = taosHashGetSize(pObj->ownedDbs);
8,449,470✔
1502
  TAOS_CHECK_EXIT(tEncodeI32v(&encoder, nOwnedDbs));
8,449,470✔
1503
  pIter = NULL;
8,449,470✔
1504
  while ((pIter = taosHashIterate(pObj->ownedDbs, pIter))) {
32,013,572✔
1505
    size_t keyLen = 0;
23,564,102✔
1506
    char  *key = taosHashGetKey(pIter, &keyLen);  // key: dbFName
23,564,102✔
1507
    TAOS_CHECK_EXIT(tEncodeCStr(&encoder, key));
23,564,102✔
1508
  }
1509

1510
  tEndEncode(&encoder);
8,449,470✔
1511
  tlen = encoder.pos;
8,449,470✔
1512
_exit:
8,449,470✔
1513
  tEncoderClear(&encoder);
8,449,470✔
1514
  if (code < 0) {
8,449,470✔
1515
    mError("user:%s, %s failed at line %d since %s", pObj->user, __func__, lino, tstrerror(code));
×
1516
    TAOS_RETURN(code);
×
1517
  }
1518

1519
  return tlen;
8,449,470✔
1520
}
1521

1522
static int32_t tDeserializeUserObjExt(void *buf, int32_t bufLen, SUserObj *pObj) {
3,385,135✔
1523
  int32_t  code = 0, lino = 0;
3,385,135✔
1524
  SDecoder decoder = {0};
3,385,135✔
1525
  tDecoderInit(&decoder, buf, bufLen);
3,385,135✔
1526

1527
  TAOS_CHECK_EXIT(tStartDecode(&decoder));
3,385,135✔
1528
  TAOS_CHECK_EXIT(tDecodeI64v(&decoder, &pObj->uid));
6,770,270✔
1529
  TAOS_CHECK_EXIT(tDeserializePrivSysObjPolicies(&decoder, &pObj->sysPrivs, &pObj->objPrivs));
3,385,135✔
1530
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->selectTbs));
3,385,135✔
1531
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->insertTbs));
3,385,135✔
1532
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->updateTbs));
3,385,135✔
1533
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->deleteTbs));
3,385,135✔
1534
  int32_t nRoles = 0;
3,385,135✔
1535
  TAOS_CHECK_EXIT(tDecodeI32v(&decoder, &nRoles));
3,385,135✔
1536
  if (nRoles > 0) {
3,385,135✔
1537
    if (!pObj->roles &&
3,351,327✔
1538
        !(pObj->roles = taosHashInit(nRoles, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), 1, HASH_ENTRY_LOCK))) {
3,351,327✔
1539
      TAOS_CHECK_EXIT(terrno);
×
1540
    }
1541
    for (int32_t i = 0; i < nRoles; i++) {
10,283,420✔
1542
      int32_t keyLen = 0;
6,932,093✔
1543
      char   *key = NULL;
6,932,093✔
1544
      TAOS_CHECK_EXIT(tDecodeCStrAndLen(&decoder, &key, &keyLen));
6,932,093✔
1545
      uint8_t flag = 0;
6,932,093✔
1546
      TAOS_CHECK_EXIT(tDecodeU8(&decoder, &flag));
6,932,093✔
1547
      TAOS_CHECK_EXIT(taosHashPut(pObj->roles, key, keyLen + 1, &flag, sizeof(flag)));
6,932,093✔
1548
    }
1549
  }
1550
  if (!tDecodeIsEnd(&decoder)) {
3,385,135✔
1551
    int32_t nOwnedDbs = 0;
3,385,135✔
1552
    TAOS_CHECK_EXIT(tDecodeI32v(&decoder, &nOwnedDbs));
3,385,135✔
1553
    if (nOwnedDbs > 0) {
3,385,135✔
1554
      if (!pObj->ownedDbs &&
1,429,367✔
1555
          !(pObj->ownedDbs =
1,429,367✔
1556
                taosHashInit(nOwnedDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), 1, HASH_ENTRY_LOCK))) {
1,429,367✔
1557
        TAOS_CHECK_EXIT(terrno);
×
1558
      }
1559
      for (int32_t i = 0; i < nOwnedDbs; ++i) {
12,037,562✔
1560
        int32_t keyLen = 0;
10,608,195✔
1561
        char   *key = NULL;
10,608,195✔
1562
        TAOS_CHECK_EXIT(tDecodeCStrAndLen(&decoder, &key, &keyLen));
10,608,195✔
1563
        TAOS_CHECK_EXIT(taosHashPut(pObj->ownedDbs, key, keyLen + 1, NULL, 0));
10,608,195✔
1564
      }
1565
    }
1566
  }
1567

1568
_exit:
3,382,838✔
1569
  tEndDecode(&decoder);
3,385,135✔
1570
  tDecoderClear(&decoder);
3,385,135✔
1571
  if (code < 0) {
3,385,135✔
1572
    mError("user, %s failed at line %d since %s, row:%p", __func__, lino, tstrerror(code), pObj);
×
1573
  }
1574
  TAOS_RETURN(code);
3,385,135✔
1575
}
1576

1577
SSdbRaw *mndUserActionEncode(SUserObj *pUser) {
4,224,735✔
1578
  int32_t code = 0;
4,224,735✔
1579
  int32_t lino = 0;
4,224,735✔
1580
  int32_t passReserve = (sizeof(SUserPassword) + 8) * pUser->numOfPasswords + 4;
4,224,735✔
1581
  int32_t ipWhiteReserve =
×
1582
      pUser->pIpWhiteListDual ? (sizeof(SIpRange) * pUser->pIpWhiteListDual->num + sizeof(SIpWhiteListDual) + 4) : 16;
4,224,735✔
1583
  int32_t timeWhiteReserve =
×
1584
      pUser->pTimeWhiteList
4,224,735✔
1585
          ? (sizeof(SDateTimeWhiteListItem) * pUser->pTimeWhiteList->num + sizeof(SDateTimeWhiteList) + 4)
4,224,735✔
1586
          : 16;
1587
  int32_t numOfReadDbs = 0;     // taosHashGetSize(pUser->readDbs);
4,224,735✔
1588
  int32_t numOfWriteDbs = 0;    // taosHashGetSize(pUser->writeDbs);
4,224,735✔
1589
  int32_t numOfReadTbs = 0;     // taosHashGetSize(pUser->readTbs);
4,224,735✔
1590
  int32_t numOfWriteTbs = 0;    // taosHashGetSize(pUser->writeTbs);
4,224,735✔
1591
  int32_t numOfAlterTbs = 0;    // taosHashGetSize(pUser->alterTbs);
4,224,735✔
1592
  int32_t numOfReadViews = 0;   // taosHashGetSize(pUser->readViews);
4,224,735✔
1593
  int32_t numOfWriteViews = 0;  // taosHashGetSize(pUser->writeViews);
4,224,735✔
1594
  int32_t numOfAlterViews = 0;  // taosHashGetSize(pUser->alterViews);
4,224,735✔
1595
  int32_t numOfTopics = 0;      // taosHashGetSize(pUser->topics);
4,224,735✔
1596
  int32_t numOfUseDbs = 0;      // taosHashGetSize(pUser->useDbs);
4,224,735✔
1597
  int32_t numOfRoles = taosHashGetSize(pUser->roles);
4,224,735✔
1598
  int32_t size = sizeof(SUserObj) + USER_RESERVE_SIZE + (numOfReadDbs + numOfWriteDbs) * TSDB_DB_FNAME_LEN +
4,224,735✔
1599
                 numOfTopics * TSDB_TOPIC_FNAME_LEN + ipWhiteReserve + timeWhiteReserve + passReserve;
4,224,735✔
1600
  char    *buf = NULL;
4,224,735✔
1601
  SSdbRaw *pRaw = NULL;
4,224,735✔
1602

1603
  char *stb = NULL;
4,224,735✔
1604
#if 0
1605
  stb = taosHashIterate(pUser->readTbs, NULL);
1606
  while (stb != NULL) {
1607
    size_t keyLen = 0;
1608
    void  *key = taosHashGetKey(stb, &keyLen);
1609
    size += sizeof(int32_t);
1610
    size += keyLen;
1611

1612
    size_t valueLen = 0;
1613
    valueLen = strlen(stb) + 1;
1614
    size += sizeof(int32_t);
1615
    size += valueLen;
1616
    stb = taosHashIterate(pUser->readTbs, stb);
1617
  }
1618

1619
  stb = taosHashIterate(pUser->writeTbs, NULL);
1620
  while (stb != NULL) {
1621
    size_t keyLen = 0;
1622
    void  *key = taosHashGetKey(stb, &keyLen);
1623
    size += sizeof(int32_t);
1624
    size += keyLen;
1625

1626
    size_t valueLen = 0;
1627
    valueLen = strlen(stb) + 1;
1628
    size += sizeof(int32_t);
1629
    size += valueLen;
1630
    stb = taosHashIterate(pUser->writeTbs, stb);
1631
  }
1632
  stb = taosHashIterate(pUser->alterTbs, NULL);
1633
  while (stb != NULL) {
1634
    size_t keyLen = 0;
1635
    void  *key = taosHashGetKey(stb, &keyLen);
1636
    size += sizeof(int32_t);
1637
    size += keyLen;
1638

1639
    size_t valueLen = 0;
1640
    valueLen = strlen(stb) + 1;
1641
    size += sizeof(int32_t);
1642
    size += valueLen;
1643
    stb = taosHashIterate(pUser->alterTbs, stb);
1644
  }
1645

1646
  stb = taosHashIterate(pUser->readViews, NULL);
1647
  while (stb != NULL) {
1648
    size_t keyLen = 0;
1649
    void  *key = taosHashGetKey(stb, &keyLen);
1650
    size += sizeof(int32_t);
1651
    size += keyLen;
1652

1653
    size_t valueLen = 0;
1654
    valueLen = strlen(stb) + 1;
1655
    size += sizeof(int32_t);
1656
    size += valueLen;
1657
    stb = taosHashIterate(pUser->readViews, stb);
1658
  }
1659

1660
  stb = taosHashIterate(pUser->writeViews, NULL);
1661
  while (stb != NULL) {
1662
    size_t keyLen = 0;
1663
    void  *key = taosHashGetKey(stb, &keyLen);
1664
    size += sizeof(int32_t);
1665
    size += keyLen;
1666

1667
    size_t valueLen = 0;
1668
    valueLen = strlen(stb) + 1;
1669
    size += sizeof(int32_t);
1670
    size += valueLen;
1671
    stb = taosHashIterate(pUser->writeViews, stb);
1672
  }
1673

1674
  stb = taosHashIterate(pUser->alterViews, NULL);
1675
  while (stb != NULL) {
1676
    size_t keyLen = 0;
1677
    void  *key = taosHashGetKey(stb, &keyLen);
1678
    size += sizeof(int32_t);
1679
    size += keyLen;
1680

1681
    size_t valueLen = 0;
1682
    valueLen = strlen(stb) + 1;
1683
    size += sizeof(int32_t);
1684
    size += valueLen;
1685
    stb = taosHashIterate(pUser->alterViews, stb);
1686
  }
1687

1688
  int32_t *useDb = taosHashIterate(pUser->useDbs, NULL);
1689
  while (useDb != NULL) {
1690
    size_t keyLen = 0;
1691
    void  *key = taosHashGetKey(useDb, &keyLen);
1692
    size += sizeof(int32_t);
1693
    size += keyLen;
1694
    size += sizeof(int32_t);
1695
    useDb = taosHashIterate(pUser->useDbs, useDb);
1696
  }
1697
#endif
1698
  int32_t sizeExt = tSerializeUserObjExt(NULL, 0, pUser);
4,224,735✔
1699
  if (sizeExt < 0) {
4,224,735✔
1700
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1701
  }
1702
  size += sizeExt;
4,224,735✔
1703

1704
  pRaw = sdbAllocRaw(SDB_USER, USER_VER_NUMBER, size);
4,224,735✔
1705
  if (pRaw == NULL) {
4,224,735✔
1706
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1707
  }
1708

1709
  int32_t dataPos = 0;
4,224,735✔
1710
  SDB_SET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN, _OVER)
4,224,735✔
1711

1712
  dropOldPasswords(pUser);
4,224,735✔
1713
  SDB_SET_INT32(pRaw, dataPos, pUser->numOfPasswords, _OVER)
4,224,735✔
1714
  for (int32_t i = 0; i < pUser->numOfPasswords; i++) {
9,243,198✔
1715
    SDB_SET_BINARY(pRaw, dataPos, pUser->passwords[i].pass, sizeof(pUser->passwords[i].pass), _OVER)
5,018,463✔
1716
    SDB_SET_INT32(pRaw, dataPos, pUser->passwords[i].setTime, _OVER)
5,018,463✔
1717
  }
1718
  SDB_SET_BINARY(pRaw, dataPos, pUser->salt, sizeof(pUser->salt), _OVER)
4,224,735✔
1719

1720
  SDB_SET_BINARY(pRaw, dataPos, pUser->acct, TSDB_USER_LEN, _OVER)
4,224,735✔
1721
  SDB_SET_INT64(pRaw, dataPos, pUser->createdTime, _OVER)
4,224,735✔
1722
  SDB_SET_INT64(pRaw, dataPos, pUser->updateTime, _OVER)
4,224,735✔
1723
  SDB_SET_INT8(pRaw, dataPos, pUser->superUser, _OVER)
4,224,735✔
1724
  SDB_SET_INT8(pRaw, dataPos, pUser->sysInfo, _OVER)
4,224,735✔
1725
  SDB_SET_INT8(pRaw, dataPos, pUser->enable, _OVER)
4,224,735✔
1726
  SDB_SET_UINT8(pRaw, dataPos, pUser->flag, _OVER)
4,224,735✔
1727
  SDB_SET_INT32(pRaw, dataPos, pUser->authVersion, _OVER)
4,224,735✔
1728
  SDB_SET_INT32(pRaw, dataPos, pUser->passVersion, _OVER)
4,224,735✔
1729
  SDB_SET_INT32(pRaw, dataPos, numOfReadDbs, _OVER)
4,224,735✔
1730
  SDB_SET_INT32(pRaw, dataPos, numOfWriteDbs, _OVER)
4,224,735✔
1731
  SDB_SET_INT32(pRaw, dataPos, numOfTopics, _OVER)
4,224,735✔
1732
#if 0
1733
  char *db = taosHashIterate(pUser->readDbs, NULL);
1734
  while (db != NULL) {
1735
    SDB_SET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER);
1736
    db = taosHashIterate(pUser->readDbs, db);
1737
  }
1738

1739
  db = taosHashIterate(pUser->writeDbs, NULL);
1740
  while (db != NULL) {
1741
    SDB_SET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER);
1742
    db = taosHashIterate(pUser->writeDbs, db);
1743
  }
1744
  char *topic = taosHashIterate(pUser->topics, NULL);
1745
  while (topic != NULL) {
1746
    SDB_SET_BINARY(pRaw, dataPos, topic, TSDB_TOPIC_FNAME_LEN, _OVER);
1747
    topic = taosHashIterate(pUser->topics, topic);
1748
  }
1749
#endif
1750
  SDB_SET_INT32(pRaw, dataPos, numOfReadTbs, _OVER)
4,224,735✔
1751
  SDB_SET_INT32(pRaw, dataPos, numOfWriteTbs, _OVER)
4,224,735✔
1752
  SDB_SET_INT32(pRaw, dataPos, numOfAlterTbs, _OVER)
4,224,735✔
1753
  SDB_SET_INT32(pRaw, dataPos, numOfReadViews, _OVER)
4,224,735✔
1754
  SDB_SET_INT32(pRaw, dataPos, numOfWriteViews, _OVER)
4,224,735✔
1755
  SDB_SET_INT32(pRaw, dataPos, numOfAlterViews, _OVER)
4,224,735✔
1756
  SDB_SET_INT32(pRaw, dataPos, numOfUseDbs, _OVER)
4,224,735✔
1757

1758
#if 0
1759
  stb = taosHashIterate(pUser->readTbs, NULL);
1760
  while (stb != NULL) {
1761
    size_t keyLen = 0;
1762
    void  *key = taosHashGetKey(stb, &keyLen);
1763
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1764
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1765

1766
    size_t valueLen = 0;
1767
    valueLen = strlen(stb) + 1;
1768
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
1769
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
1770
    stb = taosHashIterate(pUser->readTbs, stb);
1771
  }
1772

1773
  stb = taosHashIterate(pUser->writeTbs, NULL);
1774
  while (stb != NULL) {
1775
    size_t keyLen = 0;
1776
    void  *key = taosHashGetKey(stb, &keyLen);
1777
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1778
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1779

1780
    size_t valueLen = 0;
1781
    valueLen = strlen(stb) + 1;
1782
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
1783
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
1784
    stb = taosHashIterate(pUser->writeTbs, stb);
1785
  }
1786
  stb = taosHashIterate(pUser->alterTbs, NULL);
1787
  while (stb != NULL) {
1788
    size_t keyLen = 0;
1789
    void  *key = taosHashGetKey(stb, &keyLen);
1790
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1791
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1792

1793
    size_t valueLen = 0;
1794
    valueLen = strlen(stb) + 1;
1795
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
1796
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
1797
    stb = taosHashIterate(pUser->alterTbs, stb);
1798
  }
1799

1800
  stb = taosHashIterate(pUser->readViews, NULL);
1801
  while (stb != NULL) {
1802
    size_t keyLen = 0;
1803
    void  *key = taosHashGetKey(stb, &keyLen);
1804
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1805
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1806

1807
    size_t valueLen = 0;
1808
    valueLen = strlen(stb) + 1;
1809
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
1810
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
1811
    stb = taosHashIterate(pUser->readViews, stb);
1812
  }
1813

1814
  stb = taosHashIterate(pUser->writeViews, NULL);
1815
  while (stb != NULL) {
1816
    size_t keyLen = 0;
1817
    void  *key = taosHashGetKey(stb, &keyLen);
1818
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1819
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1820

1821
    size_t valueLen = 0;
1822
    valueLen = strlen(stb) + 1;
1823
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
1824
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
1825
    stb = taosHashIterate(pUser->writeViews, stb);
1826
  }
1827

1828
  stb = taosHashIterate(pUser->alterViews, NULL);
1829
  while (stb != NULL) {
1830
    size_t keyLen = 0;
1831
    void  *key = taosHashGetKey(stb, &keyLen);
1832
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1833
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1834

1835
    size_t valueLen = 0;
1836
    valueLen = strlen(stb) + 1;
1837
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
1838
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
1839
    stb = taosHashIterate(pUser->alterViews, stb);
1840
  }
1841

1842
  useDb = taosHashIterate(pUser->useDbs, NULL);
1843
  while (useDb != NULL) {
1844
    size_t keyLen = 0;
1845
    void  *key = taosHashGetKey(useDb, &keyLen);
1846
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1847
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1848

1849
    SDB_SET_INT32(pRaw, dataPos, *useDb, _OVER)
1850
    useDb = taosHashIterate(pUser->useDbs, useDb);
1851
  }
1852
#endif
1853
  // save white list
1854
  int32_t num = pUser->pIpWhiteListDual->num;
4,224,735✔
1855
  int32_t tlen = sizeof(SIpWhiteListDual) + num * sizeof(SIpRange) + 4;
4,224,735✔
1856
  int32_t maxBufLen = TMAX(tlen, sizeExt);
4,224,735✔
1857
  if ((buf = taosMemoryCalloc(1, maxBufLen)) == NULL) {
4,224,735✔
1858
    TAOS_CHECK_GOTO(terrno, NULL, _OVER);
×
1859
  }
1860
  int32_t len = 0;
4,224,735✔
1861
  TAOS_CHECK_GOTO(tSerializeIpWhiteList(buf, tlen, pUser->pIpWhiteListDual, &len), &lino, _OVER);
4,224,735✔
1862

1863
  SDB_SET_INT32(pRaw, dataPos, len, _OVER);
4,224,735✔
1864
  SDB_SET_BINARY(pRaw, dataPos, buf, len, _OVER);
4,224,735✔
1865

1866
  SDB_SET_INT64(pRaw, dataPos, pUser->ipWhiteListVer, _OVER);
4,224,735✔
1867
  SDB_SET_INT8(pRaw, dataPos, pUser->passEncryptAlgorithm, _OVER);
4,224,735✔
1868

1869
  SDB_SET_BINARY(pRaw, dataPos, pUser->totpsecret, sizeof(pUser->totpsecret), _OVER);
4,224,735✔
1870
  SDB_SET_INT8(pRaw, dataPos, pUser->changePass, _OVER);
4,224,735✔
1871
  SDB_SET_INT32(pRaw, dataPos, pUser->sessionPerUser, _OVER);
4,224,735✔
1872
  SDB_SET_INT32(pRaw, dataPos, pUser->connectTime, _OVER);
4,224,735✔
1873
  SDB_SET_INT32(pRaw, dataPos, pUser->connectIdleTime, _OVER);
4,224,735✔
1874
  SDB_SET_INT32(pRaw, dataPos, pUser->callPerSession, _OVER);
4,224,735✔
1875
  SDB_SET_INT32(pRaw, dataPos, pUser->vnodePerCall, _OVER);
4,224,735✔
1876
  SDB_SET_INT32(pRaw, dataPos, pUser->failedLoginAttempts, _OVER);
4,224,735✔
1877
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordLifeTime, _OVER);
4,224,735✔
1878
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordReuseTime, _OVER);
4,224,735✔
1879
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordReuseMax, _OVER);
4,224,735✔
1880
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordLockTime, _OVER);
4,224,735✔
1881
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordGraceTime, _OVER);
4,224,735✔
1882
  SDB_SET_INT32(pRaw, dataPos, pUser->inactiveAccountTime, _OVER);
4,224,735✔
1883
  SDB_SET_INT32(pRaw, dataPos, pUser->allowTokenNum, _OVER);
4,224,735✔
1884
  SDB_SET_INT32(pRaw, dataPos, pUser->tokenNum, _OVER);
4,224,735✔
1885

1886
  SDB_SET_INT32(pRaw, dataPos, pUser->pTimeWhiteList->num, _OVER);
4,224,735✔
1887
  for (int32_t i = 0; i < pUser->pTimeWhiteList->num; i++) {
4,231,935✔
1888
    SDateTimeWhiteListItem *range = &pUser->pTimeWhiteList->ranges[i];
7,200✔
1889
    SDB_SET_BOOL(pRaw, dataPos, range->absolute, _OVER);
7,200✔
1890
    SDB_SET_BOOL(pRaw, dataPos, range->neg, _OVER);
7,200✔
1891
    SDB_SET_INT64(pRaw, dataPos, range->start, _OVER);
7,200✔
1892
    SDB_SET_INT32(pRaw, dataPos, range->duration, _OVER);
7,200✔
1893
  }
1894

1895
  sizeExt = tSerializeUserObjExt(buf, sizeExt, pUser);
4,224,735✔
1896
  if (sizeExt < 0) {
4,224,735✔
1897
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1898
  }
1899
  SDB_SET_INT32(pRaw, dataPos, sizeExt, _OVER);
4,224,735✔
1900
  SDB_SET_BINARY(pRaw, dataPos, buf, sizeExt, _OVER);
4,224,735✔
1901

1902
  SDB_SET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
4,224,735✔
1903

1904
  SDB_SET_DATALEN(pRaw, dataPos, _OVER)
4,224,735✔
1905

1906
_OVER:
4,224,735✔
1907
  taosMemoryFree(buf);
4,224,735✔
1908
  if (code < 0) {
4,224,735✔
1909
    mError("user:%s, failed to encode user action to raw:%p at line %d since %s", pUser->user, pRaw, lino,
×
1910
           tstrerror(code));
1911
    sdbFreeRaw(pRaw);
×
1912
    pRaw = NULL;
×
1913
    terrno = code;
×
1914
  }
1915

1916
  mTrace("user:%s, encode user action to raw:%p, row:%p", pUser->user, pRaw, pUser);
4,224,735✔
1917
  return pRaw;
4,224,735✔
1918
}
1919

1920
static SSdbRow *mndUserActionDecode(SSdbRaw *pRaw) {
3,385,135✔
1921
  int32_t   code = 0;
3,385,135✔
1922
  int32_t   lino = 0;
3,385,135✔
1923
  SSdbRow  *pRow = NULL;
3,385,135✔
1924
  SUserObj *pUser = NULL;
3,385,135✔
1925
  char     *key = NULL;
3,385,135✔
1926
  char     *value = NULL;
3,385,135✔
1927

1928
  int8_t sver = 0;
3,385,135✔
1929
  if (sdbGetRawSoftVer(pRaw, &sver) != 0) {
3,385,135✔
1930
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_PTR, &lino, _OVER);
×
1931
  }
1932

1933
  if (sver < 1 || sver > USER_VER_NUMBER) {
3,385,135✔
1934
    TAOS_CHECK_GOTO(TSDB_CODE_SDB_INVALID_DATA_VER, &lino, _OVER);
×
1935
  }
1936

1937
  pRow = sdbAllocRow(sizeof(SUserObj));
3,385,135✔
1938
  if (pRow == NULL) {
3,385,135✔
1939
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1940
  }
1941

1942
  pUser = sdbGetRowObj(pRow);
3,385,135✔
1943
  if (pUser == NULL) {
3,385,135✔
1944
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1945
  }
1946

1947
  if (sver < USER_VER_SUPPORT_ADVANCED_SECURITY) {
3,385,135✔
1948
    upgradeSecurity = 1;
×
1949
    pUser->legacyPrivs = taosMemCalloc(1, sizeof(SPrivHashObjSet));
×
1950
    if (pUser->legacyPrivs == NULL) {
×
1951
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
1952
    }
1953
  }
1954

1955
  int32_t dataPos = 0;
3,385,135✔
1956
  SDB_GET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN, _OVER)
3,385,135✔
1957

1958
  if (sver < USER_VER_SUPPORT_ADVANCED_SECURITY) {
3,385,135✔
1959
    pUser->passwords = taosMemoryCalloc(1, sizeof(SUserPassword));
×
1960
    if (pUser->passwords == NULL) {
×
1961
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
1962
    }
1963
    SDB_GET_BINARY(pRaw, dataPos, pUser->passwords[0].pass, TSDB_PASSWORD_LEN, _OVER)
×
1964
    pUser->numOfPasswords = 1;
×
1965
    memset(pUser->salt, 0, sizeof(pUser->salt));
×
1966
  } else {
1967
    SDB_GET_INT32(pRaw, dataPos, &pUser->numOfPasswords, _OVER)
3,385,135✔
1968
    pUser->passwords = taosMemoryCalloc(pUser->numOfPasswords, sizeof(SUserPassword));
3,385,135✔
1969
    if (pUser->passwords == NULL) {
3,385,135✔
1970
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
1971
    }
1972
    for (int32_t i = 0; i < pUser->numOfPasswords; ++i) {
7,512,590✔
1973
      SDB_GET_BINARY(pRaw, dataPos, pUser->passwords[i].pass, sizeof(pUser->passwords[i].pass), _OVER);
4,127,455✔
1974
      SDB_GET_INT32(pRaw, dataPos, &pUser->passwords[i].setTime, _OVER);
4,127,455✔
1975
    }
1976
    SDB_GET_BINARY(pRaw, dataPos, pUser->salt, sizeof(pUser->salt), _OVER)
3,385,135✔
1977
  }
1978

1979
  SDB_GET_BINARY(pRaw, dataPos, pUser->acct, TSDB_USER_LEN, _OVER)
3,385,135✔
1980
  SDB_GET_INT64(pRaw, dataPos, &pUser->createdTime, _OVER)
3,385,135✔
1981
  SDB_GET_INT64(pRaw, dataPos, &pUser->updateTime, _OVER)
3,385,135✔
1982
  if (sver < USER_VER_SUPPORT_ADVANCED_SECURITY) {
3,385,135✔
1983
    pUser->passwords[0].setTime = (int32_t)(pUser->updateTime / 1000);
×
1984
  }
1985

1986
  SDB_GET_INT8(pRaw, dataPos, &pUser->superUser, _OVER)
3,385,135✔
1987
  SDB_GET_INT8(pRaw, dataPos, &pUser->sysInfo, _OVER)
3,385,135✔
1988
  SDB_GET_INT8(pRaw, dataPos, &pUser->enable, _OVER)
3,385,135✔
1989
  SDB_GET_UINT8(pRaw, dataPos, &pUser->flag, _OVER)
3,385,135✔
1990
  if (pUser->superUser) pUser->createdb = 1;
3,385,135✔
1991
  SDB_GET_INT32(pRaw, dataPos, &pUser->authVersion, _OVER)
3,385,135✔
1992
  if (sver >= 4) {
3,385,135✔
1993
    SDB_GET_INT32(pRaw, dataPos, &pUser->passVersion, _OVER)
3,385,135✔
1994
  }
1995

1996
  int32_t numOfReadDbs = 0;
3,385,135✔
1997
  int32_t numOfWriteDbs = 0;
3,385,135✔
1998
  int32_t numOfTopics = 0;
3,385,135✔
1999
  SDB_GET_INT32(pRaw, dataPos, &numOfReadDbs, _OVER)
3,385,135✔
2000
  SDB_GET_INT32(pRaw, dataPos, &numOfWriteDbs, _OVER)
3,385,135✔
2001
  if (sver >= 2) {
3,385,135✔
2002
    SDB_GET_INT32(pRaw, dataPos, &numOfTopics, _OVER)
3,385,135✔
2003
  }
2004

2005
  if (numOfReadDbs > 0) {
3,385,135✔
2006
    pUser->legacyPrivs->pReadDbs =
×
2007
        taosHashInit(numOfReadDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
2008
    if (pUser->legacyPrivs->pReadDbs == NULL) {
×
2009
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2010
    }
2011
  }
2012
  if (numOfWriteDbs > 0) {
3,385,135✔
2013
    pUser->legacyPrivs->pWriteDbs =
×
2014
        taosHashInit(numOfWriteDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
2015
    if (pUser->legacyPrivs->pWriteDbs == NULL) {
×
2016
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2017
    }
2018
  }
2019
  if (numOfTopics > 0) {
3,385,135✔
2020
    pUser->legacyPrivs->pTopics =
×
2021
        taosHashInit(numOfTopics, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
2022
    if (pUser->legacyPrivs->pTopics == NULL) {
×
2023
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2024
    }
2025
  }
2026
  for (int32_t i = 0; i < numOfReadDbs; ++i) {
3,385,135✔
2027
    char db[TSDB_DB_FNAME_LEN] = {0};
×
2028
    SDB_GET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER)
×
2029
    int32_t len = strlen(db) + 1;
×
2030
    TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pReadDbs, db, len, db, TSDB_DB_FNAME_LEN), &lino, _OVER);
×
2031
  }
2032

2033
  for (int32_t i = 0; i < numOfWriteDbs; ++i) {
3,385,135✔
2034
    char db[TSDB_DB_FNAME_LEN] = {0};
×
2035
    SDB_GET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER)
×
2036
    int32_t len = strlen(db) + 1;
×
2037
    TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pWriteDbs, db, len, db, TSDB_DB_FNAME_LEN), &lino, _OVER);
×
2038
  }
2039

2040
  if (sver >= 2) {
3,385,135✔
2041
    for (int32_t i = 0; i < numOfTopics; ++i) {
3,385,135✔
2042
      char topic[TSDB_TOPIC_FNAME_LEN] = {0};
×
2043
      SDB_GET_BINARY(pRaw, dataPos, topic, TSDB_TOPIC_FNAME_LEN, _OVER)
×
2044
      int32_t len = strlen(topic) + 1;
×
2045
      TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pTopics, topic, len, topic, TSDB_TOPIC_FNAME_LEN), &lino, _OVER);
×
2046
    }
2047
  }
2048

2049
  if (sver >= 3) {
3,385,135✔
2050
    int32_t numOfReadTbs = 0;
3,385,135✔
2051
    int32_t numOfWriteTbs = 0;
3,385,135✔
2052
    int32_t numOfAlterTbs = 0;
3,385,135✔
2053
    int32_t numOfReadViews = 0;
3,385,135✔
2054
    int32_t numOfWriteViews = 0;
3,385,135✔
2055
    int32_t numOfAlterViews = 0;
3,385,135✔
2056
    int32_t numOfUseDbs = 0;
3,385,135✔
2057
    SDB_GET_INT32(pRaw, dataPos, &numOfReadTbs, _OVER)
3,385,135✔
2058
    SDB_GET_INT32(pRaw, dataPos, &numOfWriteTbs, _OVER)
3,385,135✔
2059
    if (sver >= 6) {
3,385,135✔
2060
      SDB_GET_INT32(pRaw, dataPos, &numOfAlterTbs, _OVER)
3,385,135✔
2061
      SDB_GET_INT32(pRaw, dataPos, &numOfReadViews, _OVER)
3,385,135✔
2062
      SDB_GET_INT32(pRaw, dataPos, &numOfWriteViews, _OVER)
3,385,135✔
2063
      SDB_GET_INT32(pRaw, dataPos, &numOfAlterViews, _OVER)
3,385,135✔
2064
    }
2065
    SDB_GET_INT32(pRaw, dataPos, &numOfUseDbs, _OVER)
3,385,135✔
2066

2067
    if (numOfReadTbs > 0) {
3,385,135✔
2068
      pUser->legacyPrivs->pReadTbs =
×
2069
          taosHashInit(numOfReadTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
2070
      if (pUser->legacyPrivs->pReadTbs == NULL) {
×
2071
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2072
      }
2073
    }
2074
    if (numOfWriteTbs > 0) {
3,385,135✔
2075
      pUser->legacyPrivs->pWriteTbs =
×
2076
          taosHashInit(numOfWriteTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
2077
      if (pUser->legacyPrivs->pWriteTbs == NULL) {
×
2078
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2079
      }
2080
    }
2081
    if (numOfAlterTbs > 0) {
3,385,135✔
2082
      pUser->legacyPrivs->pAlterTbs =
×
2083
          taosHashInit(numOfAlterTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
2084
      if (pUser->legacyPrivs->pAlterTbs == NULL) {
×
2085
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2086
      }
2087
    }
2088
    if (numOfReadViews > 0) {
3,385,135✔
2089
      pUser->legacyPrivs->pReadViews =
×
2090
          taosHashInit(numOfReadViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
2091
      if (pUser->legacyPrivs->pReadViews == NULL) {
×
2092
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2093
      }
2094
    }
2095
    if (numOfWriteViews > 0) {
3,385,135✔
2096
      pUser->legacyPrivs->pWriteViews =
×
2097
          taosHashInit(numOfWriteViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
2098
      if (pUser->legacyPrivs->pWriteViews == NULL) {
×
2099
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2100
      }
2101
    }
2102
    if (numOfAlterViews > 0) {
3,385,135✔
2103
      pUser->legacyPrivs->pAlterViews =
×
2104
          taosHashInit(numOfAlterViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
2105
      if (pUser->legacyPrivs->pAlterViews == NULL) {
×
2106
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2107
      }
2108
    }
2109
    if (numOfUseDbs > 0) {
3,385,135✔
2110
      pUser->legacyPrivs->pUseDbs =
×
2111
          taosHashInit(numOfUseDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
2112
      if (pUser->legacyPrivs->pUseDbs == NULL) {
×
2113
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2114
      }
2115
    }
2116

2117
    for (int32_t i = 0; i < numOfReadTbs; ++i) {
3,385,135✔
2118
      int32_t keyLen = 0;
×
2119
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
2120

2121
      TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
2122
      if (key == NULL) {
×
2123
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2124
      }
2125
      (void)memset(key, 0, keyLen);
×
2126
      SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
2127

2128
      int32_t valuelen = 0;
×
2129
      SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
2130
      TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
2131
      if (value == NULL) {
×
2132
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2133
      }
2134
      (void)memset(value, 0, valuelen);
×
2135
      SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
2136

2137
      TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pReadTbs, key, keyLen, value, valuelen), &lino, _OVER);
×
2138
    }
2139

2140
    for (int32_t i = 0; i < numOfWriteTbs; ++i) {
3,385,135✔
2141
      int32_t keyLen = 0;
×
2142
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
2143

2144
      TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
2145
      if (key == NULL) {
×
2146
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2147
      }
2148
      (void)memset(key, 0, keyLen);
×
2149
      SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
2150

2151
      int32_t valuelen = 0;
×
2152
      SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
2153
      TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
2154
      if (value == NULL) {
×
2155
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2156
      }
2157
      (void)memset(value, 0, valuelen);
×
2158
      SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
2159

2160
      TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pWriteTbs, key, keyLen, value, valuelen), &lino, _OVER);
×
2161
    }
2162

2163
    if (sver >= 6) {
3,385,135✔
2164
      for (int32_t i = 0; i < numOfAlterTbs; ++i) {
3,385,135✔
2165
        int32_t keyLen = 0;
×
2166
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
2167

2168
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
2169
        if (key == NULL) {
×
2170
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2171
        }
2172
        (void)memset(key, 0, keyLen);
×
2173
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
2174

2175
        int32_t valuelen = 0;
×
2176
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
2177
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
2178
        if (value == NULL) {
×
2179
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2180
        }
2181
        (void)memset(value, 0, valuelen);
×
2182
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
2183

2184
        TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pAlterTbs, key, keyLen, value, valuelen), &lino, _OVER);
×
2185
      }
2186

2187
      for (int32_t i = 0; i < numOfReadViews; ++i) {
3,385,135✔
2188
        int32_t keyLen = 0;
×
2189
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
2190

2191
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
2192
        if (key == NULL) {
×
2193
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2194
        }
2195
        (void)memset(key, 0, keyLen);
×
2196
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
2197

2198
        int32_t valuelen = 0;
×
2199
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
2200
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
2201
        if (value == NULL) {
×
2202
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2203
        }
2204
        (void)memset(value, 0, valuelen);
×
2205
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
2206

2207
        TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pReadViews, key, keyLen, value, valuelen), &lino, _OVER);
×
2208
      }
2209

2210
      for (int32_t i = 0; i < numOfWriteViews; ++i) {
3,385,135✔
2211
        int32_t keyLen = 0;
×
2212
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
2213

2214
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
2215
        if (key == NULL) {
×
2216
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2217
        }
2218
        (void)memset(key, 0, keyLen);
×
2219
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
2220

2221
        int32_t valuelen = 0;
×
2222
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
2223
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
2224
        if (value == NULL) {
×
2225
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2226
        }
2227
        (void)memset(value, 0, valuelen);
×
2228
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
2229

2230
        TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pWriteViews, key, keyLen, value, valuelen), &lino, _OVER);
×
2231
      }
2232

2233
      for (int32_t i = 0; i < numOfAlterViews; ++i) {
3,385,135✔
2234
        int32_t keyLen = 0;
×
2235
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
2236

2237
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
2238
        if (key == NULL) {
×
2239
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2240
        }
2241
        (void)memset(key, 0, keyLen);
×
2242
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
2243

2244
        int32_t valuelen = 0;
×
2245
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
2246
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
2247
        if (value == NULL) {
×
2248
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2249
        }
2250
        (void)memset(value, 0, valuelen);
×
2251
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
2252

2253
        TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pAlterViews, key, keyLen, value, valuelen), &lino, _OVER);
×
2254
      }
2255
    }
2256

2257
    for (int32_t i = 0; i < numOfUseDbs; ++i) {
3,385,135✔
2258
      int32_t keyLen = 0;
×
2259
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
2260

2261
      TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
2262
      if (key == NULL) {
×
2263
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2264
      }
2265
      (void)memset(key, 0, keyLen);
×
2266
      SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
2267

2268
      int32_t ref = 0;
×
2269
      SDB_GET_INT32(pRaw, dataPos, &ref, _OVER);
×
2270

2271
      TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pUseDbs, key, keyLen, &ref, sizeof(ref)), &lino, _OVER);
×
2272
    }
2273
  }
2274
  // decoder white list
2275
  if (sver >= USER_VER_SUPPORT_WHITELIST) {
3,385,135✔
2276
    if (sver < USER_VER_SUPPORT_WHITELIT_DUAL_STACK) {
3,385,135✔
2277
      int32_t len = 0;
×
2278
      SDB_GET_INT32(pRaw, dataPos, &len, _OVER);
×
2279

2280
      TAOS_MEMORY_REALLOC(key, len);
×
2281
      if (key == NULL) {
×
2282
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2283
      }
2284
      SDB_GET_BINARY(pRaw, dataPos, key, len, _OVER);
×
2285

2286
      SIpWhiteList *pIpWhiteList = NULL;
×
2287
      TAOS_CHECK_GOTO(createIpWhiteListFromOldVer(key, len, &pIpWhiteList), &lino, _OVER);
×
2288

2289
      SDB_GET_INT64(pRaw, dataPos, &pUser->ipWhiteListVer, _OVER);
×
2290

2291
      code = cvtIpWhiteListToDual(pIpWhiteList, &pUser->pIpWhiteListDual);
×
2292
      if (code != 0) {
×
2293
        taosMemoryFreeClear(pIpWhiteList);
×
2294
      }
2295
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2296

2297
      taosMemoryFreeClear(pIpWhiteList);
×
2298

2299
    } else if (sver >= USER_VER_SUPPORT_WHITELIT_DUAL_STACK) {
3,385,135✔
2300
      int32_t len = 0;
3,385,135✔
2301
      SDB_GET_INT32(pRaw, dataPos, &len, _OVER);
3,385,135✔
2302

2303
      TAOS_MEMORY_REALLOC(key, len);
3,385,135✔
2304
      if (key == NULL) {
3,385,135✔
2305
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2306
      }
2307
      SDB_GET_BINARY(pRaw, dataPos, key, len, _OVER);
3,385,135✔
2308

2309
      TAOS_CHECK_GOTO(createIpWhiteList(key, len, &pUser->pIpWhiteListDual, sver >= USER_VER_SUPPORT_ADVANCED_SECURITY),
3,385,135✔
2310
                      &lino, _OVER);
2311
      SDB_GET_INT64(pRaw, dataPos, &pUser->ipWhiteListVer, _OVER);
3,385,135✔
2312
    }
2313
  }
2314

2315
  if (pUser->pIpWhiteListDual == NULL) {
3,385,135✔
2316
    TAOS_CHECK_GOTO(createDefaultIpWhiteList(&pUser->pIpWhiteListDual), &lino, _OVER);
×
2317
    pUser->ipWhiteListVer = taosGetTimestampMs();
×
2318
  }
2319

2320
  SDB_GET_INT8(pRaw, dataPos, &pUser->passEncryptAlgorithm, _OVER);
3,385,135✔
2321

2322
  if (sver < USER_VER_SUPPORT_ADVANCED_SECURITY) {
3,385,135✔
2323
    memset(pUser->totpsecret, 0, sizeof(pUser->totpsecret));
×
2324
    pUser->changePass = 2;
×
2325

2326
    if (tsEnableAdvancedSecurity) {
×
2327
      pUser->sessionPerUser = pUser->superUser ? -1 : TSDB_USER_SESSION_PER_USER_DEFAULT;
×
2328
      pUser->connectTime = TSDB_USER_CONNECT_TIME_DEFAULT;
×
2329
      pUser->connectIdleTime = TSDB_USER_CONNECT_IDLE_TIME_DEFAULT;
×
2330
      pUser->callPerSession = pUser->superUser ? -1 : TSDB_USER_CALL_PER_SESSION_DEFAULT;
×
2331
      pUser->vnodePerCall = pUser->superUser ? -1 : TSDB_USER_VNODE_PER_CALL_DEFAULT;
×
2332
      pUser->failedLoginAttempts = pUser->superUser ? -1 : TSDB_USER_FAILED_LOGIN_ATTEMPTS_DEFAULT;
×
2333
      pUser->passwordLifeTime = TSDB_USER_PASSWORD_LIFE_TIME_DEFAULT;
×
2334
      pUser->passwordReuseTime = TSDB_USER_PASSWORD_REUSE_TIME_DEFAULT;
×
2335
      pUser->passwordReuseMax = TSDB_USER_PASSWORD_REUSE_MAX_DEFAULT;
×
2336
      pUser->passwordLockTime = pUser->superUser ? 1 : TSDB_USER_PASSWORD_LOCK_TIME_DEFAULT;
×
2337
      pUser->passwordGraceTime = pUser->superUser ? -1 : TSDB_USER_PASSWORD_GRACE_TIME_DEFAULT;
×
2338
      pUser->inactiveAccountTime = pUser->superUser ? -1 : TSDB_USER_INACTIVE_ACCOUNT_TIME_DEFAULT;
×
2339
    } else {
2340
      pUser->sessionPerUser = -1;
×
2341
      pUser->connectTime = -1;
×
2342
      pUser->connectIdleTime = -1;
×
2343
      pUser->callPerSession = -1;
×
2344
      pUser->vnodePerCall = -1;
×
2345
      pUser->failedLoginAttempts = -1;
×
2346
      pUser->passwordLifeTime = -1;
×
2347
      pUser->passwordReuseTime = 0;
×
2348
      pUser->passwordReuseMax = 0;
×
2349
      pUser->passwordLockTime = 1;
×
2350
      pUser->passwordGraceTime = -1;
×
2351
      pUser->inactiveAccountTime =-1;
×
2352
    }
2353

2354
    pUser->allowTokenNum = TSDB_USER_ALLOW_TOKEN_NUM_DEFAULT;
×
2355
    pUser->tokenNum = 0;
×
2356
    pUser->pTimeWhiteList = taosMemCalloc(1, sizeof(SDateTimeWhiteList));
×
2357
    if (pUser->pTimeWhiteList == NULL) {
×
2358
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2359
    }
2360
  } else {
2361
    SDB_GET_BINARY(pRaw, dataPos, pUser->totpsecret, sizeof(pUser->totpsecret), _OVER);
3,385,135✔
2362
    SDB_GET_INT8(pRaw, dataPos, &pUser->changePass, _OVER);
3,385,135✔
2363
    SDB_GET_INT32(pRaw, dataPos, &pUser->sessionPerUser, _OVER);
3,385,135✔
2364
    SDB_GET_INT32(pRaw, dataPos, &pUser->connectTime, _OVER);
3,385,135✔
2365
    SDB_GET_INT32(pRaw, dataPos, &pUser->connectIdleTime, _OVER);
3,385,135✔
2366
    SDB_GET_INT32(pRaw, dataPos, &pUser->callPerSession, _OVER);
3,385,135✔
2367
    SDB_GET_INT32(pRaw, dataPos, &pUser->vnodePerCall, _OVER);
3,385,135✔
2368
    SDB_GET_INT32(pRaw, dataPos, &pUser->failedLoginAttempts, _OVER);
3,385,135✔
2369
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordLifeTime, _OVER);
3,385,135✔
2370
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordReuseTime, _OVER);
3,385,135✔
2371
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordReuseMax, _OVER);
3,385,135✔
2372
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordLockTime, _OVER);
3,385,135✔
2373
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordGraceTime, _OVER);
3,385,135✔
2374
    SDB_GET_INT32(pRaw, dataPos, &pUser->inactiveAccountTime, _OVER);
3,385,135✔
2375
    SDB_GET_INT32(pRaw, dataPos, &pUser->allowTokenNum, _OVER);
3,385,135✔
2376
    SDB_GET_INT32(pRaw, dataPos, &pUser->tokenNum, _OVER);
3,385,135✔
2377

2378
    int32_t num = 0;
3,385,135✔
2379
    SDB_GET_INT32(pRaw, dataPos, &num, _OVER);
3,385,135✔
2380
    pUser->pTimeWhiteList = taosMemCalloc(1, sizeof(SDateTimeWhiteList) + num * sizeof(SDateTimeWhiteListItem));
3,385,135✔
2381
    if (pUser->pTimeWhiteList == NULL) {
3,385,135✔
2382
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2383
    }
2384

2385
    pUser->pTimeWhiteList->num = num;
3,385,135✔
2386
    for (int32_t i = 0; i < num; i++) {
3,388,303✔
2387
      SDateTimeWhiteListItem *range = &pUser->pTimeWhiteList->ranges[i];
3,168✔
2388
      SDB_GET_BOOL(pRaw, dataPos, &range->absolute, _OVER);
3,168✔
2389
      SDB_GET_BOOL(pRaw, dataPos, &range->neg, _OVER);
3,168✔
2390
      SDB_GET_INT64(pRaw, dataPos, &range->start, _OVER);
3,168✔
2391
      SDB_GET_INT32(pRaw, dataPos, &range->duration, _OVER);
3,168✔
2392
    }
2393

2394
    int32_t extLen = 0;
3,385,135✔
2395
    SDB_GET_INT32(pRaw, dataPos, &extLen, _OVER);
3,385,135✔
2396
    TAOS_MEMORY_REALLOC(key, extLen);
3,385,135✔
2397
    if (key == NULL) {
3,385,135✔
2398
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2399
    }
2400
    SDB_GET_BINARY(pRaw, dataPos, key, extLen, _OVER);
3,385,135✔
2401
    TAOS_CHECK_GOTO(tDeserializeUserObjExt(key, extLen, pUser), &lino, _OVER);
3,385,135✔
2402
    if (pUser->superUser && taosHashGetSize(pUser->roles) == 0) {
3,385,135✔
2403
      upgradeSecurity = 1;
×
2404
    }
2405
  }
2406

2407
#ifndef TD_ENTERPRISE
2408
  // community users cannot modify these fields, and the default values may prevent
2409
  // the user from logging in, so we set them to different values here.
2410
  pUser->sessionPerUser = -1;
2411
  pUser->connectTime = -1;
2412
  pUser->connectIdleTime = -1;
2413
  pUser->callPerSession = -1;
2414
  pUser->vnodePerCall = -1;
2415
  pUser->failedLoginAttempts = -1;
2416
  pUser->passwordLifeTime = -1;
2417
  pUser->passwordReuseTime = 0;
2418
  pUser->passwordReuseMax = 0;
2419
  pUser->passwordLockTime = -1;
2420
  pUser->passwordGraceTime = -1;
2421
  pUser->inactiveAccountTime = -1;
2422
  pUser->allowTokenNum = -1;
2423
  pUser->tokenNum = 0;
2424
#endif  // TD_ENTERPRISE
2425

2426
  SDB_GET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
3,385,135✔
2427

2428
  taosInitRWLatch(&pUser->lock);
3,385,135✔
2429
  dropOldPasswords(pUser);
3,385,135✔
2430
_OVER:
3,385,135✔
2431
  taosMemoryFree(key);
3,385,135✔
2432
  taosMemoryFree(value);
3,385,135✔
2433
  if (code < 0) {
3,385,135✔
2434
    terrno = code;
×
2435
    mError("user:%s, failed to decode at line %d from raw:%p since %s", pUser == NULL ? "null" : pUser->user, lino,
×
2436
           pRaw, tstrerror(code));
2437
    if (pUser != NULL) {
×
2438
      mndUserFreeObj(pUser);
×
2439
    }
2440
    taosMemoryFreeClear(pRow);
×
2441
    return NULL;
×
2442
  }
2443

2444
  mTrace("user:%s, decode from raw:%p, row:%p", pUser->user, pRaw, pUser);
3,385,135✔
2445
  return pRow;
3,385,135✔
2446
}
2447

2448
static int32_t mndUserActionInsert(SSdb *pSdb, SUserObj *pUser) {
551,352✔
2449
  mTrace("user:%s, perform insert action, row:%p", pUser->user, pUser);
551,352✔
2450

2451
  SAcctObj *pAcct = sdbAcquire(pSdb, SDB_ACCT, pUser->acct);
551,352✔
2452
  if (pAcct == NULL) {
551,352✔
2453
    terrno = TSDB_CODE_MND_ACCT_NOT_EXIST;
×
2454
    mError("user:%s, failed to perform insert action since %s", pUser->user, terrstr());
×
2455
    TAOS_RETURN(terrno);
×
2456
  }
2457
  pUser->acctId = pAcct->acctId;
551,352✔
2458
  sdbRelease(pSdb, pAcct);
551,352✔
2459

2460
  return 0;
551,352✔
2461
}
2462

2463
int32_t mndDupTableHash(SHashObj *pOld, SHashObj **ppNew) {
×
2464
  int32_t code = 0;
×
2465
  *ppNew =
×
2466
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
2467
  if (*ppNew == NULL) {
×
2468
    TAOS_RETURN(terrno);
×
2469
  }
2470

2471
  char *tb = taosHashIterate(pOld, NULL);
×
2472
  while (tb != NULL) {
×
2473
    size_t keyLen = 0;
×
2474
    char  *key = taosHashGetKey(tb, &keyLen);
×
2475

2476
    int32_t valueLen = strlen(tb) + 1;
×
2477
    if ((code = taosHashPut(*ppNew, key, keyLen, tb, valueLen)) != 0) {
×
2478
      taosHashCancelIterate(pOld, tb);
×
2479
      taosHashCleanup(*ppNew);
×
2480
      TAOS_RETURN(code);
×
2481
    }
2482
    tb = taosHashIterate(pOld, tb);
×
2483
  }
2484

2485
  TAOS_RETURN(code);
×
2486
}
2487

2488
int32_t mndDupRoleHash(SHashObj *pOld, SHashObj **ppNew) {
2,743,873✔
2489
  if (!(*ppNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true,
2,743,873✔
2490
                              HASH_ENTRY_LOCK))) {
2491
    TAOS_RETURN(terrno);
×
2492
  }
2493

2494
  int32_t  code = 0;
2,743,873✔
2495
  uint8_t *flag = NULL;
2,743,873✔
2496
  while ((flag = taosHashIterate(pOld, flag))) {
8,033,378✔
2497
    size_t keyLen = 0;
5,289,505✔
2498
    char  *key = taosHashGetKey(flag, &keyLen);
5,289,505✔
2499

2500
    if ((code = taosHashPut(*ppNew, key, keyLen, flag, sizeof(*flag))) != 0) {
5,289,505✔
2501
      taosHashCancelIterate(pOld, flag);
×
2502
      taosHashCleanup(*ppNew);
×
2503
      TAOS_RETURN(code);
×
2504
    }
2505
  }
2506

2507
  TAOS_RETURN(code);
2,743,873✔
2508
}
2509

2510
int32_t mndMergePrivObjHash(SHashObj *pOld, SHashObj **ppNew) {
91,789,411✔
2511
  if (!(*ppNew)) return mndDupPrivObjHash(pOld, ppNew);
91,789,411✔
2512

2513
  int32_t           code = 0, lino = 0;
91,789,411✔
2514
  SHashObj         *pNew = *ppNew;
91,789,411✔
2515
  SPrivObjPolicies *policies = NULL;
91,788,269✔
2516
  while ((policies = taosHashIterate(pOld, policies))) {
857,728,966✔
2517
    size_t klen = 0;
765,946,590✔
2518
    char  *key = taosHashGetKey(policies, &klen);
765,946,565✔
2519
    size_t vlen = taosHashGetValueSize(policies);
765,946,079✔
2520

2521
    SPrivObjPolicies *pNewPolicies = taosHashGet(pNew, key, klen);
765,945,028✔
2522
    if (pNewPolicies) {
765,944,491✔
2523
      size_t newVlen = taosHashGetValueSize(pNewPolicies);
486,208,586✔
2524
      if (newVlen > 0 && vlen > 0) {
486,208,624✔
2525
        privAddSet(&pNewPolicies->policy, &policies->policy);
486,208,624✔
2526
      }
2527
      continue;
486,205,444✔
2528
    }
2529

2530
    if ((code = taosHashPut(pNew, key, klen, vlen ? policies : NULL, vlen)) != 0) {
279,735,905✔
UNCOV
2531
      taosHashCancelIterate(pOld, policies);
×
2532
      taosHashCleanup(pNew);
×
2533
      *ppNew = NULL;
×
2534
      TAOS_RETURN(code);
×
2535
    }
2536
  }
2537

2538
  TAOS_RETURN(code);
91,788,976✔
2539
}
2540

2541
/**
2542
 * 1. Prefer to use SPrivTblPolicies from user object(the updateUs of policy in user object is INT64_MAX)
2543
 * 2. If two or more roles have SPrivTblPolicies, the policy with latest update time take effect.
2544
 */
2545
int32_t mndMergePrivTblHash(SHashObj *pOld, SHashObj **ppNew, bool updateWithLatest) {
275,364,087✔
2546
  if (!(*ppNew)) return mndDupPrivTblHash(pOld, ppNew, false);
275,364,087✔
2547

2548
  int32_t           code = 0, lino = 0;
275,364,087✔
2549
  SHashObj         *pNew = *ppNew;
275,364,087✔
2550
  SPrivTblPolicies *policies = NULL;
275,365,475✔
2551
  while ((policies = taosHashIterate(pOld, policies))) {
275,366,140✔
2552
    size_t klen = 0;
665✔
2553
    char  *key = taosHashGetKey(policies, &klen);
665✔
2554
    size_t vlen = taosHashGetValueSize(policies);
665✔
2555

2556
    SPrivTblPolicies *pNewPolicies = taosHashGet(pNew, key, klen);
665✔
2557
    if (pNewPolicies) {
665✔
2558
      size_t newVlen = taosHashGetValueSize(pNewPolicies);
665✔
2559
      if (newVlen > 0 && vlen > 0) {
665✔
2560
        TAOS_CHECK_EXIT(privTblPoliciesMerge(pNewPolicies, policies, updateWithLatest));
665✔
2561
      }
2562
      continue;
665✔
2563
    }
2564

2565
    SPrivTblPolicies tmpPolicies = {0};
×
2566
    if (vlen > 0) {
×
2567
      if ((code = privTblPoliciesMerge(&tmpPolicies, policies, updateWithLatest))) {
×
2568
        privTblPoliciesFree(&tmpPolicies);
2569
        goto _exit;
×
2570
      }
2571
    }
2572
    if ((code = taosHashPut(pNew, key, klen, vlen ? &tmpPolicies : NULL, vlen)) != 0) {
×
2573
      privTblPoliciesFree(&tmpPolicies);
2574
      taosHashCancelIterate(pOld, policies);
×
2575
      taosHashCleanup(pNew);
×
2576
      *ppNew = NULL;
×
2577
      TAOS_RETURN(code);
×
2578
    }
2579
  }
2580

2581
_exit:
275,366,281✔
2582
  TAOS_RETURN(code);
275,366,281✔
2583
}
2584

2585
int32_t mndDupKVHash(SHashObj *pOld, SHashObj **ppNew) {
33,770,616✔
2586
  if (!(*ppNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true,
33,770,616✔
2587
                              HASH_ENTRY_LOCK))) {
2588
    TAOS_RETURN(terrno);
×
2589
  }
2590
  int32_t code = 0;
33,769,760✔
2591
  void   *val = NULL;
33,769,760✔
2592
  while ((val = taosHashIterate(pOld, val))) {
107,932,230✔
2593
    size_t klen = 0;
74,162,470✔
2594
    char  *key = taosHashGetKey(val, &klen);
74,162,470✔
2595
    size_t vlen = taosHashGetValueSize(val);
74,162,470✔
2596
    if ((code = taosHashPut(*ppNew, key, klen, vlen > 0 ? val : NULL, vlen)) != 0) {
74,162,470✔
2597
      taosHashCancelIterate(pOld, val);
×
2598
      taosHashCleanup(*ppNew);
×
2599
      TAOS_RETURN(code);
×
2600
    }
2601
  }
2602

2603
  TAOS_RETURN(code);
33,770,616✔
2604
}
2605

2606
int32_t mndDupPrivObjHash(SHashObj *pOld, SHashObj **ppNew) {
33,772,434✔
2607
  if (!(*ppNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true,
33,772,434✔
2608
                              HASH_ENTRY_LOCK))) {
2609
    TAOS_RETURN(terrno);
×
2610
  }
2611
  int32_t           code = 0;
33,773,992✔
2612
  SPrivObjPolicies *policies = NULL;
33,773,992✔
2613
  while ((policies = taosHashIterate(pOld, policies))) {
77,994,340✔
2614
    size_t klen = 0;
44,220,348✔
2615
    char  *key = taosHashGetKey(policies, &klen);
44,220,348✔
2616
    size_t vlen = taosHashGetValueSize(policies);
44,220,215✔
2617

2618
    if ((code = taosHashPut(*ppNew, key, klen, vlen > 0 ? policies : NULL, vlen)) != 0) {
44,220,215✔
2619
      taosHashCancelIterate(pOld, policies);
×
2620
      taosHashCleanup(*ppNew);
×
2621
      TAOS_RETURN(code);
×
2622
    }
2623
  }
2624

2625
  TAOS_RETURN(code);
33,773,992✔
2626
}
2627

2628
int32_t mndDupPrivTblHash(SHashObj *pOld, SHashObj **ppNew, bool setUpdateTimeMax) {
104,061,502✔
2629
  if (!(*ppNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true,
104,061,502✔
2630
                              HASH_ENTRY_LOCK))) {
2631
    TAOS_RETURN(terrno);
×
2632
  }
2633
  taosHashSetFreeFp(*ppNew, privTblPoliciesFree);
104,062,028✔
2634

2635
  int32_t           code = 0, lino = 0;
104,061,723✔
2636
  SPrivTblPolicies *policies = NULL, *pTmpPolicies = NULL;
104,061,723✔
2637
  SPrivTblPolicies  tmpPolicies = {0};
104,061,723✔
2638
  while ((policies = taosHashIterate(pOld, policies))) {
104,537,584✔
2639
    size_t klen = 0;
475,861✔
2640
    char  *key = taosHashGetKey(policies, &klen);
475,861✔
2641
    size_t vlen = taosHashGetValueSize(policies);
475,861✔
2642
    memset(&tmpPolicies, 0, sizeof(tmpPolicies));
475,861✔
2643
    pTmpPolicies = &tmpPolicies;
475,861✔
2644
    if (vlen > 0) {
475,861✔
2645
      TAOS_CHECK_EXIT(privTblPoliciesAdd(&tmpPolicies, policies, true, setUpdateTimeMax));
475,861✔
2646
    }
2647
    TAOS_CHECK_EXIT(taosHashPut(*ppNew, key, klen, vlen > 0 ? &tmpPolicies : NULL, vlen));
475,861✔
2648
    pTmpPolicies = NULL;
475,861✔
2649
  }
2650

2651
_exit:
104,061,886✔
2652
  if (code != 0) {
104,061,886✔
2653
    if (!pTmpPolicies) {
×
2654
      privTblPoliciesFree(pTmpPolicies);
2655
      pTmpPolicies = NULL;
×
2656
    }
2657
    if (policies) taosHashCancelIterate(pOld, policies);
×
2658
    taosHashCleanup(*ppNew);
×
2659
    *ppNew = NULL;
×
2660
  }
2661
  TAOS_RETURN(code);
104,061,886✔
2662
}
2663

2664
int32_t mndUserDupObj(SUserObj *pUser, SUserObj *pNew) {
2,737,121✔
2665
  int32_t code = 0;
2,737,121✔
2666
  (void)memcpy(pNew, pUser, sizeof(SUserObj));
2,737,121✔
2667
  pNew->authVersion++;
2,737,121✔
2668
  pNew->updateTime = taosGetTimestampMs();
2,737,121✔
2669
  taosInitRWLatch(&pNew->lock);
2,737,121✔
2670

2671
  pNew->passwords = NULL;
2,737,121✔
2672
  pNew->pIpWhiteListDual = NULL;
2,737,121✔
2673
  pNew->passwords = NULL;
2,737,121✔
2674
  pNew->objPrivs = NULL;
2,737,121✔
2675
  pNew->selectTbs = NULL;
2,737,121✔
2676
  pNew->insertTbs = NULL;
2,737,121✔
2677
  pNew->updateTbs = NULL;
2,737,121✔
2678
  pNew->deleteTbs = NULL;
2,737,121✔
2679
  pNew->ownedDbs = NULL;
2,737,121✔
2680
  pNew->pTimeWhiteList = NULL;
2,737,121✔
2681
  pNew->roles = NULL;
2,737,121✔
2682
  pNew->legacyPrivs = NULL;
2,737,121✔
2683

2684
  taosRLockLatch(&pUser->lock);
2,737,121✔
2685
  pNew->passwords = taosMemoryCalloc(pUser->numOfPasswords, sizeof(SUserPassword));
2,737,121✔
2686
  if (pNew->passwords == NULL) {
2,737,121✔
2687
    code = TSDB_CODE_OUT_OF_MEMORY;
×
2688
    goto _OVER;
×
2689
  }
2690
  (void)memcpy(pNew->passwords, pUser->passwords, pUser->numOfPasswords * sizeof(SUserPassword));
2,737,121✔
2691
  TAOS_CHECK_GOTO(mndDupKVHash(pUser->ownedDbs, &pNew->ownedDbs), NULL, _OVER);
2,737,121✔
2692
  TAOS_CHECK_GOTO(mndDupPrivObjHash(pUser->objPrivs, &pNew->objPrivs), NULL, _OVER);
2,737,121✔
2693
  TAOS_CHECK_GOTO(mndDupPrivTblHash(pUser->selectTbs, &pNew->selectTbs, false), NULL, _OVER);
2,737,121✔
2694
  TAOS_CHECK_GOTO(mndDupPrivTblHash(pUser->insertTbs, &pNew->insertTbs, false), NULL, _OVER);
2,737,121✔
2695
  TAOS_CHECK_GOTO(mndDupPrivTblHash(pUser->updateTbs, &pNew->updateTbs, false), NULL, _OVER);
2,737,121✔
2696
  TAOS_CHECK_GOTO(mndDupPrivTblHash(pUser->deleteTbs, &pNew->deleteTbs, false), NULL, _OVER);
2,737,121✔
2697
  TAOS_CHECK_GOTO(mndDupRoleHash(pUser->roles, &pNew->roles), NULL, _OVER);
2,737,121✔
2698
  if(pUser->legacyPrivs) {
2,737,121✔
2699
    pNew->legacyPrivs = taosMemCalloc(1, sizeof(SPrivHashObjSet));
×
2700
    if (pNew->legacyPrivs == NULL) {
×
2701
      code = TSDB_CODE_OUT_OF_MEMORY;
×
2702
      goto _OVER;
×
2703
    }
2704
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pReadDbs, &pNew->legacyPrivs->pReadDbs), NULL, _OVER);
×
2705
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pWriteDbs, &pNew->legacyPrivs->pWriteDbs), NULL, _OVER);
×
2706
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pReadTbs, &pNew->legacyPrivs->pReadTbs), NULL, _OVER);
×
2707
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pWriteTbs, &pNew->legacyPrivs->pWriteTbs), NULL, _OVER);
×
2708
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pTopics, &pNew->legacyPrivs->pTopics), NULL, _OVER);
×
2709
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pAlterTbs, &pNew->legacyPrivs->pAlterTbs), NULL, _OVER);
×
2710
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pReadViews, &pNew->legacyPrivs->pReadViews), NULL, _OVER);
×
2711
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pWriteViews, &pNew->legacyPrivs->pWriteViews), NULL, _OVER);
×
2712
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pAlterViews, &pNew->legacyPrivs->pAlterViews), NULL, _OVER);
×
2713
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pUseDbs, &pNew->legacyPrivs->pUseDbs), NULL, _OVER);
×
2714
  }
2715
  pNew->pIpWhiteListDual = cloneIpWhiteList(pUser->pIpWhiteListDual);
2,737,121✔
2716
  if (pNew->pIpWhiteListDual == NULL) {
2,737,121✔
2717
    code = TSDB_CODE_OUT_OF_MEMORY;
×
2718
    goto _OVER;
×
2719
  }
2720

2721
  pNew->pTimeWhiteList = cloneDateTimeWhiteList(pUser->pTimeWhiteList);
2,737,121✔
2722
  if (pNew->pTimeWhiteList == NULL) {
2,737,121✔
2723
    code = TSDB_CODE_OUT_OF_MEMORY;
×
2724
    goto _OVER;
×
2725
  }
2726

2727
_OVER:
2,737,121✔
2728
  taosRUnLockLatch(&pUser->lock);
2,737,121✔
2729
  if (code == 0) {
2,737,121✔
2730
    dropOldPasswords(pNew);
2,737,121✔
2731
  }
2732
  TAOS_RETURN(code);
2,737,121✔
2733
}
2734

2735
void mndUserFreeObj(SUserObj *pUser) {
6,741,381✔
2736
  taosHashCleanup(pUser->ownedDbs);
6,741,381✔
2737
  taosHashCleanup(pUser->objPrivs);
6,741,381✔
2738
  taosHashCleanup(pUser->selectTbs);
6,741,381✔
2739
  taosHashCleanup(pUser->insertTbs);
6,741,381✔
2740
  taosHashCleanup(pUser->updateTbs);
6,741,381✔
2741
  taosHashCleanup(pUser->deleteTbs);
6,741,381✔
2742
  taosHashCleanup(pUser->roles);
6,741,381✔
2743
  taosMemoryFreeClear(pUser->passwords);
6,741,381✔
2744
  taosMemoryFreeClear(pUser->pIpWhiteListDual);
6,741,381✔
2745
  taosMemoryFreeClear(pUser->pTimeWhiteList);
6,741,381✔
2746
  pUser->ownedDbs = NULL;
6,741,381✔
2747
  pUser->objPrivs = NULL;
6,741,381✔
2748
  pUser->selectTbs = NULL;
6,741,381✔
2749
  pUser->insertTbs = NULL;
6,741,381✔
2750
  pUser->updateTbs = NULL;
6,741,381✔
2751
  pUser->deleteTbs = NULL;
6,741,381✔
2752
  pUser->roles = NULL;
6,741,381✔
2753
  if (pUser->legacyPrivs) {
6,741,381✔
2754
    taosHashCleanup(pUser->legacyPrivs->pReadDbs);
×
2755
    taosHashCleanup(pUser->legacyPrivs->pWriteDbs);
×
2756
    taosHashCleanup(pUser->legacyPrivs->pReadTbs);
×
2757
    taosHashCleanup(pUser->legacyPrivs->pWriteTbs);
×
2758
    taosHashCleanup(pUser->legacyPrivs->pTopics);
×
2759
    taosHashCleanup(pUser->legacyPrivs->pAlterTbs);
×
2760
    taosHashCleanup(pUser->legacyPrivs->pReadViews);
×
2761
    taosHashCleanup(pUser->legacyPrivs->pWriteViews);
×
2762
    taosHashCleanup(pUser->legacyPrivs->pAlterViews);
×
2763
    taosHashCleanup(pUser->legacyPrivs->pUseDbs);
×
2764
    taosMemoryFreeClear(pUser->legacyPrivs);
×
2765
  }
2766
}
6,741,381✔
2767

2768
static int32_t mndUserActionDelete(SSdb *pSdb, SUserObj *pUser) {
3,385,090✔
2769
  mTrace("user:%s, perform delete action, row:%p", pUser->user, pUser);
3,385,090✔
2770
  mndUserFreeObj(pUser);
3,385,090✔
2771
  return 0;
3,385,090✔
2772
}
2773

2774
static int32_t mndUserActionUpdate(SSdb *pSdb, SUserObj *pOld, SUserObj *pNew) {
2,784,244✔
2775
  mTrace("user:%s, perform update action, old row:%p new row:%p", pOld->user, pOld, pNew);
2,784,244✔
2776
  taosWLockLatch(&pOld->lock);
2,784,244✔
2777
  pOld->updateTime = pNew->updateTime;
2,784,244✔
2778
  pOld->authVersion = pNew->authVersion;
2,784,244✔
2779
  pOld->passVersion = pNew->passVersion;
2,784,244✔
2780
  pOld->sysInfo = pNew->sysInfo;
2,784,244✔
2781
  pOld->enable = pNew->enable;
2,784,244✔
2782
  pOld->flag = pNew->flag;
2,784,244✔
2783
  pOld->changePass = pNew->changePass;
2,784,244✔
2784
  pOld->uid = pNew->uid;
2,784,244✔
2785

2786
  pOld->sessionPerUser = pNew->sessionPerUser;
2,784,244✔
2787
  pOld->connectTime = pNew->connectTime;
2,784,244✔
2788
  pOld->connectIdleTime = pNew->connectIdleTime;
2,784,244✔
2789
  pOld->callPerSession = pNew->callPerSession;
2,784,244✔
2790
  pOld->vnodePerCall = pNew->vnodePerCall;
2,784,244✔
2791
  pOld->failedLoginAttempts = pNew->failedLoginAttempts;
2,784,244✔
2792
  pOld->passwordLifeTime = pNew->passwordLifeTime;
2,784,244✔
2793
  pOld->passwordReuseTime = pNew->passwordReuseTime;
2,784,244✔
2794
  pOld->passwordReuseMax = pNew->passwordReuseMax;
2,784,244✔
2795
  pOld->passwordLockTime = pNew->passwordLockTime;
2,784,244✔
2796
  pOld->passwordGraceTime = pNew->passwordGraceTime;
2,784,244✔
2797
  pOld->inactiveAccountTime = pNew->inactiveAccountTime;
2,784,244✔
2798
  pOld->allowTokenNum = pNew->allowTokenNum;
2,784,244✔
2799
  pOld->tokenNum = pNew->tokenNum;
2,784,244✔
2800

2801
  pOld->numOfPasswords = pNew->numOfPasswords;
2,784,244✔
2802
  TSWAP(pOld->passwords, pNew->passwords);
2,784,244✔
2803
  (void)memcpy(pOld->salt, pNew->salt, sizeof(pOld->salt));
2,784,244✔
2804
  (void)memcpy(pOld->totpsecret, pNew->totpsecret, sizeof(pOld->totpsecret));
2,784,244✔
2805
  pOld->sysPrivs = pNew->sysPrivs;
2,784,244✔
2806
  TSWAP(pOld->ownedDbs, pNew->ownedDbs);
2,784,244✔
2807
  TSWAP(pOld->objPrivs, pNew->objPrivs);
2,784,244✔
2808
  TSWAP(pOld->selectTbs, pNew->selectTbs);
2,784,244✔
2809
  TSWAP(pOld->insertTbs, pNew->insertTbs);
2,784,244✔
2810
  TSWAP(pOld->updateTbs, pNew->updateTbs);
2,784,244✔
2811
  TSWAP(pOld->deleteTbs, pNew->deleteTbs);
2,784,244✔
2812
  TSWAP(pOld->roles, pNew->roles);
2,784,244✔
2813
  TSWAP(pOld->legacyPrivs, pNew->legacyPrivs);
2,784,244✔
2814

2815
  TSWAP(pOld->pIpWhiteListDual, pNew->pIpWhiteListDual);
2,784,244✔
2816
  pOld->ipWhiteListVer = pNew->ipWhiteListVer;
2,784,244✔
2817
  TSWAP(pOld->pTimeWhiteList, pNew->pTimeWhiteList);
2,784,244✔
2818
  pOld->timeWhiteListVer = pNew->timeWhiteListVer;
2,784,244✔
2819
  pOld->passEncryptAlgorithm = pNew->passEncryptAlgorithm;
2,784,244✔
2820

2821
  taosWUnLockLatch(&pOld->lock);
2,784,244✔
2822

2823
  return 0;
2,784,244✔
2824
}
2825

2826
int32_t mndAcquireUser(SMnode *pMnode, const char *userName, SUserObj **ppUser) {
109,159,296✔
2827
  int32_t code = 0;
109,159,296✔
2828
  SSdb   *pSdb = pMnode->pSdb;
109,159,296✔
2829

2830
  *ppUser = sdbAcquire(pSdb, SDB_USER, userName);
109,161,047✔
2831
  if (*ppUser == NULL) {
109,161,120✔
2832
    if (terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
106,165✔
2833
      code = TSDB_CODE_MND_USER_NOT_EXIST;
106,165✔
2834
    } else {
2835
      code = TSDB_CODE_MND_USER_NOT_AVAILABLE;
×
2836
    }
2837
  }
2838
  TAOS_RETURN(code);
109,161,120✔
2839
}
2840

2841
void mndReleaseUser(SMnode *pMnode, SUserObj *pUser) {
163,737,674✔
2842
  SSdb *pSdb = pMnode->pSdb;
163,737,674✔
2843
  sdbRelease(pSdb, pUser);
163,736,944✔
2844
}
163,738,457✔
2845

2846
int32_t mndAcquireUserById(SMnode *pMnode, int64_t userId, SUserObj **ppUser) {
×
2847
  void     *pIter = NULL;
×
2848
  SUserObj *pObj;
×
2849
  SSdb     *pSdb = pMnode->pSdb;
×
2850
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pObj))) {
×
2851
    if (pObj->uid == userId) {
×
2852
      return mndAcquireUser(pMnode, pObj->user, ppUser);
×
2853
    }
2854
  }
2855
  return 0;
×
2856
}
2857

2858
int32_t mndBuildUidNamesHash(SMnode *pMnode, SSHashObj **ppHash) {
538,548✔
2859
  int32_t    code = 0;
538,548✔
2860
  void      *pIter = NULL;
538,548✔
2861
  SUserObj  *pObj;
537,470✔
2862
  SSHashObj *pHash = NULL;
538,548✔
2863

2864
  int32_t nUser = sdbGetSize(pMnode->pSdb, SDB_USER);
538,548✔
2865

2866
  pHash = tSimpleHashInit(nUser, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT));
538,548✔
2867
  if (pHash == NULL) {
538,548✔
2868
    TAOS_RETURN(terrno);
×
2869
  }
2870

2871
  while ((pIter = sdbFetch(pMnode->pSdb, SDB_USER, pIter, (void **)&pObj))) {
1,275,068✔
2872
    code = tSimpleHashPut(pHash, &pObj->uid, sizeof(pObj->uid), pObj->name, strlen(pObj->name) + 1);
736,520✔
2873
    if (code != 0) {
736,520✔
2874
      sdbRelease(pMnode->pSdb, pObj);
×
2875
      sdbCancelFetch(pMnode->pSdb, pIter);
×
2876
      tSimpleHashCleanup(pHash);
×
2877
      TAOS_RETURN(code);
×
2878
    }
2879
    sdbRelease(pMnode->pSdb, pObj);
736,520✔
2880
  }
2881

2882
  *ppHash = pHash;
538,548✔
2883
  TAOS_RETURN(code);
538,548✔
2884
}
2885

2886
int32_t mndEncryptPass(char *pass, const char *salt, int8_t *algo) {
108,999✔
2887
  int32_t code = 0;
108,999✔
2888
  if (tsMetaKey[0] == '\0') {
108,999✔
2889
    return 0;
108,869✔
2890
  }
2891

2892
  if (salt[0] != 0) {
130✔
2893
    char passAndSalt[TSDB_PASSWORD_LEN - 1 + TSDB_PASSWORD_SALT_LEN];
130✔
2894
    (void)memcpy(passAndSalt, pass, TSDB_PASSWORD_LEN - 1);
130✔
2895
    (void)memcpy(passAndSalt + TSDB_PASSWORD_LEN - 1, salt, TSDB_PASSWORD_SALT_LEN);
130✔
2896
    taosEncryptPass_c((uint8_t *)passAndSalt, sizeof(passAndSalt), pass);
2897
  }
2898

2899
  unsigned char packetData[TSDB_PASSWORD_LEN] = {0};
130✔
2900
  SCryptOpts    opts = {0};
130✔
2901
  opts.len = TSDB_PASSWORD_LEN;
130✔
2902
  opts.source = pass;
130✔
2903
  opts.result = packetData;
130✔
2904
  opts.unitLen = TSDB_PASSWORD_LEN;
130✔
2905
  tstrncpy(opts.key, tsDataKey, ENCRYPT_KEY_LEN + 1);
130✔
2906
  int newLen = Builtin_CBC_Encrypt(&opts);
130✔
2907
  if (newLen <= 0) return terrno;
130✔
2908

2909
  memcpy(pass, packetData, newLen);
130✔
2910
  if (algo != NULL) {
130✔
2911
    *algo = DND_CA_SM4;
130✔
2912
  }
2913

2914
  return 0;
130✔
2915
}
2916

2917
static void generateSalt(char *salt, size_t len) {
87,275✔
2918
  const char *set = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
87,275✔
2919
  int32_t     setLen = 62;
87,275✔
2920
  for (int32_t i = 0; i < len - 1; ++i) {
2,792,800✔
2921
    salt[i] = set[taosSafeRand() % setLen];
2,705,525✔
2922
  }
2923
  salt[len - 1] = 0;
87,275✔
2924
}
87,275✔
2925

2926
static int32_t addDefaultIpToTable(SHashObj *pUniqueTab) {
1,081✔
2927
  int32_t code = 0;
1,081✔
2928
  int32_t lino = 0;
1,081✔
2929
  int32_t dummy = 0;
1,081✔
2930

2931
  SIpRange ipv4 = {0}, ipv6 = {0};
1,081✔
2932
  code = createDefaultIp4Range(&ipv4);
1,081✔
2933
  TSDB_CHECK_CODE(code, lino, _error);
1,081✔
2934

2935
  code = taosHashPut(pUniqueTab, &ipv4, sizeof(ipv4), &dummy, sizeof(dummy));
1,081✔
2936
  TSDB_CHECK_CODE(code, lino, _error);
1,081✔
2937

2938
  code = createDefaultIp6Range(&ipv6);
1,081✔
2939
  TSDB_CHECK_CODE(code, lino, _error);
1,081✔
2940

2941
  code = taosHashPut(pUniqueTab, &ipv6, sizeof(ipv6), &dummy, sizeof(dummy));
1,081✔
2942
  TSDB_CHECK_CODE(code, lino, _error);
1,081✔
2943
    
2944
_error:
1,081✔
2945
  if (code != 0) {
1,081✔
2946
    mError("failed to add default ip range to table since %s", tstrerror(code));
×
2947
  }
2948
  return code;
1,081✔
2949
}
2950

2951
static int32_t mndCreateUser(SMnode *pMnode, char *acct, SCreateUserReq *pCreate, SRpcMsg *pReq) {
87,091✔
2952
  int32_t  code = 0;
87,091✔
2953
  int32_t  lino = 0;
87,091✔
2954
  SUserObj userObj = {0};
87,091✔
2955

2956
  userObj.passwords = taosMemoryCalloc(1, sizeof(SUserPassword));
87,091✔
2957
  if (userObj.passwords == NULL) {
87,091✔
2958
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2959
  }
2960
  userObj.numOfPasswords = 1;
87,091✔
2961

2962
  if (pCreate->isImport == 1) {
87,091✔
2963
    memset(userObj.salt, 0, sizeof(userObj.salt));
×
2964
    memcpy(userObj.passwords[0].pass, pCreate->pass, TSDB_PASSWORD_LEN);
×
2965
  } else {
2966
    generateSalt(userObj.salt, sizeof(userObj.salt));
87,091✔
2967
    taosEncryptPass_c((uint8_t *)pCreate->pass, strlen(pCreate->pass), userObj.passwords[0].pass);
87,091✔
2968
    userObj.passwords[0].pass[sizeof(userObj.passwords[0].pass) - 1] = 0;
87,091✔
2969
    TAOS_CHECK_GOTO(mndEncryptPass(userObj.passwords[0].pass, userObj.salt, &userObj.passEncryptAlgorithm), &lino,
87,091✔
2970
                    _OVER);
2971
  }
2972
  userObj.passwords[0].setTime = taosGetTimestampSec();
87,091✔
2973

2974
  tstrncpy(userObj.user, pCreate->user, TSDB_USER_LEN);
87,091✔
2975
  tstrncpy(userObj.acct, acct, TSDB_USER_LEN);
87,091✔
2976
  if (pCreate->totpseed[0] != 0) {
87,091✔
2977
    int len = taosGenerateTotpSecret(pCreate->totpseed, 0, userObj.totpsecret, sizeof(userObj.totpsecret));
×
2978
    if (len < 0) {
×
2979
      TAOS_CHECK_GOTO(TSDB_CODE_PAR_INVALID_OPTION_VALUE, &lino, _OVER);
×
2980
    }
2981
  }
2982

2983
  userObj.createdTime = taosGetTimestampMs();
87,091✔
2984
  userObj.updateTime = userObj.createdTime;
87,091✔
2985
  userObj.superUser = 0;  // pCreate->superUser;
87,091✔
2986
  userObj.sysInfo = pCreate->sysInfo;
87,091✔
2987
  userObj.enable = pCreate->enable;
87,091✔
2988
  userObj.createdb = pCreate->createDb;
87,091✔
2989
  userObj.uid = mndGenerateUid(userObj.user, strlen(userObj.user));
87,091✔
2990

2991
  if (userObj.createdb == 1) {
87,091✔
2992
    privAddType(&userObj.sysPrivs, PRIV_DB_CREATE);
2993
  }
2994

2995
#ifdef TD_ENTERPRISE
2996

2997
  userObj.changePass = pCreate->changepass;
87,091✔
2998
  userObj.sessionPerUser = pCreate->sessionPerUser;
87,091✔
2999
  userObj.connectTime = pCreate->connectTime;
87,091✔
3000
  userObj.connectIdleTime = pCreate->connectIdleTime;
87,091✔
3001
  userObj.callPerSession = pCreate->callPerSession;
87,091✔
3002
  userObj.vnodePerCall = pCreate->vnodePerCall;
87,091✔
3003
  userObj.failedLoginAttempts = pCreate->failedLoginAttempts;
87,091✔
3004
  userObj.passwordLifeTime = pCreate->passwordLifeTime;
87,091✔
3005
  userObj.passwordReuseTime = pCreate->passwordReuseTime;
87,091✔
3006
  userObj.passwordReuseMax = pCreate->passwordReuseMax;
87,091✔
3007
  userObj.passwordLockTime = pCreate->passwordLockTime;
87,091✔
3008
  userObj.passwordGraceTime = pCreate->passwordGraceTime;
87,091✔
3009
  userObj.inactiveAccountTime = pCreate->inactiveAccountTime;
87,091✔
3010
  userObj.allowTokenNum = pCreate->allowTokenNum;
87,091✔
3011
  userObj.tokenNum = 0;
87,091✔
3012

3013
  if (pCreate->numIpRanges == 0) {
87,091✔
3014
    TAOS_CHECK_GOTO(createDefaultIpWhiteList(&userObj.pIpWhiteListDual), &lino, _OVER);
85,578✔
3015
  } else {
3016
    SHashObj *pUniqueTab = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
1,513✔
3017
    if (pUniqueTab == NULL) {
1,513✔
3018
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3019
    }
3020
    
3021
    bool hasPositive = false;
1,513✔
3022
    for (int i = 0; i < pCreate->numIpRanges; i++) {
3,790✔
3023
      SIpRange range = {0};
2,277✔
3024
      copyIpRange(&range, pCreate->pIpDualRanges + i);
2,277✔
3025
      hasPositive = hasPositive || !range.neg;
2,277✔
3026
      int32_t dummy = 0;
2,277✔
3027
      if ((code = taosHashPut(pUniqueTab, &range, sizeof(range), &dummy, sizeof(dummy))) != 0) {
2,277✔
3028
        taosHashCleanup(pUniqueTab);
×
3029
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3030
      }
3031
    }
3032

3033
    // add local ip if there is any positive range
3034
    if (hasPositive) {
1,513✔
3035
      code = addDefaultIpToTable(pUniqueTab);
1,081✔
3036
      if (code != 0) {
1,081✔
3037
        taosHashCleanup(pUniqueTab);
×
3038
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3039
      }
3040
    }
3041

3042
    if (taosHashGetSize(pUniqueTab) > MND_MAX_USER_IP_RANGE) {
1,513✔
3043
      taosHashCleanup(pUniqueTab);
×
3044
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_IP_RANGE, &lino, _OVER);
×
3045
    }
3046

3047
    int32_t           numOfRanges = taosHashGetSize(pUniqueTab);
1,513✔
3048
    SIpWhiteListDual *p = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + numOfRanges * sizeof(SIpRange));
1,513✔
3049
    if (p == NULL) {
1,513✔
3050
      taosHashCleanup(pUniqueTab);
×
3051
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3052
    }
3053

3054
    void *pIter = taosHashIterate(pUniqueTab, NULL);
1,513✔
3055
    for (int32_t i = 0; i < numOfRanges; i++) {
5,613✔
3056
      size_t    len = 0;
4,100✔
3057
      SIpRange *key = taosHashGetKey(pIter, &len);
4,100✔
3058
      memcpy(&p->pIpRanges[i], key, sizeof(SIpRange));
4,100✔
3059
      pIter = taosHashIterate(pUniqueTab, pIter);
4,100✔
3060
    }
3061

3062
    taosHashCleanup(pUniqueTab);
1,513✔
3063
    p->num = numOfRanges;
1,513✔
3064
    sortIpWhiteList(p);
1,513✔
3065
    userObj.pIpWhiteListDual = p;
1,513✔
3066
  }
3067

3068
  if (pCreate->numTimeRanges == 0) {
87,091✔
3069
    userObj.pTimeWhiteList = (SDateTimeWhiteList *)taosMemoryCalloc(1, sizeof(SDateTimeWhiteList));
85,219✔
3070
    if (userObj.pTimeWhiteList == NULL) {
85,219✔
3071
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3072
    }
3073
  } else {
3074
    SHashObj *pUniqueTab = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
1,872✔
3075
    if (pUniqueTab == NULL) {
1,872✔
3076
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3077
    }
3078

3079
    for (int i = 0; i < pCreate->numTimeRanges; i++) {
4,176✔
3080
      SDateTimeRange        *src = pCreate->pTimeRanges + i;
2,304✔
3081
      SDateTimeWhiteListItem range = {0};
2,304✔
3082
      DateTimeRangeToWhiteListItem(&range, src);
2,304✔
3083

3084
      // no need to add expired range
3085
      if (isDateTimeWhiteListItemExpired(&range)) {
2,304✔
3086
        continue;
288✔
3087
      }
3088

3089
      int32_t dummy = 0;
2,016✔
3090
      if ((code = taosHashPut(pUniqueTab, &range, sizeof(range), &dummy, sizeof(dummy))) != 0) {
2,016✔
3091
        taosHashCleanup(pUniqueTab);
×
3092
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3093
      }
3094
    }
3095

3096
    if (taosHashGetSize(pUniqueTab) > MND_MAX_USER_TIME_RANGE) {
1,872✔
3097
      taosHashCleanup(pUniqueTab);
×
3098
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_TIME_RANGE, &lino, _OVER);
×
3099
    }
3100

3101
    int32_t             numOfRanges = taosHashGetSize(pUniqueTab);
1,872✔
3102
    SDateTimeWhiteList *p =
3,744✔
3103
        taosMemoryCalloc(1, sizeof(SDateTimeWhiteList) + numOfRanges * sizeof(SDateTimeWhiteListItem));
1,872✔
3104
    if (p == NULL) {
1,872✔
3105
      taosHashCleanup(pUniqueTab);
×
3106
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3107
    }
3108

3109
    void *pIter = taosHashIterate(pUniqueTab, NULL);
1,872✔
3110
    for (int32_t i = 0; i < numOfRanges; i++) {
3,888✔
3111
      size_t                  len = 0;
2,016✔
3112
      SDateTimeWhiteListItem *key = taosHashGetKey(pIter, &len);
2,016✔
3113
      memcpy(p->ranges + i, key, sizeof(SDateTimeWhiteListItem));
2,016✔
3114
      pIter = taosHashIterate(pUniqueTab, pIter);
2,016✔
3115
    }
3116

3117
    taosHashCleanup(pUniqueTab);
1,872✔
3118
    p->num = numOfRanges;
1,872✔
3119
    sortTimeWhiteList(p);
1,872✔
3120
    userObj.pTimeWhiteList = p;
1,872✔
3121
  }
3122

3123
  userObj.ipWhiteListVer = taosGetTimestampMs();
87,091✔
3124
  userObj.timeWhiteListVer = userObj.ipWhiteListVer;
87,091✔
3125
  
3126

3127
#else  // TD_ENTERPRISE
3128

3129
  userObj.changePass = 1;
3130
  userObj.sessionPerUser = -1;
3131
  userObj.connectTime = -1;
3132
  userObj.connectIdleTime = -1;
3133
  userObj.callPerSession = -1;
3134
  userObj.vnodePerCall = -1;
3135
  userObj.failedLoginAttempts = -1;
3136
  userObj.passwordLifeTime = -1;
3137
  userObj.passwordReuseTime = 0;
3138
  userObj.passwordReuseMax = 0;
3139
  userObj.passwordLockTime = -1;
3140
  userObj.passwordGraceTime = -1;
3141
  userObj.inactiveAccountTime = -1;
3142
  userObj.allowTokenNum = -1;
3143
  userObj.tokenNum = 0;
3144

3145
  TAOS_CHECK_GOTO(createDefaultIpWhiteList(&userObj.pIpWhiteListDual), &lino, _OVER);
3146
  userObj.pTimeWhiteList = (SDateTimeWhiteList *)taosMemoryCalloc(1, sizeof(SDateTimeWhiteList));
3147
  if (userObj.pTimeWhiteList == NULL) {
3148
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
3149
  }
3150

3151
  userObj.ipWhiteListVer = 0;
3152
  userObj.timeWhiteListVer = 0;
3153

3154
#endif  // TD_ENTERPRISE
3155

3156
  userObj.roles = taosHashInit(1, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
87,091✔
3157
  if (userObj.roles == NULL) {
87,091✔
3158
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3159
  }
3160

3161
  uint8_t flag = 0x01;
87,091✔
3162
  if ((code = taosHashPut(userObj.roles, TSDB_ROLE_DEFAULT, strlen(TSDB_ROLE_DEFAULT) + 1, &flag, sizeof(flag))) != 0) {
87,091✔
3163
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3164
  }
3165

3166
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "create-user");
87,091✔
3167
  if (pTrans == NULL) {
87,091✔
3168
    mError("user:%s, failed to create since %s", pCreate->user, terrstr());
×
3169
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3170
  }
3171
  mInfo("trans:%d, used to create user:%s", pTrans->id, pCreate->user);
87,091✔
3172

3173
  SSdbRaw *pCommitRaw = mndUserActionEncode(&userObj);
87,091✔
3174
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
87,091✔
3175
    mError("trans:%d, failed to commit redo log since %s", pTrans->id, terrstr());
×
3176
    mndTransDrop(pTrans);
×
3177
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3178
  }
3179
  TAOS_CHECK_GOTO(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY), &lino, _OVER);
87,091✔
3180

3181
  if (mndTransPrepare(pMnode, pTrans) != 0) {
87,091✔
3182
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
3183
    mndTransDrop(pTrans);
×
3184
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3185
  }
3186

3187
  if ((code = userCacheUpdateWhiteList(pMnode, &userObj)) != 0) {
87,091✔
3188
    mndTransDrop(pTrans);
×
3189
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3190
  }
3191

3192
  if (taosHashGet(userObj.roles, TSDB_ROLE_SYSAUDIT_LOG, strlen(TSDB_ROLE_SYSAUDIT_LOG) + 1)) {
87,091✔
3193
    (void)mndResetAuditLogUser(pMnode, userObj.user, true);
×
3194
  }
3195

3196
  mndTransDrop(pTrans);
87,091✔
3197

3198
_OVER:
87,091✔
3199
  mndUserFreeObj(&userObj);
87,091✔
3200
  TAOS_RETURN(code);
87,091✔
3201
}
3202

3203
static int32_t mndCheckPasswordFmt(const char *pwd) {
130,106✔
3204
  if (tsEnableAdvancedSecurity == 0 && strcmp(pwd, "taosdata") == 0) {
130,106✔
3205
    return 0;
×
3206
  }
3207

3208
  if (tsEnableStrongPassword == 0) {
130,106✔
3209
    for (char c = *pwd; c != 0; c = *(++pwd)) {
104,592✔
3210
      if (c == ' ' || c == '\'' || c == '\"' || c == '`' || c == '\\') {
98,354✔
3211
        return TSDB_CODE_MND_INVALID_PASS_FORMAT;
×
3212
      }
3213
    }
3214
    return 0;
6,238✔
3215
  }
3216

3217
  int32_t len = strlen(pwd);
123,868✔
3218
  if (len < TSDB_PASSWORD_MIN_LEN) {
123,868✔
3219
    return TSDB_CODE_PAR_PASSWD_TOO_SHORT_OR_EMPTY;
×
3220
  }
3221

3222
  if (len > TSDB_PASSWORD_MAX_LEN) {
123,868✔
3223
    return TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG;
×
3224
  }
3225

3226
  if (taosIsComplexString(pwd)) {
123,868✔
3227
    return 0;
103,103✔
3228
  }
3229

3230
  return TSDB_CODE_MND_INVALID_PASS_FORMAT;
20,765✔
3231
}
3232

3233
static int32_t mndCheckTotpSeedFmt(const char *seed) {
×
3234
  int32_t len = strlen(seed);
×
3235
  if (len < TSDB_USER_TOTPSEED_MIN_LEN) {
×
3236
    return TSDB_CODE_PAR_OPTION_VALUE_TOO_SHORT;
×
3237
  }
3238

3239
  if (taosIsComplexString(seed)) {
×
3240
    return 0;
×
3241
  }
3242

3243
  return TSDB_CODE_PAR_INVALID_OPTION_VALUE;
×
3244
}
3245

3246
static int32_t mndProcessGetUserDateTimeWhiteListReq(SRpcMsg *pReq) {
×
3247
  SMnode                *pMnode = pReq->info.node;
×
3248
  int32_t                code = 0;
×
3249
  int32_t                lino = 0;
×
3250
  int32_t                contLen = 0;
×
3251
  void                  *pRsp = NULL;
×
3252
  SUserObj              *pUser = NULL;
×
3253
  SGetUserWhiteListReq   wlReq = {0};
×
3254
  SUserDateTimeWhiteList wlRsp = {0};
×
3255

3256
  if (tDeserializeSGetUserWhiteListReq(pReq->pCont, pReq->contLen, &wlReq) != 0) {
×
3257
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
3258
  }
3259
  mTrace("user: %s, start to get date time whitelist", wlReq.user);
×
3260

3261
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, wlReq.user, &pUser), &lino, _OVER);
×
3262
  TAOS_CHECK_GOTO(mndSetUserDateTimeWhiteListRsp(pMnode, pUser, &wlRsp), &lino, _OVER);
×
3263

3264
  contLen = tSerializeSUserDateTimeWhiteList(NULL, 0, &wlRsp);
×
3265
  if (contLen < 0) {
×
3266
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3267
  }
3268
  pRsp = rpcMallocCont(contLen);
×
3269
  if (pRsp == NULL) {
×
3270
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3271
  }
3272

3273
  contLen = tSerializeSUserDateTimeWhiteList(pRsp, contLen, &wlRsp);
×
3274
  if (contLen < 0) {
×
3275
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3276
  }
3277

3278
_OVER:
×
3279
  mndReleaseUser(pMnode, pUser);
×
3280
  tFreeSUserDateTimeWhiteList(&wlRsp);
×
3281
  if (code < 0) {
×
3282
    mError("user:%s, failed to get whitelist at line %d since %s", wlReq.user, lino, tstrerror(code));
×
3283
    rpcFreeCont(pRsp);
×
3284
    pRsp = NULL;
×
3285
    contLen = 0;
×
3286
  }
3287
  pReq->code = code;
×
3288
  pReq->info.rsp = pRsp;
×
3289
  pReq->info.rspLen = contLen;
×
3290

3291
  TAOS_RETURN(code);
×
3292
  return 0;
3293
}
3294

3295
static int32_t buildRetrieveDateTimeWhiteListRsp(SRetrieveDateTimeWhiteListRsp *pRsp) {
445✔
3296
  (void)taosThreadRwlockRdlock(&userCache.rw);
445✔
3297

3298
  int32_t count = taosHashGetSize(userCache.users);
445✔
3299
  pRsp->pUsers = taosMemoryCalloc(count, sizeof(SUserDateTimeWhiteList));
445✔
3300
  if (pRsp->pUsers == NULL) {
445✔
3301
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
3302
    TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
3303
  }
3304

3305
  count = 0;
445✔
3306
  void *pIter = taosHashIterate(userCache.users, NULL);
445✔
3307
  while (pIter) {
890✔
3308
    SDateTimeWhiteList *wl = (*(SCachedUserInfo **)pIter)->wlTime;
445✔
3309
    if (wl == NULL || wl->num <= 0) {
445✔
3310
      pIter = taosHashIterate(userCache.users, pIter);
445✔
3311
      continue;
445✔
3312
    }
3313

3314
    SUserDateTimeWhiteList *pUser = &pRsp->pUsers[count];
×
3315
    pUser->ver = userCache.verTime;
×
3316

3317
    size_t klen;
×
3318
    char  *key = taosHashGetKey(pIter, &klen);
×
3319
    (void)memcpy(pUser->user, key, klen);
×
3320

3321
    pUser->numWhiteLists = wl->num;
×
3322
    pUser->pWhiteLists = taosMemoryCalloc(wl->num, sizeof(SDateTimeWhiteListItem));
×
3323
    if (pUser->pWhiteLists == NULL) {
×
3324
      (void)taosThreadRwlockUnlock(&userCache.rw);
×
3325
      TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
3326
    }
3327

3328
    (void)memcpy(pUser->pWhiteLists, wl->ranges, wl->num * sizeof(SDateTimeWhiteListItem));
×
3329
    count++;
×
3330
    pIter = taosHashIterate(userCache.users, pIter);
×
3331
  }
3332

3333
  pRsp->numOfUser = count;
445✔
3334
  pRsp->ver = userCache.verTime;
445✔
3335
  (void)taosThreadRwlockUnlock(&userCache.rw);
445✔
3336
  TAOS_RETURN(0);
445✔
3337
}
3338

3339
static int32_t mndProcessRetrieveDateTimeWhiteListReq(SRpcMsg *pReq) {
445✔
3340
  int32_t                       code = 0;
445✔
3341
  int32_t                       lino = 0;
445✔
3342
  int32_t                       len = 0;
445✔
3343
  void                         *pRsp = NULL;
445✔
3344
  SRetrieveDateTimeWhiteListRsp wlRsp = {0};
445✔
3345

3346
  // impl later
3347
  SRetrieveWhiteListReq req = {0};
445✔
3348
  if (tDeserializeRetrieveWhiteListReq(pReq->pCont, pReq->contLen, &req) != 0) {
445✔
3349
    code = TSDB_CODE_INVALID_MSG;
×
3350
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3351
  }
3352

3353
  TAOS_CHECK_GOTO(buildRetrieveDateTimeWhiteListRsp(&wlRsp), &lino, _OVER);
445✔
3354

3355
  len = tSerializeSRetrieveDateTimeWhiteListRsp(NULL, 0, &wlRsp);
445✔
3356
  if (len < 0) {
445✔
3357
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
3358
  }
3359

3360
  pRsp = rpcMallocCont(len);
445✔
3361
  if (!pRsp) {
445✔
3362
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3363
  }
3364
  len = tSerializeSRetrieveDateTimeWhiteListRsp(pRsp, len, &wlRsp);
445✔
3365
  if (len < 0) {
445✔
3366
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
3367
  }
3368

3369
_OVER:
445✔
3370
  if (code < 0) {
445✔
3371
    mError("failed to process retrieve ip white request at line %d since %s", lino, tstrerror(code));
×
3372
    rpcFreeCont(pRsp);
×
3373
    pRsp = NULL;
×
3374
    len = 0;
×
3375
  }
3376
  pReq->code = code;
445✔
3377
  pReq->info.rsp = pRsp;
445✔
3378
  pReq->info.rspLen = len;
445✔
3379

3380
  tFreeSRetrieveDateTimeWhiteListRsp(&wlRsp);
445✔
3381
  TAOS_RETURN(code);
445✔
3382
}
3383

3384
static int32_t mndProcessCreateUserReq(SRpcMsg *pReq) {
97,980✔
3385
  SMnode        *pMnode = pReq->info.node;
97,980✔
3386
  int32_t        code = 0;
97,980✔
3387
  int32_t        lino = 0;
97,980✔
3388
  SRoleObj      *pRole = NULL;
97,980✔
3389
  SUserObj      *pUser = NULL;
97,980✔
3390
  SUserObj      *pOperUser = NULL;
97,980✔
3391
  SCreateUserReq createReq = {0};
97,980✔
3392
  int64_t        tss = taosGetTimestampMs();
97,980✔
3393

3394
  if (tDeserializeSCreateUserReq(pReq->pCont, pReq->contLen, &createReq) != 0) {
97,980✔
3395
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
3396
  }
3397

3398
  mInfo("user:%s, start to create, createdb:%d, is_import:%d", createReq.user, createReq.createDb, createReq.isImport);
97,980✔
3399

3400
#ifndef TD_ENTERPRISE
3401
  if (createReq.isImport == 1) {
3402
    TAOS_CHECK_GOTO(TSDB_CODE_OPS_NOT_SUPPORT, &lino, _OVER);  // enterprise feature
3403
  }
3404
#endif
3405
  code = mndAcquireUser(pMnode, RPC_MSG_USER(pReq), &pOperUser);
97,980✔
3406
  if (pOperUser == NULL) {
97,980✔
3407
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_USER_FROM_CONN, &lino, _OVER);
×
3408
  }
3409

3410
  if (createReq.isImport != 1) {
97,980✔
3411
    // TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, RPC_MSG_USER(pReq), MND_OPER_CREATE_USER), &lino, _OVER);
3412
    TAOS_CHECK_GOTO(mndCheckSysObjPrivilege(pMnode, pOperUser, RPC_MSG_TOKEN(pReq), PRIV_USER_CREATE, 0, 0, NULL, NULL),
97,980✔
3413
                    &lino, _OVER);
3414
  } else if (strcmp(RPC_MSG_USER(pReq), "root") != 0) {
×
3415
    mError("The operation is not permitted to create user:%s", RPC_MSG_USER(pReq));
×
3416
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_RIGHTS, &lino, _OVER);
×
3417
  }
3418

3419
  if (createReq.user[0] == 0) {
97,980✔
3420
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
3421
  }
3422

3423
  if (createReq.isImport != 1) {
97,980✔
3424
    code = mndCheckPasswordFmt(createReq.pass);
97,980✔
3425
    TAOS_CHECK_GOTO(code, &lino, _OVER);
97,980✔
3426
  }
3427

3428
  if (createReq.totpseed[0] != 0) {
87,433✔
3429
    code = mndCheckTotpSeedFmt(createReq.totpseed);
×
3430
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3431
  }
3432

3433
  code = mndAcquireUser(pMnode, createReq.user, &pUser);
87,433✔
3434
  if (pUser != NULL) {
87,433✔
3435
    TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_ALREADY_EXIST, &lino, _OVER);
342✔
3436
  }
3437

3438
  code = mndAcquireRole(pMnode, createReq.user, &pRole);
87,091✔
3439
  if (pRole != NULL) {
87,091✔
3440
    TAOS_CHECK_GOTO(TSDB_CODE_MND_ROLE_ALREADY_EXIST, &lino, _OVER);
×
3441
  }
3442

3443
  TAOS_CHECK_GOTO(grantCheck(TSDB_GRANT_USER), &lino, _OVER);
87,091✔
3444

3445
  if (sdbGetSize(pMnode->pSdb, SDB_USER) >= TSDB_MAX_USERS) {
87,091✔
3446
    mError("user:%s, failed to create since reach max user limit %d", createReq.user, TSDB_MAX_USERS);
×
3447
    TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USERS, &lino, _OVER);
×
3448
  }
3449

3450
  if (!createReq.hasSessionPerUser) createReq.sessionPerUser = (tsEnableAdvancedSecurity ? TSDB_USER_SESSION_PER_USER_DEFAULT : -1);
87,091✔
3451
  if (!createReq.hasConnectTime) createReq.connectTime = (tsEnableAdvancedSecurity ? TSDB_USER_CONNECT_TIME_DEFAULT : -1);
87,091✔
3452
  if (!createReq.hasConnectIdleTime) createReq.connectIdleTime = (tsEnableAdvancedSecurity ? TSDB_USER_CONNECT_IDLE_TIME_DEFAULT : -1);
87,091✔
3453
  if (!createReq.hasCallPerSession) createReq.callPerSession = (tsEnableAdvancedSecurity ? TSDB_USER_CALL_PER_SESSION_DEFAULT : -1);
87,091✔
3454
  if (!createReq.hasVnodePerCall) createReq.vnodePerCall = (tsEnableAdvancedSecurity ? TSDB_USER_VNODE_PER_CALL_DEFAULT : -1);
87,091✔
3455
  if (!createReq.hasFailedLoginAttempts) createReq.failedLoginAttempts = (tsEnableAdvancedSecurity ? TSDB_USER_FAILED_LOGIN_ATTEMPTS_DEFAULT : -1);
87,091✔
3456
  if (!createReq.hasPasswordLifeTime) createReq.passwordLifeTime = (tsEnableAdvancedSecurity ? TSDB_USER_PASSWORD_LIFE_TIME_DEFAULT : -1);
87,091✔
3457
  if (!createReq.hasPasswordReuseTime) createReq.passwordReuseTime = (tsEnableAdvancedSecurity ? TSDB_USER_PASSWORD_REUSE_TIME_DEFAULT : 0);
87,091✔
3458
  if (!createReq.hasPasswordReuseMax) createReq.passwordReuseMax = (tsEnableAdvancedSecurity ? TSDB_USER_PASSWORD_REUSE_MAX_DEFAULT : 0);
87,091✔
3459
  if (!createReq.hasPasswordLockTime) createReq.passwordLockTime = (tsEnableAdvancedSecurity ? TSDB_USER_PASSWORD_LOCK_TIME_DEFAULT : 1);
87,091✔
3460
  if (!createReq.hasPasswordGraceTime) createReq.passwordGraceTime = (tsEnableAdvancedSecurity ? TSDB_USER_PASSWORD_GRACE_TIME_DEFAULT : -1);
87,091✔
3461
  if (!createReq.hasInactiveAccountTime) createReq.inactiveAccountTime = (tsEnableAdvancedSecurity ? TSDB_USER_INACTIVE_ACCOUNT_TIME_DEFAULT : -1);
87,091✔
3462
  if (!createReq.hasAllowTokenNum) createReq.allowTokenNum = TSDB_USER_ALLOW_TOKEN_NUM_DEFAULT;
87,091✔
3463

3464
  code = mndCreateUser(pMnode, pOperUser->acct, &createReq, pReq);
87,091✔
3465
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
87,091✔
3466

3467
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
87,091✔
3468
    char detail[1000] = {0};
87,091✔
3469
    (void)snprintf(detail, sizeof(detail), "enable:%d, superUser:%d, sysInfo:%d, password:xxx", createReq.enable,
87,091✔
3470
                   createReq.superUser, createReq.sysInfo);
87,091✔
3471
    char operation[15] = {0};
87,091✔
3472
    if (createReq.isImport == 1) {
87,091✔
3473
      tstrncpy(operation, "importUser", sizeof(operation));
×
3474
    } else {
3475
      tstrncpy(operation, "createUser", sizeof(operation));
87,091✔
3476
    }
3477

3478
    int64_t tse = taosGetTimestampMs();
87,091✔
3479
    double  duration = (double)(tse - tss);
87,091✔
3480
    duration = duration / 1000;
87,091✔
3481

3482
    auditRecord(pReq, pMnode->clusterId, operation, "", createReq.user, detail, strlen(detail), duration, 0);
87,091✔
3483
  }
3484

3485
_OVER:
97,980✔
3486
  if (code == TSDB_CODE_MND_USER_ALREADY_EXIST && createReq.ignoreExists) {
97,980✔
3487
    code = 0;
×
3488
  } else if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
97,980✔
3489
    mError("user:%s, failed to create at line %d since %s", createReq.user, lino, tstrerror(code));
10,889✔
3490
  }
3491

3492
  mndReleaseRole(pMnode, pRole);
97,980✔
3493
  mndReleaseUser(pMnode, pUser);
97,980✔
3494
  mndReleaseUser(pMnode, pOperUser);
97,980✔
3495
  tFreeSCreateUserReq(&createReq);
97,980✔
3496

3497
  TAOS_RETURN(code);
97,980✔
3498
}
3499

3500
static int32_t mndProcessGetUserIpWhiteListReq(SRpcMsg *pReq) {
7,817✔
3501
  SMnode                *pMnode = pReq->info.node;
7,817✔
3502
  int32_t                code = 0;
7,817✔
3503
  int32_t                lino = 0;
7,817✔
3504
  int32_t                contLen = 0;
7,817✔
3505
  void                  *pRsp = NULL;
7,817✔
3506
  SUserObj              *pUser = NULL;
7,817✔
3507
  SGetUserWhiteListReq   wlReq = {0};
7,817✔
3508
  SGetUserIpWhiteListRsp wlRsp = {0};
7,817✔
3509

3510
  int32_t (*serialFn)(void *, int32_t, SGetUserIpWhiteListRsp *) = NULL;
7,817✔
3511
  int32_t (*setRspFn)(SMnode *pMnode, SUserObj *pUser, SGetUserIpWhiteListRsp *pRsp) = NULL;
7,817✔
3512

3513
  if (pReq->msgType == TDMT_MND_GET_USER_IP_WHITELIST_DUAL) {
7,817✔
3514
    serialFn = tSerializeSGetUserIpWhiteListDualRsp;
7,817✔
3515
    setRspFn = mndSetUserIpWhiteListDualRsp;
7,817✔
3516
  } else {
3517
    serialFn = tSerializeSGetUserIpWhiteListRsp;
×
3518
    setRspFn = mndSetUserIpWhiteListRsp;
×
3519
  }
3520
  if (tDeserializeSGetUserWhiteListReq(pReq->pCont, pReq->contLen, &wlReq) != 0) {
7,817✔
3521
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
3522
  }
3523
  mTrace("user: %s, start to get ip whitelist", wlReq.user);
7,817✔
3524

3525
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, wlReq.user, &pUser), &lino, _OVER);
7,817✔
3526
  TAOS_CHECK_GOTO(setRspFn(pMnode, pUser, &wlRsp), &lino, _OVER);
7,817✔
3527

3528
  contLen = serialFn(NULL, 0, &wlRsp);
7,817✔
3529
  if (contLen < 0) {
7,817✔
3530
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3531
  }
3532
  pRsp = rpcMallocCont(contLen);
7,817✔
3533
  if (pRsp == NULL) {
7,817✔
3534
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3535
  }
3536

3537
  contLen = serialFn(pRsp, contLen, &wlRsp);
7,817✔
3538
  if (contLen < 0) {
7,817✔
3539
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3540
  }
3541

3542
_OVER:
7,817✔
3543
  mndReleaseUser(pMnode, pUser);
7,817✔
3544
  tFreeSGetUserIpWhiteListDualRsp(&wlRsp);
7,817✔
3545
  if (code < 0) {
7,817✔
3546
    mError("user:%s, failed to get whitelist at line %d since %s", wlReq.user, lino, tstrerror(code));
×
3547
    rpcFreeCont(pRsp);
×
3548
    pRsp = NULL;
×
3549
    contLen = 0;
×
3550
  }
3551
  pReq->code = code;
7,817✔
3552
  pReq->info.rsp = pRsp;
7,817✔
3553
  pReq->info.rspLen = contLen;
7,817✔
3554

3555
  TAOS_RETURN(code);
7,817✔
3556
}
3557

3558
static int32_t buildRetrieveIpWhiteListRsp(SUpdateIpWhite *pUpdate) {
445✔
3559
  (void)taosThreadRwlockRdlock(&userCache.rw);
445✔
3560

3561
  int32_t count = taosHashGetSize(userCache.users);
445✔
3562
  pUpdate->pUserIpWhite = taosMemoryCalloc(count, sizeof(SUpdateUserIpWhite));
445✔
3563
  if (pUpdate->pUserIpWhite == NULL) {
445✔
3564
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
3565
    TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
3566
  }
3567

3568
  count = 0;
445✔
3569
  void *pIter = taosHashIterate(userCache.users, NULL);
445✔
3570
  while (pIter) {
890✔
3571
    SIpWhiteListDual *wl = (*(SCachedUserInfo **)pIter)->wlIp;
445✔
3572
    if (wl == NULL || wl->num <= 0) {
445✔
3573
      pIter = taosHashIterate(userCache.users, pIter);
×
3574
      continue;
×
3575
    }
3576

3577
    SUpdateUserIpWhite *pUser = &pUpdate->pUserIpWhite[count];
445✔
3578
    pUser->ver = userCache.verIp;
445✔
3579

3580
    size_t klen;
445✔
3581
    char  *key = taosHashGetKey(pIter, &klen);
445✔
3582
    (void)memcpy(pUser->user, key, klen);
445✔
3583

3584
    pUser->numOfRange = wl->num;
445✔
3585
    pUser->pIpRanges = taosMemoryCalloc(wl->num, sizeof(SIpRange));
445✔
3586
    if (pUser->pIpRanges == NULL) {
445✔
3587
      (void)taosThreadRwlockUnlock(&userCache.rw);
×
3588
      TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
3589
    }
3590

3591
    (void)memcpy(pUser->pIpRanges, wl->pIpRanges, wl->num * sizeof(SIpRange));
445✔
3592
    count++;
445✔
3593
    pIter = taosHashIterate(userCache.users, pIter);
445✔
3594
  }
3595

3596
  pUpdate->numOfUser = count;
445✔
3597
  pUpdate->ver = userCache.verIp;
445✔
3598
  (void)taosThreadRwlockUnlock(&userCache.rw);
445✔
3599
  TAOS_RETURN(0);
445✔
3600
}
3601

3602
int32_t mndProcessRetrieveIpWhiteListReq(SRpcMsg *pReq) {
445✔
3603
  int32_t        code = 0;
445✔
3604
  int32_t        lino = 0;
445✔
3605
  int32_t        len = 0;
445✔
3606
  void          *pRsp = NULL;
445✔
3607
  SUpdateIpWhite ipWhite = {0};
445✔
3608

3609
  // impl later
3610
  SRetrieveWhiteListReq req = {0};
445✔
3611
  if (tDeserializeRetrieveWhiteListReq(pReq->pCont, pReq->contLen, &req) != 0) {
445✔
3612
    code = TSDB_CODE_INVALID_MSG;
×
3613
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3614
  }
3615

3616
  int32_t (*fn)(void *, int32_t, SUpdateIpWhite *) = NULL;
445✔
3617
  if (pReq->msgType == TDMT_MND_RETRIEVE_IP_WHITELIST) {
445✔
3618
    fn = tSerializeSUpdateIpWhite;
×
3619
  } else if (pReq->msgType == TDMT_MND_RETRIEVE_IP_WHITELIST_DUAL) {
445✔
3620
    fn = tSerializeSUpdateIpWhiteDual;
445✔
3621
  }
3622

3623
  TAOS_CHECK_GOTO(buildRetrieveIpWhiteListRsp(&ipWhite), &lino, _OVER);
445✔
3624

3625
  len = fn(NULL, 0, &ipWhite);
445✔
3626
  if (len < 0) {
445✔
3627
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
3628
  }
3629

3630
  pRsp = rpcMallocCont(len);
445✔
3631
  if (!pRsp) {
445✔
3632
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3633
  }
3634
  len = fn(pRsp, len, &ipWhite);
445✔
3635
  if (len < 0) {
445✔
3636
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
3637
  }
3638

3639
_OVER:
445✔
3640
  if (code < 0) {
445✔
3641
    mError("failed to process retrieve ip white request at line %d since %s", lino, tstrerror(code));
×
3642
    rpcFreeCont(pRsp);
×
3643
    pRsp = NULL;
×
3644
    len = 0;
×
3645
  }
3646
  pReq->code = code;
445✔
3647
  pReq->info.rsp = pRsp;
445✔
3648
  pReq->info.rspLen = len;
445✔
3649

3650
  tFreeSUpdateIpWhiteReq(&ipWhite);
445✔
3651
  TAOS_RETURN(code);
445✔
3652
}
3653

3654
static int32_t mndAlterUser(SMnode *pMnode, SUserObj *pNew, SRpcMsg *pReq) {
1,396,009✔
3655
  int32_t code = 0, lino = 0;
1,396,009✔
3656
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "alter-user");
1,396,009✔
3657
  if (pTrans == NULL) {
1,396,009✔
3658
    mError("user:%s, failed to alter since %s", pNew->user, terrstr());
×
3659
    TAOS_RETURN(terrno);
×
3660
  }
3661
  mInfo("trans:%d, used to alter user:%s", pTrans->id, pNew->user);
1,396,009✔
3662

3663
  SSdbRaw *pCommitRaw = mndUserActionEncode(pNew);
1,396,009✔
3664
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
1,396,009✔
3665
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
3666
    mndTransDrop(pTrans);
×
3667
    TAOS_RETURN(terrno);
×
3668
  }
3669
  TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
1,396,009✔
3670

3671
  if (mndTransPrepare(pMnode, pTrans) != 0) {
1,396,009✔
3672
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
3673
    mndTransDrop(pTrans);
×
3674
    TAOS_RETURN(terrno);
×
3675
  }
3676
  if ((code = userCacheUpdateWhiteList(pMnode, pNew)) != 0) {
1,396,009✔
3677
    mndTransDrop(pTrans);
×
3678
    TAOS_RETURN(code);
×
3679
  }
3680
_exit:
1,396,009✔
3681
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
1,396,009✔
3682
    mError("user:%s, failed to alter at line %d since %s", pNew->user, lino, tstrerror(code));
×
3683
  }
3684
  mndTransDrop(pTrans);
1,396,009✔
3685
  TAOS_RETURN(code);
1,396,009✔
3686
}
3687

3688
static int32_t mndDupObjHash(SHashObj *pOld, int32_t dataLen, SHashObj **ppNew) {
×
3689
  int32_t code = 0;
×
3690

3691
  *ppNew =
×
3692
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
3693
  if (*ppNew == NULL) {
×
3694
    code = terrno ? terrno : TSDB_CODE_OUT_OF_MEMORY;
×
3695
    TAOS_RETURN(code);
×
3696
  }
3697

3698
  char *db = taosHashIterate(pOld, NULL);
×
3699
  while (db != NULL) {
×
3700
    int32_t len = strlen(db) + 1;
×
3701
    if ((code = taosHashPut(*ppNew, db, len, db, dataLen)) != 0) {
×
3702
      taosHashCancelIterate(pOld, db);
×
3703
      taosHashCleanup(*ppNew);
×
3704
      TAOS_RETURN(code);
×
3705
    }
3706
    db = taosHashIterate(pOld, db);
×
3707
  }
3708

3709
  TAOS_RETURN(code);
×
3710
}
3711

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

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

3716
static int32_t mndTablePriviledge(SMnode *pMnode, SHashObj *hash, SHashObj *useDbHash, SAlterUserReq *alterReq,
×
3717
                                  SSdb *pSdb) {
3718
  void *pIter = NULL;
×
3719
  char  tbFName[TSDB_TABLE_FNAME_LEN] = {0};
×
3720

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

3724
  if (alterReq->tagCond != NULL && alterReq->tagCondLen != 0) {
×
3725
    char *value = taosHashGet(hash, tbFName, len);
×
3726
    if (value != NULL) {
×
3727
      TAOS_RETURN(TSDB_CODE_MND_PRIVILEGE_EXIST);
×
3728
    }
3729

3730
    int32_t condLen = alterReq->tagCondLen;
×
3731
    TAOS_CHECK_RETURN(taosHashPut(hash, tbFName, len, alterReq->tagCond, condLen));
×
3732
  } else {
3733
    TAOS_CHECK_RETURN(taosHashPut(hash, tbFName, len, alterReq->isView ? "v" : "t", 2));
×
3734
  }
3735

3736
  int32_t  dbKeyLen = strlen(alterReq->objname) + 1;
×
3737
  int32_t  ref = 1;
×
3738
  int32_t *currRef = taosHashGet(useDbHash, alterReq->objname, dbKeyLen);
×
3739
  if (NULL != currRef) {
×
3740
    ref = (*currRef) + 1;
×
3741
  }
3742
  TAOS_CHECK_RETURN(taosHashPut(useDbHash, alterReq->objname, dbKeyLen, &ref, sizeof(ref)));
×
3743

3744
  TAOS_RETURN(0);
×
3745
}
3746

3747
static int32_t mndRemoveTablePriviledge(SMnode *pMnode, SHashObj *hash, SHashObj *useDbHash, SAlterUserReq *alterReq,
×
3748
                                        SSdb *pSdb) {
3749
  void *pIter = NULL;
×
3750
  char  tbFName[TSDB_TABLE_FNAME_LEN] = {0};
×
3751
  (void)snprintf(tbFName, sizeof(tbFName), "%s.%s", alterReq->objname, alterReq->tabName);
×
3752
  int32_t len = strlen(tbFName) + 1;
×
3753

3754
  if (taosHashRemove(hash, tbFName, len) != 0) {
×
3755
    TAOS_RETURN(0);  // not found
×
3756
  }
3757

3758
  int32_t  dbKeyLen = strlen(alterReq->objname) + 1;
×
3759
  int32_t *currRef = taosHashGet(useDbHash, alterReq->objname, dbKeyLen);
×
3760
  if (NULL == currRef) {
×
3761
    return 0;
×
3762
  }
3763

3764
  if (1 == *currRef) {
×
3765
    if (taosHashRemove(useDbHash, alterReq->objname, dbKeyLen) != 0) {
×
3766
      TAOS_RETURN(0);  // not found
×
3767
    }
3768
    return 0;
×
3769
  }
3770
  int32_t ref = (*currRef) - 1;
×
3771
  TAOS_CHECK_RETURN(taosHashPut(useDbHash, alterReq->objname, dbKeyLen, &ref, sizeof(ref)));
×
3772

3773
  return 0;
×
3774
}
3775

3776
#if 0
3777
static int32_t mndProcessAlterUserPrivilegesReq(SRpcMsg* pReq, SAlterUserReq *pAlterReq) {
3778
  SMnode   *pMnode = pReq->info.node;
3779
  SSdb     *pSdb = pMnode->pSdb;
3780
  int32_t   code = 0, lino = 0;
3781
  SUserObj *pUser = NULL;
3782
  SUserObj  newUser = {0};
3783
  int64_t   tss = taosGetTimestampMs();
3784

3785
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, pAlterReq->user, &pUser), &lino, _OVER);
3786
  TAOS_CHECK_GOTO(mndCheckAlterUserPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser, pAlterReq), &lino, _OVER);
3787
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
3788

3789
#if 0
3790
  if (ALTER_USER_ADD_READ_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName) ||
3791
      ALTER_USER_ADD_ALL_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName)) {
3792
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
3793
      int32_t len = strlen(pAlterReq->objname) + 1;
3794
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
3795
      if (pDb == NULL) {
3796
        mndReleaseDb(pMnode, pDb);
3797
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
3798
      }
3799
      if ((code = taosHashPut(newUser.readDbs, pAlterReq->objname, len, pAlterReq->objname, TSDB_DB_FNAME_LEN)) !=
3800
          0) {
3801
        mndReleaseDb(pMnode, pDb);
3802
        TAOS_CHECK_GOTO(code, &lino, _OVER);
3803
      }
3804
      mndReleaseDb(pMnode, pDb);
3805
    } else {
3806
      void   *pIter = NULL;
3807
      while (1) {
3808
        SDbObj *pDb = NULL;
3809
        pIter = sdbFetch(pSdb, SDB_DB, pIter, (void **)&pDb);
3810
        if (pIter == NULL) break;
3811
        int32_t len = strlen(pDb->name) + 1;
3812
        if ((code = taosHashPut(newUser.readDbs, pDb->name, len, pDb->name, TSDB_DB_FNAME_LEN)) != 0) {
3813
          sdbRelease(pSdb, pDb);
3814
          sdbCancelFetch(pSdb, pIter);
3815
          TAOS_CHECK_GOTO(code, &lino, _OVER);
3816
        }
3817
        sdbRelease(pSdb, pDb);
3818
      }
3819
    }
3820
  }
3821

3822
  if (ALTER_USER_ADD_WRITE_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName) ||
3823
      ALTER_USER_ADD_ALL_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName)) {
3824
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
3825
      int32_t len = strlen(pAlterReq->objname) + 1;
3826
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
3827
      if (pDb == NULL) {
3828
        mndReleaseDb(pMnode, pDb);
3829
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
3830
      }
3831
      if ((code = taosHashPut(newUser.writeDbs, pAlterReq->objname, len, pAlterReq->objname, TSDB_DB_FNAME_LEN)) !=
3832
          0) {
3833
        mndReleaseDb(pMnode, pDb);
3834
        TAOS_CHECK_GOTO(code, &lino, _OVER);
3835
      }
3836
      mndReleaseDb(pMnode, pDb);
3837
    } else {
3838
      void   *pIter = NULL;
3839
      while (1) {
3840
        SDbObj *pDb = NULL;
3841
        pIter = sdbFetch(pSdb, SDB_DB, pIter, (void **)&pDb);
3842
        if (pIter == NULL) break;
3843
        int32_t len = strlen(pDb->name) + 1;
3844
        if ((code = taosHashPut(newUser.writeDbs, pDb->name, len, pDb->name, TSDB_DB_FNAME_LEN)) != 0) {
3845
          sdbRelease(pSdb, pDb);
3846
          sdbCancelFetch(pSdb, pIter);
3847
          TAOS_CHECK_GOTO(code, &lino, _OVER);
3848
        }
3849
        sdbRelease(pSdb, pDb);
3850
      }
3851
    }
3852
  }
3853

3854
  if (ALTER_USER_DEL_READ_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName) ||
3855
      ALTER_USER_DEL_ALL_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName)) {
3856
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
3857
      int32_t len = strlen(pAlterReq->objname) + 1;
3858
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
3859
      if (pDb == NULL) {
3860
        mndReleaseDb(pMnode, pDb);
3861
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
3862
      }
3863
      code = taosHashRemove(newUser.readDbs, pAlterReq->objname, len);
3864
      if (code < 0) {
3865
        mError("read db:%s, failed to remove db:%s since %s", newUser.user, pAlterReq->objname, terrstr());
3866
      }
3867
      mndReleaseDb(pMnode, pDb);
3868
    } else {
3869
      taosHashClear(newUser.readDbs);
3870
    }
3871
  }
3872

3873
  if (ALTER_USER_DEL_WRITE_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName) ||
3874
      ALTER_USER_DEL_ALL_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName)) {
3875
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
3876
      int32_t len = strlen(pAlterReq->objname) + 1;
3877
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
3878
      if (pDb == NULL) {
3879
        mndReleaseDb(pMnode, pDb);
3880
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
3881
      }
3882
      code = taosHashRemove(newUser.writeDbs, pAlterReq->objname, len);
3883
      if (code < 0) {
3884
        mError("user:%s, failed to remove db:%s since %s", newUser.user, pAlterReq->objname, terrstr());
3885
      }
3886
      mndReleaseDb(pMnode, pDb);
3887
    } else {
3888
      taosHashClear(newUser.writeDbs);
3889
    }
3890
  }
3891

3892
  SHashObj *pReadTbs = newUser.readTbs;
3893
  SHashObj *pWriteTbs = newUser.writeTbs;
3894
  SHashObj *pAlterTbs = newUser.alterTbs;
3895

3896
#ifdef TD_ENTERPRISE
3897
  if (pAlterReq->isView) {
3898
    pReadTbs = newUser.readViews;
3899
    pWriteTbs = newUser.writeViews;
3900
    pAlterTbs = newUser.alterViews;
3901
  }
3902
#endif
3903

3904
  if (ALTER_USER_ADD_READ_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3905
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3906
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pReadTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3907
  }
3908

3909
  if (ALTER_USER_ADD_WRITE_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3910
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3911
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pWriteTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3912
  }
3913

3914
  if (ALTER_USER_ADD_ALTER_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3915
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3916
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pAlterTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3917
  }
3918

3919
  if (ALTER_USER_DEL_READ_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3920
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3921
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pReadTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3922
  }
3923

3924
  if (ALTER_USER_DEL_WRITE_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3925
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3926
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pWriteTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3927
  }
3928

3929
  if (ALTER_USER_DEL_ALTER_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3930
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3931
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pAlterTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3932
  }
3933
#endif
3934

3935
#if 0
3936
// #ifdef USE_TOPIC
3937
  if (ALTER_USER_ADD_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, &pAlterReq->privileges)) {
3938
    int32_t      len = strlen(pAlterReq->objname) + 1;
3939
    SMqTopicObj *pTopic = NULL;
3940
    if ((code = mndAcquireTopic(pMnode, pAlterReq->objname, &pTopic)) != 0) {
3941
      TAOS_CHECK_GOTO(code, &lino, _OVER);
3942
    }
3943
    taosRLockLatch(&pTopic->lock);
3944
    code = taosHashPut(newUser.topics, pTopic->name, len, pTopic->name, TSDB_TOPIC_FNAME_LEN);
3945
    taosRUnLockLatch(&pTopic->lock);
3946
    mndReleaseTopic(pMnode, pTopic);
3947
    TAOS_CHECK_GOTO(code, &lino, _OVER);
3948
  }
3949

3950
  if (ALTER_USER_DEL_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, &pAlterReq->privileges)) {
3951
    int32_t      len = strlen(pAlterReq->objname) + 1;
3952
    SMqTopicObj *pTopic = NULL;
3953
    if ((code = mndAcquireTopic(pMnode, pAlterReq->objname, &pTopic)) != 0) {
3954
      TAOS_CHECK_GOTO(code, &lino, _OVER);
3955
    }
3956
    taosRLockLatch(&pTopic->lock);
3957
    code = taosHashRemove(newUser.topics, pAlterReq->objname, len);
3958
    if (code < 0) {
3959
      mError("user:%s, failed to remove topic:%s since %s", newUser.user, pAlterReq->objname, tstrerror(code));
3960
    }
3961
    taosRUnLockLatch(&pTopic->lock);
3962
    mndReleaseTopic(pMnode, pTopic);
3963
  }
3964
#endif
3965

3966
  TAOS_CHECK_GOTO(mndAlterUser(pMnode, &newUser, pReq), &lino, _OVER);
3967
  code = TSDB_CODE_ACTION_IN_PROGRESS;
3968

3969
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
3970
    int64_t tse = taosGetTimestampMs();
3971
    double  duration = (double)(tse - tss);
3972
    duration = duration / 1000;
3973
    if (ALTER_USER_ADD_READ_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3974
              ALTER_USER_ADD_WRITE_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3975
              ALTER_USER_ADD_ALL_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3976
              ALTER_USER_ADD_READ_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3977
              ALTER_USER_ADD_WRITE_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3978
              ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3979
      if (strcmp(pAlterReq->objname, "1.*") != 0) {
3980
        SName name = {0};
3981
        TAOS_CHECK_GOTO(tNameFromString(&name, pAlterReq->objname, T_NAME_ACCT | T_NAME_DB), &lino, _OVER);
3982
        auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", name.dbname, pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
3983
      } else {
3984
        auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", "", pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
3985
      }
3986
    } else if (ALTER_USER_ADD_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, pAlterReq->privileges)) {
3987
      auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", pAlterReq->objname, pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
3988
    } else if (ALTER_USER_DEL_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, pAlterReq->privileges)) {
3989
      auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", pAlterReq->objname, pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
3990
    } else {
3991
      if (strcmp(pAlterReq->objname, "1.*") != 0) {
3992
        SName name = {0};
3993
        TAOS_CHECK_GOTO(tNameFromString(&name, pAlterReq->objname, T_NAME_ACCT | T_NAME_DB), &lino, _OVER);
3994
        auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", name.dbname, pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
3995
      } else {
3996
        auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", "", pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
3997
      }
3998
    }
3999
  }
4000
  
4001
_OVER:
4002
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
4003
    mError("user:%s, failed to alter user privileges at line %d since %s", pAlterReq->user, lino, tstrerror(code));
4004
  }
4005
  mndReleaseUser(pMnode, pUser);
4006
  mndUserFreeObj(&newUser);
4007
  TAOS_RETURN(code);
4008
}
4009
#endif
4010

4011
int32_t mndAlterUserFromRole(SRpcMsg *pReq, SUserObj *pOperUser, SAlterRoleReq *pAlterReq) {
1,370,786✔
4012
  SMnode   *pMnode = pReq->info.node;
1,370,786✔
4013
  SSdb     *pSdb = pMnode->pSdb;
1,370,786✔
4014
  void     *pIter = NULL;
1,370,786✔
4015
  int32_t   code = 0, lino = 0;
1,370,786✔
4016
  SUserObj *pUser = NULL;
1,370,786✔
4017
  SUserObj  newUser = {0};
1,370,786✔
4018

4019
  TAOS_CHECK_EXIT(mndAcquireUser(pMnode, pAlterReq->principal, &pUser));
1,370,786✔
4020

4021
  if (pUser->enable == 0) {
1,367,732✔
4022
    TAOS_CHECK_EXIT(TSDB_CODE_MND_USER_DISABLED);
×
4023
  }
4024
  if(pUser->superUser) {
1,367,732✔
4025
    TAOS_CHECK_EXIT(TSDB_CODE_MND_NO_RIGHTS);
2,447✔
4026
  }
4027

4028
  if (pAlterReq->alterType == TSDB_ALTER_ROLE_PRIVILEGES) {
1,365,285✔
4029
#ifdef TD_ENTERPRISE
4030
    TAOS_CHECK_EXIT(mndUserDupObj(pUser, &newUser));
1,353,900✔
4031
    if ((code = mndAlterUserPrivInfo(pMnode, &newUser, pAlterReq)) == TSDB_CODE_QRY_DUPLICATED_OPERATION) {
1,353,900✔
4032
      code = 0;
×
4033
      goto _exit;
×
4034
    } else {
4035
      TAOS_CHECK_EXIT(code);
1,353,900✔
4036
    }
4037
  } else if (pAlterReq->alterType == TSDB_ALTER_ROLE_ROLE) {
11,385✔
4038
    if ((code = mndAlterUserRoleInfo(pMnode, pOperUser, RPC_MSG_TOKEN(pReq), pUser, &newUser, pAlterReq)) ==
11,385✔
4039
        TSDB_CODE_QRY_DUPLICATED_OPERATION) {
4040
      code = 0;
156✔
4041
      goto _exit;
156✔
4042
    } else {
4043
      TAOS_CHECK_EXIT(code);
11,229✔
4044
    }
4045
#endif
4046
  } else {
4047
    TAOS_CHECK_EXIT(TSDB_CODE_INVALID_MSG);
×
4048
  }
4049
  code = mndAlterUser(pMnode, &newUser, pReq);
1,360,730✔
4050
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
1,360,730✔
4051

4052
_exit:
1,370,786✔
4053
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
1,370,786✔
4054
    mError("user:%s, failed to alter user at line %d since %s", pAlterReq->principal, lino, tstrerror(code));
9,900✔
4055
  }
4056
  mndReleaseUser(pMnode, pUser);
1,370,786✔
4057
  mndUserFreeObj(&newUser);
1,370,786✔
4058
  TAOS_RETURN(code);
1,370,786✔
4059
}
4060

4061
static int32_t mndProcessAlterUserBasicInfoReq(SRpcMsg *pReq, SAlterUserReq *pAlterReq) {
48,563✔
4062
  SMnode   *pMnode = pReq->info.node;
48,563✔
4063
  int32_t   code = 0, lino = 0;
48,563✔
4064
  SUserObj *pUser = NULL;
48,563✔
4065
  SUserObj  newUser = {0};
48,563✔
4066
  char      auditLog[1000] = {0};
48,563✔
4067
  int32_t   auditLen = 0;
48,563✔
4068
  int64_t   tss = taosGetTimestampMs();
48,563✔
4069

4070
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, pAlterReq->user, &pUser), &lino, _OVER);
48,563✔
4071
  TAOS_CHECK_GOTO(mndCheckAlterUserPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser, pAlterReq), &lino,
47,680✔
4072
                  _OVER);
4073
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
45,617✔
4074

4075
  if (pAlterReq->hasPassword) {
45,617✔
4076
    auditLen += snprintf(auditLog, sizeof(auditLog), "password,");
32,126✔
4077

4078
    TAOS_CHECK_GOTO(mndCheckPasswordFmt(pAlterReq->pass), &lino, _OVER);
32,126✔
4079
    if (newUser.salt[0] == 0) {
21,908✔
4080
      generateSalt(newUser.salt, sizeof(newUser.salt));
184✔
4081
    }
4082
    char pass[TSDB_PASSWORD_LEN] = {0};
21,908✔
4083
    taosEncryptPass_c((uint8_t *)pAlterReq->pass, strlen(pAlterReq->pass), pass);
21,908✔
4084
    pass[sizeof(pass) - 1] = 0;
21,908✔
4085
    TAOS_CHECK_GOTO(mndEncryptPass(pass, newUser.salt, &newUser.passEncryptAlgorithm), &lino, _OVER);
21,908✔
4086

4087
    if (newUser.passwordReuseMax > 0 || newUser.passwordReuseTime > 0) {
21,908✔
4088
      for (int32_t i = 0; i < newUser.numOfPasswords; ++i) {
772,272✔
4089
        if (0 == strncmp(newUser.passwords[i].pass, pass, TSDB_PASSWORD_LEN)) {
757,152✔
4090
          TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_PASSWORD_REUSE, &lino, _OVER);
432✔
4091
        }
4092
      }
4093
      SUserPassword *passwords = taosMemoryCalloc(newUser.numOfPasswords + 1, sizeof(SUserPassword));
15,120✔
4094
      if (passwords == NULL) {
15,120✔
4095
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
4096
      }
4097
      memcpy(passwords + 1, newUser.passwords, newUser.numOfPasswords * sizeof(SUserPassword));
15,120✔
4098
      memcpy(passwords[0].pass, pass, TSDB_PASSWORD_LEN);
15,120✔
4099
      passwords[0].setTime = taosGetTimestampSec();
15,120✔
4100
      taosMemoryFree(newUser.passwords);
15,120✔
4101
      newUser.passwords = passwords;
15,120✔
4102
      ++newUser.numOfPasswords;
15,120✔
4103
      ++newUser.passVersion;
15,120✔
4104
      newUser.changePass = 2;
15,120✔
4105
    } else if (0 != strncmp(newUser.passwords[0].pass, pass, TSDB_PASSWORD_LEN)) {
6,356✔
4106
      memcpy(newUser.passwords[0].pass, pass, TSDB_PASSWORD_LEN);
6,163✔
4107
      newUser.passwords[0].setTime = taosGetTimestampSec();
6,163✔
4108
      ++newUser.passVersion;
6,163✔
4109
      newUser.changePass = 2;
6,163✔
4110
    }
4111
  }
4112

4113
  if (pAlterReq->hasTotpseed) {
34,967✔
4114
    auditLen += snprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "totpseed,");
×
4115

4116
    if (pAlterReq->totpseed[0] == 0) {  // clear totp secret
×
4117
      memset(newUser.totpsecret, 0, sizeof(newUser.totpsecret));
×
4118
    } else if (taosGenerateTotpSecret(pAlterReq->totpseed, 0, newUser.totpsecret, sizeof(newUser.totpsecret)) < 0) {
×
4119
      TAOS_CHECK_GOTO(TSDB_CODE_PAR_INVALID_OPTION_VALUE, &lino, _OVER);
×
4120
    }
4121
  }
4122

4123
  if (pAlterReq->hasEnable) {
34,967✔
4124
    auditLen += snprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "enable:%d,", pAlterReq->enable);
1,646✔
4125

4126
    newUser.enable = pAlterReq->enable;  // lock or unlock user manually
1,646✔
4127
    if (newUser.enable) {
1,646✔
4128
      // reset login info to allow login immediately
4129
      userCacheResetLoginInfo(newUser.user);
993✔
4130
    }
4131
  }
4132

4133
  if (pAlterReq->hasSysinfo) {
34,967✔
4134
    auditLen += snprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "sysinfo:%d,", pAlterReq->sysinfo);
4,223✔
4135
    newUser.sysInfo = pAlterReq->sysinfo;
4,223✔
4136
  }
4137

4138
  if (pAlterReq->hasCreatedb) {
34,967✔
4139
    auditLen += snprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "createdb:%d,", pAlterReq->createdb);
5,418✔
4140
    newUser.createdb = pAlterReq->createdb;
5,418✔
4141
    if (newUser.createdb == 1) {
5,418✔
4142
      privAddType(&newUser.sysPrivs, PRIV_DB_CREATE);
4143
    } else {
4144
      privRemoveType(&newUser.sysPrivs, PRIV_DB_CREATE);
4145
    }
4146
  }
4147

4148
#ifdef TD_ENTERPRISE
4149
  if (pAlterReq->hasChangepass) {
34,967✔
4150
    auditLen += snprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "changepass:%d,", pAlterReq->changepass);
×
4151
    newUser.changePass = pAlterReq->changepass;
×
4152
  }
4153

4154
  if (pAlterReq->hasSessionPerUser) {
34,967✔
4155
    auditLen +=
288✔
4156
        tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "sessionPerUser:%d,", pAlterReq->sessionPerUser);
288✔
4157
    newUser.sessionPerUser = pAlterReq->sessionPerUser;
288✔
4158
  }
4159

4160
  if (pAlterReq->hasConnectTime) {
34,967✔
4161
    auditLen += snprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "connectTime:%d,", pAlterReq->connectTime);
144✔
4162
    newUser.connectTime = pAlterReq->connectTime;
144✔
4163
  }
4164

4165
  if (pAlterReq->hasConnectIdleTime) {
34,967✔
4166
    auditLen +=
144✔
4167
        tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "connectIdleTime:%d,", pAlterReq->connectIdleTime);
144✔
4168
    newUser.connectIdleTime = pAlterReq->connectIdleTime;
144✔
4169
  }
4170

4171
  if (pAlterReq->hasCallPerSession) {
34,967✔
4172
    auditLen +=
432✔
4173
        tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "callPerSession:%d,", pAlterReq->callPerSession);
432✔
4174
    newUser.callPerSession = pAlterReq->callPerSession;
432✔
4175
  }
4176

4177
  if (pAlterReq->hasVnodePerCall) {
34,967✔
4178
    auditLen +=
288✔
4179
        tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "vnodePerCall:%d,", pAlterReq->vnodePerCall);
288✔
4180
    newUser.vnodePerCall = pAlterReq->vnodePerCall;
288✔
4181
  }
4182

4183
  if (pAlterReq->hasFailedLoginAttempts) {
34,967✔
4184
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "failedLoginAttempts:%d,",
432✔
4185
                          pAlterReq->failedLoginAttempts);
4186
    newUser.failedLoginAttempts = pAlterReq->failedLoginAttempts;
432✔
4187
  }
4188

4189
  if (pAlterReq->hasPasswordLifeTime) {
34,967✔
4190
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordLifeTime:%d,",
144✔
4191
                          pAlterReq->passwordLifeTime);
4192
    newUser.passwordLifeTime = pAlterReq->passwordLifeTime;
144✔
4193
  }
4194

4195
  if (pAlterReq->hasPasswordReuseTime) {
34,967✔
4196
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordReuseTime:%d,",
432✔
4197
                          pAlterReq->passwordReuseTime);
4198
    newUser.passwordReuseTime = pAlterReq->passwordReuseTime;
432✔
4199
  }
4200

4201
  if (pAlterReq->hasPasswordReuseMax) {
34,967✔
4202
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordReuseMax:%d,",
432✔
4203
                          pAlterReq->passwordReuseMax);
4204
    newUser.passwordReuseMax = pAlterReq->passwordReuseMax;
432✔
4205
  }
4206

4207
  if (pAlterReq->hasPasswordLockTime) {
34,967✔
4208
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordLockTime:%d,",
144✔
4209
                          pAlterReq->passwordLockTime);
4210
    newUser.passwordLockTime = pAlterReq->passwordLockTime;
144✔
4211
  }
4212

4213
  if (pAlterReq->hasPasswordGraceTime) {
34,967✔
4214
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordGraceTime:%d,",
144✔
4215
                          pAlterReq->passwordGraceTime);
4216
    newUser.passwordGraceTime = pAlterReq->passwordGraceTime;
144✔
4217
  }
4218

4219
  if (pAlterReq->hasInactiveAccountTime) {
34,967✔
4220
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "inactiveAccountTime:%d,",
144✔
4221
                          pAlterReq->inactiveAccountTime);
4222
    newUser.inactiveAccountTime = pAlterReq->inactiveAccountTime;
144✔
4223
  }
4224

4225
  if (pAlterReq->hasAllowTokenNum) {
34,967✔
4226
    auditLen +=
288✔
4227
        tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "allowTokenNum:%d,", pAlterReq->allowTokenNum);
288✔
4228
    newUser.allowTokenNum = pAlterReq->allowTokenNum;
288✔
4229
  }
4230

4231
  if (pAlterReq->numDropIpRanges > 0 || pAlterReq->numIpRanges > 0) {
34,967✔
4232
    int32_t dummy = 0;
620✔
4233

4234
    // put previous ip whitelist into hash table
4235
    SHashObj *m = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
620✔
4236
    if (m == NULL) {
620✔
4237
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
4238
    }
4239

4240
    for (int32_t i = 0; i < newUser.pIpWhiteListDual->num; i++) {
2,646✔
4241
      SIpRange range;
2,026✔
4242
      copyIpRange(&range, newUser.pIpWhiteListDual->pIpRanges + i);
2,026✔
4243
      code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
2,026✔
4244
      if (code != 0) {
2,026✔
4245
        taosHashCleanup(m);
×
4246
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
4247
      }
4248
    }
4249

4250
    if (pAlterReq->numDropIpRanges > 0) {
620✔
4251
      auditLen +=
310✔
4252
          tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "dropIpRanges:%d,", pAlterReq->numDropIpRanges);
310✔
4253

4254
      for (int32_t i = 0; i < pAlterReq->numDropIpRanges; i++) {
764✔
4255
        if (taosHashGetSize(m) == 0) {
454✔
4256
          break;
×
4257
        }
4258

4259
        SIpRange range;
454✔
4260
        copyIpRange(&range, pAlterReq->pDropIpRanges + i);
454✔
4261

4262
        // for white list, drop default ip ranges is allowed, otherwise, we can never
4263
        // convert white list to black list.
4264

4265
        code = taosHashRemove(m, &range, sizeof(range));
454✔
4266
        if (code == TSDB_CODE_NOT_FOUND) {
454✔
4267
          // treat not exist as success
4268
          code = 0;
166✔
4269
        }
4270
        if (code != 0) {
454✔
4271
          taosHashCleanup(m);
×
4272
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
4273
        }
4274
      }
4275
    }
4276

4277
    if (pAlterReq->numIpRanges > 0) {
620✔
4278
      auditLen +=
310✔
4279
          tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "addIpRanges:%d,", pAlterReq->numIpRanges);
310✔
4280
      for (int32_t i = 0; i < pAlterReq->numIpRanges; i++) {
764✔
4281
        SIpRange range;
454✔
4282
        copyIpRange(&range, pAlterReq->pIpRanges + i);
454✔
4283
        code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
454✔
4284
        if (code != 0) {
454✔
4285
          taosHashCleanup(m);
×
4286
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
4287
        }
4288
      }
4289
    }
4290

4291
    int32_t numOfRanges = taosHashGetSize(m);
620✔
4292
    if (numOfRanges > MND_MAX_USER_IP_RANGE) {
620✔
4293
      taosHashCleanup(m);
×
4294
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_IP_RANGE, &lino, _OVER);
×
4295
    }
4296

4297
    SIpWhiteListDual *p = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + numOfRanges * sizeof(SIpRange));
620✔
4298
    if (p == NULL) {
620✔
4299
      taosHashCleanup(m);
×
4300
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
4301
    }
4302

4303
    void   *pIter = taosHashIterate(m, NULL);
620✔
4304
    int32_t i = 0;
620✔
4305
    while (pIter) {
2,812✔
4306
      size_t    len = 0;
2,192✔
4307
      SIpRange *key = taosHashGetKey(pIter, &len);
2,192✔
4308
      memcpy(p->pIpRanges + i, key, sizeof(SIpRange));
2,192✔
4309
      pIter = taosHashIterate(m, pIter);
2,192✔
4310
      i++;
2,192✔
4311
    }
4312

4313
    taosHashCleanup(m);
620✔
4314
    p->num = numOfRanges;
620✔
4315
    taosMemoryFreeClear(newUser.pIpWhiteListDual);
620✔
4316
    sortIpWhiteList(p);
620✔
4317
    newUser.pIpWhiteListDual = p;
620✔
4318

4319
    newUser.ipWhiteListVer++;
620✔
4320
  }
4321

4322
  if (pAlterReq->numTimeRanges > 0 || pAlterReq->numDropTimeRanges) {
34,967✔
4323
    int32_t dummy = 0;
576✔
4324

4325
    // put previous ip whitelist into hash table
4326
    SHashObj *m = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
576✔
4327
    if (m == NULL) {
576✔
4328
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
4329
    }
4330

4331
    for (int32_t i = 0; i < newUser.pTimeWhiteList->num; i++) {
1,440✔
4332
      SDateTimeWhiteListItem *range = &newUser.pTimeWhiteList->ranges[i];
864✔
4333
      if (isDateTimeWhiteListItemExpired(range)) {
864✔
4334
        continue;
×
4335
      }
4336
      code = taosHashPut(m, range, sizeof(*range), &dummy, sizeof(dummy));
864✔
4337
      if (code != 0) {
864✔
4338
        taosHashCleanup(m);
×
4339
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
4340
      }
4341
    }
4342

4343
    if (pAlterReq->numDropTimeRanges > 0) {
576✔
4344
      auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "dropTimeRanges:%d,",
432✔
4345
                            pAlterReq->numDropTimeRanges);
4346
      for (int32_t i = 0; i < pAlterReq->numDropTimeRanges; i++) {
1,008✔
4347
        if (taosHashGetSize(m) == 0) {
576✔
4348
          break;
×
4349
        }
4350
        SDateTimeWhiteListItem range = {0};
576✔
4351
        DateTimeRangeToWhiteListItem(&range, pAlterReq->pDropTimeRanges + i);
576✔
4352

4353
        code = taosHashRemove(m, &range, sizeof(range));
576✔
4354
        if (code == TSDB_CODE_NOT_FOUND) {
576✔
4355
          // treat not exist as success
4356
          code = 0;
×
4357
        }
4358
        if (code != 0) {
576✔
4359
          taosHashCleanup(m);
×
4360
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
4361
        }
4362
      }
4363
    }
4364

4365
    if (pAlterReq->numTimeRanges > 0) {
576✔
4366
      auditLen +=
432✔
4367
          tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "addTimeRanges:%d,", pAlterReq->numTimeRanges);
432✔
4368
      for (int32_t i = 0; i < pAlterReq->numTimeRanges; i++) {
1,008✔
4369
        SDateTimeWhiteListItem range = {0};
576✔
4370
        DateTimeRangeToWhiteListItem(&range, pAlterReq->pTimeRanges + i);
576✔
4371
        if (isDateTimeWhiteListItemExpired(&range)) {
576✔
4372
          continue;
×
4373
        }
4374
        code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
576✔
4375
        if (code != 0) {
576✔
4376
          taosHashCleanup(m);
×
4377
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
4378
        }
4379
      }
4380
    }
4381

4382
    int32_t numOfRanges = taosHashGetSize(m);
576✔
4383
    if (numOfRanges > MND_MAX_USER_TIME_RANGE) {
576✔
4384
      taosHashCleanup(m);
×
4385
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_TIME_RANGE, &lino, _OVER);
×
4386
    }
4387

4388
    SDateTimeWhiteList *p =
1,152✔
4389
        taosMemoryCalloc(1, sizeof(SDateTimeWhiteList) + numOfRanges * sizeof(SDateTimeWhiteListItem));
576✔
4390
    if (p == NULL) {
576✔
4391
      taosHashCleanup(m);
×
4392
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
4393
    }
4394

4395
    void   *pIter = taosHashIterate(m, NULL);
576✔
4396
    int32_t i = 0;
576✔
4397
    while (pIter) {
1,440✔
4398
      size_t                  len = 0;
864✔
4399
      SDateTimeWhiteListItem *key = taosHashGetKey(pIter, &len);
864✔
4400
      memcpy(&p->ranges[i], key, sizeof(SDateTimeWhiteListItem));
864✔
4401
      pIter = taosHashIterate(m, pIter);
864✔
4402
      i++;
864✔
4403
    }
4404

4405
    taosHashCleanup(m);
576✔
4406
    p->num = numOfRanges;
576✔
4407
    taosMemoryFreeClear(newUser.pTimeWhiteList);
576✔
4408
    sortTimeWhiteList(p);
576✔
4409
    newUser.pTimeWhiteList = p;
576✔
4410
    newUser.timeWhiteListVer++;
576✔
4411
  }
4412
#endif  // TD_ENTERPRISE
4413

4414
  TAOS_CHECK_GOTO(mndAlterUser(pMnode, &newUser, pReq), &lino, _OVER);
34,967✔
4415
  if (pAlterReq->hasEnable) {
34,967✔
4416
    if (newUser.enable) {
1,646✔
4417
      if (taosHashGet(newUser.roles, TSDB_ROLE_SYSAUDIT_LOG, strlen(TSDB_ROLE_SYSAUDIT_LOG) + 1)) {
993✔
4418
        (void)mndResetAuditLogUser(pMnode, newUser.user, true);
×
4419
      }
4420
    } else {
4421
      (void)mndResetAuditLogUser(pMnode, newUser.user, false);
653✔
4422
    }
4423
  }
4424
  code = TSDB_CODE_ACTION_IN_PROGRESS;
34,967✔
4425

4426
  if (auditLen > 0) {
34,967✔
4427
    auditLog[--auditLen] = 0;  // remove last ','
34,967✔
4428
  }
4429
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
34,967✔
4430
    int64_t tse = taosGetTimestampMs();
34,967✔
4431
    double  duration = (double)(tse - tss);
34,967✔
4432
    duration = duration / 1000;
34,967✔
4433
    auditRecord(pReq, pMnode->clusterId, "alterUser", "", pAlterReq->user, auditLog, auditLen, duration, 0);
34,967✔
4434
  }
4435

4436
_OVER:
48,563✔
4437
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
48,563✔
4438
    mError("user:%s, failed to alter at line %d since %s", pAlterReq->user, lino, tstrerror(code));
13,596✔
4439
  }
4440

4441
  mndReleaseUser(pMnode, pUser);
48,563✔
4442
  mndUserFreeObj(&newUser);
48,563✔
4443
  return code;
48,563✔
4444
}
4445

4446
static int32_t mndProcessAlterUserReq(SRpcMsg *pReq) {
48,563✔
4447
  SAlterUserReq alterReq = {0};
48,563✔
4448

4449
  int32_t code = tDeserializeSAlterUserReq(pReq->pCont, pReq->contLen, &alterReq);
48,563✔
4450
  if (code != 0) {
48,563✔
4451
    mError("failed to deserialize alter user request at line %d since %s", __LINE__, tstrerror(code));
×
4452
    TAOS_RETURN(code);
×
4453
  }
4454

4455
  if (alterReq.user[0] == 0) {
48,563✔
4456
    tFreeSAlterUserReq(&alterReq);
×
4457
    mError("failed to alter user at line %d since invalid user format", __LINE__);
×
4458
    TAOS_RETURN(TSDB_CODE_MND_INVALID_USER_FORMAT);
×
4459
  }
4460

4461
  mInfo("user:%s, start to alter", alterReq.user);
48,563✔
4462
  if (alterReq.alterType == TSDB_ALTER_USER_BASIC_INFO) {
48,563✔
4463
    code = mndProcessAlterUserBasicInfoReq(pReq, &alterReq);
48,563✔
4464
  } else {
4465
    // code = mndProcessAlterUserPrivilegesReq(pReq, &alterReq); // obsolete
4466
  }
4467

4468
  tFreeSAlterUserReq(&alterReq);
48,563✔
4469
  TAOS_RETURN(code);
48,563✔
4470
}
4471

4472
int32_t mndResetAuditLogUser(SMnode *pMnode, const char *user, bool isAdd) {
48,241,566✔
4473
  if (user) {
48,241,566✔
4474
    (void)taosThreadRwlockRdlock(&userCache.rw);
46,867✔
4475
    if (isAdd) {
46,867✔
4476
      if (userCache.auditLogUser[0] != 0) {
65✔
4477
        (void)taosThreadRwlockUnlock(&userCache.rw);
×
4478
        return 0;
×
4479
      }
4480
      (void)taosThreadRwlockUnlock(&userCache.rw);
65✔
4481
      (void)taosThreadRwlockWrlock(&userCache.rw);
65✔
4482
      (void)tsnprintf(userCache.auditLogUser, TSDB_USER_LEN, "%s", user);
65✔
4483
      (void)taosThreadRwlockUnlock(&userCache.rw);
65✔
4484
      return 0;
65✔
4485
    } else if (strcmp(userCache.auditLogUser, user) != 0) {
46,802✔
4486
      (void)taosThreadRwlockUnlock(&userCache.rw);
46,802✔
4487
      return 0;
46,802✔
4488
    }
4489
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
4490
  }
4491

4492
  void     *pIter = NULL;
48,194,699✔
4493
  SSdb     *pSdb = pMnode->pSdb;
48,194,699✔
4494
  SUserObj *pUser = NULL;
48,194,699✔
4495
  int32_t   len = strlen(TSDB_ROLE_SYSAUDIT_LOG) + 1;
48,194,699✔
4496
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser))) {
102,185,436✔
4497
    if (pUser->enable == 0) {
53,990,737✔
4498
      mndReleaseUser(pMnode, pUser);
18,368✔
4499
      continue;
18,368✔
4500
    }
4501
    if (taosHashGet(pUser->roles, TSDB_ROLE_SYSAUDIT_LOG, len) != NULL) {
53,972,369✔
4502
      (void)taosThreadRwlockWrlock(&userCache.rw);
×
4503
      (void)tsnprintf(userCache.auditLogUser, TSDB_USER_LEN, "%s", pUser->name);
×
4504
      (void)taosThreadRwlockUnlock(&userCache.rw);
×
4505
      sdbCancelFetch(pSdb, pIter);
×
4506
      mndReleaseUser(pMnode, pUser);
×
4507
      return 0;
×
4508
    }
4509
    mndReleaseUser(pMnode, pUser);
53,972,369✔
4510
  }
4511
  (void)taosThreadRwlockWrlock(&userCache.rw);
48,194,699✔
4512
  userCache.auditLogUser[0] = 0;
48,194,699✔
4513
  (void)taosThreadRwlockUnlock(&userCache.rw);
48,194,699✔
4514
  return TSDB_CODE_MND_USER_NOT_AVAILABLE;
48,194,699✔
4515
}
4516

4517
int32_t mndGetAuditUser(SMnode *pMnode, char *user) {
48,195,609✔
4518
  (void)taosThreadRwlockRdlock(&userCache.rw);
48,195,609✔
4519
  if (userCache.auditLogUser[0] != 0) {
48,195,609✔
4520
    (void)tsnprintf(user, TSDB_USER_LEN, "%s", userCache.auditLogUser);
910✔
4521
    (void)taosThreadRwlockUnlock(&userCache.rw);
910✔
4522
    return 0;
910✔
4523
  }
4524
  (void)taosThreadRwlockUnlock(&userCache.rw);
48,194,699✔
4525

4526
  int32_t code = 0;
48,194,699✔
4527
  if ((code = mndResetAuditLogUser(pMnode, NULL, false)) != 0) {
48,194,699✔
4528
    return code;
48,194,699✔
4529
  }
4530

4531
  (void)taosThreadRwlockRdlock(&userCache.rw);
×
4532
  (void)tsnprintf(user, TSDB_USER_LEN, "%s", userCache.auditLogUser);
×
4533
  (void)taosThreadRwlockUnlock(&userCache.rw);
×
4534

4535
  return 0;
×
4536
}
4537

4538
static int32_t mndDropUser(SMnode *pMnode, SRpcMsg *pReq, SUserObj *pUser) {
46,149✔
4539
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "drop-user");
46,149✔
4540
  if (pTrans == NULL) {
46,149✔
4541
    mError("user:%s, failed to drop since %s", pUser->user, terrstr());
×
4542
    TAOS_RETURN(terrno);
×
4543
  }
4544
  mInfo("trans:%d, used to drop user:%s", pTrans->id, pUser->user);
46,149✔
4545

4546
  SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
46,149✔
4547
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
46,149✔
4548
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
4549
    mndTransDrop(pTrans);
×
4550
    TAOS_RETURN(terrno);
×
4551
  }
4552
  if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED) < 0) {
46,149✔
4553
    mndTransDrop(pTrans);
×
4554
    TAOS_RETURN(terrno);
×
4555
  }
4556

4557
  if (mndDropTokensByUser(pMnode, pTrans, pUser->user) != 0) {
46,149✔
4558
    mndTransDrop(pTrans);
×
4559
    TAOS_RETURN(terrno);
×
4560
  }
4561

4562
  if (mndTransPrepare(pMnode, pTrans) != 0) {
46,149✔
4563
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
4564
    mndTransDrop(pTrans);
×
4565
    TAOS_RETURN(terrno);
×
4566
  }
4567

4568
  userCacheRemoveUser(pUser->user);
46,149✔
4569
  mndDropCachedTokensByUser(pUser->user);
46,149✔
4570
  (void)mndResetAuditLogUser(pMnode, pUser->user, false);
46,149✔
4571

4572
  mndTransDrop(pTrans);
46,149✔
4573
  TAOS_RETURN(0);
46,149✔
4574
}
4575

4576
static int32_t mndProcessDropUserReq(SRpcMsg *pReq) {
46,959✔
4577
  SMnode      *pMnode = pReq->info.node;
46,959✔
4578
  int32_t      code = 0;
46,959✔
4579
  int32_t      lino = 0;
46,959✔
4580
  SUserObj    *pOperUser = NULL;
46,959✔
4581
  SUserObj    *pUser = NULL;
46,959✔
4582
  SDropUserReq dropReq = {0};
46,959✔
4583
  int64_t      tss = taosGetTimestampMs();
46,959✔
4584

4585
  TAOS_CHECK_GOTO(tDeserializeSDropUserReq(pReq->pCont, pReq->contLen, &dropReq), &lino, _OVER);
46,959✔
4586

4587
  mInfo("user:%s, start to drop", dropReq.user);
46,959✔
4588

4589
  if (dropReq.user[0] == 0) {
46,959✔
4590
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
4591
  }
4592

4593
  if (0 == strcmp(dropReq.user, TSDB_DEFAULT_USER)) {
46,959✔
4594
    return TSDB_CODE_MND_NO_RIGHTS;
×
4595
  }
4596

4597
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, dropReq.user, &pUser), &lino, _OVER);
46,959✔
4598

4599
  code = mndAcquireUser(pMnode, RPC_MSG_USER(pReq), &pOperUser);
46,149✔
4600
  if (pOperUser == NULL) {
46,149✔
4601
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_USER_FROM_CONN, &lino, _OVER);
×
4602
  }
4603

4604
  // TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, RPC_MSG_USER(pReq), MND_OPER_DROP_USER), &lino, _OVER);
4605
  TAOS_CHECK_GOTO(mndCheckSysObjPrivilege(pMnode, pOperUser, RPC_MSG_TOKEN(pReq), PRIV_USER_DROP, 0, 0, NULL, NULL),
46,149✔
4606
                  &lino, _OVER);
4607

4608
  TAOS_CHECK_GOTO(mndDropUser(pMnode, pReq, pUser), &lino, _OVER);
46,149✔
4609
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
46,149✔
4610

4611
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
46,149✔
4612
    int64_t tse = taosGetTimestampMs();
46,149✔
4613
    double  duration = (double)(tse - tss);
46,149✔
4614
    duration = duration / 1000;
46,149✔
4615
    auditRecord(pReq, pMnode->clusterId, "dropUser", "", dropReq.user, dropReq.sql, dropReq.sqlLen, duration, 0);
46,149✔
4616
  }
4617

4618
_OVER:
46,959✔
4619
  if (dropReq.ignoreNotExists && code == TSDB_CODE_MND_USER_NOT_EXIST) {
46,959✔
4620
    code = 0;
498✔
4621
  } else if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
46,461✔
4622
    mError("user:%s, failed to drop at line %d since %s", dropReq.user, lino, tstrerror(code));
312✔
4623
  }
4624

4625
  mndReleaseUser(pMnode, pUser);
46,959✔
4626
  mndReleaseUser(pMnode, pOperUser);
46,959✔
4627
  tFreeSDropUserReq(&dropReq);
46,959✔
4628
  TAOS_RETURN(code);
46,959✔
4629
}
4630

4631
static int32_t mndProcessGetUserAuthReq(SRpcMsg *pReq) {
6,237,800✔
4632
  SMnode         *pMnode = pReq->info.node;
6,237,800✔
4633
  int32_t         code = 0;
6,237,800✔
4634
  int32_t         lino = 0;
6,237,800✔
4635
  int32_t         contLen = 0;
6,237,800✔
4636
  void           *pRsp = NULL;
6,237,800✔
4637
  SUserObj       *pUser = NULL;
6,237,800✔
4638
  SGetUserAuthReq authReq = {0};
6,237,800✔
4639
  SGetUserAuthRsp authRsp = {0};
6,237,800✔
4640

4641
  TAOS_CHECK_EXIT(tDeserializeSGetUserAuthReq(pReq->pCont, pReq->contLen, &authReq));
6,237,800✔
4642
  mTrace("user:%s, start to get auth", authReq.user);
6,237,800✔
4643

4644
  TAOS_CHECK_EXIT(mndAcquireUser(pMnode, authReq.user, &pUser));
6,237,800✔
4645

4646
  TAOS_CHECK_EXIT(mndSetUserAuthRsp(pMnode, pUser, &authRsp));
6,236,641✔
4647

4648
  contLen = tSerializeSGetUserAuthRsp(NULL, 0, &authRsp);
6,236,641✔
4649
  if (contLen < 0) {
6,236,641✔
4650
    TAOS_CHECK_EXIT(contLen);
×
4651
  }
4652
  pRsp = rpcMallocCont(contLen);
6,236,641✔
4653
  if (pRsp == NULL) {
6,236,641✔
4654
    TAOS_CHECK_EXIT(terrno);
×
4655
  }
4656

4657
  contLen = tSerializeSGetUserAuthRsp(pRsp, contLen, &authRsp);
6,236,641✔
4658
  if (contLen < 0) {
6,236,641✔
4659
    TAOS_CHECK_EXIT(contLen);
×
4660
  }
4661

4662
_exit:
6,237,800✔
4663
  mndReleaseUser(pMnode, pUser);
6,237,800✔
4664
  tFreeSGetUserAuthRsp(&authRsp);
6,237,800✔
4665
  if (code < 0) {
6,237,051✔
4666
    mError("user:%s, failed to get auth at line %d since %s", authReq.user, lino, tstrerror(code));
1,159✔
4667
    rpcFreeCont(pRsp);
1,159✔
4668
    pRsp = NULL;
1,159✔
4669
    contLen = 0;
1,159✔
4670
  }
4671
  pReq->info.rsp = pRsp;
6,237,051✔
4672
  pReq->info.rspLen = contLen;
6,237,800✔
4673
  pReq->code = code;
6,237,051✔
4674

4675
  TAOS_RETURN(code);
6,237,051✔
4676
}
4677

4678
static void base32Encode(const uint8_t *in, int32_t inLen, char *out) {
16,886✔
4679
  int buffer = 0, bits = 0;
16,886✔
4680
  int outLen = 0;
16,886✔
4681

4682
  // process all input bytes
4683
  for (int i = 0; i < inLen; i++) {
557,238✔
4684
    buffer = (buffer << 8) | in[i];
540,352✔
4685
    bits += 8;
540,352✔
4686

4687
    while (bits >= 5) {
1,401,538✔
4688
      int v = (buffer >> (bits - 5)) & 0x1F;
861,186✔
4689
      out[outLen++] = (v >= 26) ? (v - 26 + '2') : (v + 'A');
861,186✔
4690
      bits -= 5;
861,186✔
4691
    }
4692
  }
4693

4694
  // process remaining bits
4695
  if (bits > 0) {
16,886✔
4696
    int v = (buffer << (5 - bits)) & 0x1F;
16,886✔
4697
    out[outLen++] = (v >= 26) ? (v - 26 + '2') : (v + 'A');
16,886✔
4698
  }
4699

4700
  out[outLen] = '\0';
16,886✔
4701
}
16,886✔
4702

4703
static int32_t mndCreateTotpSecret(SMnode *pMnode, SUserObj *pUser, SRpcMsg *pReq) {
16,886✔
4704
  SCreateTotpSecretRsp rsp = {0};
16,886✔
4705

4706
  base32Encode((uint8_t *)pUser->totpsecret, sizeof(pUser->totpsecret), rsp.totpSecret);
16,886✔
4707
  tstrncpy(rsp.user, pUser->user, sizeof(rsp.user));
16,886✔
4708

4709
  int32_t len = tSerializeSCreateTotpSecretRsp(NULL, 0, &rsp);
16,886✔
4710
  if (len < 0) {
16,886✔
4711
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
4712
  }
4713

4714
  void *pData = taosMemoryMalloc(len);
16,886✔
4715
  if (pData == NULL) {
16,886✔
4716
    TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
4717
  }
4718

4719
  if (tSerializeSCreateTotpSecretRsp(pData, len, &rsp) != len) {
16,886✔
4720
    taosMemoryFree(pData);
×
4721
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
4722
  }
4723

4724
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "create-totp-secret");
16,886✔
4725
  if (pTrans == NULL) {
16,886✔
4726
    mError("user:%s, failed to create totp secret since %s", pUser->user, terrstr());
×
4727
    taosMemoryFree(pData);
×
4728
    TAOS_RETURN(terrno);
×
4729
  }
4730
  mInfo("trans:%d, used to create totp secret for user:%s", pTrans->id, pUser->user);
16,886✔
4731

4732
  mndTransSetUserData(pTrans, pData, len);
16,886✔
4733

4734
  SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
16,886✔
4735
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
16,886✔
4736
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
4737
    mndTransDrop(pTrans);
×
4738
    TAOS_RETURN(terrno);
×
4739
  }
4740
  if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY) < 0) {
16,886✔
4741
    mndTransDrop(pTrans);
×
4742
    TAOS_RETURN(terrno);
×
4743
  }
4744

4745
  if (mndTransPrepare(pMnode, pTrans) != 0) {
16,886✔
4746
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
4747
    mndTransDrop(pTrans);
×
4748
    TAOS_RETURN(terrno);
×
4749
  }
4750

4751
  mndTransDrop(pTrans);
16,886✔
4752
  TAOS_RETURN(0);
16,886✔
4753
}
4754

4755
static int32_t mndProcessCreateTotpSecretReq(SRpcMsg *pReq) {
17,042✔
4756
  SMnode              *pMnode = pReq->info.node;
17,042✔
4757
  int32_t              code = 0;
17,042✔
4758
  int32_t              lino = 0;
17,042✔
4759
  SUserObj            *pUser = NULL;
17,042✔
4760
  SUserObj             newUser = {0};
17,042✔
4761
  SCreateTotpSecretReq req = {0};
17,042✔
4762
  int64_t              tss = taosGetTimestampMs();
17,042✔
4763

4764
  TAOS_CHECK_GOTO(tDeserializeSCreateTotpSecretReq(pReq->pCont, pReq->contLen, &req), &lino, _OVER);
17,042✔
4765
  mTrace("user:%s, start to create/update totp secret", req.user);
17,042✔
4766

4767
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, req.user, &pUser), &lino, _OVER);
17,042✔
4768
  TAOS_CHECK_GOTO(mndCheckTotpSecretPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser, PRIV_TOTP_CREATE),
16,886✔
4769
                  &lino, _OVER);
4770
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
16,886✔
4771
  taosSafeRandBytes((uint8_t *)newUser.totpsecret, sizeof(newUser.totpsecret));
16,886✔
4772
  TAOS_CHECK_GOTO(mndCreateTotpSecret(pMnode, &newUser, pReq), &lino, _OVER);
16,886✔
4773

4774
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
16,886✔
4775
    double duration = (double)(taosGetTimestampMs() - tss) / 1000.0;
16,886✔
4776
    auditRecord(pReq, pMnode->clusterId, "createTotpSecret", "", req.user, req.sql, req.sqlLen, duration, 0);
16,886✔
4777
  }
4778

4779
_OVER:
17,042✔
4780
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
17,042✔
4781
    mError("user:%s, failed to create totp secret at line %d since %s", req.user, lino, tstrerror(code));
156✔
4782
  }
4783
  mndReleaseUser(pMnode, pUser);
17,042✔
4784
  mndUserFreeObj(&newUser);
17,042✔
4785
  tFreeSCreateTotpSecretReq(&req);
17,042✔
4786
  TAOS_RETURN(code);
17,042✔
4787
}
4788

4789
int32_t mndBuildSMCreateTotpSecretResp(STrans *pTrans, void **ppResp, int32_t *pRespLen) {
16,886✔
4790
  // user data is the response
4791
  *ppResp = pTrans->userData;
16,886✔
4792
  *pRespLen = pTrans->userDataLen;
16,886✔
4793
  pTrans->userData = NULL;
16,886✔
4794
  pTrans->userDataLen = 0;
16,886✔
4795
  return 0;
16,886✔
4796
}
4797

4798
static int32_t mndProcessDropTotpSecretReq(SRpcMsg *pReq) {
6,552✔
4799
  SMnode            *pMnode = pReq->info.node;
6,552✔
4800
  int32_t            code = 0;
6,552✔
4801
  int32_t            lino = 0;
6,552✔
4802
  SUserObj          *pUser = NULL;
6,552✔
4803
  SUserObj           newUser = {0};
6,552✔
4804
  SDropTotpSecretReq req = {0};
6,552✔
4805
  int64_t            tss = taosGetTimestampMs();
6,552✔
4806

4807
  TAOS_CHECK_GOTO(tDeserializeSDropTotpSecretReq(pReq->pCont, pReq->contLen, &req), &lino, _OVER);
6,552✔
4808
  mTrace("user:%s, start to drop totp secret", req.user);
6,552✔
4809

4810
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, req.user, &pUser), &lino, _OVER);
6,552✔
4811
  TAOS_CHECK_GOTO(mndCheckTotpSecretPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser, PRIV_TOTP_DROP),
4,992✔
4812
                  &lino, _OVER);
4813

4814
  if (!mndIsTotpEnabledUser(pUser)) {
4,992✔
4815
    TAOS_CHECK_GOTO(TSDB_CODE_MND_TOTP_SECRET_NOT_EXIST, &lino, _OVER);
4,680✔
4816
  }
4817

4818
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
312✔
4819
  (void)memset(newUser.totpsecret, 0, sizeof(newUser.totpsecret));
312✔
4820
  TAOS_CHECK_GOTO(mndAlterUser(pMnode, &newUser, pReq), &lino, _OVER);
312✔
4821

4822
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
312✔
4823
    double duration = (double)(taosGetTimestampMs() - tss) / 1000.0;
312✔
4824
    auditRecord(pReq, pMnode->clusterId, "dropTotpSecret", "", req.user, req.sql, req.sqlLen, duration, 0);
312✔
4825
  }
4826

4827
_OVER:
6,552✔
4828
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
6,552✔
4829
    mError("user:%s, failed to drop totp secret at line %d since %s", req.user, lino, tstrerror(code));
6,240✔
4830
  }
4831
  mndReleaseUser(pMnode, pUser);
6,552✔
4832
  mndUserFreeObj(&newUser);
6,552✔
4833
  tFreeSDropTotpSecretReq(&req);
6,552✔
4834
  TAOS_RETURN(code);
6,552✔
4835
}
4836

4837
bool mndIsTotpEnabledUser(SUserObj *pUser) {
4,166,750✔
4838
  for (int32_t i = 0; i < sizeof(pUser->totpsecret); i++) {
135,689,393✔
4839
    if (pUser->totpsecret[i] != 0) {
131,578,888✔
4840
      return true;
54,676✔
4841
    }
4842
  }
4843
  return false;
4,110,505✔
4844
}
4845

4846
static int32_t mndRetrieveUsers(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
118,728✔
4847
  SMnode   *pMnode = pReq->info.node;
118,728✔
4848
  SSdb     *pSdb = pMnode->pSdb;
118,728✔
4849
  int32_t   code = 0;
118,728✔
4850
  int32_t   lino = 0;
118,728✔
4851
  int32_t   numOfRows = 0;
118,728✔
4852
  SUserObj *pUser = NULL;
118,728✔
4853
  int32_t   cols = 0;
118,728✔
4854
  int8_t    flag = 0;
118,728✔
4855
  char     *pWrite = NULL;
118,728✔
4856
  char     *buf = NULL;
118,728✔
4857
  char     *varstr = NULL;
118,728✔
4858
  char      tBuf[TSDB_MAX_SUBROLE * TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
118,728✔
4859
  int32_t   bufSize = sizeof(tBuf) - VARSTR_HEADER_SIZE;
118,728✔
4860

4861
  while (numOfRows < rows) {
1,039,612✔
4862
    pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
1,039,612✔
4863
    if (pShow->pIter == NULL) break;
1,039,612✔
4864

4865
    cols = 0;
920,884✔
4866
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
920,884✔
4867
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
920,884✔
4868
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
920,884✔
4869
    COL_DATA_SET_VAL_GOTO((const char *)name, false, pUser, pShow->pIter, _exit);
920,884✔
4870

4871
    cols++;
920,884✔
4872
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
920,884✔
4873
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->superUser, false, pUser, pShow->pIter, _exit);
920,884✔
4874

4875
    cols++;
920,884✔
4876
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
920,884✔
4877
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->enable, false, pUser, pShow->pIter, _exit);
920,884✔
4878

4879
    cols++;
920,884✔
4880
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
920,884✔
4881
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sysInfo, false, pUser, pShow->pIter, _exit);
920,884✔
4882

4883
    cols++;
920,884✔
4884
    flag = pUser->createdb ? 1 : 0;
920,884✔
4885
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
920,884✔
4886
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
920,884✔
4887

4888
    cols++;
920,884✔
4889
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
920,884✔
4890
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->createdTime, false, pUser, pShow->pIter, _exit);
920,884✔
4891

4892
    cols++;
920,884✔
4893
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
920,884✔
4894
    flag = mndIsTotpEnabledUser(pUser) ? 1 : 0;
920,884✔
4895
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
920,884✔
4896

4897
    cols++;
920,884✔
4898

4899
    int32_t tlen = convertIpWhiteListToStr(pUser, &buf);
920,884✔
4900
    if (tlen != 0) {
920,884✔
4901
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
920,884✔
4902
      if (varstr == NULL) {
920,884✔
4903
        sdbRelease(pSdb, pUser);
×
4904
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
4905
      }
4906
      varDataSetLen(varstr, tlen);
920,884✔
4907
      (void)memcpy(varDataVal(varstr), buf, tlen);
920,884✔
4908

4909
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
920,884✔
4910
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
920,884✔
4911

4912
      taosMemoryFreeClear(buf);
920,884✔
4913
    } else {
4914
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4915
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
4916
    }
4917

4918
    cols++;
920,884✔
4919
    tlen = convertTimeRangesToStr(pUser, &buf);
920,884✔
4920
    if (tlen != 0) {
920,884✔
4921
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
920,884✔
4922
      if (varstr == NULL) {
920,884✔
4923
        sdbRelease(pSdb, pUser);
×
4924
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
4925
      }
4926
      varDataSetLen(varstr, tlen);
920,884✔
4927
      (void)memcpy(varDataVal(varstr), buf, tlen);
920,884✔
4928

4929
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
920,884✔
4930
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
920,884✔
4931

4932
      taosMemoryFreeClear(buf);
920,884✔
4933
    } else {
4934
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4935
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
4936
    }
4937

4938
    if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
920,884✔
4939
      void  *pIter = NULL;
920,884✔
4940
      size_t klen = 0, tlen = 0;
920,884✔
4941
      char  *pBuf = POINTER_SHIFT(tBuf, VARSTR_HEADER_SIZE);
920,884✔
4942
      while ((pIter = taosHashIterate(pUser->roles, pIter))) {
2,079,403✔
4943
        char *roleName = taosHashGetKey(pIter, &klen);
1,158,519✔
4944
        tlen += snprintf(pBuf + tlen, bufSize - tlen, "%s,", roleName);
1,158,519✔
4945
      }
4946
      if (tlen > 0) {
920,884✔
4947
        pBuf[--tlen] = 0;  // remove last ','
920,751✔
4948
      } else {
4949
        pBuf[0] = 0;
133✔
4950
      }
4951
      varDataSetLen(tBuf, tlen);
920,884✔
4952
      COL_DATA_SET_VAL_GOTO((const char *)tBuf, false, pUser, pShow->pIter, _exit);
920,884✔
4953
    }
4954

4955
    numOfRows++;
920,884✔
4956
    sdbRelease(pSdb, pUser);
920,884✔
4957
  }
4958

4959
  pShow->numOfRows += numOfRows;
118,728✔
4960
_exit:
118,728✔
4961
  taosMemoryFreeClear(buf);
118,728✔
4962
  taosMemoryFreeClear(varstr);
118,728✔
4963
  if (code < 0) {
118,728✔
4964
    mError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4965
    TAOS_RETURN(code);
×
4966
  }
4967
  return numOfRows;
118,728✔
4968
}
4969

4970
static int32_t mndRetrieveUsersFull(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
13,270✔
4971
  int32_t numOfRows = 0;
13,270✔
4972
#ifdef TD_ENTERPRISE
4973
  SMnode   *pMnode = pReq->info.node;
13,270✔
4974
  SSdb     *pSdb = pMnode->pSdb;
13,270✔
4975
  SUserObj *pOperUser = NULL;
13,270✔
4976
  SUserObj *pUser = NULL;
13,270✔
4977
  int32_t   code = 0;
13,270✔
4978
  int32_t   lino = 0;
13,270✔
4979
  int32_t   cols = 0;
13,270✔
4980
  int8_t    flag = 0;
13,270✔
4981
  char     *pWrite = NULL;
13,270✔
4982
  char     *buf = NULL;
13,270✔
4983
  char     *varstr = NULL;
13,270✔
4984
  char     *pBuf = NULL;
13,270✔
4985
  char      tBuf[TSDB_MAX_SUBROLE * TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
13,270✔
4986
  int32_t   bufSize = sizeof(tBuf) - VARSTR_HEADER_SIZE;
13,270✔
4987
  bool      showSecurityInfo = false;
13,270✔
4988

4989
  code = mndAcquireUser(pMnode, RPC_MSG_USER(pReq), &pOperUser);
13,270✔
4990
  if (pOperUser == NULL) {
13,270✔
4991
    TAOS_CHECK_EXIT(TSDB_CODE_MND_NO_USER_FROM_CONN);
×
4992
  }
4993
  if (0 == mndCheckSysObjPrivilege(pMnode, pOperUser, RPC_MSG_TOKEN(pReq), PRIV_USER_SHOW_SECURITY, 0, 0, NULL, NULL)) {
13,270✔
4994
    showSecurityInfo = true;
13,270✔
4995
  }
4996

4997
  while (numOfRows < rows) {
579,854✔
4998
    pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
579,854✔
4999
    if (pShow->pIter == NULL) break;
579,854✔
5000

5001
    cols = 0;
566,584✔
5002
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
566,584✔
5003
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
566,584✔
5004
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
566,584✔
5005
    COL_DATA_SET_VAL_GOTO((const char *)name, false, pUser, pShow->pIter, _exit);
566,584✔
5006

5007
    cols++;
566,584✔
5008
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
566,584✔
5009
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->superUser, false, pUser, pShow->pIter, _exit);
566,584✔
5010

5011
    cols++;
566,584✔
5012
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
566,584✔
5013
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->enable, false, pUser, pShow->pIter, _exit);
566,584✔
5014

5015
    cols++;
566,584✔
5016
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
566,584✔
5017
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sysInfo, false, pUser, pShow->pIter, _exit);
566,584✔
5018

5019
    cols++;
566,584✔
5020
    flag = pUser->createdb ? 1 : 0;
566,584✔
5021
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
566,584✔
5022
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
566,584✔
5023

5024
    cols++;
566,584✔
5025
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
566,584✔
5026
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->createdTime, false, pUser, pShow->pIter, _exit);
566,584✔
5027

5028
    cols++;
566,584✔
5029
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
566,584✔
5030
    flag = mndIsTotpEnabledUser(pUser) ? 1 : 0;
566,584✔
5031
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
566,584✔
5032

5033
    cols++;
566,584✔
5034
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
566,584✔
5035
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->changePass, false, pUser, pShow->pIter, _exit);
566,584✔
5036

5037
    cols++;
566,584✔
5038
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
566,584✔
5039
    char pass[TSDB_PASSWORD_LEN + VARSTR_HEADER_SIZE] = {0};
566,584✔
5040
    STR_WITH_MAXSIZE_TO_VARSTR(pass, showSecurityInfo ? pUser->passwords[0].pass : "*",
566,584✔
5041
                               pShow->pMeta->pSchemas[cols].bytes);
5042
    COL_DATA_SET_VAL_GOTO((const char *)pass, false, pUser, pShow->pIter, _exit);
566,584✔
5043

5044
    cols++;
566,584✔
5045
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
566,584✔
5046
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sessionPerUser, false, pUser, pShow->pIter, _exit);
566,584✔
5047

5048
    cols++;
566,584✔
5049
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
566,584✔
5050
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->connectTime, false, pUser, pShow->pIter, _exit);
566,584✔
5051

5052
    cols++;
566,584✔
5053
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
566,584✔
5054
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->connectIdleTime, false, pUser, pShow->pIter, _exit);
566,584✔
5055

5056
    cols++;
566,584✔
5057
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
566,584✔
5058
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->callPerSession, false, pUser, pShow->pIter, _exit);
566,584✔
5059

5060
    cols++;
566,584✔
5061
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
566,584✔
5062
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->vnodePerCall, false, pUser, pShow->pIter, _exit);
566,584✔
5063

5064
    cols++;
566,584✔
5065
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
566,584✔
5066
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->failedLoginAttempts, false, pUser, pShow->pIter, _exit);
566,584✔
5067

5068
    cols++;
566,584✔
5069
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
566,584✔
5070
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordLifeTime, false, pUser, pShow->pIter, _exit);
566,584✔
5071

5072
    cols++;
566,584✔
5073
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
566,584✔
5074
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordReuseTime, false, pUser, pShow->pIter, _exit);
566,584✔
5075

5076
    cols++;
566,584✔
5077
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
566,584✔
5078
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordReuseMax, false, pUser, pShow->pIter, _exit);
566,584✔
5079

5080
    cols++;
566,584✔
5081
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
566,584✔
5082
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordLockTime, false, pUser, pShow->pIter, _exit);
566,584✔
5083

5084
    cols++;
566,584✔
5085
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
566,584✔
5086
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordGraceTime, false, pUser, pShow->pIter, _exit);
566,584✔
5087

5088
    cols++;
566,584✔
5089
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
566,584✔
5090
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->inactiveAccountTime, false, pUser, pShow->pIter, _exit);
566,584✔
5091

5092
    cols++;
566,584✔
5093
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
566,584✔
5094
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->allowTokenNum, false, pUser, pShow->pIter, _exit);
566,584✔
5095

5096
    cols++;
566,584✔
5097
    int32_t tlen = convertIpWhiteListToStr(pUser, &buf);
566,584✔
5098
    if (tlen != 0) {
566,584✔
5099
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
566,584✔
5100
      if (varstr == NULL) {
566,584✔
5101
        sdbRelease(pSdb, pUser);
×
5102
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
5103
      }
5104
      varDataSetLen(varstr, tlen);
566,584✔
5105
      (void)memcpy(varDataVal(varstr), buf, tlen);
566,584✔
5106

5107
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
566,584✔
5108
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
566,584✔
5109

5110
      taosMemoryFreeClear(buf);
566,584✔
5111
    } else {
5112
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
5113
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
5114
    }
5115

5116
    cols++;
566,584✔
5117
    tlen = convertTimeRangesToStr(pUser, &buf);
566,584✔
5118
    if (tlen != 0) {
566,584✔
5119
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
566,584✔
5120
      if (varstr == NULL) {
566,584✔
5121
        sdbRelease(pSdb, pUser);
×
5122
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
5123
      }
5124
      varDataSetLen(varstr, tlen);
566,584✔
5125
      (void)memcpy(varDataVal(varstr), buf, tlen);
566,584✔
5126

5127
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
566,584✔
5128
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
566,584✔
5129

5130
      taosMemoryFreeClear(buf);
566,584✔
5131
    } else {
5132
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
5133
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
5134
    }
5135

5136
    if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
566,584✔
5137
      void  *pIter = NULL;
566,584✔
5138
      size_t klen = 0, tlen = 0;
566,584✔
5139
      char  *pBuf = POINTER_SHIFT(tBuf, VARSTR_HEADER_SIZE);
566,584✔
5140
      while ((pIter = taosHashIterate(pUser->roles, pIter))) {
1,159,708✔
5141
        char *roleName = taosHashGetKey(pIter, &klen);
593,124✔
5142
        tlen += snprintf(pBuf + tlen, bufSize - tlen, "%s,", roleName);
593,124✔
5143
      }
5144
      if (tlen > 0) {
566,584✔
5145
        pBuf[--tlen] = 0;  // remove last ','
566,584✔
5146
      } else {
5147
        pBuf[0] = 0;
×
5148
      }
5149
      varDataSetLen(tBuf, tlen);
566,584✔
5150
      COL_DATA_SET_VAL_GOTO((const char *)tBuf, false, pUser, pShow->pIter, _exit);
566,584✔
5151
    }
5152

5153
    numOfRows++;
566,584✔
5154
    sdbRelease(pSdb, pUser);
566,584✔
5155
  }
5156

5157
  pShow->numOfRows += numOfRows;
13,270✔
5158
_exit:
13,270✔
5159
  taosMemoryFreeClear(buf);
13,270✔
5160
  taosMemoryFreeClear(varstr);
13,270✔
5161
  mndReleaseUser(pMnode, pOperUser);
13,270✔
5162
  if (code < 0) {
13,270✔
5163
    mError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
5164
    TAOS_RETURN(code);
×
5165
  }
5166
#endif
5167
  return numOfRows;
13,270✔
5168
}
5169

5170
static void mndCancelGetNextUser(SMnode *pMnode, void *pIter) {
×
5171
  SSdb *pSdb = pMnode->pSdb;
×
5172
  sdbCancelFetchByType(pSdb, pIter, SDB_USER);
×
5173
}
×
5174

5175
static int32_t mndLoopHash(SHashObj *hash, char *priType, SSDataBlock *pBlock, int32_t *pNumOfRows, SSdb *pSdb,
×
5176
                           SUserObj *pUser, SShowObj *pShow, char **condition, char **sql) {
5177
  char   *value = taosHashIterate(hash, NULL);
×
5178
  char   *user = pUser->user;
×
5179
  int32_t code = 0;
×
5180
  int32_t lino = 0;
×
5181
  int32_t cols = 0;
×
5182
  int32_t numOfRows = *pNumOfRows;
×
5183

5184
  while (value != NULL) {
×
5185
    cols = 0;
×
5186
    char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
×
5187
    STR_WITH_MAXSIZE_TO_VARSTR(userName, user, pShow->pMeta->pSchemas[cols].bytes);
×
5188
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
5189
    COL_DATA_SET_VAL_GOTO((const char *)userName, false, NULL, NULL, _exit);
×
5190

5191
    char privilege[20] = {0};
×
5192
    STR_WITH_MAXSIZE_TO_VARSTR(privilege, priType, pShow->pMeta->pSchemas[cols].bytes);
×
5193
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
5194
    COL_DATA_SET_VAL_GOTO((const char *)privilege, false, NULL, NULL, _exit);
×
5195

5196
    size_t keyLen = 0;
×
5197
    void  *key = taosHashGetKey(value, &keyLen);
×
5198

5199
    char dbName[TSDB_DB_NAME_LEN] = {0};
×
5200
    (void)mndExtractShortDbNameFromStbFullName(key, dbName);
×
5201
    char dbNameContent[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
×
5202
    STR_WITH_MAXSIZE_TO_VARSTR(dbNameContent, dbName, pShow->pMeta->pSchemas[cols].bytes);
×
5203
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
5204
    COL_DATA_SET_VAL_GOTO((const char *)dbNameContent, false, NULL, NULL, _exit);
×
5205

5206
    char tableName[TSDB_TABLE_NAME_LEN] = {0};
×
5207
    mndExtractTbNameFromStbFullName(key, tableName, TSDB_TABLE_NAME_LEN);
×
5208
    char tableNameContent[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
×
5209
    STR_WITH_MAXSIZE_TO_VARSTR(tableNameContent, tableName, pShow->pMeta->pSchemas[cols].bytes);
×
5210
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
5211
    COL_DATA_SET_VAL_GOTO((const char *)tableNameContent, false, NULL, NULL, _exit);
×
5212

5213
    if (strcmp("t", value) != 0 && strcmp("v", value) != 0) {
×
5214
      SNode  *pAst = NULL;
×
5215
      int32_t sqlLen = 0;
×
5216
      size_t  bufSz = strlen(value) + 1;
×
5217
      if (bufSz < 6) bufSz = 6;
×
5218
      TAOS_MEMORY_REALLOC(*sql, bufSz);
×
5219
      if (*sql == NULL) {
×
5220
        code = terrno;
×
5221
        goto _exit;
×
5222
      }
5223
      TAOS_MEMORY_REALLOC(*condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
×
5224
      if ((*condition) == NULL) {
×
5225
        code = terrno;
×
5226
        goto _exit;
×
5227
      }
5228

5229
      if (nodesStringToNode(value, &pAst) == 0) {
×
5230
        if (nodesNodeToSQLFormat(pAst, *sql, bufSz, &sqlLen, true) != 0) {
×
5231
          sqlLen = snprintf(*sql, bufSz, "error");
×
5232
        }
5233
        nodesDestroyNode(pAst);
×
5234
      }
5235

5236
      if (sqlLen == 0) {
×
5237
        sqlLen = snprintf(*sql, bufSz, "error");
×
5238
      }
5239

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

5242
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
5243
      COL_DATA_SET_VAL_GOTO((const char *)(*condition), false, NULL, NULL, _exit);
×
5244

5245
      char notes[2] = {0};
×
5246
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
×
5247
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
5248
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, NULL, NULL, _exit);
×
5249
    } else {
5250
      TAOS_MEMORY_REALLOC(*condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
×
5251
      if ((*condition) == NULL) {
×
5252
        code = terrno;
×
5253
        goto _exit;
×
5254
      }
5255
      STR_WITH_MAXSIZE_TO_VARSTR((*condition), "", pShow->pMeta->pSchemas[cols].bytes);
×
5256
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
5257
      COL_DATA_SET_VAL_GOTO((const char *)(*condition), false, NULL, NULL, _exit);
×
5258

5259
      char notes[64 + VARSTR_HEADER_SIZE] = {0};
×
5260
      STR_WITH_MAXSIZE_TO_VARSTR(notes, value[0] == 'v' ? "view" : "", sizeof(notes));
×
5261
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
5262
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, NULL, NULL, _exit);
×
5263
    }
5264

5265
    numOfRows++;
×
5266
    value = taosHashIterate(hash, value);
×
5267
  }
5268
  *pNumOfRows = numOfRows;
×
5269
_exit:
×
5270
  if (code < 0) {
×
5271
    mError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
5272
    sdbRelease(pSdb, pUser);
×
5273
    sdbCancelFetch(pSdb, pShow->pIter);
×
5274
  }
5275
  TAOS_RETURN(code);
×
5276
}
5277

5278
#if 0
5279
static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
5280
  int32_t   code = 0;
5281
  int32_t   lino = 0;
5282
  SMnode   *pMnode = pReq->info.node;
5283
  SSdb     *pSdb = pMnode->pSdb;
5284
  int32_t   numOfRows = 0;
5285
  SUserObj *pUser = NULL;
5286
  int32_t   cols = 0;
5287
  char     *pWrite = NULL;
5288
  char     *condition = NULL;
5289
  char     *sql = NULL;
5290

5291
  bool fetchNextUser = pShow->restore ? false : true;
5292
  pShow->restore = false;
5293

5294
  while (numOfRows < rows) {
5295
    if (fetchNextUser) {
5296
      pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
5297
      if (pShow->pIter == NULL) break;
5298
    } else {
5299
      fetchNextUser = true;
5300
      void *pKey = taosHashGetKey(pShow->pIter, NULL);
5301
      pUser = sdbAcquire(pSdb, SDB_USER, pKey);
5302
      if (!pUser) {
5303
        continue;
5304
      }
5305
    }
5306

5307
    int32_t numOfReadDbs = 0; //taosHashGetSize(pUser->readDbs);
5308
    int32_t numOfWriteDbs = 0; //taosHashGetSize(pUser->writeDbs);
5309
    int32_t numOfTopics = taosHashGetSize(pUser->topics);
5310
    int32_t numOfReadTbs = taosHashGetSize(pUser->selectTbs);
5311
    int32_t numOfWriteTbs = taosHashGetSize(pUser->insertTbs);
5312
    int32_t numOfAlterTbs = taosHashGetSize(pUser->alterTbs);
5313
    int32_t numOfReadViews = taosHashGetSize(pUser->readViews);
5314
    int32_t numOfWriteViews = taosHashGetSize(pUser->writeViews);
5315
    int32_t numOfAlterViews = taosHashGetSize(pUser->alterViews);
5316
    if (numOfRows + numOfReadDbs + numOfWriteDbs + numOfTopics + numOfReadTbs + numOfWriteTbs + numOfAlterTbs +
5317
            numOfReadViews + numOfWriteViews + numOfAlterViews >=
5318
        rows) {
5319
      mInfo(
5320
          "will restore. current num of rows: %d, read dbs %d, write dbs %d, topics %d, read tables %d, write tables "
5321
          "%d, alter tables %d, select views %d, write views %d, alter views %d",
5322
          numOfRows, numOfReadDbs, numOfWriteDbs, numOfTopics, numOfReadTbs, numOfWriteTbs, numOfAlterTbs,
5323
          numOfReadViews, numOfWriteViews, numOfAlterViews);
5324
      pShow->restore = true;
5325
      sdbRelease(pSdb, pUser);
5326
      break;
5327
    }
5328

5329
    if (pUser->superUser) {
5330
      cols = 0;
5331
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
5332
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
5333
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5334
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
5335

5336
      char privilege[20] = {0};
5337
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "all", pShow->pMeta->pSchemas[cols].bytes);
5338
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5339
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
5340

5341
      char objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
5342
      STR_WITH_MAXSIZE_TO_VARSTR(objName, "all", pShow->pMeta->pSchemas[cols].bytes);
5343
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5344
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
5345

5346
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
5347
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
5348
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5349
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
5350

5351
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
5352
      if (condition == NULL) {
5353
        sdbRelease(pSdb, pUser);
5354
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
5355
      }
5356
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
5357
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5358
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
5359

5360
      char notes[2] = {0};
5361
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
5362
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5363
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
5364

5365
      numOfRows++;
5366
    }
5367
#if 0
5368
    char *db = taosHashIterate(pUser->readDbs, NULL);
5369
    while (db != NULL) {
5370
      cols = 0;
5371
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
5372
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
5373
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5374
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
5375

5376
      char privilege[20] = {0};
5377
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "read", pShow->pMeta->pSchemas[cols].bytes);
5378
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5379
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
5380

5381
      SName name = {0};
5382
      char  objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
5383
      code = tNameFromString(&name, db, T_NAME_ACCT | T_NAME_DB);
5384
      if (code < 0) {
5385
        sdbRelease(pSdb, pUser);
5386
        sdbCancelFetch(pSdb, pShow->pIter);
5387
        TAOS_CHECK_GOTO(code, &lino, _exit);
5388
      }
5389
      (void)tNameGetDbName(&name, varDataVal(objName));
5390
      varDataSetLen(objName, strlen(varDataVal(objName)));
5391
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5392
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
5393

5394
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
5395
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
5396
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5397
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
5398

5399
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
5400
      if (condition == NULL) {
5401
        sdbRelease(pSdb, pUser);
5402
        sdbCancelFetch(pSdb, pShow->pIter);
5403
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
5404
      }
5405
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
5406
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5407
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
5408

5409
      char notes[2] = {0};
5410
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
5411
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5412
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
5413

5414
      numOfRows++;
5415
      db = taosHashIterate(pUser->readDbs, db);
5416
    }
5417

5418
    db = taosHashIterate(pUser->writeDbs, NULL);
5419
    while (db != NULL) {
5420
      cols = 0;
5421
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
5422
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
5423
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5424
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
5425

5426
      char privilege[20] = {0};
5427
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "write", pShow->pMeta->pSchemas[cols].bytes);
5428
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5429
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
5430

5431
      SName name = {0};
5432
      char  objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
5433
      code = tNameFromString(&name, db, T_NAME_ACCT | T_NAME_DB);
5434
      if (code < 0) {
5435
        sdbRelease(pSdb, pUser);
5436
        sdbCancelFetch(pSdb, pShow->pIter);
5437
        TAOS_CHECK_GOTO(code, &lino, _exit);
5438
      }
5439
      (void)tNameGetDbName(&name, varDataVal(objName));
5440
      varDataSetLen(objName, strlen(varDataVal(objName)));
5441
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5442
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
5443

5444
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
5445
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
5446
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5447
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
5448

5449
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
5450
      if (condition == NULL) {
5451
        sdbRelease(pSdb, pUser);
5452
        sdbCancelFetch(pSdb, pShow->pIter);
5453
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
5454
      }
5455
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
5456
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5457
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
5458

5459
      char notes[2] = {0};
5460
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
5461
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5462
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
5463

5464
      numOfRows++;
5465
      db = taosHashIterate(pUser->writeDbs, db);
5466
    }
5467
#endif
5468
    TAOS_CHECK_EXIT(mndLoopHash(pUser->selectTbs, "select", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
5469

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

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

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

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

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

5480
    char *topic = taosHashIterate(pUser->topics, NULL);
5481
    while (topic != NULL) {
5482
      cols = 0;
5483
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
5484
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
5485
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5486
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
5487

5488
      char privilege[20] = {0};
5489
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "subscribe", pShow->pMeta->pSchemas[cols].bytes);
5490
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5491
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
5492

5493
      char topicName[TSDB_TOPIC_NAME_LEN + VARSTR_HEADER_SIZE + 5] = {0};
5494
      tstrncpy(varDataVal(topicName), mndGetDbStr(topic), TSDB_TOPIC_NAME_LEN - 2);
5495
      varDataSetLen(topicName, strlen(varDataVal(topicName)));
5496
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5497
      COL_DATA_SET_VAL_GOTO((const char *)topicName, false, pUser, pShow->pIter, _exit);
5498

5499
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
5500
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
5501
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5502
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
5503

5504
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
5505
      if (condition == NULL) {
5506
        sdbRelease(pSdb, pUser);
5507
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
5508
      }
5509
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
5510
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5511
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
5512

5513
      char notes[2] = {0};
5514
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
5515
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5516
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
5517

5518
      numOfRows++;
5519
      topic = taosHashIterate(pUser->topics, topic);
5520
    }
5521

5522
    sdbRelease(pSdb, pUser);
5523
  }
5524

5525
  pShow->numOfRows += numOfRows;
5526
_exit:
5527
  taosMemoryFreeClear(condition);
5528
  taosMemoryFreeClear(sql);
5529
  if (code < 0) {
5530
    mError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
5531
    TAOS_RETURN(code);
5532
  }
5533
  return numOfRows;
5534
}
5535
#endif
5536

5537
int32_t mndShowTablePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows, void *pObj,
388,148✔
5538
                               const char *principalName, SHashObj *privTbs, EPrivType privType, char *pBuf,
5539
                               int32_t bufSize, int32_t *pNumOfRows) {
5540
  int32_t     code = 0, lino = 0;
388,148✔
5541
  SMnode     *pMnode = pReq->info.node;
388,148✔
5542
  SSdb       *pSdb = pMnode->pSdb;
388,148✔
5543
  int32_t     cols = 0, qBufSize = bufSize - VARSTR_HEADER_SIZE;
388,148✔
5544
  int32_t     numOfRows = *pNumOfRows;
388,148✔
5545
  char       *qBuf = NULL;
388,148✔
5546
  char       *sql = NULL;
388,148✔
5547
  char        roleName[TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
388,148✔
5548
  const char *privName = privInfoGetName(privType);
388,148✔
5549

5550
  STR_WITH_MAXSIZE_TO_VARSTR(roleName, principalName, pShow->pMeta->pSchemas[cols].bytes);
388,148✔
5551

5552
  void *pIter = NULL;
388,148✔
5553
  while ((pIter = taosHashIterate(privTbs, pIter))) {
456,637✔
5554
    SPrivTblPolicies *pPolices = (SPrivTblPolicies *)pIter;
68,489✔
5555
    SArray           *tblPolicies = pPolices->policy;
68,489✔
5556

5557
    char   *key = taosHashGetKey(pPolices, NULL);
68,489✔
5558
    int32_t objType = PRIV_OBJ_UNKNOWN;
68,489✔
5559
    char    dbName[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
68,489✔
5560
    char    tblName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
68,489✔
5561
    if ((code = privObjKeyParse(key, &objType, dbName, sizeof(dbName), tblName, sizeof(tblName), false))) {
68,489✔
5562
      sdbRelease(pSdb, pObj);
×
5563
      sdbCancelFetch(pSdb, pShow->pIter);
×
5564
      TAOS_CHECK_EXIT(code);
×
5565
    }
5566

5567
    int32_t nTbPolicies = taosArrayGetSize(tblPolicies);
68,489✔
5568
    for (int32_t i = 0; i < nTbPolicies; ++i) {
136,978✔
5569
      SPrivTblPolicy *tbPolicy = (SPrivTblPolicy *)TARRAY_GET_ELEM(tblPolicies, i);
68,489✔
5570
      cols = 0;
68,489✔
5571
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
68,489✔
5572
      COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
68,489✔
5573

5574
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
68,489✔
5575
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privName, pShow->pMeta->pSchemas[cols].bytes);
68,489✔
5576
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
68,489✔
5577
      }
5578

5579
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
68,489✔
5580
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privObjGetName(objType), pShow->pMeta->pSchemas[cols].bytes);
68,489✔
5581
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
68,489✔
5582
      }
5583

5584
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
68,489✔
5585
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, dbName, pShow->pMeta->pSchemas[cols].bytes);
68,489✔
5586
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
68,489✔
5587
      }
5588

5589
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
68,489✔
5590
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, tblName, pShow->pMeta->pSchemas[cols].bytes);
68,489✔
5591
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
68,489✔
5592
      }
5593
      // condition
5594
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
68,489✔
5595
        SNode  *pAst = NULL;
68,489✔
5596
        int32_t sqlLen = 0;
68,489✔
5597
        qBuf = POINTER_SHIFT(pBuf, VARSTR_HEADER_SIZE);
68,489✔
5598
        if (tbPolicy->condLen > 0) {
68,489✔
5599
          if (nodesStringToNode(tbPolicy->cond, &pAst) == 0) {
68,489✔
5600
            if (nodesNodeToSQLFormat(pAst, qBuf, qBufSize, &sqlLen, true) != 0) {
68,489✔
5601
              sqlLen = tsnprintf(qBuf, qBufSize, "error");
×
5602
            }
5603
            nodesDestroyNode(pAst);
68,489✔
5604
          }
5605
          if (sqlLen == 0) {
68,489✔
5606
            sqlLen = tsnprintf(qBuf, qBufSize, "error");
×
5607
          }
5608
        } else {
5609
          sqlLen = tsnprintf(qBuf, qBufSize, "");
×
5610
        }
5611
        varDataSetLen(pBuf, sqlLen);
68,489✔
5612
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
68,489✔
5613
      }
5614
      // notes
5615
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
68,489✔
5616
        STR_WITH_MAXSIZE_TO_VARSTR((pBuf), "", 2);
68,489✔
5617
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
68,489✔
5618
      }
5619
      // columns
5620
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
68,489✔
5621
        SArray *pCols = tbPolicy->cols;
68,489✔
5622
        int32_t nCols = taosArrayGetSize(pCols);
68,489✔
5623
        int32_t totalLen = 0;
68,489✔
5624
        qBuf = POINTER_SHIFT(pBuf, VARSTR_HEADER_SIZE);
68,489✔
5625
        for (int32_t j = 0; j < nCols; ++j) {
95,789✔
5626
          SColNameFlag *pCol = (SColNameFlag *)TARRAY_GET_ELEM(pCols, j);
27,300✔
5627
          char          tmpBuf[TSDB_COL_NAME_LEN + 16] = {0};
27,300✔
5628
          int32_t       tmpLen = 0;
27,300✔
5629
          if (IS_MASK_ON(pCol)) {
27,300✔
5630
            tmpLen = snprintf(tmpBuf, sizeof(tmpBuf), "mask(%s)%s", pCol->colName, j == nCols - 1 ? "" : ",");
×
5631
          } else {
5632
            tmpLen = snprintf(tmpBuf, sizeof(tmpBuf), "%s%s", pCol->colName, j == nCols - 1 ? "" : ",");
27,300✔
5633
          }
5634
          if (totalLen + tmpLen > qBufSize) {
27,300✔
5635
            break;
×
5636
          }
5637
          (void)memcpy(POINTER_SHIFT(qBuf, totalLen), tmpBuf, tmpLen);
27,300✔
5638
          totalLen += tmpLen;
27,300✔
5639
        }
5640
        varDataSetLen(pBuf, totalLen);
68,489✔
5641
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
68,489✔
5642
      }
5643
      // update_time
5644
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
68,489✔
5645
        char updateTime[40] = {0};
68,489✔
5646
        (void)formatTimestampLocal(updateTime, sizeof(updateTime), tbPolicy->updateUs, TSDB_TIME_PRECISION_MICRO);
68,489✔
5647
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, updateTime, pShow->pMeta->pSchemas[cols].bytes);
68,489✔
5648
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
68,489✔
5649
      }
5650
      ++numOfRows;
68,489✔
5651
    }
5652
  }
5653
  *pNumOfRows = numOfRows;
388,148✔
5654
_exit:
388,148✔
5655
  TAOS_RETURN(code);
388,148✔
5656
}
5657

5658
static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
15,831✔
5659
  int32_t   code = 0, lino = 0;
15,831✔
5660
  SMnode   *pMnode = pReq->info.node;
15,831✔
5661
  SSdb     *pSdb = pMnode->pSdb;
15,831✔
5662
  int32_t   numOfRows = 0;
15,831✔
5663
  int32_t   cols = 0;
15,831✔
5664
  SUserObj *pObj = NULL;
15,831✔
5665
  char     *pBuf = NULL, *qBuf = NULL;
15,831✔
5666
  char     *sql = NULL;
15,831✔
5667
  char      roleName[TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
15,831✔
5668
  int32_t   bufSize = TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE;
15,831✔
5669

5670
  bool fetchNextInstance = pShow->restore ? false : true;
15,831✔
5671
  pShow->restore = false;
15,831✔
5672

5673
  while (numOfRows < rows) {
106,477✔
5674
    if (fetchNextInstance) {
106,477✔
5675
      pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pObj);
106,477✔
5676
      if (pShow->pIter == NULL) break;
106,477✔
5677
    } else {
5678
      fetchNextInstance = true;
×
5679
      void *pKey = taosHashGetKey(pShow->pIter, NULL);
×
5680
      if (!(pObj = sdbAcquire(pSdb, SDB_USER, pKey))) {
×
5681
        continue;
×
5682
      }
5683
    }
5684

5685
    // count total privileges for current user
5686
    int32_t nSysPrivileges = privPopCnt(&pObj->sysPrivs);
90,646✔
5687
    int32_t nObjPrivileges = 0;
90,646✔
5688
    void   *pIter = NULL;
90,646✔
5689
    while ((pIter = taosHashIterate(pObj->objPrivs, pIter))) {
1,155,496✔
5690
      SPrivObjPolicies *pPolices = (SPrivObjPolicies *)pIter;
1,064,850✔
5691
      nObjPrivileges += privPopCnt(&pPolices->policy);
2,129,700✔
5692
    }
5693
    int32_t nTblPrivileges = privTblPrivCnt(pObj->selectTbs);
90,646✔
5694
    nTblPrivileges += privTblPrivCnt(pObj->insertTbs);
90,646✔
5695
    nTblPrivileges += privTblPrivCnt(pObj->updateTbs);
90,646✔
5696
    nTblPrivileges += privTblPrivCnt(pObj->deleteTbs);
90,646✔
5697

5698
    int32_t totalPrivileges = nSysPrivileges + nObjPrivileges + nTblPrivileges;
90,646✔
5699

5700
    if (numOfRows + totalPrivileges >= rows) {
90,646✔
5701
      if (totalPrivileges >= SHOW_PRIVILEGES_STEP_SIZE) {
×
5702
        mError("user:%s, has too many privileges:%d to show", pObj->name, totalPrivileges);
×
5703
        sdbRelease(pSdb, pObj);
×
5704
        TAOS_CHECK_EXIT(TSDB_CODE_MND_TOO_MANY_PRIVS);
×
5705
      }
5706
      pShow->restore = true;
×
5707
      sdbRelease(pSdb, pObj);
×
5708
      break;
×
5709
    }
5710

5711
    if (!pBuf && !(pBuf = taosMemoryMalloc(bufSize))) {
90,646✔
5712
      sdbRelease(pSdb, pObj);
×
5713
      TAOS_CHECK_EXIT(terrno);
×
5714
    }
5715

5716
    cols = 0;
90,646✔
5717
    STR_WITH_MAXSIZE_TO_VARSTR(roleName, pObj->name, pShow->pMeta->pSchemas[cols].bytes);
90,646✔
5718

5719
    // system privileges
5720
    SPrivIter privIter = {0};
90,646✔
5721
    privIterInit(&privIter, &pObj->sysPrivs);
90,646✔
5722
    SPrivInfo *pPrivInfo = NULL;
90,646✔
5723
    while (privIterNext(&privIter, &pPrivInfo)) {
118,313✔
5724
      cols = 0;
27,667✔
5725
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
27,667✔
5726
      COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
27,667✔
5727

5728
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
27,667✔
5729
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, pPrivInfo->name, pShow->pMeta->pSchemas[cols].bytes);
27,667✔
5730
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
27,667✔
5731
      }
5732
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
27,667✔
5733
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privObjGetName(PRIV_OBJ_CLUSTER), pShow->pMeta->pSchemas[cols].bytes);
27,667✔
5734
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
27,667✔
5735
      }
5736
      // skip db, table, condition, notes, columns, update_time
5737
      COL_DATA_SET_EMPTY_VARCHAR(pBuf, 6);
193,669✔
5738
      numOfRows++;
27,667✔
5739
    }
5740

5741
    // object privileges
5742
    pIter = NULL;
90,646✔
5743
    while ((pIter = taosHashIterate(pObj->objPrivs, pIter))) {
1,155,496✔
5744
      SPrivObjPolicies *pPolices = (SPrivObjPolicies *)pIter;
1,064,850✔
5745

5746
      char   *key = taosHashGetKey(pPolices, NULL);
1,064,850✔
5747
      int32_t objType = PRIV_OBJ_UNKNOWN;
1,064,850✔
5748
      char    dbName[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
1,064,850✔
5749
      char    tblName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
1,064,850✔
5750
      if ((code = privObjKeyParse(key, &objType, dbName, sizeof(dbName), tblName, sizeof(tblName), false))) {
1,064,850✔
5751
        sdbRelease(pSdb, pObj);
×
5752
        TAOS_CHECK_EXIT(code);
×
5753
      }
5754

5755
      SPrivIter privIter = {0};
1,064,850✔
5756
      privIterInit(&privIter, &pPolices->policy);
1,064,850✔
5757
      SPrivInfo *pPrivInfo = NULL;
1,064,850✔
5758
      while (privIterNext(&privIter, &pPrivInfo)) {
3,266,430✔
5759
        cols = 0;
2,201,580✔
5760
        SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
2,201,580✔
5761
        COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
2,201,580✔
5762

5763
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
2,201,580✔
5764
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, pPrivInfo->name, pShow->pMeta->pSchemas[cols].bytes);
2,201,580✔
5765
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
2,201,580✔
5766
        }
5767

5768
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
2,201,580✔
5769
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privObjGetName(objType), pShow->pMeta->pSchemas[cols].bytes);
2,201,580✔
5770
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
2,201,580✔
5771
        }
5772

5773
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
2,201,580✔
5774
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, dbName, pShow->pMeta->pSchemas[cols].bytes);
2,201,580✔
5775
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
2,201,580✔
5776
        }
5777

5778
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
2,201,580✔
5779
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, tblName, pShow->pMeta->pSchemas[cols].bytes);
2,201,580✔
5780
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
2,201,580✔
5781
        }
5782

5783
        // skip condition, notes, columns, update_time
5784
        COL_DATA_SET_EMPTY_VARCHAR(pBuf, 4);
11,007,900✔
5785

5786
        numOfRows++;
2,201,580✔
5787
      }
5788
    }
5789

5790
    // table level privileges
5791
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->name, pObj->selectTbs,
90,646✔
5792
                                           PRIV_TBL_SELECT, pBuf, bufSize, &numOfRows));
5793
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->name, pObj->insertTbs,
90,646✔
5794
                                           PRIV_TBL_INSERT, pBuf, bufSize, &numOfRows));
5795
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->name, pObj->updateTbs,
90,646✔
5796
                                           PRIV_TBL_UPDATE, pBuf, bufSize, &numOfRows));
5797
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->name, pObj->deleteTbs,
90,646✔
5798
                                           PRIV_TBL_DELETE, pBuf, bufSize, &numOfRows));
5799
    sdbRelease(pSdb, pObj);
90,646✔
5800
  }
5801

5802
  pShow->numOfRows += numOfRows;
15,831✔
5803
_exit:
15,831✔
5804
  taosMemoryFreeClear(pBuf);
15,831✔
5805
  taosMemoryFreeClear(sql);
15,831✔
5806
  if (code < 0) {
15,831✔
5807
    mError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
5808
    TAOS_RETURN(code);
×
5809
  }
5810
  return numOfRows;
15,831✔
5811
}
5812

5813
static void mndCancelGetNextPrivileges(SMnode *pMnode, void *pIter) {
×
5814
  SSdb *pSdb = pMnode->pSdb;
×
5815
  sdbCancelFetchByType(pSdb, pIter, SDB_USER);
×
5816
}
×
5817

5818
int32_t mndValidateUserAuthInfo(SMnode *pMnode, SUserAuthVersion *pUsers, int32_t numOfUses, void **ppRsp,
24,382,839✔
5819
                                int32_t *pRspLen, int64_t ipWhiteListVer) {
5820
  int32_t           code = 0;
24,382,839✔
5821
  int32_t           lino = 0;
24,382,839✔
5822
  int32_t           rspLen = 0;
24,383,031✔
5823
  void             *pRsp = NULL;
24,383,031✔
5824
  SUserAuthBatchRsp batchRsp = {0};
24,383,031✔
5825

5826
  batchRsp.pArray = taosArrayInit(numOfUses, sizeof(SGetUserAuthRsp));
24,383,031✔
5827
  if (batchRsp.pArray == NULL) {
24,383,441✔
5828
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
5829
  }
5830
  int64_t now = taosGetTimestampMs();
24,383,270✔
5831
  for (int32_t i = 0; i < numOfUses; ++i) {
49,189,820✔
5832
    SUserObj *pUser = NULL;
24,806,246✔
5833
    code = mndAcquireUser(pMnode, pUsers[i].user, &pUser);
24,806,246✔
5834
    if (pUser == NULL) {
24,806,264✔
5835
      if (TSDB_CODE_MND_USER_NOT_EXIST == code) {
8,856✔
5836
        SGetUserAuthRsp rsp = {.dropped = 1};
8,856✔
5837
        (void)memcpy(rsp.user, pUsers[i].user, TSDB_USER_LEN);
8,856✔
5838
        TSDB_CHECK_NULL(taosArrayPush(batchRsp.pArray, &rsp), code, lino, _OVER, TSDB_CODE_OUT_OF_MEMORY);
17,712✔
5839
      }
5840
      mError("user:%s, failed to auth user since %s", pUsers[i].user, tstrerror(code));
8,856✔
5841
      code = 0;
8,856✔
5842
      continue;
8,856✔
5843
    }
5844

5845
    pUsers[i].version = ntohl(pUsers[i].version);
24,797,408✔
5846
    if ((pUser->authVersion <= pUsers[i].version) && (ipWhiteListVer == pMnode->ipWhiteVer) &&
24,797,517✔
5847
        !mndNeedRetrieveRole(pUser)) {
×
5848
      mndReleaseUser(pMnode, pUser);
×
5849
      continue;
×
5850
    }
5851

5852
    SGetUserAuthRsp rsp = {0};
24,796,959✔
5853
    code = mndSetUserAuthRsp(pMnode, pUser, &rsp);
24,797,092✔
5854
    if (code) {
24,796,493✔
5855
      mndReleaseUser(pMnode, pUser);
×
5856
      tFreeSGetUserAuthRsp(&rsp);
×
5857
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
5858
    }
5859

5860
    if (!(taosArrayPush(batchRsp.pArray, &rsp))) {
49,594,187✔
5861
      code = terrno;
×
5862
      mndReleaseUser(pMnode, pUser);
×
5863
      tFreeSGetUserAuthRsp(&rsp);
×
5864
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
5865
    }
5866
    pUser->lastRoleRetrieve = now;  // update user's last retrieve time
24,797,694✔
5867
    mndReleaseUser(pMnode, pUser);
24,796,606✔
5868
  }
5869

5870
  if (taosArrayGetSize(batchRsp.pArray) <= 0) {
24,383,574✔
5871
    *ppRsp = NULL;
×
5872
    *pRspLen = 0;
×
5873

5874
    tFreeSUserAuthBatchRsp(&batchRsp);
×
5875
    return 0;
×
5876
  }
5877

5878
  rspLen = tSerializeSUserAuthBatchRsp(NULL, 0, &batchRsp);
24,383,441✔
5879
  if (rspLen < 0) {
24,382,726✔
5880
    TAOS_CHECK_GOTO(rspLen, &lino, _OVER);
×
5881
  }
5882
  pRsp = taosMemoryMalloc(rspLen);
24,382,726✔
5883
  if (pRsp == NULL) {
24,381,491✔
5884
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
5885
  }
5886
  rspLen = tSerializeSUserAuthBatchRsp(pRsp, rspLen, &batchRsp);
24,381,491✔
5887
  if (rspLen < 0) {
24,383,114✔
5888
    TAOS_CHECK_GOTO(rspLen, &lino, _OVER);
×
5889
  }
5890
_OVER:
24,383,114✔
5891
  tFreeSUserAuthBatchRsp(&batchRsp);
24,383,152✔
5892
  if (code < 0) {
24,382,888✔
5893
    for (int32_t i = 0; i < numOfUses; ++i) {
×
5894
      SUserObj *pUser = NULL;
×
5895
      if (mndAcquireUser(pMnode, pUsers[i].user, &pUser) != 0) {
×
5896
        continue;
×
5897
      }
5898
      pUser->lastRoleRetrieve = 0;  // reset last retrieve time on error
×
5899
      mndReleaseUser(pMnode, pUser);
×
5900
    }
5901
    mError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
5902
    taosMemoryFreeClear(pRsp);
×
5903
    rspLen = 0;
×
5904
  }
5905
  *ppRsp = pRsp;
24,382,888✔
5906
  *pRspLen = rspLen;
24,382,888✔
5907

5908
  TAOS_RETURN(code);
24,380,257✔
5909
}
5910

5911
int32_t mndUserDropRole(SMnode *pMnode, STrans *pTrans, SRoleObj *pObj) {
1,197✔
5912
  int32_t   code = 0, lino = 0;
1,197✔
5913
  SSdb     *pSdb = pMnode->pSdb;
1,197✔
5914
  SUserObj *pUser = NULL;
1,197✔
5915
  void     *pIter = NULL;
1,197✔
5916

5917
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser))) {
3,724✔
5918
    SHashObj *pRole = taosHashGet(pUser->roles, pObj->name, strlen(pObj->name) + 1);
2,527✔
5919
    if (!pRole) {
2,527✔
5920
      sdbRelease(pSdb, pUser);
2,394✔
5921
      pUser = NULL;
2,394✔
5922
      continue;
2,394✔
5923
    }
5924

5925
    SUserObj newUser = {0};
133✔
5926
    TAOS_CHECK_EXIT(mndUserDupObj(pUser, &newUser));
133✔
5927
    code = taosHashRemove(newUser.roles, pObj->name, strlen(pObj->name) + 1);
133✔
5928
    if (code == TSDB_CODE_NOT_FOUND) {
133✔
5929
      sdbRelease(pSdb, pUser);
×
5930
      pUser = NULL;
×
5931
      mndUserFreeObj(&newUser);
×
5932
      continue;
×
5933
    }
5934
    if (code != 0) {
133✔
5935
      mndUserFreeObj(&newUser);
×
5936
      TAOS_CHECK_EXIT(code);
×
5937
    }
5938
    SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
133✔
5939
    if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
133✔
5940
      mndUserFreeObj(&newUser);
×
5941
      TAOS_CHECK_EXIT(TSDB_CODE_OUT_OF_MEMORY);
×
5942
    }
5943
    if ((code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY))) {
133✔
5944
      mndUserFreeObj(&newUser);
×
5945
      TAOS_CHECK_EXIT(code);
×
5946
    }
5947
    sdbRelease(pSdb, pUser);
133✔
5948
    pUser = NULL;
133✔
5949
    mndUserFreeObj(&newUser);
133✔
5950
  }
5951
_exit:
1,197✔
5952
  if (pIter) sdbCancelFetch(pSdb, pIter);
1,197✔
5953
  if (pUser) sdbRelease(pSdb, pUser);
1,197✔
5954
  if (code < 0) {
1,197✔
5955
    mError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
5956
  }
5957
  TAOS_RETURN(code);
1,197✔
5958
}
5959

5960
static int32_t mndUserPrivHashRemoveDb(SHashObj *pHash, const char *dbFName, int32_t dbFNameLen, bool *found) {
3,935,115✔
5961
  void *pVal = NULL;
3,935,115✔
5962
  while ((pVal = taosHashIterate(pHash, pVal))) {
4,129,856✔
5963
    size_t klen = 0;
194,741✔
5964
    char  *key = taosHashGetKey(pVal, &klen);
194,741✔
5965
    if (key && privDbKeyMatch(key, dbFName, dbFNameLen)) {
389,482✔
5966
      TAOS_CHECK_RETURN(taosHashRemove(pHash, key, klen));
21,663✔
5967
      if (found) *found = true;
21,663✔
5968
    }
5969
  }
5970
  TAOS_RETURN(0);
3,935,115✔
5971
}
5972

5973
static int32_t mndUserRemoveDbPrivsImpl(SUserObj *pUser, const char *key, int32_t keyLen, bool *pFound) {
787,023✔
5974
  bool found = false;
787,023✔
5975
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pUser->objPrivs, (char *)key, keyLen, found ? NULL : &found));
787,023✔
5976
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pUser->selectTbs, (char *)key, keyLen, found ? NULL : &found));
787,023✔
5977
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pUser->insertTbs, (char *)key, keyLen, found ? NULL : &found));
787,023✔
5978
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pUser->updateTbs, (char *)key, keyLen, found ? NULL : &found));
787,023✔
5979
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pUser->deleteTbs, (char *)key, keyLen, found ? NULL : &found));
787,023✔
5980
  if (taosHashGet(pUser->ownedDbs, key, keyLen)) {
787,023✔
5981
    TAOS_CHECK_RETURN(taosHashRemove(pUser->ownedDbs, (char *)key, keyLen));
×
5982
    if (!found) found = true;
×
5983
  }
5984
  if (pFound) *pFound = found;
787,023✔
5985
  TAOS_RETURN(0);
787,023✔
5986
}
5987

5988
static int32_t mndUserRemoveDbPrivs(SMnode *pMnode, STrans *pTrans, const char *key, int32_t keyLen,
696,164✔
5989
                                    SSHashObj **ppUsers) {
5990
  int32_t    code = 0, lino = 0;
696,164✔
5991
  SSdb      *pSdb = pMnode->pSdb;
696,164✔
5992
  void      *pIter = NULL;
696,164✔
5993
  SUserObj  *pUser = NULL;
696,164✔
5994
  SSHashObj *pUsers = ppUsers ? *ppUsers : NULL;
696,164✔
5995
  bool       output = (ppUsers != NULL);
696,164✔
5996
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser))) {
1,482,912✔
5997
    bool found = false;
786,748✔
5998
    TAOS_CHECK_EXIT(mndUserRemoveDbPrivsImpl(pUser, key, keyLen, &found));
786,748✔
5999
    if (!found) {
786,748✔
6000
      sdbRelease(pSdb, pUser);
772,756✔
6001
      pUser = NULL;
772,756✔
6002
      continue;
772,756✔
6003
    }
6004

6005
    if (output) {
13,992✔
6006
      if (!pUsers) {
550✔
6007
        TSDB_CHECK_NULL(pUsers = tSimpleHashInit(32, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY)), code, lino,
275✔
6008
                        _exit, TSDB_CODE_OUT_OF_MEMORY);
6009
        tSimpleHashSetFreeFp(pUsers, (_hash_free_fn_t)mndUserFreeObj);
275✔
6010
        *ppUsers = pUsers;
275✔
6011
      }
6012
      void   *pVal = NULL;
550✔
6013
      int32_t userLen = strlen(pUser->name) + 1;
550✔
6014
      if ((pVal = tSimpleHashGet(pUsers, pUser->name, userLen)) != NULL) {
550✔
6015
        TAOS_CHECK_EXIT(mndUserRemoveDbPrivsImpl((SUserObj *)pVal, key, keyLen, NULL));
275✔
6016
      } else {
6017
        SUserObj newUser = {0};
275✔
6018
        if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
275✔
6019
          mndUserFreeObj(&newUser);
×
6020
          TAOS_CHECK_EXIT(code);
×
6021
        }
6022
        if ((code = tSimpleHashPut(pUsers, pUser->name, userLen, &newUser, sizeof(SUserObj)))) {
275✔
6023
          mndUserFreeObj(&newUser);
×
6024
          TAOS_CHECK_EXIT(code);
×
6025
        }
6026
      }
6027
    } else {
6028
      int64_t now = taosGetTimestampMs();
13,442✔
6029
      taosWLockLatch(&pUser->lock);
13,442✔
6030
      pUser->updateTime = now;
13,442✔
6031
      ++pUser->authVersion;
13,442✔
6032
      taosWUnLockLatch(&pUser->lock);
13,442✔
6033

6034
      SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
13,442✔
6035
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
13,442✔
6036
        TAOS_CHECK_EXIT(TSDB_CODE_OUT_OF_MEMORY);
×
6037
      }
6038
      TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
13,442✔
6039
    }
6040

6041
    sdbRelease(pSdb, pUser);
13,992✔
6042
    pUser = NULL;
13,992✔
6043
  }
6044
_exit:
696,164✔
6045
  if (pUser != NULL) sdbRelease(pSdb, pUser);
696,164✔
6046
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
696,164✔
6047
  TAOS_RETURN(code);
696,164✔
6048
}
6049

6050
static int32_t mndRoleRemoveDbPrivsImpl(SRoleObj *pRole, const char *key, int32_t keyLen, bool *pFound) {
×
6051
  bool found = false;
×
6052
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pRole->objPrivs, (char *)key, keyLen, found ? NULL : &found));
×
6053
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pRole->selectTbs, (char *)key, keyLen, found ? NULL : &found));
×
6054
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pRole->insertTbs, (char *)key, keyLen, found ? NULL : &found));
×
6055
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pRole->updateTbs, (char *)key, keyLen, found ? NULL : &found));
×
6056
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pRole->deleteTbs, (char *)key, keyLen, found ? NULL : &found));
×
6057
  if (pFound) *pFound = found;
×
6058
  TAOS_RETURN(0);
×
6059
}
6060

6061
static int32_t mndRoleRemoveDbPrivs(SMnode *pMnode, STrans *pTrans, const char *key, int32_t keyLen,
×
6062
                                    SSHashObj **ppRoles) {
6063
  int32_t    code = 0, lino = 0;
×
6064
  SSdb      *pSdb = pMnode->pSdb;
×
6065
  void      *pIter = NULL;
×
6066
  SRoleObj  *pRole = NULL;
×
6067
  SSHashObj *pRoles = ppRoles ? *ppRoles : NULL;
×
6068
  bool       output = (ppRoles != NULL);
×
6069
  while ((pIter = sdbFetch(pSdb, SDB_ROLE, pIter, (void **)&pRole))) {
×
6070
    bool found = false;
×
6071
    TAOS_CHECK_EXIT(mndRoleRemoveDbPrivsImpl(pRole, key, keyLen, &found));
×
6072
    if (!found) {
×
6073
      sdbRelease(pSdb, pRole);
×
6074
      pRole = NULL;
×
6075
      continue;
×
6076
    }
6077

6078
    if (output) {
×
6079
      if (!pRoles) {
×
6080
        TSDB_CHECK_NULL(pRoles = tSimpleHashInit(32, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY)), code, lino,
×
6081
                        _exit, TSDB_CODE_OUT_OF_MEMORY);
6082
        tSimpleHashSetFreeFp(pRoles, (_hash_free_fn_t)mndRoleFreeObj);
×
6083
        *ppRoles = pRoles;
×
6084
      }
6085
      void   *pVal = NULL;
×
6086
      int32_t roleLen = strlen(pRole->name) + 1;
×
6087
      if ((pVal = tSimpleHashGet(pRoles, pRole->name, roleLen)) != NULL) {
×
6088
        TAOS_CHECK_EXIT(mndRoleRemoveDbPrivsImpl((SRoleObj *)pVal, key, keyLen, NULL));
×
6089
      } else {
6090
        SRoleObj newRole = {0};
×
6091
        if ((code = mndRoleDupObj(pRole, &newRole)) != 0) {
×
6092
          mndRoleFreeObj(&newRole);
×
6093
          TAOS_CHECK_EXIT(code);
×
6094
        }
6095
        if ((code = tSimpleHashPut(pRoles, pRole->name, roleLen, &newRole, sizeof(SRoleObj)))) {
×
6096
          mndRoleFreeObj(&newRole);
×
6097
          TAOS_CHECK_EXIT(code);
×
6098
        }
6099
      }
6100
    } else {
6101
      int64_t now = taosGetTimestampMs();
×
6102
      taosWLockLatch(&pRole->lock);
×
6103
      pRole->updateTime = now;
×
6104
      ++pRole->version;
×
6105
      taosWUnLockLatch(&pRole->lock);
×
6106

6107
      SSdbRaw *pCommitRaw = mndRoleActionEncode(pRole);
×
6108
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
×
6109
        TAOS_CHECK_EXIT(TSDB_CODE_OUT_OF_MEMORY);
×
6110
      }
6111
      TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
×
6112
    }
6113

6114
    sdbRelease(pSdb, pRole);
×
6115
    pRole = NULL;
×
6116
  }
6117
_exit:
×
6118
  if (pRole != NULL) sdbRelease(pSdb, pRole);
×
6119
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
×
6120
  TAOS_RETURN(code);
×
6121
}
6122

6123
int32_t mndPrincipalRemoveDb(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SSHashObj **ppUsers, SSHashObj **ppRoles) {
696,164✔
6124
  TAOS_RETURN(mndUserRemoveDbPrivs(pMnode, pTrans, pDb->name, strlen(pDb->name), ppUsers));
696,164✔
6125
  return mndRoleRemoveDbPrivs(pMnode, pTrans, pDb->name, strlen(pDb->name), ppRoles);
6126
}
6127

6128
int32_t mndUserRemoveStb(SMnode *pMnode, STrans *pTrans, char *stb) {
468,800✔
6129
  return mndPrincipalRemoveObjPrivs(pMnode, pTrans, stb, PRIV_OBJ_TBL);
468,800✔
6130
}
6131

6132
static int32_t mndUserRemoveObjPrivs(SMnode *pMnode, STrans *pTrans, const char *key, int32_t keyLen,
714,319✔
6133
                                     EPrivObjType objType) {
6134
  int32_t   code = 0, lino = 0;
714,319✔
6135
  SSdb     *pSdb = pMnode->pSdb;
714,319✔
6136
  void     *pIter = NULL;
714,319✔
6137
  SUserObj *pUser = NULL;
714,319✔
6138
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser))) {
1,439,534✔
6139
    bool found = false;
725,215✔
6140
    if (taosHashGet(pUser->objPrivs, key, keyLen)) {
725,215✔
6141
      TAOS_CHECK_EXIT(taosHashRemove(pUser->objPrivs, key, keyLen));
2,851✔
6142
      found = true;
2,851✔
6143
    }
6144
    if (objType == PRIV_OBJ_TBL) {
725,215✔
6145
      SPrivTblPolicies *pTblPrivs = taosHashGet(pUser->selectTbs, key, keyLen);
469,509✔
6146
      if (pTblPrivs) {
469,509✔
6147
        TAOS_CHECK_EXIT(taosHashRemove(pUser->selectTbs, key, keyLen));
×
6148
        found = true;
×
6149
      }
6150
      pTblPrivs = taosHashGet(pUser->insertTbs, key, keyLen);
469,509✔
6151
      if (pTblPrivs) {
469,509✔
6152
        TAOS_CHECK_EXIT(taosHashRemove(pUser->insertTbs, key, keyLen));
×
6153
        found = true;
×
6154
      }
6155
      pTblPrivs = taosHashGet(pUser->updateTbs, key, keyLen);
469,509✔
6156
      if (pTblPrivs) {
469,509✔
6157
        TAOS_CHECK_EXIT(taosHashRemove(pUser->updateTbs, key, keyLen));
×
6158
        found = true;
×
6159
      }
6160
      pTblPrivs = taosHashGet(pUser->deleteTbs, key, keyLen);
469,509✔
6161
      if (pTblPrivs) {
469,509✔
6162
        TAOS_CHECK_EXIT(taosHashRemove(pUser->deleteTbs, key, keyLen));
×
6163
        found = true;
×
6164
      }
6165
    }
6166
    if (!found) {
725,215✔
6167
      sdbRelease(pSdb, pUser);
722,364✔
6168
      pUser = NULL;
722,364✔
6169
      continue;
722,364✔
6170
    }
6171

6172
    int64_t now = taosGetTimestampMs();
2,851✔
6173
    taosWLockLatch(&pUser->lock);
2,851✔
6174
    pUser->updateTime = now;
2,851✔
6175
    ++pUser->authVersion;
2,851✔
6176
    taosWUnLockLatch(&pUser->lock);
2,851✔
6177

6178
    SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
2,851✔
6179
    if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
2,851✔
6180
      TAOS_CHECK_EXIT(TSDB_CODE_OUT_OF_MEMORY);
×
6181
    }
6182
    TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
2,851✔
6183

6184
    sdbRelease(pSdb, pUser);
2,851✔
6185
    pUser = NULL;
2,851✔
6186
  }
6187
_exit:
714,319✔
6188
  if (pUser != NULL) sdbRelease(pSdb, pUser);
714,319✔
6189
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
714,319✔
6190
  TAOS_RETURN(code);
714,319✔
6191
}
6192

6193
static int32_t mndRoleRemoveObjPrivs(SMnode *pMnode, STrans *pTrans, const char *key, int32_t keyLen,
714,319✔
6194
                                     EPrivObjType objType) {
6195
  int32_t   code = 0, lino = 0;
714,319✔
6196
  SSdb     *pSdb = pMnode->pSdb;
714,319✔
6197
  void     *pIter = NULL;
714,319✔
6198
  SRoleObj *pRole = NULL;
714,319✔
6199
  while ((pIter = sdbFetch(pSdb, SDB_ROLE, pIter, (void **)&pRole))) {
5,000,233✔
6200
    // inherit system roles have no direct privileges
6201
    if (taosStrncasecmp(pRole->name, "sys", 3) == 0) {
4,285,914✔
6202
      sdbRelease(pSdb, pRole);
4,285,914✔
6203
      pRole = NULL;
4,285,914✔
6204
      continue;
4,285,914✔
6205
    }
6206
    bool found = false;
×
6207
    if (taosHashGet(pRole->objPrivs, key, keyLen)) {
×
6208
      TAOS_CHECK_EXIT(taosHashRemove(pRole->objPrivs, key, keyLen));
×
6209
      found = true;
×
6210
    }
6211

6212
    if (objType == PRIV_OBJ_TBL) {
×
6213
      SPrivTblPolicies *pTblPrivs = taosHashGet(pRole->selectTbs, key, keyLen);
×
6214
      if (pTblPrivs) {
×
6215
        TAOS_CHECK_EXIT(taosHashRemove(pRole->selectTbs, key, keyLen));
×
6216
        found = true;
×
6217
      }
6218
      pTblPrivs = taosHashGet(pRole->insertTbs, key, keyLen);
×
6219
      if (pTblPrivs) {
×
6220
        TAOS_CHECK_EXIT(taosHashRemove(pRole->insertTbs, key, keyLen));
×
6221
        found = true;
×
6222
      }
6223
      pTblPrivs = taosHashGet(pRole->updateTbs, key, keyLen);
×
6224
      if (pTblPrivs) {
×
6225
        TAOS_CHECK_EXIT(taosHashRemove(pRole->updateTbs, key, keyLen));
×
6226
        found = true;
×
6227
      }
6228
      pTblPrivs = taosHashGet(pRole->deleteTbs, key, keyLen);
×
6229
      if (pTblPrivs) {
×
6230
        TAOS_CHECK_EXIT(taosHashRemove(pRole->deleteTbs, key, keyLen));
×
6231
        found = true;
×
6232
      }
6233
    }
6234
    if (!found) {
×
6235
      sdbRelease(pSdb, pRole);
×
6236
      pRole = NULL;
×
6237
      continue;
×
6238
    }
6239
    int64_t now = taosGetTimestampMs();
×
6240
    taosWLockLatch(&pRole->lock);
×
6241
    pRole->updateTime = now;
×
6242
    ++pRole->version;
×
6243
    taosWUnLockLatch(&pRole->lock);
×
6244

6245
    SSdbRaw *pCommitRaw = mndRoleActionEncode(pRole);
×
6246
    if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
×
6247
      TAOS_CHECK_EXIT(TSDB_CODE_OUT_OF_MEMORY);
×
6248
    }
6249
    TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
×
6250

6251
    sdbRelease(pSdb, pRole);
×
6252
    pRole = NULL;
×
6253
  }
6254
_exit:
714,319✔
6255
  if (pRole != NULL) sdbRelease(pSdb, pRole);
714,319✔
6256
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
714,319✔
6257
  TAOS_RETURN(code);
714,319✔
6258
}
6259

6260
static int32_t mndPrincipalRemoveObjPrivs(SMnode *pMnode, STrans *pTrans, char *objFName, EPrivObjType objType) {
714,319✔
6261
  int32_t code = 0;
714,319✔
6262
  char    key[TSDB_PRIV_MAX_KEY_LEN] = {0};
714,319✔
6263
  int32_t keyLen = snprintf(key, sizeof(key), "%d.%s", objType, objFName) + 1;
714,319✔
6264
  TAOS_CHECK_RETURN(mndUserRemoveObjPrivs(pMnode, pTrans, key, keyLen, objType));
714,319✔
6265
  TAOS_CHECK_RETURN(mndRoleRemoveObjPrivs(pMnode, pTrans, key, keyLen, objType));
714,319✔
6266
  TAOS_RETURN(code);
714,319✔
6267
}
6268

6269
int32_t mndUserRemoveView(SMnode *pMnode, STrans *pTrans, char *view) {
149,976✔
6270
  return mndPrincipalRemoveObjPrivs(pMnode, pTrans, view, PRIV_OBJ_VIEW);
149,976✔
6271
}
6272

6273
int32_t mndUserRemoveTopic(SMnode *pMnode, STrans *pTrans, char *topic) {
95,543✔
6274
  return mndPrincipalRemoveObjPrivs(pMnode, pTrans, topic, PRIV_OBJ_TOPIC);
95,543✔
6275
}
6276

6277
int64_t mndGetUserIpWhiteListVer(SMnode *pMnode, SUserObj *pUser) {
×
6278
  // ver = 0, disable ip white list
6279
  // ver > 0, enable ip white list
6280
  return tsEnableWhiteList ? pUser->ipWhiteListVer : 0;
×
6281
}
6282

6283
int64_t mndGetUserTimeWhiteListVer(SMnode *pMnode, SUserObj *pUser) {
×
6284
  // ver = 0, disable datetime white list
6285
  // ver > 0, enable datetime white list
6286
  return tsEnableWhiteList ? pUser->timeWhiteListVer : 0;
×
6287
}
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