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

taosdata / TDengine / #4945

30 Jan 2026 06:19AM UTC coverage: 66.87% (+0.02%) from 66.849%
#4945

push

travis-ci

web-flow
merge: from main to 3.0 #34453

1126 of 2018 new or added lines in 72 files covered. (55.8%)

13708 existing lines in 159 files now uncovered.

205277 of 306978 relevant lines covered (66.87%)

126353544.65 hits per line

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

63.99
/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

37
// clang-format on
38

39
#define USER_VER_SUPPORT_WHITELIST           5
40
#define USER_VER_SUPPORT_WHITELIT_DUAL_STACK 7
41
#define USER_VER_SUPPORT_ADVANCED_SECURITY   8
42
#define USER_VER_NUMBER                      USER_VER_SUPPORT_ADVANCED_SECURITY
43

44
#define USER_RESERVE_SIZE 63
45

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

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

58
#define ALTER_USER_ADD_PRIVS(_type) ((_type) == TSDB_ALTER_USER_ADD_PRIVILEGES)
59
#define ALTER_USER_DEL_PRIVS(_type) ((_type) == TSDB_ALTER_USER_DEL_PRIVILEGES)
60

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

68
#define ALTER_USER_TARGET_DB(_tbname) (0 == (_tbname)[0])
69
#define ALTER_USER_TARGET_TB(_tbname) (0 != (_tbname)[0])
70

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

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

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

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

117
static void generateSalt(char *salt, size_t len);
118

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

122
static bool isIpWhiteListEqual(SIpWhiteListDual *a, SIpWhiteListDual *b);
123
static bool isIpRangeEqual(SIpRange *a, SIpRange *b);
124

125
#define MND_MAX_USER_IP_RANGE   (TSDB_PRIVILEDGE_HOST_LEN / 24)
126
#define MND_MAX_USER_TIME_RANGE 2048
127

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

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

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

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

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

173
static SUserCache userCache;
174
static int8_t     upgradeSecurity = 0;
175

176
static int32_t userCacheInit() {
400,509✔
177
  _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
400,509✔
178

179
  SHashObj *users = taosHashInit(8, hashFn, 1, HASH_ENTRY_LOCK);
400,509✔
180
  if (users == NULL) {
400,509✔
UNCOV
181
    TAOS_RETURN(terrno);
×
182
  }
183

184
  userCache.users = users;
400,509✔
185
  userCache.verIp = 0;
400,509✔
186
  userCache.verTime = 0;
400,509✔
187
  userCache.auditLogUser[0] = '\0';
400,509✔
188

189
  (void)taosThreadRwlockInit(&userCache.rw, NULL);
400,509✔
190
  TAOS_RETURN(0);
400,509✔
191
}
192

193
static void userCacheCleanup() {
400,451✔
194
  if (userCache.users == NULL) {
400,451✔
UNCOV
195
    return;
×
196
  }
197

198
  void *pIter = taosHashIterate(userCache.users, NULL);
400,451✔
199
  while (pIter) {
817,008✔
200
    SCachedUserInfo *pInfo = *(SCachedUserInfo **)pIter;
416,557✔
201
    if (pInfo != NULL) {
416,557✔
202
      taosMemoryFree(pInfo->wlIp);
416,557✔
203
      taosMemoryFree(pInfo->wlTime);
416,557✔
204
      taosMemoryFree(pInfo);
416,557✔
205
    }
206
    pIter = taosHashIterate(userCache.users, pIter);
416,557✔
207
  }
208
  taosHashCleanup(userCache.users);
400,451✔
209

210
  (void)taosThreadRwlockDestroy(&userCache.rw);
400,451✔
211
}
212

213
static void userCacheRemoveUser(const char *user) {
30,185✔
214
  size_t userLen = strlen(user);
30,185✔
215

216
  (void)taosThreadRwlockWrlock(&userCache.rw);
30,185✔
217

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

232
  (void)taosThreadRwlockUnlock(&userCache.rw);
30,185✔
233
}
30,185✔
234

235
static void userCacheResetLoginInfo(const char *user) {
781✔
236
  size_t userLen = strlen(user);
781✔
237

238
  (void)taosThreadRwlockWrlock(&userCache.rw);
781✔
239

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

247
  (void)taosThreadRwlockUnlock(&userCache.rw);
781✔
248
}
781✔
249

250
static SCachedUserInfo *getCachedUserInfo(const char *user) {
4,098,082✔
251
  size_t            userLen = strlen(user);
4,098,082✔
252
  SCachedUserInfo **ppInfo = taosHashGet(userCache.users, user, userLen);
4,098,082✔
253
  if (ppInfo != NULL) {
4,098,082✔
254
    return *ppInfo;
3,651,340✔
255
  }
256

257
  SCachedUserInfo *pInfo = (SCachedUserInfo *)taosMemoryCalloc(1, sizeof(SCachedUserInfo));
446,742✔
258
  if (pInfo == NULL) {
446,742✔
UNCOV
259
    return NULL;
×
260
  }
261

262
  if (taosHashPut(userCache.users, user, userLen, &pInfo, sizeof(pInfo)) != 0) {
446,742✔
UNCOV
263
    taosMemoryFree(pInfo);
×
UNCOV
264
    return NULL;
×
265
  }
266

267
  return pInfo;
446,742✔
268
}
269

270
void mndGetUserLoginInfo(const char *user, SLoginInfo *pLoginInfo) {
2,614,773✔
271
  size_t userLen = strlen(user);
2,614,773✔
272

273
  (void)taosThreadRwlockRdlock(&userCache.rw);
2,614,773✔
274

275
  SCachedUserInfo **ppInfo = taosHashGet(userCache.users, user, userLen);
2,615,611✔
276
  if (ppInfo != NULL && *ppInfo != NULL) {
2,615,611✔
277
    pLoginInfo->lastLoginTime = (*ppInfo)->loginInfo.lastLoginTime;
2,337,333✔
278
    pLoginInfo->failedLoginCount = (*ppInfo)->loginInfo.failedLoginCount;
2,336,697✔
279
    pLoginInfo->lastFailedLoginTime = (*ppInfo)->loginInfo.lastFailedLoginTime;
2,337,134✔
280
  } else {
281
    pLoginInfo->lastLoginTime = taosGetTimestampSec();
278,914✔
282
    pLoginInfo->failedLoginCount = 0;
278,278✔
283
    pLoginInfo->lastFailedLoginTime = 0;
278,278✔
284
  }
285

286
  (void)taosThreadRwlockUnlock(&userCache.rw);
2,614,773✔
287

288
  if (pLoginInfo->lastLoginTime == 0) {
2,615,611✔
289
    pLoginInfo->lastLoginTime = taosGetTimestampSec();
42,907✔
290
  }
291
}
2,614,975✔
292

293
void mndSetUserLoginInfo(const char *user, const SLoginInfo *pLoginInfo) {
2,609,636✔
294
  size_t userLen = strlen(user);
2,609,636✔
295

296
  (void)taosThreadRwlockWrlock(&userCache.rw);
2,609,636✔
297

298
  SCachedUserInfo *pInfo = getCachedUserInfo(user);
2,610,602✔
299
  if (pInfo != NULL) {
2,610,602✔
300
    pInfo->loginInfo.lastLoginTime = pLoginInfo->lastLoginTime;
2,610,602✔
301
    pInfo->loginInfo.failedLoginCount = pLoginInfo->failedLoginCount;
2,610,602✔
302
    pInfo->loginInfo.lastFailedLoginTime = pLoginInfo->lastFailedLoginTime;
2,610,602✔
303
  }
304

305
  (void)taosThreadRwlockUnlock(&userCache.rw);
2,610,602✔
306
}
2,610,602✔
307

308
static bool isDateTimeWhiteListEqual(SDateTimeWhiteList *a, SDateTimeWhiteList *b) {
1,117,486✔
309
  if (a == NULL && b == NULL) {
1,117,486✔
UNCOV
310
    return true;
×
311
  }
312

313
  if (a == NULL || b == NULL) {
1,117,486✔
314
    return false;
66,954✔
315
  }
316

317
  if (a->num != b->num) {
1,050,532✔
318
    return false;
256✔
319
  }
320

321
  for (int i = 0; i < a->num; i++) {
1,050,660✔
322
    if (a->ranges[i].start != b->ranges[i].start || a->ranges[i].duration != b->ranges[i].duration ||
640✔
323
        a->ranges[i].neg != b->ranges[i].neg || a->ranges[i].absolute != b->ranges[i].absolute) {
384✔
324
      return false;
256✔
325
    }
326
  }
327

328
  return true;
1,050,020✔
329
}
330

331
static int32_t userCacheUpdateWhiteList(SMnode *pMnode, SUserObj *pUser) {
1,117,486✔
332
  int32_t code = 0, lino = 0;
1,117,486✔
333

334
  (void)taosThreadRwlockWrlock(&userCache.rw);
1,117,486✔
335

336
  SCachedUserInfo *pInfo = getCachedUserInfo(pUser->user);
1,117,486✔
337
  if (pInfo == NULL) {
1,117,486✔
UNCOV
338
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
339
  }
340

341
  if (!isIpWhiteListEqual(pInfo->wlIp, pUser->pIpWhiteListDual)) {
1,117,486✔
342
    SIpWhiteListDual *p = cloneIpWhiteList(pUser->pIpWhiteListDual);
67,366✔
343
    if (p == NULL) {
67,366✔
UNCOV
344
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
345
    }
346
    taosMemoryFree(pInfo->wlIp);
67,366✔
347
    pInfo->wlIp = p;
67,366✔
348
    userCache.verIp++;
67,366✔
349
  }
350

351
  if (!isDateTimeWhiteListEqual(pInfo->wlTime, pUser->pTimeWhiteList)) {
1,117,486✔
352
    SDateTimeWhiteList *p = cloneDateTimeWhiteList(pUser->pTimeWhiteList);
67,466✔
353
    if (p == NULL) {
67,466✔
UNCOV
354
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
355
    }
356
    taosMemoryFree(pInfo->wlTime);
67,466✔
357
    pInfo->wlTime = p;
67,466✔
358
    userCache.verTime++;
67,466✔
359
  }
360

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

369
static int32_t userCacheRebuildIpWhiteList(SMnode *pMnode) {
486,160✔
370
  int32_t code = 0, lino = 0;
486,160✔
371

372
  SSdb *pSdb = pMnode->pSdb;
486,160✔
373
  void *pIter = NULL;
486,160✔
374
  while (1) {
189,192✔
375
    SUserObj *pUser = NULL;
675,352✔
376
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
675,352✔
377
    if (pIter == NULL) {
675,352✔
378
      break;
486,160✔
379
    }
380

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

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

395
    taosMemoryFree(pInfo->wlIp);
189,192✔
396
    pInfo->wlIp = wl;
189,192✔
397

398
    sdbRelease(pSdb, pUser);
189,192✔
399
  }
400

401
  userCache.verIp++;
486,160✔
402

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

410
int64_t mndGetIpWhiteListVersion(SMnode *pMnode) {
41,221,858✔
411
  int64_t ver = 0;
41,221,858✔
412
  int32_t code = 0;
41,221,858✔
413

414
  if (mndEnableIpWhiteList(pMnode) != 0 && tsEnableWhiteList) {
41,221,858✔
415
    (void)taosThreadRwlockWrlock(&userCache.rw);
3,310✔
416

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

428
    (void)taosThreadRwlockUnlock(&userCache.rw);
3,310✔
429
  }
430

431
  mDebug("ip-white-list on mnode ver: %" PRId64, ver);
41,221,858✔
432
  return ver;
41,221,858✔
433
}
434

435
int32_t mndRefreshUserIpWhiteList(SMnode *pMnode) {
486,160✔
436
  int32_t code = 0;
486,160✔
437
  (void)taosThreadRwlockWrlock(&userCache.rw);
486,160✔
438

439
  if ((code = userCacheRebuildIpWhiteList(pMnode)) != 0) {
486,160✔
UNCOV
440
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
UNCOV
441
    TAOS_RETURN(code);
×
442
  }
443
  userCache.verIp = taosGetTimestampMs();
486,160✔
444
  (void)taosThreadRwlockUnlock(&userCache.rw);
486,160✔
445

446
  TAOS_RETURN(code);
486,160✔
447
}
448

449
static int32_t userCacheRebuildTimeWhiteList(SMnode *pMnode) {
477,770✔
450
  int32_t code = 0, lino = 0;
477,770✔
451

452
  SSdb *pSdb = pMnode->pSdb;
477,770✔
453
  void *pIter = NULL;
477,770✔
454
  while (1) {
180,802✔
455
    SUserObj *pUser = NULL;
658,572✔
456
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
658,572✔
457
    if (pIter == NULL) {
658,572✔
458
      break;
477,770✔
459
    }
460

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

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

475
    taosMemoryFree(pInfo->wlTime);
180,802✔
476
    pInfo->wlTime = wl;
180,802✔
477

478
    sdbRelease(pSdb, pUser);
180,802✔
479
  }
480

481
  userCache.verTime++;
477,770✔
482

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

490
int32_t mndRefreshUserDateTimeWhiteList(SMnode *pMnode) {
477,770✔
491
  int32_t code = 0;
477,770✔
492
  (void)taosThreadRwlockWrlock(&userCache.rw);
477,770✔
493

494
  if ((code = userCacheRebuildTimeWhiteList(pMnode)) != 0) {
477,770✔
UNCOV
495
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
UNCOV
496
    TAOS_RETURN(code);
×
497
  }
498
  userCache.verTime = taosGetTimestampMs();
477,770✔
499
  (void)taosThreadRwlockUnlock(&userCache.rw);
477,770✔
500

501
  TAOS_RETURN(code);
477,770✔
502
}
503

504
int64_t mndGetTimeWhiteListVersion(SMnode *pMnode) {
41,221,858✔
505
  int64_t ver = 0;
41,221,858✔
506
  int32_t code = 0;
41,221,858✔
507

508
  if (mndEnableTimeWhiteList(pMnode) != 0 && tsEnableWhiteList) {
41,221,858✔
509
    (void)taosThreadRwlockWrlock(&userCache.rw);
3,310✔
510

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

522
    (void)taosThreadRwlockUnlock(&userCache.rw);
3,310✔
523
  }
524

525
  mDebug("datetime-white-list on mnode ver: %" PRId64, ver);
41,221,858✔
526
  return ver;
41,221,858✔
527
}
528

529
int32_t mndInitUser(SMnode *pMnode) {
400,509✔
530
  TAOS_CHECK_RETURN(userCacheInit());
400,509✔
531

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

544
  mndSetMsgHandle(pMnode, TDMT_MND_CREATE_USER, mndProcessCreateUserReq);
400,509✔
545
  mndSetMsgHandle(pMnode, TDMT_MND_ALTER_USER, mndProcessAlterUserReq);
400,509✔
546
  mndSetMsgHandle(pMnode, TDMT_MND_DROP_USER, mndProcessDropUserReq);
400,509✔
547
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_AUTH, mndProcessGetUserAuthReq);
400,509✔
548
  mndSetMsgHandle(pMnode, TDMT_MND_UPGRADE_USER, mndProcessUpgradeUserReq);
400,509✔
549
  mndSetMsgHandle(pMnode, TDMT_MND_UPGRADE_USER_RSP, mndProcessUpgradeUserRsp);
400,509✔
550

551
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_IP_WHITELIST, mndProcessGetUserIpWhiteListReq);
400,509✔
552
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_IP_WHITELIST_DUAL, mndProcessGetUserIpWhiteListReq);
400,509✔
553
  mndSetMsgHandle(pMnode, TDMT_MND_RETRIEVE_IP_WHITELIST, mndProcessRetrieveIpWhiteListReq);
400,509✔
554
  mndSetMsgHandle(pMnode, TDMT_MND_RETRIEVE_IP_WHITELIST_DUAL, mndProcessRetrieveIpWhiteListReq);
400,509✔
555
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_DATETIME_WHITELIST, mndProcessGetUserDateTimeWhiteListReq);
400,509✔
556
  mndSetMsgHandle(pMnode, TDMT_MND_RETRIEVE_DATETIME_WHITELIST, mndProcessRetrieveDateTimeWhiteListReq);
400,509✔
557

558
  mndSetMsgHandle(pMnode, TDMT_MND_CREATE_TOTP_SECRET, mndProcessCreateTotpSecretReq);
400,509✔
559
  mndSetMsgHandle(pMnode, TDMT_MND_DROP_TOTP_SECRET, mndProcessDropTotpSecretReq);
400,509✔
560

561
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_USER, mndRetrieveUsers);
400,509✔
562
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_USER, mndCancelGetNextUser);
400,509✔
563
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_USER_FULL, mndRetrieveUsersFull);
400,509✔
564
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_USER_FULL, mndCancelGetNextUser);
400,509✔
565
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_PRIVILEGES, mndRetrievePrivileges);
400,509✔
566
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_PRIVILEGES, mndCancelGetNextPrivileges);
400,509✔
567
  return sdbSetTable(pMnode->pSdb, table);
400,509✔
568
}
569

570
void mndCleanupUser(SMnode *pMnode) { userCacheCleanup(); }
400,451✔
571

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

UNCOV
576
  SIpRange range4 = {0};
×
UNCOV
577
  SIpRange range6 = {0};
×
578

UNCOV
579
  code = createDefaultIp4Range(&range4);
×
UNCOV
580
  TSDB_CHECK_CODE(code, lino, _error);
×
581

UNCOV
582
  code = createDefaultIp6Range(&range6);
×
UNCOV
583
  TSDB_CHECK_CODE(code, lino, _error);
×
584

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

592
static int32_t ipRangeListToStr(SIpRange *range, int32_t num, char *buf, int64_t bufLen) {
1,450,058✔
593
  int32_t len = 0;
1,450,058✔
594
  for (int i = 0; i < num; i++) {
4,382,398✔
595
    SIpRange *pRange = &range[i];
2,932,340✔
596
    SIpAddr   addr = {0};
2,932,340✔
597
    int32_t   code = tIpUintToStr(pRange, &addr);
2,932,340✔
598
    if (code != 0) {
2,932,340✔
UNCOV
599
      mError("%s failed to convert ip range to str, code: %d", __func__, code);
×
600
    }
601

602
    len += tsnprintf(buf + len, bufLen - len, "%c%s/%d, ", pRange->neg ? '-' : '+', IP_ADDR_STR(&addr), addr.mask);
2,932,340✔
603
  }
604
  if (len > 0) {
1,450,058✔
605
    len -= 2;
1,450,058✔
606
    buf[len] = 0; // remove last ", "
1,450,058✔
607
  }
608
  return len;
1,450,058✔
609
}
610

611
static bool isIpRangeEqual(SIpRange *a, SIpRange *b) {
2,100,908✔
612
  if (a->type != b->type || a->neg != b->neg) {
2,100,908✔
UNCOV
613
    return false;
×
614
  }
615

616
  if (a->type == 0) {
2,100,908✔
617
    SIpV4Range *a4 = &a->ipV4;
1,050,788✔
618
    SIpV4Range *b4 = &b->ipV4;
1,050,788✔
619
    return (a4->ip == b4->ip && a4->mask == b4->mask);
1,050,788✔
620
  }
621

622
  SIpV6Range *a6 = &a->ipV6;
1,050,120✔
623
  SIpV6Range *b6 = &b->ipV6;
1,050,120✔
624
  return (a6->addr[0] == b6->addr[0] && a6->addr[1] == b6->addr[1] && a6->mask == b6->mask);
1,050,120✔
625
}
626

627
static bool isIpWhiteListEqual(SIpWhiteListDual *a, SIpWhiteListDual *b) {
1,117,486✔
628
  if (a == NULL && b == NULL) {
1,117,486✔
UNCOV
629
    return true;
×
630
  }
631

632
  if (a == NULL || b == NULL) {
1,117,486✔
633
    return false;
66,954✔
634
  }
635

636
  if (a->num != b->num) {
1,050,532✔
637
    return false;
412✔
638
  }
639
  for (int i = 0; i < a->num; i++) {
3,151,028✔
640
    if (!isIpRangeEqual(&a->pIpRanges[i], &b->pIpRanges[i])) {
2,100,908✔
UNCOV
641
      return false;
×
642
    }
643
  }
644
  return true;
1,050,120✔
645
}
646

647
static int32_t compareIpRange(const void *a, const void *b, const void *arg) {
4,938✔
648
  SIpRange *ra = (SIpRange *)a;
4,938✔
649
  SIpRange *rb = (SIpRange *)b;
4,938✔
650

651
  if (ra->neg != rb->neg) {
4,938✔
652
    return (ra->neg) ? -1 : 1;
640✔
653
  }
654

655
  if (ra->type != rb->type) {
4,298✔
656
    return (ra->type == 0) ? -1 : 1;
1,558✔
657
  }
658

659
  if (ra->type == 0) {
2,740✔
660
    if (ra->ipV4.ip != rb->ipV4.ip) {
2,740✔
661
      return (ra->ipV4.ip < rb->ipV4.ip) ? -1 : 1;
2,428✔
662
    }
663
    return (ra->ipV4.mask < rb->ipV4.mask) ? -1 : 1;
312✔
664
  }
665

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

675
static void sortIpWhiteList(SIpWhiteListDual *pList) {
1,942✔
676
  (void)taosqsort(pList->pIpRanges, pList->num, sizeof(SIpRange), NULL, compareIpRange);
1,942✔
677
}
1,942✔
678

679
static int32_t convertIpWhiteListToStr(SUserObj *pUser, char **buf) {
1,450,058✔
680
  SIpWhiteListDual *pList = pUser->pIpWhiteListDual;
1,450,058✔
681

682
  int64_t bufLen = pList->num * 128 + 8;
1,450,058✔
683
  *buf = taosMemoryCalloc(1, bufLen);
1,450,058✔
684
  if (*buf == NULL) {
1,450,058✔
UNCOV
685
    return 0;
×
686
  }
687

688
  if (pList->num == 0) {
1,450,058✔
UNCOV
689
    return tsnprintf(*buf, bufLen, "+ALL");
×
690
  }
691

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

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

707
  TAOS_CHECK_GOTO(tStartEncode(&encoder), &lino, _OVER);
3,474,891✔
708
  TAOS_CHECK_GOTO(tEncodeI32(&encoder, pList->num), &lino, _OVER);
6,949,782✔
709

710
  for (int i = 0; i < pList->num; i++) {
10,428,693✔
711
    SIpRange *pRange = &(pList->pIpRanges[i]);
6,953,802✔
712
    TAOS_CHECK_GOTO(tSerializeIpRange(&encoder, pRange), &lino, _OVER);
6,953,802✔
713
  }
714

715
  tEndEncode(&encoder);
3,474,891✔
716

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

727
static int32_t tDerializeIpWhiteList(void *buf, int32_t len, SIpWhiteListDual *pList, bool supportNeg) {
2,740,224✔
728
  int32_t  code = 0;
2,740,224✔
729
  int32_t  lino = 0;
2,740,224✔
730
  SDecoder decoder = {0};
2,740,224✔
731
  tDecoderInit(&decoder, buf, len);
2,740,224✔
732

733
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
2,740,224✔
734
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &pList->num), &lino, _OVER);
5,480,448✔
735

736
  for (int i = 0; i < pList->num; i++) {
8,223,044✔
737
    SIpRange *pRange = &(pList->pIpRanges[i]);
5,482,820✔
738
    TAOS_CHECK_GOTO(tDeserializeIpRange(&decoder, pRange, supportNeg), &lino, _OVER);
5,482,820✔
739
  }
740

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

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

UNCOV
756
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
×
UNCOV
757
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &pList->num), &lino, _OVER);
×
758

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

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

774
static int32_t createIpWhiteList(void *buf, int32_t len, SIpWhiteListDual **ppList, bool supportNeg) {
2,740,224✔
775
  int32_t           code = 0;
2,740,224✔
776
  int32_t           lino = 0;
2,740,224✔
777
  int32_t           num = 0;
2,740,224✔
778
  SIpWhiteListDual *p = NULL;
2,740,224✔
779
  SDecoder          decoder = {0};
2,740,224✔
780
  tDecoderInit(&decoder, buf, len);
2,740,224✔
781

782
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
2,740,224✔
783
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &num), &lino, _OVER);
2,740,224✔
784

785
  p = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + num * sizeof(SIpRange));
2,740,224✔
786
  if (p == NULL) {
2,740,224✔
787
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
788
  }
789
  TAOS_CHECK_GOTO(tDerializeIpWhiteList(buf, len, p, supportNeg), &lino, _OVER);
2,740,224✔
790

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

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

UNCOV
810
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
×
UNCOV
811
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &num), &lino, _OVER);
×
812

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

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

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

839
  SIpRange v4 = {0};
351,458✔
840
  SIpRange v6 = {0};
351,458✔
841

842
#ifndef TD_ASTRA
843
  code = createDefaultIp4Range(&v4);
351,458✔
844
  TSDB_CHECK_CODE(code, lino, _error);
351,458✔
845

846
  code = createDefaultIp6Range(&v6);
351,458✔
847
  TSDB_CHECK_CODE(code, lino, _error);
351,458✔
848

849
#endif
850

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

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

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

872
  int32_t pos = 0;
1,450,058✔
873
  if (pUser->pTimeWhiteList->num == 0) {
1,450,058✔
874
    pos += tsnprintf(*buf + pos, bufLen - pos, "+ALL");
1,380,426✔
875
    return pos;
1,380,426✔
876
  }
877

878
  for (int32_t i = 0; i < pUser->pTimeWhiteList->num; i++) {
158,720✔
879
    SDateTimeWhiteListItem *range = &pUser->pTimeWhiteList->ranges[i];
89,088✔
880
    int                     duration = range->duration / 60;
89,088✔
881

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

896
  if (pos > 0) {
69,632✔
897
    pos -= 2;
69,632✔
898
    (*buf)[pos] = 0; // remove last ", "
69,632✔
899
  }
900

901
  return pos;
69,632✔
902
}
903

904
static int32_t compareDateTimeInterval(const void *a, const void *b, const void *arg) {
768✔
905
  SDateTimeWhiteListItem *pA = (SDateTimeWhiteListItem *)a;
768✔
906
  SDateTimeWhiteListItem *pB = (SDateTimeWhiteListItem *)b;
768✔
907

908
  if (pA->neg != pB->neg) {
768✔
909
    return pA->neg ? -1 : 1;
512✔
910
  }
911

912
  if (pA->absolute != pB->absolute) {
256✔
913
    return pA->absolute ? 1 : -1;
256✔
914
  }
915

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

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

UNCOV
924
  return 0;
×
925
}
926

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

931
static void dropOldPasswords(SUserObj *pUser) {
8,400,489✔
932
  if (pUser->numOfPasswords <= pUser->passwordReuseMax) {
8,400,489✔
933
    return;
8,360,908✔
934
  }
935

936
  int32_t reuseMax = pUser->passwordReuseMax;
39,581✔
937
  if (reuseMax == 0) {
39,581✔
938
    reuseMax = 1;  // keep at least one password
37,167✔
939
  }
940

941
  int32_t now = taosGetTimestampSec();
39,581✔
942
  int32_t index = reuseMax;
39,581✔
943
  while(index < pUser->numOfPasswords) {
45,225✔
944
    // the set time of the n-th password is the expire time of the n+1-th password
945
    int32_t expireTime = pUser->passwords[index - 1].setTime;
5,900✔
946
    if (now - expireTime >= pUser->passwordReuseTime) {
5,900✔
947
      break;
256✔
948
    }
949
    index++;
5,644✔
950
  }
951

952
  if (index == pUser->numOfPasswords) {
39,581✔
953
    return;
39,325✔
954
  }
955
  pUser->numOfPasswords = index;
256✔
956
  // this is a shrink operation, no need to check return value
957
  pUser->passwords = taosMemoryRealloc(pUser->passwords, sizeof(SUserPassword) * pUser->numOfPasswords);
256✔
958
}
959

960
static int32_t mndCreateDefaultUser(SMnode *pMnode, char *acct, char *user, char *pass) {
286,402✔
961
  int32_t  code = 0;
286,402✔
962
  int32_t  lino = 0;
286,402✔
963
  SUserObj userObj = {0};
286,402✔
964

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

977
  userObj.passwords[0].setTime = taosGetTimestampSec();
286,402✔
978
  userObj.numOfPasswords = 1;
286,402✔
979

980
  tstrncpy(userObj.user, user, TSDB_USER_LEN);
286,402✔
981
  tstrncpy(userObj.acct, acct, TSDB_USER_LEN);
286,402✔
982
  userObj.createdTime = taosGetTimestampMs();
286,402✔
983
  userObj.updateTime = userObj.createdTime;
286,402✔
984
  userObj.uid = mndGenerateUid(userObj.user, strlen(userObj.user));
286,402✔
985
  userObj.sysInfo = 1;
286,402✔
986
  userObj.enable = 1;
286,402✔
987

988
#ifdef TD_ENTERPRISE
989

990
  // 1: force user to change password
991
  // 2: allow but not force user to change password
992
  userObj.changePass = tsAllowDefaultPassword ? 2 : 1;
286,402✔
993

994
  userObj.ipWhiteListVer = taosGetTimestampMs();
286,402✔
995
  userObj.timeWhiteListVer = userObj.ipWhiteListVer;
286,402✔
996
  userObj.connectTime = TSDB_USER_CONNECT_TIME_DEFAULT;
286,402✔
997
  userObj.connectIdleTime = TSDB_USER_CONNECT_IDLE_TIME_DEFAULT;
286,402✔
998
  userObj.callPerSession = TSDB_USER_CALL_PER_SESSION_DEFAULT;
286,402✔
999
  userObj.vnodePerCall = TSDB_USER_VNODE_PER_CALL_DEFAULT;
286,402✔
1000
  userObj.passwordReuseTime = TSDB_USER_PASSWORD_REUSE_TIME_DEFAULT;
286,402✔
1001
  userObj.passwordReuseMax = TSDB_USER_PASSWORD_REUSE_MAX_DEFAULT;
286,402✔
1002
  userObj.passwordLockTime = TSDB_USER_PASSWORD_LOCK_TIME_DEFAULT;
286,402✔
1003
  userObj.sessionPerUser = TSDB_USER_SESSION_PER_USER_DEFAULT;
286,402✔
1004
  userObj.failedLoginAttempts = TSDB_USER_FAILED_LOGIN_ATTEMPTS_DEFAULT;
286,402✔
1005
  userObj.passwordLifeTime = TSDB_USER_PASSWORD_LIFE_TIME_DEFAULT;
286,402✔
1006
  userObj.passwordGraceTime = TSDB_USER_PASSWORD_GRACE_TIME_DEFAULT;
286,402✔
1007
  userObj.inactiveAccountTime = TSDB_USER_INACTIVE_ACCOUNT_TIME_DEFAULT;
286,402✔
1008
  userObj.allowTokenNum = TSDB_USER_ALLOW_TOKEN_NUM_DEFAULT;
286,402✔
1009
  userObj.tokenNum = 0;
286,402✔
1010

1011
#else  // TD_ENTERPRISE
1012

1013
  userObj.ipWhiteListVer = 0;
1014
  userObj.timeWhiteListVer = 0;
1015
  userObj.changePass = 2;  // 2: allow but not force user to change password
1016
  userObj.connectTime = -1;
1017
  userObj.connectIdleTime = -1;
1018
  userObj.callPerSession = -1;
1019
  userObj.vnodePerCall = -1;
1020
  userObj.passwordReuseTime = 0;
1021
  userObj.passwordReuseMax = 0;
1022
  userObj.passwordLockTime = -1;
1023
  userObj.sessionPerUser = -1;
1024
  userObj.failedLoginAttempts = -1;
1025
  userObj.passwordLifeTime = -1;
1026
  userObj.passwordGraceTime = -1;
1027
  userObj.inactiveAccountTime = -1;
1028
  userObj.allowTokenNum = -1;
1029
  userObj.tokenNum = 0;
1030

1031
#endif  // TD_ENTERPRISE
1032

1033
  userObj.pTimeWhiteList = taosMemoryCalloc(1, sizeof(SDateTimeWhiteList));
286,402✔
1034
  if (userObj.pTimeWhiteList == NULL) {
286,402✔
1035
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _ERROR);
×
1036
  }
1037

1038
  TAOS_CHECK_GOTO(createDefaultIpWhiteList(&userObj.pIpWhiteListDual), &lino, _ERROR);
286,402✔
1039
  // if this is the root user, change the value of some fields to allow the user login without restriction
1040
  if (strcmp(user, TSDB_DEFAULT_USER) == 0) {
286,402✔
1041
    userObj.superUser = 1;
286,402✔
1042
    userObj.createdb = 1;
286,402✔
1043
    userObj.sessionPerUser = -1;
286,402✔
1044
    userObj.callPerSession = -1;
286,402✔
1045
    userObj.vnodePerCall = -1;
286,402✔
1046
    userObj.failedLoginAttempts = -1;
286,402✔
1047
    userObj.passwordGraceTime = -1;
286,402✔
1048
    userObj.inactiveAccountTime = -1;
286,402✔
1049
    userObj.allowTokenNum = -1;
286,402✔
1050
  }
1051

1052
  userObj.roles = taosHashInit(1, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
286,402✔
1053
  if (userObj.roles == NULL) {
286,402✔
UNCOV
1054
    TAOS_CHECK_GOTO(terrno, &lino, _ERROR);
×
1055
  }
1056

1057
  if ((code = taosHashPut(userObj.roles, TSDB_ROLE_SYSDBA, strlen(TSDB_ROLE_SYSDBA) + 1, NULL, 0)) ||
572,804✔
1058
      (code = taosHashPut(userObj.roles, TSDB_ROLE_SYSSEC, strlen(TSDB_ROLE_SYSSEC) + 1, NULL, 0)) ||
572,804✔
1059
      (code = taosHashPut(userObj.roles, TSDB_ROLE_SYSAUDIT, strlen(TSDB_ROLE_SYSAUDIT) + 1, NULL, 0))) {
286,402✔
1060
    TAOS_CHECK_GOTO(code, &lino, _ERROR);
×
1061
  }
1062

1063
  SSdbRaw *pRaw = mndUserActionEncode(&userObj);
286,402✔
1064
  if (pRaw == NULL) goto _ERROR;
286,402✔
1065
  TAOS_CHECK_GOTO(sdbSetRawStatus(pRaw, SDB_STATUS_READY), &lino, _ERROR);
286,402✔
1066

1067
  mInfo("user:%s, will be created when deploying, raw:%p", userObj.user, pRaw);
286,402✔
1068

1069
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_ROLE, NULL, "create-user");
286,402✔
1070
  if (pTrans == NULL) {
286,402✔
1071
    sdbFreeRaw(pRaw);
×
1072
    mError("user:%s, failed to create since %s", userObj.user, terrstr());
×
1073
    goto _ERROR;
×
1074
  }
1075
  mInfo("trans:%d, used to create user:%s", pTrans->id, userObj.user);
286,402✔
1076

1077
  if (mndTransAppendCommitlog(pTrans, pRaw) != 0) {
286,402✔
1078
    mError("trans:%d, failed to commit redo log since %s", pTrans->id, terrstr());
×
1079
    mndTransDrop(pTrans);
×
UNCOV
1080
    goto _ERROR;
×
1081
  }
1082
  TAOS_CHECK_GOTO(sdbSetRawStatus(pRaw, SDB_STATUS_READY), &lino, _ERROR);
286,402✔
1083

1084
  if (mndTransPrepare(pMnode, pTrans) != 0) {
286,402✔
1085
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
UNCOV
1086
    mndTransDrop(pTrans);
×
1087
    goto _ERROR;
×
1088
  }
1089

1090
  mndTransDrop(pTrans);
286,402✔
1091
  mndUserFreeObj(&userObj);
286,402✔
1092
  return 0;
286,402✔
1093

1094
_ERROR:
×
1095
  mndUserFreeObj(&userObj);
×
1096
  if (code == 0) {
×
UNCOV
1097
    code = terrno ? terrno : TSDB_CODE_APP_ERROR;
×
1098
  }
1099
  mError("user:%s, failed to create default user since %s", user, tstrerror(code));
×
1100
  TAOS_RETURN(code);
×
1101
}
1102

1103
static int32_t mndCreateDefaultUsers(SMnode *pMnode) {
286,402✔
1104
  return mndCreateDefaultUser(pMnode, TSDB_DEFAULT_USER, TSDB_DEFAULT_USER, TSDB_DEFAULT_PASS);
286,402✔
1105
}
1106

NEW
1107
static int32_t mndUserPrivUpgradeDbOwners(SMnode *pMnode, SRpcMsg *pReq) {
×
NEW
1108
  int32_t code = 0, lino = 0;
×
NEW
1109
  SSdb   *pSdb = pMnode->pSdb;
×
NEW
1110
  SDbObj *pObj = NULL;
×
NEW
1111
  void   *pIter = NULL;
×
1112

NEW
1113
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "upgrade-db");
×
NEW
1114
  if (pTrans == NULL) {
×
NEW
1115
    TAOS_CHECK_EXIT(terrno);
×
1116
  }
1117

NEW
1118
  while ((pIter = sdbFetch(pSdb, SDB_DB, pIter, (void **)&pObj))) {
×
NEW
1119
    if (pObj->cfg.isMount) {
×
NEW
1120
      sdbRelease(pSdb, pObj);
×
NEW
1121
      continue;
×
1122
    }
NEW
1123
    if (pObj->ownerId != 0) {
×
NEW
1124
      sdbRelease(pSdb, pObj);
×
NEW
1125
      continue;
×
1126
    }
NEW
1127
    SUserObj *pUser = NULL;
×
NEW
1128
    (void)mndAcquireUser(pMnode, pObj->createUser, &pUser);
×
NEW
1129
    if (pUser == NULL) {
×
NEW
1130
      mWarn("db:%s, owner user:%s not found, skip upgrade owner uid", pObj->name, pObj->createUser);
×
NEW
1131
      sdbRelease(pSdb, pObj);
×
NEW
1132
      continue;
×
1133
    }
NEW
1134
    if (pUser->uid == 0) {
×
NEW
1135
      mndReleaseUser(pMnode, pUser);
×
NEW
1136
      sdbRelease(pSdb, pObj);
×
NEW
1137
      continue;
×
1138
    }
NEW
1139
    SDbObj newObj = {0};
×
NEW
1140
    memcpy(&newObj, pObj, sizeof(SDbObj));
×
NEW
1141
    ++newObj.cfgVersion;
×
NEW
1142
    newObj.updateTime = taosGetTimestampMs();
×
NEW
1143
    newObj.ownerId = pUser->uid;
×
NEW
1144
    mInfo("db:%s, owner uid upgraded to %" PRId64, pObj->name, pUser->uid);
×
NEW
1145
    mndReleaseUser(pMnode, pUser);
×
NEW
1146
    if ((code = mndSetAlterDbCommitLogs(pMnode, pTrans, pObj, &newObj))) {
×
NEW
1147
      sdbCancelFetch(pSdb, pIter);
×
NEW
1148
      sdbRelease(pSdb, pObj);
×
NEW
1149
      TAOS_CHECK_EXIT(code);
×
1150
    }
NEW
1151
    sdbRelease(pSdb, pObj);
×
1152
  }
