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

taosdata / TDengine / #4984

13 Mar 2026 03:38AM UTC coverage: 68.643% (-0.01%) from 68.653%
#4984

push

travis-ci

web-flow
feat/6641435300-save-audit-in-self (#34738)

434 of 584 new or added lines in 10 files covered. (74.32%)

3048 existing lines in 150 files now uncovered.

212713 of 309883 relevant lines covered (68.64%)

135561814.23 hits per line

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

64.96
/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() {
430,004✔
179
  _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
430,004✔
180

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

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

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

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

200
  void *pIter = taosHashIterate(userCache.users, NULL);
429,943✔
201
  while (pIter) {
878,675✔
202
    SCachedUserInfo *pInfo = *(SCachedUserInfo **)pIter;
448,732✔
203
    if (pInfo != NULL) {
448,732✔
204
      taosMemoryFree(pInfo->wlIp);
448,732✔
205
      taosMemoryFree(pInfo->wlTime);
448,732✔
206
      taosMemoryFree(pInfo);
448,732✔
207
    }
208
    pIter = taosHashIterate(userCache.users, pIter);
448,732✔
209
  }
210
  taosHashCleanup(userCache.users);
429,943✔
211

212
  (void)taosThreadRwlockDestroy(&userCache.rw);
429,943✔
213
}
214

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

218
  (void)taosThreadRwlockWrlock(&userCache.rw);
44,836✔
219

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

234
  (void)taosThreadRwlockUnlock(&userCache.rw);
44,836✔
235
}
44,836✔
236

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

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

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

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

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

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

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

269
  return pInfo;
493,568✔
270
}
271

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

275
  (void)taosThreadRwlockRdlock(&userCache.rw);
2,896,051✔
276

277
  SCachedUserInfo **ppInfo = taosHashGet(userCache.users, user, userLen);
2,896,332✔
278
  if (ppInfo != NULL && *ppInfo != NULL) {
2,896,331✔
279
    pLoginInfo->lastLoginTime = (*ppInfo)->loginInfo.lastLoginTime;
2,595,270✔
280
    pLoginInfo->failedLoginCount = (*ppInfo)->loginInfo.failedLoginCount;
2,594,939✔
281
    pLoginInfo->lastFailedLoginTime = (*ppInfo)->loginInfo.lastFailedLoginTime;
2,595,274✔
282
  } else {
283
    pLoginInfo->lastLoginTime = taosGetTimestampSec();
301,061✔
284
    pLoginInfo->failedLoginCount = 0;
301,061✔
285
    pLoginInfo->lastFailedLoginTime = 0;
301,061✔
286
  }
287

288
  (void)taosThreadRwlockUnlock(&userCache.rw);
2,895,419✔
289

290
  if (pLoginInfo->lastLoginTime == 0) {
2,896,243✔
291
    pLoginInfo->lastLoginTime = taosGetTimestampSec();
57,918✔
292
  }
293
}
2,895,937✔
294

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

298
  (void)taosThreadRwlockWrlock(&userCache.rw);
2,890,587✔
299

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

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

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

315
  if (a == NULL || b == NULL) {
1,429,421✔
316
    return false;
84,699✔
317
  }
318

319
  if (a->num != b->num) {
1,344,722✔
320
    return false;
274✔
321
  }
322

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

330
  return true;
1,344,174✔
331
}
332

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

336
  (void)taosThreadRwlockWrlock(&userCache.rw);
1,429,421✔
337

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

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

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

363
_OVER:
1,429,421✔
364
  (void)taosThreadRwlockUnlock(&userCache.rw);
1,429,421✔
365
  if (code < 0) {
1,429,421✔
UNCOV
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,429,421✔
369
}
370

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

374
  SSdb *pSdb = pMnode->pSdb;
521,390✔
375
  void *pIter = NULL;
521,390✔
376
  while (1) {
201,093✔
377
    SUserObj *pUser = NULL;
722,483✔
378
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
722,483✔
379
    if (pIter == NULL) {
722,483✔
380
      break;
521,390✔
381
    }
382

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

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

397
    taosMemoryFree(pInfo->wlIp);
201,093✔
398
    pInfo->wlIp = wl;
201,093✔
399

400
    sdbRelease(pSdb, pUser);
201,093✔
401
  }
402

403
  userCache.verIp++;
521,390✔
404

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

412
int64_t mndGetIpWhiteListVersion(SMnode *pMnode) {
45,354,030✔
413
  int64_t ver = 0;
45,354,030✔
414
  int32_t code = 0;
45,354,030✔
415

416
  if (mndEnableIpWhiteList(pMnode) != 0 && tsEnableWhiteList) {
45,354,030✔
417
    (void)taosThreadRwlockWrlock(&userCache.rw);
3,489✔
418

419
    if (userCache.verIp == 0) {
3,489✔
420
      // get user and dnode ip white list
UNCOV
421
      if ((code = userCacheRebuildIpWhiteList(pMnode)) != 0) {
×
UNCOV
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,489✔
429

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

433
  mDebug("ip-white-list on mnode ver: %" PRId64, ver);
45,354,030✔
434
  return ver;
45,354,030✔
435
}
436

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

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

448
  TAOS_RETURN(code);
521,390✔
449
}
450

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

454
  SSdb *pSdb = pMnode->pSdb;
512,652✔
455
  void *pIter = NULL;
512,652✔
456
  while (1) {
192,355✔
457
    SUserObj *pUser = NULL;
705,007✔
458
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
705,007✔
459
    if (pIter == NULL) {
705,007✔
460
      break;
512,652✔
461
    }
462

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

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

477
    taosMemoryFree(pInfo->wlTime);
192,355✔
478
    pInfo->wlTime = wl;
192,355✔
479

480
    sdbRelease(pSdb, pUser);
192,355✔
481
  }
482

483
  userCache.verTime++;
512,652✔
484

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

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

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

503
  TAOS_RETURN(code);
512,652✔
504
}
505

506
int64_t mndGetTimeWhiteListVersion(SMnode *pMnode) {
45,354,030✔
507
  int64_t ver = 0;
45,354,030✔
508
  int32_t code = 0;
45,354,030✔
509

510
  if (mndEnableTimeWhiteList(pMnode) != 0 && tsEnableWhiteList) {
45,354,030✔
511
    (void)taosThreadRwlockWrlock(&userCache.rw);
3,489✔
512

513
    if (userCache.verIp == 0) {
3,489✔
514
      // get user and dnode datetime white list
UNCOV
515
      if ((code = userCacheRebuildTimeWhiteList(pMnode)) != 0) {
×
UNCOV
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,489✔
523

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

527
  mDebug("datetime-white-list on mnode ver: %" PRId64, ver);
45,354,030✔
528
  return ver;
45,354,030✔
529
}
530

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

534
  SSdbTable table = {
430,004✔
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);
430,004✔
547
  mndSetMsgHandle(pMnode, TDMT_MND_ALTER_USER, mndProcessAlterUserReq);
430,004✔
548
  mndSetMsgHandle(pMnode, TDMT_MND_DROP_USER, mndProcessDropUserReq);
430,004✔
549
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_AUTH, mndProcessGetUserAuthReq);
430,004✔
550
  mndSetMsgHandle(pMnode, TDMT_MND_UPGRADE_USER, mndProcessUpgradeUserReq);
430,004✔
551
  mndSetMsgHandle(pMnode, TDMT_MND_UPGRADE_USER_RSP, mndProcessUpgradeUserRsp);
430,004✔
552

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

560
  mndSetMsgHandle(pMnode, TDMT_MND_CREATE_TOTP_SECRET, mndProcessCreateTotpSecretReq);
430,004✔
561
  mndSetMsgHandle(pMnode, TDMT_MND_DROP_TOTP_SECRET, mndProcessDropTotpSecretReq);
430,004✔
562

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

572
void mndCleanupUser(SMnode *pMnode) { userCacheCleanup(); }
429,943✔
573

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

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

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

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

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

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

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

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

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

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

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

634
  if (a == NULL || b == NULL) {
1,429,421✔
635
    return false;
84,699✔
636
  }
637

638
  if (a->num != b->num) {
1,344,722✔
639
    return false;
441✔
640
  }
641
  for (int i = 0; i < a->num; i++) {
4,033,558✔
642
    if (!isIpRangeEqual(&a->pIpRanges[i], &b->pIpRanges[i])) {
2,689,277✔
UNCOV
643
      return false;
×
644
    }
645
  }
646
  return true;
1,344,281✔
647
}
648

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

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

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

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

UNCOV
668
  if (ra->ipV6.addr[0] != rb->ipV6.addr[0]) {
×
UNCOV
669
    return (ra->ipV6.addr[0] < rb->ipV6.addr[0]) ? -1 : 1;
×
670
  }
671
  if (ra->ipV6.addr[1] != rb->ipV6.addr[1]) {
×
UNCOV
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,076✔
678
  (void)taosqsort(pList->pIpRanges, pList->num, sizeof(SIpRange), NULL, compareIpRange);
2,076✔
679
}
2,076✔
680

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

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

690
  if (pList->num == 0) {
1,416,771✔
UNCOV
691
    return tsnprintf(*buf, bufLen, "+ALL");
×
692
  }
693

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

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

709
  TAOS_CHECK_GOTO(tStartEncode(&encoder), &lino, _OVER);
3,990,503✔
710
  TAOS_CHECK_GOTO(tEncodeI32(&encoder, pList->num), &lino, _OVER);
7,981,006✔
711

712
  for (int i = 0; i < pList->num; i++) {
11,975,812✔
713
    SIpRange *pRange = &(pList->pIpRanges[i]);
7,985,309✔
714
    TAOS_CHECK_GOTO(tSerializeIpRange(&encoder, pRange), &lino, _OVER);
7,985,309✔
715
  }
716

717
  tEndEncode(&encoder);
3,990,503✔
718

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

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

735
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
3,194,474✔
736
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &pList->num), &lino, _OVER);
6,388,948✔
737

738
  for (int i = 0; i < pList->num; i++) {
9,585,961✔
739
    SIpRange *pRange = &(pList->pIpRanges[i]);
6,391,487✔
740
    TAOS_CHECK_GOTO(tDeserializeIpRange(&decoder, pRange, supportNeg), &lino, _OVER);
6,391,487✔
741
  }
742

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

UNCOV
752
static int32_t tDerializeIpWhileListFromOldVer(void *buf, int32_t len, SIpWhiteList *pList) {
×
UNCOV
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);
×
UNCOV
759
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &pList->num), &lino, _OVER);
×
760

761
  for (int i = 0; i < pList->num; i++) {
×
UNCOV
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

UNCOV
767
_OVER:
×
UNCOV
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,194,474✔
777
  int32_t           code = 0;
3,194,474✔
778
  int32_t           lino = 0;
3,194,474✔
779
  int32_t           num = 0;
3,194,474✔
780
  SIpWhiteListDual *p = NULL;
3,194,474✔
781
  SDecoder          decoder = {0};
3,194,474✔
782
  tDecoderInit(&decoder, buf, len);
3,194,474✔
783

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

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

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

UNCOV
804
static int32_t createIpWhiteListFromOldVer(void *buf, int32_t len, SIpWhiteList **ppList) {
×
UNCOV
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);
×
UNCOV
813
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &num), &lino, _OVER);
×
814

815
  p = taosMemoryCalloc(1, sizeof(SIpWhiteList) + num * sizeof(SIpV4Range));
×
UNCOV
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:
×
UNCOV
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;
×
UNCOV
829
  TAOS_RETURN(code);
×
830
}
831

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

841
  SIpRange v4 = {0};
392,413✔
842
  SIpRange v6 = {0};
392,413✔
843

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

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

851
#endif
852

853
_error:
392,413✔
854
  if (code != 0) {
392,413✔
UNCOV
855
    taosMemoryFree(*ppWhiteList);
×
UNCOV
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));
392,413✔
860
    memcpy(&(*ppWhiteList)->pIpRanges[1], &v6, sizeof(SIpRange));
392,413✔
861
  }
862
  return 0;
392,413✔
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,416,771✔
868
  int32_t bufLen = pUser->pTimeWhiteList->num * 32 + 8;
1,416,771✔
869
  *buf = taosMemoryCalloc(1, bufLen);
1,416,771✔
870
  if (*buf == NULL) {
1,416,771✔
UNCOV
871
    return 0;
×
872
  }
873

874
  int32_t pos = 0;
1,416,771✔
875
  if (pUser->pTimeWhiteList->num == 0) {
1,416,771✔
876
    pos += tsnprintf(*buf + pos, bufLen - pos, "+ALL");
1,342,243✔
877
    return pos;
1,342,243✔
878
  }
879

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

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

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

903
  return pos;
74,528✔
904
}
905

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

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

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

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

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

UNCOV
926
  return 0;
×
927
}
928

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

933
static void dropOldPasswords(SUserObj *pUser) {
9,769,678✔
934
  if (pUser->numOfPasswords <= pUser->passwordReuseMax) {
9,769,678✔
935
    return;
521,396✔
936
  }
937

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

943
  int32_t now = taosGetTimestampSec();
9,248,282✔
944
  int32_t index = reuseMax;
9,248,282✔
945
  while(index < pUser->numOfPasswords) {
9,248,282✔
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;
274✔
948
    if (now - expireTime >= pUser->passwordReuseTime) {
274✔
949
      break;
274✔
950
    }
UNCOV
951
    index++;
×
952
  }
953

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

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

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

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

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

990
#ifdef TD_ENTERPRISE
991

992
  userObj.ipWhiteListVer = taosGetTimestampMs();
309,357✔
993
  userObj.timeWhiteListVer = userObj.ipWhiteListVer;
309,357✔
994

995
  if (tsEnableAdvancedSecurity) {
309,357✔
UNCOV
996
    userObj.changePass = 1;  // force user to change password
×
UNCOV
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
309,357✔
1011
    userObj.connectTime = -1;
309,357✔
1012
    userObj.connectIdleTime = -1;
309,357✔
1013
    userObj.callPerSession = -1;
309,357✔
1014
    userObj.vnodePerCall = -1;
309,357✔
1015
    userObj.passwordReuseTime = 0;
309,357✔
1016
    userObj.passwordReuseMax = 0;
309,357✔
1017
    userObj.passwordLockTime = 1;
309,357✔
1018
    userObj.sessionPerUser = -1;
309,357✔
1019
    userObj.failedLoginAttempts = -1;
309,357✔
1020
    userObj.passwordLifeTime = -1;
309,357✔
1021
    userObj.passwordGraceTime = -1;
309,357✔
1022
    userObj.inactiveAccountTime = -1;
309,357✔
1023
  }
1024

1025
  userObj.allowTokenNum = TSDB_USER_ALLOW_TOKEN_NUM_DEFAULT;
309,357✔
1026
  userObj.tokenNum = 0;
309,357✔
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));
309,357✔
1051
  if (userObj.pTimeWhiteList == NULL) {
309,357✔
UNCOV
1052
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _ERROR);
×
1053
  }
1054

1055
  TAOS_CHECK_GOTO(createDefaultIpWhiteList(&userObj.pIpWhiteListDual), &lino, _ERROR);
309,357✔
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) {
309,357✔
1058
    userObj.superUser = 1;
309,357✔
1059
    userObj.createdb = 1;
309,357✔
1060
    userObj.sessionPerUser = -1;
309,357✔
1061
    userObj.callPerSession = -1;
309,357✔
1062
    userObj.vnodePerCall = -1;
309,357✔
1063
    userObj.failedLoginAttempts = -1;
309,357✔
1064
    userObj.passwordGraceTime = -1;
309,357✔
1065
    userObj.inactiveAccountTime = -1;
309,357✔
1066
  }
1067

1068
  userObj.roles = taosHashInit(1, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
309,357✔
1069
  if (userObj.roles == NULL) {
309,357✔
UNCOV
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)) ||
618,714✔
1074
      (code = taosHashPut(userObj.roles, TSDB_ROLE_SYSSEC, strlen(TSDB_ROLE_SYSSEC) + 1, NULL, 0)) ||
618,714✔
1075
      (code = taosHashPut(userObj.roles, TSDB_ROLE_SYSAUDIT, strlen(TSDB_ROLE_SYSAUDIT) + 1, NULL, 0))) {
309,357✔
UNCOV
1076
    TAOS_CHECK_GOTO(code, &lino, _ERROR);
×
1077
  }
1078

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

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

1085
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_ROLE, NULL, "create-user");
309,357✔
1086
  if (pTrans == NULL) {
309,357✔
UNCOV
1087
    sdbFreeRaw(pRaw);
×
UNCOV
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);
309,357✔
1092

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

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

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

UNCOV
1110
_ERROR:
×
UNCOV
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));
×
UNCOV
1116
  TAOS_RETURN(code);
×
1117
}
1118

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

UNCOV
1123
static int32_t mndUserPrivUpgradeDbOwners(SMnode *pMnode, SRpcMsg *pReq) {
×
UNCOV
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");
×
UNCOV
1130
  if (pTrans == NULL) {
×
1131
    TAOS_CHECK_EXIT(terrno);
×
1132
  }
1133

UNCOV
1134
  while ((pIter = sdbFetch(pSdb, SDB_DB, pIter, (void **)&pObj))) {
×
UNCOV
1135
    if (pObj->cfg.isMount) {
×
1136
      sdbRelease(pSdb, pObj);
×
1137
      continue;
×
1138
    }
1139
    if (pObj->ownerId != 0) {
×
UNCOV
1140
      sdbRelease(pSdb, pObj);
×
1141
      continue;
×
1142
    }
1143
    SUserObj *pUser = NULL;
×
UNCOV
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) {
×
UNCOV
1151
      mndReleaseUser(pMnode, pUser);
×
1152
      sdbRelease(pSdb, pObj);
×
1153
      continue;
×
1154
    }
1155
    SDbObj newObj = {0};
×
UNCOV
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

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

1172
_exit:
×
UNCOV
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

UNCOV
1180
static int32_t mndUserPrivUpgradeOwnedDbs(SMnode *pMnode, SUserObj *pUser) {
×
UNCOV
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));
×
UNCOV
1193
    sdbRelease(pSdb, pObj);
×
1194
    pObj = NULL;
×
1195
  }
1196
_exit:
×
UNCOV
1197
  if (pIter) sdbCancelFetch(pSdb, pIter);
×
1198
  if (pObj) sdbRelease(pSdb, pObj);
×
1199
  TAOS_RETURN(code);
×
1200
}
1201

1202
#ifdef TD_ENTERPRISE
UNCOV
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;
×
UNCOV
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))) {
×
UNCOV
1213
    size_t keyLen = 0;
×
1214
    key = taosHashGetKey(pIter, &keyLen);
×
1215

1216
    SName name = {0};
×
UNCOV
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);
×
UNCOV
1220
    snprintf(alterReq.tblName, TSDB_TABLE_NAME_LEN, "%s", name.tname);
×
1221

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

UNCOV
1224
    if ((objType == PRIV_OBJ_TBL) && (((char *)pIter)[0] != 0) && (((char *)pIter)[1] != 0)) {
×
UNCOV
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'
×
UNCOV
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

UNCOV
1239
    TAOS_CHECK_EXIT(mndAlterUserPrivInfo(pMnode, pUser, &alterReq));
×
UNCOV
1240
    tFreeSAlterRoleReq(&alterReq);
×
1241
  }
1242
_exit:
×
UNCOV
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
 */
UNCOV
1251
static int32_t mndUserPrivUpgradeRwDbs(SMnode *pMnode, SUserObj *pUser, SHashObj *pDbs, int8_t rwType) {
×
UNCOV
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:
×
UNCOV
1260
  TAOS_RETURN(code);
×
1261
}
1262

UNCOV
1263
static int32_t mndUserPrivUpgradeUsedDbs(SMnode *pMnode, SUserObj *pUser, SHashObj *pDbs) {
×
UNCOV
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))) {
×
UNCOV
1272
    key = taosHashGetKey(pIter, NULL);
×
1273

1274
    SName name = {0};
×
UNCOV
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

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

UNCOV
1288
static int32_t mndUserPrivUpgradeTopics(SMnode *pMnode, SUserObj *pUser, SHashObj *pTopics) {
×
UNCOV
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

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

1304
    SName name = {0};
×
UNCOV
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;
×
UNCOV
1311
    if (mndAcquireTopic(pMnode, key, &pTopic)) {
×
1312
      continue;  // no topic exists
×
1313
    }
1314
    snprintf(alterReq.objFName, TSDB_OBJ_FNAME_LEN, "%s", pTopic->db);
×
UNCOV
1315
    mndReleaseTopic(pMnode, pTopic);
×
1316

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

UNCOV
1319
    TAOS_CHECK_EXIT(mndAlterUserPrivInfo(pMnode, pUser, &alterReq));
×
1320
  }
1321
_exit:
×
UNCOV
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
 */
UNCOV
1331
static int32_t mndUserPrivUpgradeUser(SMnode *pMnode, SUserObj *pObj) {
×
UNCOV
1332
  int32_t          code = 0, lino = 0;
×
1333
  SPrivHashObjSet *pPrivSet = pObj->legacyPrivs;
×
1334

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

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

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

UNCOV
1393
static int32_t mndUserPrivUpgradeUsers(SMnode *pMnode, SRpcMsg *pReq) {
×
UNCOV
1394
  int32_t   code = 0, lino = 0;
×
1395
  SSdb     *pSdb = pMnode->pSdb;
×
1396
  SUserObj *pObj = NULL;
×
1397
  void     *pIter = NULL;
×
1398
  SUserObj  newObj = {0};
×
1399

1400
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pObj))) {
×
UNCOV
1401
    if (pObj->uid != 0 && pObj->legacyPrivs == NULL) {
×
1402
      sdbRelease(pSdb, pObj);
×
1403
      pObj = NULL;
×
1404
      continue;
×
1405
    }
1406
    if (pObj->uid == 0) {
×
1407
      // Assign uid firstly because the transactions in mndUserPrivUpgradeUsers may not finish when
1408
      // mndUserPrivUpgradeDbOwners is called
UNCOV
1409
      pObj->uid = mndGenerateUid(pObj->name, strlen(pObj->name));
×
1410
    }
1411
    memset(&newObj, 0, sizeof(SUserObj));
×
UNCOV
1412
    TAOS_CHECK_EXIT(mndUserDupObj(pObj, &newObj));
×
1413
    TAOS_CHECK_EXIT(mndUserPrivUpgradeUser(pMnode, &newObj));
×
1414
    TAOS_CHECK_EXIT(mndAlterUser(pMnode, &newObj, pReq));
×
1415
    mndUserFreeObj(&newObj);
×
1416
    sdbRelease(pSdb, pObj);
×
1417
    pObj = NULL;
×
1418
  }
1419
_exit:
×
UNCOV
1420
  sdbCancelFetch(pSdb, pIter);
×
1421
  sdbRelease(pSdb, pObj);
×
1422
  mndUserFreeObj(&newObj);
×
1423
  if (code < 0) {
×
1424
    mError("failed at line %d to upgrade db owner uid since %s", lino, tstrerror(code));
×
1425
  }
1426
  TAOS_RETURN(code);
×
1427
}
1428

UNCOV
1429
static int32_t mndProcessUpgradeUserReq(SRpcMsg *pReq) {
×
UNCOV
1430
  SMnode *pMnode = pReq->info.node;
×
1431
  int32_t code = 0, lino = 0;
×
1432

1433
  TAOS_CHECK_EXIT(mndUserPrivUpgradeUsers(pMnode, pReq));
×
UNCOV
1434
  TAOS_CHECK_EXIT(mndUserPrivUpgradeDbOwners(pMnode, pReq));
×
1435
_exit:
×
1436
  if (code < 0) {
×
1437
    mError("failed at line %d to upgrade users since %s", lino, tstrerror(code));
×
1438
  }
1439
  TAOS_RETURN(code);
×
1440
}
1441

UNCOV
1442
static int32_t mndProcessUpgradeUserRsp(SRpcMsg *pReq) { return 0;}
×
1443

1444
static int32_t mndUpgradeUsers(SMnode *pMnode, int32_t version) {
388,772✔
1445
  int32_t code = 0, lino = 0;
388,772✔
1446
  if (upgradeSecurity == 0) return code;
388,772✔
UNCOV
1447
  if (!mndIsLeader(pMnode)) return code;
×
1448

1449
  SRpcMsg rpcMsg = {.msgType = TDMT_MND_UPGRADE_USER, .info.ahandle = 0, .info.notFreeAhandle = 1};
×
UNCOV
1450
  SEpSet  epSet = {0};
×
1451
  mndGetMnodeEpSet(pMnode, &epSet);
×
1452
  TAOS_CHECK_EXIT(tmsgSendReq(&epSet, &rpcMsg));
×
1453
_exit:
×
1454
  if (code < 0) {
×
1455
    mError("failed at line %d to upgrade users since %s", lino, tstrerror(code));
×
1456
  }
1457
  TAOS_RETURN(code);
×
1458
}
1459

1460
static int32_t tSerializeUserObjExt(void *buf, int32_t bufLen, SUserObj *pObj) {
7,981,006✔
1461
  int32_t  code = 0, lino = 0;
7,981,006✔
1462
  int32_t  tlen = 0;
7,981,006✔
1463
  void    *pIter = NULL;
7,981,006✔
1464
  SEncoder encoder = {0};
7,981,006✔
1465
  tEncoderInit(&encoder, buf, bufLen);
7,981,006✔
1466

1467
  TAOS_CHECK_EXIT(tStartEncode(&encoder));
7,981,006✔
1468
  TAOS_CHECK_EXIT(tEncodeI64v(&encoder, pObj->uid));
15,962,012✔
1469

1470
  TAOS_CHECK_EXIT(tSerializePrivSysObjPolicies(&encoder, &pObj->sysPrivs, pObj->objPrivs));
7,981,006✔
1471

1472
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->selectTbs));
7,981,006✔
1473
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->insertTbs));
7,981,006✔
1474
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->updateTbs));
7,981,006✔
1475
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->deleteTbs));
7,981,006✔
1476

1477
  int32_t nRoles = taosHashGetSize(pObj->roles);
7,981,006✔
1478
  TAOS_CHECK_EXIT(tEncodeI32v(&encoder, nRoles));
7,981,006✔
1479

1480
  while ((pIter = taosHashIterate(pObj->roles, pIter))) {
25,218,910✔
1481
    size_t keyLen = 0;
17,237,904✔
1482
    char  *key = taosHashGetKey(pIter, &keyLen);  // key: role name
17,237,904✔
1483
    TAOS_CHECK_EXIT(tEncodeCStr(&encoder, key));
17,237,904✔
1484

1485
    uint8_t flag = *(uint8_t *)pIter;
17,237,904✔
1486
    TAOS_CHECK_EXIT(tEncodeU8(&encoder, flag));  // value: 0 reset, 1 set(default)
34,475,808✔
1487
  }
1488

1489
  int32_t nOwnedDbs = taosHashGetSize(pObj->ownedDbs);
7,981,006✔
1490
  TAOS_CHECK_EXIT(tEncodeI32v(&encoder, nOwnedDbs));
7,981,006✔
1491
  pIter = NULL;
7,981,006✔
1492
  while ((pIter = taosHashIterate(pObj->ownedDbs, pIter))) {
30,183,032✔
1493
    size_t keyLen = 0;
22,202,026✔
1494
    char  *key = taosHashGetKey(pIter, &keyLen);  // key: dbFName
22,202,026✔
1495
    TAOS_CHECK_EXIT(tEncodeCStr(&encoder, key));
22,202,026✔
1496
  }
1497

1498
  tEndEncode(&encoder);
7,981,006✔
1499
  tlen = encoder.pos;
7,981,006✔
1500
_exit:
7,981,006✔
1501
  tEncoderClear(&encoder);
7,981,006✔
1502
  if (code < 0) {
7,981,006✔
UNCOV
1503
    mError("user:%s, %s failed at line %d since %s", pObj->user, __func__, lino, tstrerror(code));
×
UNCOV
1504
    TAOS_RETURN(code);
×
1505
  }
1506

1507
  return tlen;
7,981,006✔
1508
}
1509

1510
static int32_t tDeserializeUserObjExt(void *buf, int32_t bufLen, SUserObj *pObj) {
3,194,474✔
1511
  int32_t  code = 0, lino = 0;
3,194,474✔
1512
  SDecoder decoder = {0};
3,194,474✔
1513
  tDecoderInit(&decoder, buf, bufLen);
3,194,474✔
1514

1515
  TAOS_CHECK_EXIT(tStartDecode(&decoder));
3,194,474✔
1516
  TAOS_CHECK_EXIT(tDecodeI64v(&decoder, &pObj->uid));
6,388,948✔
1517
  TAOS_CHECK_EXIT(tDeserializePrivSysObjPolicies(&decoder, &pObj->sysPrivs, &pObj->objPrivs));
3,194,474✔
1518
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->selectTbs));
3,194,474✔
1519
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->insertTbs));
3,194,474✔
1520
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->updateTbs));
3,194,474✔
1521
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->deleteTbs));
3,194,474✔
1522
  int32_t nRoles = 0;
3,194,474✔
1523
  TAOS_CHECK_EXIT(tDecodeI32v(&decoder, &nRoles));
3,194,474✔
1524
  if (nRoles > 0) {
3,194,474✔
1525
    if (!pObj->roles &&
3,160,625✔
1526
        !(pObj->roles = taosHashInit(nRoles, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), 1, HASH_ENTRY_LOCK))) {
3,160,625✔
UNCOV
1527
      TAOS_CHECK_EXIT(terrno);
×
1528
    }
1529
    for (int32_t i = 0; i < nRoles; i++) {
9,642,400✔
1530
      int32_t keyLen = 0;
6,481,775✔
1531
      char   *key = NULL;
6,481,775✔
1532
      TAOS_CHECK_EXIT(tDecodeCStrAndLen(&decoder, &key, &keyLen));
6,481,775✔
1533
      uint8_t flag = 0;
6,481,775✔
1534
      TAOS_CHECK_EXIT(tDecodeU8(&decoder, &flag));
6,481,775✔
1535
      TAOS_CHECK_EXIT(taosHashPut(pObj->roles, key, keyLen + 1, &flag, sizeof(flag)));
6,481,775✔
1536
    }
1537
  }
1538
  if (!tDecodeIsEnd(&decoder)) {
3,194,474✔
1539
    int32_t nOwnedDbs = 0;
3,194,474✔
1540
    TAOS_CHECK_EXIT(tDecodeI32v(&decoder, &nOwnedDbs));
3,194,474✔
1541
    if (nOwnedDbs > 0) {
3,194,474✔
1542
      if (!pObj->ownedDbs &&
1,321,822✔
1543
          !(pObj->ownedDbs =
1,321,822✔
1544
                taosHashInit(nOwnedDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), 1, HASH_ENTRY_LOCK))) {
1,321,822✔
UNCOV
1545
        TAOS_CHECK_EXIT(terrno);
×
1546
      }
1547
      for (int32_t i = 0; i < nOwnedDbs; ++i) {
11,330,021✔
1548
        int32_t keyLen = 0;
10,008,199✔
1549
        char   *key = NULL;
10,008,199✔
1550
        TAOS_CHECK_EXIT(tDecodeCStrAndLen(&decoder, &key, &keyLen));
10,008,199✔
1551
        TAOS_CHECK_EXIT(taosHashPut(pObj->ownedDbs, key, keyLen + 1, NULL, 0));
10,008,199✔
1552
      }
1553
    }
1554
  }
1555

1556
_exit:
3,194,107✔
1557
  tEndDecode(&decoder);
3,194,474✔
1558
  tDecoderClear(&decoder);
3,194,474✔
1559
  if (code < 0) {
3,194,474✔
UNCOV
1560
    mError("user, %s failed at line %d since %s, row:%p", __func__, lino, tstrerror(code), pObj);
×
1561
  }
1562
  TAOS_RETURN(code);
3,194,474✔
1563
}
1564