1153

NEW
1154
  TAOS_CHECK_EXIT(mndTransPrepare(pMnode, pTrans));
×
1155

NEW
1156
_exit:
×
NEW
1157
  mndTransDrop(pTrans);
×
NEW
1158
  if (code < 0) {
×
NEW
1159
    mError("failed at line %d to upgrade db owner uid since %s", lino, tstrerror(code));
×
1160
  }
NEW
1161
  TAOS_RETURN(code);
×
1162
}
1163

NEW
1164
static int32_t mndUserPrivUpgradeOwnedDbs(SMnode *pMnode, SUserObj *pUser) {
×
NEW
1165
  int32_t code = 0, lino = 0;
×
NEW
1166
  SSdb   *pSdb = pMnode->pSdb;
×
NEW
1167
  SDbObj *pObj = NULL;
×
NEW
1168
  void   *pIter = NULL;
×
NEW
1169
  char   *key = NULL;
×
NEW
1170
  while ((pIter = sdbFetch(pSdb, SDB_DB, pIter, (void **)&pObj))) {
×
NEW
1171
    if (strncmp(pObj->createUser, pUser->name, sizeof(pObj->createUser)) != 0) {
×
NEW
1172
      sdbRelease(pSdb, pObj);
×
NEW
1173
      pObj = NULL;
×
NEW
1174
      continue;
×
1175
    }
NEW
1176
    TAOS_CHECK_EXIT(taosHashPut(pUser->ownedDbs, pObj->name, strlen(pObj->name) + 1, NULL, 0));
×
NEW
1177
    sdbRelease(pSdb, pObj);
×
NEW
1178
    pObj = NULL;
×
1179
  }
NEW
1180
_exit:
×
NEW
1181
  if (pIter) sdbCancelFetch(pSdb, pIter);
×
NEW
1182
  if (pObj) sdbRelease(pSdb, pObj);
×
NEW
1183
  TAOS_RETURN(code);
×
1184
}
1185

1186
#ifdef TD_ENTERPRISE
NEW
1187
static int32_t mndUserPrivUpgradeTbViews(SMnode *pMnode, SUserObj *pUser, SHashObj **ppTblHash, SHashObj *pTbs, int32_t privType,
×
1188
                                         uint8_t objType) {
NEW
1189
  int32_t code = 0, lino = 0;
×
NEW
1190
  void   *pIter = NULL;
×
NEW
1191
  char   *key = NULL;
×
NEW
1192
  char   *value = NULL;
×
1193

NEW
1194
  SAlterRoleReq alterReq = {.alterType = TSDB_ALTER_ROLE_PRIVILEGES, .add = 1, .objType = objType, .objLevel = 1};
×
1195

NEW
1196
  while ((pIter = taosHashIterate(pTbs, pIter))) {
×
NEW
1197
    size_t keyLen = 0;
×
NEW
1198
    key = taosHashGetKey(pIter, &keyLen);
×
1199

NEW
1200
    SName name = {0};
×
NEW
1201
    TAOS_CHECK_EXIT(tNameFromString(&name, key, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE));
×
1202

NEW
1203
    snprintf(alterReq.objFName, TSDB_OBJ_FNAME_LEN, "%d.%s", name.acctId, name.dbname);
×
NEW
1204
    snprintf(alterReq.tblName, TSDB_TABLE_NAME_LEN, "%s", name.tname);
×
1205

1206
    privAddType(&alterReq.privileges.privSet, privType);
1207

NEW
1208
    if ((objType == PRIV_OBJ_TBL) && (((char *)pIter)[0] != 0) && (((char *)pIter)[1] != 0)) {
×
NEW
1209
      alterReq.privileges.cond = taosStrdup(pIter);
×
NEW
1210
      if (alterReq.privileges.cond == NULL) {
×
NEW
1211
        TAOS_CHECK_EXIT(terrno);
×
1212
      }
NEW
1213
      alterReq.privileges.condLen = strlen(pIter) + 1;  // include '\0'
×
NEW
1214
      if (ppTblHash && !*ppTblHash) {
×
NEW
1215
        *ppTblHash = taosHashInit(1, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), true, HASH_ENTRY_LOCK);
×
NEW
1216
        if (!*ppTblHash) {
×
NEW
1217
          TAOS_CHECK_EXIT(terrno);
×
1218
        }
NEW
1219
        taosHashSetFreeFp(*ppTblHash, privTblPoliciesFree);
×
1220
      }
1221
    }
1222

NEW
1223
    TAOS_CHECK_EXIT(mndAlterUserPrivInfo(pMnode, pUser, &alterReq));
×
NEW
1224
    tFreeSAlterRoleReq(&alterReq);
×
1225
  }
NEW
1226
_exit:
×
NEW
1227
  tFreeSAlterRoleReq(&alterReq);
×
NEW
1228
  TAOS_RETURN(code);
×
1229
}
1230

1231
/**
1232
 * @brief upgrade read/write db privileges from 3.3.x.y to 3.4.x.y
1233
 * @param rwType 0x01 read, 0x02 write
1234
 */
NEW
1235
static int32_t mndUserPrivUpgradeRwDbs(SMnode *pMnode, SUserObj *pUser, SHashObj *pDbs, int8_t rwType) {
×
NEW
1236
  int32_t code = 0, lino = 0;
×
NEW
1237
  void   *pIter = NULL;
×
NEW
1238
  char   *key = NULL;
×
NEW
1239
  while ((pIter = taosHashIterate(pDbs, pIter))) {
×
NEW
1240
    key = taosHashGetKey(pIter, NULL);
×
NEW
1241
    TAOS_CHECK_EXIT(privUpgradeRwDb(pUser->objPrivs, key, "*", rwType));
×
1242
  }
NEW
1243
_exit:
×
NEW
1244
  TAOS_RETURN(code);
×
1245
}
1246

NEW
1247
static int32_t mndUserPrivUpgradeUsedDbs(SMnode *pMnode, SUserObj *pUser, SHashObj *pDbs) {
×
NEW
1248
  int32_t code = 0, lino = 0;
×
NEW
1249
  void   *pIter = NULL;
×
NEW
1250
  char   *key = NULL;
×
NEW
1251
  char   *value = NULL;
×
1252

NEW
1253
  SAlterRoleReq alterReq = {.alterType = TSDB_ALTER_ROLE_PRIVILEGES, .add = 1, .objType = PRIV_OBJ_DB};
×
1254

NEW
1255
  while ((pIter = taosHashIterate(pDbs, pIter))) {
×
NEW
1256
    key = taosHashGetKey(pIter, NULL);
×
1257

NEW
1258
    SName name = {0};
×
NEW
1259
    TAOS_CHECK_EXIT(tNameFromString(&name, key, T_NAME_ACCT | T_NAME_DB));
×
1260

NEW
1261
    snprintf(alterReq.objFName, TSDB_OBJ_FNAME_LEN, "%d.%s", name.acctId, name.dbname);
×
1262

1263
    privAddType(&alterReq.privileges.privSet, PRIV_DB_USE);
1264

NEW
1265
    TAOS_CHECK_EXIT(mndAlterUserPrivInfo(pMnode, pUser, &alterReq));
×
1266
  }
NEW
1267
_exit:
×
NEW
1268
  tFreeSAlterRoleReq(&alterReq);
×
NEW
1269
  TAOS_RETURN(code);
×
1270
}
1271

NEW
1272
static int32_t mndUserPrivUpgradeTopics(SMnode *pMnode, SUserObj *pUser, SHashObj *pTopics) {
×
NEW
1273
  int32_t code = 0, lino = 0;
×
NEW
1274
  void   *pIter = NULL;
×
NEW
1275
  char   *key = NULL;
×
NEW
1276
  char   *value = NULL;
×
1277

NEW
1278
  SAlterRoleReq alterReq = {.alterType = TSDB_ALTER_ROLE_PRIVILEGES,
×
1279
                            .add = 1,
1280
                            .objType = PRIV_OBJ_TOPIC,
1281
                            .objLevel = 1,
1282
                            .ignoreNotExists = 1};
1283

NEW
1284
  while ((pIter = taosHashIterate(pTopics, pIter))) {
×
NEW
1285
    size_t keyLen = 0;
×
NEW
1286
    key = taosHashGetKey(pIter, &keyLen);
×
1287

NEW
1288
    SName name = {0};
×
NEW
1289
    if (tNameFromString(&name, key, T_NAME_ACCT | T_NAME_DB)) {  // 1.topicName
×
NEW
1290
      continue;
×
1291
    }
NEW
1292
    snprintf(alterReq.tblName, TSDB_TABLE_NAME_LEN, "%s", name.dbname);
×
1293

NEW
1294
    SMqTopicObj *pTopic = NULL;
×
NEW
1295
    if (mndAcquireTopic(pMnode, key, &pTopic)) {
×
NEW
1296
      continue;  // no topic exists
×
1297
    }
NEW
1298
    snprintf(alterReq.objFName, TSDB_OBJ_FNAME_LEN, "%s", pTopic->db);
×
NEW
1299
    mndReleaseTopic(pMnode, pTopic);
×
1300

1301
    privAddType(&alterReq.privileges.privSet, PRIV_CM_SUBSCRIBE);
1302

NEW
1303
    TAOS_CHECK_EXIT(mndAlterUserPrivInfo(pMnode, pUser, &alterReq));
×
1304
  }
NEW
1305
_exit:
×
NEW
1306
  tFreeSAlterRoleReq(&alterReq);
×
NEW
1307
  TAOS_RETURN(code);
×
1308
}
1309
#endif
1310

1311
/**
1312
 * @brief migrate from 3.3.x.y to 3.4.x.y
1313
 * @return int32_t
1314
 */
NEW
1315
static int32_t mndUserPrivUpgradeUser(SMnode *pMnode, SUserObj *pObj) {
×
NEW
1316
  int32_t          code = 0, lino = 0;
×
NEW
1317
  SPrivHashObjSet *pPrivSet = pObj->legacyPrivs;
×
1318

NEW
1319
  if (pObj->uid == 0) {
×
NEW
1320
    pObj->uid = mndGenerateUid(pObj->name, strlen(pObj->name));
×
1321
  }
1322

NEW
1323
  if (!pObj->objPrivs &&
×
NEW
1324
      !(pObj->objPrivs = taosHashInit(1, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK))) {
×
NEW
1325
    TAOS_CHECK_EXIT(terrno);
×
1326
  }
1327

NEW
1328
  if (!pObj->roles &&
×
NEW
1329
      !(pObj->roles = taosHashInit(1, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK))) {
×
NEW
1330
    TAOS_CHECK_EXIT(terrno);
×
1331
  }
1332

1333
  // assign roles and system privileges
NEW
1334
  uint8_t flag = 0x01;
×
NEW
1335
  if (pObj->superUser) {
×
NEW
1336
    TAOS_CHECK_EXIT(taosHashPut(pObj->roles, TSDB_ROLE_SYSDBA, strlen(TSDB_ROLE_SYSDBA) + 1, &flag, sizeof(flag)));
×
NEW
1337
    TAOS_CHECK_EXIT(taosHashPut(pObj->roles, TSDB_ROLE_SYSSEC, strlen(TSDB_ROLE_SYSSEC) + 1, &flag, sizeof(flag)));
×
NEW
1338
    TAOS_CHECK_EXIT(taosHashPut(pObj->roles, TSDB_ROLE_SYSAUDIT, strlen(TSDB_ROLE_SYSAUDIT) + 1, &flag, sizeof(flag)));
×
1339
  } else {
NEW
1340
    if (pObj->sysInfo == 1) {
×
NEW
1341
      TAOS_CHECK_EXIT(
×
1342
          taosHashPut(pObj->roles, TSDB_ROLE_SYSINFO_1, strlen(TSDB_ROLE_SYSINFO_1) + 1, &flag, sizeof(flag)));
1343
    } else {
NEW
1344
      TAOS_CHECK_EXIT(
×
1345
          taosHashPut(pObj->roles, TSDB_ROLE_SYSINFO_0, strlen(TSDB_ROLE_SYSINFO_0) + 1, &flag, sizeof(flag)));
1346
    }
NEW
1347
    if (pObj->createdb == 1) {
×
NEW
1348
      privAddType(&pObj->sysPrivs, PRIV_DB_CREATE);
×
1349
    }
1350
  }
1351
#ifdef TD_ENTERPRISE
1352
  // read db: db.*
NEW
1353
  TAOS_CHECK_EXIT(mndUserPrivUpgradeRwDbs(pMnode, pObj, pPrivSet->pReadDbs, 0x01));
×
1354
  // write db: db.*
NEW
1355
  TAOS_CHECK_EXIT(mndUserPrivUpgradeRwDbs(pMnode, pObj, pPrivSet->pWriteDbs, 0x02));
×
1356
  // tables/views
NEW
1357
  TAOS_CHECK_EXIT(
×
1358
      mndUserPrivUpgradeTbViews(pMnode, pObj, &pObj->selectTbs, pPrivSet->pReadTbs, PRIV_TBL_SELECT, PRIV_OBJ_TBL));
NEW
1359
  TAOS_CHECK_EXIT(
×
1360
      mndUserPrivUpgradeTbViews(pMnode, pObj, &pObj->insertTbs, pPrivSet->pWriteTbs, PRIV_TBL_INSERT, PRIV_OBJ_TBL));
NEW
1361
  TAOS_CHECK_EXIT(mndUserPrivUpgradeTbViews(pMnode, pObj, NULL, pPrivSet->pAlterTbs, PRIV_CM_ALTER, PRIV_OBJ_TBL));
×
NEW
1362
  TAOS_CHECK_EXIT(mndUserPrivUpgradeTbViews(pMnode, pObj, NULL, pPrivSet->pReadViews, PRIV_VIEW_SELECT, PRIV_OBJ_VIEW));
×
NEW
1363
  TAOS_CHECK_EXIT(mndUserPrivUpgradeTbViews(pMnode, pObj, NULL, pPrivSet->pAlterViews, PRIV_CM_ALTER, PRIV_OBJ_VIEW));
×
NEW
1364
  TAOS_CHECK_EXIT(mndUserPrivUpgradeTbViews(pMnode, pObj, NULL, pPrivSet->pWriteViews, PRIV_CM_DROP, PRIV_OBJ_VIEW));
×
1365
  // used dbs
NEW
1366
  TAOS_CHECK_EXIT(mndUserPrivUpgradeUsedDbs(pMnode, pObj, pPrivSet->pUseDbs));
×
1367
  // subscribe
NEW
1368
  TAOS_CHECK_EXIT(mndUserPrivUpgradeTopics(pMnode, pObj, pPrivSet->pTopics));
×
1369
#endif
1370
  // owned dbs
NEW
1371
  TAOS_CHECK_EXIT(mndUserPrivUpgradeOwnedDbs(pMnode, pObj));
×
NEW
1372
  mInfo("user:%s, upgraded with uid:%" PRId64, pObj->name, pObj->uid);
×
NEW
1373
_exit:
×
NEW
1374
  TAOS_RETURN(code);
×
1375
}
1376

NEW
1377
static int32_t mndUserPrivUpgradeUsers(SMnode *pMnode, SRpcMsg *pReq) {
×
NEW
1378
  int32_t   code = 0, lino = 0;
×
NEW
1379
  SSdb     *pSdb = pMnode->pSdb;
×
NEW
1380
  SUserObj *pObj = NULL;
×
NEW
1381
  void     *pIter = NULL;
×
NEW
1382
  SUserObj  newObj = {0};
×
1383

NEW
1384
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pObj))) {
×
NEW
1385
    if (pObj->uid != 0 && pObj->legacyPrivs == NULL) {
×
NEW
1386
      sdbRelease(pSdb, pObj);
×
NEW
1387
      pObj = NULL;
×
NEW
1388
      continue;
×
1389
    }
NEW
1390
    if (pObj->uid == 0) {
×
1391
      // Assign uid firstly because the transactions in mndUserPrivUpgradeUsers may not finish when
1392
      // mndUserPrivUpgradeDbOwners is called
NEW
1393
      pObj->uid = mndGenerateUid(pObj->name, strlen(pObj->name));
×
1394
    }
NEW
1395
    memset(&newObj, 0, sizeof(SUserObj));
×
NEW
1396
    TAOS_CHECK_EXIT(mndUserDupObj(pObj, &newObj));
×
NEW
1397
    TAOS_CHECK_EXIT(mndUserPrivUpgradeUser(pMnode, &newObj));
×
NEW
1398
    TAOS_CHECK_EXIT(mndAlterUser(pMnode, &newObj, pReq));
×
NEW
1399
    mndUserFreeObj(&newObj);
×
NEW
1400
    sdbRelease(pSdb, pObj);
×
NEW
1401
    pObj = NULL;
×
1402
  }
NEW
1403
_exit:
×
NEW
1404
  sdbCancelFetch(pSdb, pIter);
×
NEW
1405
  sdbRelease(pSdb, pObj);
×
NEW
1406
  mndUserFreeObj(&newObj);
×
NEW
1407
  if (code < 0) {
×
NEW
1408
    mError("failed at line %d to upgrade db owner uid since %s", lino, tstrerror(code));
×
1409
  }
NEW
1410
  TAOS_RETURN(code);
×
1411
}
1412

NEW
1413
static int32_t mndProcessUpgradeUserReq(SRpcMsg *pReq) {
×
NEW
1414
  SMnode *pMnode = pReq->info.node;
×
NEW
1415
  int32_t code = 0, lino = 0;
×
1416

NEW
1417
  TAOS_CHECK_EXIT(mndUserPrivUpgradeUsers(pMnode, pReq));
×
NEW
1418
  TAOS_CHECK_EXIT(mndUserPrivUpgradeDbOwners(pMnode, pReq));
×
NEW
1419
_exit:
×
NEW
1420
  if (code < 0) {
×
NEW
1421
    mError("failed at line %d to upgrade users since %s", lino, tstrerror(code));
×
1422
  }
NEW
1423
  TAOS_RETURN(code);
×
1424
}
1425

NEW
1426
static int32_t mndProcessUpgradeUserRsp(SRpcMsg *pReq) { return 0;}
×
1427

1428
static int32_t mndUpgradeUsers(SMnode *pMnode, int32_t version) {
360,565✔
1429
  int32_t code = 0, lino = 0;
360,565✔
1430
  if (upgradeSecurity == 0) return code;
360,565✔
NEW
1431
  if (!mndIsLeader(pMnode)) return code;
×
1432

NEW
1433
  SRpcMsg rpcMsg = {.msgType = TDMT_MND_UPGRADE_USER, .info.ahandle = 0, .info.notFreeAhandle = 1};
×
NEW
1434
  SEpSet  epSet = {0};
×
NEW
1435
  mndGetMnodeEpSet(pMnode, &epSet);
×
NEW
1436
  TAOS_CHECK_EXIT(tmsgSendReq(&epSet, &rpcMsg));
×
NEW
1437
_exit:
×
NEW
1438
  if (code < 0) {
×
NEW
1439
    mError("failed at line %d to upgrade users since %s", lino, tstrerror(code));
×
1440
  }
NEW
1441
  TAOS_RETURN(code);
×
1442
}
1443

1444
static int32_t tSerializeUserObjExt(void *buf, int32_t bufLen, SUserObj *pObj) {
6,949,782✔
1445
  int32_t  code = 0, lino = 0;
6,949,782✔
1446
  int32_t  tlen = 0;
6,949,782✔
1447
  void    *pIter = NULL;
6,949,782✔
1448
  SEncoder encoder = {0};
6,949,782✔
1449
  tEncoderInit(&encoder, buf, bufLen);
6,949,782✔
1450

1451
  TAOS_CHECK_EXIT(tStartEncode(&encoder));
6,949,782✔
1452
  TAOS_CHECK_EXIT(tEncodeI64v(&encoder, pObj->uid));
13,899,564✔
1453

1454
  TAOS_CHECK_EXIT(tSerializePrivSysObjPolicies(&encoder, &pObj->sysPrivs, pObj->objPrivs));
6,949,782✔
1455

1456
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->selectTbs));
6,949,782✔
1457
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->insertTbs));
6,949,782✔
1458
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->updateTbs));
6,949,782✔
1459
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->deleteTbs));
6,949,782✔
1460

1461
  int32_t nRoles = taosHashGetSize(pObj->roles);
6,949,782✔
1462
  TAOS_CHECK_EXIT(tEncodeI32v(&encoder, nRoles));
6,949,782✔
1463

1464
  while ((pIter = taosHashIterate(pObj->roles, pIter))) {
22,534,422✔
1465
    size_t keyLen = 0;
15,584,640✔
1466
    char  *key = taosHashGetKey(pIter, &keyLen);  // key: role name
15,584,640✔
1467
    TAOS_CHECK_EXIT(tEncodeCStr(&encoder, key));
15,584,640✔
1468

1469
    uint8_t flag = *(uint8_t *)pIter;
15,584,640✔
1470
    TAOS_CHECK_EXIT(tEncodeU8(&encoder, flag));  // value: 0 reset, 1 set(default)
31,169,280✔
1471
  }
1472

1473
  int32_t nOwnedDbs = taosHashGetSize(pObj->ownedDbs);
6,949,782✔
1474
  TAOS_CHECK_EXIT(tEncodeI32v(&encoder, nOwnedDbs));
6,949,782✔
1475
  pIter = NULL;
6,949,782✔
1476
  while ((pIter = taosHashIterate(pObj->ownedDbs, pIter))) {
27,743,090✔
1477
    size_t keyLen = 0;
20,793,308✔
1478
    char  *key = taosHashGetKey(pIter, &keyLen);  // key: dbFName
20,793,308✔
1479
    TAOS_CHECK_EXIT(tEncodeCStr(&encoder, key));
20,793,308✔
1480
  }
1481

1482
  tEndEncode(&encoder);
6,949,782✔
1483
  tlen = encoder.pos;
6,949,782✔
1484
_exit:
6,949,782✔
1485
  tEncoderClear(&encoder);
6,949,782✔
1486
  if (code < 0) {
6,949,782✔
1487
    mError("user:%s, %s failed at line %d since %s", pObj->user, __func__, lino, tstrerror(code));
×
1488
    TAOS_RETURN(code);
×
1489
  }
1490

1491
  return tlen;
6,949,782✔
1492
}
1493

1494
static int32_t tDeserializeUserObjExt(void *buf, int32_t bufLen, SUserObj *pObj) {
2,740,224✔
1495
  int32_t  code = 0, lino = 0;
2,740,224✔
1496
  SDecoder decoder = {0};
2,740,224✔
1497
  tDecoderInit(&decoder, buf, bufLen);
2,740,224✔
1498

1499
  TAOS_CHECK_EXIT(tStartDecode(&decoder));
2,740,224✔
1500
  TAOS_CHECK_EXIT(tDecodeI64v(&decoder, &pObj->uid));
5,480,448✔
1501
  TAOS_CHECK_EXIT(tDeserializePrivSysObjPolicies(&decoder, &pObj->sysPrivs, &pObj->objPrivs));
2,740,224✔
1502
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->selectTbs));
2,740,224✔
1503
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->insertTbs));
2,740,224✔
1504
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->updateTbs));
2,740,224✔
1505
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->deleteTbs));
2,740,224✔
1506
  int32_t nRoles = 0;
2,740,224✔
1507
  TAOS_CHECK_EXIT(tDecodeI32v(&decoder, &nRoles));
2,740,224✔
1508
  if (nRoles > 0) {
2,740,224✔
1509
    if (!pObj->roles &&
2,734,605✔
1510
        !(pObj->roles = taosHashInit(nRoles, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), 1, HASH_ENTRY_LOCK))) {
2,734,605✔
1511
      TAOS_CHECK_EXIT(terrno);
×
1512
    }
1513
    for (int32_t i = 0; i < nRoles; i++) {
8,549,542✔
1514
      int32_t keyLen = 0;
5,814,937✔
1515
      char   *key = NULL;
5,814,937✔
1516
      TAOS_CHECK_EXIT(tDecodeCStrAndLen(&decoder, &key, &keyLen));
5,814,937✔
1517
      uint8_t flag = 0;
5,814,937✔
1518
      TAOS_CHECK_EXIT(tDecodeU8(&decoder, &flag));
5,814,937✔
1519
      TAOS_CHECK_EXIT(taosHashPut(pObj->roles, key, keyLen + 1, &flag, sizeof(flag)));
5,814,937✔
1520
    }
1521
  }
1522
  if (!tDecodeIsEnd(&decoder)) {
2,740,224✔
1523
    int32_t nOwnedDbs = 0;
2,740,224✔
1524
    TAOS_CHECK_EXIT(tDecodeI32v(&decoder, &nOwnedDbs));
2,740,224✔
1525
    if (nOwnedDbs > 0) {
2,740,224✔
1526
      if (!pObj->ownedDbs &&
1,222,865✔
1527
          !(pObj->ownedDbs =
1,222,865✔
1528
                taosHashInit(nOwnedDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), 1, HASH_ENTRY_LOCK))) {
1,222,865✔
NEW
1529
        TAOS_CHECK_EXIT(terrno);
×
1530
      }
1531
      for (int32_t i = 0; i < nOwnedDbs; ++i) {
10,609,728✔
1532
        int32_t keyLen = 0;
9,386,863✔
1533
        char   *key = NULL;
9,386,863✔
1534
        TAOS_CHECK_EXIT(tDecodeCStrAndLen(&decoder, &key, &keyLen));
9,386,863✔
1535
        TAOS_CHECK_EXIT(taosHashPut(pObj->ownedDbs, key, keyLen + 1, NULL, 0));
9,386,863✔
1536
      }
1537
    }
1538
  }
1539

1540
_exit:
2,739,875✔
1541
  tEndDecode(&decoder);
2,740,224✔
1542
  tDecoderClear(&decoder);
2,740,224✔
1543
  if (code < 0) {
2,740,224✔
1544
    mError("user, %s failed at line %d since %s, row:%p", __func__, lino, tstrerror(code), pObj);
×
1545
  }
1546
  TAOS_RETURN(code);
2,740,224✔
1547
}
1548

1549
SSdbRaw *mndUserActionEncode(SUserObj *pUser) {
3,474,891✔
1550
  int32_t code = 0;
3,474,891✔
1551
  int32_t lino = 0;
3,474,891✔
1552
  int32_t passReserve = (sizeof(SUserPassword) + 8) * pUser->numOfPasswords + 4;
3,474,891✔
NEW
1553
  int32_t ipWhiteReserve =
×
1554
      pUser->pIpWhiteListDual ? (sizeof(SIpRange) * pUser->pIpWhiteListDual->num + sizeof(SIpWhiteListDual) + 4) : 16;
3,474,891✔
NEW
1555
  int32_t timeWhiteReserve =
×
1556
      pUser->pTimeWhiteList
3,474,891✔
1557
          ? (sizeof(SDateTimeWhiteListItem) * pUser->pTimeWhiteList->num + sizeof(SDateTimeWhiteList) + 4)
3,474,891✔
1558
          : 16;
1559
  int32_t numOfReadDbs = 0;     // taosHashGetSize(pUser->readDbs);
3,474,891✔
1560
  int32_t numOfWriteDbs = 0;    // taosHashGetSize(pUser->writeDbs);
3,474,891✔
1561
  int32_t numOfReadTbs = 0;     // taosHashGetSize(pUser->readTbs);
3,474,891✔
1562
  int32_t numOfWriteTbs = 0;    // taosHashGetSize(pUser->writeTbs);
3,474,891✔
1563
  int32_t numOfAlterTbs = 0;    // taosHashGetSize(pUser->alterTbs);
3,474,891✔
1564
  int32_t numOfReadViews = 0;   // taosHashGetSize(pUser->readViews);
3,474,891✔
1565
  int32_t numOfWriteViews = 0;  // taosHashGetSize(pUser->writeViews);
3,474,891✔
1566
  int32_t numOfAlterViews = 0;  // taosHashGetSize(pUser->alterViews);
3,474,891✔
1567
  int32_t numOfTopics = 0;      // taosHashGetSize(pUser->topics);
3,474,891✔
1568
  int32_t numOfUseDbs = 0;      // taosHashGetSize(pUser->useDbs);
3,474,891✔
1569
  int32_t numOfRoles = taosHashGetSize(pUser->roles);
3,474,891✔
1570
  int32_t size = sizeof(SUserObj) + USER_RESERVE_SIZE + (numOfReadDbs + numOfWriteDbs) * TSDB_DB_FNAME_LEN +
3,474,891✔
1571
                 numOfTopics * TSDB_TOPIC_FNAME_LEN + ipWhiteReserve + timeWhiteReserve + passReserve;
3,474,891✔
1572
  char    *buf = NULL;
3,474,891✔
1573
  SSdbRaw *pRaw = NULL;
3,474,891✔
1574

1575
  char *stb = NULL;
3,474,891✔
1576
#if 0
1577
  stb = taosHashIterate(pUser->readTbs, NULL);
1578
  while (stb != NULL) {
1579
    size_t keyLen = 0;
1580
    void  *key = taosHashGetKey(stb, &keyLen);
1581
    size += sizeof(int32_t);
1582
    size += keyLen;
1583

1584
    size_t valueLen = 0;
1585
    valueLen = strlen(stb) + 1;
1586
    size += sizeof(int32_t);
1587
    size += valueLen;
1588
    stb = taosHashIterate(pUser->readTbs, stb);
1589
  }
1590

1591
  stb = taosHashIterate(pUser->writeTbs, NULL);
1592
  while (stb != NULL) {
1593
    size_t keyLen = 0;
1594
    void  *key = taosHashGetKey(stb, &keyLen);
1595
    size += sizeof(int32_t);
1596
    size += keyLen;
1597

1598
    size_t valueLen = 0;
1599
    valueLen = strlen(stb) + 1;
1600
    size += sizeof(int32_t);
1601
    size += valueLen;
1602
    stb = taosHashIterate(pUser->writeTbs, stb);
1603
  }
1604
  stb = taosHashIterate(pUser->alterTbs, NULL);
1605
  while (stb != NULL) {
1606
    size_t keyLen = 0;
1607
    void  *key = taosHashGetKey(stb, &keyLen);
1608
    size += sizeof(int32_t);
1609
    size += keyLen;
1610

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

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

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

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

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

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

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

1660
  int32_t *useDb = taosHashIterate(pUser->useDbs, NULL);
1661
  while (useDb != NULL) {
1662
    size_t keyLen = 0;
1663
    void  *key = taosHashGetKey(useDb, &keyLen);
1664
    size += sizeof(int32_t);
1665
    size += keyLen;
1666
    size += sizeof(int32_t);
1667
    useDb = taosHashIterate(pUser->useDbs, useDb);
1668
  }
1669
#endif
1670
  int32_t sizeExt = tSerializeUserObjExt(NULL, 0, pUser);
3,474,891✔
1671
  if (sizeExt < 0) {
3,474,891✔
1672
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1673
  }
1674
  size += sizeExt;
3,474,891✔
1675

1676
  pRaw = sdbAllocRaw(SDB_USER, USER_VER_NUMBER, size);
3,474,891✔
1677
  if (pRaw == NULL) {
3,474,891✔
1678
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1679
  }
1680

1681
  int32_t dataPos = 0;
3,474,891✔
1682
  SDB_SET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN, _OVER)
3,474,891✔
1683

1684
  dropOldPasswords(pUser);
3,474,891✔
1685
  SDB_SET_INT32(pRaw, dataPos, pUser->numOfPasswords, _OVER)
3,474,891✔
1686
  for (int32_t i = 0; i < pUser->numOfPasswords; i++) {
7,667,856✔
1687
    SDB_SET_BINARY(pRaw, dataPos, pUser->passwords[i].pass, sizeof(pUser->passwords[i].pass), _OVER)
4,192,965✔
1688
    SDB_SET_INT32(pRaw, dataPos, pUser->passwords[i].setTime, _OVER)
4,192,965✔
1689
  }
1690
  SDB_SET_BINARY(pRaw, dataPos, pUser->salt, sizeof(pUser->salt), _OVER)
3,474,891✔
1691

1692
  SDB_SET_BINARY(pRaw, dataPos, pUser->acct, TSDB_USER_LEN, _OVER)
3,474,891✔
1693
  SDB_SET_INT64(pRaw, dataPos, pUser->createdTime, _OVER)
3,474,891✔
1694
  SDB_SET_INT64(pRaw, dataPos, pUser->updateTime, _OVER)
3,474,891✔
1695
  SDB_SET_INT8(pRaw, dataPos, pUser->superUser, _OVER)
3,474,891✔
1696
  SDB_SET_INT8(pRaw, dataPos, pUser->sysInfo, _OVER)
3,474,891✔
1697
  SDB_SET_INT8(pRaw, dataPos, pUser->enable, _OVER)
3,474,891✔
1698
  SDB_SET_UINT8(pRaw, dataPos, pUser->flag, _OVER)
3,474,891✔
1699
  SDB_SET_INT32(pRaw, dataPos, pUser->authVersion, _OVER)
3,474,891✔
1700
  SDB_SET_INT32(pRaw, dataPos, pUser->passVersion, _OVER)
3,474,891✔
1701
  SDB_SET_INT32(pRaw, dataPos, numOfReadDbs, _OVER)
3,474,891✔
1702
  SDB_SET_INT32(pRaw, dataPos, numOfWriteDbs, _OVER)
3,474,891✔
1703
  SDB_SET_INT32(pRaw, dataPos, numOfTopics, _OVER)
3,474,891✔
1704
#if 0
1705
  char *db = taosHashIterate(pUser->readDbs, NULL);
1706
  while (db != NULL) {
1707
    SDB_SET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER);
1708
    db = taosHashIterate(pUser->readDbs, db);
1709
  }
1710

1711
  db = taosHashIterate(pUser->writeDbs, NULL);
1712
  while (db != NULL) {
1713
    SDB_SET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER);
1714
    db = taosHashIterate(pUser->writeDbs, db);
1715
  }
1716
  char *topic = taosHashIterate(pUser->topics, NULL);
1717
  while (topic != NULL) {
1718
    SDB_SET_BINARY(pRaw, dataPos, topic, TSDB_TOPIC_FNAME_LEN, _OVER);
1719
    topic = taosHashIterate(pUser->topics, topic);
1720
  }
1721
#endif
1722
  SDB_SET_INT32(pRaw, dataPos, numOfReadTbs, _OVER)
3,474,891✔
1723
  SDB_SET_INT32(pRaw, dataPos, numOfWriteTbs, _OVER)
3,474,891✔
1724
  SDB_SET_INT32(pRaw, dataPos, numOfAlterTbs, _OVER)
3,474,891✔
1725
  SDB_SET_INT32(pRaw, dataPos, numOfReadViews, _OVER)
3,474,891✔
1726
  SDB_SET_INT32(pRaw, dataPos, numOfWriteViews, _OVER)
3,474,891✔
1727
  SDB_SET_INT32(pRaw, dataPos, numOfAlterViews, _OVER)
3,474,891✔
1728
  SDB_SET_INT32(pRaw, dataPos, numOfUseDbs, _OVER)
3,474,891✔
1729

1730
#if 0
1731
  stb = taosHashIterate(pUser->readTbs, NULL);
1732
  while (stb != NULL) {
1733
    size_t keyLen = 0;
1734
    void  *key = taosHashGetKey(stb, &keyLen);
1735
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1736
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1737

1738
    size_t valueLen = 0;
1739
    valueLen = strlen(stb) + 1;
1740
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
1741
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
1742
    stb = taosHashIterate(pUser->readTbs, stb);
1743
  }
1744

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

1752
    size_t valueLen = 0;
1753
    valueLen = strlen(stb) + 1;
1754
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
1755
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
1756
    stb = taosHashIterate(pUser->writeTbs, stb);
1757
  }
1758
  stb = taosHashIterate(pUser->alterTbs, NULL);
1759
  while (stb != NULL) {
1760
    size_t keyLen = 0;
1761
    void  *key = taosHashGetKey(stb, &keyLen);
1762
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1763
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1764

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

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

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

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

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

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

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

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

1821
    SDB_SET_INT32(pRaw, dataPos, *useDb, _OVER)
1822
    useDb = taosHashIterate(pUser->useDbs, useDb);
1823
  }
1824
#endif
1825
  // save white list
1826
  int32_t num = pUser->pIpWhiteListDual->num;
3,474,891✔
1827
  int32_t tlen = sizeof(SIpWhiteListDual) + num * sizeof(SIpRange) + 4;
3,474,891✔
1828
  int32_t maxBufLen = TMAX(tlen, sizeExt);
3,474,891✔
1829
  if ((buf = taosMemoryCalloc(1, maxBufLen)) == NULL) {
3,474,891✔
UNCOV
1830
    TAOS_CHECK_GOTO(terrno, NULL, _OVER);
×
1831
  }
1832
  int32_t len = 0;
3,474,891✔
1833
  TAOS_CHECK_GOTO(tSerializeIpWhiteList(buf, tlen, pUser->pIpWhiteListDual, &len), &lino, _OVER);
3,474,891✔
1834

1835
  SDB_SET_INT32(pRaw, dataPos, len, _OVER);
3,474,891✔
1836
  SDB_SET_BINARY(pRaw, dataPos, buf, len, _OVER);
3,474,891✔
1837

1838
  SDB_SET_INT64(pRaw, dataPos, pUser->ipWhiteListVer, _OVER);
3,474,891✔
1839
  SDB_SET_INT8(pRaw, dataPos, pUser->passEncryptAlgorithm, _OVER);
3,474,891✔
1840

1841
  SDB_SET_BINARY(pRaw, dataPos, pUser->totpsecret, sizeof(pUser->totpsecret), _OVER);
3,474,891✔
1842
  SDB_SET_INT8(pRaw, dataPos, pUser->changePass, _OVER);
3,474,891✔
1843
  SDB_SET_INT32(pRaw, dataPos, pUser->sessionPerUser, _OVER);
3,474,891✔
1844
  SDB_SET_INT32(pRaw, dataPos, pUser->connectTime, _OVER);
3,474,891✔
1845
  SDB_SET_INT32(pRaw, dataPos, pUser->connectIdleTime, _OVER);
3,474,891✔
1846
  SDB_SET_INT32(pRaw, dataPos, pUser->callPerSession, _OVER);
3,474,891✔
1847
  SDB_SET_INT32(pRaw, dataPos, pUser->vnodePerCall, _OVER);