1565
SSdbRaw *mndUserActionEncode(SUserObj *pUser) {
3,990,503✔
1566
  int32_t code = 0;
3,990,503✔
1567
  int32_t lino = 0;
3,990,503✔
1568
  int32_t passReserve = (sizeof(SUserPassword) + 8) * pUser->numOfPasswords + 4;
3,990,503✔
UNCOV
1569
  int32_t ipWhiteReserve =
×
1570
      pUser->pIpWhiteListDual ? (sizeof(SIpRange) * pUser->pIpWhiteListDual->num + sizeof(SIpWhiteListDual) + 4) : 16;
3,990,503✔
1571
  int32_t timeWhiteReserve =
×
1572
      pUser->pTimeWhiteList
3,990,503✔
1573
          ? (sizeof(SDateTimeWhiteListItem) * pUser->pTimeWhiteList->num + sizeof(SDateTimeWhiteList) + 4)
3,990,503✔
1574
          : 16;
1575
  int32_t numOfReadDbs = 0;     // taosHashGetSize(pUser->readDbs);
3,990,503✔
1576
  int32_t numOfWriteDbs = 0;    // taosHashGetSize(pUser->writeDbs);
3,990,503✔
1577
  int32_t numOfReadTbs = 0;     // taosHashGetSize(pUser->readTbs);
3,990,503✔
1578
  int32_t numOfWriteTbs = 0;    // taosHashGetSize(pUser->writeTbs);
3,990,503✔
1579
  int32_t numOfAlterTbs = 0;    // taosHashGetSize(pUser->alterTbs);
3,990,503✔
1580
  int32_t numOfReadViews = 0;   // taosHashGetSize(pUser->readViews);
3,990,503✔
1581
  int32_t numOfWriteViews = 0;  // taosHashGetSize(pUser->writeViews);
3,990,503✔
1582
  int32_t numOfAlterViews = 0;  // taosHashGetSize(pUser->alterViews);
3,990,503✔
1583
  int32_t numOfTopics = 0;      // taosHashGetSize(pUser->topics);
3,990,503✔
1584
  int32_t numOfUseDbs = 0;      // taosHashGetSize(pUser->useDbs);
3,990,503✔
1585
  int32_t numOfRoles = taosHashGetSize(pUser->roles);
3,990,503✔
1586
  int32_t size = sizeof(SUserObj) + USER_RESERVE_SIZE + (numOfReadDbs + numOfWriteDbs) * TSDB_DB_FNAME_LEN +
3,990,503✔
1587
                 numOfTopics * TSDB_TOPIC_FNAME_LEN + ipWhiteReserve + timeWhiteReserve + passReserve;
3,990,503✔
1588
  char    *buf = NULL;
3,990,503✔
1589
  SSdbRaw *pRaw = NULL;
3,990,503✔
1590

1591
  char *stb = NULL;
3,990,503✔
1592
#if 0
1593
  stb = taosHashIterate(pUser->readTbs, NULL);
1594
  while (stb != NULL) {
1595
    size_t keyLen = 0;
1596
    void  *key = taosHashGetKey(stb, &keyLen);
1597
    size += sizeof(int32_t);
1598
    size += keyLen;
1599

1600
    size_t valueLen = 0;
1601
    valueLen = strlen(stb) + 1;
1602
    size += sizeof(int32_t);
1603
    size += valueLen;
1604
    stb = taosHashIterate(pUser->readTbs, stb);
1605
  }
1606

1607
  stb = taosHashIterate(pUser->writeTbs, NULL);
1608
  while (stb != NULL) {
1609
    size_t keyLen = 0;
1610
    void  *key = taosHashGetKey(stb, &keyLen);
1611
    size += sizeof(int32_t);
1612
    size += keyLen;
1613

1614
    size_t valueLen = 0;
1615
    valueLen = strlen(stb) + 1;
1616
    size += sizeof(int32_t);
1617
    size += valueLen;
1618
    stb = taosHashIterate(pUser->writeTbs, stb);
1619
  }
1620
  stb = taosHashIterate(pUser->alterTbs, NULL);
1621
  while (stb != NULL) {
1622
    size_t keyLen = 0;
1623
    void  *key = taosHashGetKey(stb, &keyLen);
1624
    size += sizeof(int32_t);
1625
    size += keyLen;
1626

1627
    size_t valueLen = 0;
1628
    valueLen = strlen(stb) + 1;
1629
    size += sizeof(int32_t);
1630
    size += valueLen;
1631
    stb = taosHashIterate(pUser->alterTbs, stb);
1632
  }
1633

1634
  stb = taosHashIterate(pUser->readViews, NULL);
1635
  while (stb != NULL) {
1636
    size_t keyLen = 0;
1637
    void  *key = taosHashGetKey(stb, &keyLen);
1638
    size += sizeof(int32_t);
1639
    size += keyLen;
1640

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

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

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

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

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

1676
  int32_t *useDb = taosHashIterate(pUser->useDbs, NULL);
1677
  while (useDb != NULL) {
1678
    size_t keyLen = 0;
1679
    void  *key = taosHashGetKey(useDb, &keyLen);
1680
    size += sizeof(int32_t);
1681
    size += keyLen;
1682
    size += sizeof(int32_t);
1683
    useDb = taosHashIterate(pUser->useDbs, useDb);
1684
  }
1685
#endif
1686
  int32_t sizeExt = tSerializeUserObjExt(NULL, 0, pUser);
3,990,503✔
1687
  if (sizeExt < 0) {
3,990,503✔
UNCOV
1688
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1689
  }
1690
  size += sizeExt;
3,990,503✔
1691

1692
  pRaw = sdbAllocRaw(SDB_USER, USER_VER_NUMBER, size);
3,990,503✔
1693
  if (pRaw == NULL) {
3,990,503✔
UNCOV
1694
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1695
  }
1696

1697
  int32_t dataPos = 0;
3,990,503✔
1698
  SDB_SET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN, _OVER)
3,990,503✔
1699

1700
  dropOldPasswords(pUser);
3,990,503✔
1701
  SDB_SET_INT32(pRaw, dataPos, pUser->numOfPasswords, _OVER)
3,990,503✔
1702
  for (int32_t i = 0; i < pUser->numOfPasswords; i++) {
8,736,013✔
1703
    SDB_SET_BINARY(pRaw, dataPos, pUser->passwords[i].pass, sizeof(pUser->passwords[i].pass), _OVER)
4,745,510✔
1704
    SDB_SET_INT32(pRaw, dataPos, pUser->passwords[i].setTime, _OVER)
4,745,510✔
1705
  }
1706
  SDB_SET_BINARY(pRaw, dataPos, pUser->salt, sizeof(pUser->salt), _OVER)
3,990,503✔
1707

1708
  SDB_SET_BINARY(pRaw, dataPos, pUser->acct, TSDB_USER_LEN, _OVER)
3,990,503✔
1709
  SDB_SET_INT64(pRaw, dataPos, pUser->createdTime, _OVER)
3,990,503✔
1710
  SDB_SET_INT64(pRaw, dataPos, pUser->updateTime, _OVER)
3,990,503✔
1711
  SDB_SET_INT8(pRaw, dataPos, pUser->superUser, _OVER)
3,990,503✔
1712
  SDB_SET_INT8(pRaw, dataPos, pUser->sysInfo, _OVER)
3,990,503✔
1713
  SDB_SET_INT8(pRaw, dataPos, pUser->enable, _OVER)
3,990,503✔
1714
  SDB_SET_UINT8(pRaw, dataPos, pUser->flag, _OVER)
3,990,503✔
1715
  SDB_SET_INT32(pRaw, dataPos, pUser->authVersion, _OVER)
3,990,503✔
1716
  SDB_SET_INT32(pRaw, dataPos, pUser->passVersion, _OVER)
3,990,503✔
1717
  SDB_SET_INT32(pRaw, dataPos, numOfReadDbs, _OVER)
3,990,503✔
1718
  SDB_SET_INT32(pRaw, dataPos, numOfWriteDbs, _OVER)
3,990,503✔
1719
  SDB_SET_INT32(pRaw, dataPos, numOfTopics, _OVER)
3,990,503✔
1720
#if 0
1721
  char *db = taosHashIterate(pUser->readDbs, NULL);
1722
  while (db != NULL) {
1723
    SDB_SET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER);
1724
    db = taosHashIterate(pUser->readDbs, db);
1725
  }
1726

1727
  db = taosHashIterate(pUser->writeDbs, NULL);
1728
  while (db != NULL) {
1729
    SDB_SET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER);
1730
    db = taosHashIterate(pUser->writeDbs, db);
1731
  }
1732
  char *topic = taosHashIterate(pUser->topics, NULL);
1733
  while (topic != NULL) {
1734
    SDB_SET_BINARY(pRaw, dataPos, topic, TSDB_TOPIC_FNAME_LEN, _OVER);
1735
    topic = taosHashIterate(pUser->topics, topic);
1736
  }
1737
#endif
1738
  SDB_SET_INT32(pRaw, dataPos, numOfReadTbs, _OVER)
3,990,503✔
1739
  SDB_SET_INT32(pRaw, dataPos, numOfWriteTbs, _OVER)
3,990,503✔
1740
  SDB_SET_INT32(pRaw, dataPos, numOfAlterTbs, _OVER)
3,990,503✔
1741
  SDB_SET_INT32(pRaw, dataPos, numOfReadViews, _OVER)
3,990,503✔
1742
  SDB_SET_INT32(pRaw, dataPos, numOfWriteViews, _OVER)
3,990,503✔
1743
  SDB_SET_INT32(pRaw, dataPos, numOfAlterViews, _OVER)
3,990,503✔
1744
  SDB_SET_INT32(pRaw, dataPos, numOfUseDbs, _OVER)
3,990,503✔
1745

1746
#if 0
1747
  stb = taosHashIterate(pUser->readTbs, NULL);
1748
  while (stb != NULL) {
1749
    size_t keyLen = 0;
1750
    void  *key = taosHashGetKey(stb, &keyLen);
1751
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1752
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1753

1754
    size_t valueLen = 0;
1755
    valueLen = strlen(stb) + 1;
1756
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
1757
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
1758
    stb = taosHashIterate(pUser->readTbs, stb);
1759
  }
1760

1761
  stb = taosHashIterate(pUser->writeTbs, NULL);
1762
  while (stb != NULL) {
1763
    size_t keyLen = 0;
1764
    void  *key = taosHashGetKey(stb, &keyLen);
1765
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1766
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1767

1768
    size_t valueLen = 0;
1769
    valueLen = strlen(stb) + 1;
1770
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
1771
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
1772
    stb = taosHashIterate(pUser->writeTbs, stb);
1773
  }
1774
  stb = taosHashIterate(pUser->alterTbs, NULL);
1775
  while (stb != NULL) {
1776
    size_t keyLen = 0;
1777
    void  *key = taosHashGetKey(stb, &keyLen);
1778
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1779
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1780

1781
    size_t valueLen = 0;
1782
    valueLen = strlen(stb) + 1;
1783
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
1784
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
1785
    stb = taosHashIterate(pUser->alterTbs, stb);
1786
  }
1787

1788
  stb = taosHashIterate(pUser->readViews, NULL);
1789
  while (stb != NULL) {
1790
    size_t keyLen = 0;
1791
    void  *key = taosHashGetKey(stb, &keyLen);
1792
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1793
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1794

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

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

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

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

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

1830
  useDb = taosHashIterate(pUser->useDbs, NULL);
1831
  while (useDb != NULL) {
1832
    size_t keyLen = 0;
1833
    void  *key = taosHashGetKey(useDb, &keyLen);
1834
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1835
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1836

1837
    SDB_SET_INT32(pRaw, dataPos, *useDb, _OVER)
1838
    useDb = taosHashIterate(pUser->useDbs, useDb);
1839
  }
1840
#endif
1841
  // save white list
1842
  int32_t num = pUser->pIpWhiteListDual->num;
3,990,503✔
1843
  int32_t tlen = sizeof(SIpWhiteListDual) + num * sizeof(SIpRange) + 4;
3,990,503✔
1844
  int32_t maxBufLen = TMAX(tlen, sizeExt);
3,990,503✔
1845
  if ((buf = taosMemoryCalloc(1, maxBufLen)) == NULL) {
3,990,503✔
UNCOV
1846
    TAOS_CHECK_GOTO(terrno, NULL, _OVER);
×
1847
  }
1848
  int32_t len = 0;
3,990,503✔
1849
  TAOS_CHECK_GOTO(tSerializeIpWhiteList(buf, tlen, pUser->pIpWhiteListDual, &len), &lino, _OVER);
3,990,503✔
1850

1851
  SDB_SET_INT32(pRaw, dataPos, len, _OVER);
3,990,503✔
1852
  SDB_SET_BINARY(pRaw, dataPos, buf, len, _OVER);
3,990,503✔
1853

1854
  SDB_SET_INT64(pRaw, dataPos, pUser->ipWhiteListVer, _OVER);
3,990,503✔
1855
  SDB_SET_INT8(pRaw, dataPos, pUser->passEncryptAlgorithm, _OVER);
3,990,503✔
1856

1857
  SDB_SET_BINARY(pRaw, dataPos, pUser->totpsecret, sizeof(pUser->totpsecret), _OVER);
3,990,503✔
1858
  SDB_SET_INT8(pRaw, dataPos, pUser->changePass, _OVER);
3,990,503✔
1859
  SDB_SET_INT32(pRaw, dataPos, pUser->sessionPerUser, _OVER);
3,990,503✔
1860
  SDB_SET_INT32(pRaw, dataPos, pUser->connectTime, _OVER);
3,990,503✔
1861
  SDB_SET_INT32(pRaw, dataPos, pUser->connectIdleTime, _OVER);
3,990,503✔
1862
  SDB_SET_INT32(pRaw, dataPos, pUser->callPerSession, _OVER);
3,990,503✔
1863
  SDB_SET_INT32(pRaw, dataPos, pUser->vnodePerCall, _OVER);
3,990,503✔
1864
  SDB_SET_INT32(pRaw, dataPos, pUser->failedLoginAttempts, _OVER);
3,990,503✔
1865
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordLifeTime, _OVER);
3,990,503✔
1866
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordReuseTime, _OVER);
3,990,503✔
1867
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordReuseMax, _OVER);
3,990,503✔
1868
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordLockTime, _OVER);
3,990,503✔
1869
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordGraceTime, _OVER);
3,990,503✔
1870
  SDB_SET_INT32(pRaw, dataPos, pUser->inactiveAccountTime, _OVER);
3,990,503✔
1871
  SDB_SET_INT32(pRaw, dataPos, pUser->allowTokenNum, _OVER);
3,990,503✔
1872
  SDB_SET_INT32(pRaw, dataPos, pUser->tokenNum, _OVER);
3,990,503✔
1873

1874
  SDB_SET_INT32(pRaw, dataPos, pUser->pTimeWhiteList->num, _OVER);
3,990,503✔
1875
  for (int32_t i = 0; i < pUser->pTimeWhiteList->num; i++) {
3,997,353✔
1876
    SDateTimeWhiteListItem *range = &pUser->pTimeWhiteList->ranges[i];
6,850✔
1877
    SDB_SET_BOOL(pRaw, dataPos, range->absolute, _OVER);
6,850✔
1878
    SDB_SET_BOOL(pRaw, dataPos, range->neg, _OVER);
6,850✔
1879
    SDB_SET_INT64(pRaw, dataPos, range->start, _OVER);
6,850✔
1880
    SDB_SET_INT32(pRaw, dataPos, range->duration, _OVER);
6,850✔
1881
  }
1882

1883
  sizeExt = tSerializeUserObjExt(buf, sizeExt, pUser);
3,990,503✔
1884
  if (sizeExt < 0) {
3,990,503✔
UNCOV
1885
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1886
  }
1887
  SDB_SET_INT32(pRaw, dataPos, sizeExt, _OVER);
3,990,503✔
1888
  SDB_SET_BINARY(pRaw, dataPos, buf, sizeExt, _OVER);
3,990,503✔
1889

1890
  SDB_SET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
3,990,503✔
1891

1892
  SDB_SET_DATALEN(pRaw, dataPos, _OVER)
3,990,503✔
1893

1894
_OVER:
3,990,503✔
1895
  taosMemoryFree(buf);
3,990,503✔
1896
  if (code < 0) {
3,990,503✔
UNCOV
1897
    mError("user:%s, failed to encode user action to raw:%p at line %d since %s", pUser->user, pRaw, lino,
×
1898
           tstrerror(code));
1899
    sdbFreeRaw(pRaw);
×
UNCOV
1900
    pRaw = NULL;
×
1901
    terrno = code;
×
1902
  }
1903

1904
  mTrace("user:%s, encode user action to raw:%p, row:%p", pUser->user, pRaw, pUser);
3,990,503✔
1905
  return pRaw;
3,990,503✔
1906
}
1907

1908
static SSdbRow *mndUserActionDecode(SSdbRaw *pRaw) {
3,194,474✔
1909
  int32_t   code = 0;
3,194,474✔
1910
  int32_t   lino = 0;
3,194,474✔
1911
  SSdbRow  *pRow = NULL;
3,194,474✔
1912
  SUserObj *pUser = NULL;
3,194,474✔
1913
  char     *key = NULL;
3,194,474✔
1914
  char     *value = NULL;
3,194,474✔
1915

1916
  int8_t sver = 0;
3,194,474✔
1917
  if (sdbGetRawSoftVer(pRaw, &sver) != 0) {
3,194,474✔
UNCOV
1918
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_PTR, &lino, _OVER);
×
1919
  }
1920

1921
  if (sver < 1 || sver > USER_VER_NUMBER) {
3,194,474✔
UNCOV
1922
    TAOS_CHECK_GOTO(TSDB_CODE_SDB_INVALID_DATA_VER, &lino, _OVER);
×
1923
  }
1924

1925
  pRow = sdbAllocRow(sizeof(SUserObj));
3,194,474✔
1926
  if (pRow == NULL) {
3,194,474✔
UNCOV
1927
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1928
  }
1929

1930
  pUser = sdbGetRowObj(pRow);
3,194,474✔
1931
  if (pUser == NULL) {
3,194,474✔
UNCOV
1932
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1933
  }
1934

1935
  if (sver < USER_VER_SUPPORT_ADVANCED_SECURITY) {
3,194,474✔
UNCOV
1936
    upgradeSecurity = 1;
×
UNCOV
1937
    pUser->legacyPrivs = taosMemCalloc(1, sizeof(SPrivHashObjSet));
×
1938
    if (pUser->legacyPrivs == NULL) {
×
1939
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
1940
    }
1941
  }
1942

1943
  int32_t dataPos = 0;
3,194,474✔
1944
  SDB_GET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN, _OVER)
3,194,474✔
1945

1946
  if (sver < USER_VER_SUPPORT_ADVANCED_SECURITY) {
3,194,474✔
UNCOV
1947
    pUser->passwords = taosMemoryCalloc(1, sizeof(SUserPassword));
×
UNCOV
1948
    if (pUser->passwords == NULL) {
×
1949
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
1950
    }
1951
    SDB_GET_BINARY(pRaw, dataPos, pUser->passwords[0].pass, TSDB_PASSWORD_LEN, _OVER)
×
UNCOV
1952
    pUser->numOfPasswords = 1;
×
1953
    memset(pUser->salt, 0, sizeof(pUser->salt));
×
1954
  } else {
1955
    SDB_GET_INT32(pRaw, dataPos, &pUser->numOfPasswords, _OVER)
3,194,474✔
1956
    pUser->passwords = taosMemoryCalloc(pUser->numOfPasswords, sizeof(SUserPassword));
3,194,474✔
1957
    if (pUser->passwords == NULL) {
3,194,474✔
UNCOV
1958
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
1959
    }
1960
    for (int32_t i = 0; i < pUser->numOfPasswords; ++i) {
7,095,183✔
1961
      SDB_GET_BINARY(pRaw, dataPos, pUser->passwords[i].pass, sizeof(pUser->passwords[i].pass), _OVER);
3,900,709✔
1962
      SDB_GET_INT32(pRaw, dataPos, &pUser->passwords[i].setTime, _OVER);
3,900,709✔
1963
    }
1964
    SDB_GET_BINARY(pRaw, dataPos, pUser->salt, sizeof(pUser->salt), _OVER)
3,194,474✔
1965
  }
1966

1967
  SDB_GET_BINARY(pRaw, dataPos, pUser->acct, TSDB_USER_LEN, _OVER)
3,194,474✔
1968
  SDB_GET_INT64(pRaw, dataPos, &pUser->createdTime, _OVER)
3,194,474✔
1969
  SDB_GET_INT64(pRaw, dataPos, &pUser->updateTime, _OVER)
3,194,474✔
1970
  if (sver < USER_VER_SUPPORT_ADVANCED_SECURITY) {
3,194,474✔
UNCOV
1971
    pUser->passwords[0].setTime = (int32_t)(pUser->updateTime / 1000);
×
1972
  }
1973

1974
  SDB_GET_INT8(pRaw, dataPos, &pUser->superUser, _OVER)
3,194,474✔
1975
  SDB_GET_INT8(pRaw, dataPos, &pUser->sysInfo, _OVER)
3,194,474✔
1976
  SDB_GET_INT8(pRaw, dataPos, &pUser->enable, _OVER)
3,194,474✔
1977
  SDB_GET_UINT8(pRaw, dataPos, &pUser->flag, _OVER)
3,194,474✔
1978
  if (pUser->superUser) pUser->createdb = 1;
3,194,474✔
1979
  SDB_GET_INT32(pRaw, dataPos, &pUser->authVersion, _OVER)
3,194,474✔
1980
  if (sver >= 4) {
3,194,474✔
1981
    SDB_GET_INT32(pRaw, dataPos, &pUser->passVersion, _OVER)
3,194,474✔
1982
  }
1983

1984
  int32_t numOfReadDbs = 0;
3,194,474✔
1985
  int32_t numOfWriteDbs = 0;
3,194,474✔
1986
  int32_t numOfTopics = 0;
3,194,474✔
1987
  SDB_GET_INT32(pRaw, dataPos, &numOfReadDbs, _OVER)
3,194,474✔
1988
  SDB_GET_INT32(pRaw, dataPos, &numOfWriteDbs, _OVER)
3,194,474✔
1989
  if (sver >= 2) {
3,194,474✔
1990
    SDB_GET_INT32(pRaw, dataPos, &numOfTopics, _OVER)
3,194,474✔
1991
  }
1992

1993
  if (numOfReadDbs > 0) {
3,194,474✔
UNCOV
1994
    pUser->legacyPrivs->pReadDbs =
×
UNCOV
1995
        taosHashInit(numOfReadDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
1996
    if (pUser->legacyPrivs->pReadDbs == NULL) {
×
1997
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1998
    }
1999
  }
2000
  if (numOfWriteDbs > 0) {
3,194,474✔
UNCOV
2001
    pUser->legacyPrivs->pWriteDbs =
×
UNCOV
2002
        taosHashInit(numOfWriteDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
2003
    if (pUser->legacyPrivs->pWriteDbs == NULL) {
×
2004
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2005
    }
2006
  }
2007
  if (numOfTopics > 0) {
3,194,474✔
UNCOV
2008
    pUser->legacyPrivs->pTopics =
×
UNCOV
2009
        taosHashInit(numOfTopics, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
2010
    if (pUser->legacyPrivs->pTopics == NULL) {
×
2011
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2012
    }
2013
  }
2014
  for (int32_t i = 0; i < numOfReadDbs; ++i) {
3,194,474✔
UNCOV
2015
    char db[TSDB_DB_FNAME_LEN] = {0};
×
UNCOV
2016
    SDB_GET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER)
×
2017
    int32_t len = strlen(db) + 1;
×
2018
    TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pReadDbs, db, len, db, TSDB_DB_FNAME_LEN), &lino, _OVER);
×
2019
  }
2020

2021
  for (int32_t i = 0; i < numOfWriteDbs; ++i) {
3,194,474✔
UNCOV
2022
    char db[TSDB_DB_FNAME_LEN] = {0};
×
UNCOV
2023
    SDB_GET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER)
×
2024
    int32_t len = strlen(db) + 1;
×
2025
    TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pWriteDbs, db, len, db, TSDB_DB_FNAME_LEN), &lino, _OVER);
×
2026
  }
2027

2028
  if (sver >= 2) {
3,194,474✔
2029
    for (int32_t i = 0; i < numOfTopics; ++i) {
3,194,474✔
UNCOV
2030
      char topic[TSDB_TOPIC_FNAME_LEN] = {0};
×
UNCOV
2031
      SDB_GET_BINARY(pRaw, dataPos, topic, TSDB_TOPIC_FNAME_LEN, _OVER)
×
2032
      int32_t len = strlen(topic) + 1;
×
2033
      TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pTopics, topic, len, topic, TSDB_TOPIC_FNAME_LEN), &lino, _OVER);
×
2034
    }
2035
  }
2036

2037
  if (sver >= 3) {
3,194,474✔
2038
    int32_t numOfReadTbs = 0;
3,194,474✔
2039
    int32_t numOfWriteTbs = 0;
3,194,474✔
2040
    int32_t numOfAlterTbs = 0;
3,194,474✔
2041
    int32_t numOfReadViews = 0;
3,194,474✔
2042
    int32_t numOfWriteViews = 0;
3,194,474✔
2043
    int32_t numOfAlterViews = 0;
3,194,474✔
2044
    int32_t numOfUseDbs = 0;
3,194,474✔
2045
    SDB_GET_INT32(pRaw, dataPos, &numOfReadTbs, _OVER)
3,194,474✔
2046
    SDB_GET_INT32(pRaw, dataPos, &numOfWriteTbs, _OVER)
3,194,474✔
2047
    if (sver >= 6) {
3,194,474✔
2048
      SDB_GET_INT32(pRaw, dataPos, &numOfAlterTbs, _OVER)
3,194,474✔
2049
      SDB_GET_INT32(pRaw, dataPos, &numOfReadViews, _OVER)
3,194,474✔
2050
      SDB_GET_INT32(pRaw, dataPos, &numOfWriteViews, _OVER)
3,194,474✔
2051
      SDB_GET_INT32(pRaw, dataPos, &numOfAlterViews, _OVER)
3,194,474✔
2052
    }
2053
    SDB_GET_INT32(pRaw, dataPos, &numOfUseDbs, _OVER)
3,194,474✔
2054

2055
    if (numOfReadTbs > 0) {
3,194,474✔
UNCOV
2056
      pUser->legacyPrivs->pReadTbs =
×
UNCOV
2057
          taosHashInit(numOfReadTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
2058
      if (pUser->legacyPrivs->pReadTbs == NULL) {
×
2059
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2060
      }
2061
    }
2062
    if (numOfWriteTbs > 0) {
3,194,474✔
UNCOV
2063
      pUser->legacyPrivs->pWriteTbs =
×
UNCOV
2064
          taosHashInit(numOfWriteTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
2065
      if (pUser->legacyPrivs->pWriteTbs == NULL) {
×
2066
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2067
      }
2068
    }
2069
    if (numOfAlterTbs > 0) {
3,194,474✔
UNCOV
2070
      pUser->legacyPrivs->pAlterTbs =
×
UNCOV
2071
          taosHashInit(numOfAlterTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
2072
      if (pUser->legacyPrivs->pAlterTbs == NULL) {
×
2073
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2074
      }
2075
    }
2076
    if (numOfReadViews > 0) {
3,194,474✔
UNCOV
2077
      pUser->legacyPrivs->pReadViews =
×
UNCOV
2078
          taosHashInit(numOfReadViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
2079
      if (pUser->legacyPrivs->pReadViews == NULL) {
×
2080
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2081
      }
2082
    }
2083
    if (numOfWriteViews > 0) {
3,194,474✔
UNCOV
2084
      pUser->legacyPrivs->pWriteViews =
×
UNCOV
2085
          taosHashInit(numOfWriteViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
2086
      if (pUser->legacyPrivs->pWriteViews == NULL) {
×
2087
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2088
      }
2089
    }
2090
    if (numOfAlterViews > 0) {
3,194,474✔
UNCOV
2091
      pUser->legacyPrivs->pAlterViews =
×
UNCOV
2092
          taosHashInit(numOfAlterViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
2093
      if (pUser->legacyPrivs->pAlterViews == NULL) {
×
2094
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2095
      }
2096
    }
2097
    if (numOfUseDbs > 0) {
3,194,474✔
UNCOV
2098
      pUser->legacyPrivs->pUseDbs =
×
UNCOV
2099
          taosHashInit(numOfUseDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
2100
      if (pUser->legacyPrivs->pUseDbs == NULL) {
×
2101
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2102
      }
2103
    }
2104

2105
    for (int32_t i = 0; i < numOfReadTbs; ++i) {
3,194,474✔
UNCOV
2106
      int32_t keyLen = 0;
×
UNCOV
2107
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
2108

2109
      TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
UNCOV
2110
      if (key == NULL) {
×
2111
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2112
      }
2113
      (void)memset(key, 0, keyLen);
×
UNCOV
2114
      SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
2115

2116
      int32_t valuelen = 0;
×
UNCOV
2117
      SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
2118
      TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
2119
      if (value == NULL) {
×
2120
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2121
      }
2122
      (void)memset(value, 0, valuelen);
×
UNCOV
2123
      SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
2124

2125
      TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pReadTbs, key, keyLen, value, valuelen), &lino, _OVER);
×
2126
    }
2127

2128
    for (int32_t i = 0; i < numOfWriteTbs; ++i) {
3,194,474✔
UNCOV
2129
      int32_t keyLen = 0;
×
UNCOV
2130
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
2131

2132
      TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
UNCOV
2133
      if (key == NULL) {
×
2134
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2135
      }
2136
      (void)memset(key, 0, keyLen);
×
UNCOV
2137
      SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
2138

2139
      int32_t valuelen = 0;
×
UNCOV
2140
      SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
2141
      TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
2142
      if (value == NULL) {
×
2143
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2144
      }
2145
      (void)memset(value, 0, valuelen);
×
UNCOV
2146
      SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
2147

2148
      TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pWriteTbs, key, keyLen, value, valuelen), &lino, _OVER);
×
2149
    }
2150

2151
    if (sver >= 6) {
3,194,474✔
2152
      for (int32_t i = 0; i < numOfAlterTbs; ++i) {
3,194,474✔
UNCOV
2153
        int32_t keyLen = 0;
×
UNCOV
2154
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
2155

2156
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
UNCOV
2157
        if (key == NULL) {
×
2158
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2159
        }
2160
        (void)memset(key, 0, keyLen);
×
UNCOV
2161
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
2162

2163
        int32_t valuelen = 0;
×
UNCOV
2164
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
2165
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
2166
        if (value == NULL) {
×
2167
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2168
        }
2169
        (void)memset(value, 0, valuelen);
×
UNCOV
2170
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
2171

2172
        TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pAlterTbs, key, keyLen, value, valuelen), &lino, _OVER);
×
2173
      }
2174

2175
      for (int32_t i = 0; i < numOfReadViews; ++i) {
3,194,474✔
UNCOV
2176
        int32_t keyLen = 0;
×
UNCOV
2177
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
2178

2179
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
UNCOV
2180
        if (key == NULL) {
×
2181
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2182
        }
2183
        (void)memset(key, 0, keyLen);
×
UNCOV
2184
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
2185

2186
        int32_t valuelen = 0;
×
UNCOV
2187
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
2188
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
2189
        if (value == NULL) {
×
2190
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2191
        }
2192
        (void)memset(value, 0, valuelen);
×
UNCOV
2193
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
2194

2195
        TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pReadViews, key, keyLen, value, valuelen), &lino, _OVER);
×
2196
      }
2197

2198
      for (int32_t i = 0; i < numOfWriteViews; ++i) {
3,194,474✔
UNCOV
2199
        int32_t keyLen = 0;
×
UNCOV
2200
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
2201

2202
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
UNCOV
2203
        if (key == NULL) {
×
2204
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2205
        }
2206
        (void)memset(key, 0, keyLen);
×
UNCOV
2207
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
2208

2209
        int32_t valuelen = 0;
×
UNCOV
2210
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
2211
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
2212
        if (value == NULL) {
×
2213
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2214
        }
2215
        (void)memset(value, 0, valuelen);
×
UNCOV
2216
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
2217

2218
        TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pWriteViews, key, keyLen, value, valuelen), &lino, _OVER);
×
2219
      }
2220

2221
      for (int32_t i = 0; i < numOfAlterViews; ++i) {
3,194,474✔
UNCOV
2222
        int32_t keyLen = 0;
×
UNCOV
2223
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
2224

2225
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
UNCOV
2226
        if (key == NULL) {
×
2227
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2228
        }
2229
        (void)memset(key, 0, keyLen);
×
UNCOV
2230
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
2231

2232
        int32_t valuelen = 0;
×
UNCOV
2233
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
2234
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
2235
        if (value == NULL) {
×
2236
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2237
        }
2238
        (void)memset(value, 0, valuelen);
×
UNCOV
2239
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
2240

2241
        TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pAlterViews, key, keyLen, value, valuelen), &lino, _OVER);
×
2242
      }
2243
    }
2244

2245
    for (int32_t i = 0; i < numOfUseDbs; ++i) {
3,194,474✔
UNCOV
2246
      int32_t keyLen = 0;
×
UNCOV
2247
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
2248

2249
      TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
UNCOV
2250
      if (key == NULL) {
×
2251
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2252
      }
2253
      (void)memset(key, 0, keyLen);
×
UNCOV
2254
      SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
2255

2256
      int32_t ref = 0;
×
UNCOV
2257
      SDB_GET_INT32(pRaw, dataPos, &ref, _OVER);
×
2258

2259
      TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pUseDbs, key, keyLen, &ref, sizeof(ref)), &lino, _OVER);
×
2260
    }
2261
  }
2262
  // decoder white list
2263
  if (sver >= USER_VER_SUPPORT_WHITELIST) {
3,194,474✔
2264
    if (sver < USER_VER_SUPPORT_WHITELIT_DUAL_STACK) {
3,194,474✔
UNCOV
2265
      int32_t len = 0;
×
UNCOV
2266
      SDB_GET_INT32(pRaw, dataPos, &len, _OVER);
×
2267

2268
      TAOS_MEMORY_REALLOC(key, len);
×
UNCOV
2269
      if (key == NULL) {
×
2270
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2271
      }
2272
      SDB_GET_BINARY(pRaw, dataPos, key, len, _OVER);
×
2273

2274
      SIpWhiteList *pIpWhiteList = NULL;
×
UNCOV
2275
      TAOS_CHECK_GOTO(createIpWhiteListFromOldVer(key, len, &pIpWhiteList), &lino, _OVER);
×
2276

2277
      SDB_GET_INT64(pRaw, dataPos, &pUser->ipWhiteListVer, _OVER);
×
2278

2279
      code = cvtIpWhiteListToDual(pIpWhiteList, &pUser->pIpWhiteListDual);
×
UNCOV
2280
      if (code != 0) {
×
2281
        taosMemoryFreeClear(pIpWhiteList);
×
2282
      }
2283
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2284

2285
      taosMemoryFreeClear(pIpWhiteList);
×
2286

2287
    } else if (sver >= USER_VER_SUPPORT_WHITELIT_DUAL_STACK) {
3,194,474✔
2288
      int32_t len = 0;
3,194,474✔
2289
      SDB_GET_INT32(pRaw, dataPos, &len, _OVER);
3,194,474✔
2290

2291
      TAOS_MEMORY_REALLOC(key, len);
3,194,474✔
2292
      if (key == NULL) {
3,194,474✔
UNCOV
2293
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2294
      }
2295
      SDB_GET_BINARY(pRaw, dataPos, key, len, _OVER);
3,194,474✔
2296

2297
      TAOS_CHECK_GOTO(createIpWhiteList(key, len, &pUser->pIpWhiteListDual, sver >= USER_VER_SUPPORT_ADVANCED_SECURITY),
3,194,474✔
2298
                      &lino, _OVER);
2299
      SDB_GET_INT64(pRaw, dataPos, &pUser->ipWhiteListVer, _OVER);
3,194,474✔
2300
    }
2301
  }
2302

2303
  if (pUser->pIpWhiteListDual == NULL) {
3,194,474✔
UNCOV
2304
    TAOS_CHECK_GOTO(createDefaultIpWhiteList(&pUser->pIpWhiteListDual), &lino, _OVER);
×
UNCOV
2305
    pUser->ipWhiteListVer = taosGetTimestampMs();
×
2306
  }
2307

2308
  SDB_GET_INT8(pRaw, dataPos, &pUser->passEncryptAlgorithm, _OVER);
3,194,474✔
2309

2310
  if (sver < USER_VER_SUPPORT_ADVANCED_SECURITY) {
3,194,474✔
UNCOV
2311
    memset(pUser->totpsecret, 0, sizeof(pUser->totpsecret));
×
UNCOV
2312
    pUser->changePass = 2;
×
2313

2314
    if (tsEnableAdvancedSecurity) {
×
UNCOV
2315
      pUser->sessionPerUser = pUser->superUser ? -1 : TSDB_USER_SESSION_PER_USER_DEFAULT;
×
2316
      pUser->connectTime = TSDB_USER_CONNECT_TIME_DEFAULT;
×
2317
      pUser->connectIdleTime = TSDB_USER_CONNECT_IDLE_TIME_DEFAULT;
×
2318
      pUser->callPerSession = pUser->superUser ? -1 : TSDB_USER_CALL_PER_SESSION_DEFAULT;
×
2319
      pUser->vnodePerCall = pUser->superUser ? -1 : TSDB_USER_VNODE_PER_CALL_DEFAULT;
×
2320
      pUser->failedLoginAttempts = pUser->superUser ? -1 : TSDB_USER_FAILED_LOGIN_ATTEMPTS_DEFAULT;
×
2321
      pUser->passwordLifeTime = TSDB_USER_PASSWORD_LIFE_TIME_DEFAULT;
×
2322
      pUser->passwordReuseTime = TSDB_USER_PASSWORD_REUSE_TIME_DEFAULT;
×
2323
      pUser->passwordReuseMax = TSDB_USER_PASSWORD_REUSE_MAX_DEFAULT;
×
2324
      pUser->passwordLockTime = pUser->superUser ? 1 : TSDB_USER_PASSWORD_LOCK_TIME_DEFAULT;
×
2325
      pUser->passwordGraceTime = pUser->superUser ? -1 : TSDB_USER_PASSWORD_GRACE_TIME_DEFAULT;
×
2326
      pUser->inactiveAccountTime = pUser->superUser ? -1 : TSDB_USER_INACTIVE_ACCOUNT_TIME_DEFAULT;
×
2327
    } else {
2328
      pUser->sessionPerUser = -1;
×
UNCOV
2329
      pUser->connectTime = -1;
×
2330
      pUser->connectIdleTime = -1;
×
2331
      pUser->callPerSession = -1;
×
2332
      pUser->vnodePerCall = -1;
×
2333
      pUser->failedLoginAttempts = -1;
×
2334
      pUser->passwordLifeTime = -1;
×
2335
      pUser->passwordReuseTime = 0;
×
2336
      pUser->passwordReuseMax = 0;
×
2337
      pUser->passwordLockTime = 1;
×
2338
      pUser->passwordGraceTime = -1;
×
2339
      pUser->inactiveAccountTime =-1;
×
2340
    }
2341

UNCOV
2342
    pUser->allowTokenNum = TSDB_USER_ALLOW_TOKEN_NUM_DEFAULT;
×
UNCOV
2343
    pUser->tokenNum = 0;
×
2344
    pUser->pTimeWhiteList = taosMemCalloc(1, sizeof(SDateTimeWhiteList));
×
2345
    if (pUser->pTimeWhiteList == NULL) {
×
2346
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2347
    }
2348
  } else {
2349
    SDB_GET_BINARY(pRaw, dataPos, pUser->totpsecret, sizeof(pUser->totpsecret), _OVER);
3,194,474✔
2350
    SDB_GET_INT8(pRaw, dataPos, &pUser->changePass, _OVER);
3,194,474✔
2351
    SDB_GET_INT32(pRaw, dataPos, &pUser->sessionPerUser, _OVER);
3,194,474✔
2352
    SDB_GET_INT32(pRaw, dataPos, &pUser->connectTime, _OVER);
3,194,474✔
2353
    SDB_GET_INT32(pRaw, dataPos, &pUser->connectIdleTime, _OVER);
3,194,474✔
2354
    SDB_GET_INT32(pRaw, dataPos, &pUser->callPerSession, _OVER);
3,194,474✔
2355
    SDB_GET_INT32(pRaw, dataPos, &pUser->vnodePerCall, _OVER);
3,194,474✔
2356
    SDB_GET_INT32(pRaw, dataPos, &pUser->failedLoginAttempts, _OVER);
3,194,474✔
2357
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordLifeTime, _OVER);
3,194,474✔
2358
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordReuseTime, _OVER);
3,194,474✔
2359
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordReuseMax, _OVER);
3,194,474✔
2360
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordLockTime, _OVER);
3,194,474✔
2361
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordGraceTime, _OVER);
3,194,474✔
2362
    SDB_GET_INT32(pRaw, dataPos, &pUser->inactiveAccountTime, _OVER);
3,194,474✔
2363
    SDB_GET_INT32(pRaw, dataPos, &pUser->allowTokenNum, _OVER);
3,194,474✔
2364
    SDB_GET_INT32(pRaw, dataPos, &pUser->tokenNum, _OVER);
3,194,474✔
2365

2366
    int32_t num = 0;
3,194,474✔
2367
    SDB_GET_INT32(pRaw, dataPos, &num, _OVER);
3,194,474✔
2368
    pUser->pTimeWhiteList = taosMemCalloc(1, sizeof(SDateTimeWhiteList) + num * sizeof(SDateTimeWhiteListItem));
3,194,474✔
2369
    if (pUser->pTimeWhiteList == NULL) {
3,194,474✔
UNCOV
2370
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2371
    }
2372

2373
    pUser->pTimeWhiteList->num = num;
3,194,474✔
2374
    for (int32_t i = 0; i < num; i++) {
3,197,488✔
2375
      SDateTimeWhiteListItem *range = &pUser->pTimeWhiteList->ranges[i];
3,014✔
2376
      SDB_GET_BOOL(pRaw, dataPos, &range->absolute, _OVER);
3,014✔
2377
      SDB_GET_BOOL(pRaw, dataPos, &range->neg, _OVER);
3,014✔
2378
      SDB_GET_INT64(pRaw, dataPos, &range->start, _OVER);
3,014✔
2379
      SDB_GET_INT32(pRaw, dataPos, &range->duration, _OVER);
3,014✔
2380
    }
2381

2382
    int32_t extLen = 0;
3,194,474✔
2383
    SDB_GET_INT32(pRaw, dataPos, &extLen, _OVER);
3,194,474✔
2384
    TAOS_MEMORY_REALLOC(key, extLen);
3,194,474✔
2385
    if (key == NULL) {
3,194,474✔
UNCOV
2386
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2387
    }
2388
    SDB_GET_BINARY(pRaw, dataPos, key, extLen, _OVER);
3,194,474✔
2389
    TAOS_CHECK_GOTO(tDeserializeUserObjExt(key, extLen, pUser), &lino, _OVER);
3,194,474✔
2390
  }
2391

2392
#ifndef TD_ENTERPRISE
2393
  // community users cannot modify these fields, and the default values may prevent
2394
  // the user from logging in, so we set them to different values here.
2395
  pUser->sessionPerUser = -1;
2396
  pUser->connectTime = -1;
2397
  pUser->connectIdleTime = -1;
2398
  pUser->callPerSession = -1;
2399
  pUser->vnodePerCall = -1;
2400
  pUser->failedLoginAttempts = -1;
2401
  pUser->passwordLifeTime = -1;
2402
  pUser->passwordReuseTime = 0;
2403
  pUser->passwordReuseMax = 0;
2404
  pUser->passwordLockTime = -1;
2405
  pUser->passwordGraceTime = -1;
2406
  pUser->inactiveAccountTime = -1;
2407
  pUser->allowTokenNum = -1;
2408
  pUser->tokenNum = 0;
2409
#endif  // TD_ENTERPRISE
2410

2411
  SDB_GET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
3,194,474✔
2412

2413
  taosInitRWLatch(&pUser->lock);
3,194,474✔
2414
  dropOldPasswords(pUser);
3,194,474✔
2415
_OVER:
3,194,474✔
2416
  taosMemoryFree(key);
3,194,474✔
2417
  taosMemoryFree(value);
3,194,474✔
2418
  if (code < 0) {
3,194,474✔
UNCOV
2419
    terrno = code;
×
UNCOV
2420
    mError("user:%s, failed to decode at line %d from raw:%p since %s", pUser == NULL ? "null" : pUser->user, lino,
×
2421
           pRaw, tstrerror(code));
2422
    if (pUser != NULL) {
×
UNCOV
2423
      mndUserFreeObj(pUser);
×
2424
    }
2425
    taosMemoryFreeClear(pRow);
×
UNCOV
2426
    return NULL;
×
2427
  }
2428

2429
  mTrace("user:%s, decode from raw:%p, row:%p", pUser->user, pRaw, pUser);
3,194,474✔
2430
  return pRow;
3,194,474✔
2431
}
2432

2433
static int32_t mndUserActionInsert(SSdb *pSdb, SUserObj *pUser) {
520,195✔
2434
  mTrace("user:%s, perform insert action, row:%p", pUser->user, pUser);
520,195✔
2435

2436
  SAcctObj *pAcct = sdbAcquire(pSdb, SDB_ACCT, pUser->acct);
520,195✔
2437
  if (pAcct == NULL) {
520,195✔
UNCOV
2438
    terrno = TSDB_CODE_MND_ACCT_NOT_EXIST;
×
UNCOV
2439
    mError("user:%s, failed to perform insert action since %s", pUser->user, terrstr());
×
2440
    TAOS_RETURN(terrno);
×
2441
  }
2442
  pUser->acctId = pAcct->acctId;
520,195✔
2443
  sdbRelease(pSdb, pAcct);
520,195✔
2444

2445
  return 0;
520,195✔
2446
}
2447

UNCOV
2448
int32_t mndDupTableHash(SHashObj *pOld, SHashObj **ppNew) {
×
UNCOV
2449
  int32_t code = 0;
×
2450
  *ppNew =
×
2451
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
2452
  if (*ppNew == NULL) {
×
2453
    TAOS_RETURN(terrno);
×
2454
  }
2455

UNCOV
2456
  char *tb = taosHashIterate(pOld, NULL);
×
UNCOV
2457
  while (tb != NULL) {
×
2458
    size_t keyLen = 0;
×
2459
    char  *key = taosHashGetKey(tb, &keyLen);
×
2460

2461
    int32_t valueLen = strlen(tb) + 1;
×
UNCOV
2462
    if ((code = taosHashPut(*ppNew, key, keyLen, tb, valueLen)) != 0) {
×
2463
      taosHashCancelIterate(pOld, tb);
×
2464
      taosHashCleanup(*ppNew);
×
2465
      TAOS_RETURN(code);
×
2466
    }
2467
    tb = taosHashIterate(pOld, tb);
×
2468
  }
2469

UNCOV
2470
  TAOS_RETURN(code);
×
2471
}
2472

2473
int32_t mndDupRoleHash(SHashObj *pOld, SHashObj **ppNew) {
2,591,325✔
2474
  if (!(*ppNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true,
2,591,325✔
2475
                              HASH_ENTRY_LOCK))) {
UNCOV
2476
    TAOS_RETURN(terrno);
×
2477
  }
2478

2479
  int32_t  code = 0;
2,591,325✔
2480
  uint8_t *flag = NULL;
2,591,325✔
2481
  while ((flag = taosHashIterate(pOld, flag))) {
7,528,491✔
2482
    size_t keyLen = 0;
4,937,166✔
2483
    char  *key = taosHashGetKey(flag, &keyLen);
4,937,166✔
2484

2485
    if ((code = taosHashPut(*ppNew, key, keyLen, flag, sizeof(*flag))) != 0) {
4,937,166✔
UNCOV
2486
      taosHashCancelIterate(pOld, flag);
×
UNCOV
2487
      taosHashCleanup(*ppNew);
×
2488
      TAOS_RETURN(code);
×
2489
    }
2490
  }
2491

2492
  TAOS_RETURN(code);
2,591,325✔
2493
}
2494

2495
int32_t mndMergePrivObjHash(SHashObj *pOld, SHashObj **ppNew) {
90,604,833✔
2496
  if (!(*ppNew)) return mndDupPrivObjHash(pOld, ppNew);
90,604,833✔
2497

2498
  int32_t           code = 0, lino = 0;
90,604,686✔
2499
  SHashObj         *pNew = *ppNew;
90,604,686✔
2500
  SPrivObjPolicies *policies = NULL;
90,604,152✔
2501
  while ((policies = taosHashIterate(pOld, policies))) {
816,638,339✔
2502
    size_t klen = 0;
726,038,611✔
2503
    char  *key = taosHashGetKey(policies, &klen);
726,038,611✔
2504
    size_t vlen = taosHashGetValueSize(policies);
726,037,797✔
2505

2506
    SPrivObjPolicies *pNewPolicies = taosHashGet(pNew, key, klen);
726,037,629✔
2507
    if (pNewPolicies) {
726,038,097✔
2508
      size_t newVlen = taosHashGetValueSize(pNewPolicies);
480,011,802✔
2509
      if (newVlen > 0 && vlen > 0) {
480,011,905✔
2510
        privAddSet(&pNewPolicies->policy, &policies->policy);
480,011,905✔
2511
      }
2512
      continue;
480,008,011✔
2513
    }
2514

2515
    if ((code = taosHashPut(pNew, key, klen, vlen ? policies : NULL, vlen)) != 0) {
246,026,295✔
2516
      taosHashCancelIterate(pOld, policies);
523✔
UNCOV
2517
      taosHashCleanup(pNew);
×
UNCOV
2518
      *ppNew = NULL;
×
2519
      TAOS_RETURN(code);
×
2520
    }
2521
  }
2522

2523
  TAOS_RETURN(code);
90,602,957✔
2524
}
2525

2526
/**
2527
 * 1. Prefer to use SPrivTblPolicies from user object(the updateUs of policy in user object is INT64_MAX)
2528
 * 2. If two or more roles have SPrivTblPolicies, the policy with latest update time take effect.
2529
 */
2530
int32_t mndMergePrivTblHash(SHashObj *pOld, SHashObj **ppNew, bool updateWithLatest) {
271,812,285✔
2531
  if (!(*ppNew)) return mndDupPrivTblHash(pOld, ppNew, false);
271,812,285✔
2532

2533
  int32_t           code = 0, lino = 0;
271,812,285✔
2534
  SHashObj         *pNew = *ppNew;
271,812,285✔
2535
  SPrivTblPolicies *policies = NULL;
271,812,285✔
2536
  while ((policies = taosHashIterate(pOld, policies))) {
271,813,077✔
2537
    size_t klen = 0;
792✔
2538
    char  *key = taosHashGetKey(policies, &klen);
792✔
2539
    size_t vlen = taosHashGetValueSize(policies);
792✔
2540

2541
    SPrivTblPolicies *pNewPolicies = taosHashGet(pNew, key, klen);
792✔
2542
    if (pNewPolicies) {
792✔
2543
      size_t newVlen = taosHashGetValueSize(pNewPolicies);
792✔
2544
      if (newVlen > 0 && vlen > 0) {
792✔
2545
        TAOS_CHECK_EXIT(privTblPoliciesMerge(pNewPolicies, policies, updateWithLatest));
792✔
2546
      }
2547
      continue;
792✔
2548
    }
2549

UNCOV
2550
    SPrivTblPolicies tmpPolicies = {0};
×
UNCOV
2551
    if (vlen > 0) {
×
2552
      if ((code = privTblPoliciesMerge(&tmpPolicies, policies, updateWithLatest))) {
×
2553
        privTblPoliciesFree(&tmpPolicies);
2554
        goto _exit;
×
2555
      }
2556
    }
UNCOV
2557
    if ((code = taosHashPut(pNew, key, klen, vlen ? &tmpPolicies : NULL, vlen)) != 0) {
×
2558
      privTblPoliciesFree(&tmpPolicies);
2559
      taosHashCancelIterate(pOld, policies);
×
UNCOV
2560
      taosHashCleanup(pNew);
×
2561
      *ppNew = NULL;
×
2562
      TAOS_RETURN(code);
×
2563
    }
2564
  }
2565

2566
_exit:
271,813,599✔
2567
  TAOS_RETURN(code);
271,813,599✔
2568
}
2569

2570
int32_t mndDupKVHash(SHashObj *pOld, SHashObj **ppNew) {
33,207,257✔
2571
  if (!(*ppNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true,
33,207,257✔
2572
                              HASH_ENTRY_LOCK))) {
UNCOV
2573
    TAOS_RETURN(terrno);
×
2574
  }
2575
  int32_t code = 0;
33,207,257✔
2576
  void   *val = NULL;
33,207,257✔
2577
  while ((val = taosHashIterate(pOld, val))) {
101,181,734✔
2578
    size_t klen = 0;
67,974,477✔
2579
    char  *key = taosHashGetKey(val, &klen);
67,974,477✔
2580
    size_t vlen = taosHashGetValueSize(val);
67,974,477✔
2581
    if ((code = taosHashPut(*ppNew, key, klen, vlen > 0 ? val : NULL, vlen)) != 0) {
67,974,477✔
UNCOV
2582
      taosHashCancelIterate(pOld, val);
×
UNCOV
2583
      taosHashCleanup(*ppNew);
×
2584
      TAOS_RETURN(code);
×
2585
    }
2586
  }
2587

2588
  TAOS_RETURN(code);
33,207,257✔
2589
}
2590

2591
int32_t mndDupPrivObjHash(SHashObj *pOld, SHashObj **ppNew) {
33,210,431✔
2592
  if (!(*ppNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true,
33,210,431✔
2593
                              HASH_ENTRY_LOCK))) {
UNCOV
2594
    TAOS_RETURN(terrno);
×
2595
  }
2596
  int32_t           code = 0;
33,210,672✔
2597
  SPrivObjPolicies *policies = NULL;
33,210,672✔
2598
  while ((policies = taosHashIterate(pOld, policies))) {
77,360,590✔
2599
    size_t klen = 0;
44,150,075✔
2600
    char  *key = taosHashGetKey(policies, &klen);
44,150,075✔
2601
    size_t vlen = taosHashGetValueSize(policies);
44,150,075✔
2602

2603
    if ((code = taosHashPut(*ppNew, key, klen, vlen > 0 ? policies : NULL, vlen)) != 0) {
44,150,075✔
UNCOV
2604
      taosHashCancelIterate(pOld, policies);
×
UNCOV
2605
      taosHashCleanup(*ppNew);
×
2606
      TAOS_RETURN(code);
×
2607
    }
2608
  }
2609

2610
  TAOS_RETURN(code);
33,210,672✔
2611
}
2612

2613
int32_t mndDupPrivTblHash(SHashObj *pOld, SHashObj **ppNew, bool setUpdateTimeMax) {
102,219,551✔
2614
  if (!(*ppNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true,
102,219,551✔
2615
                              HASH_ENTRY_LOCK))) {
UNCOV
2616
    TAOS_RETURN(terrno);
×
2617
  }
2618
  taosHashSetFreeFp(*ppNew, privTblPoliciesFree);
102,219,892✔
2619

2620
  int32_t           code = 0, lino = 0;
102,219,552✔
2621
  SPrivTblPolicies *policies = NULL, *pTmpPolicies = NULL;
102,219,552✔
2622
  SPrivTblPolicies  tmpPolicies = {0};
102,219,552✔
2623
  while ((policies = taosHashIterate(pOld, policies))) {
102,672,723✔
2624
    size_t klen = 0;
453,309✔
2625
    char  *key = taosHashGetKey(policies, &klen);
453,309✔
2626
    size_t vlen = taosHashGetValueSize(policies);
453,309✔
2627
    memset(&tmpPolicies, 0, sizeof(tmpPolicies));
453,309✔
2628
    pTmpPolicies = &tmpPolicies;
453,309✔
2629
    if (vlen > 0) {
453,309✔
2630
      TAOS_CHECK_EXIT(privTblPoliciesAdd(&tmpPolicies, policies, true, setUpdateTimeMax));
453,309✔
2631
    }
2632
    TAOS_CHECK_EXIT(taosHashPut(*ppNew, key, klen, vlen > 0 ? &tmpPolicies : NULL, vlen));
453,309✔
2633
    pTmpPolicies = NULL;
453,309✔
2634
  }
2635

2636
_exit:
102,219,891✔
2637
  if (code != 0) {
102,219,891✔
UNCOV
2638
    if (!pTmpPolicies) {
×
2639
      privTblPoliciesFree(pTmpPolicies);
2640
      pTmpPolicies = NULL;
×
2641
    }
2642
    if (policies) taosHashCancelIterate(pOld, policies);
×
UNCOV
2643
    taosHashCleanup(*ppNew);
×
2644
    *ppNew = NULL;
×
2645
  }
2646
  TAOS_RETURN(code);
102,219,891✔
2647
}
2648

2649
int32_t mndUserDupObj(SUserObj *pUser, SUserObj *pNew) {
2,584,701✔
2650
  int32_t code = 0;
2,584,701✔
2651
  (void)memcpy(pNew, pUser, sizeof(SUserObj));
2,584,701✔
2652
  pNew->authVersion++;
2,584,701✔
2653
  pNew->updateTime = taosGetTimestampMs();
2,584,701✔
2654
  taosInitRWLatch(&pNew->lock);
2,584,701✔
2655

2656
  pNew->passwords = NULL;
2,584,701✔
2657
  pNew->pIpWhiteListDual = NULL;
2,584,701✔
2658
  pNew->passwords = NULL;
2,584,701✔
2659
  pNew->objPrivs = NULL;
2,584,701✔
2660
  pNew->selectTbs = NULL;
2,584,701✔
2661
  pNew->insertTbs = NULL;
2,584,701✔
2662
  pNew->updateTbs = NULL;
2,584,701✔
2663
  pNew->deleteTbs = NULL;
2,584,701✔
2664
  pNew->ownedDbs = NULL;
2,584,701✔
2665
  pNew->pTimeWhiteList = NULL;
2,584,701✔
2666
  pNew->roles = NULL;
2,584,701✔
2667
  pNew->legacyPrivs = NULL;
2,584,701✔
2668

2669
  taosRLockLatch(&pUser->lock);
2,584,701✔
2670
  pNew->passwords = taosMemoryCalloc(pUser->numOfPasswords, sizeof(SUserPassword));
2,584,701✔
2671
  if (pNew->passwords == NULL) {
2,584,701✔
UNCOV
2672
    code = TSDB_CODE_OUT_OF_MEMORY;
×
UNCOV
2673
    goto _OVER;
×
2674
  }
2675
  (void)memcpy(pNew->passwords, pUser->passwords, pUser->numOfPasswords * sizeof(SUserPassword));
2,584,701✔
2676
  TAOS_CHECK_GOTO(mndDupKVHash(pUser->ownedDbs, &pNew->ownedDbs), NULL, _OVER);
2,584,701✔
2677
  TAOS_CHECK_GOTO(mndDupPrivObjHash(pUser->objPrivs, &pNew->objPrivs), NULL, _OVER);
2,584,701✔
2678
  TAOS_CHECK_GOTO(mndDupPrivTblHash(pUser->selectTbs, &pNew->selectTbs, false), NULL, _OVER);
2,584,701✔
2679
  TAOS_CHECK_GOTO(mndDupPrivTblHash(pUser->insertTbs, &pNew->insertTbs, false), NULL, _OVER);
2,584,701✔
2680
  TAOS_CHECK_GOTO(mndDupPrivTblHash(pUser->updateTbs, &pNew->updateTbs, false), NULL, _OVER);
2,584,701✔
2681
  TAOS_CHECK_GOTO(mndDupPrivTblHash(pUser->deleteTbs, &pNew->deleteTbs, false), NULL, _OVER);
2,584,701✔
2682
  TAOS_CHECK_GOTO(mndDupRoleHash(pUser->roles, &pNew->roles), NULL, _OVER);
2,584,701✔
2683
  if(pUser->legacyPrivs) {
2,584,701✔
UNCOV
2684
    pNew->legacyPrivs = taosMemCalloc(1, sizeof(SPrivHashObjSet));
×
UNCOV
2685
    if (pNew->legacyPrivs == NULL) {
×
2686
      code = TSDB_CODE_OUT_OF_MEMORY;
×
2687
      goto _OVER;
×
2688
    }
2689
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pReadDbs, &pNew->legacyPrivs->pReadDbs), NULL, _OVER);
×
UNCOV
2690
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pWriteDbs, &pNew->legacyPrivs->pWriteDbs), NULL, _OVER);
×
2691
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pReadTbs, &pNew->legacyPrivs->pReadTbs), NULL, _OVER);
×
2692
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pWriteTbs, &pNew->legacyPrivs->pWriteTbs), NULL, _OVER);
×
2693
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pTopics, &pNew->legacyPrivs->pTopics), NULL, _OVER);
×
2694
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pAlterTbs, &pNew->legacyPrivs->pAlterTbs), NULL, _OVER);
×
2695
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pReadViews, &pNew->legacyPrivs->pReadViews), NULL, _OVER);
×
2696
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pWriteViews, &pNew->legacyPrivs->pWriteViews), NULL, _OVER);
×
2697
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pAlterViews, &pNew->legacyPrivs->pAlterViews), NULL, _OVER);
×
2698
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pUseDbs, &pNew->legacyPrivs->pUseDbs), NULL, _OVER);
×
2699
  }
2700
  pNew->pIpWhiteListDual = cloneIpWhiteList(pUser->pIpWhiteListDual);
2,584,701✔
2701
  if (pNew->pIpWhiteListDual == NULL) {
2,584,701✔
UNCOV
2702
    code = TSDB_CODE_OUT_OF_MEMORY;
×
UNCOV
2703
    goto _OVER;
×
2704
  }
2705

2706
  pNew->pTimeWhiteList = cloneDateTimeWhiteList(pUser->pTimeWhiteList);
2,584,701✔
2707
  if (pNew->pTimeWhiteList == NULL) {
2,584,701✔
UNCOV
2708
    code = TSDB_CODE_OUT_OF_MEMORY;
×
UNCOV
2709
    goto _OVER;
×
2710
  }
2711

2712
_OVER:
2,584,701✔
2713
  taosRUnLockLatch(&pUser->lock);
2,584,701✔
2714
  if (code == 0) {
2,584,701✔
2715
    dropOldPasswords(pNew);
2,584,701✔
2716
  }
2717
  TAOS_RETURN(code);
2,584,701✔
2718
}
2719

2720
void mndUserFreeObj(SUserObj *pUser) {
6,366,867✔
2721
  taosHashCleanup(pUser->ownedDbs);
6,366,867✔
2722
  taosHashCleanup(pUser->objPrivs);
6,366,867✔
2723
  taosHashCleanup(pUser->selectTbs);
6,366,867✔
2724
  taosHashCleanup(pUser->insertTbs);
6,366,867✔
2725
  taosHashCleanup(pUser->updateTbs);
6,366,867✔
2726
  taosHashCleanup(pUser->deleteTbs);
6,366,867✔
2727
  taosHashCleanup(pUser->roles);
6,366,867✔
2728
  taosMemoryFreeClear(pUser->passwords);
6,366,867✔
2729
  taosMemoryFreeClear(pUser->pIpWhiteListDual);
6,366,867✔
2730
  taosMemoryFreeClear(pUser->pTimeWhiteList);
6,366,867✔
2731
  pUser->ownedDbs = NULL;
6,366,867✔
2732
  pUser->objPrivs = NULL;
6,366,867✔
2733
  pUser->selectTbs = NULL;
6,366,867✔
2734
  pUser->insertTbs = NULL;
6,366,867✔
2735
  pUser->updateTbs = NULL;
6,366,867✔
2736
  pUser->deleteTbs = NULL;
6,366,867✔
2737
  pUser->roles = NULL;
6,366,867✔
2738
  if (pUser->legacyPrivs) {
6,366,867✔
UNCOV
2739
    taosHashCleanup(pUser->legacyPrivs->pReadDbs);
×
UNCOV
2740
    taosHashCleanup(pUser->legacyPrivs->pWriteDbs);
×
2741
    taosHashCleanup(pUser->legacyPrivs->pReadTbs);
×
2742
    taosHashCleanup(pUser->legacyPrivs->pWriteTbs);
×
2743
    taosHashCleanup(pUser->legacyPrivs->pTopics);
×
2744
    taosHashCleanup(pUser->legacyPrivs->pAlterTbs);
×
2745
    taosHashCleanup(pUser->legacyPrivs->pReadViews);
×
2746
    taosHashCleanup(pUser->legacyPrivs->pWriteViews);
×
2747
    taosHashCleanup(pUser->legacyPrivs->pAlterViews);
×
2748
    taosHashCleanup(pUser->legacyPrivs->pUseDbs);
×
2749
    taosMemoryFreeClear(pUser->legacyPrivs);
×
2750
  }
2751
}
6,366,867✔
2752

2753
static int32_t mndUserActionDelete(SSdb *pSdb, SUserObj *pUser) {
3,194,429✔
2754
  mTrace("user:%s, perform delete action, row:%p", pUser->user, pUser);
3,194,429✔
2755
  mndUserFreeObj(pUser);
3,194,429✔
2756
  return 0;
3,194,429✔
2757
}
2758

2759
static int32_t mndUserActionUpdate(SSdb *pSdb, SUserObj *pOld, SUserObj *pNew) {
2,626,433✔
2760
  mTrace("user:%s, perform update action, old row:%p new row:%p", pOld->user, pOld, pNew);
2,626,433✔
2761
  taosWLockLatch(&pOld->lock);
2,626,433✔
2762
  pOld->updateTime = pNew->updateTime;
2,626,433✔
2763
  pOld->authVersion = pNew->authVersion;
2,626,433✔
2764
  pOld->passVersion = pNew->passVersion;
2,626,433✔
2765
  pOld->sysInfo = pNew->sysInfo;
2,626,433✔
2766
  pOld->enable = pNew->enable;
2,626,433✔
2767
  pOld->flag = pNew->flag;
2,626,433✔
2768
  pOld->changePass = pNew->changePass;
2,626,433✔
2769
  pOld->uid = pNew->uid;
2,626,433✔
2770

2771
  pOld->sessionPerUser = pNew->sessionPerUser;
2,626,433✔
2772
  pOld->connectTime = pNew->connectTime;
2,626,433✔
2773
  pOld->connectIdleTime = pNew->connectIdleTime;
2,626,433✔
2774
  pOld->callPerSession = pNew->callPerSession;
2,626,433✔
2775
  pOld->vnodePerCall = pNew->vnodePerCall;
2,626,433✔
2776
  pOld->failedLoginAttempts = pNew->failedLoginAttempts;
2,626,433✔
2777
  pOld->passwordLifeTime = pNew->passwordLifeTime;
2,626,433✔
2778
  pOld->passwordReuseTime = pNew->passwordReuseTime;
2,626,433✔
2779
  pOld->passwordReuseMax = pNew->passwordReuseMax;
2,626,433✔
2780
  pOld->passwordLockTime = pNew->passwordLockTime;
2,626,433✔
2781
  pOld->passwordGraceTime = pNew->passwordGraceTime;
2,626,433✔
2782
  pOld->inactiveAccountTime = pNew->inactiveAccountTime;
2,626,433✔
2783
  pOld->allowTokenNum = pNew->allowTokenNum;
2,626,433✔
2784
  pOld->tokenNum = pNew->tokenNum;
2,626,433✔
2785

2786
  pOld->numOfPasswords = pNew->numOfPasswords;
2,626,433✔
2787
  TSWAP(pOld->passwords, pNew->passwords);
2,626,433✔
2788
  (void)memcpy(pOld->salt, pNew->salt, sizeof(pOld->salt));
2,626,433✔
2789
  (void)memcpy(pOld->totpsecret, pNew->totpsecret, sizeof(pOld->totpsecret));
2,626,433✔
2790
  pOld->sysPrivs = pNew->sysPrivs;
2,626,433✔
2791
  TSWAP(pOld->ownedDbs, pNew->ownedDbs);
2,626,433✔
2792
  TSWAP(pOld->objPrivs, pNew->objPrivs);
2,626,433✔
2793
  TSWAP(pOld->selectTbs, pNew->selectTbs);
2,626,433✔
2794
  TSWAP(pOld->insertTbs, pNew->insertTbs);
2,626,433✔
2795
  TSWAP(pOld->updateTbs, pNew->updateTbs);
2,626,433✔
2796
  TSWAP(pOld->deleteTbs, pNew->deleteTbs);
2,626,433✔
2797
  TSWAP(pOld->roles, pNew->roles);
2,626,433✔
2798
  TSWAP(pOld->legacyPrivs, pNew->legacyPrivs);
2,626,433✔
2799

2800
  TSWAP(pOld->pIpWhiteListDual, pNew->pIpWhiteListDual);
2,626,433✔
2801
  pOld->ipWhiteListVer = pNew->ipWhiteListVer;
2,626,433✔
2802
  TSWAP(pOld->pTimeWhiteList, pNew->pTimeWhiteList);
2,626,433✔
2803
  pOld->timeWhiteListVer = pNew->timeWhiteListVer;
2,626,433✔
2804
  pOld->passEncryptAlgorithm = pNew->passEncryptAlgorithm;
2,626,433✔
2805

2806
  taosWUnLockLatch(&pOld->lock);
2,626,433✔
2807

2808
  return 0;
2,626,433✔
2809
}
2810

2811
int32_t mndAcquireUser(SMnode *pMnode, const char *userName, SUserObj **ppUser) {
106,188,183✔
2812
  int32_t code = 0;
106,188,183✔
2813
  SSdb   *pSdb = pMnode->pSdb;
106,188,183✔
2814

2815
  *ppUser = sdbAcquire(pSdb, SDB_USER, userName);
106,188,890✔
2816
  if (*ppUser == NULL) {
106,189,278✔
2817
    if (terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
102,521✔
2818
      code = TSDB_CODE_MND_USER_NOT_EXIST;
102,521✔
2819
    } else {
UNCOV
2820
      code = TSDB_CODE_MND_USER_NOT_AVAILABLE;
×
2821
    }
2822
  }
2823
  TAOS_RETURN(code);
106,189,584✔
2824
}
2825

2826
void mndReleaseUser(SMnode *pMnode, SUserObj *pUser) {
157,512,025✔
2827
  SSdb *pSdb = pMnode->pSdb;
157,512,025✔
2828
  sdbRelease(pSdb, pUser);
157,512,362✔
2829
}
157,512,408✔
2830

UNCOV
2831
int32_t mndAcquireUserById(SMnode *pMnode, int64_t userId, SUserObj **ppUser) {
×
UNCOV
2832
  void     *pIter = NULL;
×
2833
  SUserObj *pObj;
×
2834
  SSdb     *pSdb = pMnode->pSdb;
×
2835
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pObj))) {
×
2836
    if (pObj->uid == userId) {
×
2837
      return mndAcquireUser(pMnode, pObj->user, ppUser);
×
2838
    }
2839
  }
UNCOV
2840
  return 0;
×
2841
}
2842

2843
int32_t mndBuildUidNamesHash(SMnode *pMnode, SSHashObj **ppHash) {
514,805✔
2844
  int32_t    code = 0;
514,805✔
2845
  void      *pIter = NULL;
514,805✔
2846
  SUserObj  *pObj;
514,805✔
2847
  SSHashObj *pHash = NULL;
514,805✔
2848

2849
  int32_t nUser = sdbGetSize(pMnode->pSdb, SDB_USER);
514,805✔
2850

2851
  pHash = tSimpleHashInit(nUser, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT));
514,805✔
2852
  if (pHash == NULL) {
514,805✔
UNCOV
2853
    TAOS_RETURN(terrno);
×
2854
  }
2855

2856
  while ((pIter = sdbFetch(pMnode->pSdb, SDB_USER, pIter, (void **)&pObj))) {
1,220,410✔
2857
    code = tSimpleHashPut(pHash, &pObj->uid, sizeof(pObj->uid), pObj->name, strlen(pObj->name) + 1);
705,605✔
2858
    if (code != 0) {
705,605✔
UNCOV
2859
      sdbRelease(pMnode->pSdb, pObj);
×
UNCOV
2860
      sdbCancelFetch(pMnode->pSdb, pIter);
×
2861
      tSimpleHashCleanup(pHash);
×
2862
      TAOS_RETURN(code);
×
2863
    }
2864
    sdbRelease(pMnode->pSdb, pObj);
705,605✔
2865
  }
2866

2867
  *ppHash = pHash;
514,805✔
2868
  TAOS_RETURN(code);
514,805✔
2869
}
2870