3,474,891✔
1848
  SDB_SET_INT32(pRaw, dataPos, pUser->failedLoginAttempts, _OVER);
3,474,891✔
1849
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordLifeTime, _OVER);
3,474,891✔
1850
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordReuseTime, _OVER);
3,474,891✔
1851
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordReuseMax, _OVER);
3,474,891✔
1852
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordLockTime, _OVER);
3,474,891✔
1853
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordGraceTime, _OVER);
3,474,891✔
1854
  SDB_SET_INT32(pRaw, dataPos, pUser->inactiveAccountTime, _OVER);
3,474,891✔
1855
  SDB_SET_INT32(pRaw, dataPos, pUser->allowTokenNum, _OVER);
3,474,891✔
1856
  SDB_SET_INT32(pRaw, dataPos, pUser->tokenNum, _OVER);
3,474,891✔
1857

1858
  SDB_SET_INT32(pRaw, dataPos, pUser->pTimeWhiteList->num, _OVER);
3,474,891✔
1859
  for (int32_t i = 0; i < pUser->pTimeWhiteList->num; i++) {
3,481,291✔
1860
    SDateTimeWhiteListItem *range = &pUser->pTimeWhiteList->ranges[i];
6,400✔
1861
    SDB_SET_BOOL(pRaw, dataPos, range->absolute, _OVER);
6,400✔
1862
    SDB_SET_BOOL(pRaw, dataPos, range->neg, _OVER);
6,400✔
1863
    SDB_SET_INT64(pRaw, dataPos, range->start, _OVER);
6,400✔
1864
    SDB_SET_INT32(pRaw, dataPos, range->duration, _OVER);
6,400✔
1865
  }
1866

1867
  sizeExt = tSerializeUserObjExt(buf, sizeExt, pUser);
3,474,891✔
1868
  if (sizeExt < 0) {
3,474,891✔
UNCOV
1869
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1870
  }
1871
  SDB_SET_INT32(pRaw, dataPos, sizeExt, _OVER);
3,474,891✔
1872
  SDB_SET_BINARY(pRaw, dataPos, buf, sizeExt, _OVER);
3,474,891✔
1873

1874
  SDB_SET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
3,474,891✔
1875

1876
  SDB_SET_DATALEN(pRaw, dataPos, _OVER)
3,474,891✔
1877

1878
_OVER:
3,474,891✔
1879
  taosMemoryFree(buf);
3,474,891✔
1880
  if (code < 0) {
3,474,891✔
UNCOV
1881
    mError("user:%s, failed to encode user action to raw:%p at line %d since %s", pUser->user, pRaw, lino,
×
1882
           tstrerror(code));
UNCOV
1883
    sdbFreeRaw(pRaw);
×
1884
    pRaw = NULL;
×
UNCOV
1885
    terrno = code;
×
1886
  }
1887

1888
  mTrace("user:%s, encode user action to raw:%p, row:%p", pUser->user, pRaw, pUser);
3,474,891✔
1889
  return pRaw;
3,474,891✔
1890
}
1891

1892
static SSdbRow *mndUserActionDecode(SSdbRaw *pRaw) {
2,740,224✔
1893
  int32_t   code = 0;
2,740,224✔
1894
  int32_t   lino = 0;
2,740,224✔
1895
  SSdbRow  *pRow = NULL;
2,740,224✔
1896
  SUserObj *pUser = NULL;
2,740,224✔
1897
  char     *key = NULL;
2,740,224✔
1898
  char     *value = NULL;
2,740,224✔
1899

1900
  int8_t sver = 0;
2,740,224✔
1901
  if (sdbGetRawSoftVer(pRaw, &sver) != 0) {
2,740,224✔
UNCOV
1902
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_PTR, &lino, _OVER);
×
1903
  }
1904

1905
  if (sver < 1 || sver > USER_VER_NUMBER) {
2,740,224✔
UNCOV
1906
    TAOS_CHECK_GOTO(TSDB_CODE_SDB_INVALID_DATA_VER, &lino, _OVER);
×
1907
  }
1908

1909
  pRow = sdbAllocRow(sizeof(SUserObj));
2,740,224✔
1910
  if (pRow == NULL) {
2,740,224✔
UNCOV
1911
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1912
  }
1913

1914
  pUser = sdbGetRowObj(pRow);
2,740,224✔
1915
  if (pUser == NULL) {
2,740,224✔
UNCOV
1916
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1917
  }
1918

1919
  if (sver < USER_VER_SUPPORT_ADVANCED_SECURITY) {
2,740,224✔
NEW
1920
    upgradeSecurity = 1;
×
NEW
1921
    pUser->legacyPrivs = taosMemCalloc(1, sizeof(SPrivHashObjSet));
×
NEW
1922
    if (pUser->legacyPrivs == NULL) {
×
NEW
1923
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
1924
    }
1925
  }
1926

1927
  int32_t dataPos = 0;
2,740,224✔
1928
  SDB_GET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN, _OVER)
2,740,224✔
1929

1930
  if (sver < USER_VER_SUPPORT_ADVANCED_SECURITY) {
2,740,224✔
UNCOV
1931
    pUser->passwords = taosMemoryCalloc(1, sizeof(SUserPassword));
×
UNCOV
1932
    if (pUser->passwords == NULL) {
×
UNCOV
1933
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
1934
    }
UNCOV
1935
    SDB_GET_BINARY(pRaw, dataPos, pUser->passwords[0].pass, TSDB_PASSWORD_LEN, _OVER)
×
UNCOV
1936
    pUser->numOfPasswords = 1;
×
UNCOV
1937
    memset(pUser->salt, 0, sizeof(pUser->salt));
×
1938
  } else {
1939
    SDB_GET_INT32(pRaw, dataPos, &pUser->numOfPasswords, _OVER)
2,740,224✔
1940
    pUser->passwords = taosMemoryCalloc(pUser->numOfPasswords, sizeof(SUserPassword));
2,740,224✔
1941
    if (pUser->passwords == NULL) {
2,740,224✔
UNCOV
1942
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
1943
    }
1944
    for (int32_t i = 0; i < pUser->numOfPasswords; ++i) {
6,158,202✔
1945
      SDB_GET_BINARY(pRaw, dataPos, pUser->passwords[i].pass, sizeof(pUser->passwords[i].pass), _OVER);
3,417,978✔
1946
      SDB_GET_INT32(pRaw, dataPos, &pUser->passwords[i].setTime, _OVER);
3,417,978✔
1947
    }
1948
    SDB_GET_BINARY(pRaw, dataPos, pUser->salt, sizeof(pUser->salt), _OVER)
2,740,224✔
1949
  }
1950

1951
  SDB_GET_BINARY(pRaw, dataPos, pUser->acct, TSDB_USER_LEN, _OVER)
2,740,224✔
1952
  SDB_GET_INT64(pRaw, dataPos, &pUser->createdTime, _OVER)
2,740,224✔
1953
  SDB_GET_INT64(pRaw, dataPos, &pUser->updateTime, _OVER)
2,740,224✔
1954
  if (sver < USER_VER_SUPPORT_ADVANCED_SECURITY) {
2,740,224✔
UNCOV
1955
    pUser->passwords[0].setTime = (int32_t)(pUser->updateTime / 1000);
×
1956
  }
1957

1958
  SDB_GET_INT8(pRaw, dataPos, &pUser->superUser, _OVER)
2,740,224✔
1959
  SDB_GET_INT8(pRaw, dataPos, &pUser->sysInfo, _OVER)
2,740,224✔
1960
  SDB_GET_INT8(pRaw, dataPos, &pUser->enable, _OVER)
2,740,224✔
1961
  SDB_GET_UINT8(pRaw, dataPos, &pUser->flag, _OVER)
2,740,224✔
1962
  if (pUser->superUser) pUser->createdb = 1;
2,740,224✔
1963
  SDB_GET_INT32(pRaw, dataPos, &pUser->authVersion, _OVER)
2,740,224✔
1964
  if (sver >= 4) {
2,740,224✔
1965
    SDB_GET_INT32(pRaw, dataPos, &pUser->passVersion, _OVER)
2,740,224✔
1966
  }
1967

1968
  int32_t numOfReadDbs = 0;
2,740,224✔
1969
  int32_t numOfWriteDbs = 0;
2,740,224✔
1970
  int32_t numOfTopics = 0;
2,740,224✔
1971
  SDB_GET_INT32(pRaw, dataPos, &numOfReadDbs, _OVER)
2,740,224✔
1972
  SDB_GET_INT32(pRaw, dataPos, &numOfWriteDbs, _OVER)
2,740,224✔
1973
  if (sver >= 2) {
2,740,224✔
1974
    SDB_GET_INT32(pRaw, dataPos, &numOfTopics, _OVER)
2,740,224✔
1975
  }
1976

1977
  if (numOfReadDbs > 0) {
2,740,224✔
NEW
1978
    pUser->legacyPrivs->pReadDbs =
×
NEW
1979
        taosHashInit(numOfReadDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
NEW
1980
    if (pUser->legacyPrivs->pReadDbs == NULL) {
×
UNCOV
1981
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1982
    }
1983
  }
1984
  if (numOfWriteDbs > 0) {
2,740,224✔
NEW
1985
    pUser->legacyPrivs->pWriteDbs =
×
NEW
1986
        taosHashInit(numOfWriteDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
NEW
1987
    if (pUser->legacyPrivs->pWriteDbs == NULL) {
×
UNCOV
1988
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1989
    }
1990
  }
1991
  if (numOfTopics > 0) {
2,740,224✔
NEW
1992
    pUser->legacyPrivs->pTopics =
×
NEW
1993
        taosHashInit(numOfTopics, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
NEW
1994
    if (pUser->legacyPrivs->pTopics == NULL) {
×
UNCOV
1995
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1996
    }
1997
  }
1998
  for (int32_t i = 0; i < numOfReadDbs; ++i) {
2,740,224✔
UNCOV
1999
    char db[TSDB_DB_FNAME_LEN] = {0};
×
UNCOV
2000
    SDB_GET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER)
×
UNCOV
2001
    int32_t len = strlen(db) + 1;
×
NEW
2002
    TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pReadDbs, db, len, db, TSDB_DB_FNAME_LEN), &lino, _OVER);
×
2003
  }
2004

2005
  for (int32_t i = 0; i < numOfWriteDbs; ++i) {
2,740,224✔
UNCOV
2006
    char db[TSDB_DB_FNAME_LEN] = {0};
×
UNCOV
2007
    SDB_GET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER)
×
UNCOV
2008
    int32_t len = strlen(db) + 1;
×
NEW
2009
    TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pWriteDbs, db, len, db, TSDB_DB_FNAME_LEN), &lino, _OVER);
×
2010
  }
2011

2012
  if (sver >= 2) {
2,740,224✔
2013
    for (int32_t i = 0; i < numOfTopics; ++i) {
2,740,224✔
UNCOV
2014
      char topic[TSDB_TOPIC_FNAME_LEN] = {0};
×
UNCOV
2015
      SDB_GET_BINARY(pRaw, dataPos, topic, TSDB_TOPIC_FNAME_LEN, _OVER)
×
UNCOV
2016
      int32_t len = strlen(topic) + 1;
×
NEW
2017
      TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pTopics, topic, len, topic, TSDB_TOPIC_FNAME_LEN), &lino, _OVER);
×
2018
    }
2019
  }
2020

2021
  if (sver >= 3) {
2,740,224✔
2022
    int32_t numOfReadTbs = 0;
2,740,224✔
2023
    int32_t numOfWriteTbs = 0;
2,740,224✔
2024
    int32_t numOfAlterTbs = 0;
2,740,224✔
2025
    int32_t numOfReadViews = 0;
2,740,224✔
2026
    int32_t numOfWriteViews = 0;
2,740,224✔
2027
    int32_t numOfAlterViews = 0;
2,740,224✔
2028
    int32_t numOfUseDbs = 0;
2,740,224✔
2029
    SDB_GET_INT32(pRaw, dataPos, &numOfReadTbs, _OVER)
2,740,224✔
2030
    SDB_GET_INT32(pRaw, dataPos, &numOfWriteTbs, _OVER)
2,740,224✔
2031
    if (sver >= 6) {
2,740,224✔
2032
      SDB_GET_INT32(pRaw, dataPos, &numOfAlterTbs, _OVER)
2,740,224✔
2033
      SDB_GET_INT32(pRaw, dataPos, &numOfReadViews, _OVER)
2,740,224✔
2034
      SDB_GET_INT32(pRaw, dataPos, &numOfWriteViews, _OVER)
2,740,224✔
2035
      SDB_GET_INT32(pRaw, dataPos, &numOfAlterViews, _OVER)
2,740,224✔
2036
    }
2037
    SDB_GET_INT32(pRaw, dataPos, &numOfUseDbs, _OVER)
2,740,224✔
2038

2039
    if (numOfReadTbs > 0) {
2,740,224✔
NEW
2040
      pUser->legacyPrivs->pReadTbs =
×
NEW
2041
          taosHashInit(numOfReadTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
NEW
2042
      if (pUser->legacyPrivs->pReadTbs == NULL) {
×
UNCOV
2043
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2044
      }
2045
    }
2046
    if (numOfWriteTbs > 0) {
2,740,224✔
NEW
2047
      pUser->legacyPrivs->pWriteTbs =
×
NEW
2048
          taosHashInit(numOfWriteTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
NEW
2049
      if (pUser->legacyPrivs->pWriteTbs == NULL) {
×
UNCOV
2050
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2051
      }
2052
    }
2053
    if (numOfAlterTbs > 0) {
2,740,224✔
NEW
2054
      pUser->legacyPrivs->pAlterTbs =
×
NEW
2055
          taosHashInit(numOfAlterTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
NEW
2056
      if (pUser->legacyPrivs->pAlterTbs == NULL) {
×
NEW
2057
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2058
      }
2059
    }
2060
    if (numOfReadViews > 0) {
2,740,224✔
NEW
2061
      pUser->legacyPrivs->pReadViews =
×
NEW
2062
          taosHashInit(numOfReadViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
NEW
2063
      if (pUser->legacyPrivs->pReadViews == NULL) {
×
NEW
2064
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2065
      }
2066
    }
2067
    if (numOfWriteViews > 0) {
2,740,224✔
NEW
2068
      pUser->legacyPrivs->pWriteViews =
×
NEW
2069
          taosHashInit(numOfWriteViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
NEW
2070
      if (pUser->legacyPrivs->pWriteViews == NULL) {
×
NEW
2071
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2072
      }
2073
    }
2074
    if (numOfAlterViews > 0) {
2,740,224✔
NEW
2075
      pUser->legacyPrivs->pAlterViews =
×
NEW
2076
          taosHashInit(numOfAlterViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
NEW
2077
      if (pUser->legacyPrivs->pAlterViews == NULL) {
×
NEW
2078
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2079
      }
2080
    }
2081
    if (numOfUseDbs > 0) {
2,740,224✔
NEW
2082
      pUser->legacyPrivs->pUseDbs =
×
NEW
2083
          taosHashInit(numOfUseDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
NEW
2084
      if (pUser->legacyPrivs->pUseDbs == NULL) {
×
NEW
2085
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2086
      }
2087
    }
2088

2089
    for (int32_t i = 0; i < numOfReadTbs; ++i) {
2,740,224✔
UNCOV
2090
      int32_t keyLen = 0;
×
UNCOV
2091
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
2092

UNCOV
2093
      TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
UNCOV
2094
      if (key == NULL) {
×
UNCOV
2095
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2096
      }
UNCOV
2097
      (void)memset(key, 0, keyLen);
×
UNCOV
2098
      SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
2099

UNCOV
2100
      int32_t valuelen = 0;
×
UNCOV
2101
      SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
UNCOV
2102
      TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
UNCOV
2103
      if (value == NULL) {
×
UNCOV
2104
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2105
      }
UNCOV
2106
      (void)memset(value, 0, valuelen);
×
UNCOV
2107
      SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
2108

NEW
2109
      TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pReadTbs, key, keyLen, value, valuelen), &lino, _OVER);
×
2110
    }
2111

2112
    for (int32_t i = 0; i < numOfWriteTbs; ++i) {
2,740,224✔
UNCOV
2113
      int32_t keyLen = 0;
×
UNCOV
2114
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
2115

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

UNCOV
2123
      int32_t valuelen = 0;
×
UNCOV
2124
      SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
UNCOV
2125
      TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
UNCOV
2126
      if (value == NULL) {
×
UNCOV
2127
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2128
      }
UNCOV
2129
      (void)memset(value, 0, valuelen);
×
UNCOV
2130
      SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
2131

NEW
2132
      TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pWriteTbs, key, keyLen, value, valuelen), &lino, _OVER);
×
2133
    }
2134

2135
    if (sver >= 6) {
2,740,224✔
2136
      for (int32_t i = 0; i < numOfAlterTbs; ++i) {
2,740,224✔
UNCOV
2137
        int32_t keyLen = 0;
×
UNCOV
2138
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
2139

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

UNCOV
2147
        int32_t valuelen = 0;
×
UNCOV
2148
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
UNCOV
2149
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
UNCOV
2150
        if (value == NULL) {
×
UNCOV
2151
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2152
        }
UNCOV
2153
        (void)memset(value, 0, valuelen);
×
UNCOV
2154
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
2155

NEW
2156
        TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pAlterTbs, key, keyLen, value, valuelen), &lino, _OVER);
×
2157
      }
2158

2159
      for (int32_t i = 0; i < numOfReadViews; ++i) {
2,740,224✔
UNCOV
2160
        int32_t keyLen = 0;
×
UNCOV
2161
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
2162

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

UNCOV
2170
        int32_t valuelen = 0;
×
UNCOV
2171
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
UNCOV
2172
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
UNCOV
2173
        if (value == NULL) {
×
UNCOV
2174
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2175
        }
UNCOV
2176
        (void)memset(value, 0, valuelen);
×
UNCOV
2177
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
2178

NEW
2179
        TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pReadViews, key, keyLen, value, valuelen), &lino, _OVER);
×
2180
      }
2181

2182
      for (int32_t i = 0; i < numOfWriteViews; ++i) {
2,740,224✔
UNCOV
2183
        int32_t keyLen = 0;
×
UNCOV
2184
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
2185

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

UNCOV
2193
        int32_t valuelen = 0;
×
UNCOV
2194
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
UNCOV
2195
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
UNCOV
2196
        if (value == NULL) {
×
UNCOV
2197
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2198
        }
UNCOV
2199
        (void)memset(value, 0, valuelen);
×
UNCOV
2200
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
2201

NEW
2202
        TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pWriteViews, key, keyLen, value, valuelen), &lino, _OVER);
×
2203
      }
2204

2205
      for (int32_t i = 0; i < numOfAlterViews; ++i) {
2,740,224✔
UNCOV
2206
        int32_t keyLen = 0;
×
UNCOV
2207
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
2208

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

UNCOV
2216
        int32_t valuelen = 0;
×
UNCOV
2217
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
UNCOV
2218
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
UNCOV
2219
        if (value == NULL) {
×
UNCOV
2220
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2221
        }
UNCOV
2222
        (void)memset(value, 0, valuelen);
×
UNCOV
2223
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
2224

NEW
2225
        TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pAlterViews, key, keyLen, value, valuelen), &lino, _OVER);
×
2226
      }
2227
    }
2228

2229
    for (int32_t i = 0; i < numOfUseDbs; ++i) {
2,740,224✔
UNCOV
2230
      int32_t keyLen = 0;
×
UNCOV
2231
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
2232

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

2240
      int32_t ref = 0;
×
2241
      SDB_GET_INT32(pRaw, dataPos, &ref, _OVER);
×
2242

NEW
2243
      TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pUseDbs, key, keyLen, &ref, sizeof(ref)), &lino, _OVER);
×
2244
    }
2245
  }
2246
  // decoder white list
2247
  if (sver >= USER_VER_SUPPORT_WHITELIST) {
2,740,224✔
2248
    if (sver < USER_VER_SUPPORT_WHITELIT_DUAL_STACK) {
2,740,224✔
UNCOV
2249
      int32_t len = 0;
×
UNCOV
2250
      SDB_GET_INT32(pRaw, dataPos, &len, _OVER);
×
2251

UNCOV
2252
      TAOS_MEMORY_REALLOC(key, len);
×
UNCOV
2253
      if (key == NULL) {
×
UNCOV
2254
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2255
      }
UNCOV
2256
      SDB_GET_BINARY(pRaw, dataPos, key, len, _OVER);
×
2257

2258
      SIpWhiteList *pIpWhiteList = NULL;
×
UNCOV
2259
      TAOS_CHECK_GOTO(createIpWhiteListFromOldVer(key, len, &pIpWhiteList), &lino, _OVER);
×
2260

UNCOV
2261
      SDB_GET_INT64(pRaw, dataPos, &pUser->ipWhiteListVer, _OVER);
×
2262

UNCOV
2263
      code = cvtIpWhiteListToDual(pIpWhiteList, &pUser->pIpWhiteListDual);
×
UNCOV
2264
      if (code != 0) {
×
UNCOV
2265
        taosMemoryFreeClear(pIpWhiteList);
×
2266
      }
2267
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2268

UNCOV
2269
      taosMemoryFreeClear(pIpWhiteList);
×
2270

2271
    } else if (sver >= USER_VER_SUPPORT_WHITELIT_DUAL_STACK) {
2,740,224✔
2272
      int32_t len = 0;
2,740,224✔
2273
      SDB_GET_INT32(pRaw, dataPos, &len, _OVER);
2,740,224✔
2274

2275
      TAOS_MEMORY_REALLOC(key, len);
2,740,224✔
2276
      if (key == NULL) {
2,740,224✔
2277
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2278
      }
2279
      SDB_GET_BINARY(pRaw, dataPos, key, len, _OVER);
2,740,224✔
2280

2281
      TAOS_CHECK_GOTO(createIpWhiteList(key, len, &pUser->pIpWhiteListDual, sver >= USER_VER_SUPPORT_ADVANCED_SECURITY),
2,740,224✔
2282
                      &lino, _OVER);
2283
      SDB_GET_INT64(pRaw, dataPos, &pUser->ipWhiteListVer, _OVER);
2,740,224✔
2284
    }
2285
  }
2286

2287
  if (pUser->pIpWhiteListDual == NULL) {
2,740,224✔
2288
    TAOS_CHECK_GOTO(createDefaultIpWhiteList(&pUser->pIpWhiteListDual), &lino, _OVER);
×
2289
    pUser->ipWhiteListVer = taosGetTimestampMs();
×
2290
  }
2291

2292
  SDB_GET_INT8(pRaw, dataPos, &pUser->passEncryptAlgorithm, _OVER);
2,740,224✔
2293

2294
  if (sver < USER_VER_SUPPORT_ADVANCED_SECURITY) {
2,740,224✔
UNCOV
2295
    memset(pUser->totpsecret, 0, sizeof(pUser->totpsecret));
×
UNCOV
2296
    pUser->changePass = 2;
×
UNCOV
2297
    pUser->sessionPerUser = pUser->superUser ? -1 : TSDB_USER_SESSION_PER_USER_DEFAULT;
×
UNCOV
2298
    pUser->connectTime = TSDB_USER_CONNECT_TIME_DEFAULT;
×
2299
    pUser->connectIdleTime = TSDB_USER_CONNECT_IDLE_TIME_DEFAULT;
×
UNCOV
2300
    pUser->callPerSession = pUser->superUser ? -1 : TSDB_USER_CALL_PER_SESSION_DEFAULT;
×
UNCOV
2301
    pUser->vnodePerCall = pUser->superUser ? -1 : TSDB_USER_VNODE_PER_CALL_DEFAULT;
×
UNCOV
2302
    pUser->failedLoginAttempts = pUser->superUser ? -1 : TSDB_USER_FAILED_LOGIN_ATTEMPTS_DEFAULT;
×
UNCOV
2303
    pUser->passwordLifeTime = TSDB_USER_PASSWORD_LIFE_TIME_DEFAULT;
×
UNCOV
2304
    pUser->passwordReuseTime = TSDB_USER_PASSWORD_REUSE_TIME_DEFAULT;
×
UNCOV
2305
    pUser->passwordReuseMax = TSDB_USER_PASSWORD_REUSE_MAX_DEFAULT;
×
UNCOV
2306
    pUser->passwordLockTime = TSDB_USER_PASSWORD_LOCK_TIME_DEFAULT;
×
UNCOV
2307
    pUser->passwordGraceTime = pUser->superUser ? -1 : TSDB_USER_PASSWORD_GRACE_TIME_DEFAULT;
×
UNCOV
2308
    pUser->inactiveAccountTime = pUser->superUser ? -1 : TSDB_USER_INACTIVE_ACCOUNT_TIME_DEFAULT;
×
UNCOV
2309
    pUser->allowTokenNum = pUser->superUser ? -1 : TSDB_USER_ALLOW_TOKEN_NUM_DEFAULT;
×
UNCOV
2310
    pUser->tokenNum = 0;
×
UNCOV
2311
    pUser->pTimeWhiteList = taosMemCalloc(1, sizeof(SDateTimeWhiteList));
×
2312
    if (pUser->pTimeWhiteList == NULL) {
×
2313
    }
2314
  } else {
2315
    SDB_GET_BINARY(pRaw, dataPos, pUser->totpsecret, sizeof(pUser->totpsecret), _OVER);
2,740,224✔
2316
    SDB_GET_INT8(pRaw, dataPos, &pUser->changePass, _OVER);
2,740,224✔
2317
    SDB_GET_INT32(pRaw, dataPos, &pUser->sessionPerUser, _OVER);
2,740,224✔
2318
    SDB_GET_INT32(pRaw, dataPos, &pUser->connectTime, _OVER);
2,740,224✔
2319
    SDB_GET_INT32(pRaw, dataPos, &pUser->connectIdleTime, _OVER);
2,740,224✔
2320
    SDB_GET_INT32(pRaw, dataPos, &pUser->callPerSession, _OVER);
2,740,224✔
2321
    SDB_GET_INT32(pRaw, dataPos, &pUser->vnodePerCall, _OVER);
2,740,224✔
2322
    SDB_GET_INT32(pRaw, dataPos, &pUser->failedLoginAttempts, _OVER);
2,740,224✔
2323
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordLifeTime, _OVER);
2,740,224✔
2324
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordReuseTime, _OVER);
2,740,224✔
2325
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordReuseMax, _OVER);
2,740,224✔
2326
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordLockTime, _OVER);
2,740,224✔
2327
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordGraceTime, _OVER);
2,740,224✔
2328
    SDB_GET_INT32(pRaw, dataPos, &pUser->inactiveAccountTime, _OVER);
2,740,224✔
2329
    SDB_GET_INT32(pRaw, dataPos, &pUser->allowTokenNum, _OVER);
2,740,224✔
2330
    SDB_GET_INT32(pRaw, dataPos, &pUser->tokenNum, _OVER);
2,740,224✔
2331

2332
    int32_t num = 0;
2,740,224✔
2333
    SDB_GET_INT32(pRaw, dataPos, &num, _OVER);
2,740,224✔
2334
    pUser->pTimeWhiteList = taosMemCalloc(1, sizeof(SDateTimeWhiteList) + num * sizeof(SDateTimeWhiteListItem));
2,740,224✔
2335
    if (pUser->pTimeWhiteList == NULL) {
2,740,224✔
2336
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2337
    }
2338

2339
    pUser->pTimeWhiteList->num = num;
2,740,224✔
2340
    for (int32_t i = 0; i < num; i++) {
2,743,040✔
2341
      SDateTimeWhiteListItem *range = &pUser->pTimeWhiteList->ranges[i];
2,816✔
2342
      SDB_GET_BOOL(pRaw, dataPos, &range->absolute, _OVER);
2,816✔
2343
      SDB_GET_BOOL(pRaw, dataPos, &range->neg, _OVER);
2,816✔
2344
      SDB_GET_INT64(pRaw, dataPos, &range->start, _OVER);
2,816✔
2345
      SDB_GET_INT32(pRaw, dataPos, &range->duration, _OVER);
2,816✔
2346
    }
2347

2348
    int32_t extLen = 0;
2,740,224✔
2349
    SDB_GET_INT32(pRaw, dataPos, &extLen, _OVER);
2,740,224✔
2350
    TAOS_MEMORY_REALLOC(key, extLen);
2,740,224✔
2351
    if (key == NULL) {
2,740,224✔
2352
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2353
    }
2354
    SDB_GET_BINARY(pRaw, dataPos, key, extLen, _OVER);
2,740,224✔
2355
    TAOS_CHECK_GOTO(tDeserializeUserObjExt(key, extLen, pUser), &lino, _OVER);
2,740,224✔
2356
  }
2357

2358
#ifndef TD_ENTERPRISE
2359
  // community users cannot modify these fields, and the default values may prevent
2360
  // the user from logging in, so we set them to different values here.
2361
  pUser->sessionPerUser = -1;
2362
  pUser->connectTime = -1;
2363
  pUser->connectIdleTime = -1;
2364
  pUser->callPerSession = -1;
2365
  pUser->vnodePerCall = -1;
2366
  pUser->failedLoginAttempts = -1;
2367
  pUser->passwordLifeTime = -1;
2368
  pUser->passwordReuseTime = 0;
2369
  pUser->passwordReuseMax = 0;
2370
  pUser->passwordLockTime = -1;
2371
  pUser->passwordGraceTime = -1;
2372
  pUser->inactiveAccountTime = -1;
2373
  pUser->allowTokenNum = -1;
2374
  pUser->tokenNum = 0;
2375
#endif  // TD_ENTERPRISE
2376

2377
  SDB_GET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
2,740,224✔
2378

2379
  taosInitRWLatch(&pUser->lock);
2,740,224✔
2380
  dropOldPasswords(pUser);
2,740,224✔
2381
_OVER:
2,740,224✔
2382
  taosMemoryFree(key);
2,740,224✔
2383
  taosMemoryFree(value);
2,740,224✔
2384
  if (code < 0) {
2,740,224✔
UNCOV
2385
    terrno = code;
×
2386
    mError("user:%s, failed to decode at line %d from raw:%p since %s", pUser == NULL ? "null" : pUser->user, lino,
×
2387
           pRaw, tstrerror(code));
2388
    if (pUser != NULL) {
×
2389
      mndUserFreeObj(pUser);
×
2390
    }
UNCOV
2391
    taosMemoryFreeClear(pRow);
×
UNCOV
2392
    return NULL;
×
2393
  }
2394

2395
  mTrace("user:%s, decode from raw:%p, row:%p", pUser->user, pRaw, pUser);
2,740,224✔
2396
  return pRow;
2,740,224✔
2397
}
2398

2399
static int32_t mndUserActionInsert(SSdb *pSdb, SUserObj *pUser) {
472,608✔
2400
  mTrace("user:%s, perform insert action, row:%p", pUser->user, pUser);
472,608✔
2401

2402
  SAcctObj *pAcct = sdbAcquire(pSdb, SDB_ACCT, pUser->acct);
472,608✔
2403
  if (pAcct == NULL) {
472,608✔
UNCOV
2404
    terrno = TSDB_CODE_MND_ACCT_NOT_EXIST;
×
UNCOV
2405
    mError("user:%s, failed to perform insert action since %s", pUser->user, terrstr());
×
UNCOV
2406
    TAOS_RETURN(terrno);
×
2407
  }
2408
  pUser->acctId = pAcct->acctId;
472,608✔
2409
  sdbRelease(pSdb, pAcct);
472,608✔
2410

2411
  return 0;
472,608✔
2412
}
2413

2414
int32_t mndDupTableHash(SHashObj *pOld, SHashObj **ppNew) {
×
2415
  int32_t code = 0;
×
2416
  *ppNew =
×
2417
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
UNCOV
2418
  if (*ppNew == NULL) {
×
UNCOV
2419
    TAOS_RETURN(terrno);
×
2420
  }
2421

2422
  char *tb = taosHashIterate(pOld, NULL);
×
2423
  while (tb != NULL) {
×
2424
    size_t keyLen = 0;
×
UNCOV
2425
    char  *key = taosHashGetKey(tb, &keyLen);
×
2426

UNCOV
2427
    int32_t valueLen = strlen(tb) + 1;
×
2428
    if ((code = taosHashPut(*ppNew, key, keyLen, tb, valueLen)) != 0) {
×
2429
      taosHashCancelIterate(pOld, tb);
×
2430
      taosHashCleanup(*ppNew);
×
2431
      TAOS_RETURN(code);
×
2432
    }
UNCOV
2433
    tb = taosHashIterate(pOld, tb);
×
2434
  }
2435

2436
  TAOS_RETURN(code);
×
2437
}
2438

2439
int32_t mndDupRoleHash(SHashObj *pOld, SHashObj **ppNew) {
2,187,758✔
2440
  if (!(*ppNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true,
2,187,758✔
2441
                              HASH_ENTRY_LOCK))) {
2442
    TAOS_RETURN(terrno);
×
2443
  }
2444

2445
  int32_t  code = 0;
2,187,758✔
2446
  uint8_t *flag = NULL;
2,187,758✔
2447
  while ((flag = taosHashIterate(pOld, flag))) {
6,571,089✔
2448
    size_t keyLen = 0;
4,383,331✔
2449
    char  *key = taosHashGetKey(flag, &keyLen);
4,383,331✔
2450

2451
    if ((code = taosHashPut(*ppNew, key, keyLen, flag, sizeof(*flag))) != 0) {
4,383,331✔
2452
      taosHashCancelIterate(pOld, flag);
×
UNCOV
2453
      taosHashCleanup(*ppNew);
×
2454
      TAOS_RETURN(code);
×
2455
    }
2456
  }
2457

2458
  TAOS_RETURN(code);
2,187,758✔
2459
}
2460

2461
int32_t mndMergePrivObjHash(SHashObj *pOld, SHashObj **ppNew) {
79,491,097✔
2462
  if (!(*ppNew)) return mndDupPrivObjHash(pOld, ppNew);
79,491,097✔
2463

2464
  int32_t           code = 0, lino = 0;
79,491,097✔
2465
  SHashObj         *pNew = *ppNew;
79,491,097✔
2466
  SPrivObjPolicies *policies = NULL;
79,491,097✔
2467
  while ((policies = taosHashIterate(pOld, policies))) {
716,445,772✔
2468
    size_t klen = 0;
636,957,572✔
2469
    char  *key = taosHashGetKey(policies, &klen);
636,957,572✔
2470
    size_t vlen = taosHashGetValueSize(policies);
636,957,259✔
2471

2472
    SPrivObjPolicies *pNewPolicies = taosHashGet(pNew, key, klen);
636,956,901✔
2473
    if (pNewPolicies) {
636,957,563✔
2474
      size_t newVlen = taosHashGetValueSize(pNewPolicies);
421,207,026✔
2475
      if (newVlen > 0 && vlen > 0) {
421,207,026✔
2476
        privAddSet(&pNewPolicies->policy, &policies->policy);
421,206,755✔
2477
      }
2478
      continue;
421,204,190✔
2479
    }
2480

2481
    if ((code = taosHashPut(pNew, key, klen, vlen ? policies : NULL, vlen)) != 0) {
215,750,537✔
2482
      taosHashCancelIterate(pOld, policies);
×
2483
      taosHashCleanup(pNew);
×
UNCOV
2484
      *ppNew = NULL;
×
2485
      TAOS_RETURN(code);
×
2486
    }
2487
  }
2488

2489
  TAOS_RETURN(code);
79,491,097✔
2490
}
2491

2492
/**
2493
 * 1. Prefer to use SPrivTblPolicies from user object(the updateUs of policy in user object is INT64_MAX)
2494
 * 2. If two or more roles have SPrivTblPolicies, the policy with latest update time take effect.
2495
 */
2496
int32_t mndMergePrivTblHash(SHashObj *pOld, SHashObj **ppNew, bool updateWithLatest) {
238,472,636✔
2497
  if (!(*ppNew)) return mndDupPrivTblHash(pOld, ppNew, false);
238,472,636✔
2498

2499
  int32_t           code = 0, lino = 0;
238,472,636✔
2500
  SHashObj         *pNew = *ppNew;
238,472,636✔
2501
  SPrivTblPolicies *policies = NULL;
238,472,785✔
2502
  while ((policies = taosHashIterate(pOld, policies))) {
238,472,785✔
UNCOV
2503
    size_t klen = 0;
×
UNCOV
2504
    char  *key = taosHashGetKey(policies, &klen);
×
2505
    size_t vlen = taosHashGetValueSize(policies);
×
2506

UNCOV
2507
    SPrivTblPolicies *pNewPolicies = taosHashGet(pNew, key, klen);
×
2508
    if (pNewPolicies) {
×
2509
      size_t newVlen = taosHashGetValueSize(pNewPolicies);
×
2510
      if (newVlen > 0 && vlen > 0) {
×
UNCOV
2511
        TAOS_CHECK_EXIT(privTblPoliciesMerge(pNewPolicies, policies, updateWithLatest));
×
2512
      }
2513
      continue;
×
2514
    }
2515

2516
    SPrivTblPolicies tmpPolicies = {0};
×
2517
    if (vlen > 0) {
×
2518
      if ((code = privTblPoliciesMerge(&tmpPolicies, policies, updateWithLatest))) {
×
2519
        privTblPoliciesFree(&tmpPolicies);
UNCOV
2520
        goto _exit;
×
2521
      }
2522
    }
UNCOV
2523
    if ((code = taosHashPut(pNew, key, klen, vlen ? &tmpPolicies : NULL, vlen)) != 0) {
×
2524
      privTblPoliciesFree(&tmpPolicies);
UNCOV
2525
      taosHashCancelIterate(pOld, policies);
×
UNCOV
2526
      taosHashCleanup(pNew);
×
UNCOV
2527
      *ppNew = NULL;
×
2528
      TAOS_RETURN(code);
×
2529
    }
2530
  }
2531

2532
_exit:
238,473,287✔
2533
  TAOS_RETURN(code);
238,473,287✔
2534
}
2535

2536
int32_t mndDupKVHash(SHashObj *pOld, SHashObj **ppNew) {
29,030,543✔
2537
  if (!(*ppNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true,
29,030,543✔
2538
                              HASH_ENTRY_LOCK))) {
NEW
2539
    TAOS_RETURN(terrno);
×
2540
  }
2541
  int32_t code = 0;
29,030,543✔
2542
  void   *val = NULL;
29,030,543✔
2543
  while ((val = taosHashIterate(pOld, val))) {
91,056,143✔
2544
    size_t klen = 0;
62,025,600✔
2545
    char  *key = taosHashGetKey(val, &klen);
62,025,600✔
2546
    size_t vlen = taosHashGetValueSize(val);
62,025,600✔
2547
    if ((code = taosHashPut(*ppNew, key, klen, vlen > 0 ? val : NULL, vlen)) != 0) {
62,025,600✔
NEW
2548
      taosHashCancelIterate(pOld, val);
×
NEW
2549
      taosHashCleanup(*ppNew);
×
NEW
2550
      TAOS_RETURN(code);
×
2551
    }
2552
  }
2553

2554
  TAOS_RETURN(code);
29,030,543✔
2555
}
2556

2557
int32_t mndDupPrivObjHash(SHashObj *pOld, SHashObj **ppNew) {
29,031,475✔
2558
  if (!(*ppNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true,
29,031,475✔
2559
                              HASH_ENTRY_LOCK))) {
2560
    TAOS_RETURN(terrno);
×
2561
  }
2562
  int32_t           code = 0;
29,031,735✔
2563
  SPrivObjPolicies *policies = NULL;
29,031,735✔
2564
  while ((policies = taosHashIterate(pOld, policies))) {
32,105,762✔
2565
    size_t klen = 0;
3,074,027✔
2566
    char  *key = taosHashGetKey(policies, &klen);
3,074,027✔
2567
    size_t vlen = taosHashGetValueSize(policies);
3,074,027✔
2568

2569
    if ((code = taosHashPut(*ppNew, key, klen, vlen > 0 ? policies : NULL, vlen)) != 0) {
3,074,027✔
UNCOV
2570
      taosHashCancelIterate(pOld, policies);
×
UNCOV
2571
      taosHashCleanup(*ppNew);
×
UNCOV
2572
      TAOS_RETURN(code);
×
2573
    }
2574
  }
2575

2576
  TAOS_RETURN(code);
29,031,735✔
2577
}
2578

2579
int32_t mndDupPrivTblHash(SHashObj *pOld, SHashObj **ppNew, bool setUpdateTimeMax) {
89,281,522✔
2580
  if (!(*ppNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true,
89,281,522✔
2581
                              HASH_ENTRY_LOCK))) {
UNCOV
2582
    TAOS_RETURN(terrno);
×
2583
  }
2584
  taosHashSetFreeFp(*ppNew, privTblPoliciesFree);
89,281,771✔
2585

2586
  int32_t           code = 0, lino = 0;
89,281,522✔
2587
  SPrivTblPolicies *policies = NULL, *pTmpPolicies = NULL;
89,281,522✔
2588
  SPrivTblPolicies  tmpPolicies = {0};
89,281,522✔
2589
  while ((policies = taosHashIterate(pOld, policies))) {
89,336,624✔
2590
    size_t klen = 0;
55,102✔
2591
    char  *key = taosHashGetKey(policies, &klen);
55,102✔
2592
    size_t vlen = taosHashGetValueSize(policies);
55,102✔
2593
    memset(&tmpPolicies, 0, sizeof(tmpPolicies));
55,102✔
2594
    pTmpPolicies = &tmpPolicies;
55,102✔
2595
    if (vlen > 0) {
55,102✔
2596
      TAOS_CHECK_EXIT(privTblPoliciesAdd(&tmpPolicies, policies, true, setUpdateTimeMax));
55,102✔
2597
    }
2598
    TAOS_CHECK_EXIT(taosHashPut(*ppNew, key, klen, vlen > 0 ? &tmpPolicies : NULL, vlen));
55,102✔
2599
    pTmpPolicies = NULL;
55,102✔
2600
  }
2601

2602
_exit:
89,281,522✔
2603
  if (code != 0) {
89,281,522✔
2604
    if (!pTmpPolicies) {
×
2605
      privTblPoliciesFree(pTmpPolicies);
2606
      pTmpPolicies = NULL;
×
2607
    }
2608
    if (policies) taosHashCancelIterate(pOld, policies);
×
UNCOV
2609
    taosHashCleanup(*ppNew);
×
2610
    *ppNew = NULL;
×
2611
  }
2612
  TAOS_RETURN(code);
89,281,522✔
2613
}
2614

2615
int32_t mndUserDupObj(SUserObj *pUser, SUserObj *pNew) {
2,185,374✔
2616
  int32_t code = 0;
2,185,374✔
2617
  (void)memcpy(pNew, pUser, sizeof(SUserObj));
2,185,374✔
2618
  pNew->authVersion++;
2,185,374✔
2619
  pNew->updateTime = taosGetTimestampMs();
2,185,374✔
2620
  taosInitRWLatch(&pNew->lock);
2,185,374✔
2621

2622
  pNew->passwords = NULL;
2,185,374✔
2623
  pNew->pIpWhiteListDual = NULL;
2,185,374✔
2624
  pNew->passwords = NULL;
2,185,374✔
2625
  pNew->objPrivs = NULL;
2,185,374✔
2626
  pNew->selectTbs = NULL;
2,185,374✔
2627
  pNew->insertTbs = NULL;
2,185,374✔
2628
  pNew->updateTbs = NULL;
2,185,374✔
2629
  pNew->deleteTbs = NULL;
2,185,374✔
2630
  pNew->ownedDbs = NULL;
2,185,374✔
2631
  pNew->pTimeWhiteList = NULL;
2,185,374✔
2632
  pNew->roles = NULL;
2,185,374✔
2633
  pNew->legacyPrivs = NULL;
2,185,374✔
2634

2635
  taosRLockLatch(&pUser->lock);
2,185,374✔
2636
  pNew->passwords = taosMemoryCalloc(pUser->numOfPasswords, sizeof(SUserPassword));
2,185,374✔
2637
  if (pNew->passwords == NULL) {
2,185,374✔
UNCOV
2638
    code = TSDB_CODE_OUT_OF_MEMORY;
×
UNCOV
2639
    goto _OVER;
×
2640
  }
2641
  (void)memcpy(pNew->passwords, pUser->passwords, pUser->numOfPasswords * sizeof(SUserPassword));
2,185,374✔
2642
  TAOS_CHECK_GOTO(mndDupKVHash(pUser->ownedDbs, &pNew->ownedDbs), NULL, _OVER);
2,185,374✔
2643
  TAOS_CHECK_GOTO(mndDupPrivObjHash(pUser->objPrivs, &pNew->objPrivs), NULL, _OVER);
2,185,374✔
2644
  TAOS_CHECK_GOTO(mndDupPrivTblHash(pUser->selectTbs, &pNew->selectTbs, false), NULL, _OVER);
2,185,374✔
2645
  TAOS_CHECK_GOTO(mndDupPrivTblHash(pUser->insertTbs, &pNew->insertTbs, false), NULL, _OVER);
2,185,374✔
2646
  TAOS_CHECK_GOTO(mndDupPrivTblHash(pUser->updateTbs, &pNew->updateTbs, false), NULL, _OVER);
2,185,374✔
2647
  TAOS_CHECK_GOTO(mndDupPrivTblHash(pUser->deleteTbs, &pNew->deleteTbs, false), NULL, _OVER);
2,185,374✔
2648
  TAOS_CHECK_GOTO(mndDupRoleHash(pUser->roles, &pNew->roles), NULL, _OVER);
2,185,374✔
2649
  if(pUser->legacyPrivs) {
2,185,374✔
NEW
2650
    pNew->legacyPrivs = taosMemCalloc(1, sizeof(SPrivHashObjSet));
×
NEW
2651
    if (pNew->legacyPrivs == NULL) {
×
NEW
2652
      code = TSDB_CODE_OUT_OF_MEMORY;
×
NEW
2653
      goto _OVER;
×
2654
    }
NEW
2655
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pReadDbs, &pNew->legacyPrivs->pReadDbs), NULL, _OVER);
×
NEW
2656
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pWriteDbs, &pNew->legacyPrivs->pWriteDbs), NULL, _OVER);
×
NEW
2657
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pReadTbs, &pNew->legacyPrivs->pReadTbs), NULL, _OVER);
×
NEW
2658
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pWriteTbs, &pNew->legacyPrivs->pWriteTbs), NULL, _OVER);
×
NEW
2659
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pTopics, &pNew->legacyPrivs->pTopics), NULL, _OVER);
×
NEW
2660
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pAlterTbs, &pNew->legacyPrivs->pAlterTbs), NULL, _OVER);
×
NEW
2661
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pReadViews, &pNew->legacyPrivs->pReadViews), NULL, _OVER);
×
NEW
2662
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pWriteViews, &pNew->legacyPrivs->pWriteViews), NULL, _OVER);
×
NEW
2663
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pAlterViews, &pNew->legacyPrivs->pAlterViews), NULL, _OVER);
×
NEW
2664
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pUseDbs, &pNew->legacyPrivs->pUseDbs), NULL, _OVER);
×
2665
  }
2666
  pNew->pIpWhiteListDual = cloneIpWhiteList(pUser->pIpWhiteListDual);
2,185,374✔
2667
  if (pNew->pIpWhiteListDual == NULL) {
2,185,374✔
2668
    code = TSDB_CODE_OUT_OF_MEMORY;
×
2669
    goto _OVER;
×
2670
  }
2671

2672
  pNew->pTimeWhiteList = cloneDateTimeWhiteList(pUser->pTimeWhiteList);
2,185,374✔
2673
  if (pNew->pTimeWhiteList == NULL) {
2,185,374✔
2674
    code = TSDB_CODE_OUT_OF_MEMORY;
×
2675
    goto _OVER;
×
2676
  }
2677

2678
_OVER:
2,185,374✔
2679
  taosRUnLockLatch(&pUser->lock);
2,185,374✔
2680
  if (code == 0) {
2,185,374✔
2681
    dropOldPasswords(pNew);
2,185,374✔
2682
  }
2683
  TAOS_RETURN(code);
2,185,374✔
2684
}
2685

2686
void mndUserFreeObj(SUserObj *pUser) {
5,454,812✔
2687
  taosHashCleanup(pUser->ownedDbs);
5,454,812✔
2688
  taosHashCleanup(pUser->objPrivs);
5,454,812✔
2689
  taosHashCleanup(pUser->selectTbs);
5,454,812✔
2690
  taosHashCleanup(pUser->insertTbs);
5,454,812✔
2691
  taosHashCleanup(pUser->updateTbs);
5,454,812✔
2692
  taosHashCleanup(pUser->deleteTbs);
5,454,812✔
2693
  taosHashCleanup(pUser->roles);
5,454,812✔
2694
  taosMemoryFreeClear(pUser->passwords);
5,454,812✔
2695
  taosMemoryFreeClear(pUser->pIpWhiteListDual);
5,454,812✔
2696
  taosMemoryFreeClear(pUser->pTimeWhiteList);
5,454,812✔
2697
  pUser->ownedDbs = NULL;
5,454,812✔
2698
  pUser->objPrivs = NULL;
5,454,812✔
2699
  pUser->selectTbs = NULL;
5,454,812✔
2700
  pUser->insertTbs = NULL;
5,454,812✔
2701
  pUser->updateTbs = NULL;
5,454,812✔
2702
  pUser->deleteTbs = NULL;
5,454,812✔
2703
  pUser->roles = NULL;
5,454,812✔
2704
  if (pUser->legacyPrivs) {
5,454,812✔
NEW
2705
    taosHashCleanup(pUser->legacyPrivs->pReadDbs);
×
NEW
2706
    taosHashCleanup(pUser->legacyPrivs->pWriteDbs);
×
NEW
2707
    taosHashCleanup(pUser->legacyPrivs->pReadTbs);
×
NEW
2708
    taosHashCleanup(pUser->legacyPrivs->pWriteTbs);
×
NEW
2709
    taosHashCleanup(pUser->legacyPrivs->pTopics);
×
NEW
2710
    taosHashCleanup(pUser->legacyPrivs->pAlterTbs);
×
NEW
2711
    taosHashCleanup(pUser->legacyPrivs->pReadViews);
×
NEW
2712
    taosHashCleanup(pUser->legacyPrivs->pWriteViews);
×
NEW
2713
    taosHashCleanup(pUser->legacyPrivs->pAlterViews);
×
NEW
2714
    taosHashCleanup(pUser->legacyPrivs->pUseDbs);
×
NEW
2715
    taosMemoryFreeClear(pUser->legacyPrivs);
×
2716
  }
2717
}
5,454,812✔
2718

2719
static int32_t mndUserActionDelete(SSdb *pSdb, SUserObj *pUser) {
2,740,181✔
2720
  mTrace("user:%s, perform delete action, row:%p", pUser->user, pUser);
2,740,181✔
2721
  mndUserFreeObj(pUser);
2,740,181✔
2722
  return 0;
2,740,181✔
2723
}
2724

2725
static int32_t mndUserActionUpdate(SSdb *pSdb, SUserObj *pOld, SUserObj *pNew) {
2,234,181✔
2726
  mTrace("user:%s, perform update action, old row:%p new row:%p", pOld->user, pOld, pNew);
2,234,181✔
2727
  taosWLockLatch(&pOld->lock);
2,234,181✔
2728
  pOld->updateTime = pNew->updateTime;
2,234,181✔
2729
  pOld->authVersion = pNew->authVersion;
2,234,181✔
2730
  pOld->passVersion = pNew->passVersion;
2,234,181✔
2731
  pOld->sysInfo = pNew->sysInfo;
2,234,181✔
2732
  pOld->enable = pNew->enable;
2,234,181✔
2733
  pOld->flag = pNew->flag;
2,234,181✔
2734
  pOld->changePass = pNew->changePass;
2,234,181✔
2735
  pOld->uid = pNew->uid;
2,234,181✔
2736

2737
  pOld->sessionPerUser = pNew->sessionPerUser;
2,234,181✔
2738
  pOld->connectTime = pNew->connectTime;
2,234,181✔
2739
  pOld->connectIdleTime = pNew->connectIdleTime;
2,234,181✔
2740
  pOld->callPerSession = pNew->callPerSession;
2,234,181✔
2741
  pOld->vnodePerCall = pNew->vnodePerCall;
2,234,181✔
2742
  pOld->failedLoginAttempts = pNew->failedLoginAttempts;
2,234,181✔
2743
  pOld->passwordLifeTime = pNew->passwordLifeTime;
2,234,181✔
2744
  pOld->passwordReuseTime = pNew->passwordReuseTime;
2,234,181✔
2745
  pOld->passwordReuseMax = pNew->passwordReuseMax;
2,234,181✔
2746
  pOld->passwordLockTime = pNew->passwordLockTime;
2,234,181✔
2747
  pOld->passwordGraceTime = pNew->passwordGraceTime;
2,234,181✔
2748
  pOld->inactiveAccountTime = pNew->inactiveAccountTime;
2,234,181✔
2749
  pOld->allowTokenNum = pNew->allowTokenNum;
2,234,181✔
2750
  pOld->tokenNum = pNew->tokenNum;
2,234,181✔
2751

2752
  pOld->numOfPasswords = pNew->numOfPasswords;
2,234,181✔
2753
  TSWAP(pOld->passwords, pNew->passwords);
2,234,181✔
2754
  (void)memcpy(pOld->salt, pNew->salt, sizeof(pOld->salt));
2,234,181✔
2755
  (void)memcpy(pOld->totpsecret, pNew->totpsecret, sizeof(pOld->totpsecret));
2,234,181✔
2756
  pOld->sysPrivs = pNew->sysPrivs;
2,234,181✔
2757
  TSWAP(pOld->ownedDbs, pNew->ownedDbs);
2,234,181✔
2758
  TSWAP(pOld->objPrivs, pNew->objPrivs);
2,234,181✔
2759
  TSWAP(pOld->selectTbs, pNew->selectTbs);
2,234,181✔
2760
  TSWAP(pOld->insertTbs, pNew->insertTbs);
2,234,181✔
2761
  TSWAP(pOld->updateTbs, pNew->updateTbs);
2,234,181✔
2762
  TSWAP(pOld->deleteTbs, pNew->deleteTbs);
2,234,181✔
2763
  TSWAP(pOld->roles, pNew->roles);
2,234,181✔
2764
  TSWAP(pOld->legacyPrivs, pNew->legacyPrivs);
2,234,181✔
2765

2766
  TSWAP(pOld->pIpWhiteListDual, pNew->pIpWhiteListDual);
2,234,181✔
2767
  pOld->ipWhiteListVer = pNew->ipWhiteListVer;
2,234,181✔
2768
  TSWAP(pOld->pTimeWhiteList, pNew->pTimeWhiteList);
2,234,181✔
2769
  pOld->timeWhiteListVer = pNew->timeWhiteListVer;
2,234,181✔
2770
  pOld->passEncryptAlgorithm = pNew->passEncryptAlgorithm;
2,234,181✔
2771

2772
  taosWUnLockLatch(&pOld->lock);
2,234,181✔
2773

2774
  return 0;
2,234,181✔
2775
}
2776

2777
int32_t mndAcquireUser(SMnode *pMnode, const char *userName, SUserObj **ppUser) {
95,991,307✔
2778
  int32_t code = 0;
95,991,307✔
2779
  SSdb   *pSdb = pMnode->pSdb;
95,991,307✔
2780

2781
  *ppUser = sdbAcquire(pSdb, SDB_USER, userName);
95,991,905✔
2782
  if (*ppUser == NULL) {
95,991,484✔
2783
    if (terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
76,377✔
2784
      code = TSDB_CODE_MND_USER_NOT_EXIST;
76,377✔
2785
    } else {
2786
      code = TSDB_CODE_MND_USER_NOT_AVAILABLE;
×
2787
    }
2788
  }
2789
  TAOS_RETURN(code);
95,991,484✔
2790
}
2791

2792
void mndReleaseUser(SMnode *pMnode, SUserObj *pUser) {
142,870,081✔
2793
  SSdb *pSdb = pMnode->pSdb;
142,870,081✔
2794
  sdbRelease(pSdb, pUser);
142,871,197✔
2795
}
142,871,513✔
2796

2797
int32_t mndAcquireUserById(SMnode *pMnode, int64_t userId, SUserObj **ppUser) {
×
2798
  void     *pIter = NULL;
×
2799
  SUserObj *pObj;
×
UNCOV
2800
  SSdb     *pSdb = pMnode->pSdb;
×
UNCOV
2801
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pObj))) {
×
2802
    if (pObj->uid == userId) {
×
2803
      return mndAcquireUser(pMnode, pObj->user, ppUser);
×
2804
    }
2805
  }
UNCOV
2806
  return 0;
×
2807
}
2808

2809
int32_t mndBuildUidNamesHash(SMnode *pMnode, SSHashObj **ppHash) {
479,606✔
2810
  int32_t    code = 0;
479,606✔
2811
  void      *pIter = NULL;
479,606✔
2812
  SUserObj  *pObj;
479,606✔
2813
  SSHashObj *pHash = NULL;
479,606✔
2814

2815
  int32_t nUser = sdbGetSize(pMnode->pSdb, SDB_USER);
479,606✔
2816

2817
  pHash = tSimpleHashInit(nUser, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT));
479,606✔
2818
  if (pHash == NULL) {
479,606✔
UNCOV
2819
    TAOS_RETURN(terrno);
×
2820
  }
2821

2822
  while ((pIter = sdbFetch(pMnode->pSdb, SDB_USER, pIter, (void **)&pObj))) {
1,136,022✔
2823
    code = tSimpleHashPut(pHash, &pObj->uid, sizeof(pObj->uid), pObj->name, strlen(pObj->name) + 1);
656,416✔
2824
    if (code != 0) {
656,416✔
UNCOV
2825
      sdbRelease(pMnode->pSdb, pObj);
×
UNCOV
2826
      sdbCancelFetch(pMnode->pSdb, pIter);
×
UNCOV
2827
      tSimpleHashCleanup(pHash);
×
UNCOV
2828
      TAOS_RETURN(code);
×
2829
    }
2830
    sdbRelease(pMnode->pSdb, pObj);
656,416✔
2831
  }
2832

2833
  *ppHash = pHash;
479,606✔
2834
  TAOS_RETURN(code);
479,606✔
2835
}
2836

2837
int32_t mndEncryptPass(char *pass, const char *salt, int8_t *algo) {
86,073✔
2838
  int32_t code = 0;
86,073✔
2839
  if (tsMetaKey[0] == '\0') {
86,073✔
2840
    return 0;
86,009✔
2841
  }
2842

2843
  if (salt[0] != 0) {
64✔
2844
    char passAndSalt[TSDB_PASSWORD_LEN - 1 + TSDB_PASSWORD_SALT_LEN];
64✔
2845
    (void)memcpy(passAndSalt, pass, TSDB_PASSWORD_LEN - 1);
64✔
2846
    (void)memcpy(passAndSalt + TSDB_PASSWORD_LEN - 1, salt, TSDB_PASSWORD_SALT_LEN);
64✔
2847
    taosEncryptPass_c((uint8_t *)passAndSalt, sizeof(passAndSalt), pass);
2848
  }
2849

2850
  unsigned char packetData[TSDB_PASSWORD_LEN] = {0};
64✔
2851
  SCryptOpts    opts = {0};
64✔
2852
  opts.len = TSDB_PASSWORD_LEN;
64✔
2853
  opts.source = pass;
64✔
2854
  opts.result = packetData;
64✔
2855
  opts.unitLen = TSDB_PASSWORD_LEN;
64✔
2856
  tstrncpy(opts.key, tsDataKey, ENCRYPT_KEY_LEN + 1);
64✔
2857
  int newLen = Builtin_CBC_Encrypt(&opts);
64✔
2858
  if (newLen <= 0) return terrno;
64✔
2859

2860
  memcpy(pass, packetData, newLen);
64✔
2861
  if (algo != NULL) {
64✔
2862
    *algo = DND_CA_SM4;
64✔
2863
  }
2864

2865
  return 0;
64✔
2866
}
2867

2868
static void generateSalt(char *salt, size_t len) {
66,596✔
2869
  const char *set = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
66,596✔
2870
  int32_t     setLen = 62;
66,596✔
2871
  for (int32_t i = 0; i < len - 1; ++i) {
2,131,072✔
2872
    salt[i] = set[taosSafeRand() % setLen];
2,064,476✔
2873
  }
2874
  salt[len - 1] = 0;
66,596✔
2875
}
66,596✔
2876

2877
static int32_t addDefaultIpToTable(SHashObj *pUniqueTab) {
990✔
2878
  int32_t code = 0;
990✔
2879
  int32_t lino = 0;
990✔
2880
  int32_t dummy = 0;
990✔
2881

2882
  SIpRange ipv4 = {0}, ipv6 = {0};
990✔
2883
  code = createDefaultIp4Range(&ipv4);
990✔
2884
  TSDB_CHECK_CODE(code, lino, _error);
990✔
2885

2886
  code = taosHashPut(pUniqueTab, &ipv4, sizeof(ipv4), &dummy, sizeof(dummy));
990✔
2887
  TSDB_CHECK_CODE(code, lino, _error);
990✔
2888

2889
  code = createDefaultIp6Range(&ipv6);
990✔
2890
  TSDB_CHECK_CODE(code, lino, _error);
990✔
2891

2892
  code = taosHashPut(pUniqueTab, &ipv6, sizeof(ipv6), &dummy, sizeof(dummy));
990✔
2893
  TSDB_CHECK_CODE(code, lino, _error);
990✔
2894
    
2895
_error:
990✔
2896
  if (code != 0) {
990✔
UNCOV
2897
    mError("failed to add default ip range to table since %s", tstrerror(code));
×
2898
  }
2899
  return code;
990✔
2900
}
2901

2902
static int32_t mndCreateUser(SMnode *pMnode, char *acct, SCreateUserReq *pCreate, SRpcMsg *pReq) {
66,430✔
2903
  int32_t  code = 0;
66,430✔
2904
  int32_t  lino = 0;
66,430✔
2905
  SUserObj userObj = {0};
66,430✔
2906

2907
  userObj.passwords = taosMemoryCalloc(1, sizeof(SUserPassword));
66,430✔
2908
  if (userObj.passwords == NULL) {
66,430✔
UNCOV
2909
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2910
  }
2911
  userObj.numOfPasswords = 1;
66,430✔
2912

2913
  if (pCreate->isImport == 1) {
66,430✔
UNCOV
2914
    memset(userObj.salt, 0, sizeof(userObj.salt));
×
2915
    memcpy(userObj.passwords[0].pass, pCreate->pass, TSDB_PASSWORD_LEN);
×
2916
  } else {
2917
    generateSalt(userObj.salt, sizeof(userObj.salt));
66,430✔
2918
    taosEncryptPass_c((uint8_t *)pCreate->pass, strlen(pCreate->pass), userObj.passwords[0].pass);
66,430✔
2919
    userObj.passwords[0].pass[sizeof(userObj.passwords[0].pass) - 1] = 0;
66,430✔
2920
    TAOS_CHECK_GOTO(mndEncryptPass(userObj.passwords[0].pass, userObj.salt, &userObj.passEncryptAlgorithm), &lino,
66,430✔
2921
                    _OVER);
2922
  }
2923
  userObj.passwords[0].setTime = taosGetTimestampSec();
66,430✔
2924

2925
  tstrncpy(userObj.user, pCreate->user, TSDB_USER_LEN);
66,430✔
2926
  tstrncpy(userObj.acct, acct, TSDB_USER_LEN);
66,430✔
2927
  if (pCreate->totpseed[0] != 0) {
66,430✔
UNCOV
2928
    int len = taosGenerateTotpSecret(pCreate->totpseed, 0, userObj.totpsecret, sizeof(userObj.totpsecret));
×
UNCOV
2929
    if (len < 0) {
×
UNCOV
2930
      TAOS_CHECK_GOTO(TSDB_CODE_PAR_INVALID_OPTION_VALUE, &lino, _OVER);
×
2931
    }
2932
  }
2933

2934
  userObj.createdTime = taosGetTimestampMs();
66,430✔
2935
  userObj.updateTime = userObj.createdTime;
66,430✔
2936
  userObj.superUser = 0;  // pCreate->superUser;
66,430✔
2937
  userObj.sysInfo = pCreate->sysInfo;
66,430✔
2938
  userObj.enable = pCreate->enable;
66,430✔
2939
  userObj.createdb = pCreate->createDb;
66,430✔
2940
  userObj.uid = mndGenerateUid(userObj.user, strlen(userObj.user));
66,430✔
2941

2942
  if (userObj.createdb == 1) {
66,430✔
2943
    privAddType(&userObj.sysPrivs, PRIV_DB_CREATE);
2944
  }
2945

2946
#ifdef TD_ENTERPRISE
2947

2948
  userObj.changePass = pCreate->changepass;
66,430✔
2949
  userObj.sessionPerUser = pCreate->sessionPerUser;
66,430✔
2950
  userObj.connectTime = pCreate->connectTime;
66,430✔
2951
  userObj.connectIdleTime = pCreate->connectIdleTime;
66,430✔
2952
  userObj.callPerSession = pCreate->callPerSession;
66,430✔
2953
  userObj.vnodePerCall = pCreate->vnodePerCall;
66,430✔
2954
  userObj.failedLoginAttempts = pCreate->failedLoginAttempts;
66,430✔
2955
  userObj.passwordLifeTime = pCreate->passwordLifeTime;
66,430✔
2956
  userObj.passwordReuseTime = pCreate->passwordReuseTime;
66,430✔
2957
  userObj.passwordReuseMax = pCreate->passwordReuseMax;
66,430✔
2958
  userObj.passwordLockTime = pCreate->passwordLockTime;
66,430✔
2959
  userObj.passwordGraceTime = pCreate->passwordGraceTime;
66,430✔
2960
  userObj.inactiveAccountTime = pCreate->inactiveAccountTime;
66,430✔
2961
  userObj.allowTokenNum = pCreate->allowTokenNum;
66,430✔
2962
  userObj.tokenNum = 0;
66,430✔
2963

2964
  if (pCreate->numIpRanges == 0) {
66,430✔
2965
    TAOS_CHECK_GOTO(createDefaultIpWhiteList(&userObj.pIpWhiteListDual), &lino, _OVER);
65,056✔
2966
  } else {
2967
    SHashObj *pUniqueTab = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
1,374✔
2968
    if (pUniqueTab == NULL) {
1,374✔
UNCOV
2969
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2970
    }
2971
    
2972
    bool hasPositive = false;
1,374✔
2973
    for (int i = 0; i < pCreate->numIpRanges; i++) {
3,444✔
2974
      SIpRange range = {0};
2,070✔
2975
      copyIpRange(&range, pCreate->pIpDualRanges + i);
2,070✔
2976
      hasPositive = hasPositive || !range.neg;
2,070✔
2977
      int32_t dummy = 0;
2,070✔
2978
      if ((code = taosHashPut(pUniqueTab, &range, sizeof(range), &dummy, sizeof(dummy))) != 0) {
2,070✔
UNCOV
2979
        taosHashCleanup(pUniqueTab);
×
UNCOV
2980
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2981
      }
2982
    }
2983

2984
    // add local ip if there is any positive range
2985
    if (hasPositive) {
1,374✔
2986
      code = addDefaultIpToTable(pUniqueTab);
990✔
2987
      if (code != 0) {
990✔
UNCOV
2988
        taosHashCleanup(pUniqueTab);
×
2989
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2990
      }
2991
    }
2992

2993
    if (taosHashGetSize(pUniqueTab) > MND_MAX_USER_IP_RANGE) {
1,374✔
UNCOV
2994
      taosHashCleanup(pUniqueTab);
×
UNCOV
2995
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_IP_RANGE, &lino, _OVER);
×
2996
    }
2997

2998
    int32_t           numOfRanges = taosHashGetSize(pUniqueTab);
1,374✔
2999
    SIpWhiteListDual *p = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + numOfRanges * sizeof(SIpRange));
1,374✔
3000
    if (p == NULL) {
1,374✔
UNCOV
3001
      taosHashCleanup(pUniqueTab);
×
UNCOV
3002
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3003
    }
3004

3005
    void *pIter = taosHashIterate(pUniqueTab, NULL);
1,374✔
3006
    for (int32_t i = 0; i < numOfRanges; i++) {
5,102✔
3007
      size_t    len = 0;
3,728✔
3008
      SIpRange *key = taosHashGetKey(pIter, &len);
3,728✔
3009
      memcpy(&p->pIpRanges[i], key, sizeof(SIpRange));
3,728✔
3010
      pIter = taosHashIterate(pUniqueTab, pIter);
3,728✔
3011
    }
3012

3013
    taosHashCleanup(pUniqueTab);
1,374✔
3014
    p->num = numOfRanges;
1,374✔
3015
    sortIpWhiteList(p);
1,374✔
3016
    userObj.pIpWhiteListDual = p;
1,374✔
3017
  }
3018

3019
  if (pCreate->numTimeRanges == 0) {
66,430✔
3020
    userObj.pTimeWhiteList = (SDateTimeWhiteList *)taosMemoryCalloc(1, sizeof(SDateTimeWhiteList));
64,766✔
3021
    if (userObj.pTimeWhiteList == NULL) {
64,766✔
UNCOV
3022
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3023
    }
3024
  } else {
3025
    SHashObj *pUniqueTab = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
1,664✔
3026
    if (pUniqueTab == NULL) {
1,664✔
UNCOV
3027
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3028
    }
3029

3030
    for (int i = 0; i < pCreate->numTimeRanges; i++) {
3,712✔
3031
      SDateTimeRange        *src = pCreate->pTimeRanges + i;
2,048✔
3032
      SDateTimeWhiteListItem range = {0};
2,048✔
3033
      DateTimeRangeToWhiteListItem(&range, src);
2,048✔
3034

3035
      // no need to add expired range
3036
      if (isDateTimeWhiteListItemExpired(&range)) {
2,048✔
3037
        continue;
256✔
3038
      }
3039

3040
      int32_t dummy = 0;
1,792✔
3041
      if ((code = taosHashPut(pUniqueTab, &range, sizeof(range), &dummy, sizeof(dummy))) != 0) {
1,792✔
3042
        taosHashCleanup(pUniqueTab);
×
3043
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3044
      }
3045
    }
3046

3047
    if (taosHashGetSize(pUniqueTab) > MND_MAX_USER_TIME_RANGE) {
1,664✔
UNCOV
3048
      taosHashCleanup(pUniqueTab);
×
3049
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_TIME_RANGE, &lino, _OVER);
×
3050
    }
3051

3052
    int32_t             numOfRanges = taosHashGetSize(pUniqueTab);
1,664✔
3053
    SDateTimeWhiteList *p =
3,328✔
3054
        taosMemoryCalloc(1, sizeof(SDateTimeWhiteList) + numOfRanges * sizeof(SDateTimeWhiteListItem));
1,664✔
3055
    if (p == NULL) {
1,664✔
3056
      taosHashCleanup(pUniqueTab);
×
3057
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3058
    }
3059

3060
    void *pIter = taosHashIterate(pUniqueTab, NULL);
1,664✔
3061
    for (int32_t i = 0; i < numOfRanges; i++) {
3,456✔
3062
      size_t                  len = 0;
1,792✔
3063
      SDateTimeWhiteListItem *key = taosHashGetKey(pIter, &len);
1,792✔
3064
      memcpy(p->ranges + i, key, sizeof(SDateTimeWhiteListItem));
1,792✔
3065
      pIter = taosHashIterate(pUniqueTab, pIter);
1,792✔
3066
    }
3067

3068
    taosHashCleanup(pUniqueTab);
1,664✔
3069
    p->num = numOfRanges;
1,664✔
3070
    sortTimeWhiteList(p);
1,664✔
3071
    userObj.pTimeWhiteList = p;
1,664✔
3072
  }
3073

3074
  userObj.ipWhiteListVer = taosGetTimestampMs();
66,430✔
3075
  userObj.timeWhiteListVer = userObj.ipWhiteListVer;
66,430✔
3076
  
3077

3078
#else  // TD_ENTERPRISE
3079

3080
  userObj.changePass = 1;
3081
  userObj.sessionPerUser = -1;
3082
  userObj.connectTime = -1;
3083
  userObj.connectIdleTime = -1;
3084
  userObj.callPerSession = -1;
3085
  userObj.vnodePerCall = -1;
3086
  userObj.failedLoginAttempts = -1;
3087
  userObj.passwordLifeTime = -1;
3088
  userObj.passwordReuseTime = 0;
3089
  userObj.passwordReuseMax = 0;
3090
  userObj.passwordLockTime = -1;
3091
  userObj.passwordGraceTime = -1;
3092
  userObj.inactiveAccountTime = -1;
3093
  userObj.allowTokenNum = -1;
3094
  userObj.tokenNum = 0;
3095

3096
  TAOS_CHECK_GOTO(createDefaultIpWhiteList(&userObj.pIpWhiteListDual), &lino, _OVER);
3097
  userObj.pTimeWhiteList = (SDateTimeWhiteList *)taosMemoryCalloc(1, sizeof(SDateTimeWhiteList));
3098
  if (userObj.pTimeWhiteList == NULL) {
3099
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
3100
  }
3101

3102
  userObj.ipWhiteListVer = 0;
3103
  userObj.timeWhiteListVer = 0;
3104

3105
#endif  // TD_ENTERPRISE
3106

3107
  userObj.roles = taosHashInit(1, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
66,430✔
3108
  if (userObj.roles == NULL) {
66,430✔
UNCOV
3109
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3110
  }
3111

3112
  uint8_t flag = 0x01;
66,430✔
3113
  if ((code = taosHashPut(userObj.roles, TSDB_ROLE_DEFAULT, strlen(TSDB_ROLE_DEFAULT) + 1, &flag, sizeof(flag))) != 0) {
66,430✔
UNCOV
3114
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3115
  }
3116

3117
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "create-user");
66,430✔
3118
  if (pTrans == NULL) {
66,430✔
UNCOV
3119
    mError("user:%s, failed to create since %s", pCreate->user, terrstr());
×
UNCOV
3120
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3121
  }
3122
  mInfo("trans:%d, used to create user:%s", pTrans->id, pCreate->user);
66,430✔
3123

3124
  SSdbRaw *pCommitRaw = mndUserActionEncode(&userObj);
66,430✔
3125
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
66,430✔
UNCOV
3126
    mError("trans:%d, failed to commit redo log since %s", pTrans->id, terrstr());
×
UNCOV
3127
    mndTransDrop(pTrans);
×
UNCOV
3128
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3129
  }
3130
  TAOS_CHECK_GOTO(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY), &lino, _OVER);
66,430✔
3131

3132
  if (mndTransPrepare(pMnode, pTrans) != 0) {
66,430✔
UNCOV
3133
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
UNCOV
3134
    mndTransDrop(pTrans);
×
UNCOV
3135
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3136
  }
3137

3138
  if ((code = userCacheUpdateWhiteList(pMnode, &userObj)) != 0) {
66,430✔
UNCOV
3139
    mndTransDrop(pTrans);
×
UNCOV
3140
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3141
  }
3142

3143
  if (taosHashGet(userObj.roles, TSDB_ROLE_SYSAUDIT_LOG, strlen(TSDB_ROLE_SYSAUDIT_LOG) + 1)) {
66,430✔
NEW
3144
    (void)mndResetAuditLogUser(pMnode, userObj.user, true);
×
3145
  }
3146

3147
  mndTransDrop(pTrans);
66,430✔
3148

3149
_OVER:
66,430✔
3150
  mndUserFreeObj(&userObj);
66,430✔
3151
  TAOS_RETURN(code);
66,430✔
3152
}
3153

3154
static int32_t mndCheckPasswordFmt(const char *pwd) {
86,371✔
3155
  if (tsEnableStrongPassword == 0) {
86,371✔
3156
    for (char c = *pwd; c != 0; c = *(++pwd)) {
45,484✔
3157
      if (c == ' ' || c == '\'' || c == '\"' || c == '`' || c == '\\') {
44,986✔
UNCOV
3158
        return TSDB_CODE_MND_INVALID_PASS_FORMAT;
×
3159
      }
3160
    }
3161
    return 0;
498✔
3162
  }
3163

3164
  int32_t len = strlen(pwd);
85,873✔
3165
  if (len < TSDB_PASSWORD_MIN_LEN) {
85,873✔
UNCOV
3166
    return TSDB_CODE_PAR_PASSWD_TOO_SHORT_OR_EMPTY;
×
3167
  }
3168

3169
  if (len > TSDB_PASSWORD_MAX_LEN) {
85,873✔
UNCOV
3170
    return TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG;
×
3171
  }
3172

3173
  if (taosIsComplexString(pwd)) {
85,873✔
3174
    return 0;
85,873✔
3175
  }
3176

UNCOV
3177
  return TSDB_CODE_MND_INVALID_PASS_FORMAT;
×
3178
}
3179

UNCOV
3180
static int32_t mndCheckTotpSeedFmt(const char *seed) {
×
UNCOV
3181
  int32_t len = strlen(seed);
×
3182
  if (len < TSDB_USER_TOTPSEED_MIN_LEN) {
×
3183
    return TSDB_CODE_PAR_OPTION_VALUE_TOO_SHORT;
×
3184
  }
3185

3186
  if (taosIsComplexString(seed)) {
×
3187
    return 0;
×
3188
  }
3189

UNCOV
3190
  return TSDB_CODE_PAR_INVALID_OPTION_VALUE;
×
3191
}
3192