2871
int32_t mndEncryptPass(char *pass, const char *salt, int8_t *algo) {
105,407✔
2872
  int32_t code = 0;
105,407✔
2873
  if (tsMetaKey[0] == '\0') {
105,407✔
2874
    return 0;
105,275✔
2875
  }
2876

2877
  if (salt[0] != 0) {
132✔
2878
    char passAndSalt[TSDB_PASSWORD_LEN - 1 + TSDB_PASSWORD_SALT_LEN];
132✔
2879
    (void)memcpy(passAndSalt, pass, TSDB_PASSWORD_LEN - 1);
132✔
2880
    (void)memcpy(passAndSalt + TSDB_PASSWORD_LEN - 1, salt, TSDB_PASSWORD_SALT_LEN);
132✔
2881
    taosEncryptPass_c((uint8_t *)passAndSalt, sizeof(passAndSalt), pass);
2882
  }
2883

2884
  unsigned char packetData[TSDB_PASSWORD_LEN] = {0};
132✔
2885
  SCryptOpts    opts = {0};
132✔
2886
  opts.len = TSDB_PASSWORD_LEN;
132✔
2887
  opts.source = pass;
132✔
2888
  opts.result = packetData;
132✔
2889
  opts.unitLen = TSDB_PASSWORD_LEN;
132✔
2890
  tstrncpy(opts.key, tsDataKey, ENCRYPT_KEY_LEN + 1);
132✔
2891
  int newLen = Builtin_CBC_Encrypt(&opts);
132✔
2892
  if (newLen <= 0) return terrno;
132✔
2893

2894
  memcpy(pass, packetData, newLen);
132✔
2895
  if (algo != NULL) {
132✔
2896
    *algo = DND_CA_SM4;
132✔
2897
  }
2898

2899
  return 0;
132✔
2900
}
2901

2902
static void generateSalt(char *salt, size_t len) {
84,699✔
2903
  const char *set = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
84,699✔
2904
  int32_t     setLen = 62;
84,699✔
2905
  for (int32_t i = 0; i < len - 1; ++i) {
2,710,368✔
2906
    salt[i] = set[taosSafeRand() % setLen];
2,625,669✔
2907
  }
2908
  salt[len - 1] = 0;
84,699✔
2909
}
84,699✔
2910

2911
static int32_t addDefaultIpToTable(SHashObj *pUniqueTab) {
1,057✔
2912
  int32_t code = 0;
1,057✔
2913
  int32_t lino = 0;
1,057✔
2914
  int32_t dummy = 0;
1,057✔
2915

2916
  SIpRange ipv4 = {0}, ipv6 = {0};
1,057✔
2917
  code = createDefaultIp4Range(&ipv4);
1,057✔
2918
  TSDB_CHECK_CODE(code, lino, _error);
1,057✔
2919

2920
  code = taosHashPut(pUniqueTab, &ipv4, sizeof(ipv4), &dummy, sizeof(dummy));
1,057✔
2921
  TSDB_CHECK_CODE(code, lino, _error);
1,057✔
2922

2923
  code = createDefaultIp6Range(&ipv6);
1,057✔
2924
  TSDB_CHECK_CODE(code, lino, _error);
1,057✔
2925

2926
  code = taosHashPut(pUniqueTab, &ipv6, sizeof(ipv6), &dummy, sizeof(dummy));
1,057✔
2927
  TSDB_CHECK_CODE(code, lino, _error);
1,057✔
2928
    
2929
_error:
1,057✔
2930
  if (code != 0) {
1,057✔
UNCOV
2931
    mError("failed to add default ip range to table since %s", tstrerror(code));
×
2932
  }
2933
  return code;
1,057✔
2934
}
2935

2936
static int32_t mndCreateUser(SMnode *pMnode, char *acct, SCreateUserReq *pCreate, SRpcMsg *pReq) {
84,524✔
2937
  int32_t  code = 0;
84,524✔
2938
  int32_t  lino = 0;
84,524✔
2939
  SUserObj userObj = {0};
84,524✔
2940

2941
  userObj.passwords = taosMemoryCalloc(1, sizeof(SUserPassword));
84,524✔
2942
  if (userObj.passwords == NULL) {
84,524✔
UNCOV
2943
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2944
  }
2945
  userObj.numOfPasswords = 1;
84,524✔
2946

2947
  if (pCreate->isImport == 1) {
84,524✔
UNCOV
2948
    memset(userObj.salt, 0, sizeof(userObj.salt));
×
UNCOV
2949
    memcpy(userObj.passwords[0].pass, pCreate->pass, TSDB_PASSWORD_LEN);
×
2950
  } else {
2951
    generateSalt(userObj.salt, sizeof(userObj.salt));
84,524✔
2952
    taosEncryptPass_c((uint8_t *)pCreate->pass, strlen(pCreate->pass), userObj.passwords[0].pass);
84,524✔
2953
    userObj.passwords[0].pass[sizeof(userObj.passwords[0].pass) - 1] = 0;
84,524✔
2954
    TAOS_CHECK_GOTO(mndEncryptPass(userObj.passwords[0].pass, userObj.salt, &userObj.passEncryptAlgorithm), &lino,
84,524✔
2955
                    _OVER);
2956
  }
2957
  userObj.passwords[0].setTime = taosGetTimestampSec();
84,524✔
2958

2959
  tstrncpy(userObj.user, pCreate->user, TSDB_USER_LEN);
84,524✔
2960
  tstrncpy(userObj.acct, acct, TSDB_USER_LEN);
84,524✔
2961
  if (pCreate->totpseed[0] != 0) {
84,524✔
UNCOV
2962
    int len = taosGenerateTotpSecret(pCreate->totpseed, 0, userObj.totpsecret, sizeof(userObj.totpsecret));
×
UNCOV
2963
    if (len < 0) {
×
2964
      TAOS_CHECK_GOTO(TSDB_CODE_PAR_INVALID_OPTION_VALUE, &lino, _OVER);
×
2965
    }
2966
  }
2967

2968
  userObj.createdTime = taosGetTimestampMs();
84,524✔
2969
  userObj.updateTime = userObj.createdTime;
84,524✔
2970
  userObj.superUser = 0;  // pCreate->superUser;
84,524✔
2971
  userObj.sysInfo = pCreate->sysInfo;
84,524✔
2972
  userObj.enable = pCreate->enable;
84,524✔
2973
  userObj.createdb = pCreate->createDb;
84,524✔
2974
  userObj.uid = mndGenerateUid(userObj.user, strlen(userObj.user));
84,524✔
2975

2976
  if (userObj.createdb == 1) {
84,524✔
2977
    privAddType(&userObj.sysPrivs, PRIV_DB_CREATE);
2978
  }
2979

2980
#ifdef TD_ENTERPRISE
2981

2982
  userObj.changePass = pCreate->changepass;
84,524✔
2983
  userObj.sessionPerUser = pCreate->sessionPerUser;
84,524✔
2984
  userObj.connectTime = pCreate->connectTime;
84,524✔
2985
  userObj.connectIdleTime = pCreate->connectIdleTime;
84,524✔
2986
  userObj.callPerSession = pCreate->callPerSession;
84,524✔
2987
  userObj.vnodePerCall = pCreate->vnodePerCall;
84,524✔
2988
  userObj.failedLoginAttempts = pCreate->failedLoginAttempts;
84,524✔
2989
  userObj.passwordLifeTime = pCreate->passwordLifeTime;
84,524✔
2990
  userObj.passwordReuseTime = pCreate->passwordReuseTime;
84,524✔
2991
  userObj.passwordReuseMax = pCreate->passwordReuseMax;
84,524✔
2992
  userObj.passwordLockTime = pCreate->passwordLockTime;
84,524✔
2993
  userObj.passwordGraceTime = pCreate->passwordGraceTime;
84,524✔
2994
  userObj.inactiveAccountTime = pCreate->inactiveAccountTime;
84,524✔
2995
  userObj.allowTokenNum = pCreate->allowTokenNum;
84,524✔
2996
  userObj.tokenNum = 0;
84,524✔
2997

2998
  if (pCreate->numIpRanges == 0) {
84,524✔
2999
    TAOS_CHECK_GOTO(createDefaultIpWhiteList(&userObj.pIpWhiteListDual), &lino, _OVER);
83,056✔
3000
  } else {
3001
    SHashObj *pUniqueTab = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
1,468✔
3002
    if (pUniqueTab == NULL) {
1,468✔
UNCOV
3003
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3004
    }
3005
    
3006
    bool hasPositive = false;
1,468✔
3007
    for (int i = 0; i < pCreate->numIpRanges; i++) {
3,681✔
3008
      SIpRange range = {0};
2,213✔
3009
      copyIpRange(&range, pCreate->pIpDualRanges + i);
2,213✔
3010
      hasPositive = hasPositive || !range.neg;
2,213✔
3011
      int32_t dummy = 0;
2,213✔
3012
      if ((code = taosHashPut(pUniqueTab, &range, sizeof(range), &dummy, sizeof(dummy))) != 0) {
2,213✔
UNCOV
3013
        taosHashCleanup(pUniqueTab);
×
UNCOV
3014
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3015
      }
3016
    }
3017

3018
    // add local ip if there is any positive range
3019
    if (hasPositive) {
1,468✔
3020
      code = addDefaultIpToTable(pUniqueTab);
1,057✔
3021
      if (code != 0) {
1,057✔
UNCOV
3022
        taosHashCleanup(pUniqueTab);
×
UNCOV
3023
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3024
      }
3025
    }
3026

3027
    if (taosHashGetSize(pUniqueTab) > MND_MAX_USER_IP_RANGE) {
1,468✔
UNCOV
3028
      taosHashCleanup(pUniqueTab);
×
UNCOV
3029
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_IP_RANGE, &lino, _OVER);
×
3030
    }
3031

3032
    int32_t           numOfRanges = taosHashGetSize(pUniqueTab);
1,468✔
3033
    SIpWhiteListDual *p = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + numOfRanges * sizeof(SIpRange));
1,468✔
3034
    if (p == NULL) {
1,468✔
UNCOV
3035
      taosHashCleanup(pUniqueTab);
×
UNCOV
3036
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3037
    }
3038

3039
    void *pIter = taosHashIterate(pUniqueTab, NULL);
1,468✔
3040
    for (int32_t i = 0; i < numOfRanges; i++) {
5,453✔
3041
      size_t    len = 0;
3,985✔
3042
      SIpRange *key = taosHashGetKey(pIter, &len);
3,985✔
3043
      memcpy(&p->pIpRanges[i], key, sizeof(SIpRange));
3,985✔
3044
      pIter = taosHashIterate(pUniqueTab, pIter);
3,985✔
3045
    }
3046

3047
    taosHashCleanup(pUniqueTab);
1,468✔
3048
    p->num = numOfRanges;
1,468✔
3049
    sortIpWhiteList(p);
1,468✔
3050
    userObj.pIpWhiteListDual = p;
1,468✔
3051
  }
3052

3053
  if (pCreate->numTimeRanges == 0) {
84,524✔
3054
    userObj.pTimeWhiteList = (SDateTimeWhiteList *)taosMemoryCalloc(1, sizeof(SDateTimeWhiteList));
82,743✔
3055
    if (userObj.pTimeWhiteList == NULL) {
82,743✔
UNCOV
3056
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3057
    }
3058
  } else {
3059
    SHashObj *pUniqueTab = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
1,781✔
3060
    if (pUniqueTab == NULL) {
1,781✔
UNCOV
3061
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3062
    }
3063

3064
    for (int i = 0; i < pCreate->numTimeRanges; i++) {
3,973✔
3065
      SDateTimeRange        *src = pCreate->pTimeRanges + i;
2,192✔
3066
      SDateTimeWhiteListItem range = {0};
2,192✔
3067
      DateTimeRangeToWhiteListItem(&range, src);
2,192✔
3068

3069
      // no need to add expired range
3070
      if (isDateTimeWhiteListItemExpired(&range)) {
2,192✔
3071
        continue;
274✔
3072
      }
3073

3074
      int32_t dummy = 0;
1,918✔
3075
      if ((code = taosHashPut(pUniqueTab, &range, sizeof(range), &dummy, sizeof(dummy))) != 0) {
1,918✔
UNCOV
3076
        taosHashCleanup(pUniqueTab);
×
UNCOV
3077
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3078
      }
3079
    }
3080

3081
    if (taosHashGetSize(pUniqueTab) > MND_MAX_USER_TIME_RANGE) {
1,781✔
UNCOV
3082
      taosHashCleanup(pUniqueTab);
×
UNCOV
3083
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_TIME_RANGE, &lino, _OVER);
×
3084
    }
3085

3086
    int32_t             numOfRanges = taosHashGetSize(pUniqueTab);
1,781✔
3087
    SDateTimeWhiteList *p =
3,562✔
3088
        taosMemoryCalloc(1, sizeof(SDateTimeWhiteList) + numOfRanges * sizeof(SDateTimeWhiteListItem));
1,781✔
3089
    if (p == NULL) {
1,781✔
UNCOV
3090
      taosHashCleanup(pUniqueTab);
×
UNCOV
3091
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3092
    }
3093

3094
    void *pIter = taosHashIterate(pUniqueTab, NULL);
1,781✔
3095
    for (int32_t i = 0; i < numOfRanges; i++) {
3,699✔
3096
      size_t                  len = 0;
1,918✔
3097
      SDateTimeWhiteListItem *key = taosHashGetKey(pIter, &len);
1,918✔
3098
      memcpy(p->ranges + i, key, sizeof(SDateTimeWhiteListItem));
1,918✔
3099
      pIter = taosHashIterate(pUniqueTab, pIter);
1,918✔
3100
    }
3101

3102
    taosHashCleanup(pUniqueTab);
1,781✔
3103
    p->num = numOfRanges;
1,781✔
3104
    sortTimeWhiteList(p);
1,781✔
3105
    userObj.pTimeWhiteList = p;
1,781✔
3106
  }
3107

3108
  userObj.ipWhiteListVer = taosGetTimestampMs();
84,524✔
3109
  userObj.timeWhiteListVer = userObj.ipWhiteListVer;
84,524✔
3110
  
3111

3112
#else  // TD_ENTERPRISE
3113

3114
  userObj.changePass = 1;
3115
  userObj.sessionPerUser = -1;
3116
  userObj.connectTime = -1;
3117
  userObj.connectIdleTime = -1;
3118
  userObj.callPerSession = -1;
3119
  userObj.vnodePerCall = -1;
3120
  userObj.failedLoginAttempts = -1;
3121
  userObj.passwordLifeTime = -1;
3122
  userObj.passwordReuseTime = 0;
3123
  userObj.passwordReuseMax = 0;
3124
  userObj.passwordLockTime = -1;
3125
  userObj.passwordGraceTime = -1;
3126
  userObj.inactiveAccountTime = -1;
3127
  userObj.allowTokenNum = -1;
3128
  userObj.tokenNum = 0;
3129

3130
  TAOS_CHECK_GOTO(createDefaultIpWhiteList(&userObj.pIpWhiteListDual), &lino, _OVER);
3131
  userObj.pTimeWhiteList = (SDateTimeWhiteList *)taosMemoryCalloc(1, sizeof(SDateTimeWhiteList));
3132
  if (userObj.pTimeWhiteList == NULL) {
3133
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
3134
  }
3135

3136
  userObj.ipWhiteListVer = 0;
3137
  userObj.timeWhiteListVer = 0;
3138

3139
#endif  // TD_ENTERPRISE
3140

3141
  userObj.roles = taosHashInit(1, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
84,524✔
3142
  if (userObj.roles == NULL) {
84,524✔
UNCOV
3143
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3144
  }
3145

3146
  uint8_t flag = 0x01;
84,524✔
3147
  if ((code = taosHashPut(userObj.roles, TSDB_ROLE_DEFAULT, strlen(TSDB_ROLE_DEFAULT) + 1, &flag, sizeof(flag))) != 0) {
84,524✔
UNCOV
3148
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3149
  }
3150

3151
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "create-user");
84,524✔
3152
  if (pTrans == NULL) {
84,524✔
UNCOV
3153
    mError("user:%s, failed to create since %s", pCreate->user, terrstr());
×
UNCOV
3154
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3155
  }
3156
  mInfo("trans:%d, used to create user:%s", pTrans->id, pCreate->user);
84,524✔
3157

3158
  SSdbRaw *pCommitRaw = mndUserActionEncode(&userObj);
84,524✔
3159
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
84,524✔
UNCOV
3160
    mError("trans:%d, failed to commit redo log since %s", pTrans->id, terrstr());
×
UNCOV
3161
    mndTransDrop(pTrans);
×
3162
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3163
  }
3164
  TAOS_CHECK_GOTO(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY), &lino, _OVER);
84,524✔
3165

3166
  if (mndTransPrepare(pMnode, pTrans) != 0) {
84,524✔
UNCOV
3167
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
UNCOV
3168
    mndTransDrop(pTrans);
×
3169
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3170
  }
3171

3172
  if ((code = userCacheUpdateWhiteList(pMnode, &userObj)) != 0) {
84,524✔
UNCOV
3173
    mndTransDrop(pTrans);
×
UNCOV
3174
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3175
  }
3176

3177
  if (taosHashGet(userObj.roles, TSDB_ROLE_SYSAUDIT_LOG, strlen(TSDB_ROLE_SYSAUDIT_LOG) + 1)) {
84,524✔
UNCOV
3178
    (void)mndResetAuditLogUser(pMnode, userObj.user, true);
×
3179
  }
3180

3181
  mndTransDrop(pTrans);
84,524✔
3182

3183
_OVER:
84,524✔
3184
  mndUserFreeObj(&userObj);
84,524✔
3185
  TAOS_RETURN(code);
84,524✔
3186
}
3187

3188
static int32_t mndCheckPasswordFmt(const char *pwd) {
126,667✔
3189
  if (tsEnableAdvancedSecurity == 0 && strcmp(pwd, "taosdata") == 0) {
126,667✔
UNCOV
3190
    return 0;
×
3191
  }
3192

3193
  if (tsEnableStrongPassword == 0) {
126,667✔
3194
    for (char c = *pwd; c != 0; c = *(++pwd)) {
104,710✔
3195
      if (c == ' ' || c == '\'' || c == '\"' || c == '`' || c == '\\') {
98,509✔
UNCOV
3196
        return TSDB_CODE_MND_INVALID_PASS_FORMAT;
×
3197
      }
3198
    }
3199
    return 0;
6,201✔
3200
  }
3201

3202
  int32_t len = strlen(pwd);
120,466✔
3203
  if (len < TSDB_PASSWORD_MIN_LEN) {
120,466✔
UNCOV
3204
    return TSDB_CODE_PAR_PASSWD_TOO_SHORT_OR_EMPTY;
×
3205
  }
3206

3207
  if (len > TSDB_PASSWORD_MAX_LEN) {
120,466✔
UNCOV
3208
    return TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG;
×
3209
  }
3210

3211
  if (taosIsComplexString(pwd)) {
120,466✔
3212
    return 0;
99,520✔
3213
  }
3214

3215
  return TSDB_CODE_MND_INVALID_PASS_FORMAT;
20,946✔
3216
}
3217

UNCOV
3218
static int32_t mndCheckTotpSeedFmt(const char *seed) {
×
UNCOV
3219
  int32_t len = strlen(seed);
×
3220
  if (len < TSDB_USER_TOTPSEED_MIN_LEN) {
×
3221
    return TSDB_CODE_PAR_OPTION_VALUE_TOO_SHORT;
×
3222
  }
3223

UNCOV
3224
  if (taosIsComplexString(seed)) {
×
UNCOV
3225
    return 0;
×
3226
  }
3227

UNCOV
3228
  return TSDB_CODE_PAR_INVALID_OPTION_VALUE;
×
3229
}
3230

UNCOV
3231
static int32_t mndProcessGetUserDateTimeWhiteListReq(SRpcMsg *pReq) {
×
UNCOV
3232
  SMnode                *pMnode = pReq->info.node;
×
3233
  int32_t                code = 0;
×
3234
  int32_t                lino = 0;
×
3235
  int32_t                contLen = 0;
×
3236
  void                  *pRsp = NULL;
×
3237
  SUserObj              *pUser = NULL;
×
3238
  SGetUserWhiteListReq   wlReq = {0};
×
3239
  SUserDateTimeWhiteList wlRsp = {0};
×
3240

3241
  if (tDeserializeSGetUserWhiteListReq(pReq->pCont, pReq->contLen, &wlReq) != 0) {
×
UNCOV
3242
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
3243
  }
3244
  mTrace("user: %s, start to get date time whitelist", wlReq.user);
×
3245

3246
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, wlReq.user, &pUser), &lino, _OVER);
×
UNCOV
3247
  TAOS_CHECK_GOTO(mndSetUserDateTimeWhiteListRsp(pMnode, pUser, &wlRsp), &lino, _OVER);
×
3248

3249
  contLen = tSerializeSUserDateTimeWhiteList(NULL, 0, &wlRsp);
×
UNCOV
3250
  if (contLen < 0) {
×
3251
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3252
  }
3253
  pRsp = rpcMallocCont(contLen);
×
UNCOV
3254
  if (pRsp == NULL) {
×
3255
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3256
  }
3257

UNCOV
3258
  contLen = tSerializeSUserDateTimeWhiteList(pRsp, contLen, &wlRsp);
×
UNCOV
3259
  if (contLen < 0) {
×
3260
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3261
  }
3262

UNCOV
3263
_OVER:
×
UNCOV
3264
  mndReleaseUser(pMnode, pUser);
×
3265
  tFreeSUserDateTimeWhiteList(&wlRsp);
×
3266
  if (code < 0) {
×
3267
    mError("user:%s, failed to get whitelist at line %d since %s", wlReq.user, lino, tstrerror(code));
×
3268
    rpcFreeCont(pRsp);
×
3269
    pRsp = NULL;
×
3270
    contLen = 0;
×
3271
  }
3272
  pReq->code = code;
×
UNCOV
3273
  pReq->info.rsp = pRsp;
×
3274
  pReq->info.rspLen = contLen;
×
3275

3276
  TAOS_RETURN(code);
×
3277
  return 0;
3278
}
3279

3280
static int32_t buildRetrieveDateTimeWhiteListRsp(SRetrieveDateTimeWhiteListRsp *pRsp) {
453✔
3281
  (void)taosThreadRwlockRdlock(&userCache.rw);
453✔
3282

3283
  int32_t count = taosHashGetSize(userCache.users);
453✔
3284
  pRsp->pUsers = taosMemoryCalloc(count, sizeof(SUserDateTimeWhiteList));
453✔
3285
  if (pRsp->pUsers == NULL) {
453✔
UNCOV
3286
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
UNCOV
3287
    TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
3288
  }
3289

3290
  count = 0;
453✔
3291
  void *pIter = taosHashIterate(userCache.users, NULL);
453✔
3292
  while (pIter) {
906✔
3293
    SDateTimeWhiteList *wl = (*(SCachedUserInfo **)pIter)->wlTime;
453✔
3294
    if (wl == NULL || wl->num <= 0) {
453✔
3295
      pIter = taosHashIterate(userCache.users, pIter);
453✔
3296
      continue;
453✔
3297
    }
3298

UNCOV
3299
    SUserDateTimeWhiteList *pUser = &pRsp->pUsers[count];
×
UNCOV
3300
    pUser->ver = userCache.verTime;
×
3301

3302
    size_t klen;
×
UNCOV
3303
    char  *key = taosHashGetKey(pIter, &klen);
×
3304
    (void)memcpy(pUser->user, key, klen);
×
3305

3306
    pUser->numWhiteLists = wl->num;
×
UNCOV
3307
    pUser->pWhiteLists = taosMemoryCalloc(wl->num, sizeof(SDateTimeWhiteListItem));
×
3308
    if (pUser->pWhiteLists == NULL) {
×
3309
      (void)taosThreadRwlockUnlock(&userCache.rw);
×
3310
      TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
3311
    }
3312

UNCOV
3313
    (void)memcpy(pUser->pWhiteLists, wl->ranges, wl->num * sizeof(SDateTimeWhiteListItem));
×
UNCOV
3314
    count++;
×
3315
    pIter = taosHashIterate(userCache.users, pIter);
×
3316
  }
3317

3318
  pRsp->numOfUser = count;
453✔
3319
  pRsp->ver = userCache.verTime;
453✔
3320
  (void)taosThreadRwlockUnlock(&userCache.rw);
453✔
3321
  TAOS_RETURN(0);
453✔
3322
}
3323

3324
static int32_t mndProcessRetrieveDateTimeWhiteListReq(SRpcMsg *pReq) {
453✔
3325
  int32_t                       code = 0;
453✔
3326
  int32_t                       lino = 0;
453✔
3327
  int32_t                       len = 0;
453✔
3328
  void                         *pRsp = NULL;
453✔
3329
  SRetrieveDateTimeWhiteListRsp wlRsp = {0};
453✔
3330

3331
  // impl later
3332
  SRetrieveWhiteListReq req = {0};
453✔
3333
  if (tDeserializeRetrieveWhiteListReq(pReq->pCont, pReq->contLen, &req) != 0) {
453✔
UNCOV
3334
    code = TSDB_CODE_INVALID_MSG;
×
UNCOV
3335
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3336
  }
3337

3338
  TAOS_CHECK_GOTO(buildRetrieveDateTimeWhiteListRsp(&wlRsp), &lino, _OVER);
453✔
3339

3340
  len = tSerializeSRetrieveDateTimeWhiteListRsp(NULL, 0, &wlRsp);
453✔
3341
  if (len < 0) {
453✔
UNCOV
3342
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
3343
  }
3344

3345
  pRsp = rpcMallocCont(len);
453✔
3346
  if (!pRsp) {
453✔
UNCOV
3347
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3348
  }
3349
  len = tSerializeSRetrieveDateTimeWhiteListRsp(pRsp, len, &wlRsp);
453✔
3350
  if (len < 0) {
453✔
UNCOV
3351
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
3352
  }
3353

3354
_OVER:
453✔
3355
  if (code < 0) {
453✔
UNCOV
3356
    mError("failed to process retrieve ip white request at line %d since %s", lino, tstrerror(code));
×
UNCOV
3357
    rpcFreeCont(pRsp);
×
3358
    pRsp = NULL;
×
3359
    len = 0;
×
3360
  }
3361
  pReq->code = code;
453✔
3362
  pReq->info.rsp = pRsp;
453✔
3363
  pReq->info.rspLen = len;
453✔
3364

3365
  tFreeSRetrieveDateTimeWhiteListRsp(&wlRsp);
453✔
3366
  TAOS_RETURN(code);
453✔
3367
}
3368

3369
static int32_t mndProcessCreateUserReq(SRpcMsg *pReq) {
95,459✔
3370
  SMnode        *pMnode = pReq->info.node;
95,459✔
3371
  int32_t        code = 0;
95,459✔
3372
  int32_t        lino = 0;
95,459✔
3373
  SRoleObj      *pRole = NULL;
95,459✔
3374
  SUserObj      *pUser = NULL;
95,459✔
3375
  SUserObj      *pOperUser = NULL;
95,459✔
3376
  SCreateUserReq createReq = {0};
95,459✔
3377
  int64_t        tss = taosGetTimestampMs();
95,459✔
3378

3379
  if (tDeserializeSCreateUserReq(pReq->pCont, pReq->contLen, &createReq) != 0) {
95,459✔
UNCOV
3380
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
3381
  }
3382

3383
  mInfo("user:%s, start to create, createdb:%d, is_import:%d", createReq.user, createReq.createDb, createReq.isImport);
95,459✔
3384

3385
#ifndef TD_ENTERPRISE
3386
  if (createReq.isImport == 1) {
3387
    TAOS_CHECK_GOTO(TSDB_CODE_OPS_NOT_SUPPORT, &lino, _OVER);  // enterprise feature
3388
  }
3389
#endif
3390
  code = mndAcquireUser(pMnode, RPC_MSG_USER(pReq), &pOperUser);
95,459✔
3391
  if (pOperUser == NULL) {
95,459✔
UNCOV
3392
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_USER_FROM_CONN, &lino, _OVER);
×
3393
  }
3394

3395
  if (createReq.isImport != 1) {
95,459✔
3396
    // TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, RPC_MSG_USER(pReq), MND_OPER_CREATE_USER), &lino, _OVER);
3397
    TAOS_CHECK_GOTO(mndCheckSysObjPrivilege(pMnode, pOperUser, RPC_MSG_TOKEN(pReq), PRIV_USER_CREATE, 0, 0, NULL, NULL),
95,459✔
3398
                    &lino, _OVER);
UNCOV
3399
  } else if (strcmp(RPC_MSG_USER(pReq), "root") != 0) {
×
UNCOV
3400
    mError("The operation is not permitted to create user:%s", RPC_MSG_USER(pReq));
×
3401
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_RIGHTS, &lino, _OVER);
×
3402
  }
3403

3404
  if (createReq.user[0] == 0) {
95,459✔
UNCOV
3405
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
3406
  }
3407

3408
  if (createReq.isImport != 1) {
95,459✔
3409
    code = mndCheckPasswordFmt(createReq.pass);
95,459✔
3410
    TAOS_CHECK_GOTO(code, &lino, _OVER);
95,459✔
3411
  }
3412

3413
  if (createReq.totpseed[0] != 0) {
84,838✔
UNCOV
3414
    code = mndCheckTotpSeedFmt(createReq.totpseed);
×
UNCOV
3415
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3416
  }
3417

3418
  code = mndAcquireUser(pMnode, createReq.user, &pUser);
84,838✔
3419
  if (pUser != NULL) {
84,838✔
3420
    TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_ALREADY_EXIST, &lino, _OVER);
314✔
3421
  }
3422

3423
  code = mndAcquireRole(pMnode, createReq.user, &pRole);
84,524✔
3424
  if (pRole != NULL) {
84,524✔
UNCOV
3425
    TAOS_CHECK_GOTO(TSDB_CODE_MND_ROLE_ALREADY_EXIST, &lino, _OVER);
×
3426
  }
3427

3428
  TAOS_CHECK_GOTO(grantCheck(TSDB_GRANT_USER), &lino, _OVER);
84,524✔
3429

3430
  if (sdbGetSize(pMnode->pSdb, SDB_USER) >= TSDB_MAX_USERS) {
84,524✔
UNCOV
3431
    mError("user:%s, failed to create since reach max user limit %d", createReq.user, TSDB_MAX_USERS);
×
UNCOV
3432
    TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USERS, &lino, _OVER);
×
3433
  }
3434

3435
  if (!createReq.hasSessionPerUser) createReq.sessionPerUser = (tsEnableAdvancedSecurity ? TSDB_USER_SESSION_PER_USER_DEFAULT : -1);
84,524✔
3436
  if (!createReq.hasConnectTime) createReq.connectTime = (tsEnableAdvancedSecurity ? TSDB_USER_CONNECT_TIME_DEFAULT : -1);
84,524✔
3437
  if (!createReq.hasConnectIdleTime) createReq.connectIdleTime = (tsEnableAdvancedSecurity ? TSDB_USER_CONNECT_IDLE_TIME_DEFAULT : -1);
84,524✔
3438
  if (!createReq.hasCallPerSession) createReq.callPerSession = (tsEnableAdvancedSecurity ? TSDB_USER_CALL_PER_SESSION_DEFAULT : -1);
84,524✔
3439
  if (!createReq.hasVnodePerCall) createReq.vnodePerCall = (tsEnableAdvancedSecurity ? TSDB_USER_VNODE_PER_CALL_DEFAULT : -1);
84,524✔
3440
  if (!createReq.hasFailedLoginAttempts) createReq.failedLoginAttempts = (tsEnableAdvancedSecurity ? TSDB_USER_FAILED_LOGIN_ATTEMPTS_DEFAULT : -1);
84,524✔
3441
  if (!createReq.hasPasswordLifeTime) createReq.passwordLifeTime = (tsEnableAdvancedSecurity ? TSDB_USER_PASSWORD_LIFE_TIME_DEFAULT : -1);
84,524✔
3442
  if (!createReq.hasPasswordReuseTime) createReq.passwordReuseTime = (tsEnableAdvancedSecurity ? TSDB_USER_PASSWORD_REUSE_TIME_DEFAULT : 0);
84,524✔
3443
  if (!createReq.hasPasswordReuseMax) createReq.passwordReuseMax = (tsEnableAdvancedSecurity ? TSDB_USER_PASSWORD_REUSE_MAX_DEFAULT : 0);
84,524✔
3444
  if (!createReq.hasPasswordLockTime) createReq.passwordLockTime = (tsEnableAdvancedSecurity ? TSDB_USER_PASSWORD_LOCK_TIME_DEFAULT : 1);
84,524✔
3445
  if (!createReq.hasPasswordGraceTime) createReq.passwordGraceTime = (tsEnableAdvancedSecurity ? TSDB_USER_PASSWORD_GRACE_TIME_DEFAULT : -1);
84,524✔
3446
  if (!createReq.hasInactiveAccountTime) createReq.inactiveAccountTime = (tsEnableAdvancedSecurity ? TSDB_USER_INACTIVE_ACCOUNT_TIME_DEFAULT : -1);
84,524✔
3447
  if (!createReq.hasAllowTokenNum) createReq.allowTokenNum = TSDB_USER_ALLOW_TOKEN_NUM_DEFAULT;
84,524✔
3448

3449
  code = mndCreateUser(pMnode, pOperUser->acct, &createReq, pReq);
84,524✔
3450
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
84,524✔
3451

3452
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
84,524✔
3453
    char detail[1000] = {0};
84,524✔
3454
    (void)tsnprintf(detail, sizeof(detail), "enable:%d, superUser:%d, sysInfo:%d, password:xxx", createReq.enable,
84,524✔
3455
                    createReq.superUser, createReq.sysInfo);
84,524✔
3456
    char operation[15] = {0};
84,524✔
3457
    if (createReq.isImport == 1) {
84,524✔
UNCOV
3458
      tstrncpy(operation, "importUser", sizeof(operation));
×
3459
    } else {
3460
      tstrncpy(operation, "createUser", sizeof(operation));
84,524✔
3461
    }
3462

3463
    int64_t tse = taosGetTimestampMs();
84,524✔
3464
    double  duration = (double)(tse - tss);
84,524✔
3465
    duration = duration / 1000;
84,524✔
3466

3467
    auditRecord(pReq, pMnode->clusterId, operation, "", createReq.user, detail, strlen(detail), duration, 0);
84,524✔
3468
  }
3469

3470
_OVER:
95,459✔
3471
  if (code == TSDB_CODE_MND_USER_ALREADY_EXIST && createReq.ignoreExists) {
95,459✔
UNCOV
3472
    code = 0;
×
3473
  } else if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
95,459✔
3474
    mError("user:%s, failed to create at line %d since %s", createReq.user, lino, tstrerror(code));
10,935✔
3475
  }
3476

3477
  mndReleaseRole(pMnode, pRole);
95,459✔
3478
  mndReleaseUser(pMnode, pUser);
95,459✔
3479
  mndReleaseUser(pMnode, pOperUser);
95,459✔
3480
  tFreeSCreateUserReq(&createReq);
95,459✔
3481

3482
  TAOS_RETURN(code);
95,459✔
3483
}
3484