UNCOV
3193
static int32_t mndProcessGetUserDateTimeWhiteListReq(SRpcMsg *pReq) {
×
NEW
3194
  SMnode                *pMnode = pReq->info.node;
×
NEW
3195
  int32_t                code = 0;
×
NEW
3196
  int32_t                lino = 0;
×
NEW
3197
  int32_t                contLen = 0;
×
NEW
3198
  void                  *pRsp = NULL;
×
NEW
3199
  SUserObj              *pUser = NULL;
×
NEW
3200
  SGetUserWhiteListReq   wlReq = {0};
×
3201
  SUserDateTimeWhiteList wlRsp = {0};
×
3202

UNCOV
3203
  if (tDeserializeSGetUserWhiteListReq(pReq->pCont, pReq->contLen, &wlReq) != 0) {
×
UNCOV
3204
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
3205
  }
UNCOV
3206
  mTrace("user: %s, start to get date time whitelist", wlReq.user);
×
3207

3208
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, wlReq.user, &pUser), &lino, _OVER);
×
3209
  TAOS_CHECK_GOTO(mndSetUserDateTimeWhiteListRsp(pMnode, pUser, &wlRsp), &lino, _OVER);
×
3210

3211
  contLen = tSerializeSUserDateTimeWhiteList(NULL, 0, &wlRsp);
×
UNCOV
3212
  if (contLen < 0) {
×
UNCOV
3213
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3214
  }
UNCOV
3215
  pRsp = rpcMallocCont(contLen);
×
UNCOV
3216
  if (pRsp == NULL) {
×
UNCOV
3217
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3218
  }
3219

UNCOV
3220
  contLen = tSerializeSUserDateTimeWhiteList(pRsp, contLen, &wlRsp);
×
UNCOV
3221
  if (contLen < 0) {
×
UNCOV
3222
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3223
  }
3224

UNCOV
3225
_OVER:
×
UNCOV
3226
  mndReleaseUser(pMnode, pUser);
×
UNCOV
3227
  tFreeSUserDateTimeWhiteList(&wlRsp);
×
UNCOV
3228
  if (code < 0) {
×
UNCOV
3229
    mError("user:%s, failed to get whitelist at line %d since %s", wlReq.user, lino, tstrerror(code));
×
UNCOV
3230
    rpcFreeCont(pRsp);
×
UNCOV
3231
    pRsp = NULL;
×
UNCOV
3232
    contLen = 0;
×
3233
  }
UNCOV
3234
  pReq->code = code;
×
UNCOV
3235
  pReq->info.rsp = pRsp;
×
UNCOV
3236
  pReq->info.rspLen = contLen;
×
3237

UNCOV
3238
  TAOS_RETURN(code);
×
3239
  return 0;
3240
}
3241

3242
static int32_t buildRetrieveDateTimeWhiteListRsp(SRetrieveDateTimeWhiteListRsp *pRsp) {
442✔
3243
  (void)taosThreadRwlockRdlock(&userCache.rw);
442✔
3244

3245
  int32_t count = taosHashGetSize(userCache.users);
442✔
3246
  pRsp->pUsers = taosMemoryCalloc(count, sizeof(SUserDateTimeWhiteList));
442✔
3247
  if (pRsp->pUsers == NULL) {
442✔
UNCOV
3248
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
UNCOV
3249
    TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
3250
  }
3251

3252
  count = 0;
442✔
3253
  void *pIter = taosHashIterate(userCache.users, NULL);
442✔
3254
  while (pIter) {
884✔
3255
    SDateTimeWhiteList *wl = (*(SCachedUserInfo **)pIter)->wlTime;
442✔
3256
    if (wl == NULL || wl->num <= 0) {
442✔
3257
      pIter = taosHashIterate(userCache.users, pIter);
442✔
3258
      continue;
442✔
3259
    }
3260

UNCOV
3261
    SUserDateTimeWhiteList *pUser = &pRsp->pUsers[count];
×
UNCOV
3262
    pUser->ver = userCache.verTime;
×
3263

UNCOV
3264
    size_t klen;
×
UNCOV
3265
    char  *key = taosHashGetKey(pIter, &klen);
×
UNCOV
3266
    (void)memcpy(pUser->user, key, klen);
×
3267

UNCOV
3268
    pUser->numWhiteLists = wl->num;
×
UNCOV
3269
    pUser->pWhiteLists = taosMemoryCalloc(wl->num, sizeof(SDateTimeWhiteListItem));
×
UNCOV
3270
    if (pUser->pWhiteLists == NULL) {
×
UNCOV
3271
      (void)taosThreadRwlockUnlock(&userCache.rw);
×
UNCOV
3272
      TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
3273
    }
3274

UNCOV
3275
    (void)memcpy(pUser->pWhiteLists, wl->ranges, wl->num * sizeof(SDateTimeWhiteListItem));
×
UNCOV
3276
    count++;
×
UNCOV
3277
    pIter = taosHashIterate(userCache.users, pIter);
×
3278
  }
3279

3280
  pRsp->numOfUser = count;
442✔
3281
  pRsp->ver = userCache.verTime;
442✔
3282
  (void)taosThreadRwlockUnlock(&userCache.rw);
442✔
3283
  TAOS_RETURN(0);
442✔
3284
}
3285

3286
static int32_t mndProcessRetrieveDateTimeWhiteListReq(SRpcMsg *pReq) {
442✔
3287
  int32_t                       code = 0;
442✔
3288
  int32_t                       lino = 0;
442✔
3289
  int32_t                       len = 0;
442✔
3290
  void                         *pRsp = NULL;
442✔
3291
  SRetrieveDateTimeWhiteListRsp wlRsp = {0};
442✔
3292

3293
  // impl later
3294
  SRetrieveWhiteListReq req = {0};
442✔
3295
  if (tDeserializeRetrieveWhiteListReq(pReq->pCont, pReq->contLen, &req) != 0) {
442✔
UNCOV
3296
    code = TSDB_CODE_INVALID_MSG;
×
UNCOV
3297
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3298
  }
3299

3300
  TAOS_CHECK_GOTO(buildRetrieveDateTimeWhiteListRsp(&wlRsp), &lino, _OVER);
442✔
3301

3302
  len = tSerializeSRetrieveDateTimeWhiteListRsp(NULL, 0, &wlRsp);
442✔
3303
  if (len < 0) {
442✔
UNCOV
3304
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
3305
  }
3306

3307
  pRsp = rpcMallocCont(len);
442✔
3308
  if (!pRsp) {
442✔
3309
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3310
  }
3311
  len = tSerializeSRetrieveDateTimeWhiteListRsp(pRsp, len, &wlRsp);
442✔
3312
  if (len < 0) {
442✔
UNCOV
3313
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
3314
  }
3315

3316
_OVER:
442✔
3317
  if (code < 0) {
442✔
UNCOV
3318
    mError("failed to process retrieve ip white request at line %d since %s", lino, tstrerror(code));
×
UNCOV
3319
    rpcFreeCont(pRsp);
×
UNCOV
3320
    pRsp = NULL;
×
UNCOV
3321
    len = 0;
×
3322
  }
3323
  pReq->code = code;
442✔
3324
  pReq->info.rsp = pRsp;
442✔
3325
  pReq->info.rspLen = len;
442✔
3326

3327
  tFreeSRetrieveDateTimeWhiteListRsp(&wlRsp);
442✔
3328
  TAOS_RETURN(code);
442✔
3329
}
3330

3331
static int32_t mndProcessCreateUserReq(SRpcMsg *pReq) {
66,728✔
3332
  SMnode        *pMnode = pReq->info.node;
66,728✔
3333
  int32_t        code = 0;
66,728✔
3334
  int32_t        lino = 0;
66,728✔
3335
  SRoleObj      *pRole = NULL;
66,728✔
3336
  SUserObj      *pUser = NULL;
66,728✔
3337
  SUserObj      *pOperUser = NULL;
66,728✔
3338
  SCreateUserReq createReq = {0};
66,728✔
3339
  int64_t        tss = taosGetTimestampMs();
66,728✔
3340

3341
  if (tDeserializeSCreateUserReq(pReq->pCont, pReq->contLen, &createReq) != 0) {
66,728✔
UNCOV
3342
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
3343
  }
3344

3345
  mInfo("user:%s, start to create, createdb:%d, is_import:%d", createReq.user, createReq.createDb, createReq.isImport);
66,728✔
3346

3347
#ifndef TD_ENTERPRISE
3348
  if (createReq.isImport == 1) {
3349
    TAOS_CHECK_GOTO(TSDB_CODE_OPS_NOT_SUPPORT, &lino, _OVER);  // enterprise feature
3350
  }
3351
#endif
3352
  code = mndAcquireUser(pMnode, RPC_MSG_USER(pReq), &pOperUser);
66,728✔
3353
  if (pOperUser == NULL) {
66,728✔
UNCOV
3354
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_USER_FROM_CONN, &lino, _OVER);
×
3355
  }
3356

3357
  if (createReq.isImport != 1) {
66,728✔
3358
    // TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, RPC_MSG_USER(pReq), MND_OPER_CREATE_USER), &lino, _OVER);
3359
    TAOS_CHECK_GOTO(mndCheckSysObjPrivilege(pMnode, pOperUser, RPC_MSG_TOKEN(pReq), PRIV_USER_CREATE, 0, 0, NULL, NULL),
66,728✔
3360
                    &lino, _OVER);
UNCOV
3361
  } else if (strcmp(RPC_MSG_USER(pReq), "root") != 0) {
×
UNCOV
3362
    mError("The operation is not permitted to create user:%s", RPC_MSG_USER(pReq));
×
UNCOV
3363
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_RIGHTS, &lino, _OVER);
×
3364
  }
3365

3366
  if (createReq.user[0] == 0) {
66,728✔
3367
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
3368
  }
3369

3370
  if (createReq.isImport != 1) {
66,728✔
3371
    code = mndCheckPasswordFmt(createReq.pass);
66,728✔
3372
    TAOS_CHECK_GOTO(code, &lino, _OVER);
66,728✔
3373
  }
3374

3375
  if (createReq.totpseed[0] != 0) {
66,728✔
UNCOV
3376
    code = mndCheckTotpSeedFmt(createReq.totpseed);
×
UNCOV
3377
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3378
  }
3379

3380
  code = mndAcquireUser(pMnode, createReq.user, &pUser);
66,728✔
3381
  if (pUser != NULL) {
66,728✔
3382
    TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_ALREADY_EXIST, &lino, _OVER);
298✔
3383
  }
3384

3385
  code = mndAcquireRole(pMnode, createReq.user, &pRole);
66,430✔
3386
  if (pRole != NULL) {
66,430✔
UNCOV
3387
    TAOS_CHECK_GOTO(TSDB_CODE_MND_ROLE_ALREADY_EXIST, &lino, _OVER);
×
3388
  }
3389

3390
  TAOS_CHECK_GOTO(grantCheck(TSDB_GRANT_USER), &lino, _OVER);
66,430✔
3391

3392
  if (sdbGetSize(pMnode->pSdb, SDB_USER) >= TSDB_MAX_USERS) {
66,430✔
NEW
3393
    mError("user:%s, failed to create since reach max user limit %d", createReq.user, TSDB_MAX_USERS);
×
NEW
3394
    TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USERS, &lino, _OVER);
×
3395
  }
3396

3397
  code = mndCreateUser(pMnode, pOperUser->acct, &createReq, pReq);
66,430✔
3398
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
66,430✔
3399

3400
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
66,430✔
3401
    char detail[1000] = {0};
66,430✔
3402
    (void)tsnprintf(detail, sizeof(detail), "enable:%d, superUser:%d, sysInfo:%d, password:xxx", createReq.enable,
66,430✔
3403
                    createReq.superUser, createReq.sysInfo);
66,430✔
3404
    char operation[15] = {0};
66,430✔
3405
    if (createReq.isImport == 1) {
66,430✔
UNCOV
3406
      tstrncpy(operation, "importUser", sizeof(operation));
×
3407
    } else {
3408
      tstrncpy(operation, "createUser", sizeof(operation));
66,430✔
3409
    }
3410

3411
    int64_t tse = taosGetTimestampMs();
66,430✔
3412
    double  duration = (double)(tse - tss);
66,430✔
3413
    duration = duration / 1000;
66,430✔
3414
    auditRecord(pReq, pMnode->clusterId, operation, "", createReq.user, detail, strlen(detail), duration, 0);
66,430✔
3415
  }
3416

3417
_OVER:
66,728✔
3418
  if (code == TSDB_CODE_MND_USER_ALREADY_EXIST && createReq.ignoreExists) {
66,728✔
UNCOV
3419
    code = 0;
×
3420
  } else if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
66,728✔
3421
    mError("user:%s, failed to create at line %d since %s", createReq.user, lino, tstrerror(code));
298✔
3422
  }
3423

3424
  mndReleaseRole(pMnode, pRole);
66,728✔
3425
  mndReleaseUser(pMnode, pUser);
66,728✔
3426
  mndReleaseUser(pMnode, pOperUser);
66,728✔
3427
  tFreeSCreateUserReq(&createReq);
66,728✔
3428

3429
  TAOS_RETURN(code);
66,728✔
3430
}
3431

3432
static int32_t mndProcessGetUserIpWhiteListReq(SRpcMsg *pReq) {
7,821✔
3433
  SMnode                *pMnode = pReq->info.node;
7,821✔
3434
  int32_t                code = 0;
7,821✔
3435
  int32_t                lino = 0;
7,821✔
3436
  int32_t                contLen = 0;
7,821✔
3437
  void                  *pRsp = NULL;
7,821✔
3438
  SUserObj              *pUser = NULL;
7,821✔
3439
  SGetUserWhiteListReq   wlReq = {0};
7,821✔
3440
  SGetUserIpWhiteListRsp wlRsp = {0};
7,821✔
3441

3442
  int32_t (*serialFn)(void *, int32_t, SGetUserIpWhiteListRsp *) = NULL;
7,821✔
3443
  int32_t (*setRspFn)(SMnode *pMnode, SUserObj *pUser, SGetUserIpWhiteListRsp *pRsp) = NULL;
7,821✔
3444

3445
  if (pReq->msgType == TDMT_MND_GET_USER_IP_WHITELIST_DUAL) {
7,821✔
3446
    serialFn = tSerializeSGetUserIpWhiteListDualRsp;
7,821✔
3447
    setRspFn = mndSetUserIpWhiteListDualRsp;
7,821✔
3448
  } else {
UNCOV
3449
    serialFn = tSerializeSGetUserIpWhiteListRsp;
×
UNCOV
3450
    setRspFn = mndSetUserIpWhiteListRsp;
×
3451
  }
3452
  if (tDeserializeSGetUserWhiteListReq(pReq->pCont, pReq->contLen, &wlReq) != 0) {
7,821✔
UNCOV
3453
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
3454
  }
3455
  mTrace("user: %s, start to get ip whitelist", wlReq.user);
7,821✔
3456

3457
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, wlReq.user, &pUser), &lino, _OVER);
7,821✔
3458
  TAOS_CHECK_GOTO(setRspFn(pMnode, pUser, &wlRsp), &lino, _OVER);
7,821✔
3459

3460
  contLen = serialFn(NULL, 0, &wlRsp);
7,821✔
3461
  if (contLen < 0) {
7,821✔
UNCOV
3462
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3463
  }
3464
  pRsp = rpcMallocCont(contLen);
7,821✔
3465
  if (pRsp == NULL) {
7,821✔
UNCOV
3466
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3467
  }
3468

3469
  contLen = serialFn(pRsp, contLen, &wlRsp);
7,821✔
3470
  if (contLen < 0) {
7,821✔
UNCOV
3471
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3472
  }
3473

3474
_OVER:
7,821✔
3475
  mndReleaseUser(pMnode, pUser);
7,792✔
3476
  tFreeSGetUserIpWhiteListDualRsp(&wlRsp);
7,821✔
3477
  if (code < 0) {
7,821✔
UNCOV
3478
    mError("user:%s, failed to get whitelist at line %d since %s", wlReq.user, lino, tstrerror(code));
×
UNCOV
3479
    rpcFreeCont(pRsp);
×
UNCOV
3480
    pRsp = NULL;
×
UNCOV
3481
    contLen = 0;
×
3482
  }
3483
  pReq->code = code;
7,821✔
3484
  pReq->info.rsp = pRsp;
7,821✔
3485
  pReq->info.rspLen = contLen;
7,821✔
3486

3487
  TAOS_RETURN(code);
7,821✔
3488
}
3489

3490
static int32_t buildRetrieveIpWhiteListRsp(SUpdateIpWhite *pUpdate) {
442✔
3491
  (void)taosThreadRwlockRdlock(&userCache.rw);
442✔
3492

3493
  int32_t count = taosHashGetSize(userCache.users);
442✔
3494
  pUpdate->pUserIpWhite = taosMemoryCalloc(count, sizeof(SUpdateUserIpWhite));
442✔
3495
  if (pUpdate->pUserIpWhite == NULL) {
442✔
UNCOV
3496
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
UNCOV
3497
    TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
3498
  }
3499

3500
  count = 0;
442✔
3501
  void *pIter = taosHashIterate(userCache.users, NULL);
442✔
3502
  while (pIter) {
884✔
3503
    SIpWhiteListDual *wl = (*(SCachedUserInfo **)pIter)->wlIp;
442✔
3504
    if (wl == NULL || wl->num <= 0) {
442✔
3505
      pIter = taosHashIterate(userCache.users, pIter);
×
3506
      continue;
×
3507
    }
3508

3509
    SUpdateUserIpWhite *pUser = &pUpdate->pUserIpWhite[count];
442✔
3510
    pUser->ver = userCache.verIp;
442✔
3511

3512
    size_t klen;
442✔
3513
    char  *key = taosHashGetKey(pIter, &klen);
442✔
3514
    (void)memcpy(pUser->user, key, klen);
442✔
3515

3516
    pUser->numOfRange = wl->num;
442✔
3517
    pUser->pIpRanges = taosMemoryCalloc(wl->num, sizeof(SIpRange));
442✔
3518
    if (pUser->pIpRanges == NULL) {
442✔
3519
      (void)taosThreadRwlockUnlock(&userCache.rw);
×
UNCOV
3520
      TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
3521
    }
3522

3523
    (void)memcpy(pUser->pIpRanges, wl->pIpRanges, wl->num * sizeof(SIpRange));
442✔
3524
    count++;
442✔
3525
    pIter = taosHashIterate(userCache.users, pIter);
442✔
3526
  }
3527

3528
  pUpdate->numOfUser = count;
442✔
3529
  pUpdate->ver = userCache.verIp;
442✔
3530
  (void)taosThreadRwlockUnlock(&userCache.rw);
442✔
3531
  TAOS_RETURN(0);
442✔
3532
}
3533

3534
int32_t mndProcessRetrieveIpWhiteListReq(SRpcMsg *pReq) {
442✔
3535
  int32_t        code = 0;
442✔
3536
  int32_t        lino = 0;
442✔
3537
  int32_t        len = 0;
442✔
3538
  void          *pRsp = NULL;
442✔
3539
  SUpdateIpWhite ipWhite = {0};
442✔
3540

3541
  // impl later
3542
  SRetrieveWhiteListReq req = {0};
442✔
3543
  if (tDeserializeRetrieveWhiteListReq(pReq->pCont, pReq->contLen, &req) != 0) {
442✔
UNCOV
3544
    code = TSDB_CODE_INVALID_MSG;
×
UNCOV
3545
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3546
  }
3547

3548
  int32_t (*fn)(void *, int32_t, SUpdateIpWhite *) = NULL;
442✔
3549
  if (pReq->msgType == TDMT_MND_RETRIEVE_IP_WHITELIST) {
442✔
UNCOV
3550
    fn = tSerializeSUpdateIpWhite;
×
3551
  } else if (pReq->msgType == TDMT_MND_RETRIEVE_IP_WHITELIST_DUAL) {
442✔
3552
    fn = tSerializeSUpdateIpWhiteDual;
442✔
3553
  }
3554

3555
  TAOS_CHECK_GOTO(buildRetrieveIpWhiteListRsp(&ipWhite), &lino, _OVER);
442✔
3556

3557
  len = fn(NULL, 0, &ipWhite);
442✔
3558
  if (len < 0) {
442✔
3559
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
3560
  }
3561

3562
  pRsp = rpcMallocCont(len);
442✔
3563
  if (!pRsp) {
442✔
3564
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3565
  }
3566
  len = fn(pRsp, len, &ipWhite);
442✔
3567
  if (len < 0) {
442✔
UNCOV
3568
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
3569
  }
3570

3571
_OVER:
442✔
3572
  if (code < 0) {
442✔
3573
    mError("failed to process retrieve ip white request at line %d since %s", lino, tstrerror(code));
×
3574
    rpcFreeCont(pRsp);
×
3575
    pRsp = NULL;
×
3576
    len = 0;
×
3577
  }
3578
  pReq->code = code;
442✔
3579
  pReq->info.rsp = pRsp;
442✔
3580
  pReq->info.rspLen = len;
442✔
3581

3582
  tFreeSUpdateIpWhiteReq(&ipWhite);
442✔
3583
  TAOS_RETURN(code);
442✔
3584
}
3585

3586
static int32_t mndAlterUser(SMnode *pMnode, SUserObj *pNew, SRpcMsg *pReq) {
1,051,056✔
3587
  int32_t code = 0, lino = 0;
1,051,056✔
3588
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "alter-user");
1,051,056✔
3589
  if (pTrans == NULL) {
1,051,056✔
3590
    mError("user:%s, failed to alter since %s", pNew->user, terrstr());
×
UNCOV
3591
    TAOS_RETURN(terrno);
×
3592
  }
3593
  mInfo("trans:%d, used to alter user:%s", pTrans->id, pNew->user);
1,051,056✔
3594

3595
  SSdbRaw *pCommitRaw = mndUserActionEncode(pNew);
1,051,056✔
3596
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
1,051,056✔
3597
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
3598
    mndTransDrop(pTrans);
×
3599
    TAOS_RETURN(terrno);
×
3600
  }
3601
  TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
1,051,056✔
3602

3603
  if (mndTransPrepare(pMnode, pTrans) != 0) {
1,051,056✔
3604
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
3605
    mndTransDrop(pTrans);
×
3606
    TAOS_RETURN(terrno);
×
3607
  }
3608
  if ((code = userCacheUpdateWhiteList(pMnode, pNew)) != 0) {
1,051,056✔
3609
    mndTransDrop(pTrans);
×
UNCOV
3610
    TAOS_RETURN(code);
×
3611
  }
3612
_exit:
1,051,056✔
3613
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
1,051,056✔
UNCOV
3614
    mError("user:%s, failed to alter at line %d since %s", pNew->user, lino, tstrerror(code));
×
3615
  }
3616
  mndTransDrop(pTrans);
1,051,056✔
3617
  TAOS_RETURN(code);
1,051,056✔
3618
}
3619

UNCOV
3620
static int32_t mndDupObjHash(SHashObj *pOld, int32_t dataLen, SHashObj **ppNew) {
×
UNCOV
3621
  int32_t code = 0;
×
3622

UNCOV
3623
  *ppNew =
×
UNCOV
3624
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
3625
  if (*ppNew == NULL) {
×
3626
    code = terrno ? terrno : TSDB_CODE_OUT_OF_MEMORY;
×
UNCOV
3627
    TAOS_RETURN(code);
×
3628
  }
3629

UNCOV
3630
  char *db = taosHashIterate(pOld, NULL);
×
UNCOV
3631
  while (db != NULL) {
×
UNCOV
3632
    int32_t len = strlen(db) + 1;
×
UNCOV
3633
    if ((code = taosHashPut(*ppNew, db, len, db, dataLen)) != 0) {
×
UNCOV
3634
      taosHashCancelIterate(pOld, db);
×
UNCOV
3635
      taosHashCleanup(*ppNew);
×
UNCOV
3636
      TAOS_RETURN(code);
×
3637
    }
3638
    db = taosHashIterate(pOld, db);
×
3639
  }
3640

3641
  TAOS_RETURN(code);
×
3642
}
3643

UNCOV
3644
int32_t mndDupDbHash(SHashObj *pOld, SHashObj **ppNew) { return mndDupObjHash(pOld, TSDB_DB_FNAME_LEN, ppNew); }
×
3645

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

3648
static int32_t mndTablePriviledge(SMnode *pMnode, SHashObj *hash, SHashObj *useDbHash, SAlterUserReq *alterReq,
×
3649
                                  SSdb *pSdb) {
UNCOV
3650
  void *pIter = NULL;
×
UNCOV
3651
  char  tbFName[TSDB_TABLE_FNAME_LEN] = {0};
×
3652

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

UNCOV
3656
  if (alterReq->tagCond != NULL && alterReq->tagCondLen != 0) {
×
UNCOV
3657
    char *value = taosHashGet(hash, tbFName, len);
×
UNCOV
3658
    if (value != NULL) {
×
UNCOV
3659
      TAOS_RETURN(TSDB_CODE_MND_PRIVILEGE_EXIST);
×
3660
    }
3661

UNCOV
3662
    int32_t condLen = alterReq->tagCondLen;
×
UNCOV
3663
    TAOS_CHECK_RETURN(taosHashPut(hash, tbFName, len, alterReq->tagCond, condLen));
×
3664
  } else {
UNCOV
3665
    TAOS_CHECK_RETURN(taosHashPut(hash, tbFName, len, alterReq->isView ? "v" : "t", 2));
×
3666
  }
3667

UNCOV
3668
  int32_t  dbKeyLen = strlen(alterReq->objname) + 1;
×
UNCOV
3669
  int32_t  ref = 1;
×
UNCOV
3670
  int32_t *currRef = taosHashGet(useDbHash, alterReq->objname, dbKeyLen);
×
UNCOV
3671
  if (NULL != currRef) {
×
UNCOV
3672
    ref = (*currRef) + 1;
×
3673
  }
3674
  TAOS_CHECK_RETURN(taosHashPut(useDbHash, alterReq->objname, dbKeyLen, &ref, sizeof(ref)));
×
3675

UNCOV
3676
  TAOS_RETURN(0);
×
3677
}
3678

UNCOV
3679
static int32_t mndRemoveTablePriviledge(SMnode *pMnode, SHashObj *hash, SHashObj *useDbHash, SAlterUserReq *alterReq,
×
3680
                                        SSdb *pSdb) {
3681
  void *pIter = NULL;
×
UNCOV
3682
  char  tbFName[TSDB_TABLE_FNAME_LEN] = {0};
×
UNCOV
3683
  (void)snprintf(tbFName, sizeof(tbFName), "%s.%s", alterReq->objname, alterReq->tabName);
×
UNCOV
3684
  int32_t len = strlen(tbFName) + 1;
×
3685

3686
  if (taosHashRemove(hash, tbFName, len) != 0) {
×
UNCOV
3687
    TAOS_RETURN(0);  // not found
×
3688
  }
3689

3690
  int32_t  dbKeyLen = strlen(alterReq->objname) + 1;
×
UNCOV
3691
  int32_t *currRef = taosHashGet(useDbHash, alterReq->objname, dbKeyLen);
×
UNCOV
3692
  if (NULL == currRef) {
×
UNCOV
3693
    return 0;
×
3694
  }
3695

3696
  if (1 == *currRef) {
×
3697
    if (taosHashRemove(useDbHash, alterReq->objname, dbKeyLen) != 0) {
×
3698
      TAOS_RETURN(0);  // not found
×
3699
    }
UNCOV
3700
    return 0;
×
3701
  }
UNCOV
3702
  int32_t ref = (*currRef) - 1;
×
UNCOV
3703
  TAOS_CHECK_RETURN(taosHashPut(useDbHash, alterReq->objname, dbKeyLen, &ref, sizeof(ref)));
×
3704

UNCOV
3705
  return 0;
×
3706
}
3707

3708
#if 0
3709
static int32_t mndProcessAlterUserPrivilegesReq(SRpcMsg* pReq, SAlterUserReq *pAlterReq) {
3710
  SMnode   *pMnode = pReq->info.node;
3711
  SSdb     *pSdb = pMnode->pSdb;
3712
  int32_t   code = 0, lino = 0;
3713
  SUserObj *pUser = NULL;
3714
  SUserObj  newUser = {0};
3715
  int64_t   tss = taosGetTimestampMs();
3716

3717
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, pAlterReq->user, &pUser), &lino, _OVER);
3718
  TAOS_CHECK_GOTO(mndCheckAlterUserPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser, pAlterReq), &lino, _OVER);
3719
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
3720

3721
#if 0
3722
  if (ALTER_USER_ADD_READ_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName) ||
3723
      ALTER_USER_ADD_ALL_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName)) {
3724
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
3725
      int32_t len = strlen(pAlterReq->objname) + 1;
3726
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
3727
      if (pDb == NULL) {
3728
        mndReleaseDb(pMnode, pDb);
3729
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
3730
      }
3731
      if ((code = taosHashPut(newUser.readDbs, pAlterReq->objname, len, pAlterReq->objname, TSDB_DB_FNAME_LEN)) !=
3732
          0) {
3733
        mndReleaseDb(pMnode, pDb);
3734
        TAOS_CHECK_GOTO(code, &lino, _OVER);
3735
      }
3736
      mndReleaseDb(pMnode, pDb);
3737
    } else {
3738
      void   *pIter = NULL;
3739
      while (1) {
3740
        SDbObj *pDb = NULL;
3741
        pIter = sdbFetch(pSdb, SDB_DB, pIter, (void **)&pDb);
3742
        if (pIter == NULL) break;
3743
        int32_t len = strlen(pDb->name) + 1;
3744
        if ((code = taosHashPut(newUser.readDbs, pDb->name, len, pDb->name, TSDB_DB_FNAME_LEN)) != 0) {
3745
          sdbRelease(pSdb, pDb);
3746
          sdbCancelFetch(pSdb, pIter);
3747
          TAOS_CHECK_GOTO(code, &lino, _OVER);
3748
        }
3749
        sdbRelease(pSdb, pDb);
3750
      }
3751
    }
3752
  }
3753

3754
  if (ALTER_USER_ADD_WRITE_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName) ||
3755
      ALTER_USER_ADD_ALL_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName)) {
3756
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
3757
      int32_t len = strlen(pAlterReq->objname) + 1;
3758
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
3759
      if (pDb == NULL) {
3760
        mndReleaseDb(pMnode, pDb);
3761
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
3762
      }
3763
      if ((code = taosHashPut(newUser.writeDbs, pAlterReq->objname, len, pAlterReq->objname, TSDB_DB_FNAME_LEN)) !=
3764
          0) {
3765
        mndReleaseDb(pMnode, pDb);
3766
        TAOS_CHECK_GOTO(code, &lino, _OVER);
3767
      }
3768
      mndReleaseDb(pMnode, pDb);
3769
    } else {
3770
      void   *pIter = NULL;
3771
      while (1) {
3772
        SDbObj *pDb = NULL;
3773
        pIter = sdbFetch(pSdb, SDB_DB, pIter, (void **)&pDb);
3774
        if (pIter == NULL) break;
3775
        int32_t len = strlen(pDb->name) + 1;
3776
        if ((code = taosHashPut(newUser.writeDbs, pDb->name, len, pDb->name, TSDB_DB_FNAME_LEN)) != 0) {
3777
          sdbRelease(pSdb, pDb);
3778
          sdbCancelFetch(pSdb, pIter);
3779
          TAOS_CHECK_GOTO(code, &lino, _OVER);
3780
        }
3781
        sdbRelease(pSdb, pDb);
3782
      }
3783
    }
3784
  }
3785

3786
  if (ALTER_USER_DEL_READ_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName) ||
3787
      ALTER_USER_DEL_ALL_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName)) {
3788
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
3789
      int32_t len = strlen(pAlterReq->objname) + 1;
3790
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
3791
      if (pDb == NULL) {
3792
        mndReleaseDb(pMnode, pDb);
3793
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
3794
      }
3795
      code = taosHashRemove(newUser.readDbs, pAlterReq->objname, len);
3796
      if (code < 0) {
3797
        mError("read db:%s, failed to remove db:%s since %s", newUser.user, pAlterReq->objname, terrstr());
3798
      }
3799
      mndReleaseDb(pMnode, pDb);
3800
    } else {
3801
      taosHashClear(newUser.readDbs);
3802
    }
3803
  }
3804

3805
  if (ALTER_USER_DEL_WRITE_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName) ||
3806
      ALTER_USER_DEL_ALL_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName)) {
3807
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
3808
      int32_t len = strlen(pAlterReq->objname) + 1;
3809
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
3810
      if (pDb == NULL) {
3811
        mndReleaseDb(pMnode, pDb);
3812
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
3813
      }
3814
      code = taosHashRemove(newUser.writeDbs, pAlterReq->objname, len);
3815
      if (code < 0) {
3816
        mError("user:%s, failed to remove db:%s since %s", newUser.user, pAlterReq->objname, terrstr());
3817
      }
3818
      mndReleaseDb(pMnode, pDb);
3819
    } else {
3820
      taosHashClear(newUser.writeDbs);
3821
    }
3822
  }
3823

3824
  SHashObj *pReadTbs = newUser.readTbs;
3825
  SHashObj *pWriteTbs = newUser.writeTbs;
3826
  SHashObj *pAlterTbs = newUser.alterTbs;
3827

3828
#ifdef TD_ENTERPRISE
3829
  if (pAlterReq->isView) {
3830
    pReadTbs = newUser.readViews;
3831
    pWriteTbs = newUser.writeViews;
3832
    pAlterTbs = newUser.alterViews;
3833
  }
3834
#endif
3835

3836
  if (ALTER_USER_ADD_READ_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3837
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3838
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pReadTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3839
  }
3840

3841
  if (ALTER_USER_ADD_WRITE_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3842
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3843
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pWriteTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3844
  }
3845

3846
  if (ALTER_USER_ADD_ALTER_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3847
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3848
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pAlterTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3849
  }
3850

3851
  if (ALTER_USER_DEL_READ_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3852
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3853
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pReadTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3854
  }
3855

3856
  if (ALTER_USER_DEL_WRITE_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3857
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3858
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pWriteTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3859
  }
3860

3861
  if (ALTER_USER_DEL_ALTER_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3862
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3863
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pAlterTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3864
  }
3865
#endif
3866

3867
#if 0
3868
// #ifdef USE_TOPIC
3869
  if (ALTER_USER_ADD_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, &pAlterReq->privileges)) {
3870
    int32_t      len = strlen(pAlterReq->objname) + 1;
3871
    SMqTopicObj *pTopic = NULL;
3872
    if ((code = mndAcquireTopic(pMnode, pAlterReq->objname, &pTopic)) != 0) {
3873
      TAOS_CHECK_GOTO(code, &lino, _OVER);
3874
    }
3875
    taosRLockLatch(&pTopic->lock);
3876
    code = taosHashPut(newUser.topics, pTopic->name, len, pTopic->name, TSDB_TOPIC_FNAME_LEN);
3877
    taosRUnLockLatch(&pTopic->lock);
3878
    mndReleaseTopic(pMnode, pTopic);
3879
    TAOS_CHECK_GOTO(code, &lino, _OVER);
3880
  }
3881

3882
  if (ALTER_USER_DEL_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, &pAlterReq->privileges)) {
3883
    int32_t      len = strlen(pAlterReq->objname) + 1;
3884
    SMqTopicObj *pTopic = NULL;
3885
    if ((code = mndAcquireTopic(pMnode, pAlterReq->objname, &pTopic)) != 0) {
3886
      TAOS_CHECK_GOTO(code, &lino, _OVER);
3887
    }
3888
    taosRLockLatch(&pTopic->lock);
3889
    code = taosHashRemove(newUser.topics, pAlterReq->objname, len);
3890
    if (code < 0) {
3891
      mError("user:%s, failed to remove topic:%s since %s", newUser.user, pAlterReq->objname, tstrerror(code));
3892
    }
3893
    taosRUnLockLatch(&pTopic->lock);
3894
    mndReleaseTopic(pMnode, pTopic);
3895
  }
3896
#endif
3897

3898
  TAOS_CHECK_GOTO(mndAlterUser(pMnode, &newUser, pReq), &lino, _OVER);
3899
  code = TSDB_CODE_ACTION_IN_PROGRESS;
3900

3901
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
3902
    int64_t tse = taosGetTimestampMs();
3903
    double  duration = (double)(tse - tss);
3904
    duration = duration / 1000;
3905
    if (ALTER_USER_ADD_READ_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3906
              ALTER_USER_ADD_WRITE_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3907
              ALTER_USER_ADD_ALL_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3908
              ALTER_USER_ADD_READ_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3909
              ALTER_USER_ADD_WRITE_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3910
              ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3911
      if (strcmp(pAlterReq->objname, "1.*") != 0) {
3912
        SName name = {0};
3913
        TAOS_CHECK_GOTO(tNameFromString(&name, pAlterReq->objname, T_NAME_ACCT | T_NAME_DB), &lino, _OVER);
3914
        auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", name.dbname, pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
3915
      } else {
3916
        auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", "", pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
3917
      }
3918
    } else if (ALTER_USER_ADD_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, pAlterReq->privileges)) {
3919
      auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", pAlterReq->objname, pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
3920
    } else if (ALTER_USER_DEL_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, pAlterReq->privileges)) {
3921
      auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", pAlterReq->objname, pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
3922
    } else {
3923
      if (strcmp(pAlterReq->objname, "1.*") != 0) {
3924
        SName name = {0};
3925
        TAOS_CHECK_GOTO(tNameFromString(&name, pAlterReq->objname, T_NAME_ACCT | T_NAME_DB), &lino, _OVER);
3926
        auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", name.dbname, pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
3927
      } else {
3928
        auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", "", pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
3929
      }
3930
    }
3931
  }
3932
  
3933
_OVER:
3934
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
3935
    mError("user:%s, failed to alter user privileges at line %d since %s", pAlterReq->user, lino, tstrerror(code));
3936
  }
3937
  mndReleaseUser(pMnode, pUser);
3938
  mndUserFreeObj(&newUser);
3939
  TAOS_RETURN(code);
3940
}
3941
#endif
3942