3485
static int32_t mndProcessGetUserIpWhiteListReq(SRpcMsg *pReq) {
8,157✔
3486
  SMnode                *pMnode = pReq->info.node;
8,157✔
3487
  int32_t                code = 0;
8,157✔
3488
  int32_t                lino = 0;
8,157✔
3489
  int32_t                contLen = 0;
8,157✔
3490
  void                  *pRsp = NULL;
8,157✔
3491
  SUserObj              *pUser = NULL;
8,157✔
3492
  SGetUserWhiteListReq   wlReq = {0};
8,157✔
3493
  SGetUserIpWhiteListRsp wlRsp = {0};
8,157✔
3494

3495
  int32_t (*serialFn)(void *, int32_t, SGetUserIpWhiteListRsp *) = NULL;
8,157✔
3496
  int32_t (*setRspFn)(SMnode *pMnode, SUserObj *pUser, SGetUserIpWhiteListRsp *pRsp) = NULL;
8,157✔
3497

3498
  if (pReq->msgType == TDMT_MND_GET_USER_IP_WHITELIST_DUAL) {
8,157✔
3499
    serialFn = tSerializeSGetUserIpWhiteListDualRsp;
8,157✔
3500
    setRspFn = mndSetUserIpWhiteListDualRsp;
8,157✔
3501
  } else {
UNCOV
3502
    serialFn = tSerializeSGetUserIpWhiteListRsp;
×
UNCOV
3503
    setRspFn = mndSetUserIpWhiteListRsp;
×
3504
  }
3505
  if (tDeserializeSGetUserWhiteListReq(pReq->pCont, pReq->contLen, &wlReq) != 0) {
8,157✔
3506
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
3507
  }
3508
  mTrace("user: %s, start to get ip whitelist", wlReq.user);
8,157✔
3509

3510
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, wlReq.user, &pUser), &lino, _OVER);
8,157✔
3511
  TAOS_CHECK_GOTO(setRspFn(pMnode, pUser, &wlRsp), &lino, _OVER);
8,157✔
3512

3513
  contLen = serialFn(NULL, 0, &wlRsp);
8,157✔
3514
  if (contLen < 0) {
8,157✔
UNCOV
3515
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3516
  }
3517
  pRsp = rpcMallocCont(contLen);
8,157✔
3518
  if (pRsp == NULL) {
8,157✔
UNCOV
3519
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3520
  }
3521

3522
  contLen = serialFn(pRsp, contLen, &wlRsp);
8,157✔
3523
  if (contLen < 0) {
8,157✔
UNCOV
3524
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3525
  }
3526

3527
_OVER:
8,157✔
3528
  mndReleaseUser(pMnode, pUser);
8,157✔
3529
  tFreeSGetUserIpWhiteListDualRsp(&wlRsp);
8,157✔
3530
  if (code < 0) {
8,157✔
UNCOV
3531
    mError("user:%s, failed to get whitelist at line %d since %s", wlReq.user, lino, tstrerror(code));
×
UNCOV
3532
    rpcFreeCont(pRsp);
×
UNCOV
3533
    pRsp = NULL;
×
3534
    contLen = 0;
×
3535
  }
3536
  pReq->code = code;
8,157✔
3537
  pReq->info.rsp = pRsp;
8,157✔
3538
  pReq->info.rspLen = contLen;
8,157✔
3539

3540
  TAOS_RETURN(code);
8,157✔
3541
}
3542

3543
static int32_t buildRetrieveIpWhiteListRsp(SUpdateIpWhite *pUpdate) {
453✔
3544
  (void)taosThreadRwlockRdlock(&userCache.rw);
453✔
3545

3546
  int32_t count = taosHashGetSize(userCache.users);
453✔
3547
  pUpdate->pUserIpWhite = taosMemoryCalloc(count, sizeof(SUpdateUserIpWhite));
453✔
3548
  if (pUpdate->pUserIpWhite == NULL) {
453✔
UNCOV
3549
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
UNCOV
3550
    TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
3551
  }
3552

3553
  count = 0;
453✔
3554
  void *pIter = taosHashIterate(userCache.users, NULL);
453✔
3555
  while (pIter) {
906✔
3556
    SIpWhiteListDual *wl = (*(SCachedUserInfo **)pIter)->wlIp;
453✔
3557
    if (wl == NULL || wl->num <= 0) {
453✔
UNCOV
3558
      pIter = taosHashIterate(userCache.users, pIter);
×
UNCOV
3559
      continue;
×
3560
    }
3561

3562
    SUpdateUserIpWhite *pUser = &pUpdate->pUserIpWhite[count];
453✔
3563
    pUser->ver = userCache.verIp;
453✔
3564

3565
    size_t klen;
453✔
3566
    char  *key = taosHashGetKey(pIter, &klen);
453✔
3567
    (void)memcpy(pUser->user, key, klen);
453✔
3568

3569
    pUser->numOfRange = wl->num;
453✔
3570
    pUser->pIpRanges = taosMemoryCalloc(wl->num, sizeof(SIpRange));
453✔
3571
    if (pUser->pIpRanges == NULL) {
453✔
UNCOV
3572
      (void)taosThreadRwlockUnlock(&userCache.rw);
×
UNCOV
3573
      TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
3574
    }
3575

3576
    (void)memcpy(pUser->pIpRanges, wl->pIpRanges, wl->num * sizeof(SIpRange));
453✔
3577
    count++;
453✔
3578
    pIter = taosHashIterate(userCache.users, pIter);
453✔
3579
  }
3580

3581
  pUpdate->numOfUser = count;
453✔
3582
  pUpdate->ver = userCache.verIp;
453✔
3583
  (void)taosThreadRwlockUnlock(&userCache.rw);
453✔
3584
  TAOS_RETURN(0);
453✔
3585
}
3586

3587
int32_t mndProcessRetrieveIpWhiteListReq(SRpcMsg *pReq) {
453✔
3588
  int32_t        code = 0;
453✔
3589
  int32_t        lino = 0;
453✔
3590
  int32_t        len = 0;
453✔
3591
  void          *pRsp = NULL;
453✔
3592
  SUpdateIpWhite ipWhite = {0};
453✔
3593

3594
  // impl later
3595
  SRetrieveWhiteListReq req = {0};
453✔
3596
  if (tDeserializeRetrieveWhiteListReq(pReq->pCont, pReq->contLen, &req) != 0) {
453✔
UNCOV
3597
    code = TSDB_CODE_INVALID_MSG;
×
UNCOV
3598
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3599
  }
3600

3601
  int32_t (*fn)(void *, int32_t, SUpdateIpWhite *) = NULL;
453✔
3602
  if (pReq->msgType == TDMT_MND_RETRIEVE_IP_WHITELIST) {
453✔
UNCOV
3603
    fn = tSerializeSUpdateIpWhite;
×
3604
  } else if (pReq->msgType == TDMT_MND_RETRIEVE_IP_WHITELIST_DUAL) {
453✔
3605
    fn = tSerializeSUpdateIpWhiteDual;
453✔
3606
  }
3607

3608
  TAOS_CHECK_GOTO(buildRetrieveIpWhiteListRsp(&ipWhite), &lino, _OVER);
453✔
3609

3610
  len = fn(NULL, 0, &ipWhite);
453✔
3611
  if (len < 0) {
453✔
UNCOV
3612
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
3613
  }
3614

3615
  pRsp = rpcMallocCont(len);
453✔
3616
  if (!pRsp) {
453✔
UNCOV
3617
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3618
  }
3619
  len = fn(pRsp, len, &ipWhite);
453✔
3620
  if (len < 0) {
453✔
UNCOV
3621
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
3622
  }
3623

3624
_OVER:
453✔
3625
  if (code < 0) {
453✔
UNCOV
3626
    mError("failed to process retrieve ip white request at line %d since %s", lino, tstrerror(code));
×
UNCOV
3627
    rpcFreeCont(pRsp);
×
UNCOV
3628
    pRsp = NULL;
×
3629
    len = 0;
×
3630
  }
3631
  pReq->code = code;
453✔
3632
  pReq->info.rsp = pRsp;
453✔
3633
  pReq->info.rspLen = len;
453✔
3634

3635
  tFreeSUpdateIpWhiteReq(&ipWhite);
453✔
3636
  TAOS_RETURN(code);
453✔
3637
}
3638

3639
static int32_t mndAlterUser(SMnode *pMnode, SUserObj *pNew, SRpcMsg *pReq) {
1,344,897✔
3640
  int32_t code = 0, lino = 0;
1,344,897✔
3641
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "alter-user");
1,344,897✔
3642
  if (pTrans == NULL) {
1,344,897✔
UNCOV
3643
    mError("user:%s, failed to alter since %s", pNew->user, terrstr());
×
UNCOV
3644
    TAOS_RETURN(terrno);
×
3645
  }
3646
  mInfo("trans:%d, used to alter user:%s", pTrans->id, pNew->user);
1,344,897✔
3647

3648
  SSdbRaw *pCommitRaw = mndUserActionEncode(pNew);
1,344,897✔
3649
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
1,344,897✔
UNCOV
3650
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
UNCOV
3651
    mndTransDrop(pTrans);
×
UNCOV
3652
    TAOS_RETURN(terrno);
×
3653
  }
3654
  TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
1,344,897✔
3655

3656
  if (mndTransPrepare(pMnode, pTrans) != 0) {
1,344,897✔
UNCOV
3657
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
UNCOV
3658
    mndTransDrop(pTrans);
×
UNCOV
3659
    TAOS_RETURN(terrno);
×
3660
  }
3661
  if ((code = userCacheUpdateWhiteList(pMnode, pNew)) != 0) {
1,344,897✔
3662
    mndTransDrop(pTrans);
×
UNCOV
3663
    TAOS_RETURN(code);
×
3664
  }
3665
_exit:
1,344,897✔
3666
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
1,344,897✔
UNCOV
3667
    mError("user:%s, failed to alter at line %d since %s", pNew->user, lino, tstrerror(code));
×
3668
  }
3669
  mndTransDrop(pTrans);
1,344,897✔
3670
  TAOS_RETURN(code);
1,344,897✔
3671
}
3672

UNCOV
3673
static int32_t mndDupObjHash(SHashObj *pOld, int32_t dataLen, SHashObj **ppNew) {
×
UNCOV
3674
  int32_t code = 0;
×
3675

3676
  *ppNew =
×
3677
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
UNCOV
3678
  if (*ppNew == NULL) {
×
3679
    code = terrno ? terrno : TSDB_CODE_OUT_OF_MEMORY;
×
3680
    TAOS_RETURN(code);
×
3681
  }
3682

3683
  char *db = taosHashIterate(pOld, NULL);
×
UNCOV
3684
  while (db != NULL) {
×
UNCOV
3685
    int32_t len = strlen(db) + 1;
×
3686
    if ((code = taosHashPut(*ppNew, db, len, db, dataLen)) != 0) {
×
3687
      taosHashCancelIterate(pOld, db);
×
3688
      taosHashCleanup(*ppNew);
×
3689
      TAOS_RETURN(code);
×
3690
    }
3691
    db = taosHashIterate(pOld, db);
×
3692
  }
3693

3694
  TAOS_RETURN(code);
×
3695
}
3696

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

UNCOV
3699
int32_t mndDupTopicHash(SHashObj *pOld, SHashObj **ppNew) { return mndDupObjHash(pOld, TSDB_TOPIC_FNAME_LEN, ppNew); }
×
3700

UNCOV
3701
static int32_t mndTablePriviledge(SMnode *pMnode, SHashObj *hash, SHashObj *useDbHash, SAlterUserReq *alterReq,
×
3702
                                  SSdb *pSdb) {
UNCOV
3703
  void *pIter = NULL;
×
3704
  char  tbFName[TSDB_TABLE_FNAME_LEN] = {0};
×
3705

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

3709
  if (alterReq->tagCond != NULL && alterReq->tagCondLen != 0) {
×
3710
    char *value = taosHashGet(hash, tbFName, len);
×
UNCOV
3711
    if (value != NULL) {
×
3712
      TAOS_RETURN(TSDB_CODE_MND_PRIVILEGE_EXIST);
×
3713
    }
3714

3715
    int32_t condLen = alterReq->tagCondLen;
×
UNCOV
3716
    TAOS_CHECK_RETURN(taosHashPut(hash, tbFName, len, alterReq->tagCond, condLen));
×
3717
  } else {
3718
    TAOS_CHECK_RETURN(taosHashPut(hash, tbFName, len, alterReq->isView ? "v" : "t", 2));
×
3719
  }
3720

3721
  int32_t  dbKeyLen = strlen(alterReq->objname) + 1;
×
UNCOV
3722
  int32_t  ref = 1;
×
UNCOV
3723
  int32_t *currRef = taosHashGet(useDbHash, alterReq->objname, dbKeyLen);
×
3724
  if (NULL != currRef) {
×
3725
    ref = (*currRef) + 1;
×
3726
  }
3727
  TAOS_CHECK_RETURN(taosHashPut(useDbHash, alterReq->objname, dbKeyLen, &ref, sizeof(ref)));
×
3728

UNCOV
3729
  TAOS_RETURN(0);
×
3730
}
3731

3732
static int32_t mndRemoveTablePriviledge(SMnode *pMnode, SHashObj *hash, SHashObj *useDbHash, SAlterUserReq *alterReq,
×
3733
                                        SSdb *pSdb) {
UNCOV
3734
  void *pIter = NULL;
×
3735
  char  tbFName[TSDB_TABLE_FNAME_LEN] = {0};
×
UNCOV
3736
  (void)snprintf(tbFName, sizeof(tbFName), "%s.%s", alterReq->objname, alterReq->tabName);
×
3737
  int32_t len = strlen(tbFName) + 1;
×
3738

3739
  if (taosHashRemove(hash, tbFName, len) != 0) {
×
3740
    TAOS_RETURN(0);  // not found
×
3741
  }
3742

3743
  int32_t  dbKeyLen = strlen(alterReq->objname) + 1;
×
UNCOV
3744
  int32_t *currRef = taosHashGet(useDbHash, alterReq->objname, dbKeyLen);
×
UNCOV
3745
  if (NULL == currRef) {
×
3746
    return 0;
×
3747
  }
3748

3749
  if (1 == *currRef) {
×
UNCOV
3750
    if (taosHashRemove(useDbHash, alterReq->objname, dbKeyLen) != 0) {
×
UNCOV
3751
      TAOS_RETURN(0);  // not found
×
3752
    }
3753
    return 0;
×
3754
  }
UNCOV
3755
  int32_t ref = (*currRef) - 1;
×
3756
  TAOS_CHECK_RETURN(taosHashPut(useDbHash, alterReq->objname, dbKeyLen, &ref, sizeof(ref)));
×
3757

3758
  return 0;
×
3759
}
3760

3761
#if 0
3762
static int32_t mndProcessAlterUserPrivilegesReq(SRpcMsg* pReq, SAlterUserReq *pAlterReq) {
3763
  SMnode   *pMnode = pReq->info.node;
3764
  SSdb     *pSdb = pMnode->pSdb;
3765
  int32_t   code = 0, lino = 0;
3766
  SUserObj *pUser = NULL;
3767
  SUserObj  newUser = {0};
3768
  int64_t   tss = taosGetTimestampMs();
3769

3770
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, pAlterReq->user, &pUser), &lino, _OVER);
3771
  TAOS_CHECK_GOTO(mndCheckAlterUserPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser, pAlterReq), &lino, _OVER);
3772
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
3773

3774
#if 0
3775
  if (ALTER_USER_ADD_READ_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName) ||
3776
      ALTER_USER_ADD_ALL_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName)) {
3777
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
3778
      int32_t len = strlen(pAlterReq->objname) + 1;
3779
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
3780
      if (pDb == NULL) {
3781
        mndReleaseDb(pMnode, pDb);
3782
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
3783
      }
3784
      if ((code = taosHashPut(newUser.readDbs, pAlterReq->objname, len, pAlterReq->objname, TSDB_DB_FNAME_LEN)) !=
3785
          0) {
3786
        mndReleaseDb(pMnode, pDb);
3787
        TAOS_CHECK_GOTO(code, &lino, _OVER);
3788
      }
3789
      mndReleaseDb(pMnode, pDb);
3790
    } else {
3791
      void   *pIter = NULL;
3792
      while (1) {
3793
        SDbObj *pDb = NULL;
3794
        pIter = sdbFetch(pSdb, SDB_DB, pIter, (void **)&pDb);
3795
        if (pIter == NULL) break;
3796
        int32_t len = strlen(pDb->name) + 1;
3797
        if ((code = taosHashPut(newUser.readDbs, pDb->name, len, pDb->name, TSDB_DB_FNAME_LEN)) != 0) {
3798
          sdbRelease(pSdb, pDb);
3799
          sdbCancelFetch(pSdb, pIter);
3800
          TAOS_CHECK_GOTO(code, &lino, _OVER);
3801
        }
3802
        sdbRelease(pSdb, pDb);
3803
      }
3804
    }
3805
  }
3806

3807
  if (ALTER_USER_ADD_WRITE_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName) ||
3808
      ALTER_USER_ADD_ALL_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName)) {
3809
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
3810
      int32_t len = strlen(pAlterReq->objname) + 1;
3811
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
3812
      if (pDb == NULL) {
3813
        mndReleaseDb(pMnode, pDb);
3814
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
3815
      }
3816
      if ((code = taosHashPut(newUser.writeDbs, pAlterReq->objname, len, pAlterReq->objname, TSDB_DB_FNAME_LEN)) !=
3817
          0) {
3818
        mndReleaseDb(pMnode, pDb);
3819
        TAOS_CHECK_GOTO(code, &lino, _OVER);
3820
      }
3821
      mndReleaseDb(pMnode, pDb);
3822
    } else {
3823
      void   *pIter = NULL;
3824
      while (1) {
3825
        SDbObj *pDb = NULL;
3826
        pIter = sdbFetch(pSdb, SDB_DB, pIter, (void **)&pDb);
3827
        if (pIter == NULL) break;
3828
        int32_t len = strlen(pDb->name) + 1;
3829
        if ((code = taosHashPut(newUser.writeDbs, pDb->name, len, pDb->name, TSDB_DB_FNAME_LEN)) != 0) {
3830
          sdbRelease(pSdb, pDb);
3831
          sdbCancelFetch(pSdb, pIter);
3832
          TAOS_CHECK_GOTO(code, &lino, _OVER);
3833
        }
3834
        sdbRelease(pSdb, pDb);
3835
      }
3836
    }
3837
  }
3838

3839
  if (ALTER_USER_DEL_READ_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName) ||
3840
      ALTER_USER_DEL_ALL_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName)) {
3841
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
3842
      int32_t len = strlen(pAlterReq->objname) + 1;
3843
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
3844
      if (pDb == NULL) {
3845
        mndReleaseDb(pMnode, pDb);
3846
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
3847
      }
3848
      code = taosHashRemove(newUser.readDbs, pAlterReq->objname, len);
3849
      if (code < 0) {
3850
        mError("read db:%s, failed to remove db:%s since %s", newUser.user, pAlterReq->objname, terrstr());
3851
      }
3852
      mndReleaseDb(pMnode, pDb);
3853
    } else {
3854
      taosHashClear(newUser.readDbs);
3855
    }
3856
  }
3857

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

3877
  SHashObj *pReadTbs = newUser.readTbs;
3878
  SHashObj *pWriteTbs = newUser.writeTbs;
3879
  SHashObj *pAlterTbs = newUser.alterTbs;
3880

3881
#ifdef TD_ENTERPRISE
3882
  if (pAlterReq->isView) {
3883
    pReadTbs = newUser.readViews;
3884
    pWriteTbs = newUser.writeViews;
3885
    pAlterTbs = newUser.alterViews;
3886
  }
3887
#endif
3888

3889
  if (ALTER_USER_ADD_READ_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3890
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3891
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pReadTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3892
  }
3893

3894
  if (ALTER_USER_ADD_WRITE_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3895
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3896
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pWriteTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3897
  }
3898

3899
  if (ALTER_USER_ADD_ALTER_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3900
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3901
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pAlterTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3902
  }
3903

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

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

3914
  if (ALTER_USER_DEL_ALTER_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3915
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3916
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pAlterTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3917
  }
3918
#endif
3919

3920
#if 0
3921
// #ifdef USE_TOPIC
3922
  if (ALTER_USER_ADD_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, &pAlterReq->privileges)) {
3923
    int32_t      len = strlen(pAlterReq->objname) + 1;
3924
    SMqTopicObj *pTopic = NULL;
3925
    if ((code = mndAcquireTopic(pMnode, pAlterReq->objname, &pTopic)) != 0) {
3926
      TAOS_CHECK_GOTO(code, &lino, _OVER);
3927
    }
3928
    taosRLockLatch(&pTopic->lock);
3929
    code = taosHashPut(newUser.topics, pTopic->name, len, pTopic->name, TSDB_TOPIC_FNAME_LEN);
3930
    taosRUnLockLatch(&pTopic->lock);
3931
    mndReleaseTopic(pMnode, pTopic);
3932
    TAOS_CHECK_GOTO(code, &lino, _OVER);
3933
  }
3934

3935
  if (ALTER_USER_DEL_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, &pAlterReq->privileges)) {
3936
    int32_t      len = strlen(pAlterReq->objname) + 1;
3937
    SMqTopicObj *pTopic = NULL;
3938
    if ((code = mndAcquireTopic(pMnode, pAlterReq->objname, &pTopic)) != 0) {
3939
      TAOS_CHECK_GOTO(code, &lino, _OVER);
3940
    }
3941
    taosRLockLatch(&pTopic->lock);
3942
    code = taosHashRemove(newUser.topics, pAlterReq->objname, len);
3943
    if (code < 0) {
3944
      mError("user:%s, failed to remove topic:%s since %s", newUser.user, pAlterReq->objname, tstrerror(code));
3945
    }
3946
    taosRUnLockLatch(&pTopic->lock);
3947
    mndReleaseTopic(pMnode, pTopic);
3948
  }
3949
#endif
3950

3951
  TAOS_CHECK_GOTO(mndAlterUser(pMnode, &newUser, pReq), &lino, _OVER);
3952
  code = TSDB_CODE_ACTION_IN_PROGRESS;
3953

3954
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
3955
    int64_t tse = taosGetTimestampMs();
3956
    double  duration = (double)(tse - tss);
3957
    duration = duration / 1000;
3958
    if (ALTER_USER_ADD_READ_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3959
              ALTER_USER_ADD_WRITE_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3960
              ALTER_USER_ADD_ALL_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3961
              ALTER_USER_ADD_READ_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3962
              ALTER_USER_ADD_WRITE_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3963
              ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3964
      if (strcmp(pAlterReq->objname, "1.*") != 0) {
3965
        SName name = {0};
3966
        TAOS_CHECK_GOTO(tNameFromString(&name, pAlterReq->objname, T_NAME_ACCT | T_NAME_DB), &lino, _OVER);
3967
        auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", name.dbname, pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
3968
      } else {
3969
        auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", "", pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
3970
      }
3971
    } else if (ALTER_USER_ADD_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, pAlterReq->privileges)) {
3972
      auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", pAlterReq->objname, pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
3973
    } else if (ALTER_USER_DEL_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, pAlterReq->privileges)) {
3974
      auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", pAlterReq->objname, pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
3975
    } else {
3976
      if (strcmp(pAlterReq->objname, "1.*") != 0) {
3977
        SName name = {0};
3978
        TAOS_CHECK_GOTO(tNameFromString(&name, pAlterReq->objname, T_NAME_ACCT | T_NAME_DB), &lino, _OVER);
3979
        auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", name.dbname, pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
3980
      } else {
3981
        auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", "", pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
3982
      }
3983
    }
3984
  }
3985
  
3986
_OVER:
3987
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
3988
    mError("user:%s, failed to alter user privileges at line %d since %s", pAlterReq->user, lino, tstrerror(code));
3989
  }
3990
  mndReleaseUser(pMnode, pUser);
3991
  mndUserFreeObj(&newUser);
3992
  TAOS_RETURN(code);
3993
}
3994
#endif
3995

3996
int32_t mndAlterUserFromRole(SRpcMsg *pReq, SUserObj *pOperUser, SAlterRoleReq *pAlterReq) {
1,320,988✔
3997
  SMnode   *pMnode = pReq->info.node;
1,320,988✔
3998
  SSdb     *pSdb = pMnode->pSdb;
1,320,988✔
3999
  void     *pIter = NULL;
1,320,988✔
4000
  int32_t   code = 0, lino = 0;
1,320,988✔
4001
  SUserObj *pUser = NULL;
1,320,988✔
4002
  SUserObj  newUser = {0};
1,320,988✔
4003

4004
  TAOS_CHECK_EXIT(mndAcquireUser(pMnode, pAlterReq->principal, &pUser));
1,320,988✔
4005

4006
  if (pUser->enable == 0) {
1,317,881✔
UNCOV
4007
    TAOS_CHECK_EXIT(TSDB_CODE_MND_USER_DISABLED);
×
4008
  }
4009
  if(pUser->superUser) {
1,317,881✔
4010
    TAOS_CHECK_EXIT(TSDB_CODE_MND_NO_RIGHTS);
2,332✔
4011
  }
4012

4013
  if (pAlterReq->alterType == TSDB_ALTER_ROLE_PRIVILEGES) {
1,315,549✔
4014
#ifdef TD_ENTERPRISE
4015
    TAOS_CHECK_EXIT(mndUserDupObj(pUser, &newUser));
1,304,191✔
4016
    if ((code = mndAlterUserPrivInfo(pMnode, &newUser, pAlterReq)) == TSDB_CODE_QRY_DUPLICATED_OPERATION) {
1,304,191✔
UNCOV
4017
      code = 0;
×
UNCOV
4018
      goto _exit;
×
4019
    } else {
4020
      TAOS_CHECK_EXIT(code);
1,304,191✔
4021
    }
4022
  } else if (pAlterReq->alterType == TSDB_ALTER_ROLE_ROLE) {
11,358✔
4023
    if ((code = mndAlterUserRoleInfo(pMnode, pOperUser, RPC_MSG_TOKEN(pReq), pUser, &newUser, pAlterReq)) ==
11,358✔
4024
        TSDB_CODE_QRY_DUPLICATED_OPERATION) {
4025
      code = 0;
150✔
4026
      goto _exit;
150✔
4027
    } else {
4028
      TAOS_CHECK_EXIT(code);
11,208✔
4029
    }
4030
#endif
4031
  } else {
UNCOV
4032
    TAOS_CHECK_EXIT(TSDB_CODE_INVALID_MSG);
×
4033
  }
4034
  code = mndAlterUser(pMnode, &newUser, pReq);
1,311,147✔
4035
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
1,311,147✔
4036

4037
_exit:
1,320,988✔
4038
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
1,320,988✔
4039
    mError("user:%s, failed to alter user at line %d since %s", pAlterReq->principal, lino, tstrerror(code));
9,691✔
4040
  }
4041
  mndReleaseUser(pMnode, pUser);
1,320,988✔
4042
  mndUserFreeObj(&newUser);
1,320,988✔
4043
  TAOS_RETURN(code);
1,320,988✔
4044
}
4045

4046
static int32_t mndProcessAlterUserBasicInfoReq(SRpcMsg *pReq, SAlterUserReq *pAlterReq) {
47,048✔
4047
  SMnode   *pMnode = pReq->info.node;
47,048✔
4048
  int32_t   code = 0, lino = 0;
47,048✔
4049
  SUserObj *pUser = NULL;
47,048✔
4050
  SUserObj  newUser = {0};
47,048✔
4051
  char      auditLog[1000] = {0};
47,048✔
4052
  int32_t   auditLen = 0;
47,048✔
4053
  int64_t   tss = taosGetTimestampMs();
47,048✔
4054

4055
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, pAlterReq->user, &pUser), &lino, _OVER);
47,048✔
4056
  TAOS_CHECK_GOTO(mndCheckAlterUserPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser, pAlterReq), &lino,
46,161✔
4057
                  _OVER);
4058
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
44,186✔
4059

4060
  if (pAlterReq->hasPassword) {
44,186✔
4061
    auditLen += tsnprintf(auditLog, sizeof(auditLog), "password,");
31,208✔
4062

4063
    TAOS_CHECK_GOTO(mndCheckPasswordFmt(pAlterReq->pass), &lino, _OVER);
31,208✔
4064
    if (newUser.salt[0] == 0) {
20,883✔
4065
      generateSalt(newUser.salt, sizeof(newUser.salt));
175✔
4066
    }
4067
    char pass[TSDB_PASSWORD_LEN] = {0};
20,883✔
4068
    taosEncryptPass_c((uint8_t *)pAlterReq->pass, strlen(pAlterReq->pass), pass);
20,883✔
4069
    pass[sizeof(pass) - 1] = 0;
20,883✔
4070
    TAOS_CHECK_GOTO(mndEncryptPass(pass, newUser.salt, &newUser.passEncryptAlgorithm), &lino, _OVER);
20,883✔
4071

4072
    if (newUser.passwordReuseMax > 0 || newUser.passwordReuseTime > 0) {
20,883✔
4073
      for (int32_t i = 0; i < newUser.numOfPasswords; ++i) {
734,731✔
4074
        if (0 == strncmp(newUser.passwords[i].pass, pass, TSDB_PASSWORD_LEN)) {
720,346✔
4075
          TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_PASSWORD_REUSE, &lino, _OVER);
411✔
4076
        }
4077
      }
4078
      SUserPassword *passwords = taosMemoryCalloc(newUser.numOfPasswords + 1, sizeof(SUserPassword));
14,385✔
4079
      if (passwords == NULL) {
14,385✔
UNCOV
4080
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
4081
      }
4082
      memcpy(passwords + 1, newUser.passwords, newUser.numOfPasswords * sizeof(SUserPassword));
14,385✔
4083
      memcpy(passwords[0].pass, pass, TSDB_PASSWORD_LEN);
14,385✔
4084
      passwords[0].setTime = taosGetTimestampSec();
14,385✔
4085
      taosMemoryFree(newUser.passwords);
14,385✔
4086
      newUser.passwords = passwords;
14,385✔
4087
      ++newUser.numOfPasswords;
14,385✔
4088
      ++newUser.passVersion;
14,385✔
4089
      newUser.changePass = 2;
14,385✔
4090
    } else if (0 != strncmp(newUser.passwords[0].pass, pass, TSDB_PASSWORD_LEN)) {
6,087✔
4091
      memcpy(newUser.passwords[0].pass, pass, TSDB_PASSWORD_LEN);
5,882✔
4092
      newUser.passwords[0].setTime = taosGetTimestampSec();
5,882✔
4093
      ++newUser.passVersion;
5,882✔
4094
      newUser.changePass = 2;
5,882✔
4095
    }
4096
  }
4097

4098
  if (pAlterReq->hasTotpseed) {
33,450✔
UNCOV
4099
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "totpseed,");
×
4100

UNCOV
4101
    if (pAlterReq->totpseed[0] == 0) {  // clear totp secret
×
4102
      memset(newUser.totpsecret, 0, sizeof(newUser.totpsecret));
×
UNCOV
4103
    } else if (taosGenerateTotpSecret(pAlterReq->totpseed, 0, newUser.totpsecret, sizeof(newUser.totpsecret)) < 0) {
×
4104
      TAOS_CHECK_GOTO(TSDB_CODE_PAR_INVALID_OPTION_VALUE, &lino, _OVER);
×
4105
    }
4106
  }
4107

4108
  if (pAlterReq->hasEnable) {
33,450✔
4109
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "enable:%d,", pAlterReq->enable);
1,574✔
4110

4111
    newUser.enable = pAlterReq->enable;  // lock or unlock user manually
1,574✔
4112
    if (newUser.enable) {
1,574✔
4113
      // reset login info to allow login immediately
4114
      userCacheResetLoginInfo(newUser.user);
961✔
4115
    }
4116
  }
4117

4118
  if (pAlterReq->hasSysinfo) {
33,450✔
4119
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "sysinfo:%d,", pAlterReq->sysinfo);
4,118✔
4120
    newUser.sysInfo = pAlterReq->sysinfo;
4,118✔
4121
  }
4122

4123
  if (pAlterReq->hasCreatedb) {
33,450✔
4124
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "createdb:%d,", pAlterReq->createdb);
5,171✔
4125
    newUser.createdb = pAlterReq->createdb;
5,171✔
4126
    if (newUser.createdb == 1) {
5,171✔
4127
      privAddType(&newUser.sysPrivs, PRIV_DB_CREATE);
4128
    } else {
4129
      privRemoveType(&newUser.sysPrivs, PRIV_DB_CREATE);
4130
    }
4131
  }
4132

4133
#ifdef TD_ENTERPRISE
4134
  if (pAlterReq->hasChangepass) {
33,450✔
UNCOV
4135
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "changepass:%d,", pAlterReq->changepass);
×
UNCOV
4136
    newUser.changePass = pAlterReq->changepass;
×
4137
  }
4138

4139
  if (pAlterReq->hasSessionPerUser) {
33,450✔
4140
    auditLen +=
274✔
4141
        tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "sessionPerUser:%d,", pAlterReq->sessionPerUser);
274✔
4142
    newUser.sessionPerUser = pAlterReq->sessionPerUser;
274✔
4143
  }
4144

4145
  if (pAlterReq->hasConnectTime) {
33,450✔
4146
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "connectTime:%d,", pAlterReq->connectTime);
137✔
4147
    newUser.connectTime = pAlterReq->connectTime;
137✔
4148
  }
4149

4150
  if (pAlterReq->hasConnectIdleTime) {
33,450✔
4151
    auditLen +=
137✔
4152
        tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "connectIdleTime:%d,", pAlterReq->connectIdleTime);
137✔
4153
    newUser.connectIdleTime = pAlterReq->connectIdleTime;
137✔
4154
  }
4155

4156
  if (pAlterReq->hasCallPerSession) {
33,450✔
4157
    auditLen +=
411✔
4158
        tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "callPerSession:%d,", pAlterReq->callPerSession);
411✔
4159
    newUser.callPerSession = pAlterReq->callPerSession;
411✔
4160
  }
4161

4162
  if (pAlterReq->hasVnodePerCall) {
33,450✔
4163
    auditLen +=
274✔
4164
        tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "vnodePerCall:%d,", pAlterReq->vnodePerCall);
274✔
4165
    newUser.vnodePerCall = pAlterReq->vnodePerCall;
274✔
4166
  }
4167

4168
  if (pAlterReq->hasFailedLoginAttempts) {
33,450✔
4169
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "failedLoginAttempts:%d,",
411✔
4170
                          pAlterReq->failedLoginAttempts);
4171
    newUser.failedLoginAttempts = pAlterReq->failedLoginAttempts;
411✔
4172
  }
4173

4174
  if (pAlterReq->hasPasswordLifeTime) {
33,450✔
4175
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordLifeTime:%d,",
137✔
4176
                          pAlterReq->passwordLifeTime);
4177
    newUser.passwordLifeTime = pAlterReq->passwordLifeTime;
137✔
4178
  }
4179

4180
  if (pAlterReq->hasPasswordReuseTime) {
33,450✔
4181
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordReuseTime:%d,",
411✔
4182
                          pAlterReq->passwordReuseTime);