3943
int32_t mndAlterUserFromRole(SRpcMsg *pReq, SUserObj *pOperUser, SAlterRoleReq *pAlterReq) {
1,021,242✔
3944
  SMnode   *pMnode = pReq->info.node;
1,021,242✔
3945
  SSdb     *pSdb = pMnode->pSdb;
1,021,242✔
3946
  void     *pIter = NULL;
1,021,242✔
3947
  int32_t   code = 0, lino = 0;
1,021,242✔
3948
  SUserObj *pUser = NULL;
1,021,242✔
3949
  SUserObj  newUser = {0};
1,021,242✔
3950

3951
  TAOS_CHECK_EXIT(mndAcquireUser(pMnode, pAlterReq->principal, &pUser));
1,021,242✔
3952

3953
  if (pUser->enable == 0) {
1,020,262✔
UNCOV
3954
    TAOS_CHECK_EXIT(TSDB_CODE_MND_USER_DISABLED);
×
3955
  }
3956

3957
  if (pAlterReq->alterType == TSDB_ALTER_ROLE_PRIVILEGES) {
1,020,262✔
3958
#ifdef TD_ENTERPRISE
3959
    TAOS_CHECK_EXIT(mndUserDupObj(pUser, &newUser));
1,016,624✔
3960
    if ((code = mndAlterUserPrivInfo(pMnode, &newUser, pAlterReq)) == TSDB_CODE_QRY_DUPLICATED_OPERATION) {
1,016,624✔
3961
      code = 0;
×
3962
      goto _exit;
×
3963
    } else {
3964
      TAOS_CHECK_EXIT(code);
1,016,624✔
3965
    }
3966
  } else if (pAlterReq->alterType == TSDB_ALTER_ROLE_ROLE) {
3,638✔
3967
    if ((code = mndAlterUserRoleInfo(pMnode, pOperUser, RPC_MSG_TOKEN(pReq), pUser, &newUser, pAlterReq)) ==
3,638✔
3968
        TSDB_CODE_QRY_DUPLICATED_OPERATION) {
3969
      code = 0;
149✔
3970
      goto _exit;
149✔
3971
    } else {
3972
      TAOS_CHECK_EXIT(code);
3,489✔
3973
    }
3974
#endif
3975
  } else {
3976
    TAOS_CHECK_EXIT(TSDB_CODE_INVALID_MSG);
×
3977
  }
3978
  code = mndAlterUser(pMnode, &newUser, pReq);
1,019,666✔
3979
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
1,019,666✔
3980

3981
_exit:
1,021,242✔
3982
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
1,021,242✔
3983
    mError("user:%s, failed to alter user at line %d since %s", pAlterReq->principal, lino, tstrerror(code));
1,427✔
3984
  }
3985
  mndReleaseUser(pMnode, pUser);
1,021,242✔
3986
  mndUserFreeObj(&newUser);
1,021,242✔
3987
  TAOS_RETURN(code);
1,021,242✔
3988
}
3989

3990
static int32_t mndProcessAlterUserBasicInfoReq(SRpcMsg *pReq, SAlterUserReq *pAlterReq) {
33,607✔
3991
  SMnode   *pMnode = pReq->info.node;
33,607✔
3992
  int32_t   code = 0, lino = 0;
33,607✔
3993
  SUserObj *pUser = NULL;
33,607✔
3994
  SUserObj  newUser = {0};
33,607✔
3995
  char      auditLog[1000] = {0};
33,607✔
3996
  int32_t   auditLen = 0;
33,607✔
3997
  int64_t   tss = taosGetTimestampMs();
33,607✔
3998

3999
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, pAlterReq->user, &pUser), &lino, _OVER);
33,607✔
4000
  TAOS_CHECK_GOTO(mndCheckAlterUserPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser, pAlterReq), &lino,
32,767✔
4001
                  _OVER);
4002
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
31,494✔
4003

4004
  if (pAlterReq->hasPassword) {
31,494✔
4005
    auditLen += tsnprintf(auditLog, sizeof(auditLog), "password,");
19,643✔
4006

4007
    TAOS_CHECK_GOTO(mndCheckPasswordFmt(pAlterReq->pass), &lino, _OVER);
19,643✔
4008
    if (newUser.salt[0] == 0) {
19,643✔
4009
      generateSalt(newUser.salt, sizeof(newUser.salt));
166✔
4010
    }
4011
    char pass[TSDB_PASSWORD_LEN] = {0};
19,643✔
4012
    taosEncryptPass_c((uint8_t *)pAlterReq->pass, strlen(pAlterReq->pass), pass);
19,643✔
4013
    pass[sizeof(pass) - 1] = 0;
19,643✔
4014
    TAOS_CHECK_GOTO(mndEncryptPass(pass, newUser.salt, &newUser.passEncryptAlgorithm), &lino, _OVER);
19,643✔
4015

4016
    if (newUser.passwordReuseMax > 0 || newUser.passwordReuseTime > 0) {
19,643✔
4017
      for (int32_t i = 0; i < newUser.numOfPasswords; ++i) {
697,712✔
4018
        if (0 == strncmp(newUser.passwords[i].pass, pass, TSDB_PASSWORD_LEN)) {
680,972✔
4019
          TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_PASSWORD_REUSE, &lino, _OVER);
384✔
4020
        }
4021
      }
4022
      SUserPassword *passwords = taosMemoryCalloc(newUser.numOfPasswords + 1, sizeof(SUserPassword));
16,740✔
4023
      if (passwords == NULL) {
16,740✔
UNCOV
4024
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
4025
      }
4026
      memcpy(passwords + 1, newUser.passwords, newUser.numOfPasswords * sizeof(SUserPassword));
16,740✔
4027
      memcpy(passwords[0].pass, pass, TSDB_PASSWORD_LEN);
16,740✔
4028
      passwords[0].setTime = taosGetTimestampSec();
16,740✔
4029
      taosMemoryFree(newUser.passwords);
16,740✔
4030
      newUser.passwords = passwords;
16,740✔
4031
      ++newUser.numOfPasswords;
16,740✔
4032
      ++newUser.passVersion;
16,740✔
4033
      newUser.changePass = 2;
16,740✔
4034
    } else if (0 != strncmp(newUser.passwords[0].pass, pass, TSDB_PASSWORD_LEN)) {
2,519✔
4035
      memcpy(newUser.passwords[0].pass, pass, TSDB_PASSWORD_LEN);
2,326✔
4036
      newUser.passwords[0].setTime = taosGetTimestampSec();
2,326✔
4037
      ++newUser.passVersion;
2,326✔
4038
      newUser.changePass = 2;
2,326✔
4039
    }
4040
  }
4041

4042
  if (pAlterReq->hasTotpseed) {
31,110✔
4043
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "totpseed,");
×
4044

NEW
4045
    if (pAlterReq->totpseed[0] == 0) {  // clear totp secret
×
4046
      memset(newUser.totpsecret, 0, sizeof(newUser.totpsecret));
×
UNCOV
4047
    } else if (taosGenerateTotpSecret(pAlterReq->totpseed, 0, newUser.totpsecret, sizeof(newUser.totpsecret)) < 0) {
×
4048
      TAOS_CHECK_GOTO(TSDB_CODE_PAR_INVALID_OPTION_VALUE, &lino, _OVER);
×
4049
    }
4050
  }
4051

4052
  if (pAlterReq->hasEnable) {
31,110✔
4053
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "enable:%d,", pAlterReq->enable);
1,245✔
4054

4055
    newUser.enable = pAlterReq->enable;  // lock or unlock user manually
1,245✔
4056
    if (newUser.enable) {
1,245✔
4057
      // reset login info to allow login immediately
4058
      userCacheResetLoginInfo(newUser.user);
781✔
4059
    }
4060
  }
4061

4062
  if (pAlterReq->hasSysinfo) {
31,110✔
4063
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "sysinfo:%d,", pAlterReq->sysinfo);
3,869✔
4064
    newUser.sysInfo = pAlterReq->sysinfo;
3,869✔
4065
  }
4066

4067
  if (pAlterReq->hasCreatedb) {
31,110✔
4068
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "createdb:%d,", pAlterReq->createdb);
4,761✔
4069
    newUser.createdb = pAlterReq->createdb;
4,761✔
4070
    if (newUser.createdb == 1) {
4,761✔
4071
      privAddType(&newUser.sysPrivs, PRIV_DB_CREATE);
4072
    } else {
4073
      privRemoveType(&newUser.sysPrivs, PRIV_DB_CREATE);
4074
    }
4075
  }
4076

4077
#ifdef TD_ENTERPRISE
4078
  if (pAlterReq->hasChangepass) {
31,110✔
4079
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "changepass:%d,", pAlterReq->changepass);
×
4080
    newUser.changePass = pAlterReq->changepass;
×
4081
  }
4082

4083
  if (pAlterReq->hasSessionPerUser) {
31,110✔
4084
    auditLen +=
256✔
4085
        tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "sessionPerUser:%d,", pAlterReq->sessionPerUser);
256✔
4086
    newUser.sessionPerUser = pAlterReq->sessionPerUser;
256✔
4087
  }
4088

4089
  if (pAlterReq->hasConnectTime) {
31,110✔
4090
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "connectTime:%d,", pAlterReq->connectTime);
128✔
4091
    newUser.connectTime = pAlterReq->connectTime;
128✔
4092
  }
4093

4094
  if (pAlterReq->hasConnectIdleTime) {
31,110✔
4095
    auditLen +=
128✔
4096
        tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "connectIdleTime:%d,", pAlterReq->connectIdleTime);
128✔
4097
    newUser.connectIdleTime = pAlterReq->connectIdleTime;
128✔
4098
  }
4099

4100
  if (pAlterReq->hasCallPerSession) {
31,110✔
4101
    auditLen +=
384✔
4102
        tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "callPerSession:%d,", pAlterReq->callPerSession);
384✔
4103
    newUser.callPerSession = pAlterReq->callPerSession;
384✔
4104
  }
4105

4106
  if (pAlterReq->hasVnodePerCall) {
31,110✔
4107
    auditLen +=
256✔
4108
        tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "vnodePerCall:%d,", pAlterReq->vnodePerCall);
256✔
4109
    newUser.vnodePerCall = pAlterReq->vnodePerCall;
256✔
4110
  }
4111

4112
  if (pAlterReq->hasFailedLoginAttempts) {
31,110✔
4113
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "failedLoginAttempts:%d,",
384✔
4114
                          pAlterReq->failedLoginAttempts);
4115
    newUser.failedLoginAttempts = pAlterReq->failedLoginAttempts;
384✔
4116
  }
4117

4118
  if (pAlterReq->hasPasswordLifeTime) {
31,110✔
4119
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordLifeTime:%d,",
128✔
4120
                          pAlterReq->passwordLifeTime);
4121
    newUser.passwordLifeTime = pAlterReq->passwordLifeTime;
128✔
4122
  }
4123

4124
  if (pAlterReq->hasPasswordReuseTime) {
31,110✔
4125
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordReuseTime:%d,",
384✔
4126
                          pAlterReq->passwordReuseTime);
4127
    newUser.passwordReuseTime = pAlterReq->passwordReuseTime;
384✔
4128
  }
4129

4130
  if (pAlterReq->hasPasswordReuseMax) {
31,110✔
4131
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordReuseMax:%d,",
384✔
4132
                          pAlterReq->passwordReuseMax);
4133
    newUser.passwordReuseMax = pAlterReq->passwordReuseMax;
384✔
4134
  }
4135

4136
  if (pAlterReq->hasPasswordLockTime) {
31,110✔
4137
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordLockTime:%d,",
128✔
4138
                          pAlterReq->passwordLockTime);
4139
    newUser.passwordLockTime = pAlterReq->passwordLockTime;
128✔
4140
  }
4141

4142
  if (pAlterReq->hasPasswordGraceTime) {
31,110✔
4143
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordGraceTime:%d,",
128✔
4144
                          pAlterReq->passwordGraceTime);
4145
    newUser.passwordGraceTime = pAlterReq->passwordGraceTime;
128✔
4146
  }
4147

4148
  if (pAlterReq->hasInactiveAccountTime) {
31,110✔
4149
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "inactiveAccountTime:%d,",
128✔
4150
                          pAlterReq->inactiveAccountTime);
4151
    newUser.inactiveAccountTime = pAlterReq->inactiveAccountTime;
128✔
4152
  }
4153

4154
  if (pAlterReq->hasAllowTokenNum) {
31,110✔
4155
    auditLen +=
256✔
4156
        tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "allowTokenNum:%d,", pAlterReq->allowTokenNum);
256✔
4157
    newUser.allowTokenNum = pAlterReq->allowTokenNum;
256✔
4158
  }
4159

4160
  if (pAlterReq->numDropIpRanges > 0 || pAlterReq->numIpRanges > 0) {
31,110✔
4161
    int32_t dummy = 0;
568✔
4162

4163
    // put previous ip whitelist into hash table
4164
    SHashObj *m = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
568✔
4165
    if (m == NULL) {
568✔
UNCOV
4166
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
4167
    }
4168

4169
    for (int32_t i = 0; i < newUser.pIpWhiteListDual->num; i++) {
2,428✔
4170
      SIpRange range;
1,860✔
4171
      copyIpRange(&range, newUser.pIpWhiteListDual->pIpRanges + i);
1,860✔
4172
      code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
1,860✔
4173
      if (code != 0) {
1,860✔
UNCOV
4174
        taosHashCleanup(m);
×
UNCOV
4175
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
4176
      }
4177
    }
4178

4179
    if (pAlterReq->numDropIpRanges > 0) {
568✔
4180
      auditLen +=
284✔
4181
          tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "dropIpRanges:%d,", pAlterReq->numDropIpRanges);
284✔
4182

4183
      for (int32_t i = 0; i < pAlterReq->numDropIpRanges; i++) {
696✔
4184
        if (taosHashGetSize(m) == 0) {
412✔
UNCOV
4185
          break;
×
4186
        }
4187

4188
        SIpRange range;
412✔
4189
        copyIpRange(&range, pAlterReq->pDropIpRanges + i);
412✔
4190

4191
        // for white list, drop default ip ranges is allowed, otherwise, we can never
4192
        // convert white list to black list.
4193

4194
        code = taosHashRemove(m, &range, sizeof(range));
412✔
4195
        if (code == TSDB_CODE_NOT_FOUND) {
412✔
4196
          // treat not exist as success
4197
          code = 0;
156✔
4198
        }
4199
        if (code != 0) {
412✔
UNCOV
4200
          taosHashCleanup(m);
×
UNCOV
4201
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
4202
        }
4203
      }
4204
    }
4205

4206
    if (pAlterReq->numIpRanges > 0) {
568✔
4207
      auditLen +=
284✔
4208
          tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "addIpRanges:%d,", pAlterReq->numIpRanges);
284✔
4209
      for (int32_t i = 0; i < pAlterReq->numIpRanges; i++) {
696✔
4210
        SIpRange range;
412✔
4211
        copyIpRange(&range, pAlterReq->pIpRanges + i);
412✔
4212
        code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
412✔
4213
        if (code != 0) {
412✔
UNCOV
4214
          taosHashCleanup(m);
×
UNCOV
4215
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
4216
        }
4217
      }
4218
    }
4219

4220
    int32_t numOfRanges = taosHashGetSize(m);
568✔
4221
    if (numOfRanges > MND_MAX_USER_IP_RANGE) {
568✔
UNCOV
4222
      taosHashCleanup(m);
×
UNCOV
4223
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_IP_RANGE, &lino, _OVER);
×
4224
    }
4225

4226
    SIpWhiteListDual *p = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + numOfRanges * sizeof(SIpRange));
568✔
4227
    if (p == NULL) {
568✔
UNCOV
4228
      taosHashCleanup(m);
×
UNCOV
4229
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
4230
    }
4231

4232
    void   *pIter = taosHashIterate(m, NULL);
568✔
4233
    int32_t i = 0;
568✔
4234
    while (pIter) {
2,584✔
4235
      size_t    len = 0;
2,016✔
4236
      SIpRange *key = taosHashGetKey(pIter, &len);
2,016✔
4237
      memcpy(p->pIpRanges + i, key, sizeof(SIpRange));
2,016✔
4238
      pIter = taosHashIterate(m, pIter);
2,016✔
4239
      i++;
2,016✔
4240
    }
4241

4242
    taosHashCleanup(m);
568✔
4243
    p->num = numOfRanges;
568✔
4244
    taosMemoryFreeClear(newUser.pIpWhiteListDual);
568✔
4245
    sortIpWhiteList(p);
568✔
4246
    newUser.pIpWhiteListDual = p;
568✔
4247

4248
    newUser.ipWhiteListVer++;
568✔
4249
  }
4250

4251
  if (pAlterReq->numTimeRanges > 0 || pAlterReq->numDropTimeRanges) {
31,110✔
4252
    int32_t dummy = 0;
512✔
4253

4254
    // put previous ip whitelist into hash table
4255
    SHashObj *m = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
512✔
4256
    if (m == NULL) {
512✔
UNCOV
4257
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
4258
    }
4259

4260
    for (int32_t i = 0; i < newUser.pTimeWhiteList->num; i++) {
1,280✔
4261
      SDateTimeWhiteListItem *range = &newUser.pTimeWhiteList->ranges[i];
768✔
4262
      if (isDateTimeWhiteListItemExpired(range)) {
768✔
UNCOV
4263
        continue;
×
4264
      }
4265
      code = taosHashPut(m, range, sizeof(*range), &dummy, sizeof(dummy));
768✔
4266
      if (code != 0) {
768✔
UNCOV
4267
        taosHashCleanup(m);
×
UNCOV
4268
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
4269
      }
4270
    }
4271

4272
    if (pAlterReq->numDropTimeRanges > 0) {
512✔
4273
      auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "dropTimeRanges:%d,",
384✔
4274
                            pAlterReq->numDropTimeRanges);
4275
      for (int32_t i = 0; i < pAlterReq->numDropTimeRanges; i++) {
896✔
4276
        if (taosHashGetSize(m) == 0) {
512✔
UNCOV
4277
          break;
×
4278
        }
4279
        SDateTimeWhiteListItem range = {0};
512✔
4280
        DateTimeRangeToWhiteListItem(&range, pAlterReq->pDropTimeRanges + i);
512✔
4281

4282
        code = taosHashRemove(m, &range, sizeof(range));
512✔
4283
        if (code == TSDB_CODE_NOT_FOUND) {
512✔
4284
          // treat not exist as success
UNCOV
4285
          code = 0;
×
4286
        }
4287
        if (code != 0) {
512✔
UNCOV
4288
          taosHashCleanup(m);
×
UNCOV
4289
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
4290
        }
4291
      }
4292
    }
4293

4294
    if (pAlterReq->numTimeRanges > 0) {
512✔
4295
      auditLen +=
384✔
4296
          tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "addTimeRanges:%d,", pAlterReq->numTimeRanges);
384✔
4297
      for (int32_t i = 0; i < pAlterReq->numTimeRanges; i++) {
896✔
4298
        SDateTimeWhiteListItem range = {0};
512✔
4299
        DateTimeRangeToWhiteListItem(&range, pAlterReq->pTimeRanges + i);
512✔
4300
        if (isDateTimeWhiteListItemExpired(&range)) {
512✔
UNCOV
4301
          continue;
×
4302
        }
4303
        code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
512✔
4304
        if (code != 0) {
512✔
UNCOV
4305
          taosHashCleanup(m);
×
UNCOV
4306
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
4307
        }
4308
      }
4309
    }
4310

4311
    int32_t numOfRanges = taosHashGetSize(m);
512✔
4312
    if (numOfRanges > MND_MAX_USER_TIME_RANGE) {
512✔
UNCOV
4313
      taosHashCleanup(m);
×
UNCOV
4314
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_TIME_RANGE, &lino, _OVER);
×
4315
    }
4316

4317
    SDateTimeWhiteList *p =
1,024✔
4318
        taosMemoryCalloc(1, sizeof(SDateTimeWhiteList) + numOfRanges * sizeof(SDateTimeWhiteListItem));
512✔
4319
    if (p == NULL) {
512✔
UNCOV
4320
      taosHashCleanup(m);
×
UNCOV
4321
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
4322
    }
4323

4324
    void   *pIter = taosHashIterate(m, NULL);
512✔
4325
    int32_t i = 0;
512✔
4326
    while (pIter) {
1,280✔
4327
      size_t                  len = 0;
768✔
4328
      SDateTimeWhiteListItem *key = taosHashGetKey(pIter, &len);
768✔
4329
      memcpy(&p->ranges[i], key, sizeof(SDateTimeWhiteListItem));
768✔
4330
      pIter = taosHashIterate(m, pIter);
768✔
4331
      i++;
768✔
4332
    }
4333

4334
    taosHashCleanup(m);
512✔
4335
    p->num = numOfRanges;
512✔
4336
    taosMemoryFreeClear(newUser.pTimeWhiteList);
512✔
4337
    sortTimeWhiteList(p);
512✔
4338
    newUser.pTimeWhiteList = p;
512✔
4339
    newUser.timeWhiteListVer++;
512✔
4340
  }
4341
#endif  // TD_ENTERPRISE
4342

4343
  TAOS_CHECK_GOTO(mndAlterUser(pMnode, &newUser, pReq), &lino, _OVER);
31,110✔
4344
  if (pAlterReq->hasEnable) {
31,110✔
4345
    if (newUser.enable) {
1,245✔
4346
      if (taosHashGet(newUser.roles, TSDB_ROLE_SYSAUDIT_LOG, strlen(TSDB_ROLE_SYSAUDIT_LOG) + 1)) {
781✔
NEW
4347
        (void)mndResetAuditLogUser(pMnode, newUser.user, true);
×
4348
      }
4349
    } else {
4350
      (void)mndResetAuditLogUser(pMnode, newUser.user, false);
464✔
4351
    }
4352
  }
4353
  code = TSDB_CODE_ACTION_IN_PROGRESS;
31,110✔
4354

4355
  if (auditLen > 0) {
31,110✔
4356
    auditLog[--auditLen] = 0;  // remove last ','
31,110✔
4357
  }
4358
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
31,110✔
4359
    int64_t tse = taosGetTimestampMs();
31,110✔
4360
    double  duration = (double)(tse - tss);
31,110✔
4361
    duration = duration / 1000;
31,110✔
4362
    auditRecord(pReq, pMnode->clusterId, "alterUser", "", pAlterReq->user, auditLog, auditLen, duration, 0);
31,110✔
4363
  }
4364

4365
_OVER:
33,607✔
4366
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
33,607✔
4367
    mError("user:%s, failed to alter at line %d since %s", pAlterReq->user, lino, tstrerror(code));
2,497✔
4368
  }
4369

4370
  mndReleaseUser(pMnode, pUser);
33,607✔
4371
  mndUserFreeObj(&newUser);
33,607✔
4372
  return code;
33,607✔
4373
}
4374

4375
static int32_t mndProcessAlterUserReq(SRpcMsg *pReq) {
33,607✔
4376
  SAlterUserReq alterReq = {0};
33,607✔
4377

4378
  int32_t code = tDeserializeSAlterUserReq(pReq->pCont, pReq->contLen, &alterReq);
33,607✔
4379
  if (code != 0) {
33,607✔
UNCOV
4380
    mError("failed to deserialize alter user request at line %d since %s", __LINE__, tstrerror(code));
×
UNCOV
4381
    TAOS_RETURN(code);
×
4382
  }
4383

4384
  if (alterReq.user[0] == 0) {
33,607✔
NEW
4385
    tFreeSAlterUserReq(&alterReq);
×
NEW
4386
    mError("failed to alter user at line %d since invalid user format", __LINE__);
×
NEW
4387
    TAOS_RETURN(TSDB_CODE_MND_INVALID_USER_FORMAT);
×
4388
  }
4389

4390
  mInfo("user:%s, start to alter", alterReq.user);
33,607✔
4391
  if (alterReq.alterType == TSDB_ALTER_USER_BASIC_INFO) {
33,607✔
4392
    code = mndProcessAlterUserBasicInfoReq(pReq, &alterReq);
33,607✔
4393
  } else {
4394
    // code = mndProcessAlterUserPrivilegesReq(pReq, &alterReq); // obsolete
4395
  }
4396

4397
  tFreeSAlterUserReq(&alterReq);
33,607✔
4398
  TAOS_RETURN(code);
33,607✔
4399
}
4400

4401
int32_t mndResetAuditLogUser(SMnode *pMnode, const char *user, bool isAdd) {
41,251,547✔
4402
  if (user) {
41,251,547✔
4403
    (void)taosThreadRwlockRdlock(&userCache.rw);
30,713✔
4404
    if (isAdd) {
30,713✔
4405
      if (userCache.auditLogUser[0] != 0) {
64✔
NEW
4406
        (void)taosThreadRwlockUnlock(&userCache.rw);
×
NEW
4407
        return 0;
×
4408
      }
4409
      (void)taosThreadRwlockUnlock(&userCache.rw);
64✔
4410
      (void)taosThreadRwlockWrlock(&userCache.rw);
64✔
4411
      (void)tsnprintf(userCache.auditLogUser, TSDB_USER_LEN, "%s", user);
64✔
4412
      (void)taosThreadRwlockUnlock(&userCache.rw);
64✔
4413
      return 0;
64✔
4414
    } else if (strcmp(userCache.auditLogUser, user) != 0) {
30,649✔
4415
      (void)taosThreadRwlockUnlock(&userCache.rw);
30,649✔
4416
      return 0;
30,649✔
4417
    }
NEW
4418
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
4419
  }
4420

4421
  void     *pIter = NULL;
41,220,834✔
4422
  SSdb     *pSdb = pMnode->pSdb;
41,220,834✔
4423
  SUserObj *pUser = NULL;
41,220,834✔
4424
  int32_t   len = strlen(TSDB_ROLE_SYSAUDIT_LOG) + 1;
41,220,834✔
4425
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser))) {
87,592,122✔
4426
    if (pUser->enable == 0) {
46,371,288✔
4427
      mndReleaseUser(pMnode, pUser);
17,106✔
4428
      continue;
17,106✔
4429
    }
4430
    if (taosHashGet(pUser->roles, TSDB_ROLE_SYSAUDIT_LOG, len) != NULL) {
46,354,182✔
NEW
4431
      (void)taosThreadRwlockWrlock(&userCache.rw);
×
NEW
4432
      (void)tsnprintf(userCache.auditLogUser, TSDB_USER_LEN, "%s", pUser->name);
×
NEW
4433
      (void)taosThreadRwlockUnlock(&userCache.rw);
×
NEW
4434
      sdbCancelFetch(pSdb, pIter);
×
NEW
4435
      mndReleaseUser(pMnode, pUser);
×
NEW
4436
      return 0;
×
4437
    }
4438
    mndReleaseUser(pMnode, pUser);
46,354,182✔
4439
  }
4440
  (void)taosThreadRwlockWrlock(&userCache.rw);
41,220,834✔
4441
  userCache.auditLogUser[0] = 0;
41,220,834✔
4442
  (void)taosThreadRwlockUnlock(&userCache.rw);
41,220,834✔
4443
  return TSDB_CODE_MND_USER_NOT_AVAILABLE;
41,220,834✔
4444
}
4445

4446
int32_t mndGetAuditUser(SMnode *pMnode, char *user) {
41,221,858✔
4447
  (void)taosThreadRwlockRdlock(&userCache.rw);
41,221,858✔
4448
  if (userCache.auditLogUser[0] != 0) {
41,221,858✔
4449
    (void)tsnprintf(user, TSDB_USER_LEN, "%s", userCache.auditLogUser);
1,024✔
4450
    (void)taosThreadRwlockUnlock(&userCache.rw);
1,024✔
4451
    return 0;
1,024✔
4452
  }
4453
  (void)taosThreadRwlockUnlock(&userCache.rw);
41,220,834✔
4454

4455
  int32_t code = 0;
41,220,834✔
4456
  if ((code = mndResetAuditLogUser(pMnode, NULL, false)) != 0) {
41,220,834✔
4457
    return code;
41,220,834✔
4458
  }
4459

NEW
4460
  (void)taosThreadRwlockRdlock(&userCache.rw);
×
NEW
4461
  (void)tsnprintf(user, TSDB_USER_LEN, "%s", userCache.auditLogUser);
×
NEW
4462
  (void)taosThreadRwlockUnlock(&userCache.rw);
×
4463

UNCOV
4464
  return 0;
×
4465
}
4466

4467
static int32_t mndDropUser(SMnode *pMnode, SRpcMsg *pReq, SUserObj *pUser) {
30,185✔
4468
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "drop-user");
30,185✔
4469
  if (pTrans == NULL) {
30,185✔
UNCOV
4470
    mError("user:%s, failed to drop since %s", pUser->user, terrstr());
×
UNCOV
4471
    TAOS_RETURN(terrno);
×
4472
  }
4473
  mInfo("trans:%d, used to drop user:%s", pTrans->id, pUser->user);
30,185✔
4474

4475
  SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
30,185✔
4476
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
30,185✔
UNCOV
4477
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
UNCOV
4478
    mndTransDrop(pTrans);
×
UNCOV
4479
    TAOS_RETURN(terrno);
×
4480
  }
4481
  if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED) < 0) {
30,185✔
UNCOV
4482
    mndTransDrop(pTrans);
×
UNCOV
4483
    TAOS_RETURN(terrno);
×
4484
  }
4485

4486
  if (mndDropTokensByUser(pMnode, pTrans, pUser->user) != 0) {
30,185✔
UNCOV
4487
    mndTransDrop(pTrans);
×
UNCOV
4488
    TAOS_RETURN(terrno);
×
4489
  }
4490

4491
  if (mndTransPrepare(pMnode, pTrans) != 0) {
30,185✔
UNCOV
4492
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
UNCOV
4493
    mndTransDrop(pTrans);
×
UNCOV
4494
    TAOS_RETURN(terrno);
×
4495
  }
4496

4497
  userCacheRemoveUser(pUser->user);
30,185✔
4498
  mndDropCachedTokensByUser(pUser->user);
30,185✔
4499
  (void)mndResetAuditLogUser(pMnode, pUser->user, false);
30,185✔
4500

4501
  mndTransDrop(pTrans);
30,185✔
4502
  TAOS_RETURN(0);
30,185✔
4503
}
4504

4505
static int32_t mndProcessDropUserReq(SRpcMsg *pReq) {
30,918✔
4506
  SMnode      *pMnode = pReq->info.node;
30,918✔
4507
  int32_t      code = 0;
30,918✔
4508
  int32_t      lino = 0;
30,918✔
4509
  SUserObj    *pOperUser = NULL;
30,918✔
4510
  SUserObj    *pUser = NULL;
30,918✔
4511
  SDropUserReq dropReq = {0};
30,918✔
4512
  int64_t      tss = taosGetTimestampMs();
30,918✔
4513

4514
  TAOS_CHECK_GOTO(tDeserializeSDropUserReq(pReq->pCont, pReq->contLen, &dropReq), &lino, _OVER);
30,918✔
4515

4516
  mInfo("user:%s, start to drop", dropReq.user);
30,918✔
4517

4518
  if (dropReq.user[0] == 0) {
30,918✔
UNCOV
4519
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
4520
  }
4521

4522
  if (0 == strcmp(dropReq.user, TSDB_DEFAULT_USER)) {
30,918✔
UNCOV
4523
    return TSDB_CODE_MND_NO_RIGHTS;
×
4524
  }
4525

4526
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, dropReq.user, &pUser), &lino, _OVER);
30,918✔
4527

4528
  code = mndAcquireUser(pMnode, RPC_MSG_USER(pReq), &pOperUser);
30,185✔
4529
  if (pOperUser == NULL) {
30,185✔
UNCOV
4530
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_USER_FROM_CONN, &lino, _OVER);
×
4531
  }
4532

4533
  // TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, RPC_MSG_USER(pReq), MND_OPER_DROP_USER), &lino, _OVER);
4534
  TAOS_CHECK_GOTO(mndCheckSysObjPrivilege(pMnode, pOperUser, RPC_MSG_TOKEN(pReq), PRIV_USER_DROP, 0, 0, NULL, NULL),
30,185✔
4535
                  &lino, _OVER);
4536

4537
  TAOS_CHECK_GOTO(mndDropUser(pMnode, pReq, pUser), &lino, _OVER);
30,185✔
4538
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
30,185✔
4539

4540
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
30,185✔
4541
    int64_t tse = taosGetTimestampMs();
30,185✔
4542
    double  duration = (double)(tse - tss);
30,185✔
4543
    duration = duration / 1000;
30,185✔
4544
    auditRecord(pReq, pMnode->clusterId, "dropUser", "", dropReq.user, dropReq.sql, dropReq.sqlLen, duration, 0);
30,185✔
4545
  }
4546

4547
_OVER:
30,918✔
4548
  if (dropReq.ignoreNotExists && code == TSDB_CODE_MND_USER_NOT_EXIST) {
30,918✔
4549
    code = 0;
456✔
4550
  } else if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
30,462✔
4551
    mError("user:%s, failed to drop at line %d since %s", dropReq.user, lino, tstrerror(code));
277✔
4552
  }
4553

4554
  mndReleaseUser(pMnode, pUser);
30,918✔
4555
  mndReleaseUser(pMnode, pOperUser);
30,918✔
4556
  tFreeSDropUserReq(&dropReq);
30,918✔
4557
  TAOS_RETURN(code);
30,918✔
4558
}
4559

4560
static int32_t mndProcessGetUserAuthReq(SRpcMsg *pReq) {
6,207,751✔
4561
  SMnode         *pMnode = pReq->info.node;
6,207,751✔
4562
  int32_t         code = 0;
6,207,751✔
4563
  int32_t         lino = 0;
6,207,751✔
4564
  int32_t         contLen = 0;
6,207,751✔
4565
  void           *pRsp = NULL;
6,207,751✔
4566
  SUserObj       *pUser = NULL;
6,207,751✔
4567
  SGetUserAuthReq authReq = {0};
6,207,751✔
4568
  SGetUserAuthRsp authRsp = {0};
6,207,751✔
4569

4570
  TAOS_CHECK_EXIT(tDeserializeSGetUserAuthReq(pReq->pCont, pReq->contLen, &authReq));
6,207,751✔
4571
  mTrace("user:%s, start to get auth", authReq.user);
6,207,751✔
4572

4573
  TAOS_CHECK_EXIT(mndAcquireUser(pMnode, authReq.user, &pUser));
6,207,751✔
4574

4575
  TAOS_CHECK_EXIT(mndSetUserAuthRsp(pMnode, pUser, &authRsp));
6,206,683✔
4576

4577
  contLen = tSerializeSGetUserAuthRsp(NULL, 0, &authRsp);
6,206,683✔
4578
  if (contLen < 0) {
6,206,683✔
UNCOV
4579
    TAOS_CHECK_EXIT(contLen);
×
4580
  }
4581
  pRsp = rpcMallocCont(contLen);
6,206,683✔
4582
  if (pRsp == NULL) {
6,206,683✔
UNCOV
4583
    TAOS_CHECK_EXIT(terrno);
×
4584
  }
4585

4586
  contLen = tSerializeSGetUserAuthRsp(pRsp, contLen, &authRsp);
6,206,683✔
4587
  if (contLen < 0) {
6,206,683✔
UNCOV
4588
    TAOS_CHECK_EXIT(contLen);
×
4589
  }
4590

4591
_exit:
6,207,751✔
4592
  mndReleaseUser(pMnode, pUser);
6,207,751✔
4593
  tFreeSGetUserAuthRsp(&authRsp);
6,207,751✔
4594
  if (code < 0) {
6,207,751✔
4595
    mError("user:%s, failed to get auth at line %d since %s", authReq.user, lino, tstrerror(code));
1,068✔
4596
    rpcFreeCont(pRsp);
1,068✔
4597
    pRsp = NULL;
1,068✔
4598
    contLen = 0;
1,068✔
4599
  }
4600
  pReq->info.rsp = pRsp;
6,207,751✔
4601
  pReq->info.rspLen = contLen;
6,207,751✔
4602
  pReq->code = code;
6,207,751✔
4603

4604
  TAOS_RETURN(code);
6,207,751✔
4605
}
4606

4607
static void base32Encode(const uint8_t *in, int32_t inLen, char *out) {
15,156✔
4608
  int buffer = 0, bits = 0;
15,156✔
4609
  int outLen = 0;
15,156✔
4610

4611
  // process all input bytes
4612
  for (int i = 0; i < inLen; i++) {
500,148✔
4613
    buffer = (buffer << 8) | in[i];
484,992✔
4614
    bits += 8;
484,992✔
4615

4616
    while (bits >= 5) {
1,257,948✔
4617
      int v = (buffer >> (bits - 5)) & 0x1F;
772,956✔
4618
      out[outLen++] = (v >= 26) ? (v - 26 + '2') : (v + 'A');
772,956✔
4619
      bits -= 5;
772,956✔
4620
    }
4621
  }
4622

4623
  // process remaining bits
4624
  if (bits > 0) {
15,156✔
4625
    int v = (buffer << (5 - bits)) & 0x1F;
15,156✔
4626
    out[outLen++] = (v >= 26) ? (v - 26 + '2') : (v + 'A');
15,156✔
4627
  }
4628

4629
  out[outLen] = '\0';
15,156✔
4630
}
15,156✔
4631

4632
static int32_t mndCreateTotpSecret(SMnode *pMnode, SUserObj *pUser, SRpcMsg *pReq) {
15,156✔
4633
  SCreateTotpSecretRsp rsp = {0};
15,156✔
4634

4635
  base32Encode((uint8_t *)pUser->totpsecret, sizeof(pUser->totpsecret), rsp.totpSecret);
15,156✔
4636
  tstrncpy(rsp.user, pUser->user, sizeof(rsp.user));
15,156✔
4637

4638
  int32_t len = tSerializeSCreateTotpSecretRsp(NULL, 0, &rsp);
15,156✔
4639
  if (len < 0) {
15,156✔
UNCOV
4640
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
4641
  }
4642

4643
  void *pData = taosMemoryMalloc(len);
15,156✔
4644
  if (pData == NULL) {
15,156✔
4645
    TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
4646
  }
4647

4648
  if (tSerializeSCreateTotpSecretRsp(pData, len, &rsp) != len) {
15,156✔
UNCOV
4649
    taosMemoryFree(pData);
×
UNCOV
4650
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
4651
  }
4652

4653
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "create-totp-secret");
15,156✔
4654
  if (pTrans == NULL) {
15,156✔
UNCOV
4655
    mError("user:%s, failed to create totp secret since %s", pUser->user, terrstr());
×
UNCOV
4656
    taosMemoryFree(pData);
×
UNCOV
4657
    TAOS_RETURN(terrno);
×
4658
  }
4659
  mInfo("trans:%d, used to create totp secret for user:%s", pTrans->id, pUser->user);
15,156✔
4660

4661
  mndTransSetUserData(pTrans, pData, len);
15,156✔
4662

4663
  SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
15,156✔
4664
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
15,156✔
UNCOV
4665
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
UNCOV
4666
    mndTransDrop(pTrans);
×
UNCOV
4667
    TAOS_RETURN(terrno);
×
4668
  }
4669
  if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY) < 0) {
15,156✔
UNCOV
4670
    mndTransDrop(pTrans);
×
UNCOV
4671
    TAOS_RETURN(terrno);
×
4672
  }
4673

4674
  if (mndTransPrepare(pMnode, pTrans) != 0) {
15,156✔
4675
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
UNCOV
4676
    mndTransDrop(pTrans);
×
UNCOV
4677
    TAOS_RETURN(terrno);
×
4678
  }
4679

4680
  mndTransDrop(pTrans);
15,156✔
4681
  TAOS_RETURN(0);
15,156✔
4682
}
4683

4684
static int32_t mndProcessCreateTotpSecretReq(SRpcMsg *pReq) {
15,296✔
4685
  SMnode              *pMnode = pReq->info.node;
15,296✔
4686
  int32_t              code = 0;
15,296✔
4687
  int32_t              lino = 0;
15,296✔
4688
  SUserObj            *pUser = NULL;
15,296✔
4689
  SUserObj             newUser = {0};
15,296✔
4690
  SCreateTotpSecretReq req = {0};
15,296✔
4691
  int64_t              tss = taosGetTimestampMs();
15,296✔
4692

4693
  TAOS_CHECK_GOTO(tDeserializeSCreateTotpSecretReq(pReq->pCont, pReq->contLen, &req), &lino, _OVER);
15,296✔
4694
  mTrace("user:%s, start to create/update totp secret", req.user);
15,296✔
4695

4696
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, req.user, &pUser), &lino, _OVER);
15,296✔
4697
  TAOS_CHECK_GOTO(mndCheckTotpSecretPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser, PRIV_TOTP_CREATE),
15,156✔
4698
                  &lino, _OVER);
4699
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
15,156✔
4700
  taosSafeRandBytes((uint8_t *)newUser.totpsecret, sizeof(newUser.totpsecret));
15,156✔
4701
  TAOS_CHECK_GOTO(mndCreateTotpSecret(pMnode, &newUser, pReq), &lino, _OVER);
15,156✔
4702

4703
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
15,156✔
4704
    double duration = (double)(taosGetTimestampMs() - tss) / 1000.0;
15,156✔
4705
    auditRecord(pReq, pMnode->clusterId, "createTotpSecret", "", req.user, req.sql, req.sqlLen, duration, 0);
15,156✔
4706
  }
4707

4708
_OVER:
15,296✔
4709
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
15,296✔
4710
    mError("user:%s, failed to create totp secret at line %d since %s", req.user, lino, tstrerror(code));
140✔
4711
  }
4712
  mndReleaseUser(pMnode, pUser);
15,296✔
4713
  mndUserFreeObj(&newUser);
15,296✔
4714
  tFreeSCreateTotpSecretReq(&req);
15,296✔
4715
  TAOS_RETURN(code);
15,296✔
4716
}
4717

4718
int32_t mndBuildSMCreateTotpSecretResp(STrans *pTrans, void **ppResp, int32_t *pRespLen) {
15,156✔
4719
  // user data is the response
4720
  *ppResp = pTrans->userData;
15,156✔
4721
  *pRespLen = pTrans->userDataLen;
15,156✔
4722
  pTrans->userData = NULL;
15,156✔
4723
  pTrans->userDataLen = 0;
15,156✔
4724
  return 0;
15,156✔
4725
}
4726

4727
static int32_t mndProcessDropTotpSecretReq(SRpcMsg *pReq) {
5,880✔
4728
  SMnode            *pMnode = pReq->info.node;
5,880✔
4729
  int32_t            code = 0;
5,880✔
4730
  int32_t            lino = 0;
5,880✔
4731
  SUserObj          *pUser = NULL;
5,880✔
4732
  SUserObj           newUser = {0};
5,880✔
4733
  SDropTotpSecretReq req = {0};
5,880✔
4734
  int64_t            tss = taosGetTimestampMs();
5,880✔
4735

4736
  TAOS_CHECK_GOTO(tDeserializeSDropTotpSecretReq(pReq->pCont, pReq->contLen, &req), &lino, _OVER);
5,880✔
4737
  mTrace("user:%s, start to drop totp secret", req.user);
5,880✔
4738

4739
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, req.user, &pUser), &lino, _OVER);
5,880✔
4740
  TAOS_CHECK_GOTO(mndCheckTotpSecretPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser, PRIV_TOTP_DROP),
4,480✔
4741
                  &lino, _OVER);
4742

4743
  if (!mndIsTotpEnabledUser(pUser)) {
4,480✔
4744
    TAOS_CHECK_GOTO(TSDB_CODE_MND_TOTP_SECRET_NOT_EXIST, &lino, _OVER);
4,200✔
4745
  }
4746

4747
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
280✔
4748
  (void)memset(newUser.totpsecret, 0, sizeof(newUser.totpsecret));
280✔
4749
  TAOS_CHECK_GOTO(mndAlterUser(pMnode, &newUser, pReq), &lino, _OVER);
280✔
4750

4751
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
280✔
4752
    double duration = (double)(taosGetTimestampMs() - tss) / 1000.0;
280✔
4753
    auditRecord(pReq, pMnode->clusterId, "dropTotpSecret", "", req.user, req.sql, req.sqlLen, duration, 0);
280✔
4754
  }
4755

4756
_OVER:
5,880✔
4757
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
5,880✔
4758
    mError("user:%s, failed to drop totp secret at line %d since %s", req.user, lino, tstrerror(code));
5,600✔
4759
  }
4760
  mndReleaseUser(pMnode, pUser);
5,880✔
4761
  mndUserFreeObj(&newUser);
5,880✔
4762
  tFreeSDropTotpSecretReq(&req);
5,880✔
4763
  TAOS_RETURN(code);
5,880✔
4764
}
4765

4766
bool mndIsTotpEnabledUser(SUserObj *pUser) {
4,060,399✔
4767
  for (int32_t i = 0; i < sizeof(pUser->totpsecret); i++) {
132,408,111✔
4768
    if (pUser->totpsecret[i] != 0) {
128,397,045✔
4769
      return true;
49,072✔
4770
    }
4771
  }
4772
  return false;
4,011,066✔
4773
}
4774

4775
static int32_t mndRetrieveUsers(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
126,960✔
4776
  SMnode   *pMnode = pReq->info.node;
126,960✔
4777
  SSdb     *pSdb = pMnode->pSdb;
126,960✔
4778
  int32_t   code = 0;
126,960✔
4779
  int32_t   lino = 0;
126,960✔
4780
  int32_t   numOfRows = 0;
126,960✔
4781
  SUserObj *pUser = NULL;
126,960✔
4782
  int32_t   cols = 0;
126,960✔
4783
  int8_t    flag = 0;
126,960✔
4784
  char     *pWrite = NULL;
126,960✔
4785
  char     *buf = NULL;
126,960✔
4786
  char     *varstr = NULL;
126,960✔
4787
  char      tBuf[TSDB_MAX_SUBROLE * TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
126,960✔
4788
  int32_t   bufSize = sizeof(tBuf) - VARSTR_HEADER_SIZE;
126,960✔
4789

4790
  while (numOfRows < rows) {
1,074,490✔
4791
    pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
1,074,490✔
4792
    if (pShow->pIter == NULL) break;
1,074,490✔
4793

4794
    cols = 0;
947,530✔
4795
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
947,530✔
4796
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
947,530✔
4797
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
947,530✔
4798
    COL_DATA_SET_VAL_GOTO((const char *)name, false, pUser, pShow->pIter, _exit);
947,530✔
4799

4800
    cols++;
947,530✔
4801
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
947,530✔
4802
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->superUser, false, pUser, pShow->pIter, _exit);
947,530✔
4803

4804
    cols++;
947,530✔
4805
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
947,530✔
4806
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->enable, false, pUser, pShow->pIter, _exit);
947,530✔
4807

4808
    cols++;
947,530✔
4809
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
947,530✔
4810
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sysInfo, false, pUser, pShow->pIter, _exit);
947,530✔
4811

4812
    cols++;
947,530✔
4813
    flag = pUser->createdb ? 1 : 0;
947,530✔
4814
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
947,530✔
4815
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
947,530✔
4816

4817
    cols++;
947,530✔
4818
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
947,530✔
4819
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->createdTime, false, pUser, pShow->pIter, _exit);
947,530✔
4820

4821
    cols++;
947,530✔
4822
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
947,530✔
4823
    flag = mndIsTotpEnabledUser(pUser) ? 1 : 0;
947,530✔
4824
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
947,530✔
4825

4826
    cols++;
947,530✔
4827

4828
    int32_t tlen = convertIpWhiteListToStr(pUser, &buf);
947,530✔
4829
    if (tlen != 0) {
947,530✔
4830
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
947,530✔
4831
      if (varstr == NULL) {
947,530✔
UNCOV
4832
        sdbRelease(pSdb, pUser);
×
UNCOV
4833
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
4834
      }
4835
      varDataSetLen(varstr, tlen);
947,530✔
4836
      (void)memcpy(varDataVal(varstr), buf, tlen);
947,530✔
4837

4838
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
947,530✔
4839
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
947,530✔
4840

4841
      taosMemoryFreeClear(buf);
947,530✔
4842
    } else {
UNCOV
4843
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4844
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
4845
    }
4846

4847
    cols++;
947,530✔
4848
    tlen = convertTimeRangesToStr(pUser, &buf);
947,530✔
4849
    if (tlen != 0) {
947,530✔
4850
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
947,530✔
4851
      if (varstr == NULL) {
947,530✔
UNCOV
4852
        sdbRelease(pSdb, pUser);
×
UNCOV
4853
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
4854
      }
4855
      varDataSetLen(varstr, tlen);
947,530✔
4856
      (void)memcpy(varDataVal(varstr), buf, tlen);
947,530✔
4857

4858
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
947,530✔
4859
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
947,530✔
4860

4861
      taosMemoryFreeClear(buf);
947,530✔
4862
    } else {
UNCOV
4863
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4864
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
4865
    }
4866

4867
    if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
947,530✔
4868
      void  *pIter = NULL;
947,530✔
4869
      size_t klen = 0, tlen = 0;
947,530✔
4870
      char  *pBuf = POINTER_SHIFT(tBuf, VARSTR_HEADER_SIZE);
947,530✔
4871
      while ((pIter = taosHashIterate(pUser->roles, pIter))) {
2,149,278✔
4872
        char *roleName = taosHashGetKey(pIter, &klen);
1,201,748✔
4873
        tlen += snprintf(pBuf + tlen, bufSize - tlen, "%s,", roleName);
1,201,748✔
4874
      }
4875
      if (tlen > 0) {
947,530✔
4876
        pBuf[--tlen] = 0;  // remove last ','
947,530✔
4877
      } else {
UNCOV
4878
        pBuf[0] = 0;
×
4879
      }
4880
      varDataSetLen(tBuf, tlen);
947,530✔
4881
      COL_DATA_SET_VAL_GOTO((const char *)tBuf, false, pUser, pShow->pIter, _exit);
947,530✔
4882
    }
4883

4884
    numOfRows++;
947,530✔
4885
    sdbRelease(pSdb, pUser);
947,530✔
4886
  }
4887

4888
  pShow->numOfRows += numOfRows;
126,960✔
4889
_exit:
126,960✔
4890
  taosMemoryFreeClear(buf);
126,960✔
4891
  taosMemoryFreeClear(varstr);
126,960✔
4892
  if (code < 0) {
126,960✔
NEW
4893
    mError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
UNCOV
4894
    TAOS_RETURN(code);
×
4895
  }
4896
  return numOfRows;
126,960✔
4897
}
4898

4899
static int32_t mndRetrieveUsersFull(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
11,520✔
4900
  int32_t numOfRows = 0;
11,520✔
4901
#ifdef TD_ENTERPRISE
4902
  SMnode   *pMnode = pReq->info.node;
11,520✔
4903
  SSdb     *pSdb = pMnode->pSdb;
11,520✔
4904
  SUserObj *pUser = NULL;
11,520✔
4905
  int32_t   code = 0;
11,520✔
4906
  int32_t   lino = 0;
11,520✔
4907
  int32_t   cols = 0;
11,520✔
4908
  int8_t    flag = 0;
11,520✔
4909
  char     *pWrite = NULL;
11,520✔
4910
  char     *buf = NULL;
11,520✔
4911
  char     *varstr = NULL;
11,520✔
4912
  char     *pBuf = NULL;
11,520✔
4913
  char      tBuf[TSDB_MAX_SUBROLE * TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
11,520✔
4914
  int32_t   bufSize = sizeof(tBuf) - VARSTR_HEADER_SIZE;
11,520✔
4915

4916
  while (numOfRows < rows) {
514,048✔
4917
    pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
514,048✔
4918
    if (pShow->pIter == NULL) break;
514,048✔
4919

4920
    cols = 0;
502,528✔
4921
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
502,528✔
4922
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
502,528✔
4923
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
502,528✔
4924
    COL_DATA_SET_VAL_GOTO((const char *)name, false, pUser, pShow->pIter, _exit);
502,528✔
4925

4926
    cols++;
502,528✔
4927
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
502,528✔
4928
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->superUser, false, pUser, pShow->pIter, _exit);
502,528✔
4929

4930
    cols++;
502,528✔
4931
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
502,528✔
4932
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->enable, false, pUser, pShow->pIter, _exit);
502,528✔
4933

4934
    cols++;
502,528✔
4935
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
502,528✔
4936
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sysInfo, false, pUser, pShow->pIter, _exit);
502,528✔
4937

4938
    cols++;
502,528✔
4939
    flag = pUser->createdb ? 1 : 0;
502,528✔
4940
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
502,528✔
4941
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
502,528✔
4942

4943
    cols++;
502,528✔
4944
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
502,528✔
4945
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->createdTime, false, pUser, pShow->pIter, _exit);
502,528✔
4946

4947
    cols++;
502,528✔
4948
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
502,528✔
4949
    flag = mndIsTotpEnabledUser(pUser) ? 1 : 0;
502,528✔
4950
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
502,528✔
4951

4952
    cols++;
502,528✔
4953
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
502,528✔
4954
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->changePass, false, pUser, pShow->pIter, _exit);
502,528✔
4955

4956
    cols++;
502,528✔
4957
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
502,528✔
4958
    char pass[TSDB_PASSWORD_LEN + VARSTR_HEADER_SIZE] = {0};
502,528✔
4959
    STR_WITH_MAXSIZE_TO_VARSTR(pass, pUser->passwords[0].pass, pShow->pMeta->pSchemas[cols].bytes);
502,528✔
4960
    COL_DATA_SET_VAL_GOTO((const char *)pass, false, pUser, pShow->pIter, _exit);
502,528✔
4961

4962
    cols++;
502,528✔
4963
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
502,528✔
4964
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sessionPerUser, false, pUser, pShow->pIter, _exit);
502,528✔
4965

4966
    cols++;
502,528✔
4967
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
502,528✔
4968
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->connectTime, false, pUser, pShow->pIter, _exit);
502,528✔
4969

4970
    cols++;
502,528✔
4971
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
502,528✔
4972
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->connectIdleTime, false, pUser, pShow->pIter, _exit);
502,528✔
4973

4974
    cols++;
502,528✔
4975
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
502,528✔
4976
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->callPerSession, false, pUser, pShow->pIter, _exit);
502,528✔
4977

4978
    cols++;
502,528✔
4979
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
502,528✔
4980
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->vnodePerCall, false, pUser, pShow->pIter, _exit);
502,528✔
4981

4982
    cols++;
502,528✔
4983
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
502,528✔
4984
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->failedLoginAttempts, false, pUser, pShow->pIter, _exit);
502,528✔
4985

4986
    cols++;
502,528✔
4987
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
502,528✔
4988
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordLifeTime, false, pUser, pShow->pIter, _exit);
502,528✔
4989

4990
    cols++;
502,528✔
4991
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
502,528✔
4992
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordReuseTime, false, pUser, pShow->pIter, _exit);
502,528✔
4993

4994
    cols++;
502,528✔
4995
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
502,528✔
4996
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordReuseMax, false, pUser, pShow->pIter, _exit);
502,528✔
4997

4998
    cols++;
502,528✔
4999
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
502,528✔
5000
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordLockTime, false, pUser, pShow->pIter, _exit);
502,528✔
5001

5002
    cols++;
502,528✔
5003
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
502,528✔
5004
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordGraceTime, false, pUser, pShow->pIter, _exit);
502,528✔
5005

5006
    cols++;
502,528✔
5007
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
502,528✔
5008
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->inactiveAccountTime, false, pUser, pShow->pIter, _exit);
502,528✔
5009

5010
    cols++;
502,528✔
5011
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
502,528✔
5012
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->allowTokenNum, false, pUser, pShow->pIter, _exit);
502,528✔
5013

5014
    cols++;
502,528✔
5015
    int32_t tlen = convertIpWhiteListToStr(pUser, &buf);
502,528✔
5016
    if (tlen != 0) {
502,528✔
5017
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
502,528✔
5018
      if (varstr == NULL) {
502,528✔
UNCOV
5019
        sdbRelease(pSdb, pUser);
×
UNCOV
5020
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
5021
      }
5022
      varDataSetLen(varstr, tlen);
502,528✔
5023
      (void)memcpy(varDataVal(varstr), buf, tlen);
502,528✔
5024

5025
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
502,528✔
5026
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
502,528✔
5027

5028
      taosMemoryFreeClear(buf);
502,528✔
5029
    } else {
5030
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
5031
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
5032
    }
5033

5034
    cols++;
502,528✔
5035
    tlen = convertTimeRangesToStr(pUser, &buf);
502,528✔
5036
    if (tlen != 0) {
502,528✔
5037
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
502,528✔
5038
      if (varstr == NULL) {
502,528✔
5039
        sdbRelease(pSdb, pUser);
×
UNCOV
5040
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
5041
      }
5042
      varDataSetLen(varstr, tlen);
502,528✔
5043
      (void)memcpy(varDataVal(varstr), buf, tlen);
502,528✔
5044

5045
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
502,528✔
5046
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
502,528✔
5047

5048
      taosMemoryFreeClear(buf);
502,528✔
5049
    } else {
UNCOV
5050
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
5051
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
5052
    }
5053

5054
    if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
502,528✔
5055
      void  *pIter = NULL;
502,528✔
5056
      size_t klen = 0, tlen = 0;
502,528✔
5057
      char  *pBuf = POINTER_SHIFT(tBuf, VARSTR_HEADER_SIZE);
502,528✔
5058
      while ((pIter = taosHashIterate(pUser->roles, pIter))) {
1,028,096✔
5059
        char *roleName = taosHashGetKey(pIter, &klen);
525,568✔
5060
        tlen += snprintf(pBuf + tlen, bufSize - tlen, "%s,", roleName);
525,568✔
5061
      }
5062
      if (tlen > 0) {
502,528✔
5063
        pBuf[--tlen] = 0;  // remove last ','
502,528✔
5064
      } else {
UNCOV
5065
        pBuf[0] = 0;
×
5066
      }
5067
      varDataSetLen(tBuf, tlen);
502,528✔
5068
      COL_DATA_SET_VAL_GOTO((const char *)tBuf, false, pUser, pShow->pIter, _exit);
502,528✔
5069
    }
5070

5071
    numOfRows++;
502,528✔
5072
    sdbRelease(pSdb, pUser);
502,528✔
5073
  }
5074

5075
  pShow->numOfRows += numOfRows;
11,520✔
5076
_exit:
11,520✔
5077
  taosMemoryFreeClear(buf);
11,520✔
5078
  taosMemoryFreeClear(varstr);
11,520✔
5079
  if (code < 0) {
11,520✔
NEW
5080
    mError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
UNCOV
5081
    TAOS_RETURN(code);
×
5082
  }
5083
#endif
5084
  return numOfRows;
11,520✔
5085
}
5086

UNCOV
5087
static void mndCancelGetNextUser(SMnode *pMnode, void *pIter) {
×
UNCOV
5088
  SSdb *pSdb = pMnode->pSdb;
×
UNCOV
5089
  sdbCancelFetchByType(pSdb, pIter, SDB_USER);
×
5090
}
×
5091

UNCOV
5092
static int32_t mndLoopHash(SHashObj *hash, char *priType, SSDataBlock *pBlock, int32_t *pNumOfRows, SSdb *pSdb,
×
5093
                           SUserObj *pUser, SShowObj *pShow, char **condition, char **sql) {
UNCOV
5094
  char   *value = taosHashIterate(hash, NULL);
×
5095
  char   *user = pUser->user;
×
UNCOV
5096
  int32_t code = 0;
×
UNCOV
5097
  int32_t lino = 0;
×
UNCOV
5098
  int32_t cols = 0;
×
5099
  int32_t numOfRows = *pNumOfRows;
×
5100

UNCOV
5101
  while (value != NULL) {
×
UNCOV
5102
    cols = 0;
×
UNCOV
5103
    char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
×
UNCOV
5104
    STR_WITH_MAXSIZE_TO_VARSTR(userName, user, pShow->pMeta->pSchemas[cols].bytes);
×
5105
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
5106
    COL_DATA_SET_VAL_GOTO((const char *)userName, false, NULL, NULL, _exit);
×
5107

UNCOV
5108
    char privilege[20] = {0};
×
UNCOV
5109
    STR_WITH_MAXSIZE_TO_VARSTR(privilege, priType, pShow->pMeta->pSchemas[cols].bytes);
×
UNCOV
5110
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
UNCOV
5111
    COL_DATA_SET_VAL_GOTO((const char *)privilege, false, NULL, NULL, _exit);
×
5112

UNCOV
5113
    size_t keyLen = 0;
×
UNCOV
5114
    void  *key = taosHashGetKey(value, &keyLen);
×
5115

5116
    char dbName[TSDB_DB_NAME_LEN] = {0};
×
5117
    (void)mndExtractShortDbNameFromStbFullName(key, dbName);
×
UNCOV
5118
    char dbNameContent[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
×
UNCOV
5119
    STR_WITH_MAXSIZE_TO_VARSTR(dbNameContent, dbName, pShow->pMeta->pSchemas[cols].bytes);
×
5120
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
5121
    COL_DATA_SET_VAL_GOTO((const char *)dbNameContent, false, NULL, NULL, _exit);
×
5122

UNCOV
5123
    char tableName[TSDB_TABLE_NAME_LEN] = {0};
×
UNCOV
5124
    mndExtractTbNameFromStbFullName(key, tableName, TSDB_TABLE_NAME_LEN);
×
5125
    char tableNameContent[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
×
5126
    STR_WITH_MAXSIZE_TO_VARSTR(tableNameContent, tableName, pShow->pMeta->pSchemas[cols].bytes);
×
5127
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
UNCOV
5128
    COL_DATA_SET_VAL_GOTO((const char *)tableNameContent, false, NULL, NULL, _exit);
×
5129

UNCOV
5130
    if (strcmp("t", value) != 0 && strcmp("v", value) != 0) {
×
UNCOV
5131
      SNode  *pAst = NULL;
×
UNCOV
5132
      int32_t sqlLen = 0;
×
UNCOV
5133
      size_t  bufSz = strlen(value) + 1;
×
UNCOV
5134
      if (bufSz < 6) bufSz = 6;
×
UNCOV
5135
      TAOS_MEMORY_REALLOC(*sql, bufSz);
×
UNCOV
5136
      if (*sql == NULL) {
×
UNCOV
5137
        code = terrno;
×
UNCOV
5138
        goto _exit;
×
5139
      }
UNCOV
5140
      TAOS_MEMORY_REALLOC(*condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
×
UNCOV
5141
      if ((*condition) == NULL) {
×
UNCOV
5142
        code = terrno;
×
UNCOV
5143
        goto _exit;
×
5144
      }
5145

UNCOV
5146
      if (nodesStringToNode(value, &pAst) == 0) {
×
UNCOV
5147
        if (nodesNodeToSQLFormat(pAst, *sql, bufSz, &sqlLen, true) != 0) {
×
UNCOV
5148
          sqlLen = tsnprintf(*sql, bufSz, "error");
×
5149
        }
UNCOV
5150
        nodesDestroyNode(pAst);
×
5151
      }
5152

UNCOV
5153
      if (sqlLen == 0) {
×
UNCOV
5154
        sqlLen = tsnprintf(*sql, bufSz, "error");
×
5155
      }
5156

UNCOV
5157
      STR_WITH_MAXSIZE_TO_VARSTR((*condition), (*sql), pShow->pMeta->pSchemas[cols].bytes);
×
5158

UNCOV
5159
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
UNCOV
5160
      COL_DATA_SET_VAL_GOTO((const char *)(*condition), false, NULL, NULL, _exit);
×
5161

UNCOV
5162
      char notes[2] = {0};
×
UNCOV
5163
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
×
UNCOV
5164
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
UNCOV
5165
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, NULL, NULL, _exit);
×
5166
    } else {
UNCOV
5167
      TAOS_MEMORY_REALLOC(*condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
×
UNCOV
5168
      if ((*condition) == NULL) {
×
UNCOV
5169
        code = terrno;
×
UNCOV
5170
        goto _exit;
×
5171
      }
UNCOV
5172
      STR_WITH_MAXSIZE_TO_VARSTR((*condition), "", pShow->pMeta->pSchemas[cols].bytes);
×
UNCOV
5173
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
UNCOV
5174
      COL_DATA_SET_VAL_GOTO((const char *)(*condition), false, NULL, NULL, _exit);
×
5175

UNCOV
5176
      char notes[64 + VARSTR_HEADER_SIZE] = {0};
×
UNCOV
5177
      STR_WITH_MAXSIZE_TO_VARSTR(notes, value[0] == 'v' ? "view" : "", sizeof(notes));
×
UNCOV
5178
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
UNCOV
5179
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, NULL, NULL, _exit);
×
5180
    }
5181

UNCOV
5182
    numOfRows++;
×
UNCOV
5183
    value = taosHashIterate(hash, value);
×
5184
  }
UNCOV
5185
  *pNumOfRows = numOfRows;
×
UNCOV
5186
_exit:
×
UNCOV
5187
  if (code < 0) {
×
NEW
5188
    mError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
UNCOV
5189
    sdbRelease(pSdb, pUser);
×
UNCOV
5190
    sdbCancelFetch(pSdb, pShow->pIter);
×
5191
  }
UNCOV
5192
  TAOS_RETURN(code);
×
5193
}
5194

5195
#if 0
5196
static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
5197
  int32_t   code = 0;
5198
  int32_t   lino = 0;
5199
  SMnode   *pMnode = pReq->info.node;
5200
  SSdb     *pSdb = pMnode->pSdb;
5201
  int32_t   numOfRows = 0;
5202
  SUserObj *pUser = NULL;
5203
  int32_t   cols = 0;
5204
  char     *pWrite = NULL;
5205
  char     *condition = NULL;
5206
  char     *sql = NULL;
5207

5208
  bool fetchNextUser = pShow->restore ? false : true;
5209
  pShow->restore = false;
5210

5211
  while (numOfRows < rows) {
5212
    if (fetchNextUser) {
5213
      pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
5214
      if (pShow->pIter == NULL) break;
5215
    } else {
5216
      fetchNextUser = true;
5217
      void *pKey = taosHashGetKey(pShow->pIter, NULL);
5218
      pUser = sdbAcquire(pSdb, SDB_USER, pKey);
5219
      if (!pUser) {
5220
        continue;
5221
      }
5222
    }
5223

5224
    int32_t numOfReadDbs = 0; //taosHashGetSize(pUser->readDbs);
5225
    int32_t numOfWriteDbs = 0; //taosHashGetSize(pUser->writeDbs);
5226
    int32_t numOfTopics = taosHashGetSize(pUser->topics);
5227
    int32_t numOfReadTbs = taosHashGetSize(pUser->selectTbs);
5228
    int32_t numOfWriteTbs = taosHashGetSize(pUser->insertTbs);
5229
    int32_t numOfAlterTbs = taosHashGetSize(pUser->alterTbs);
5230
    int32_t numOfReadViews = taosHashGetSize(pUser->readViews);
5231
    int32_t numOfWriteViews = taosHashGetSize(pUser->writeViews);
5232
    int32_t numOfAlterViews = taosHashGetSize(pUser->alterViews);
5233
    if (numOfRows + numOfReadDbs + numOfWriteDbs + numOfTopics + numOfReadTbs + numOfWriteTbs + numOfAlterTbs +
5234
            numOfReadViews + numOfWriteViews + numOfAlterViews >=
5235
        rows) {
5236
      mInfo(
5237
          "will restore. current num of rows: %d, read dbs %d, write dbs %d, topics %d, read tables %d, write tables "
5238
          "%d, alter tables %d, select views %d, write views %d, alter views %d",
5239
          numOfRows, numOfReadDbs, numOfWriteDbs, numOfTopics, numOfReadTbs, numOfWriteTbs, numOfAlterTbs,
5240
          numOfReadViews, numOfWriteViews, numOfAlterViews);
5241
      pShow->restore = true;
5242
      sdbRelease(pSdb, pUser);
5243
      break;
5244
    }
5245

5246
    if (pUser->superUser) {
5247
      cols = 0;
5248
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
5249
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
5250
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5251
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
5252

5253
      char privilege[20] = {0};
5254
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "all", pShow->pMeta->pSchemas[cols].bytes);
5255
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5256
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
5257

5258
      char objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
5259
      STR_WITH_MAXSIZE_TO_VARSTR(objName, "all", pShow->pMeta->pSchemas[cols].bytes);
5260
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5261
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
5262

5263
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
5264
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
5265
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5266
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
5267

5268
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
5269
      if (condition == NULL) {
5270
        sdbRelease(pSdb, pUser);
5271
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
5272
      }
5273
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
5274
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5275
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
5276

5277
      char notes[2] = {0};
5278
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
5279
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5280
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
5281

5282
      numOfRows++;
5283
    }
5284
#if 0
5285
    char *db = taosHashIterate(pUser->readDbs, NULL);
5286
    while (db != NULL) {
5287
      cols = 0;
5288
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
5289
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
5290
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5291
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
5292

5293
      char privilege[20] = {0};
5294
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "read", pShow->pMeta->pSchemas[cols].bytes);
5295
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5296
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
5297

5298
      SName name = {0};
5299
      char  objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
5300
      code = tNameFromString(&name, db, T_NAME_ACCT | T_NAME_DB);
5301
      if (code < 0) {
5302
        sdbRelease(pSdb, pUser);
5303
        sdbCancelFetch(pSdb, pShow->pIter);
5304
        TAOS_CHECK_GOTO(code, &lino, _exit);
5305
      }
5306
      (void)tNameGetDbName(&name, varDataVal(objName));
5307
      varDataSetLen(objName, strlen(varDataVal(objName)));
5308
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5309
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
5310

5311
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
5312
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
5313
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5314
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
5315

5316
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
5317
      if (condition == NULL) {
5318
        sdbRelease(pSdb, pUser);
5319
        sdbCancelFetch(pSdb, pShow->pIter);
5320
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
5321
      }
5322
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
5323
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5324
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
5325

5326
      char notes[2] = {0};
5327
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
5328
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5329
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
5330

5331
      numOfRows++;
5332
      db = taosHashIterate(pUser->readDbs, db);
5333
    }
5334

5335
    db = taosHashIterate(pUser->writeDbs, NULL);
5336
    while (db != NULL) {
5337
      cols = 0;
5338
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
5339
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
5340
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5341
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
5342

5343
      char privilege[20] = {0};
5344
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "write", pShow->pMeta->pSchemas[cols].bytes);
5345
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5346
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
5347

5348
      SName name = {0};
5349
      char  objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
5350
      code = tNameFromString(&name, db, T_NAME_ACCT | T_NAME_DB);
5351
      if (code < 0) {
5352
        sdbRelease(pSdb, pUser);
5353
        sdbCancelFetch(pSdb, pShow->pIter);
5354
        TAOS_CHECK_GOTO(code, &lino, _exit);
5355
      }
5356
      (void)tNameGetDbName(&name, varDataVal(objName));
5357
      varDataSetLen(objName, strlen(varDataVal(objName)));
5358
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5359
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
5360

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

5366
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
5367
      if (condition == NULL) {
5368
        sdbRelease(pSdb, pUser);
5369
        sdbCancelFetch(pSdb, pShow->pIter);
5370
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
5371
      }
5372
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
5373
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5374
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
5375

5376
      char notes[2] = {0};
5377
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
5378
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5379
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
5380

5381
      numOfRows++;
5382
      db = taosHashIterate(pUser->writeDbs, db);
5383
    }
5384
#endif
5385
    TAOS_CHECK_EXIT(mndLoopHash(pUser->selectTbs, "select", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
5386

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

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

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

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

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

5397
    char *topic = taosHashIterate(pUser->topics, NULL);
5398
    while (topic != NULL) {
5399
      cols = 0;
5400
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
5401
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
5402
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5403
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
5404

5405
      char privilege[20] = {0};
5406
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "subscribe", pShow->pMeta->pSchemas[cols].bytes);
5407
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5408
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
5409

5410
      char topicName[TSDB_TOPIC_NAME_LEN + VARSTR_HEADER_SIZE + 5] = {0};
5411
      tstrncpy(varDataVal(topicName), mndGetDbStr(topic), TSDB_TOPIC_NAME_LEN - 2);
5412
      varDataSetLen(topicName, strlen(varDataVal(topicName)));
5413
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5414
      COL_DATA_SET_VAL_GOTO((const char *)topicName, false, pUser, pShow->pIter, _exit);
5415

5416
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
5417
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
5418
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5419
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
5420

5421
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
5422
      if (condition == NULL) {
5423
        sdbRelease(pSdb, pUser);
5424
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
5425
      }
5426
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
5427
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5428
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
5429

5430
      char notes[2] = {0};
5431
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
5432
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5433
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
5434

5435
      numOfRows++;
5436
      topic = taosHashIterate(pUser->topics, topic);
5437
    }
5438

5439
    sdbRelease(pSdb, pUser);
5440
  }
5441

5442
  pShow->numOfRows += numOfRows;
5443
_exit:
5444
  taosMemoryFreeClear(condition);
5445
  taosMemoryFreeClear(sql);
5446
  if (code < 0) {
5447
    mError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
5448
    TAOS_RETURN(code);
5449
  }
5450
  return numOfRows;
5451
}
5452
#endif
5453

5454
int32_t mndShowTablePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows, void *pObj,
202,980✔
5455
                               const char *principalName, SHashObj *privTbs, EPrivType privType, char *pBuf,
5456
                               int32_t bufSize, int32_t *pNumOfRows) {
5457
  int32_t     code = 0, lino = 0;
202,980✔
5458
  SMnode     *pMnode = pReq->info.node;
202,980✔
5459
  SSdb       *pSdb = pMnode->pSdb;
202,980✔
5460
  int32_t     cols = 0, qBufSize = bufSize - VARSTR_HEADER_SIZE;
202,980✔
5461
  int32_t     numOfRows = *pNumOfRows;
202,980✔
5462
  char       *qBuf = NULL;
202,980✔
5463
  char       *sql = NULL;
202,980✔
5464
  char        roleName[TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
202,980✔
5465
  const char *privName = privInfoGetName(privType);
202,980✔
5466

5467
  STR_WITH_MAXSIZE_TO_VARSTR(roleName, principalName, pShow->pMeta->pSchemas[cols].bytes);
202,980✔
5468

5469
  void *pIter = NULL;
202,980✔
5470
  while ((pIter = taosHashIterate(privTbs, pIter))) {
233,422✔
5471
    SPrivTblPolicies *pPolices = (SPrivTblPolicies *)pIter;
30,442✔
5472
    SArray           *tblPolicies = pPolices->policy;
30,442✔
5473

5474
    char   *key = taosHashGetKey(pPolices, NULL);
30,442✔
5475
    int32_t objType = PRIV_OBJ_UNKNOWN;
30,442✔
5476
    char    dbName[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
30,442✔
5477
    char    tblName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
30,442✔
5478
    if ((code = privObjKeyParse(key, &objType, dbName, sizeof(dbName), tblName, sizeof(tblName), false))) {
30,442✔
UNCOV
5479
      sdbRelease(pSdb, pObj);
×
UNCOV
5480
      sdbCancelFetch(pSdb, pShow->pIter);
×
5481
      TAOS_CHECK_EXIT(code);
×
5482
    }
5483

5484
    int32_t nTbPolicies = taosArrayGetSize(tblPolicies);
30,442✔
5485
    for (int32_t i = 0; i < nTbPolicies; ++i) {
60,884✔
5486
      SPrivTblPolicy *tbPolicy = (SPrivTblPolicy *)TARRAY_GET_ELEM(tblPolicies, i);
30,442✔
5487
      cols = 0;
30,442✔
5488
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
30,442✔
5489
      COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
30,442✔
5490

5491
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
30,442✔
5492
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privName, pShow->pMeta->pSchemas[cols].bytes);
30,442✔
5493
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
30,442✔
5494
      }
5495

5496
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
30,442✔
5497
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privObjGetName(objType), pShow->pMeta->pSchemas[cols].bytes);
30,442✔
5498
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
30,442✔
5499
      }
5500

5501
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
30,442✔
5502
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, dbName, pShow->pMeta->pSchemas[cols].bytes);
30,442✔
5503
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
30,442✔
5504
      }
5505

5506
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
30,442✔
5507
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, tblName, pShow->pMeta->pSchemas[cols].bytes);
30,442✔
5508
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
30,442✔
5509
      }
5510
      // condition
5511
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
30,442✔
5512
        SNode  *pAst = NULL;
30,442✔
5513
        int32_t sqlLen = 0;
30,442✔
5514
        qBuf = POINTER_SHIFT(pBuf, VARSTR_HEADER_SIZE);
30,442✔
5515
        if (tbPolicy->condLen > 0) {
30,442✔
5516
          if (nodesStringToNode(tbPolicy->cond, &pAst) == 0) {
30,442✔
5517
            if (nodesNodeToSQLFormat(pAst, qBuf, qBufSize, &sqlLen, true) != 0) {
30,442✔
UNCOV
5518
              sqlLen = tsnprintf(qBuf, qBufSize, "error");
×
5519
            }
5520
            nodesDestroyNode(pAst);
30,442✔
5521
          }
5522
          if (sqlLen == 0) {
30,442✔
UNCOV
5523
            sqlLen = tsnprintf(qBuf, qBufSize, "error");
×
5524
          }
5525
        } else {
UNCOV
5526
          sqlLen = tsnprintf(qBuf, qBufSize, "");
×
5527
        }
5528
        varDataSetLen(pBuf, sqlLen);
30,442✔
5529
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
30,442✔
5530
      }
5531
      // notes
5532
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
30,442✔
5533
        STR_WITH_MAXSIZE_TO_VARSTR((pBuf), "", 2);
30,442✔
5534
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
30,442✔
5535
      }
5536
      // columns
5537
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
30,442✔
5538
        SArray *pCols = tbPolicy->cols;