4183
    newUser.passwordReuseTime = pAlterReq->passwordReuseTime;
411✔
4184
  }
4185

4186
  if (pAlterReq->hasPasswordReuseMax) {
33,450✔
4187
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordReuseMax:%d,",
411✔
4188
                          pAlterReq->passwordReuseMax);
4189
    newUser.passwordReuseMax = pAlterReq->passwordReuseMax;
411✔
4190
  }
4191

4192
  if (pAlterReq->hasPasswordLockTime) {
33,450✔
4193
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordLockTime:%d,",
137✔
4194
                          pAlterReq->passwordLockTime);
4195
    newUser.passwordLockTime = pAlterReq->passwordLockTime;
137✔
4196
  }
4197

4198
  if (pAlterReq->hasPasswordGraceTime) {
33,450✔
4199
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordGraceTime:%d,",
137✔
4200
                          pAlterReq->passwordGraceTime);
4201
    newUser.passwordGraceTime = pAlterReq->passwordGraceTime;
137✔
4202
  }
4203

4204
  if (pAlterReq->hasInactiveAccountTime) {
33,450✔
4205
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "inactiveAccountTime:%d,",
137✔
4206
                          pAlterReq->inactiveAccountTime);
4207
    newUser.inactiveAccountTime = pAlterReq->inactiveAccountTime;
137✔
4208
  }
4209

4210
  if (pAlterReq->hasAllowTokenNum) {
33,450✔
4211
    auditLen +=
274✔
4212
        tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "allowTokenNum:%d,", pAlterReq->allowTokenNum);
274✔
4213
    newUser.allowTokenNum = pAlterReq->allowTokenNum;
274✔
4214
  }
4215

4216
  if (pAlterReq->numDropIpRanges > 0 || pAlterReq->numIpRanges > 0) {
33,450✔
4217
    int32_t dummy = 0;
608✔
4218

4219
    // put previous ip whitelist into hash table
4220
    SHashObj *m = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
608✔
4221
    if (m == NULL) {
608✔
UNCOV
4222
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
4223
    }
4224

4225
    for (int32_t i = 0; i < newUser.pIpWhiteListDual->num; i++) {
2,599✔
4226
      SIpRange range;
1,991✔
4227
      copyIpRange(&range, newUser.pIpWhiteListDual->pIpRanges + i);
1,991✔
4228
      code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
1,991✔
4229
      if (code != 0) {
1,991✔
UNCOV
4230
        taosHashCleanup(m);
×
UNCOV
4231
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
4232
      }
4233
    }
4234

4235
    if (pAlterReq->numDropIpRanges > 0) {
608✔
4236
      auditLen +=
304✔
4237
          tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "dropIpRanges:%d,", pAlterReq->numDropIpRanges);
304✔
4238

4239
      for (int32_t i = 0; i < pAlterReq->numDropIpRanges; i++) {
745✔
4240
        if (taosHashGetSize(m) == 0) {
441✔
UNCOV
4241
          break;
×
4242
        }
4243

4244
        SIpRange range;
441✔
4245
        copyIpRange(&range, pAlterReq->pDropIpRanges + i);
441✔
4246

4247
        // for white list, drop default ip ranges is allowed, otherwise, we can never
4248
        // convert white list to black list.
4249

4250
        code = taosHashRemove(m, &range, sizeof(range));
441✔
4251
        if (code == TSDB_CODE_NOT_FOUND) {
441✔
4252
          // treat not exist as success
4253
          code = 0;
167✔
4254
        }
4255
        if (code != 0) {
441✔
UNCOV
4256
          taosHashCleanup(m);
×
UNCOV
4257
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
4258
        }
4259
      }
4260
    }
4261

4262
    if (pAlterReq->numIpRanges > 0) {
608✔
4263
      auditLen +=
304✔
4264
          tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "addIpRanges:%d,", pAlterReq->numIpRanges);
304✔
4265
      for (int32_t i = 0; i < pAlterReq->numIpRanges; i++) {
745✔
4266
        SIpRange range;
441✔
4267
        copyIpRange(&range, pAlterReq->pIpRanges + i);
441✔
4268
        code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
441✔
4269
        if (code != 0) {
441✔
UNCOV
4270
          taosHashCleanup(m);
×
UNCOV
4271
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
4272
        }
4273
      }
4274
    }
4275

4276
    int32_t numOfRanges = taosHashGetSize(m);
608✔
4277
    if (numOfRanges > MND_MAX_USER_IP_RANGE) {
608✔
UNCOV
4278
      taosHashCleanup(m);
×
UNCOV
4279
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_IP_RANGE, &lino, _OVER);
×
4280
    }
4281

4282
    SIpWhiteListDual *p = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + numOfRanges * sizeof(SIpRange));
608✔
4283
    if (p == NULL) {
608✔
UNCOV
4284
      taosHashCleanup(m);
×
UNCOV
4285
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
4286
    }
4287

4288
    void   *pIter = taosHashIterate(m, NULL);
608✔
4289
    int32_t i = 0;
608✔
4290
    while (pIter) {
2,766✔
4291
      size_t    len = 0;
2,158✔
4292
      SIpRange *key = taosHashGetKey(pIter, &len);
2,158✔
4293
      memcpy(p->pIpRanges + i, key, sizeof(SIpRange));
2,158✔
4294
      pIter = taosHashIterate(m, pIter);
2,158✔
4295
      i++;
2,158✔
4296
    }
4297

4298
    taosHashCleanup(m);
608✔
4299
    p->num = numOfRanges;
608✔
4300
    taosMemoryFreeClear(newUser.pIpWhiteListDual);
608✔
4301
    sortIpWhiteList(p);
608✔
4302
    newUser.pIpWhiteListDual = p;
608✔
4303

4304
    newUser.ipWhiteListVer++;
608✔
4305
  }
4306

4307
  if (pAlterReq->numTimeRanges > 0 || pAlterReq->numDropTimeRanges) {
33,450✔
4308
    int32_t dummy = 0;
548✔
4309

4310
    // put previous ip whitelist into hash table
4311
    SHashObj *m = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
548✔
4312
    if (m == NULL) {
548✔
UNCOV
4313
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
4314
    }
4315

4316
    for (int32_t i = 0; i < newUser.pTimeWhiteList->num; i++) {
1,370✔
4317
      SDateTimeWhiteListItem *range = &newUser.pTimeWhiteList->ranges[i];
822✔
4318
      if (isDateTimeWhiteListItemExpired(range)) {
822✔
UNCOV
4319
        continue;
×
4320
      }
4321
      code = taosHashPut(m, range, sizeof(*range), &dummy, sizeof(dummy));
822✔
4322
      if (code != 0) {
822✔
UNCOV
4323
        taosHashCleanup(m);
×
UNCOV
4324
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
4325
      }
4326
    }
4327

4328
    if (pAlterReq->numDropTimeRanges > 0) {
548✔
4329
      auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "dropTimeRanges:%d,",
411✔
4330
                            pAlterReq->numDropTimeRanges);
4331
      for (int32_t i = 0; i < pAlterReq->numDropTimeRanges; i++) {
959✔
4332
        if (taosHashGetSize(m) == 0) {
548✔
UNCOV
4333
          break;
×
4334
        }
4335
        SDateTimeWhiteListItem range = {0};
548✔
4336
        DateTimeRangeToWhiteListItem(&range, pAlterReq->pDropTimeRanges + i);
548✔
4337

4338
        code = taosHashRemove(m, &range, sizeof(range));
548✔
4339
        if (code == TSDB_CODE_NOT_FOUND) {
548✔
4340
          // treat not exist as success
UNCOV
4341
          code = 0;
×
4342
        }
4343
        if (code != 0) {
548✔
4344
          taosHashCleanup(m);
×
UNCOV
4345
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
4346
        }
4347
      }
4348
    }
4349

4350
    if (pAlterReq->numTimeRanges > 0) {
548✔
4351
      auditLen +=
411✔
4352
          tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "addTimeRanges:%d,", pAlterReq->numTimeRanges);
411✔
4353
      for (int32_t i = 0; i < pAlterReq->numTimeRanges; i++) {
959✔
4354
        SDateTimeWhiteListItem range = {0};
548✔
4355
        DateTimeRangeToWhiteListItem(&range, pAlterReq->pTimeRanges + i);
548✔
4356
        if (isDateTimeWhiteListItemExpired(&range)) {
548✔
UNCOV
4357
          continue;
×
4358
        }
4359
        code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
548✔
4360
        if (code != 0) {
548✔
UNCOV
4361
          taosHashCleanup(m);
×
UNCOV
4362
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
4363
        }
4364
      }
4365
    }
4366

4367
    int32_t numOfRanges = taosHashGetSize(m);
548✔
4368
    if (numOfRanges > MND_MAX_USER_TIME_RANGE) {
548✔
UNCOV
4369
      taosHashCleanup(m);
×
UNCOV
4370
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_TIME_RANGE, &lino, _OVER);
×
4371
    }
4372

4373
    SDateTimeWhiteList *p =
1,096✔
4374
        taosMemoryCalloc(1, sizeof(SDateTimeWhiteList) + numOfRanges * sizeof(SDateTimeWhiteListItem));
548✔
4375
    if (p == NULL) {
548✔
UNCOV
4376
      taosHashCleanup(m);
×
UNCOV
4377
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
4378
    }
4379

4380
    void   *pIter = taosHashIterate(m, NULL);
548✔
4381
    int32_t i = 0;
548✔
4382
    while (pIter) {
1,370✔
4383
      size_t                  len = 0;
822✔
4384
      SDateTimeWhiteListItem *key = taosHashGetKey(pIter, &len);
822✔
4385
      memcpy(&p->ranges[i], key, sizeof(SDateTimeWhiteListItem));
822✔
4386
      pIter = taosHashIterate(m, pIter);
822✔
4387
      i++;
822✔
4388
    }
4389

4390
    taosHashCleanup(m);
548✔
4391
    p->num = numOfRanges;
548✔
4392
    taosMemoryFreeClear(newUser.pTimeWhiteList);
548✔
4393
    sortTimeWhiteList(p);
548✔
4394
    newUser.pTimeWhiteList = p;
548✔
4395
    newUser.timeWhiteListVer++;
548✔
4396
  }
4397
#endif  // TD_ENTERPRISE
4398

4399
  TAOS_CHECK_GOTO(mndAlterUser(pMnode, &newUser, pReq), &lino, _OVER);
33,450✔
4400
  if (pAlterReq->hasEnable) {
33,450✔
4401
    if (newUser.enable) {
1,574✔
4402
      if (taosHashGet(newUser.roles, TSDB_ROLE_SYSAUDIT_LOG, strlen(TSDB_ROLE_SYSAUDIT_LOG) + 1)) {
961✔
UNCOV
4403
        (void)mndResetAuditLogUser(pMnode, newUser.user, true);
×
4404
      }
4405
    } else {
4406
      (void)mndResetAuditLogUser(pMnode, newUser.user, false);
613✔
4407
    }
4408
  }
4409
  code = TSDB_CODE_ACTION_IN_PROGRESS;
33,450✔
4410

4411
  if (auditLen > 0) {
33,450✔
4412
    auditLog[--auditLen] = 0;  // remove last ','
33,450✔
4413
  }
4414
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
33,450✔
4415
    int64_t tse = taosGetTimestampMs();
33,450✔
4416
    double  duration = (double)(tse - tss);
33,450✔
4417
    duration = duration / 1000;
33,450✔
4418
    auditRecord(pReq, pMnode->clusterId, "alterUser", "", pAlterReq->user, auditLog, auditLen, duration, 0);
33,450✔
4419
  }
4420

4421
_OVER:
47,048✔
4422
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
47,048✔
4423
    mError("user:%s, failed to alter at line %d since %s", pAlterReq->user, lino, tstrerror(code));
13,598✔
4424
  }
4425

4426
  mndReleaseUser(pMnode, pUser);
47,048✔
4427
  mndUserFreeObj(&newUser);
47,048✔
4428
  return code;
47,048✔
4429
}
4430

4431
static int32_t mndProcessAlterUserReq(SRpcMsg *pReq) {
47,048✔
4432
  SAlterUserReq alterReq = {0};
47,048✔
4433

4434
  int32_t code = tDeserializeSAlterUserReq(pReq->pCont, pReq->contLen, &alterReq);
47,048✔
4435
  if (code != 0) {
47,048✔
UNCOV
4436
    mError("failed to deserialize alter user request at line %d since %s", __LINE__, tstrerror(code));
×
UNCOV
4437
    TAOS_RETURN(code);
×
4438
  }
4439

4440
  if (alterReq.user[0] == 0) {
47,048✔
UNCOV
4441
    tFreeSAlterUserReq(&alterReq);
×
UNCOV
4442
    mError("failed to alter user at line %d since invalid user format", __LINE__);
×
UNCOV
4443
    TAOS_RETURN(TSDB_CODE_MND_INVALID_USER_FORMAT);
×
4444
  }
4445

4446
  mInfo("user:%s, start to alter", alterReq.user);
47,048✔
4447
  if (alterReq.alterType == TSDB_ALTER_USER_BASIC_INFO) {
47,048✔
4448
    code = mndProcessAlterUserBasicInfoReq(pReq, &alterReq);
47,048✔
4449
  } else {
4450
    // code = mndProcessAlterUserPrivilegesReq(pReq, &alterReq); // obsolete
4451
  }
4452

4453
  tFreeSAlterUserReq(&alterReq);
47,048✔
4454
  TAOS_RETURN(code);
47,048✔
4455
}
4456

4457
int32_t mndResetAuditLogUser(SMnode *pMnode, const char *user, bool isAdd) {
45,397,169✔
4458
  if (user) {
45,397,169✔
4459
    (void)taosThreadRwlockRdlock(&userCache.rw);
45,515✔
4460
    if (isAdd) {
45,515✔
4461
      if (userCache.auditLogUser[0] != 0) {
66✔
UNCOV
4462
        (void)taosThreadRwlockUnlock(&userCache.rw);
×
UNCOV
4463
        return 0;
×
4464
      }
4465
      (void)taosThreadRwlockUnlock(&userCache.rw);
66✔
4466
      (void)taosThreadRwlockWrlock(&userCache.rw);
66✔
4467
      (void)tsnprintf(userCache.auditLogUser, TSDB_USER_LEN, "%s", user);
66✔
4468
      (void)taosThreadRwlockUnlock(&userCache.rw);
66✔
4469
      return 0;
66✔
4470
    } else if (strcmp(userCache.auditLogUser, user) != 0) {
45,449✔
4471
      (void)taosThreadRwlockUnlock(&userCache.rw);
45,449✔
4472
      return 0;
45,449✔
4473
    }
UNCOV
4474
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
4475
  }
4476

4477
  void     *pIter = NULL;
45,351,654✔
4478
  SSdb     *pSdb = pMnode->pSdb;
45,351,654✔
4479
  SUserObj *pUser = NULL;
45,351,654✔
4480
  int32_t   len = strlen(TSDB_ROLE_SYSAUDIT_LOG) + 1;
45,351,654✔
4481
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser))) {
96,132,618✔
4482
    if (pUser->enable == 0) {
50,780,964✔
4483
      mndReleaseUser(pMnode, pUser);
18,304✔
4484
      continue;
18,304✔
4485
    }
4486
    if (taosHashGet(pUser->roles, TSDB_ROLE_SYSAUDIT_LOG, len) != NULL) {
50,762,660✔
UNCOV
4487
      (void)taosThreadRwlockWrlock(&userCache.rw);
×
UNCOV
4488
      (void)tsnprintf(userCache.auditLogUser, TSDB_USER_LEN, "%s", pUser->name);
×
UNCOV
4489
      (void)taosThreadRwlockUnlock(&userCache.rw);
×
4490
      sdbCancelFetch(pSdb, pIter);
×
4491
      mndReleaseUser(pMnode, pUser);
×
4492
      return 0;
×
4493
    }
4494
    mndReleaseUser(pMnode, pUser);
50,762,660✔
4495
  }
4496
  (void)taosThreadRwlockWrlock(&userCache.rw);
45,351,654✔
4497
  userCache.auditLogUser[0] = 0;
45,351,654✔
4498
  (void)taosThreadRwlockUnlock(&userCache.rw);
45,351,654✔
4499
  return TSDB_CODE_MND_USER_NOT_AVAILABLE;
45,351,654✔
4500
}
4501

4502
int32_t mndGetAuditUser(SMnode *pMnode, char *user) {
45,352,644✔
4503
  (void)taosThreadRwlockRdlock(&userCache.rw);
45,352,644✔
4504
  if (userCache.auditLogUser[0] != 0) {
45,352,644✔
4505
    (void)tsnprintf(user, TSDB_USER_LEN, "%s", userCache.auditLogUser);
990✔
4506
    (void)taosThreadRwlockUnlock(&userCache.rw);
990✔
4507
    return 0;
990✔
4508
  }
4509
  (void)taosThreadRwlockUnlock(&userCache.rw);
45,351,654✔
4510

4511
  int32_t code = 0;
45,351,654✔
4512
  if ((code = mndResetAuditLogUser(pMnode, NULL, false)) != 0) {
45,351,654✔
4513
    return code;
45,351,654✔
4514
  }
4515

UNCOV
4516
  (void)taosThreadRwlockRdlock(&userCache.rw);
×
UNCOV
4517
  (void)tsnprintf(user, TSDB_USER_LEN, "%s", userCache.auditLogUser);
×
UNCOV
4518
  (void)taosThreadRwlockUnlock(&userCache.rw);
×
4519

4520
  return 0;
×
4521
}
4522

4523
static int32_t mndDropUser(SMnode *pMnode, SRpcMsg *pReq, SUserObj *pUser) {
44,836✔
4524
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "drop-user");
44,836✔
4525
  if (pTrans == NULL) {
44,836✔
UNCOV
4526
    mError("user:%s, failed to drop since %s", pUser->user, terrstr());
×
UNCOV
4527
    TAOS_RETURN(terrno);
×
4528
  }
4529
  mInfo("trans:%d, used to drop user:%s", pTrans->id, pUser->user);
44,836✔
4530

4531
  SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
44,836✔
4532
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
44,836✔
UNCOV
4533
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
UNCOV
4534
    mndTransDrop(pTrans);
×
UNCOV
4535
    TAOS_RETURN(terrno);
×
4536
  }
4537
  if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED) < 0) {
44,836✔
4538
    mndTransDrop(pTrans);
×
UNCOV
4539
    TAOS_RETURN(terrno);
×
4540
  }
4541

4542
  if (mndDropTokensByUser(pMnode, pTrans, pUser->user) != 0) {
44,836✔
UNCOV
4543
    mndTransDrop(pTrans);
×
UNCOV
4544
    TAOS_RETURN(terrno);
×
4545
  }
4546

4547
  if (mndTransPrepare(pMnode, pTrans) != 0) {
44,836✔
UNCOV
4548
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
UNCOV
4549
    mndTransDrop(pTrans);
×
UNCOV
4550
    TAOS_RETURN(terrno);
×
4551
  }
4552

4553
  userCacheRemoveUser(pUser->user);
44,836✔
4554
  mndDropCachedTokensByUser(pUser->user);
44,836✔
4555
  (void)mndResetAuditLogUser(pMnode, pUser->user, false);
44,836✔
4556

4557
  mndTransDrop(pTrans);
44,836✔
4558
  TAOS_RETURN(0);
44,836✔
4559
}
4560

4561
static int32_t mndProcessDropUserReq(SRpcMsg *pReq) {
45,618✔
4562
  SMnode      *pMnode = pReq->info.node;
45,618✔
4563
  int32_t      code = 0;
45,618✔
4564
  int32_t      lino = 0;
45,618✔
4565
  SUserObj    *pOperUser = NULL;
45,618✔
4566
  SUserObj    *pUser = NULL;
45,618✔
4567
  SDropUserReq dropReq = {0};
45,618✔
4568
  int64_t      tss = taosGetTimestampMs();
45,618✔
4569

4570
  TAOS_CHECK_GOTO(tDeserializeSDropUserReq(pReq->pCont, pReq->contLen, &dropReq), &lino, _OVER);
45,618✔
4571

4572
  mInfo("user:%s, start to drop", dropReq.user);
45,618✔
4573

4574
  if (dropReq.user[0] == 0) {
45,618✔
UNCOV
4575
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
4576
  }
4577

4578
  if (0 == strcmp(dropReq.user, TSDB_DEFAULT_USER)) {
45,618✔
UNCOV
4579
    return TSDB_CODE_MND_NO_RIGHTS;
×
4580
  }
4581

4582
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, dropReq.user, &pUser), &lino, _OVER);
45,618✔
4583

4584
  code = mndAcquireUser(pMnode, RPC_MSG_USER(pReq), &pOperUser);
44,836✔
4585
  if (pOperUser == NULL) {
44,836✔
UNCOV
4586
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_USER_FROM_CONN, &lino, _OVER);
×
4587
  }
4588

4589
  // TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, RPC_MSG_USER(pReq), MND_OPER_DROP_USER), &lino, _OVER);
4590
  TAOS_CHECK_GOTO(mndCheckSysObjPrivilege(pMnode, pOperUser, RPC_MSG_TOKEN(pReq), PRIV_USER_DROP, 0, 0, NULL, NULL),
44,836✔
4591
                  &lino, _OVER);
4592

4593
  TAOS_CHECK_GOTO(mndDropUser(pMnode, pReq, pUser), &lino, _OVER);
44,836✔
4594
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
44,836✔
4595

4596
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
44,836✔
4597
    int64_t tse = taosGetTimestampMs();
44,836✔
4598
    double  duration = (double)(tse - tss);
44,836✔
4599
    duration = duration / 1000;
44,836✔
4600
    auditRecord(pReq, pMnode->clusterId, "dropUser", "", dropReq.user, dropReq.sql, dropReq.sqlLen, duration, 0);
44,836✔
4601
  }
4602

4603
_OVER:
45,618✔
4604
  if (dropReq.ignoreNotExists && code == TSDB_CODE_MND_USER_NOT_EXIST) {
45,618✔
4605
    code = 0;
492✔
4606
  } else if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
45,126✔
4607
    mError("user:%s, failed to drop at line %d since %s", dropReq.user, lino, tstrerror(code));
290✔
4608
  }
4609

4610
  mndReleaseUser(pMnode, pUser);
45,618✔
4611
  mndReleaseUser(pMnode, pOperUser);
45,618✔
4612
  tFreeSDropUserReq(&dropReq);
45,618✔
4613
  TAOS_RETURN(code);
45,618✔
4614
}
4615

4616
static int32_t mndProcessGetUserAuthReq(SRpcMsg *pReq) {
6,549,999✔
4617
  SMnode         *pMnode = pReq->info.node;
6,549,999✔
4618
  int32_t         code = 0;
6,549,999✔
4619
  int32_t         lino = 0;
6,549,999✔
4620
  int32_t         contLen = 0;
6,549,999✔
4621
  void           *pRsp = NULL;
6,549,999✔
4622
  SUserObj       *pUser = NULL;
6,549,999✔
4623
  SGetUserAuthReq authReq = {0};
6,549,999✔
4624
  SGetUserAuthRsp authRsp = {0};
6,549,999✔
4625

4626
  TAOS_CHECK_EXIT(tDeserializeSGetUserAuthReq(pReq->pCont, pReq->contLen, &authReq));
6,549,999✔
4627
  mTrace("user:%s, start to get auth", authReq.user);
6,549,999✔
4628

4629
  TAOS_CHECK_EXIT(mndAcquireUser(pMnode, authReq.user, &pUser));
6,549,999✔
4630

4631
  TAOS_CHECK_EXIT(mndSetUserAuthRsp(pMnode, pUser, &authRsp));
6,548,892✔
4632

4633
  contLen = tSerializeSGetUserAuthRsp(NULL, 0, &authRsp);
6,548,892✔
4634
  if (contLen < 0) {
6,548,892✔
UNCOV
4635
    TAOS_CHECK_EXIT(contLen);
×
4636
  }
4637
  pRsp = rpcMallocCont(contLen);
6,548,892✔
4638
  if (pRsp == NULL) {
6,548,892✔
UNCOV
4639
    TAOS_CHECK_EXIT(terrno);
×
4640
  }
4641

4642
  contLen = tSerializeSGetUserAuthRsp(pRsp, contLen, &authRsp);
6,548,892✔
4643
  if (contLen < 0) {
6,548,892✔
UNCOV
4644
    TAOS_CHECK_EXIT(contLen);
×
4645
  }
4646

4647
_exit:
6,549,999✔
4648
  mndReleaseUser(pMnode, pUser);
6,549,999✔
4649
  tFreeSGetUserAuthRsp(&authRsp);
6,549,999✔
4650
  if (code < 0) {
6,549,999✔
4651
    mError("user:%s, failed to get auth at line %d since %s", authReq.user, lino, tstrerror(code));
1,107✔
4652
    rpcFreeCont(pRsp);
1,107✔
4653
    pRsp = NULL;
1,107✔
4654
    contLen = 0;
1,107✔
4655
  }
4656
  pReq->info.rsp = pRsp;
6,549,999✔
4657
  pReq->info.rspLen = contLen;
6,549,999✔
4658
  pReq->code = code;
6,549,999✔
4659

4660
  TAOS_RETURN(code);
6,549,999✔
4661
}
4662

4663
static void base32Encode(const uint8_t *in, int32_t inLen, char *out) {
16,388✔
4664
  int buffer = 0, bits = 0;
16,388✔
4665
  int outLen = 0;
16,388✔
4666

4667
  // process all input bytes
4668
  for (int i = 0; i < inLen; i++) {
540,804✔
4669
    buffer = (buffer << 8) | in[i];
524,416✔
4670
    bits += 8;
524,416✔
4671

4672
    while (bits >= 5) {
1,360,204✔
4673
      int v = (buffer >> (bits - 5)) & 0x1F;
835,788✔
4674
      out[outLen++] = (v >= 26) ? (v - 26 + '2') : (v + 'A');
835,788✔
4675
      bits -= 5;
835,788✔
4676
    }
4677
  }
4678

4679
  // process remaining bits
4680
  if (bits > 0) {
16,388✔
4681
    int v = (buffer << (5 - bits)) & 0x1F;
16,388✔
4682
    out[outLen++] = (v >= 26) ? (v - 26 + '2') : (v + 'A');
16,388✔
4683
  }
4684

4685
  out[outLen] = '\0';
16,388✔
4686
}
16,388✔
4687

4688
static int32_t mndCreateTotpSecret(SMnode *pMnode, SUserObj *pUser, SRpcMsg *pReq) {
16,388✔
4689
  SCreateTotpSecretRsp rsp = {0};
16,388✔
4690

4691
  base32Encode((uint8_t *)pUser->totpsecret, sizeof(pUser->totpsecret), rsp.totpSecret);
16,388✔
4692
  tstrncpy(rsp.user, pUser->user, sizeof(rsp.user));
16,388✔
4693

4694
  int32_t len = tSerializeSCreateTotpSecretRsp(NULL, 0, &rsp);
16,388✔
4695
  if (len < 0) {
16,388✔
UNCOV
4696
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
4697
  }
4698

4699
  void *pData = taosMemoryMalloc(len);
16,388✔
4700
  if (pData == NULL) {
16,388✔
UNCOV
4701
    TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
4702
  }
4703

4704
  if (tSerializeSCreateTotpSecretRsp(pData, len, &rsp) != len) {
16,388✔
UNCOV
4705
    taosMemoryFree(pData);
×
UNCOV
4706
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
4707
  }
4708

4709
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "create-totp-secret");
16,388✔
4710
  if (pTrans == NULL) {
16,388✔
UNCOV
4711
    mError("user:%s, failed to create totp secret since %s", pUser->user, terrstr());
×
UNCOV
4712
    taosMemoryFree(pData);
×
UNCOV
4713
    TAOS_RETURN(terrno);
×
4714
  }
4715
  mInfo("trans:%d, used to create totp secret for user:%s", pTrans->id, pUser->user);
16,388✔
4716

4717
  mndTransSetUserData(pTrans, pData, len);
16,388✔
4718

4719
  SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
16,388✔
4720
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
16,388✔
UNCOV
4721
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
UNCOV
4722
    mndTransDrop(pTrans);
×
UNCOV
4723
    TAOS_RETURN(terrno);
×
4724
  }
4725
  if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY) < 0) {
16,388✔
4726
    mndTransDrop(pTrans);
×
UNCOV
4727
    TAOS_RETURN(terrno);
×
4728
  }
4729

4730
  if (mndTransPrepare(pMnode, pTrans) != 0) {
16,388✔
UNCOV
4731
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
UNCOV
4732
    mndTransDrop(pTrans);
×
UNCOV
4733
    TAOS_RETURN(terrno);
×
4734
  }
4735

4736
  mndTransDrop(pTrans);
16,388✔
4737
  TAOS_RETURN(0);
16,388✔
4738
}
4739

4740
static int32_t mndProcessCreateTotpSecretReq(SRpcMsg *pReq) {
16,538✔
4741
  SMnode              *pMnode = pReq->info.node;
16,538✔
4742
  int32_t              code = 0;
16,538✔
4743
  int32_t              lino = 0;
16,538✔
4744
  SUserObj            *pUser = NULL;
16,538✔
4745
  SUserObj             newUser = {0};
16,538✔
4746
  SCreateTotpSecretReq req = {0};
16,538✔
4747
  int64_t              tss = taosGetTimestampMs();
16,538✔
4748

4749
  TAOS_CHECK_GOTO(tDeserializeSCreateTotpSecretReq(pReq->pCont, pReq->contLen, &req), &lino, _OVER);
16,538✔
4750
  mTrace("user:%s, start to create/update totp secret", req.user);
16,538✔
4751

4752
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, req.user, &pUser), &lino, _OVER);
16,538✔
4753
  TAOS_CHECK_GOTO(mndCheckTotpSecretPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser, PRIV_TOTP_CREATE),
16,388✔
4754
                  &lino, _OVER);
4755
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
16,388✔
4756
  taosSafeRandBytes((uint8_t *)newUser.totpsecret, sizeof(newUser.totpsecret));
16,388✔
4757
  TAOS_CHECK_GOTO(mndCreateTotpSecret(pMnode, &newUser, pReq), &lino, _OVER);
16,388✔
4758

4759
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
16,388✔
4760
    double duration = (double)(taosGetTimestampMs() - tss) / 1000.0;
16,388✔
4761
    auditRecord(pReq, pMnode->clusterId, "createTotpSecret", "", req.user, req.sql, req.sqlLen, duration, 0);
16,388✔
4762
  }
4763

4764
_OVER:
16,538✔
4765
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
16,538✔
4766
    mError("user:%s, failed to create totp secret at line %d since %s", req.user, lino, tstrerror(code));
150✔
4767
  }
4768
  mndReleaseUser(pMnode, pUser);
16,538✔
4769
  mndUserFreeObj(&newUser);
16,538✔
4770
  tFreeSCreateTotpSecretReq(&req);
16,538✔
4771
  TAOS_RETURN(code);
16,538✔
4772
}
4773

4774
int32_t mndBuildSMCreateTotpSecretResp(STrans *pTrans, void **ppResp, int32_t *pRespLen) {
16,388✔
4775
  // user data is the response
4776
  *ppResp = pTrans->userData;
16,388✔
4777
  *pRespLen = pTrans->userDataLen;
16,388✔
4778
  pTrans->userData = NULL;
16,388✔
4779
  pTrans->userDataLen = 0;
16,388✔
4780
  return 0;
16,388✔
4781
}
4782

4783
static int32_t mndProcessDropTotpSecretReq(SRpcMsg *pReq) {
6,300✔
4784
  SMnode            *pMnode = pReq->info.node;
6,300✔
4785
  int32_t            code = 0;
6,300✔
4786
  int32_t            lino = 0;
6,300✔
4787
  SUserObj          *pUser = NULL;
6,300✔
4788
  SUserObj           newUser = {0};
6,300✔
4789
  SDropTotpSecretReq req = {0};
6,300✔
4790
  int64_t            tss = taosGetTimestampMs();
6,300✔
4791

4792
  TAOS_CHECK_GOTO(tDeserializeSDropTotpSecretReq(pReq->pCont, pReq->contLen, &req), &lino, _OVER);
6,300✔
4793
  mTrace("user:%s, start to drop totp secret", req.user);
6,300✔
4794

4795
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, req.user, &pUser), &lino, _OVER);
6,300✔
4796
  TAOS_CHECK_GOTO(mndCheckTotpSecretPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser, PRIV_TOTP_DROP),
4,800✔
4797
                  &lino, _OVER);
4798

4799
  if (!mndIsTotpEnabledUser(pUser)) {
4,800✔
4800
    TAOS_CHECK_GOTO(TSDB_CODE_MND_TOTP_SECRET_NOT_EXIST, &lino, _OVER);
4,500✔
4801
  }
4802

4803
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
300✔
4804
  (void)memset(newUser.totpsecret, 0, sizeof(newUser.totpsecret));
300✔
4805
  TAOS_CHECK_GOTO(mndAlterUser(pMnode, &newUser, pReq), &lino, _OVER);
300✔
4806

4807
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
300✔
4808
    double duration = (double)(taosGetTimestampMs() - tss) / 1000.0;
300✔
4809
    auditRecord(pReq, pMnode->clusterId, "dropTotpSecret", "", req.user, req.sql, req.sqlLen, duration, 0);
300✔
4810
  }
4811

4812
_OVER:
6,300✔
4813
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
6,300✔
4814
    mError("user:%s, failed to drop totp secret at line %d since %s", req.user, lino, tstrerror(code));
6,000✔
4815
  }
4816
  mndReleaseUser(pMnode, pUser);
6,300✔
4817
  mndUserFreeObj(&newUser);
6,300✔
4818
  tFreeSDropTotpSecretReq(&req);
6,300✔
4819
  TAOS_RETURN(code);
6,300✔
4820
}
4821

4822
bool mndIsTotpEnabledUser(SUserObj *pUser) {
4,308,517✔
4823
  for (int32_t i = 0; i < sizeof(pUser->totpsecret); i++) {
140,493,992✔
4824
    if (pUser->totpsecret[i] != 0) {
136,239,126✔
4825
      return true;
52,576✔
4826
    }
4827
  }
4828
  return false;
4,254,866✔
4829
}
4830