30,442✔
5539
        int32_t nCols = taosArrayGetSize(pCols);
30,442✔
5540
        int32_t totalLen = 0;
30,442✔
5541
        qBuf = POINTER_SHIFT(pBuf, VARSTR_HEADER_SIZE);
30,442✔
5542
        for (int32_t j = 0; j < nCols; ++j) {
30,442✔
5543
          SColNameFlag *pCol = (SColNameFlag *)TARRAY_GET_ELEM(pCols, j);
×
UNCOV
5544
          char          tmpBuf[TSDB_COL_NAME_LEN + 16] = {0};
×
5545
          int32_t       tmpLen = 0;
×
5546
          if (IS_MASK_ON(pCol)) {
×
5547
            tmpLen = snprintf(tmpBuf, sizeof(tmpBuf), "mask(%s)%s", pCol->colName, j == nCols - 1 ? "" : ",");
×
5548
          } else {
5549
            tmpLen = snprintf(tmpBuf, sizeof(tmpBuf), "%s%s", pCol->colName, j == nCols - 1 ? "" : ",");
×
5550
          }
NEW
5551
          if (totalLen + tmpLen > qBufSize) {
×
5552
            break;
×
5553
          }
5554
          (void)memcpy(POINTER_SHIFT(qBuf, totalLen), tmpBuf, tmpLen);
×
5555
          totalLen += tmpLen;
×
5556
        }
5557
        varDataSetLen(pBuf, totalLen);
30,442✔
5558
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
30,442✔
5559
      }
5560
      // update_time
5561
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
30,442✔
5562
        char updateTime[40] = {0};
30,442✔
5563
        (void)formatTimestampLocal(updateTime, tbPolicy->updateUs, TSDB_TIME_PRECISION_MICRO);
30,442✔
5564
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, updateTime, pShow->pMeta->pSchemas[cols].bytes);
30,442✔
5565
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
30,442✔
5566
      }
5567
      ++numOfRows;
30,442✔
5568
    }
5569
  }
5570
  *pNumOfRows = numOfRows;
202,980✔
5571
_exit:
202,980✔
5572
  TAOS_RETURN(code);
202,980✔
5573
}
5574

5575
static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
8,627✔
5576
  int32_t   code = 0, lino = 0;
8,627✔
5577
  SMnode   *pMnode = pReq->info.node;
8,627✔
5578
  SSdb     *pSdb = pMnode->pSdb;
8,627✔
5579
  int32_t   numOfRows = 0;
8,627✔
5580
  int32_t   cols = 0;
8,627✔
5581
  SUserObj *pObj = NULL;
8,627✔
5582
  char     *pBuf = NULL, *qBuf = NULL;
8,627✔
5583
  char     *sql = NULL;
8,627✔
5584
  char      roleName[TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
8,627✔
5585
  int32_t   bufSize = TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE;
8,627✔
5586

5587
  bool fetchNextInstance = pShow->restore ? false : true;
8,627✔
5588
  pShow->restore = false;
8,627✔
5589

5590
  while (numOfRows < rows) {
54,157✔
5591
    if (fetchNextInstance) {
54,157✔
5592
      pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pObj);
54,157✔
5593
      if (pShow->pIter == NULL) break;
54,157✔
5594
    } else {
UNCOV
5595
      fetchNextInstance = true;
×
UNCOV
5596
      void *pKey = taosHashGetKey(pShow->pIter, NULL);
×
5597
      if (!(pObj = sdbAcquire(pSdb, SDB_USER, pKey))) {
×
5598
        continue;
×
5599
      }
5600
    }
5601

5602
    // count total privileges for current user
5603
    int32_t nSysPrivileges = privPopCnt(&pObj->sysPrivs);
45,530✔
5604
    int32_t nObjPrivileges = 0;
45,530✔
5605
    void   *pIter = NULL;
45,530✔
5606
    while ((pIter = taosHashIterate(pObj->objPrivs, pIter))) {
64,363✔
5607
      SPrivObjPolicies *pPolices = (SPrivObjPolicies *)pIter;
18,833✔
5608
      nObjPrivileges += privPopCnt(&pPolices->policy);
37,666✔
5609
    }
5610
    int32_t nTblPrivileges = privTblPrivCnt(pObj->selectTbs);
45,530✔
5611
    nTblPrivileges += privTblPrivCnt(pObj->insertTbs);
45,530✔
5612
    nTblPrivileges += privTblPrivCnt(pObj->updateTbs);
45,530✔
5613
    nTblPrivileges += privTblPrivCnt(pObj->deleteTbs);
45,530✔
5614

5615
    int32_t totalPrivileges = nSysPrivileges + nObjPrivileges + nTblPrivileges;
45,530✔
5616

5617
    if (numOfRows + totalPrivileges >= rows) {
45,530✔
NEW
5618
      if (totalPrivileges >= SHOW_PRIVILEGES_STEP_SIZE) {
×
NEW
5619
        mError("user:%s, has too many privileges:%d to show", pObj->name, totalPrivileges);
×
NEW
5620
        sdbRelease(pSdb, pObj);
×
NEW
5621
        TAOS_CHECK_EXIT(TSDB_CODE_MND_TOO_MANY_PRIVS);
×
5622
      }
5623
      pShow->restore = true;
×
5624
      sdbRelease(pSdb, pObj);
×
UNCOV
5625
      break;
×
5626
    }
5627

5628
    if (!pBuf && !(pBuf = taosMemoryMalloc(bufSize))) {
45,530✔
5629
      sdbRelease(pSdb, pObj);
×
5630
      TAOS_CHECK_EXIT(terrno);
×
5631
    }
5632

5633
    cols = 0;
45,530✔
5634
    STR_WITH_MAXSIZE_TO_VARSTR(roleName, pObj->name, pShow->pMeta->pSchemas[cols].bytes);
45,530✔
5635

5636
    // system privileges
5637
    SPrivIter privIter = {0};
45,530✔
5638
    privIterInit(&privIter, &pObj->sysPrivs);
45,530✔
5639
    SPrivInfo *pPrivInfo = NULL;
45,530✔
5640
    while (privIterNext(&privIter, &pPrivInfo)) {
49,786✔
5641
      cols = 0;
4,256✔
5642
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
4,256✔
5643
      COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
4,256✔
5644

5645
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
4,256✔
5646
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, pPrivInfo->name, pShow->pMeta->pSchemas[cols].bytes);
4,256✔
5647
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
4,256✔
5648
      }
5649
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
4,256✔
5650
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privObjGetName(PRIV_OBJ_CLUSTER), pShow->pMeta->pSchemas[cols].bytes);
4,256✔
5651
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
4,256✔
5652
      }
5653
      // skip db, table, condition, notes, columns, update_time
5654
      COL_DATA_SET_EMPTY_VARCHAR(pBuf, 6);
29,792✔
5655
      numOfRows++;
4,256✔
5656
    }
5657

5658
    // object privileges
5659
    pIter = NULL;
45,530✔
5660
    while ((pIter = taosHashIterate(pObj->objPrivs, pIter))) {
64,363✔
5661
      SPrivObjPolicies *pPolices = (SPrivObjPolicies *)pIter;
18,833✔
5662

5663
      char   *key = taosHashGetKey(pPolices, NULL);
18,833✔
5664
      int32_t objType = PRIV_OBJ_UNKNOWN;
18,833✔
5665
      char    dbName[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
18,833✔
5666
      char    tblName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
18,833✔
5667
      if ((code = privObjKeyParse(key, &objType, dbName, sizeof(dbName), tblName, sizeof(tblName), false))) {
18,833✔
UNCOV
5668
        sdbRelease(pSdb, pObj);
×
UNCOV
5669
        TAOS_CHECK_EXIT(code);
×
5670
      }
5671

5672
      SPrivIter privIter = {0};
18,833✔
5673
      privIterInit(&privIter, &pPolices->policy);
18,833✔
5674
      SPrivInfo *pPrivInfo = NULL;
18,833✔
5675
      while (privIterNext(&privIter, &pPrivInfo)) {
103,513✔
5676
        cols = 0;
84,680✔
5677
        SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
84,680✔
5678
        COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
84,680✔
5679

5680
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
84,680✔
5681
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, pPrivInfo->name, pShow->pMeta->pSchemas[cols].bytes);
84,680✔
5682
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
84,680✔
5683
        }
5684

5685
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
84,680✔
5686
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privObjGetName(objType), pShow->pMeta->pSchemas[cols].bytes);
84,680✔
5687
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
84,680✔
5688
        }
5689

5690
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
84,680✔
5691
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, dbName, pShow->pMeta->pSchemas[cols].bytes);
84,680✔
5692
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
84,680✔
5693
        }
5694

5695
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
84,680✔
5696
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, tblName, pShow->pMeta->pSchemas[cols].bytes);
84,680✔
5697
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
84,680✔
5698
        }
5699

5700
        // skip condition, notes, columns, update_time
5701
        COL_DATA_SET_EMPTY_VARCHAR(pBuf, 4);
423,400✔
5702

5703
        numOfRows++;
84,680✔
5704
      }
5705
    }
5706

5707
    // table level privileges
5708
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->name, pObj->selectTbs,
45,530✔
5709
                                           PRIV_TBL_SELECT, pBuf, bufSize, &numOfRows));
5710
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->name, pObj->insertTbs,
45,530✔
5711
                                           PRIV_TBL_INSERT, pBuf, bufSize, &numOfRows));
5712
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->name, pObj->updateTbs,
45,530✔
5713
                                           PRIV_TBL_UPDATE, pBuf, bufSize, &numOfRows));
5714
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->name, pObj->deleteTbs,
45,530✔
5715
                                           PRIV_TBL_DELETE, pBuf, bufSize, &numOfRows));
5716
    sdbRelease(pSdb, pObj);
45,530✔
5717
  }
5718

5719
  pShow->numOfRows += numOfRows;
8,627✔
5720
_exit:
8,627✔
5721
  taosMemoryFreeClear(pBuf);
8,627✔
5722
  taosMemoryFreeClear(sql);
8,627✔
5723
  if (code < 0) {
8,627✔
NEW
5724
    mError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
UNCOV
5725
    TAOS_RETURN(code);
×
5726
  }
5727
  return numOfRows;
8,627✔
5728
}
5729

UNCOV
5730
static void mndCancelGetNextPrivileges(SMnode *pMnode, void *pIter) {
×
UNCOV
5731
  SSdb *pSdb = pMnode->pSdb;
×
UNCOV
5732
  sdbCancelFetchByType(pSdb, pIter, SDB_USER);
×
UNCOV
5733
}
×
5734

5735
int32_t mndValidateUserAuthInfo(SMnode *pMnode, SUserAuthVersion *pUsers, int32_t numOfUses, void **ppRsp,
20,309,767✔
5736
                                int32_t *pRspLen, int64_t ipWhiteListVer) {
5737
  int32_t           code = 0;
20,309,767✔
5738
  int32_t           lino = 0;
20,309,767✔
5739
  int32_t           rspLen = 0;
20,309,767✔
5740
  void             *pRsp = NULL;
20,309,767✔
5741
  SUserAuthBatchRsp batchRsp = {0};
20,309,767✔
5742

5743
  batchRsp.pArray = taosArrayInit(numOfUses, sizeof(SGetUserAuthRsp));
20,309,767✔
5744
  if (batchRsp.pArray == NULL) {
20,309,767✔
UNCOV
5745
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
5746
  }
5747
  int64_t now = taosGetTimestampMs();
20,309,767✔
5748
  for (int32_t i = 0; i < numOfUses; ++i) {
40,952,532✔
5749
    SUserObj *pUser = NULL;
20,642,765✔
5750
    code = mndAcquireUser(pMnode, pUsers[i].user, &pUser);
20,642,765✔
5751
    if (pUser == NULL) {
20,642,765✔
5752
      if (TSDB_CODE_MND_USER_NOT_EXIST == code) {
3,534✔
5753
        SGetUserAuthRsp rsp = {.dropped = 1};
3,534✔
5754
        (void)memcpy(rsp.user, pUsers[i].user, TSDB_USER_LEN);
3,534✔
5755
        TSDB_CHECK_NULL(taosArrayPush(batchRsp.pArray, &rsp), code, lino, _OVER, TSDB_CODE_OUT_OF_MEMORY);
7,068✔
5756
      }
5757
      mError("user:%s, failed to auth user since %s", pUsers[i].user, tstrerror(code));
3,534✔
5758
      code = 0;
3,534✔
5759
      continue;
3,534✔
5760
    }
5761

5762
    pUsers[i].version = ntohl(pUsers[i].version);
20,639,231✔
5763
    if ((pUser->authVersion <= pUsers[i].version) && (ipWhiteListVer == pMnode->ipWhiteVer) &&
20,639,231✔
UNCOV
5764
        !mndNeedRetrieveRole(pUser)) {
×
UNCOV
5765
      mndReleaseUser(pMnode, pUser);
×
UNCOV
5766
      continue;
×
5767
    }
5768

5769
    SGetUserAuthRsp rsp = {0};
20,639,231✔
5770
    code = mndSetUserAuthRsp(pMnode, pUser, &rsp);
20,639,231✔
5771
    if (code) {
20,639,231✔
UNCOV
5772
      mndReleaseUser(pMnode, pUser);
×
UNCOV
5773
      tFreeSGetUserAuthRsp(&rsp);
×
UNCOV
5774
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
5775
    }
5776

5777
    if (!(taosArrayPush(batchRsp.pArray, &rsp))) {
41,278,462✔
UNCOV
5778
      code = terrno;
×
UNCOV
5779
      mndReleaseUser(pMnode, pUser);
×
UNCOV
5780
      tFreeSGetUserAuthRsp(&rsp);
×
UNCOV
5781
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
5782
    }
5783
    pUser->lastRoleRetrieve = now;  // update user's last retrieve time
20,639,231✔
5784
    mndReleaseUser(pMnode, pUser);
20,639,231✔
5785
  }
5786

5787
  if (taosArrayGetSize(batchRsp.pArray) <= 0) {
20,309,767✔
UNCOV
5788
    *ppRsp = NULL;
×
UNCOV
5789
    *pRspLen = 0;
×
5790

UNCOV
5791
    tFreeSUserAuthBatchRsp(&batchRsp);
×
UNCOV
5792
    return 0;
×
5793
  }
5794

5795
  rspLen = tSerializeSUserAuthBatchRsp(NULL, 0, &batchRsp);
20,309,767✔
5796
  if (rspLen < 0) {
20,308,960✔
UNCOV
5797
    TAOS_CHECK_GOTO(rspLen, &lino, _OVER);
×
5798
  }
5799
  pRsp = taosMemoryMalloc(rspLen);
20,308,960✔
5800
  if (pRsp == NULL) {
20,308,647✔
UNCOV
5801
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
5802
  }
5803
  rspLen = tSerializeSUserAuthBatchRsp(pRsp, rspLen, &batchRsp);
20,308,647✔
5804
  if (rspLen < 0) {
20,309,506✔
UNCOV
5805
    TAOS_CHECK_GOTO(rspLen, &lino, _OVER);
×
5806
  }
5807
_OVER:
20,309,506✔
5808
  tFreeSUserAuthBatchRsp(&batchRsp);
20,309,024✔
5809
  if (code < 0) {
20,308,072✔
UNCOV
5810
    for (int32_t i = 0; i < numOfUses; ++i) {
×
UNCOV
5811
      SUserObj *pUser = NULL;
×
UNCOV
5812
      if (mndAcquireUser(pMnode, pUsers[i].user, &pUser) != 0) {
×
UNCOV
5813
        continue;
×
5814
      }
UNCOV
5815
      pUser->lastRoleRetrieve = 0;  // reset last retrieve time on error
×
UNCOV
5816
      mndReleaseUser(pMnode, pUser);
×
5817
    }
NEW
5818
    mError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
UNCOV
5819
    taosMemoryFreeClear(pRsp);
×
UNCOV
5820
    rspLen = 0;
×
5821
  }
5822
  *ppRsp = pRsp;
20,308,072✔
5823
  *pRspLen = rspLen;
20,309,181✔
5824

5825
  TAOS_RETURN(code);
20,309,181✔
5826
}
5827

UNCOV
5828
int32_t mndUserDropRole(SMnode *pMnode, STrans *pTrans, SRoleObj *pObj) {
×
UNCOV
5829
  int32_t   code = 0, lino = 0;
×
UNCOV
5830
  SSdb     *pSdb = pMnode->pSdb;
×
UNCOV
5831
  SUserObj *pUser = NULL;
×
UNCOV
5832
  void     *pIter = NULL;
×
5833

UNCOV
5834
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser))) {
×
UNCOV
5835
    SHashObj *pRole = taosHashGet(pUser->roles, pObj->name, strlen(pObj->name) + 1);
×
UNCOV
5836
    if (!pRole) {
×
UNCOV
5837
      sdbRelease(pSdb, pUser);
×
UNCOV
5838
      pUser = NULL;
×
UNCOV
5839
      continue;
×
5840
    }
5841

UNCOV
5842
    SUserObj newUser = {0};
×
UNCOV
5843
    TAOS_CHECK_EXIT(mndUserDupObj(pUser, &newUser));
×
UNCOV
5844
    code = taosHashRemove(newUser.roles, pObj->name, strlen(pObj->name) + 1);
×
UNCOV
5845
    if (code == TSDB_CODE_NOT_FOUND) {
×
UNCOV
5846
      sdbRelease(pSdb, pUser);
×
UNCOV
5847
      pUser = NULL;
×
UNCOV
5848
      mndUserFreeObj(&newUser);
×
UNCOV
5849
      continue;
×
5850
    }
UNCOV
5851
    if (code != 0) {
×
UNCOV
5852
      mndUserFreeObj(&newUser);
×
UNCOV
5853
      TAOS_CHECK_EXIT(code);
×
5854
    }
UNCOV
5855
    SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
×
UNCOV
5856
    if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
×
UNCOV
5857
      mndUserFreeObj(&newUser);
×
UNCOV
5858
      TAOS_CHECK_EXIT(TSDB_CODE_OUT_OF_MEMORY);
×
5859
    }
UNCOV
5860
    if ((code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY))) {
×
UNCOV
5861
      mndUserFreeObj(&newUser);
×
UNCOV
5862
      TAOS_CHECK_EXIT(code);
×
5863
    }
UNCOV
5864
    sdbRelease(pSdb, pUser);
×
UNCOV
5865
    pUser = NULL;
×
UNCOV
5866
    mndUserFreeObj(&newUser);
×
5867
  }
UNCOV
5868
_exit:
×
UNCOV
5869
  if (pIter) sdbCancelFetch(pSdb, pIter);
×
UNCOV
5870
  if (pUser) sdbRelease(pSdb, pUser);
×
UNCOV
5871
  if (code < 0) {
×
NEW
5872
    mError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
5873
  }
UNCOV
5874
  TAOS_RETURN(code);
×
5875
}
5876

5877
static int32_t mndUserPrivHashRemoveDb(SHashObj *pHash, const char *dbFName, int32_t dbFNameLen, bool *found) {
3,373,225✔
5878
  void *pVal = NULL;
3,373,225✔
5879
  while ((pVal = taosHashIterate(pHash, pVal))) {
3,483,241✔
5880
    size_t klen = 0;
110,016✔
5881
    char  *key = taosHashGetKey(pVal, &klen);
110,016✔
5882
    if (key && privDbKeyMatch(key, dbFName, dbFNameLen)) {
220,032✔
5883
      TAOS_CHECK_RETURN(taosHashRemove(pHash, key, klen));
8,760✔
5884
      if (found) *found = true;
8,760✔
5885
    }
5886
  }
5887
  TAOS_RETURN(0);
3,373,225✔
5888
}
5889

5890
static int32_t mndUserRemoveDbPrivsImpl(SUserObj *pUser, const char *key, int32_t keyLen, bool *pFound) {
674,645✔
5891
  bool found = false;
674,645✔
5892
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pUser->objPrivs, (char *)key, keyLen, found ? NULL : &found));
674,645✔
5893
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pUser->selectTbs, (char *)key, keyLen, found ? NULL : &found));
674,645✔
5894
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pUser->insertTbs, (char *)key, keyLen, found ? NULL : &found));
674,645✔
5895
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pUser->updateTbs, (char *)key, keyLen, found ? NULL : &found));
674,645✔
5896
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pUser->deleteTbs, (char *)key, keyLen, found ? NULL : &found));
674,645✔
5897
  if (taosHashGet(pUser->ownedDbs, key, keyLen)) {
674,645✔
NEW
5898
    TAOS_CHECK_RETURN(taosHashRemove(pUser->ownedDbs, (char *)key, keyLen));
×
NEW
5899
    if (!found) found = true;
×
5900
  }
5901
  if (pFound) *pFound = found;
674,645✔
5902
  TAOS_RETURN(0);
674,645✔
5903
}
5904

5905
static int32_t mndUserRemoveDbPrivs(SMnode *pMnode, STrans *pTrans, const char *key, int32_t keyLen,
605,876✔
5906
                                    SSHashObj **ppUsers) {
5907
  int32_t    code = 0, lino = 0;
605,876✔
5908
  SSdb      *pSdb = pMnode->pSdb;
605,876✔
5909
  void      *pIter = NULL;
605,876✔
5910
  SUserObj  *pUser = NULL;
605,876✔
5911
  SSHashObj *pUsers = ppUsers ? *ppUsers : NULL;
605,876✔
5912
  bool       output = (ppUsers != NULL);
605,876✔
5913
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser))) {
1,280,275✔
5914
    bool found = false;
674,399✔
5915
    TAOS_CHECK_EXIT(mndUserRemoveDbPrivsImpl(pUser, key, keyLen, &found));
674,399✔
5916
    if (!found) {
674,399✔
5917
      sdbRelease(pSdb, pUser);
668,003✔
5918
      pUser = NULL;
668,003✔
5919
      continue;
668,003✔
5920
    }
5921

5922
    if (output) {
6,396✔
5923
      if (!pUsers) {
492✔
5924
        TSDB_CHECK_NULL(pUsers = tSimpleHashInit(32, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY)), code, lino,
246✔
5925
                        _exit, TSDB_CODE_OUT_OF_MEMORY);
5926
        tSimpleHashSetFreeFp(pUsers, (_hash_free_fn_t)mndUserFreeObj);
246✔
5927
        *ppUsers = pUsers;
246✔
5928
      }
5929
      void   *pVal = NULL;
492✔
5930
      int32_t userLen = strlen(pUser->name) + 1;
492✔
5931
      if ((pVal = tSimpleHashGet(pUsers, pUser->name, userLen)) != NULL) {
492✔
5932
        TAOS_CHECK_EXIT(mndUserRemoveDbPrivsImpl((SUserObj *)pVal, key, keyLen, NULL));
246✔
5933
      } else {
5934
        SUserObj newUser = {0};
246✔
5935
        if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
246✔
NEW
5936
          mndUserFreeObj(&newUser);
×
NEW
5937
          TAOS_CHECK_EXIT(code);
×
5938
        }
5939
        if ((code = tSimpleHashPut(pUsers, pUser->name, userLen, &newUser, sizeof(SUserObj)))) {
246✔
NEW
5940
          mndUserFreeObj(&newUser);
×
NEW
5941
          TAOS_CHECK_EXIT(code);
×
5942
        }
5943
      }
5944
    } else {
5945
      int64_t now = taosGetTimestampMs();
5,904✔
5946
      taosWLockLatch(&pUser->lock);
5,904✔
5947
      pUser->updateTime = now;
5,904✔
5948
      ++pUser->authVersion;
5,904✔
5949
      taosWUnLockLatch(&pUser->lock);
5,904✔
5950

5951
      SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
5,904✔
5952
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
5,904✔
NEW
5953
        TAOS_CHECK_EXIT(TSDB_CODE_OUT_OF_MEMORY);
×
5954
      }
5955
      TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
5,904✔
5956
    }
5957

5958
    sdbRelease(pSdb, pUser);
6,396✔
5959
    pUser = NULL;
6,396✔
5960
  }
5961
_exit:
605,876✔
5962
  if (pUser != NULL) sdbRelease(pSdb, pUser);
605,876✔
5963
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
605,876✔
5964
  TAOS_RETURN(code);
605,876✔
5965
}
5966

NEW
5967
static int32_t mndRoleRemoveDbPrivsImpl(SRoleObj *pRole, const char *key, int32_t keyLen, bool *pFound) {
×
NEW
5968
  bool found = false;
×
NEW
5969
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pRole->objPrivs, (char *)key, keyLen, found ? NULL : &found));
×
NEW
5970
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pRole->selectTbs, (char *)key, keyLen, found ? NULL : &found));
×
NEW
5971
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pRole->insertTbs, (char *)key, keyLen, found ? NULL : &found));
×
NEW
5972
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pRole->updateTbs, (char *)key, keyLen, found ? NULL : &found));
×
NEW
5973
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pRole->deleteTbs, (char *)key, keyLen, found ? NULL : &found));
×
NEW
5974
  if (pFound) *pFound = found;
×
NEW
5975
  TAOS_RETURN(0);
×
5976
}
5977

NEW
5978
static int32_t mndRoleRemoveDbPrivs(SMnode *pMnode, STrans *pTrans, const char *key, int32_t keyLen,
×
5979
                                    SSHashObj **ppRoles) {
NEW
5980
  int32_t    code = 0, lino = 0;
×
NEW
5981
  SSdb      *pSdb = pMnode->pSdb;
×
NEW
5982
  void      *pIter = NULL;
×
NEW
5983
  SRoleObj  *pRole = NULL;
×
NEW
5984
  SSHashObj *pRoles = ppRoles ? *ppRoles : NULL;
×
NEW
5985
  bool       output = (ppRoles != NULL);
×
NEW
5986
  while ((pIter = sdbFetch(pSdb, SDB_ROLE, pIter, (void **)&pRole))) {
×
NEW
5987
    bool found = false;
×
NEW
5988
    TAOS_CHECK_EXIT(mndRoleRemoveDbPrivsImpl(pRole, key, keyLen, &found));
×
NEW
5989
    if (!found) {
×
NEW
5990
      sdbRelease(pSdb, pRole);
×
NEW
5991
      pRole = NULL;
×
NEW
5992
      continue;
×
5993
    }
5994

NEW
5995
    if (output) {
×
NEW
5996
      if (!pRoles) {
×
NEW
5997
        TSDB_CHECK_NULL(pRoles = tSimpleHashInit(32, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY)), code, lino,
×
5998
                        _exit, TSDB_CODE_OUT_OF_MEMORY);
NEW
5999
        tSimpleHashSetFreeFp(pRoles, (_hash_free_fn_t)mndRoleFreeObj);
×
NEW
6000
        *ppRoles = pRoles;
×
6001
      }
NEW
6002
      void   *pVal = NULL;
×
NEW
6003
      int32_t roleLen = strlen(pRole->name) + 1;
×
NEW
6004
      if ((pVal = tSimpleHashGet(pRoles, pRole->name, roleLen)) != NULL) {
×
NEW
6005
        TAOS_CHECK_EXIT(mndRoleRemoveDbPrivsImpl((SRoleObj *)pVal, key, keyLen, NULL));
×
6006
      } else {
NEW
6007
        SRoleObj newRole = {0};
×
NEW
6008
        if ((code = mndRoleDupObj(pRole, &newRole)) != 0) {
×
NEW
6009
          mndRoleFreeObj(&newRole);
×
NEW
6010
          TAOS_CHECK_EXIT(code);
×
6011
        }
NEW
6012
        if ((code = tSimpleHashPut(pRoles, pRole->name, roleLen, &newRole, sizeof(SRoleObj)))) {
×
NEW
6013
          mndRoleFreeObj(&newRole);
×
NEW
6014
          TAOS_CHECK_EXIT(code);
×
6015
        }
6016
      }
6017
    } else {
NEW
6018
      int64_t now = taosGetTimestampMs();
×
NEW
6019
      taosWLockLatch(&pRole->lock);
×
NEW
6020
      pRole->updateTime = now;
×
NEW
6021
      ++pRole->version;
×
NEW
6022
      taosWUnLockLatch(&pRole->lock);
×
6023

NEW
6024
      SSdbRaw *pCommitRaw = mndRoleActionEncode(pRole);
×
UNCOV
6025
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
×
NEW
6026
        TAOS_CHECK_EXIT(TSDB_CODE_OUT_OF_MEMORY);
×
6027
      }
NEW
6028
      TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
×
6029
    }
6030

NEW
6031
    sdbRelease(pSdb, pRole);
×
NEW
6032
    pRole = NULL;
×
6033
  }
NEW
6034
_exit:
×
NEW
6035
  if (pRole != NULL) sdbRelease(pSdb, pRole);
×
6036
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
×
6037
  TAOS_RETURN(code);
×
6038
}
6039

6040
int32_t mndPrincipalRemoveDb(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SSHashObj **ppUsers, SSHashObj **ppRoles) {
605,876✔
6041
  TAOS_RETURN(mndUserRemoveDbPrivs(pMnode, pTrans, pDb->name, strlen(pDb->name), ppUsers));
605,876✔
6042
  return mndRoleRemoveDbPrivs(pMnode, pTrans, pDb->name, strlen(pDb->name), ppRoles);
6043
}
6044

6045
int32_t mndUserRemoveStb(SMnode *pMnode, STrans *pTrans, char *stb) {
434,537✔
6046
  return mndPrincipalRemoveObjPrivs(pMnode, pTrans, stb, PRIV_OBJ_TBL);
434,537✔
6047
}
6048

6049
static int32_t mndUserRemoveObjPrivs(SMnode *pMnode, STrans *pTrans, const char *key, int32_t keyLen,
666,432✔
6050
                                     EPrivObjType objType) {
6051
  int32_t   code = 0, lino = 0;
666,432✔
6052
  SSdb     *pSdb = pMnode->pSdb;
666,432✔
6053
  void     *pIter = NULL;
666,432✔
6054
  SUserObj *pUser = NULL;
666,432✔
6055
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser))) {
1,339,776✔
6056
    bool found = false;
673,344✔
6057
    if (taosHashGet(pUser->objPrivs, key, keyLen)) {
673,344✔
6058
      TAOS_CHECK_EXIT(taosHashRemove(pUser->objPrivs, key, keyLen));
2,256✔
6059
      found = true;
2,256✔
6060
    }
6061
    if (objType == PRIV_OBJ_TBL) {
673,344✔
6062
      SPrivTblPolicies *pTblPrivs = taosHashGet(pUser->selectTbs, key, keyLen);
434,537✔
6063
      if (pTblPrivs) {
434,537✔
NEW
6064
        TAOS_CHECK_EXIT(taosHashRemove(pUser->selectTbs, key, keyLen));
×
NEW
6065
        found = true;
×
6066
      }
6067
      pTblPrivs = taosHashGet(pUser->insertTbs, key, keyLen);
434,537✔
6068
      if (pTblPrivs) {
434,537✔
NEW
6069
        TAOS_CHECK_EXIT(taosHashRemove(pUser->insertTbs, key, keyLen));
×
NEW
6070
        found = true;
×
6071
      }
6072
      pTblPrivs = taosHashGet(pUser->updateTbs, key, keyLen);
434,537✔
6073
      if (pTblPrivs) {
434,537✔
NEW
6074
        TAOS_CHECK_EXIT(taosHashRemove(pUser->updateTbs, key, keyLen));
×
NEW
6075
        found = true;
×
6076
      }
6077
      pTblPrivs = taosHashGet(pUser->deleteTbs, key, keyLen);
434,537✔
6078
      if (pTblPrivs) {
434,537✔
NEW
6079
        TAOS_CHECK_EXIT(taosHashRemove(pUser->deleteTbs, key, keyLen));
×
NEW
6080
        found = true;
×
6081
      }
6082
    }
6083
    if (!found) {
673,344✔
6084
      sdbRelease(pSdb, pUser);
671,088✔
6085
      pUser = NULL;
671,088✔
6086
      continue;
671,088✔
6087
    }
6088

6089
    int64_t now = taosGetTimestampMs();
2,256✔
6090
    taosWLockLatch(&pUser->lock);
2,256✔
6091
    pUser->updateTime = now;
2,256✔
6092
    ++pUser->authVersion;
2,256✔
6093
    taosWUnLockLatch(&pUser->lock);
2,256✔
6094

6095
    SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
2,256✔
6096
    if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
2,256✔
NEW
6097
      TAOS_CHECK_EXIT(TSDB_CODE_OUT_OF_MEMORY);
×
6098
    }
6099
    TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
2,256✔
6100

6101
    sdbRelease(pSdb, pUser);
2,256✔
6102
    pUser = NULL;
2,256✔
6103
  }
6104
_exit:
666,432✔
6105
  if (pUser != NULL) sdbRelease(pSdb, pUser);
666,432✔
6106
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
666,432✔
6107
  TAOS_RETURN(code);
666,432✔
6108
}
6109

6110
static int32_t mndRoleRemoveObjPrivs(SMnode *pMnode, STrans *pTrans, const char *key, int32_t keyLen,
666,432✔
6111
                                     EPrivObjType objType) {
6112
  int32_t   code = 0, lino = 0;
666,432✔
6113
  SSdb     *pSdb = pMnode->pSdb;
666,432✔
6114
  void     *pIter = NULL;
666,432✔
6115
  SRoleObj *pRole = NULL;
666,432✔
6116
  while ((pIter = sdbFetch(pSdb, SDB_ROLE, pIter, (void **)&pRole))) {
4,665,024✔
6117
    // inherit system roles have no direct privileges
6118
    if (taosStrncasecmp(pRole->name, "sys", 3) == 0) {
3,998,592✔
6119
      sdbRelease(pSdb, pRole);
3,998,592✔
6120
      pRole = NULL;
3,998,592✔
6121
      continue;
3,998,592✔
6122
    }
NEW
6123
    bool found = false;
×
NEW
6124
    if (taosHashGet(pRole->objPrivs, key, keyLen)) {
×
NEW
6125
      TAOS_CHECK_EXIT(taosHashRemove(pRole->objPrivs, key, keyLen));
×
NEW
6126
      found = true;
×
6127
    }
6128

NEW
6129
    if (objType == PRIV_OBJ_TBL) {
×
NEW
6130
      SPrivTblPolicies *pTblPrivs = taosHashGet(pRole->selectTbs, key, keyLen);
×
NEW
6131
      if (pTblPrivs) {
×
NEW
6132
        TAOS_CHECK_EXIT(taosHashRemove(pRole->selectTbs, key, keyLen));
×
NEW
6133
        found = true;
×
6134
      }
NEW
6135
      pTblPrivs = taosHashGet(pRole->insertTbs, key, keyLen);
×
NEW
6136
      if (pTblPrivs) {
×
NEW
6137
        TAOS_CHECK_EXIT(taosHashRemove(pRole->insertTbs, key, keyLen));
×
NEW
6138
        found = true;
×
6139
      }
NEW
6140
      pTblPrivs = taosHashGet(pRole->updateTbs, key, keyLen);
×
NEW
6141
      if (pTblPrivs) {
×
NEW
6142
        TAOS_CHECK_EXIT(taosHashRemove(pRole->updateTbs, key, keyLen));
×
NEW
6143
        found = true;
×
6144
      }
NEW
6145
      pTblPrivs = taosHashGet(pRole->deleteTbs, key, keyLen);
×
NEW
6146
      if (pTblPrivs) {
×
NEW
6147
        TAOS_CHECK_EXIT(taosHashRemove(pRole->deleteTbs, key, keyLen));
×
NEW
6148
        found = true;
×
6149
      }
6150
    }
NEW
6151
    if (!found) {
×
NEW
6152
      sdbRelease(pSdb, pRole);
×
NEW
6153
      pRole = NULL;
×
NEW
6154
      continue;
×
6155
    }
NEW
6156
    int64_t now = taosGetTimestampMs();
×
NEW
6157
    taosWLockLatch(&pRole->lock);
×
NEW
6158
    pRole->updateTime = now;
×
NEW
6159
    ++pRole->version;
×
NEW
6160
    taosWUnLockLatch(&pRole->lock);
×
6161

NEW
6162
    SSdbRaw *pCommitRaw = mndRoleActionEncode(pRole);
×
NEW
6163
    if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
×
NEW
6164
      TAOS_CHECK_EXIT(TSDB_CODE_OUT_OF_MEMORY);
×
6165
    }
NEW
6166
    TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
×
6167

NEW
6168
    sdbRelease(pSdb, pRole);
×
NEW
6169
    pRole = NULL;
×
6170
  }
6171
_exit:
666,432✔
6172
  if (pRole != NULL) sdbRelease(pSdb, pRole);
666,432✔
6173
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
666,432✔
6174
  TAOS_RETURN(code);
666,432✔
6175
}
6176

6177
static int32_t mndPrincipalRemoveObjPrivs(SMnode *pMnode, STrans *pTrans, char *objFName, EPrivObjType objType) {
666,432✔
6178
  int32_t code = 0;
666,432✔
6179
  char    key[TSDB_PRIV_MAX_KEY_LEN] = {0};
666,432✔
6180
  int32_t keyLen = snprintf(key, sizeof(key), "%d.%s", objType, objFName) + 1;
666,432✔
6181
  TAOS_CHECK_RETURN(mndUserRemoveObjPrivs(pMnode, pTrans, key, keyLen, objType));
666,432✔
6182
  TAOS_CHECK_RETURN(mndRoleRemoveObjPrivs(pMnode, pTrans, key, keyLen, objType));
666,432✔
6183
  TAOS_RETURN(code);
666,432✔
6184
}
6185

6186
int32_t mndUserRemoveView(SMnode *pMnode, STrans *pTrans, char *view) {
137,142✔
6187
  return mndPrincipalRemoveObjPrivs(pMnode, pTrans, view, PRIV_OBJ_VIEW);
137,142✔
6188
}
6189

6190
int32_t mndUserRemoveTopic(SMnode *pMnode, STrans *pTrans, char *topic) {
94,753✔
6191
  return mndPrincipalRemoveObjPrivs(pMnode, pTrans, topic, PRIV_OBJ_TOPIC);
94,753✔
6192
}
6193

UNCOV
6194
int64_t mndGetUserIpWhiteListVer(SMnode *pMnode, SUserObj *pUser) {
×
6195
  // ver = 0, disable ip white list
6196
  // ver > 0, enable ip white list
UNCOV
6197
  return tsEnableWhiteList ? pUser->ipWhiteListVer : 0;
×
6198
}
6199

UNCOV
6200
int64_t mndGetUserTimeWhiteListVer(SMnode *pMnode, SUserObj *pUser) {
×
6201
  // ver = 0, disable datetime white list
6202
  // ver > 0, enable datetime white list
UNCOV
6203
  return tsEnableWhiteList ? pUser->timeWhiteListVer : 0;
×
6204
}
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