4831
static int32_t mndRetrieveUsers(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
113,476✔
4832
  SMnode   *pMnode = pReq->info.node;
113,476✔
4833
  SSdb     *pSdb = pMnode->pSdb;
113,476✔
4834
  int32_t   code = 0;
113,476✔
4835
  int32_t   lino = 0;
113,476✔
4836
  int32_t   numOfRows = 0;
113,476✔
4837
  SUserObj *pUser = NULL;
113,476✔
4838
  int32_t   cols = 0;
113,476✔
4839
  int8_t    flag = 0;
113,476✔
4840
  char     *pWrite = NULL;
113,476✔
4841
  char     *buf = NULL;
113,476✔
4842
  char     *varstr = NULL;
113,476✔
4843
  char      tBuf[TSDB_MAX_SUBROLE * TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
113,476✔
4844
  int32_t   bufSize = sizeof(tBuf) - VARSTR_HEADER_SIZE;
113,476✔
4845

4846
  while (numOfRows < rows) {
991,161✔
4847
    pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
991,161✔
4848
    if (pShow->pIter == NULL) break;
991,161✔
4849

4850
    cols = 0;
877,685✔
4851
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
877,685✔
4852
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
877,685✔
4853
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
877,685✔
4854
    COL_DATA_SET_VAL_GOTO((const char *)name, false, pUser, pShow->pIter, _exit);
877,685✔
4855

4856
    cols++;
877,685✔
4857
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
877,685✔
4858
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->superUser, false, pUser, pShow->pIter, _exit);
877,685✔
4859

4860
    cols++;
877,685✔
4861
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
877,685✔
4862
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->enable, false, pUser, pShow->pIter, _exit);
877,685✔
4863

4864
    cols++;
877,685✔
4865
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
877,685✔
4866
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sysInfo, false, pUser, pShow->pIter, _exit);
877,685✔
4867

4868
    cols++;
877,685✔
4869
    flag = pUser->createdb ? 1 : 0;
877,685✔
4870
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
877,685✔
4871
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
877,685✔
4872

4873
    cols++;
877,685✔
4874
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
877,685✔
4875
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->createdTime, false, pUser, pShow->pIter, _exit);
877,685✔
4876

4877
    cols++;
877,685✔
4878
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
877,685✔
4879
    flag = mndIsTotpEnabledUser(pUser) ? 1 : 0;
877,685✔
4880
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
877,685✔
4881

4882
    cols++;
877,685✔
4883

4884
    int32_t tlen = convertIpWhiteListToStr(pUser, &buf);
877,685✔
4885
    if (tlen != 0) {
877,685✔
4886
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
877,685✔
4887
      if (varstr == NULL) {
877,685✔
UNCOV
4888
        sdbRelease(pSdb, pUser);
×
UNCOV
4889
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
4890
      }
4891
      varDataSetLen(varstr, tlen);
877,685✔
4892
      (void)memcpy(varDataVal(varstr), buf, tlen);
877,685✔
4893

4894
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
877,685✔
4895
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
877,685✔
4896

4897
      taosMemoryFreeClear(buf);
877,685✔
4898
    } else {
UNCOV
4899
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4900
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
4901
    }
4902

4903
    cols++;
877,685✔
4904
    tlen = convertTimeRangesToStr(pUser, &buf);
877,685✔
4905
    if (tlen != 0) {
877,685✔
4906
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
877,685✔
4907
      if (varstr == NULL) {
877,685✔
UNCOV
4908
        sdbRelease(pSdb, pUser);
×
UNCOV
4909
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
4910
      }
4911
      varDataSetLen(varstr, tlen);
877,685✔
4912
      (void)memcpy(varDataVal(varstr), buf, tlen);
877,685✔
4913

4914
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
877,685✔
4915
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
877,685✔
4916

4917
      taosMemoryFreeClear(buf);
877,685✔
4918
    } else {
UNCOV
4919
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4920
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
4921
    }
4922

4923
    if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
877,685✔
4924
      void  *pIter = NULL;
877,685✔
4925
      size_t klen = 0, tlen = 0;
877,685✔
4926
      char  *pBuf = POINTER_SHIFT(tBuf, VARSTR_HEADER_SIZE);
877,685✔
4927
      while ((pIter = taosHashIterate(pUser->roles, pIter))) {
1,982,490✔
4928
        char *roleName = taosHashGetKey(pIter, &klen);
1,104,805✔
4929
        tlen += snprintf(pBuf + tlen, bufSize - tlen, "%s,", roleName);
1,104,805✔
4930
      }
4931
      if (tlen > 0) {
877,685✔
4932
        pBuf[--tlen] = 0;  // remove last ','
877,553✔
4933
      } else {
4934
        pBuf[0] = 0;
132✔
4935
      }
4936
      varDataSetLen(tBuf, tlen);
877,685✔
4937
      COL_DATA_SET_VAL_GOTO((const char *)tBuf, false, pUser, pShow->pIter, _exit);
877,685✔
4938
    }
4939

4940
    numOfRows++;
877,685✔
4941
    sdbRelease(pSdb, pUser);
877,685✔
4942
  }
4943

4944
  pShow->numOfRows += numOfRows;
113,476✔
4945
_exit:
113,476✔
4946
  taosMemoryFreeClear(buf);
113,476✔
4947
  taosMemoryFreeClear(varstr);
113,476✔
4948
  if (code < 0) {
113,476✔
UNCOV
4949
    mError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
UNCOV
4950
    TAOS_RETURN(code);
×
4951
  }
4952
  return numOfRows;
113,476✔
4953
}
4954

4955
static int32_t mndRetrieveUsersFull(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
12,636✔
4956
  int32_t numOfRows = 0;
12,636✔
4957
#ifdef TD_ENTERPRISE
4958
  SMnode   *pMnode = pReq->info.node;
12,636✔
4959
  SSdb     *pSdb = pMnode->pSdb;
12,636✔
4960
  SUserObj *pOperUser = NULL;
12,636✔
4961
  SUserObj *pUser = NULL;
12,636✔
4962
  int32_t   code = 0;
12,636✔
4963
  int32_t   lino = 0;
12,636✔
4964
  int32_t   cols = 0;
12,636✔
4965
  int8_t    flag = 0;
12,636✔
4966
  char     *pWrite = NULL;
12,636✔
4967
  char     *buf = NULL;
12,636✔
4968
  char     *varstr = NULL;
12,636✔
4969
  char     *pBuf = NULL;
12,636✔
4970
  char      tBuf[TSDB_MAX_SUBROLE * TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
12,636✔
4971
  int32_t   bufSize = sizeof(tBuf) - VARSTR_HEADER_SIZE;
12,636✔
4972
  bool      showSecurityInfo = false;
12,636✔
4973

4974
  code = mndAcquireUser(pMnode, RPC_MSG_USER(pReq), &pOperUser);
12,636✔
4975
  if (pOperUser == NULL) {
12,636✔
UNCOV
4976
    TAOS_CHECK_EXIT(TSDB_CODE_MND_NO_USER_FROM_CONN);
×
4977
  }
4978
  if (0 == mndCheckSysObjPrivilege(pMnode, pOperUser, RPC_MSG_TOKEN(pReq), PRIV_USER_SHOW_SECURITY, 0, 0, NULL, NULL)) {
12,636✔
4979
    showSecurityInfo = true;
12,636✔
4980
  }
4981

4982
  while (numOfRows < rows) {
551,722✔
4983
    pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
551,722✔
4984
    if (pShow->pIter == NULL) break;
551,722✔
4985

4986
    cols = 0;
539,086✔
4987
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
539,086✔
4988
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
539,086✔
4989
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
539,086✔
4990
    COL_DATA_SET_VAL_GOTO((const char *)name, false, pUser, pShow->pIter, _exit);
539,086✔
4991

4992
    cols++;
539,086✔
4993
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
539,086✔
4994
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->superUser, false, pUser, pShow->pIter, _exit);
539,086✔
4995

4996
    cols++;
539,086✔
4997
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
539,086✔
4998
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->enable, false, pUser, pShow->pIter, _exit);
539,086✔
4999

5000
    cols++;
539,086✔
5001
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
539,086✔
5002
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sysInfo, false, pUser, pShow->pIter, _exit);
539,086✔
5003

5004
    cols++;
539,086✔
5005
    flag = pUser->createdb ? 1 : 0;
539,086✔
5006
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
539,086✔
5007
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
539,086✔
5008

5009
    cols++;
539,086✔
5010
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
539,086✔
5011
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->createdTime, false, pUser, pShow->pIter, _exit);
539,086✔
5012

5013
    cols++;
539,086✔
5014
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
539,086✔
5015
    flag = mndIsTotpEnabledUser(pUser) ? 1 : 0;
539,086✔
5016
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
539,086✔
5017

5018
    cols++;
539,086✔
5019
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
539,086✔
5020
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->changePass, false, pUser, pShow->pIter, _exit);
539,086✔
5021

5022
    cols++;
539,086✔
5023
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
539,086✔
5024
    char pass[TSDB_PASSWORD_LEN + VARSTR_HEADER_SIZE] = {0};
539,086✔
5025
    STR_WITH_MAXSIZE_TO_VARSTR(pass, showSecurityInfo ? pUser->passwords[0].pass : "*",
539,086✔
5026
                               pShow->pMeta->pSchemas[cols].bytes);
5027
    COL_DATA_SET_VAL_GOTO((const char *)pass, false, pUser, pShow->pIter, _exit);
539,086✔
5028

5029
    cols++;
539,086✔
5030
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
539,086✔
5031
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sessionPerUser, false, pUser, pShow->pIter, _exit);
539,086✔
5032

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

5037
    cols++;
539,086✔
5038
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
539,086✔
5039
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->connectIdleTime, false, pUser, pShow->pIter, _exit);
539,086✔
5040

5041
    cols++;
539,086✔
5042
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
539,086✔
5043
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->callPerSession, false, pUser, pShow->pIter, _exit);
539,086✔
5044

5045
    cols++;
539,086✔
5046
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
539,086✔
5047
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->vnodePerCall, false, pUser, pShow->pIter, _exit);
539,086✔
5048

5049
    cols++;
539,086✔
5050
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
539,086✔
5051
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->failedLoginAttempts, false, pUser, pShow->pIter, _exit);
539,086✔
5052

5053
    cols++;
539,086✔
5054
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
539,086✔
5055
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordLifeTime, false, pUser, pShow->pIter, _exit);
539,086✔
5056

5057
    cols++;
539,086✔
5058
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
539,086✔
5059
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordReuseTime, false, pUser, pShow->pIter, _exit);
539,086✔
5060

5061
    cols++;
539,086✔
5062
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
539,086✔
5063
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordReuseMax, false, pUser, pShow->pIter, _exit);
539,086✔
5064

5065
    cols++;
539,086✔
5066
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
539,086✔
5067
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordLockTime, false, pUser, pShow->pIter, _exit);
539,086✔
5068

5069
    cols++;
539,086✔
5070
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
539,086✔
5071
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordGraceTime, false, pUser, pShow->pIter, _exit);
539,086✔
5072

5073
    cols++;
539,086✔
5074
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
539,086✔
5075
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->inactiveAccountTime, false, pUser, pShow->pIter, _exit);
539,086✔
5076

5077
    cols++;
539,086✔
5078
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
539,086✔
5079
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->allowTokenNum, false, pUser, pShow->pIter, _exit);
539,086✔
5080

5081
    cols++;
539,086✔
5082
    int32_t tlen = convertIpWhiteListToStr(pUser, &buf);
539,086✔
5083
    if (tlen != 0) {
539,086✔
5084
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
539,086✔
5085
      if (varstr == NULL) {
539,086✔
UNCOV
5086
        sdbRelease(pSdb, pUser);
×
UNCOV
5087
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
5088
      }
5089
      varDataSetLen(varstr, tlen);
539,086✔
5090
      (void)memcpy(varDataVal(varstr), buf, tlen);
539,086✔
5091

5092
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
539,086✔
5093
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
539,086✔
5094

5095
      taosMemoryFreeClear(buf);
539,086✔
5096
    } else {
UNCOV
5097
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
5098
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
5099
    }
5100

5101
    cols++;
539,086✔
5102
    tlen = convertTimeRangesToStr(pUser, &buf);
539,086✔
5103
    if (tlen != 0) {
539,086✔
5104
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
539,086✔
5105
      if (varstr == NULL) {
539,086✔
UNCOV
5106
        sdbRelease(pSdb, pUser);
×
UNCOV
5107
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
5108
      }
5109
      varDataSetLen(varstr, tlen);
539,086✔
5110
      (void)memcpy(varDataVal(varstr), buf, tlen);
539,086✔
5111

5112
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
539,086✔
5113
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
539,086✔
5114

5115
      taosMemoryFreeClear(buf);
539,086✔
5116
    } else {
UNCOV
5117
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
5118
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
5119
    }
5120

5121
    if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
539,086✔
5122
      void  *pIter = NULL;
539,086✔
5123
      size_t klen = 0, tlen = 0;
539,086✔
5124
      char  *pBuf = POINTER_SHIFT(tBuf, VARSTR_HEADER_SIZE);
539,086✔
5125
      while ((pIter = taosHashIterate(pUser->roles, pIter))) {
1,103,444✔
5126
        char *roleName = taosHashGetKey(pIter, &klen);
564,358✔
5127
        tlen += snprintf(pBuf + tlen, bufSize - tlen, "%s,", roleName);
564,358✔
5128
      }
5129
      if (tlen > 0) {
539,086✔
5130
        pBuf[--tlen] = 0;  // remove last ','
539,086✔
5131
      } else {
UNCOV
5132
        pBuf[0] = 0;
×
5133
      }
5134
      varDataSetLen(tBuf, tlen);
539,086✔
5135
      COL_DATA_SET_VAL_GOTO((const char *)tBuf, false, pUser, pShow->pIter, _exit);
539,086✔
5136
    }
5137

5138
    numOfRows++;
539,086✔
5139
    sdbRelease(pSdb, pUser);
539,086✔
5140
  }
5141

5142
  pShow->numOfRows += numOfRows;
12,636✔
5143
_exit:
12,636✔
5144
  taosMemoryFreeClear(buf);
12,636✔
5145
  taosMemoryFreeClear(varstr);
12,636✔
5146
  mndReleaseUser(pMnode, pOperUser);
12,636✔
5147
  if (code < 0) {
12,636✔
UNCOV
5148
    mError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
UNCOV
5149
    TAOS_RETURN(code);
×
5150
  }
5151
#endif
5152
  return numOfRows;
12,636✔
5153
}
5154

UNCOV
5155
static void mndCancelGetNextUser(SMnode *pMnode, void *pIter) {
×
UNCOV
5156
  SSdb *pSdb = pMnode->pSdb;
×
UNCOV
5157
  sdbCancelFetchByType(pSdb, pIter, SDB_USER);
×
5158
}
×
5159

5160
static int32_t mndLoopHash(SHashObj *hash, char *priType, SSDataBlock *pBlock, int32_t *pNumOfRows, SSdb *pSdb,
×
5161
                           SUserObj *pUser, SShowObj *pShow, char **condition, char **sql) {
UNCOV
5162
  char   *value = taosHashIterate(hash, NULL);
×
5163
  char   *user = pUser->user;
×
UNCOV
5164
  int32_t code = 0;
×
5165
  int32_t lino = 0;
×
5166
  int32_t cols = 0;
×
5167
  int32_t numOfRows = *pNumOfRows;
×
5168

5169
  while (value != NULL) {
×
5170
    cols = 0;
×
UNCOV
5171
    char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
×
5172
    STR_WITH_MAXSIZE_TO_VARSTR(userName, user, pShow->pMeta->pSchemas[cols].bytes);
×
5173
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
5174
    COL_DATA_SET_VAL_GOTO((const char *)userName, false, NULL, NULL, _exit);
×
5175

5176
    char privilege[20] = {0};
×
5177
    STR_WITH_MAXSIZE_TO_VARSTR(privilege, priType, pShow->pMeta->pSchemas[cols].bytes);
×
UNCOV
5178
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
5179
    COL_DATA_SET_VAL_GOTO((const char *)privilege, false, NULL, NULL, _exit);
×
5180

5181
    size_t keyLen = 0;
×
5182
    void  *key = taosHashGetKey(value, &keyLen);
×
5183

5184
    char dbName[TSDB_DB_NAME_LEN] = {0};
×
5185
    (void)mndExtractShortDbNameFromStbFullName(key, dbName);
×
UNCOV
5186
    char dbNameContent[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
×
5187
    STR_WITH_MAXSIZE_TO_VARSTR(dbNameContent, dbName, pShow->pMeta->pSchemas[cols].bytes);
×
5188
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
5189
    COL_DATA_SET_VAL_GOTO((const char *)dbNameContent, false, NULL, NULL, _exit);
×
5190

5191
    char tableName[TSDB_TABLE_NAME_LEN] = {0};
×
5192
    mndExtractTbNameFromStbFullName(key, tableName, TSDB_TABLE_NAME_LEN);
×
UNCOV
5193
    char tableNameContent[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
×
5194
    STR_WITH_MAXSIZE_TO_VARSTR(tableNameContent, tableName, pShow->pMeta->pSchemas[cols].bytes);
×
5195
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
5196
    COL_DATA_SET_VAL_GOTO((const char *)tableNameContent, false, NULL, NULL, _exit);
×
5197

5198
    if (strcmp("t", value) != 0 && strcmp("v", value) != 0) {
×
5199
      SNode  *pAst = NULL;
×
UNCOV
5200
      int32_t sqlLen = 0;
×
5201
      size_t  bufSz = strlen(value) + 1;
×
5202
      if (bufSz < 6) bufSz = 6;
×
5203
      TAOS_MEMORY_REALLOC(*sql, bufSz);
×
5204
      if (*sql == NULL) {
×
5205
        code = terrno;
×
5206
        goto _exit;
×
5207
      }
5208
      TAOS_MEMORY_REALLOC(*condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
×
5209
      if ((*condition) == NULL) {
×
UNCOV
5210
        code = terrno;
×
5211
        goto _exit;
×
5212
      }
5213

5214
      if (nodesStringToNode(value, &pAst) == 0) {
×
UNCOV
5215
        if (nodesNodeToSQLFormat(pAst, *sql, bufSz, &sqlLen, true) != 0) {
×
UNCOV
5216
          sqlLen = tsnprintf(*sql, bufSz, "error");
×
5217
        }
5218
        nodesDestroyNode(pAst);
×
5219
      }
5220

5221
      if (sqlLen == 0) {
×
UNCOV
5222
        sqlLen = tsnprintf(*sql, bufSz, "error");
×
5223
      }
5224

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

UNCOV
5227
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
5228
      COL_DATA_SET_VAL_GOTO((const char *)(*condition), false, NULL, NULL, _exit);
×
5229

5230
      char notes[2] = {0};
×
5231
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
×
UNCOV
5232
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
5233
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, NULL, NULL, _exit);
×
5234
    } else {
5235
      TAOS_MEMORY_REALLOC(*condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
×
5236
      if ((*condition) == NULL) {
×
UNCOV
5237
        code = terrno;
×
5238
        goto _exit;
×
5239
      }
5240
      STR_WITH_MAXSIZE_TO_VARSTR((*condition), "", pShow->pMeta->pSchemas[cols].bytes);
×
5241
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
UNCOV
5242
      COL_DATA_SET_VAL_GOTO((const char *)(*condition), false, NULL, NULL, _exit);
×
5243

5244
      char notes[64 + VARSTR_HEADER_SIZE] = {0};
×
5245
      STR_WITH_MAXSIZE_TO_VARSTR(notes, value[0] == 'v' ? "view" : "", sizeof(notes));
×
UNCOV
5246
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
5247
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, NULL, NULL, _exit);
×
5248
    }
5249

5250
    numOfRows++;
×
UNCOV
5251
    value = taosHashIterate(hash, value);
×
5252
  }
5253
  *pNumOfRows = numOfRows;
×
5254
_exit:
×
UNCOV
5255
  if (code < 0) {
×
5256
    mError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
5257
    sdbRelease(pSdb, pUser);
×
5258
    sdbCancelFetch(pSdb, pShow->pIter);
×
5259
  }
5260
  TAOS_RETURN(code);
×
5261
}
5262

5263
#if 0
5264
static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
5265
  int32_t   code = 0;
5266
  int32_t   lino = 0;
5267
  SMnode   *pMnode = pReq->info.node;
5268
  SSdb     *pSdb = pMnode->pSdb;
5269
  int32_t   numOfRows = 0;
5270
  SUserObj *pUser = NULL;
5271
  int32_t   cols = 0;
5272
  char     *pWrite = NULL;
5273
  char     *condition = NULL;
5274
  char     *sql = NULL;
5275

5276
  bool fetchNextUser = pShow->restore ? false : true;
5277
  pShow->restore = false;
5278

5279
  while (numOfRows < rows) {
5280
    if (fetchNextUser) {
5281
      pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
5282
      if (pShow->pIter == NULL) break;
5283
    } else {
5284
      fetchNextUser = true;
5285
      void *pKey = taosHashGetKey(pShow->pIter, NULL);
5286
      pUser = sdbAcquire(pSdb, SDB_USER, pKey);
5287
      if (!pUser) {
5288
        continue;
5289
      }
5290
    }
5291

5292
    int32_t numOfReadDbs = 0; //taosHashGetSize(pUser->readDbs);
5293
    int32_t numOfWriteDbs = 0; //taosHashGetSize(pUser->writeDbs);
5294
    int32_t numOfTopics = taosHashGetSize(pUser->topics);
5295
    int32_t numOfReadTbs = taosHashGetSize(pUser->selectTbs);
5296
    int32_t numOfWriteTbs = taosHashGetSize(pUser->insertTbs);
5297
    int32_t numOfAlterTbs = taosHashGetSize(pUser->alterTbs);
5298
    int32_t numOfReadViews = taosHashGetSize(pUser->readViews);
5299
    int32_t numOfWriteViews = taosHashGetSize(pUser->writeViews);
5300
    int32_t numOfAlterViews = taosHashGetSize(pUser->alterViews);
5301
    if (numOfRows + numOfReadDbs + numOfWriteDbs + numOfTopics + numOfReadTbs + numOfWriteTbs + numOfAlterTbs +
5302
            numOfReadViews + numOfWriteViews + numOfAlterViews >=
5303
        rows) {
5304
      mInfo(
5305
          "will restore. current num of rows: %d, read dbs %d, write dbs %d, topics %d, read tables %d, write tables "
5306
          "%d, alter tables %d, select views %d, write views %d, alter views %d",
5307
          numOfRows, numOfReadDbs, numOfWriteDbs, numOfTopics, numOfReadTbs, numOfWriteTbs, numOfAlterTbs,
5308
          numOfReadViews, numOfWriteViews, numOfAlterViews);
5309
      pShow->restore = true;
5310
      sdbRelease(pSdb, pUser);
5311
      break;
5312
    }
5313

5314
    if (pUser->superUser) {
5315
      cols = 0;
5316
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
5317
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
5318
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5319
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
5320

5321
      char privilege[20] = {0};
5322
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "all", pShow->pMeta->pSchemas[cols].bytes);
5323
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5324
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
5325

5326
      char objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
5327
      STR_WITH_MAXSIZE_TO_VARSTR(objName, "all", pShow->pMeta->pSchemas[cols].bytes);
5328
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5329
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
5330

5331
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
5332
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
5333
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5334
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
5335

5336
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
5337
      if (condition == NULL) {
5338
        sdbRelease(pSdb, pUser);
5339
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
5340
      }
5341
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
5342
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5343
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
5344

5345
      char notes[2] = {0};
5346
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
5347
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5348
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
5349

5350
      numOfRows++;
5351
    }
5352
#if 0
5353
    char *db = taosHashIterate(pUser->readDbs, NULL);
5354
    while (db != NULL) {
5355
      cols = 0;
5356
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
5357
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
5358
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5359
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
5360

5361
      char privilege[20] = {0};
5362
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "read", pShow->pMeta->pSchemas[cols].bytes);
5363
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5364
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
5365

5366
      SName name = {0};
5367
      char  objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
5368
      code = tNameFromString(&name, db, T_NAME_ACCT | T_NAME_DB);
5369
      if (code < 0) {
5370
        sdbRelease(pSdb, pUser);
5371
        sdbCancelFetch(pSdb, pShow->pIter);
5372
        TAOS_CHECK_GOTO(code, &lino, _exit);
5373
      }
5374
      (void)tNameGetDbName(&name, varDataVal(objName));
5375
      varDataSetLen(objName, strlen(varDataVal(objName)));
5376
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5377
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
5378

5379
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
5380
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
5381
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5382
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
5383

5384
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
5385
      if (condition == NULL) {
5386
        sdbRelease(pSdb, pUser);
5387
        sdbCancelFetch(pSdb, pShow->pIter);
5388
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
5389
      }
5390
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
5391
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5392
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
5393

5394
      char notes[2] = {0};
5395
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
5396
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5397
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
5398

5399
      numOfRows++;
5400
      db = taosHashIterate(pUser->readDbs, db);
5401
    }
5402

5403
    db = taosHashIterate(pUser->writeDbs, NULL);
5404
    while (db != NULL) {
5405
      cols = 0;
5406
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
5407
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
5408
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5409
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
5410

5411
      char privilege[20] = {0};
5412
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "write", pShow->pMeta->pSchemas[cols].bytes);
5413
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5414
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
5415

5416
      SName name = {0};
5417
      char  objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
5418
      code = tNameFromString(&name, db, T_NAME_ACCT | T_NAME_DB);
5419
      if (code < 0) {
5420
        sdbRelease(pSdb, pUser);
5421
        sdbCancelFetch(pSdb, pShow->pIter);
5422
        TAOS_CHECK_GOTO(code, &lino, _exit);
5423
      }
5424
      (void)tNameGetDbName(&name, varDataVal(objName));
5425
      varDataSetLen(objName, strlen(varDataVal(objName)));
5426
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5427
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
5428

5429
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
5430
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
5431
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5432
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
5433

5434
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
5435
      if (condition == NULL) {
5436
        sdbRelease(pSdb, pUser);
5437
        sdbCancelFetch(pSdb, pShow->pIter);
5438
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
5439
      }
5440
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
5441
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5442
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
5443

5444
      char notes[2] = {0};
5445
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
5446
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5447
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
5448

5449
      numOfRows++;
5450
      db = taosHashIterate(pUser->writeDbs, db);
5451
    }
5452
#endif
5453
    TAOS_CHECK_EXIT(mndLoopHash(pUser->selectTbs, "select", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
5454

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

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

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

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

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

5465
    char *topic = taosHashIterate(pUser->topics, NULL);
5466
    while (topic != NULL) {
5467
      cols = 0;
5468
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
5469
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
5470
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5471
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
5472

5473
      char privilege[20] = {0};
5474
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "subscribe", pShow->pMeta->pSchemas[cols].bytes);
5475
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5476
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
5477

5478
      char topicName[TSDB_TOPIC_NAME_LEN + VARSTR_HEADER_SIZE + 5] = {0};
5479
      tstrncpy(varDataVal(topicName), mndGetDbStr(topic), TSDB_TOPIC_NAME_LEN - 2);
5480
      varDataSetLen(topicName, strlen(varDataVal(topicName)));
5481
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5482
      COL_DATA_SET_VAL_GOTO((const char *)topicName, false, pUser, pShow->pIter, _exit);
5483

5484
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
5485
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
5486
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5487
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
5488

5489
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
5490
      if (condition == NULL) {
5491
        sdbRelease(pSdb, pUser);
5492
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
5493
      }
5494
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
5495
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5496
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
5497

5498
      char notes[2] = {0};
5499
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
5500
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5501
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
5502

5503
      numOfRows++;
5504
      topic = taosHashIterate(pUser->topics, topic);
5505
    }
5506

5507
    sdbRelease(pSdb, pUser);
5508
  }
5509

5510
  pShow->numOfRows += numOfRows;
5511
_exit:
5512
  taosMemoryFreeClear(condition);
5513
  taosMemoryFreeClear(sql);
5514
  if (code < 0) {
5515
    mError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
5516
    TAOS_RETURN(code);
5517
  }
5518
  return numOfRows;
5519
}
5520
#endif
5521

5522
int32_t mndShowTablePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows, void *pObj,
377,036✔
5523
                               const char *principalName, SHashObj *privTbs, EPrivType privType, char *pBuf,
5524
                               int32_t bufSize, int32_t *pNumOfRows) {
5525
  int32_t     code = 0, lino = 0;
377,036✔
5526
  SMnode     *pMnode = pReq->info.node;
377,036✔
5527
  SSdb       *pSdb = pMnode->pSdb;
377,036✔
5528
  int32_t     cols = 0, qBufSize = bufSize - VARSTR_HEADER_SIZE;
377,036✔
5529
  int32_t     numOfRows = *pNumOfRows;
377,036✔
5530
  char       *qBuf = NULL;
377,036✔
5531
  char       *sql = NULL;
377,036✔
5532
  char        roleName[TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
377,036✔
5533
  const char *privName = privInfoGetName(privType);
377,036✔
5534

5535
  STR_WITH_MAXSIZE_TO_VARSTR(roleName, principalName, pShow->pMeta->pSchemas[cols].bytes);
377,036✔
5536

5537
  void *pIter = NULL;
377,036✔
5538
  while ((pIter = taosHashIterate(privTbs, pIter))) {
435,967✔
5539
    SPrivTblPolicies *pPolices = (SPrivTblPolicies *)pIter;
58,931✔
5540
    SArray           *tblPolicies = pPolices->policy;
58,931✔
5541

5542
    char   *key = taosHashGetKey(pPolices, NULL);
58,931✔
5543
    int32_t objType = PRIV_OBJ_UNKNOWN;
58,931✔
5544
    char    dbName[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
58,931✔
5545
    char    tblName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
58,931✔
5546
    if ((code = privObjKeyParse(key, &objType, dbName, sizeof(dbName), tblName, sizeof(tblName), false))) {
58,931✔
UNCOV
5547
      sdbRelease(pSdb, pObj);
×
UNCOV
5548
      sdbCancelFetch(pSdb, pShow->pIter);
×
UNCOV
5549
      TAOS_CHECK_EXIT(code);
×
5550
    }
5551

5552
    int32_t nTbPolicies = taosArrayGetSize(tblPolicies);
58,931✔
5553
    for (int32_t i = 0; i < nTbPolicies; ++i) {
117,862✔
5554
      SPrivTblPolicy *tbPolicy = (SPrivTblPolicy *)TARRAY_GET_ELEM(tblPolicies, i);
58,931✔
5555
      cols = 0;
58,931✔
5556
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
58,931✔
5557
      COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
58,931✔
5558

5559
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
58,931✔
5560
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privName, pShow->pMeta->pSchemas[cols].bytes);
58,931✔
5561
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
58,931✔
5562
      }
5563

5564
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
58,931✔
5565
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privObjGetName(objType), pShow->pMeta->pSchemas[cols].bytes);
58,931✔
5566
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
58,931✔
5567
      }
5568

5569
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
58,931✔
5570
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, dbName, pShow->pMeta->pSchemas[cols].bytes);
58,931✔
5571
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
58,931✔
5572
      }
5573

5574
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
58,931✔
5575
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, tblName, pShow->pMeta->pSchemas[cols].bytes);
58,931✔
5576
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
58,931✔
5577
      }
5578
      // condition
5579
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
58,931✔
5580
        SNode  *pAst = NULL;
58,931✔
5581
        int32_t sqlLen = 0;
58,931✔
5582
        qBuf = POINTER_SHIFT(pBuf, VARSTR_HEADER_SIZE);
58,931✔
5583
        if (tbPolicy->condLen > 0) {
58,931✔
5584
          if (nodesStringToNode(tbPolicy->cond, &pAst) == 0) {
58,931✔
5585
            if (nodesNodeToSQLFormat(pAst, qBuf, qBufSize, &sqlLen, true) != 0) {
58,931✔
UNCOV
5586
              sqlLen = tsnprintf(qBuf, qBufSize, "error");
×
5587
            }
5588
            nodesDestroyNode(pAst);
58,931✔
5589
          }
5590
          if (sqlLen == 0) {
58,931✔
UNCOV
5591
            sqlLen = tsnprintf(qBuf, qBufSize, "error");
×
5592
          }
5593
        } else {
5594
          sqlLen = tsnprintf(qBuf, qBufSize, "");
×
5595
        }
5596
        varDataSetLen(pBuf, sqlLen);
58,931✔
5597
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
58,931✔
5598
      }
5599
      // notes
5600
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
58,931✔
5601
        STR_WITH_MAXSIZE_TO_VARSTR((pBuf), "", 2);
58,931✔
5602
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
58,931✔
5603
      }
5604
      // columns
5605
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
58,931✔
5606
        SArray *pCols = tbPolicy->cols;
58,931✔
5607
        int32_t nCols = taosArrayGetSize(pCols);
58,931✔
5608
        int32_t totalLen = 0;
58,931✔
5609
        qBuf = POINTER_SHIFT(pBuf, VARSTR_HEADER_SIZE);
58,931✔
5610
        for (int32_t j = 0; j < nCols; ++j) {
85,181✔
5611
          SColNameFlag *pCol = (SColNameFlag *)TARRAY_GET_ELEM(pCols, j);
26,250✔
5612
          char          tmpBuf[TSDB_COL_NAME_LEN + 16] = {0};
26,250✔
5613
          int32_t       tmpLen = 0;
26,250✔
5614
          if (IS_MASK_ON(pCol)) {
26,250✔
UNCOV
5615
            tmpLen = snprintf(tmpBuf, sizeof(tmpBuf), "mask(%s)%s", pCol->colName, j == nCols - 1 ? "" : ",");
×
5616
          } else {
5617
            tmpLen = snprintf(tmpBuf, sizeof(tmpBuf), "%s%s", pCol->colName, j == nCols - 1 ? "" : ",");
26,250✔
5618
          }
5619
          if (totalLen + tmpLen > qBufSize) {
26,250✔
UNCOV
5620
            break;
×
5621
          }
5622
          (void)memcpy(POINTER_SHIFT(qBuf, totalLen), tmpBuf, tmpLen);
26,250✔
5623
          totalLen += tmpLen;
26,250✔
5624
        }
5625
        varDataSetLen(pBuf, totalLen);
58,931✔
5626
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
58,931✔
5627
      }
5628
      // update_time
5629
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
58,931✔
5630
        char updateTime[40] = {0};
58,931✔
5631
        (void)formatTimestampLocal(updateTime, tbPolicy->updateUs, TSDB_TIME_PRECISION_MICRO);
58,931✔
5632
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, updateTime, pShow->pMeta->pSchemas[cols].bytes);
58,931✔
5633
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
58,931✔
5634
      }
5635
      ++numOfRows;
58,931✔
5636
    }
5637
  }
5638
  *pNumOfRows = numOfRows;
377,036✔
5639
_exit:
377,036✔
5640
  TAOS_RETURN(code);
377,036✔
5641
}
5642

5643
static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
15,371✔
5644
  int32_t   code = 0, lino = 0;
15,371✔
5645
  SMnode   *pMnode = pReq->info.node;
15,371✔
5646
  SSdb     *pSdb = pMnode->pSdb;
15,371✔
5647
  int32_t   numOfRows = 0;
15,371✔
5648
  int32_t   cols = 0;
15,371✔
5649
  SUserObj *pObj = NULL;
15,371✔
5650
  char     *pBuf = NULL, *qBuf = NULL;
15,371✔
5651
  char     *sql = NULL;
15,371✔
5652
  char      roleName[TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
15,371✔
5653
  int32_t   bufSize = TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE;
15,371✔
5654

5655
  bool fetchNextInstance = pShow->restore ? false : true;
15,371✔
5656
  pShow->restore = false;
15,371✔
5657

5658
  while (numOfRows < rows) {
103,456✔
5659
    if (fetchNextInstance) {
103,456✔
5660
      pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pObj);
103,456✔
5661
      if (pShow->pIter == NULL) break;
103,456✔
5662
    } else {
UNCOV
5663
      fetchNextInstance = true;
×
UNCOV
5664
      void *pKey = taosHashGetKey(pShow->pIter, NULL);
×
UNCOV
5665
      if (!(pObj = sdbAcquire(pSdb, SDB_USER, pKey))) {
×
5666
        continue;
×
5667
      }
5668
    }
5669

5670
    // count total privileges for current user
5671
    int32_t nSysPrivileges = privPopCnt(&pObj->sysPrivs);
88,085✔
5672
    int32_t nObjPrivileges = 0;
88,085✔
5673
    void   *pIter = NULL;
88,085✔
5674
    while ((pIter = taosHashIterate(pObj->objPrivs, pIter))) {
1,108,659✔
5675
      SPrivObjPolicies *pPolices = (SPrivObjPolicies *)pIter;
1,020,574✔
5676
      nObjPrivileges += privPopCnt(&pPolices->policy);
2,041,148✔
5677
    }
5678
    int32_t nTblPrivileges = privTblPrivCnt(pObj->selectTbs);
88,085✔
5679
    nTblPrivileges += privTblPrivCnt(pObj->insertTbs);
88,085✔
5680
    nTblPrivileges += privTblPrivCnt(pObj->updateTbs);
88,085✔
5681
    nTblPrivileges += privTblPrivCnt(pObj->deleteTbs);
88,085✔
5682

5683
    int32_t totalPrivileges = nSysPrivileges + nObjPrivileges + nTblPrivileges;
88,085✔
5684

5685
    if (numOfRows + totalPrivileges >= rows) {
88,085✔
UNCOV
5686
      if (totalPrivileges >= SHOW_PRIVILEGES_STEP_SIZE) {
×
UNCOV
5687
        mError("user:%s, has too many privileges:%d to show", pObj->name, totalPrivileges);
×
UNCOV
5688
        sdbRelease(pSdb, pObj);
×
5689
        TAOS_CHECK_EXIT(TSDB_CODE_MND_TOO_MANY_PRIVS);
×
5690
      }
5691
      pShow->restore = true;
×
5692
      sdbRelease(pSdb, pObj);
×
UNCOV
5693
      break;
×
5694
    }
5695

5696
    if (!pBuf && !(pBuf = taosMemoryMalloc(bufSize))) {
88,085✔
UNCOV
5697
      sdbRelease(pSdb, pObj);
×
UNCOV
5698
      TAOS_CHECK_EXIT(terrno);
×
5699
    }
5700

5701
    cols = 0;
88,085✔
5702
    STR_WITH_MAXSIZE_TO_VARSTR(roleName, pObj->name, pShow->pMeta->pSchemas[cols].bytes);
88,085✔
5703

5704
    // system privileges
5705
    SPrivIter privIter = {0};
88,085✔
5706
    privIterInit(&privIter, &pObj->sysPrivs);
88,085✔
5707
    SPrivInfo *pPrivInfo = NULL;
88,085✔
5708
    while (privIterNext(&privIter, &pPrivInfo)) {
114,807✔
5709
      cols = 0;
26,722✔
5710
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
26,722✔
5711
      COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
26,722✔
5712

5713
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
26,722✔
5714
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, pPrivInfo->name, pShow->pMeta->pSchemas[cols].bytes);
26,722✔
5715
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
26,722✔
5716
      }
5717
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
26,722✔
5718
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privObjGetName(PRIV_OBJ_CLUSTER), pShow->pMeta->pSchemas[cols].bytes);
26,722✔
5719
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
26,722✔
5720
      }
5721
      // skip db, table, condition, notes, columns, update_time
5722
      COL_DATA_SET_EMPTY_VARCHAR(pBuf, 6);
187,054✔
5723
      numOfRows++;
26,722✔
5724
    }
5725

5726
    // object privileges
5727
    pIter = NULL;
88,085✔
5728
    while ((pIter = taosHashIterate(pObj->objPrivs, pIter))) {
1,108,659✔
5729
      SPrivObjPolicies *pPolices = (SPrivObjPolicies *)pIter;
1,020,574✔
5730

5731
      char   *key = taosHashGetKey(pPolices, NULL);
1,020,574✔
5732
      int32_t objType = PRIV_OBJ_UNKNOWN;
1,020,574✔
5733
      char    dbName[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
1,020,574✔
5734
      char    tblName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
1,020,574✔
5735
      if ((code = privObjKeyParse(key, &objType, dbName, sizeof(dbName), tblName, sizeof(tblName), false))) {
1,020,574✔
UNCOV
5736
        sdbRelease(pSdb, pObj);
×
UNCOV
5737
        TAOS_CHECK_EXIT(code);
×
5738
      }
5739

5740
      SPrivIter privIter = {0};
1,020,574✔
5741
      privIterInit(&privIter, &pPolices->policy);
1,020,574✔
5742
      SPrivInfo *pPrivInfo = NULL;
1,020,574✔
5743
      while (privIterNext(&privIter, &pPrivInfo)) {
3,133,050✔
5744
        cols = 0;
2,112,476✔
5745
        SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
2,112,476✔
5746
        COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
2,112,476✔
5747

5748
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
2,112,476✔
5749
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, pPrivInfo->name, pShow->pMeta->pSchemas[cols].bytes);
2,112,476✔
5750
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
2,112,476✔
5751
        }
5752

5753
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
2,112,476✔
5754
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privObjGetName(objType), pShow->pMeta->pSchemas[cols].bytes);
2,112,476✔
5755
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
2,112,476✔
5756
        }
5757

5758
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
2,112,476✔
5759
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, dbName, pShow->pMeta->pSchemas[cols].bytes);
2,112,476✔
5760
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
2,112,476✔
5761
        }
5762

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

5768
        // skip condition, notes, columns, update_time
5769
        COL_DATA_SET_EMPTY_VARCHAR(pBuf, 4);
10,562,380✔
5770

5771
        numOfRows++;
2,112,476✔
5772
      }
5773
    }
5774

5775
    // table level privileges
5776
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->name, pObj->selectTbs,
88,085✔
5777
                                           PRIV_TBL_SELECT, pBuf, bufSize, &numOfRows));
5778
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->name, pObj->insertTbs,
88,085✔
5779
                                           PRIV_TBL_INSERT, pBuf, bufSize, &numOfRows));
5780
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->name, pObj->updateTbs,
88,085✔
5781
                                           PRIV_TBL_UPDATE, pBuf, bufSize, &numOfRows));
5782
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->name, pObj->deleteTbs,
88,085✔
5783
                                           PRIV_TBL_DELETE, pBuf, bufSize, &numOfRows));
5784
    sdbRelease(pSdb, pObj);
88,085✔
5785
  }
5786

5787
  pShow->numOfRows += numOfRows;
15,371✔
5788
_exit:
15,371✔
5789
  taosMemoryFreeClear(pBuf);
15,371✔
5790
  taosMemoryFreeClear(sql);
15,371✔
5791
  if (code < 0) {
15,371✔
UNCOV
5792
    mError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
UNCOV
5793
    TAOS_RETURN(code);
×
5794
  }
5795
  return numOfRows;
15,371✔
5796
}
5797

UNCOV
5798
static void mndCancelGetNextPrivileges(SMnode *pMnode, void *pIter) {
×
UNCOV
5799
  SSdb *pSdb = pMnode->pSdb;
×
UNCOV
5800
  sdbCancelFetchByType(pSdb, pIter, SDB_USER);
×
5801
}
×
5802

5803
int32_t mndValidateUserAuthInfo(SMnode *pMnode, SUserAuthVersion *pUsers, int32_t numOfUses, void **ppRsp,
23,672,543✔
5804
                                int32_t *pRspLen, int64_t ipWhiteListVer) {
5805
  int32_t           code = 0;
23,672,543✔
5806
  int32_t           lino = 0;
23,672,543✔
5807
  int32_t           rspLen = 0;
23,672,681✔
5808
  void             *pRsp = NULL;
23,672,681✔
5809
  SUserAuthBatchRsp batchRsp = {0};
23,672,681✔
5810

5811
  batchRsp.pArray = taosArrayInit(numOfUses, sizeof(SGetUserAuthRsp));
23,672,681✔
5812
  if (batchRsp.pArray == NULL) {
23,672,681✔
UNCOV
5813
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
5814
  }
5815
  int64_t now = taosGetTimestampMs();
23,672,681✔
5816
  for (int32_t i = 0; i < numOfUses; ++i) {
47,755,173✔
5817
    SUserObj *pUser = NULL;
24,082,492✔
5818
    code = mndAcquireUser(pMnode, pUsers[i].user, &pUser);
24,082,492✔
5819
    if (pUser == NULL) {
24,082,354✔
5820
      if (TSDB_CODE_MND_USER_NOT_EXIST == code) {
7,960✔
5821
        SGetUserAuthRsp rsp = {.dropped = 1};
7,960✔
5822
        (void)memcpy(rsp.user, pUsers[i].user, TSDB_USER_LEN);
7,960✔
5823
        TSDB_CHECK_NULL(taosArrayPush(batchRsp.pArray, &rsp), code, lino, _OVER, TSDB_CODE_OUT_OF_MEMORY);
15,920✔
5824
      }
5825
      mError("user:%s, failed to auth user since %s", pUsers[i].user, tstrerror(code));
7,960✔
5826
      code = 0;
7,960✔
5827
      continue;
7,960✔
5828
    }
5829

5830
    pUsers[i].version = ntohl(pUsers[i].version);
24,074,394✔
5831
    if ((pUser->authVersion <= pUsers[i].version) && (ipWhiteListVer == pMnode->ipWhiteVer) &&
24,074,054✔
UNCOV
5832
        !mndNeedRetrieveRole(pUser)) {
×
UNCOV
5833
      mndReleaseUser(pMnode, pUser);
×
UNCOV
5834
      continue;
×
5835
    }
5836

5837
    SGetUserAuthRsp rsp = {0};
24,074,532✔
5838
    code = mndSetUserAuthRsp(pMnode, pUser, &rsp);
24,074,532✔
5839
    if (code) {
24,074,292✔
UNCOV
5840
      mndReleaseUser(pMnode, pUser);
×
UNCOV
5841
      tFreeSGetUserAuthRsp(&rsp);
×
UNCOV
5842
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
5843
    }
5844

5845
    if (!(taosArrayPush(batchRsp.pArray, &rsp))) {
48,148,721✔
UNCOV
5846
      code = terrno;
×
UNCOV
5847
      mndReleaseUser(pMnode, pUser);
×
UNCOV
5848
      tFreeSGetUserAuthRsp(&rsp);
×
5849
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
5850
    }
5851
    pUser->lastRoleRetrieve = now;  // update user's last retrieve time
24,074,429✔
5852
    mndReleaseUser(pMnode, pUser);
24,074,532✔
5853
  }
5854

5855
  if (taosArrayGetSize(batchRsp.pArray) <= 0) {
23,672,681✔
UNCOV
5856
    *ppRsp = NULL;
×
UNCOV
5857
    *pRspLen = 0;
×
5858

5859
    tFreeSUserAuthBatchRsp(&batchRsp);
×
5860
    return 0;
×
5861
  }
5862

5863
  rspLen = tSerializeSUserAuthBatchRsp(NULL, 0, &batchRsp);
23,672,681✔
5864
  if (rspLen < 0) {
23,672,218✔
UNCOV
5865
    TAOS_CHECK_GOTO(rspLen, &lino, _OVER);
×
5866
  }
5867
  pRsp = taosMemoryMalloc(rspLen);
23,672,218✔
5868
  if (pRsp == NULL) {
23,671,493✔
UNCOV
5869
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
5870
  }
5871
  rspLen = tSerializeSUserAuthBatchRsp(pRsp, rspLen, &batchRsp);
23,671,493✔
5872
  if (rspLen < 0) {
23,672,237✔
UNCOV
5873
    TAOS_CHECK_GOTO(rspLen, &lino, _OVER);
×
5874
  }
5875
_OVER:
23,672,237✔
5876
  tFreeSUserAuthBatchRsp(&batchRsp);
23,672,578✔
5877
  if (code < 0) {
23,672,099✔
UNCOV
5878
    for (int32_t i = 0; i < numOfUses; ++i) {
×
UNCOV
5879
      SUserObj *pUser = NULL;
×
UNCOV
5880
      if (mndAcquireUser(pMnode, pUsers[i].user, &pUser) != 0) {
×
5881
        continue;
×
5882
      }
5883
      pUser->lastRoleRetrieve = 0;  // reset last retrieve time on error
×
5884
      mndReleaseUser(pMnode, pUser);
×
5885
    }
5886
    mError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
5887
    taosMemoryFreeClear(pRsp);
×
UNCOV
5888
    rspLen = 0;
×
5889
  }
5890
  *ppRsp = pRsp;
23,672,099✔
5891
  *pRspLen = rspLen;
23,671,801✔
5892

5893
  TAOS_RETURN(code);
23,668,870✔
5894
}
5895

5896
int32_t mndUserDropRole(SMnode *pMnode, STrans *pTrans, SRoleObj *pObj) {
1,188✔
5897
  int32_t   code = 0, lino = 0;
1,188✔
5898
  SSdb     *pSdb = pMnode->pSdb;
1,188✔
5899
  SUserObj *pUser = NULL;
1,188✔
5900
  void     *pIter = NULL;
1,188✔
5901

5902
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser))) {
3,696✔
5903
    SHashObj *pRole = taosHashGet(pUser->roles, pObj->name, strlen(pObj->name) + 1);
2,508✔
5904
    if (!pRole) {
2,508✔
5905
      sdbRelease(pSdb, pUser);
2,376✔
5906
      pUser = NULL;
2,376✔
5907
      continue;
2,376✔
5908
    }
5909

5910
    SUserObj newUser = {0};
132✔
5911
    TAOS_CHECK_EXIT(mndUserDupObj(pUser, &newUser));
132✔
5912
    code = taosHashRemove(newUser.roles, pObj->name, strlen(pObj->name) + 1);
132✔
5913
    if (code == TSDB_CODE_NOT_FOUND) {
132✔
UNCOV
5914
      sdbRelease(pSdb, pUser);
×
UNCOV
5915
      pUser = NULL;
×
UNCOV
5916
      mndUserFreeObj(&newUser);
×
5917
      continue;
×
5918
    }
5919
    if (code != 0) {
132✔
5920
      mndUserFreeObj(&newUser);
×
UNCOV
5921
      TAOS_CHECK_EXIT(code);
×
5922
    }
5923
    SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
132✔
5924
    if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
132✔
UNCOV
5925
      mndUserFreeObj(&newUser);
×
UNCOV
5926
      TAOS_CHECK_EXIT(TSDB_CODE_OUT_OF_MEMORY);
×
5927
    }
5928
    if ((code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY))) {
132✔
5929
      mndUserFreeObj(&newUser);
×
UNCOV
5930
      TAOS_CHECK_EXIT(code);
×
5931
    }
5932
    sdbRelease(pSdb, pUser);
132✔
5933
    pUser = NULL;
132✔
5934
    mndUserFreeObj(&newUser);
132✔
5935
  }
5936
_exit:
1,188✔
5937
  if (pIter) sdbCancelFetch(pSdb, pIter);
1,188✔
5938
  if (pUser) sdbRelease(pSdb, pUser);
1,188✔
5939
  if (code < 0) {
1,188✔
UNCOV
5940
    mError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
5941
  }
5942
  TAOS_RETURN(code);
1,188✔
5943
}
5944

5945
static int32_t mndUserPrivHashRemoveDb(SHashObj *pHash, const char *dbFName, int32_t dbFNameLen, bool *found) {
3,690,690✔
5946
  void *pVal = NULL;
3,690,690✔
5947
  while ((pVal = taosHashIterate(pHash, pVal))) {
3,874,459✔
5948
    size_t klen = 0;
183,769✔
5949
    char  *key = taosHashGetKey(pVal, &klen);
183,769✔
5950
    if (key && privDbKeyMatch(key, dbFName, dbFNameLen)) {
367,538✔
5951
      TAOS_CHECK_RETURN(taosHashRemove(pHash, key, klen));
18,289✔
5952
      if (found) *found = true;
18,289✔
5953
    }
5954
  }
5955
  TAOS_RETURN(0);
3,690,690✔
5956
}
5957

5958
static int32_t mndUserRemoveDbPrivsImpl(SUserObj *pUser, const char *key, int32_t keyLen, bool *pFound) {
738,138✔
5959
  bool found = false;
738,138✔
5960
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pUser->objPrivs, (char *)key, keyLen, found ? NULL : &found));
738,138✔
5961
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pUser->selectTbs, (char *)key, keyLen, found ? NULL : &found));
738,138✔
5962
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pUser->insertTbs, (char *)key, keyLen, found ? NULL : &found));
738,138✔
5963
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pUser->updateTbs, (char *)key, keyLen, found ? NULL : &found));
738,138✔
5964
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pUser->deleteTbs, (char *)key, keyLen, found ? NULL : &found));
738,138✔
5965
  if (taosHashGet(pUser->ownedDbs, key, keyLen)) {
738,138✔
UNCOV
5966
    TAOS_CHECK_RETURN(taosHashRemove(pUser->ownedDbs, (char *)key, keyLen));
×
UNCOV
5967
    if (!found) found = true;
×
5968
  }
5969
  if (pFound) *pFound = found;
738,138✔
5970
  TAOS_RETURN(0);
738,138✔
5971
}
5972

5973
static int32_t mndUserRemoveDbPrivs(SMnode *pMnode, STrans *pTrans, const char *key, int32_t keyLen,
650,612✔
5974
                                    SSHashObj **ppUsers) {
5975
  int32_t    code = 0, lino = 0;
650,612✔
5976
  SSdb      *pSdb = pMnode->pSdb;
650,612✔
5977
  void      *pIter = NULL;
650,612✔
5978
  SUserObj  *pUser = NULL;
650,612✔
5979
  SSHashObj *pUsers = ppUsers ? *ppUsers : NULL;
650,612✔
5980
  bool       output = (ppUsers != NULL);
650,612✔
5981
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser))) {
1,388,495✔
5982
    bool found = false;
737,883✔
5983
    TAOS_CHECK_EXIT(mndUserRemoveDbPrivsImpl(pUser, key, keyLen, &found));
737,883✔
5984
    if (!found) {
737,883✔
5985
      sdbRelease(pSdb, pUser);
727,158✔
5986
      pUser = NULL;
727,158✔
5987
      continue;
727,158✔
5988
    }
5989

5990
    if (output) {
10,725✔
5991
      if (!pUsers) {
510✔
5992
        TSDB_CHECK_NULL(pUsers = tSimpleHashInit(32, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY)), code, lino,
255✔
5993
                        _exit, TSDB_CODE_OUT_OF_MEMORY);
5994
        tSimpleHashSetFreeFp(pUsers, (_hash_free_fn_t)mndUserFreeObj);
255✔
5995
        *ppUsers = pUsers;
255✔
5996
      }
5997
      void   *pVal = NULL;
510✔
5998
      int32_t userLen = strlen(pUser->name) + 1;
510✔
5999
      if ((pVal = tSimpleHashGet(pUsers, pUser->name, userLen)) != NULL) {
510✔
6000
        TAOS_CHECK_EXIT(mndUserRemoveDbPrivsImpl((SUserObj *)pVal, key, keyLen, NULL));
255✔
6001
      } else {
6002
        SUserObj newUser = {0};
255✔
6003
        if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
255✔
UNCOV
6004
          mndUserFreeObj(&newUser);
×
UNCOV
6005
          TAOS_CHECK_EXIT(code);
×
6006
        }
6007
        if ((code = tSimpleHashPut(pUsers, pUser->name, userLen, &newUser, sizeof(SUserObj)))) {
255✔
6008
          mndUserFreeObj(&newUser);
×
UNCOV
6009
          TAOS_CHECK_EXIT(code);
×
6010
        }
6011
      }
6012
    } else {
6013
      int64_t now = taosGetTimestampMs();
10,215✔
6014
      taosWLockLatch(&pUser->lock);
10,215✔
6015
      pUser->updateTime = now;
10,215✔
6016
      ++pUser->authVersion;
10,215✔
6017
      taosWUnLockLatch(&pUser->lock);
10,215✔
6018

6019
      SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
10,215✔
6020
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
10,215✔
UNCOV
6021
        TAOS_CHECK_EXIT(TSDB_CODE_OUT_OF_MEMORY);
×
6022
      }
6023
      TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
10,215✔
6024
    }
6025

6026
    sdbRelease(pSdb, pUser);
10,725✔
6027
    pUser = NULL;
10,725✔
6028
  }
6029
_exit:
650,612✔
6030
  if (pUser != NULL) sdbRelease(pSdb, pUser);
650,612✔
6031
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
650,612✔
6032
  TAOS_RETURN(code);
650,612✔
6033
}
6034

UNCOV
6035
static int32_t mndRoleRemoveDbPrivsImpl(SRoleObj *pRole, const char *key, int32_t keyLen, bool *pFound) {
×
UNCOV
6036
  bool found = false;
×
UNCOV
6037
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pRole->objPrivs, (char *)key, keyLen, found ? NULL : &found));
×
6038
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pRole->selectTbs, (char *)key, keyLen, found ? NULL : &found));
×
6039
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pRole->insertTbs, (char *)key, keyLen, found ? NULL : &found));
×
6040
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pRole->updateTbs, (char *)key, keyLen, found ? NULL : &found));
×
6041
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pRole->deleteTbs, (char *)key, keyLen, found ? NULL : &found));
×
6042
  if (pFound) *pFound = found;
×
6043
  TAOS_RETURN(0);
×
6044
}
6045

6046
static int32_t mndRoleRemoveDbPrivs(SMnode *pMnode, STrans *pTrans, const char *key, int32_t keyLen,
×
6047
                                    SSHashObj **ppRoles) {
UNCOV
6048
  int32_t    code = 0, lino = 0;
×
6049
  SSdb      *pSdb = pMnode->pSdb;
×
UNCOV
6050
  void      *pIter = NULL;
×
6051
  SRoleObj  *pRole = NULL;
×
6052
  SSHashObj *pRoles = ppRoles ? *ppRoles : NULL;
×
6053
  bool       output = (ppRoles != NULL);
×
6054
  while ((pIter = sdbFetch(pSdb, SDB_ROLE, pIter, (void **)&pRole))) {
×
6055
    bool found = false;
×
6056
    TAOS_CHECK_EXIT(mndRoleRemoveDbPrivsImpl(pRole, key, keyLen, &found));
×
6057
    if (!found) {
×
6058
      sdbRelease(pSdb, pRole);
×
6059
      pRole = NULL;
×
6060
      continue;
×
6061
    }
6062

6063
    if (output) {
×
UNCOV
6064
      if (!pRoles) {
×
UNCOV
6065
        TSDB_CHECK_NULL(pRoles = tSimpleHashInit(32, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY)), code, lino,
×
6066
                        _exit, TSDB_CODE_OUT_OF_MEMORY);
6067
        tSimpleHashSetFreeFp(pRoles, (_hash_free_fn_t)mndRoleFreeObj);
×
6068
        *ppRoles = pRoles;
×
6069
      }
6070
      void   *pVal = NULL;
×
6071
      int32_t roleLen = strlen(pRole->name) + 1;
×
UNCOV
6072
      if ((pVal = tSimpleHashGet(pRoles, pRole->name, roleLen)) != NULL) {
×
6073
        TAOS_CHECK_EXIT(mndRoleRemoveDbPrivsImpl((SRoleObj *)pVal, key, keyLen, NULL));
×
6074
      } else {
6075
        SRoleObj newRole = {0};
×
6076
        if ((code = mndRoleDupObj(pRole, &newRole)) != 0) {
×
UNCOV
6077
          mndRoleFreeObj(&newRole);
×
6078
          TAOS_CHECK_EXIT(code);
×
6079
        }
6080
        if ((code = tSimpleHashPut(pRoles, pRole->name, roleLen, &newRole, sizeof(SRoleObj)))) {
×
6081
          mndRoleFreeObj(&newRole);
×
UNCOV
6082
          TAOS_CHECK_EXIT(code);
×
6083
        }
6084
      }
6085
    } else {
UNCOV
6086
      int64_t now = taosGetTimestampMs();
×
UNCOV
6087
      taosWLockLatch(&pRole->lock);
×
UNCOV
6088
      pRole->updateTime = now;
×
6089
      ++pRole->version;
×
6090
      taosWUnLockLatch(&pRole->lock);
×
6091

6092
      SSdbRaw *pCommitRaw = mndRoleActionEncode(pRole);
×
6093
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
×
UNCOV
6094
        TAOS_CHECK_EXIT(TSDB_CODE_OUT_OF_MEMORY);
×
6095
      }
6096
      TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
×
6097
    }
6098

6099
    sdbRelease(pSdb, pRole);
×
UNCOV
6100
    pRole = NULL;
×
6101
  }
6102
_exit:
×
6103
  if (pRole != NULL) sdbRelease(pSdb, pRole);
×
UNCOV
6104
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
×
6105
  TAOS_RETURN(code);
×
6106
}
6107

6108
int32_t mndPrincipalRemoveDb(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SSHashObj **ppUsers, SSHashObj **ppRoles) {
650,612✔
6109
  TAOS_RETURN(mndUserRemoveDbPrivs(pMnode, pTrans, pDb->name, strlen(pDb->name), ppUsers));
650,612✔
6110
  return mndRoleRemoveDbPrivs(pMnode, pTrans, pDb->name, strlen(pDb->name), ppRoles);
6111
}
6112

6113
int32_t mndUserRemoveStb(SMnode *pMnode, STrans *pTrans, char *stb) {
451,246✔
6114
  return mndPrincipalRemoveObjPrivs(pMnode, pTrans, stb, PRIV_OBJ_TBL);
451,246✔
6115
}
6116

6117
static int32_t mndUserRemoveObjPrivs(SMnode *pMnode, STrans *pTrans, const char *key, int32_t keyLen,
696,762✔
6118
                                     EPrivObjType objType) {
6119
  int32_t   code = 0, lino = 0;
696,762✔
6120
  SSdb     *pSdb = pMnode->pSdb;
696,762✔
6121
  void     *pIter = NULL;
696,762✔
6122
  SUserObj *pUser = NULL;
696,762✔
6123
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser))) {
1,404,143✔
6124
    bool found = false;
707,381✔
6125
    if (taosHashGet(pUser->objPrivs, key, keyLen)) {
707,381✔
6126
      TAOS_CHECK_EXIT(taosHashRemove(pUser->objPrivs, key, keyLen));
2,764✔
6127
      found = true;
2,764✔
6128
    }
6129
    if (objType == PRIV_OBJ_TBL) {
707,381✔
6130
      SPrivTblPolicies *pTblPrivs = taosHashGet(pUser->selectTbs, key, keyLen);
451,938✔
6131
      if (pTblPrivs) {
451,938✔
UNCOV
6132
        TAOS_CHECK_EXIT(taosHashRemove(pUser->selectTbs, key, keyLen));
×
UNCOV
6133
        found = true;
×
6134
      }
6135
      pTblPrivs = taosHashGet(pUser->insertTbs, key, keyLen);
451,938✔
6136
      if (pTblPrivs) {
451,938✔
UNCOV
6137
        TAOS_CHECK_EXIT(taosHashRemove(pUser->insertTbs, key, keyLen));
×
UNCOV
6138
        found = true;
×
6139
      }
6140
      pTblPrivs = taosHashGet(pUser->updateTbs, key, keyLen);
451,938✔
6141
      if (pTblPrivs) {
451,938✔
UNCOV
6142
        TAOS_CHECK_EXIT(taosHashRemove(pUser->updateTbs, key, keyLen));
×
UNCOV
6143
        found = true;
×
6144
      }
6145
      pTblPrivs = taosHashGet(pUser->deleteTbs, key, keyLen);
451,938✔
6146
      if (pTblPrivs) {
451,938✔
UNCOV
6147
        TAOS_CHECK_EXIT(taosHashRemove(pUser->deleteTbs, key, keyLen));
×
UNCOV
6148
        found = true;
×
6149
      }
6150
    }
6151
    if (!found) {
707,381✔
6152
      sdbRelease(pSdb, pUser);
704,617✔
6153
      pUser = NULL;
704,617✔
6154
      continue;
704,617✔
6155
    }
6156

6157
    int64_t now = taosGetTimestampMs();
2,764✔
6158
    taosWLockLatch(&pUser->lock);
2,764✔
6159
    pUser->updateTime = now;
2,764✔
6160
    ++pUser->authVersion;
2,764✔
6161
    taosWUnLockLatch(&pUser->lock);
2,764✔
6162

6163
    SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
2,764✔
6164
    if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
2,764✔
UNCOV
6165
      TAOS_CHECK_EXIT(TSDB_CODE_OUT_OF_MEMORY);
×
6166
    }
6167
    TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
2,764✔
6168

6169
    sdbRelease(pSdb, pUser);
2,764✔
6170
    pUser = NULL;
2,764✔
6171
  }
6172
_exit:
696,762✔
6173
  if (pUser != NULL) sdbRelease(pSdb, pUser);
696,762✔
6174
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
696,762✔
6175
  TAOS_RETURN(code);
696,762✔
6176
}
6177

6178
static int32_t mndRoleRemoveObjPrivs(SMnode *pMnode, STrans *pTrans, const char *key, int32_t keyLen,
696,762✔
6179
                                     EPrivObjType objType) {
6180
  int32_t   code = 0, lino = 0;
696,762✔
6181
  SSdb     *pSdb = pMnode->pSdb;
696,762✔
6182
  void     *pIter = NULL;
696,762✔
6183
  SRoleObj *pRole = NULL;
696,762✔
6184
  while ((pIter = sdbFetch(pSdb, SDB_ROLE, pIter, (void **)&pRole))) {
4,877,334✔
6185
    // inherit system roles have no direct privileges
6186
    if (taosStrncasecmp(pRole->name, "sys", 3) == 0) {
4,180,572✔
6187
      sdbRelease(pSdb, pRole);
4,180,572✔
6188
      pRole = NULL;
4,180,572✔
6189
      continue;
4,180,572✔
6190
    }
UNCOV
6191
    bool found = false;
×
UNCOV
6192
    if (taosHashGet(pRole->objPrivs, key, keyLen)) {
×
UNCOV
6193
      TAOS_CHECK_EXIT(taosHashRemove(pRole->objPrivs, key, keyLen));
×
6194
      found = true;
×
6195
    }
6196

6197
    if (objType == PRIV_OBJ_TBL) {
×
UNCOV
6198
      SPrivTblPolicies *pTblPrivs = taosHashGet(pRole->selectTbs, key, keyLen);
×
UNCOV
6199
      if (pTblPrivs) {
×
6200
        TAOS_CHECK_EXIT(taosHashRemove(pRole->selectTbs, key, keyLen));
×
6201
        found = true;
×
6202
      }
6203
      pTblPrivs = taosHashGet(pRole->insertTbs, key, keyLen);
×
6204
      if (pTblPrivs) {
×
UNCOV
6205
        TAOS_CHECK_EXIT(taosHashRemove(pRole->insertTbs, key, keyLen));
×
6206
        found = true;
×
6207
      }
6208
      pTblPrivs = taosHashGet(pRole->updateTbs, key, keyLen);
×
6209
      if (pTblPrivs) {
×
UNCOV
6210
        TAOS_CHECK_EXIT(taosHashRemove(pRole->updateTbs, key, keyLen));
×
6211
        found = true;
×
6212
      }
6213
      pTblPrivs = taosHashGet(pRole->deleteTbs, key, keyLen);
×
6214
      if (pTblPrivs) {
×
UNCOV
6215
        TAOS_CHECK_EXIT(taosHashRemove(pRole->deleteTbs, key, keyLen));
×
6216
        found = true;
×
6217
      }
6218
    }
6219
    if (!found) {
×
UNCOV
6220
      sdbRelease(pSdb, pRole);
×
UNCOV
6221
      pRole = NULL;
×
6222
      continue;
×
6223
    }
6224
    int64_t now = taosGetTimestampMs();
×
6225
    taosWLockLatch(&pRole->lock);
×
UNCOV
6226
    pRole->updateTime = now;
×
6227
    ++pRole->version;
×
6228
    taosWUnLockLatch(&pRole->lock);
×
6229

6230
    SSdbRaw *pCommitRaw = mndRoleActionEncode(pRole);
×
6231
    if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
×
UNCOV
6232
      TAOS_CHECK_EXIT(TSDB_CODE_OUT_OF_MEMORY);
×
6233
    }
6234
    TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
×
6235

UNCOV
6236
    sdbRelease(pSdb, pRole);
×
6237
    pRole = NULL;
×
6238
  }
6239
_exit:
696,762✔
6240
  if (pRole != NULL) sdbRelease(pSdb, pRole);
696,762✔
6241
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
696,762✔
6242
  TAOS_RETURN(code);
696,762✔
6243
}
6244

6245
static int32_t mndPrincipalRemoveObjPrivs(SMnode *pMnode, STrans *pTrans, char *objFName, EPrivObjType objType) {
696,762✔
6246
  int32_t code = 0;
696,762✔
6247
  char    key[TSDB_PRIV_MAX_KEY_LEN] = {0};
696,762✔
6248
  int32_t keyLen = snprintf(key, sizeof(key), "%d.%s", objType, objFName) + 1;
696,762✔
6249
  TAOS_CHECK_RETURN(mndUserRemoveObjPrivs(pMnode, pTrans, key, keyLen, objType));
696,762✔
6250
  TAOS_CHECK_RETURN(mndRoleRemoveObjPrivs(pMnode, pTrans, key, keyLen, objType));
696,762✔
6251
  TAOS_RETURN(code);
696,762✔
6252
}
6253

6254
int32_t mndUserRemoveView(SMnode *pMnode, STrans *pTrans, char *view) {
144,105✔
6255
  return mndPrincipalRemoveObjPrivs(pMnode, pTrans, view, PRIV_OBJ_VIEW);
144,105✔
6256
}
6257

6258
int32_t mndUserRemoveTopic(SMnode *pMnode, STrans *pTrans, char *topic) {
101,411✔
6259
  return mndPrincipalRemoveObjPrivs(pMnode, pTrans, topic, PRIV_OBJ_TOPIC);
101,411✔
6260
}
6261

UNCOV
6262
int64_t mndGetUserIpWhiteListVer(SMnode *pMnode, SUserObj *pUser) {
×
6263
  // ver = 0, disable ip white list
6264
  // ver > 0, enable ip white list
6265
  return tsEnableWhiteList ? pUser->ipWhiteListVer : 0;
×
6266
}
6267

6268
int64_t mndGetUserTimeWhiteListVer(SMnode *pMnode, SUserObj *pUser) {
×
6269
  // ver = 0, disable datetime white list
6270
  // ver > 0, enable datetime white list
6271
  return tsEnableWhiteList ? pUser->timeWhiteListVer : 0;
×
6272
}
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