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

taosdata / TDengine / #4978

06 Mar 2026 09:48AM UTC coverage: 68.439% (-0.02%) from 68.456%
#4978

push

travis-ci

web-flow
feat(TDgpt): support multiple input data columns for anomaly detection. (#34606)

0 of 93 new or added lines in 9 files covered. (0.0%)

3130 existing lines in 120 files now uncovered.

211124 of 308486 relevant lines covered (68.44%)

136029500.43 hits per line

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

63.69
/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() {
425,025✔
177
  _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
425,025✔
178

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

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

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

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

198
  void *pIter = taosHashIterate(userCache.users, NULL);
424,966✔
199
  while (pIter) {
867,385✔
200
    SCachedUserInfo *pInfo = *(SCachedUserInfo **)pIter;
442,419✔
201
    if (pInfo != NULL) {
442,419✔
202
      taosMemoryFree(pInfo->wlIp);
442,419✔
203
      taosMemoryFree(pInfo->wlTime);
442,419✔
204
      taosMemoryFree(pInfo);
442,419✔
205
    }
206
    pIter = taosHashIterate(userCache.users, pIter);
442,419✔
207
  }
208
  taosHashCleanup(userCache.users);
424,966✔
209

210
  (void)taosThreadRwlockDestroy(&userCache.rw);
424,966✔
211
}
212

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

216
  (void)taosThreadRwlockWrlock(&userCache.rw);
31,351✔
217

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

232
  (void)taosThreadRwlockUnlock(&userCache.rw);
31,351✔
233
}
31,351✔
234

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

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

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

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

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

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

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

267
  return pInfo;
473,770✔
268
}
269

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

273
  (void)taosThreadRwlockRdlock(&userCache.rw);
2,481,895✔
274

275
  SCachedUserInfo **ppInfo = taosHashGet(userCache.users, user, userLen);
2,481,929✔
276
  if (ppInfo != NULL && *ppInfo != NULL) {
2,481,722✔
277
    pLoginInfo->lastLoginTime = (*ppInfo)->loginInfo.lastLoginTime;
2,184,385✔
278
    pLoginInfo->failedLoginCount = (*ppInfo)->loginInfo.failedLoginCount;
2,183,886✔
279
    pLoginInfo->lastFailedLoginTime = (*ppInfo)->loginInfo.lastFailedLoginTime;
2,184,355✔
280
  } else {
281
    pLoginInfo->lastLoginTime = taosGetTimestampSec();
297,337✔
282
    pLoginInfo->failedLoginCount = 0;
297,337✔
283
    pLoginInfo->lastFailedLoginTime = 0;
297,337✔
284
  }
285

286
  (void)taosThreadRwlockUnlock(&userCache.rw);
2,481,020✔
287

288
  if (pLoginInfo->lastLoginTime == 0) {
2,481,895✔
289
    pLoginInfo->lastLoginTime = taosGetTimestampSec();
45,937✔
290
  }
291
}
2,481,291✔
292

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

296
  (void)taosThreadRwlockWrlock(&userCache.rw);
2,476,605✔
297

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

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

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

313
  if (a == NULL || b == NULL) {
1,333,344✔
314
    return false;
69,274✔
315
  }
316

317
  if (a->num != b->num) {
1,264,070✔
318
    return false;
270✔
319
  }
320

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

328
  return true;
1,263,530✔
329
}
330

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

334
  (void)taosThreadRwlockWrlock(&userCache.rw);
1,333,344✔
335

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

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

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

361
_OVER:
1,333,344✔
362
  (void)taosThreadRwlockUnlock(&userCache.rw);
1,333,344✔
363
  if (code < 0) {
1,333,344✔
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,333,344✔
367
}
368

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

372
  SSdb *pSdb = pMnode->pSdb;
516,496✔
373
  void *pIter = NULL;
516,496✔
374
  while (1) {
200,226✔
375
    SUserObj *pUser = NULL;
716,722✔
376
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
716,722✔
377
    if (pIter == NULL) {
716,722✔
378
      break;
516,496✔
379
    }
380

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

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

395
    taosMemoryFree(pInfo->wlIp);
200,226✔
396
    pInfo->wlIp = wl;
200,226✔
397

398
    sdbRelease(pSdb, pUser);
200,226✔
399
  }
400

401
  userCache.verIp++;
516,496✔
402

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

410
int64_t mndGetIpWhiteListVersion(SMnode *pMnode) {
47,861,336✔
411
  int64_t ver = 0;
47,861,336✔
412
  int32_t code = 0;
47,861,336✔
413

414
  if (mndEnableIpWhiteList(pMnode) != 0 && tsEnableWhiteList) {
47,861,336✔
415
    (void)taosThreadRwlockWrlock(&userCache.rw);
3,455✔
416

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

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

431
  mDebug("ip-white-list on mnode ver: %" PRId64, ver);
47,861,336✔
432
  return ver;
47,861,336✔
433
}
434

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

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

446
  TAOS_RETURN(code);
516,496✔
447
}
448

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

452
  SSdb *pSdb = pMnode->pSdb;
507,852✔
453
  void *pIter = NULL;
507,852✔
454
  while (1) {
191,582✔
455
    SUserObj *pUser = NULL;
699,434✔
456
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
699,434✔
457
    if (pIter == NULL) {
699,434✔
458
      break;
507,852✔
459
    }
460

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

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

475
    taosMemoryFree(pInfo->wlTime);
191,582✔
476
    pInfo->wlTime = wl;
191,582✔
477

478
    sdbRelease(pSdb, pUser);
191,582✔
479
  }
480

481
  userCache.verTime++;
507,852✔
482

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

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

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

501
  TAOS_RETURN(code);
507,852✔
502
}
503

504
int64_t mndGetTimeWhiteListVersion(SMnode *pMnode) {
47,861,336✔
505
  int64_t ver = 0;
47,861,336✔
506
  int32_t code = 0;
47,861,336✔
507

508
  if (mndEnableTimeWhiteList(pMnode) != 0 && tsEnableWhiteList) {
47,861,336✔
509
    (void)taosThreadRwlockWrlock(&userCache.rw);
3,455✔
510

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

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

525
  mDebug("datetime-white-list on mnode ver: %" PRId64, ver);
47,861,336✔
526
  return ver;
47,861,336✔
527
}
528

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

532
  SSdbTable table = {
425,025✔
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);
425,025✔
545
  mndSetMsgHandle(pMnode, TDMT_MND_ALTER_USER, mndProcessAlterUserReq);
425,025✔
546
  mndSetMsgHandle(pMnode, TDMT_MND_DROP_USER, mndProcessDropUserReq);
425,025✔
547
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_AUTH, mndProcessGetUserAuthReq);
425,025✔
548
  mndSetMsgHandle(pMnode, TDMT_MND_UPGRADE_USER, mndProcessUpgradeUserReq);
425,025✔
549
  mndSetMsgHandle(pMnode, TDMT_MND_UPGRADE_USER_RSP, mndProcessUpgradeUserRsp);
425,025✔
550

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

558
  mndSetMsgHandle(pMnode, TDMT_MND_CREATE_TOTP_SECRET, mndProcessCreateTotpSecretReq);
425,025✔
559
  mndSetMsgHandle(pMnode, TDMT_MND_DROP_TOTP_SECRET, mndProcessDropTotpSecretReq);
425,025✔
560

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

570
void mndCleanupUser(SMnode *pMnode) { userCacheCleanup(); }
424,966✔
571

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

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

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

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

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

592
static int32_t ipRangeListToStr(SIpRange *range, int32_t num, char *buf, int64_t bufLen) {
1,393,460✔
593
  int32_t len = 0;
1,393,460✔
594
  for (int i = 0; i < num; i++) {
4,214,330✔
595
    SIpRange *pRange = &range[i];
2,820,870✔
596
    SIpAddr   addr = {0};
2,820,870✔
597
    int32_t   code = tIpUintToStr(pRange, &addr);
2,820,870✔
598
    if (code != 0) {
2,820,870✔
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,820,870✔
603
  }
604
  if (len > 0) {
1,393,460✔
605
    len -= 2;
1,393,460✔
606
    buf[len] = 0; // remove last ", "
1,393,460✔
607
  }
608
  return len;
1,393,460✔
609
}
610

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

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

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

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

632
  if (a == NULL || b == NULL) {
1,333,344✔
633
    return false;
69,274✔
634
  }
635

636
  if (a->num != b->num) {
1,264,070✔
637
    return false;
430✔
638
  }
639
  for (int i = 0; i < a->num; i++) {
3,791,620✔
640
    if (!isIpRangeEqual(&a->pIpRanges[i], &b->pIpRanges[i])) {
2,527,980✔
641
      return false;
×
642
    }
643
  }
644
  return true;
1,263,640✔
645
}
646

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

651
  if (ra->neg != rb->neg) {
5,129✔
652
    return (ra->neg) ? -1 : 1;
675✔
653
  }
654

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

659
  if (ra->type == 0) {
2,840✔
660
    if (ra->ipV4.ip != rb->ipV4.ip) {
2,840✔
661
      return (ra->ipV4.ip < rb->ipV4.ip) ? -1 : 1;
2,520✔
662
    }
663
    return (ra->ipV4.mask < rb->ipV4.mask) ? -1 : 1;
320✔
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
  }
669
  if (ra->ipV6.addr[1] != rb->ipV6.addr[1]) {
×
670
    return (ra->ipV6.addr[1] < rb->ipV6.addr[1]) ? -1 : 1;
×
671
  }
672
  return (ra->ipV6.mask < rb->ipV6.mask) ? -1 : 1;
×
673
}
674

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

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

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

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

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

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

707
  TAOS_CHECK_GOTO(tStartEncode(&encoder), &lino, _OVER);
3,838,316✔
708
  TAOS_CHECK_GOTO(tEncodeI32(&encoder, pList->num), &lino, _OVER);
7,676,632✔
709

710
  for (int i = 0; i < pList->num; i++) {
11,519,138✔
711
    SIpRange *pRange = &(pList->pIpRanges[i]);
7,680,822✔
712
    TAOS_CHECK_GOTO(tSerializeIpRange(&encoder, pRange), &lino, _OVER);
7,680,822✔
713
  }
714

715
  tEndEncode(&encoder);
3,838,316✔
716

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

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

733
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
3,051,541✔
734
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &pList->num), &lino, _OVER);
6,103,082✔
735

736
  for (int i = 0; i < pList->num; i++) {
9,157,093✔
737
    SIpRange *pRange = &(pList->pIpRanges[i]);
6,105,552✔
738
    TAOS_CHECK_GOTO(tDeserializeIpRange(&decoder, pRange, supportNeg), &lino, _OVER);
6,105,552✔
739
  }
740

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

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

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

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

765
_OVER:
×
766
  tEndDecode(&decoder);
×
767
  tDecoderClear(&decoder);
×
768
  if (code < 0) {
×
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) {
3,051,541✔
775
  int32_t           code = 0;
3,051,541✔
776
  int32_t           lino = 0;
3,051,541✔
777
  int32_t           num = 0;
3,051,541✔
778
  SIpWhiteListDual *p = NULL;
3,051,541✔
779
  SDecoder          decoder = {0};
3,051,541✔
780
  tDecoderInit(&decoder, buf, len);
3,051,541✔
781

782
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
3,051,541✔
783
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &num), &lino, _OVER);
3,051,541✔
784

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

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

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

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

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

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

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

839
  SIpRange v4 = {0};
373,374✔
840
  SIpRange v6 = {0};
373,374✔
841

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

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

849
#endif
850

851
_error:
373,374✔
852
  if (code != 0) {
373,374✔
853
    taosMemoryFree(*ppWhiteList);
×
854
    *ppWhiteList = NULL;
×
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));
373,374✔
858
    memcpy(&(*ppWhiteList)->pIpRanges[1], &v6, sizeof(SIpRange));
373,374✔
859
  }
860
  return 0;
373,374✔
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,393,460✔
866
  int32_t bufLen = pUser->pTimeWhiteList->num * 32 + 8;
1,393,460✔
867
  *buf = taosMemoryCalloc(1, bufLen);
1,393,460✔
868
  if (*buf == NULL) {
1,393,460✔
869
    return 0;
×
870
  }
871

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

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

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

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

901
  return pos;
73,440✔
902
}
903

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

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

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

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

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

924
  return 0;
×
925
}
926

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

931
static void dropOldPasswords(SUserObj *pUser) {
9,365,983✔
932
  if (pUser->numOfPasswords <= pUser->passwordReuseMax) {
9,365,983✔
933
    return;
366,343✔
934
  }
935

936
  int32_t reuseMax = pUser->passwordReuseMax;
8,999,640✔
937
  if (reuseMax == 0) {
8,999,640✔
938
    reuseMax = 1;  // keep at least one password
8,999,370✔
939
  }
940

941
  int32_t now = taosGetTimestampSec();
8,999,640✔
942
  int32_t index = reuseMax;
8,999,640✔
943
  while(index < pUser->numOfPasswords) {
8,999,640✔
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;
270✔
946
    if (now - expireTime >= pUser->passwordReuseTime) {
270✔
947
      break;
270✔
948
    }
949
    index++;
×
950
  }
951

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

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

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

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

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

988
#ifdef TD_ENTERPRISE
989

990
  userObj.ipWhiteListVer = taosGetTimestampMs();
305,697✔
991
  userObj.timeWhiteListVer = userObj.ipWhiteListVer;
305,697✔
992

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

1023
  userObj.allowTokenNum = TSDB_USER_ALLOW_TOKEN_NUM_DEFAULT;
305,697✔
1024
  userObj.tokenNum = 0;
305,697✔
1025

1026
#else  // TD_ENTERPRISE
1027

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

1046
#endif  // TD_ENTERPRISE
1047

1048
  userObj.pTimeWhiteList = taosMemoryCalloc(1, sizeof(SDateTimeWhiteList));
305,697✔
1049
  if (userObj.pTimeWhiteList == NULL) {
305,697✔
1050
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _ERROR);
×
1051
  }
1052

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

1066
  userObj.roles = taosHashInit(1, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
305,697✔
1067
  if (userObj.roles == NULL) {
305,697✔
1068
    TAOS_CHECK_GOTO(terrno, &lino, _ERROR);
×
1069
  }
1070

1071
  if ((code = taosHashPut(userObj.roles, TSDB_ROLE_SYSDBA, strlen(TSDB_ROLE_SYSDBA) + 1, NULL, 0)) ||
611,394✔
1072
      (code = taosHashPut(userObj.roles, TSDB_ROLE_SYSSEC, strlen(TSDB_ROLE_SYSSEC) + 1, NULL, 0)) ||
611,394✔
1073
      (code = taosHashPut(userObj.roles, TSDB_ROLE_SYSAUDIT, strlen(TSDB_ROLE_SYSAUDIT) + 1, NULL, 0))) {
305,697✔
1074
    TAOS_CHECK_GOTO(code, &lino, _ERROR);
×
1075
  }
1076

1077
  SSdbRaw *pRaw = mndUserActionEncode(&userObj);
305,697✔
1078
  if (pRaw == NULL) goto _ERROR;
305,697✔
1079
  TAOS_CHECK_GOTO(sdbSetRawStatus(pRaw, SDB_STATUS_READY), &lino, _ERROR);
305,697✔
1080

1081
  mInfo("user:%s, will be created when deploying, raw:%p", userObj.user, pRaw);
305,697✔
1082

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

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

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

1104
  mndTransDrop(pTrans);
305,697✔
1105
  mndUserFreeObj(&userObj);
305,697✔
1106
  return 0;
305,697✔
1107

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

1117
static int32_t mndCreateDefaultUsers(SMnode *pMnode) {
305,697✔
1118
  return mndCreateDefaultUser(pMnode, TSDB_DEFAULT_USER, TSDB_DEFAULT_USER, TSDB_DEFAULT_PASS);
305,697✔
1119
}
1120

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

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

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

1168
  TAOS_CHECK_EXIT(mndTransPrepare(pMnode, pTrans));
×
1169

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

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

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

1208
  SAlterRoleReq alterReq = {.alterType = TSDB_ALTER_ROLE_PRIVILEGES, .add = 1, .objType = objType, .objLevel = 1};
×
1209

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

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

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

1220
    privAddType(&alterReq.privileges.privSet, privType);
1221

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

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

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

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

1267
  SAlterRoleReq alterReq = {.alterType = TSDB_ALTER_ROLE_PRIVILEGES, .add = 1, .objType = PRIV_OBJ_DB};
×
1268

1269
  while ((pIter = taosHashIterate(pDbs, pIter))) {
×
1270
    key = taosHashGetKey(pIter, NULL);
×
1271

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

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

1277
    privAddType(&alterReq.privileges.privSet, PRIV_DB_USE);
1278

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

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

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

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

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

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

1315
    privAddType(&alterReq.privileges.privSet, PRIV_CM_SUBSCRIBE);
1316

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

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

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

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

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

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

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

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

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

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

1440
static int32_t mndProcessUpgradeUserRsp(SRpcMsg *pReq) { return 0;}
×
1441

1442
static int32_t mndUpgradeUsers(SMnode *pMnode, int32_t version) {
384,798✔
1443
  int32_t code = 0, lino = 0;
384,798✔
1444
  if (upgradeSecurity == 0) return code;
384,798✔
1445
  if (!mndIsLeader(pMnode)) return code;
×
1446

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

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

1465
  TAOS_CHECK_EXIT(tStartEncode(&encoder));
7,676,632✔
1466
  TAOS_CHECK_EXIT(tEncodeI64v(&encoder, pObj->uid));
15,353,264✔
1467

1468
  TAOS_CHECK_EXIT(tSerializePrivSysObjPolicies(&encoder, &pObj->sysPrivs, pObj->objPrivs));
7,676,632✔
1469

1470
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->selectTbs));
7,676,632✔
1471
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->insertTbs));
7,676,632✔
1472
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->updateTbs));
7,676,632✔
1473
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->deleteTbs));
7,676,632✔
1474

1475
  int32_t nRoles = taosHashGetSize(pObj->roles);
7,676,632✔
1476
  TAOS_CHECK_EXIT(tEncodeI32v(&encoder, nRoles));
7,676,632✔
1477

1478
  while ((pIter = taosHashIterate(pObj->roles, pIter))) {
24,537,520✔
1479
    size_t keyLen = 0;
16,860,888✔
1480
    char  *key = taosHashGetKey(pIter, &keyLen);  // key: role name
16,860,888✔
1481
    TAOS_CHECK_EXIT(tEncodeCStr(&encoder, key));
16,860,888✔
1482

1483
    uint8_t flag = *(uint8_t *)pIter;
16,860,888✔
1484
    TAOS_CHECK_EXIT(tEncodeU8(&encoder, flag));  // value: 0 reset, 1 set(default)
33,721,776✔
1485
  }
1486

1487
  int32_t nOwnedDbs = taosHashGetSize(pObj->ownedDbs);
7,676,632✔
1488
  TAOS_CHECK_EXIT(tEncodeI32v(&encoder, nOwnedDbs));
7,676,632✔
1489
  pIter = NULL;
7,676,632✔
1490
  while ((pIter = taosHashIterate(pObj->ownedDbs, pIter))) {
29,542,868✔
1491
    size_t keyLen = 0;
21,866,236✔
1492
    char  *key = taosHashGetKey(pIter, &keyLen);  // key: dbFName
21,866,236✔
1493
    TAOS_CHECK_EXIT(tEncodeCStr(&encoder, key));
21,866,236✔
1494
  }
1495

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

1505
  return tlen;
7,676,632✔
1506
}
1507

1508
static int32_t tDeserializeUserObjExt(void *buf, int32_t bufLen, SUserObj *pObj) {
3,051,541✔
1509
  int32_t  code = 0, lino = 0;
3,051,541✔
1510
  SDecoder decoder = {0};
3,051,541✔
1511
  tDecoderInit(&decoder, buf, bufLen);
3,051,541✔
1512

1513
  TAOS_CHECK_EXIT(tStartDecode(&decoder));
3,051,541✔
1514
  TAOS_CHECK_EXIT(tDecodeI64v(&decoder, &pObj->uid));
6,103,082✔
1515
  TAOS_CHECK_EXIT(tDeserializePrivSysObjPolicies(&decoder, &pObj->sysPrivs, &pObj->objPrivs));
3,051,541✔
1516
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->selectTbs));
3,051,541✔
1517
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->insertTbs));
3,051,541✔
1518
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->updateTbs));
3,051,541✔
1519
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->deleteTbs));
3,051,541✔
1520
  int32_t nRoles = 0;
3,051,541✔
1521
  TAOS_CHECK_EXIT(tDecodeI32v(&decoder, &nRoles));
3,051,541✔
1522
  if (nRoles > 0) {
3,051,541✔
1523
    if (!pObj->roles &&
3,045,711✔
1524
        !(pObj->roles = taosHashInit(nRoles, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), 1, HASH_ENTRY_LOCK))) {
3,045,711✔
1525
      TAOS_CHECK_EXIT(terrno);
×
1526
    }
1527
    for (int32_t i = 0; i < nRoles; i++) {
9,352,502✔
1528
      int32_t keyLen = 0;
6,306,791✔
1529
      char   *key = NULL;
6,306,791✔
1530
      TAOS_CHECK_EXIT(tDecodeCStrAndLen(&decoder, &key, &keyLen));
6,306,791✔
1531
      uint8_t flag = 0;
6,306,791✔
1532
      TAOS_CHECK_EXIT(tDecodeU8(&decoder, &flag));
6,306,791✔
1533
      TAOS_CHECK_EXIT(taosHashPut(pObj->roles, key, keyLen + 1, &flag, sizeof(flag)));
6,306,791✔
1534
    }
1535
  }
1536
  if (!tDecodeIsEnd(&decoder)) {
3,051,541✔
1537
    int32_t nOwnedDbs = 0;
3,051,541✔
1538
    TAOS_CHECK_EXIT(tDecodeI32v(&decoder, &nOwnedDbs));
3,051,541✔
1539
    if (nOwnedDbs > 0) {
3,051,541✔
1540
      if (!pObj->ownedDbs &&
1,295,726✔
1541
          !(pObj->ownedDbs =
1,295,726✔
1542
                taosHashInit(nOwnedDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), 1, HASH_ENTRY_LOCK))) {
1,295,726✔
1543
        TAOS_CHECK_EXIT(terrno);
×
1544
      }
1545
      for (int32_t i = 0; i < nOwnedDbs; ++i) {
11,150,051✔
1546
        int32_t keyLen = 0;
9,854,325✔
1547
        char   *key = NULL;
9,854,325✔
1548
        TAOS_CHECK_EXIT(tDecodeCStrAndLen(&decoder, &key, &keyLen));
9,854,325✔
1549
        TAOS_CHECK_EXIT(taosHashPut(pObj->ownedDbs, key, keyLen + 1, NULL, 0));
9,854,325✔
1550
      }
1551
    }
1552
  }
1553

1554
_exit:
3,051,172✔
1555
  tEndDecode(&decoder);
3,051,541✔
1556
  tDecoderClear(&decoder);
3,051,541✔
1557
  if (code < 0) {
3,051,541✔
1558
    mError("user, %s failed at line %d since %s, row:%p", __func__, lino, tstrerror(code), pObj);
×
1559
  }
1560
  TAOS_RETURN(code);
3,051,541✔
1561
}
1562

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

1589
  char *stb = NULL;
3,838,316✔
1590
#if 0
1591
  stb = taosHashIterate(pUser->readTbs, 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->readTbs, stb);
1603
  }
1604

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

1612
    size_t valueLen = 0;
1613
    valueLen = strlen(stb) + 1;
1614
    size += sizeof(int32_t);
1615
    size += valueLen;
1616
    stb = taosHashIterate(pUser->writeTbs, stb);
1617
  }
1618
  stb = taosHashIterate(pUser->alterTbs, 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->alterTbs, stb);
1630
  }
1631

1632
  stb = taosHashIterate(pUser->readViews, 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->readViews, stb);
1644
  }
1645

1646
  stb = taosHashIterate(pUser->writeViews, 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->writeViews, stb);
1658
  }
1659

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

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

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

1690
  pRaw = sdbAllocRaw(SDB_USER, USER_VER_NUMBER, size);
3,838,316✔
1691
  if (pRaw == NULL) {
3,838,316✔
1692
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1693
  }
1694

1695
  int32_t dataPos = 0;
3,838,316✔
1696
  SDB_SET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN, _OVER)
3,838,316✔
1697

1698
  dropOldPasswords(pUser);
3,838,316✔
1699
  SDB_SET_INT32(pRaw, dataPos, pUser->numOfPasswords, _OVER)
3,838,316✔
1700
  for (int32_t i = 0; i < pUser->numOfPasswords; i++) {
8,420,752✔
1701
    SDB_SET_BINARY(pRaw, dataPos, pUser->passwords[i].pass, sizeof(pUser->passwords[i].pass), _OVER)
4,582,436✔
1702
    SDB_SET_INT32(pRaw, dataPos, pUser->passwords[i].setTime, _OVER)
4,582,436✔
1703
  }
1704
  SDB_SET_BINARY(pRaw, dataPos, pUser->salt, sizeof(pUser->salt), _OVER)
3,838,316✔
1705

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

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

1744
#if 0
1745
  stb = taosHashIterate(pUser->readTbs, 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->readTbs, stb);
1757
  }
1758

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

1766
    size_t valueLen = 0;
1767
    valueLen = strlen(stb) + 1;
1768
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
1769
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
1770
    stb = taosHashIterate(pUser->writeTbs, stb);
1771
  }
1772
  stb = taosHashIterate(pUser->alterTbs, 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->alterTbs, stb);
1784
  }
1785

1786
  stb = taosHashIterate(pUser->readViews, 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->readViews, stb);
1798
  }
1799

1800
  stb = taosHashIterate(pUser->writeViews, 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->writeViews, stb);
1812
  }
1813

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

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

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

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

1849
  SDB_SET_INT32(pRaw, dataPos, len, _OVER);
3,838,316✔
1850
  SDB_SET_BINARY(pRaw, dataPos, buf, len, _OVER);
3,838,316✔
1851

1852
  SDB_SET_INT64(pRaw, dataPos, pUser->ipWhiteListVer, _OVER);
3,838,316✔
1853
  SDB_SET_INT8(pRaw, dataPos, pUser->passEncryptAlgorithm, _OVER);
3,838,316✔
1854

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

1872
  SDB_SET_INT32(pRaw, dataPos, pUser->pTimeWhiteList->num, _OVER);
3,838,316✔
1873
  for (int32_t i = 0; i < pUser->pTimeWhiteList->num; i++) {
3,845,066✔
1874
    SDateTimeWhiteListItem *range = &pUser->pTimeWhiteList->ranges[i];
6,750✔
1875
    SDB_SET_BOOL(pRaw, dataPos, range->absolute, _OVER);
6,750✔
1876
    SDB_SET_BOOL(pRaw, dataPos, range->neg, _OVER);
6,750✔
1877
    SDB_SET_INT64(pRaw, dataPos, range->start, _OVER);
6,750✔
1878
    SDB_SET_INT32(pRaw, dataPos, range->duration, _OVER);
6,750✔
1879
  }
1880

1881
  sizeExt = tSerializeUserObjExt(buf, sizeExt, pUser);
3,838,316✔
1882
  if (sizeExt < 0) {
3,838,316✔
1883
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1884
  }
1885
  SDB_SET_INT32(pRaw, dataPos, sizeExt, _OVER);
3,838,316✔
1886
  SDB_SET_BINARY(pRaw, dataPos, buf, sizeExt, _OVER);
3,838,316✔
1887

1888
  SDB_SET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
3,838,316✔
1889

1890
  SDB_SET_DATALEN(pRaw, dataPos, _OVER)
3,838,316✔
1891

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

1902
  mTrace("user:%s, encode user action to raw:%p, row:%p", pUser->user, pRaw, pUser);
3,838,316✔
1903
  return pRaw;
3,838,316✔
1904
}
1905

1906
static SSdbRow *mndUserActionDecode(SSdbRaw *pRaw) {
3,051,541✔
1907
  int32_t   code = 0;
3,051,541✔
1908
  int32_t   lino = 0;
3,051,541✔
1909
  SSdbRow  *pRow = NULL;
3,051,541✔
1910
  SUserObj *pUser = NULL;
3,051,541✔
1911
  char     *key = NULL;
3,051,541✔
1912
  char     *value = NULL;
3,051,541✔
1913

1914
  int8_t sver = 0;
3,051,541✔
1915
  if (sdbGetRawSoftVer(pRaw, &sver) != 0) {
3,051,541✔
1916
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_PTR, &lino, _OVER);
×
1917
  }
1918

1919
  if (sver < 1 || sver > USER_VER_NUMBER) {
3,051,541✔
1920
    TAOS_CHECK_GOTO(TSDB_CODE_SDB_INVALID_DATA_VER, &lino, _OVER);
×
1921
  }
1922

1923
  pRow = sdbAllocRow(sizeof(SUserObj));
3,051,541✔
1924
  if (pRow == NULL) {
3,051,541✔
1925
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1926
  }
1927

1928
  pUser = sdbGetRowObj(pRow);
3,051,541✔
1929
  if (pUser == NULL) {
3,051,541✔
1930
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1931
  }
1932

1933
  if (sver < USER_VER_SUPPORT_ADVANCED_SECURITY) {
3,051,541✔
1934
    upgradeSecurity = 1;
×
1935
    pUser->legacyPrivs = taosMemCalloc(1, sizeof(SPrivHashObjSet));
×
1936
    if (pUser->legacyPrivs == NULL) {
×
1937
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
1938
    }
1939
  }
1940

1941
  int32_t dataPos = 0;
3,051,541✔
1942
  SDB_GET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN, _OVER)
3,051,541✔
1943

1944
  if (sver < USER_VER_SUPPORT_ADVANCED_SECURITY) {
3,051,541✔
1945
    pUser->passwords = taosMemoryCalloc(1, sizeof(SUserPassword));
×
1946
    if (pUser->passwords == NULL) {
×
1947
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
1948
    }
1949
    SDB_GET_BINARY(pRaw, dataPos, pUser->passwords[0].pass, TSDB_PASSWORD_LEN, _OVER)
×
1950
    pUser->numOfPasswords = 1;
×
1951
    memset(pUser->salt, 0, sizeof(pUser->salt));
×
1952
  } else {
1953
    SDB_GET_INT32(pRaw, dataPos, &pUser->numOfPasswords, _OVER)
3,051,541✔
1954
    pUser->passwords = taosMemoryCalloc(pUser->numOfPasswords, sizeof(SUserPassword));
3,051,541✔
1955
    if (pUser->passwords == NULL) {
3,051,541✔
1956
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
1957
    }
1958
    for (int32_t i = 0; i < pUser->numOfPasswords; ++i) {
6,799,007✔
1959
      SDB_GET_BINARY(pRaw, dataPos, pUser->passwords[i].pass, sizeof(pUser->passwords[i].pass), _OVER);
3,747,466✔
1960
      SDB_GET_INT32(pRaw, dataPos, &pUser->passwords[i].setTime, _OVER);
3,747,466✔
1961
    }
1962
    SDB_GET_BINARY(pRaw, dataPos, pUser->salt, sizeof(pUser->salt), _OVER)
3,051,541✔
1963
  }
1964

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

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

1982
  int32_t numOfReadDbs = 0;
3,051,541✔
1983
  int32_t numOfWriteDbs = 0;
3,051,541✔
1984
  int32_t numOfTopics = 0;
3,051,541✔
1985
  SDB_GET_INT32(pRaw, dataPos, &numOfReadDbs, _OVER)
3,051,541✔
1986
  SDB_GET_INT32(pRaw, dataPos, &numOfWriteDbs, _OVER)
3,051,541✔
1987
  if (sver >= 2) {
3,051,541✔
1988
    SDB_GET_INT32(pRaw, dataPos, &numOfTopics, _OVER)
3,051,541✔
1989
  }
1990

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

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

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

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

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

2103
    for (int32_t i = 0; i < numOfReadTbs; ++i) {
3,051,541✔
2104
      int32_t keyLen = 0;
×
2105
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
2106

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

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

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

2126
    for (int32_t i = 0; i < numOfWriteTbs; ++i) {
3,051,541✔
2127
      int32_t keyLen = 0;
×
2128
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
2129

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

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

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

2149
    if (sver >= 6) {
3,051,541✔
2150
      for (int32_t i = 0; i < numOfAlterTbs; ++i) {
3,051,541✔
2151
        int32_t keyLen = 0;
×
2152
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
2153

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

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

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

2173
      for (int32_t i = 0; i < numOfReadViews; ++i) {
3,051,541✔
2174
        int32_t keyLen = 0;
×
2175
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
2176

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

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

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

2196
      for (int32_t i = 0; i < numOfWriteViews; ++i) {
3,051,541✔
2197
        int32_t keyLen = 0;
×
2198
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
2199

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

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

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

2219
      for (int32_t i = 0; i < numOfAlterViews; ++i) {
3,051,541✔
2220
        int32_t keyLen = 0;
×
2221
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
2222

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

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

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

2243
    for (int32_t i = 0; i < numOfUseDbs; ++i) {
3,051,541✔
2244
      int32_t keyLen = 0;
×
2245
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
2246

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

2254
      int32_t ref = 0;
×
2255
      SDB_GET_INT32(pRaw, dataPos, &ref, _OVER);
×
2256

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

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

2272
      SIpWhiteList *pIpWhiteList = NULL;
×
2273
      TAOS_CHECK_GOTO(createIpWhiteListFromOldVer(key, len, &pIpWhiteList), &lino, _OVER);
×
2274

2275
      SDB_GET_INT64(pRaw, dataPos, &pUser->ipWhiteListVer, _OVER);
×
2276

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

2283
      taosMemoryFreeClear(pIpWhiteList);
×
2284

2285
    } else if (sver >= USER_VER_SUPPORT_WHITELIT_DUAL_STACK) {
3,051,541✔
2286
      int32_t len = 0;
3,051,541✔
2287
      SDB_GET_INT32(pRaw, dataPos, &len, _OVER);
3,051,541✔
2288

2289
      TAOS_MEMORY_REALLOC(key, len);
3,051,541✔
2290
      if (key == NULL) {
3,051,541✔
2291
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2292
      }
2293
      SDB_GET_BINARY(pRaw, dataPos, key, len, _OVER);
3,051,541✔
2294

2295
      TAOS_CHECK_GOTO(createIpWhiteList(key, len, &pUser->pIpWhiteListDual, sver >= USER_VER_SUPPORT_ADVANCED_SECURITY),
3,051,541✔
2296
                      &lino, _OVER);
2297
      SDB_GET_INT64(pRaw, dataPos, &pUser->ipWhiteListVer, _OVER);
3,051,541✔
2298
    }
2299
  }
2300

2301
  if (pUser->pIpWhiteListDual == NULL) {
3,051,541✔
2302
    TAOS_CHECK_GOTO(createDefaultIpWhiteList(&pUser->pIpWhiteListDual), &lino, _OVER);
×
2303
    pUser->ipWhiteListVer = taosGetTimestampMs();
×
2304
  }
2305

2306
  SDB_GET_INT8(pRaw, dataPos, &pUser->passEncryptAlgorithm, _OVER);
3,051,541✔
2307

2308
  if (sver < USER_VER_SUPPORT_ADVANCED_SECURITY) {
3,051,541✔
2309
    memset(pUser->totpsecret, 0, sizeof(pUser->totpsecret));
×
2310
    pUser->changePass = 2;
×
2311

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

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

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

2371
    pUser->pTimeWhiteList->num = num;
3,051,541✔
2372
    for (int32_t i = 0; i < num; i++) {
3,054,511✔
2373
      SDateTimeWhiteListItem *range = &pUser->pTimeWhiteList->ranges[i];
2,970✔
2374
      SDB_GET_BOOL(pRaw, dataPos, &range->absolute, _OVER);
2,970✔
2375
      SDB_GET_BOOL(pRaw, dataPos, &range->neg, _OVER);
2,970✔
2376
      SDB_GET_INT64(pRaw, dataPos, &range->start, _OVER);
2,970✔
2377
      SDB_GET_INT32(pRaw, dataPos, &range->duration, _OVER);
2,970✔
2378
    }
2379

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

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

2409
  SDB_GET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
3,051,541✔
2410

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

2427
  mTrace("user:%s, decode from raw:%p, row:%p", pUser->user, pRaw, pUser);
3,051,541✔
2428
  return pRow;
3,051,541✔
2429
}
2430

2431
static int32_t mndUserActionInsert(SSdb *pSdb, SUserObj *pUser) {
499,657✔
2432
  mTrace("user:%s, perform insert action, row:%p", pUser->user, pUser);
499,657✔
2433

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

2443
  return 0;
499,657✔
2444
}
2445

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

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

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

2468
  TAOS_RETURN(code);
×
2469
}
2470

2471
int32_t mndDupRoleHash(SHashObj *pOld, SHashObj **ppNew) {
2,478,558✔
2472
  if (!(*ppNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true,
2,478,558✔
2473
                              HASH_ENTRY_LOCK))) {
2474
    TAOS_RETURN(terrno);
×
2475
  }
2476

2477
  int32_t  code = 0;
2,478,558✔
2478
  uint8_t *flag = NULL;
2,478,558✔
2479
  while ((flag = taosHashIterate(pOld, flag))) {
7,281,534✔
2480
    size_t keyLen = 0;
4,802,976✔
2481
    char  *key = taosHashGetKey(flag, &keyLen);
4,802,976✔
2482

2483
    if ((code = taosHashPut(*ppNew, key, keyLen, flag, sizeof(*flag))) != 0) {
4,802,976✔
2484
      taosHashCancelIterate(pOld, flag);
×
2485
      taosHashCleanup(*ppNew);
×
2486
      TAOS_RETURN(code);
×
2487
    }
2488
  }
2489

2490
  TAOS_RETURN(code);
2,478,558✔
2491
}
2492

2493
int32_t mndMergePrivObjHash(SHashObj *pOld, SHashObj **ppNew) {
91,646,442✔
2494
  if (!(*ppNew)) return mndDupPrivObjHash(pOld, ppNew);
91,646,442✔
2495

2496
  int32_t           code = 0, lino = 0;
91,646,136✔
2497
  SHashObj         *pNew = *ppNew;
91,646,136✔
2498
  SPrivObjPolicies *policies = NULL;
91,645,993✔
2499
  while ((policies = taosHashIterate(pOld, policies))) {
825,933,718✔
2500
    size_t klen = 0;
734,288,550✔
2501
    char  *key = taosHashGetKey(policies, &klen);
734,288,550✔
2502
    size_t vlen = taosHashGetValueSize(policies);
734,288,275✔
2503

2504
    SPrivObjPolicies *pNewPolicies = taosHashGet(pNew, key, klen);
734,288,550✔
2505
    if (pNewPolicies) {
734,288,550✔
2506
      size_t newVlen = taosHashGetValueSize(pNewPolicies);
485,802,320✔
2507
      if (newVlen > 0 && vlen > 0) {
485,802,320✔
2508
        privAddSet(&pNewPolicies->policy, &policies->policy);
485,802,320✔
2509
      }
2510
      continue;
485,801,770✔
2511
    }
2512

2513
    if ((code = taosHashPut(pNew, key, klen, vlen ? policies : NULL, vlen)) != 0) {
248,486,230✔
UNCOV
2514
      taosHashCancelIterate(pOld, policies);
×
2515
      taosHashCleanup(pNew);
×
2516
      *ppNew = NULL;
×
2517
      TAOS_RETURN(code);
×
2518
    }
2519
  }
2520

2521
  TAOS_RETURN(code);
91,646,442✔
2522
}
2523

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

2531
  int32_t           code = 0, lino = 0;
274,937,882✔
2532
  SHashObj         *pNew = *ppNew;
274,937,882✔
2533
  SPrivTblPolicies *policies = NULL;
274,938,717✔
2534
  while ((policies = taosHashIterate(pOld, policies))) {
274,938,717✔
2535
    size_t klen = 0;
×
2536
    char  *key = taosHashGetKey(policies, &klen);
×
2537
    size_t vlen = taosHashGetValueSize(policies);
×
2538

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

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

2564
_exit:
274,939,326✔
2565
  TAOS_RETURN(code);
274,939,326✔
2566
}
2567

2568
int32_t mndDupKVHash(SHashObj *pOld, SHashObj **ppNew) {
33,402,302✔
2569
  if (!(*ppNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true,
33,402,302✔
2570
                              HASH_ENTRY_LOCK))) {
2571
    TAOS_RETURN(terrno);
×
2572
  }
2573
  int32_t code = 0;
33,402,462✔
2574
  void   *val = NULL;
33,402,462✔
2575
  while ((val = taosHashIterate(pOld, val))) {
100,321,563✔
2576
    size_t klen = 0;
66,919,101✔
2577
    char  *key = taosHashGetKey(val, &klen);
66,919,101✔
2578
    size_t vlen = taosHashGetValueSize(val);
66,918,158✔
2579
    if ((code = taosHashPut(*ppNew, key, klen, vlen > 0 ? val : NULL, vlen)) != 0) {
66,918,158✔
2580
      taosHashCancelIterate(pOld, val);
×
2581
      taosHashCleanup(*ppNew);
×
2582
      TAOS_RETURN(code);
×
2583
    }
2584
  }
2585

2586
  TAOS_RETURN(code);
33,402,314✔
2587
}
2588

2589
int32_t mndDupPrivObjHash(SHashObj *pOld, SHashObj **ppNew) {
33,402,298✔
2590
  if (!(*ppNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true,
33,402,298✔
2591
                              HASH_ENTRY_LOCK))) {
2592
    TAOS_RETURN(terrno);
×
2593
  }
2594
  int32_t           code = 0;
33,403,678✔
2595
  SPrivObjPolicies *policies = NULL;
33,403,678✔
2596
  while ((policies = taosHashIterate(pOld, policies))) {
73,629,042✔
2597
    size_t klen = 0;
40,225,364✔
2598
    char  *key = taosHashGetKey(policies, &klen);
40,225,364✔
2599
    size_t vlen = taosHashGetValueSize(policies);
40,225,364✔
2600

2601
    if ((code = taosHashPut(*ppNew, key, klen, vlen > 0 ? policies : NULL, vlen)) != 0) {
40,225,364✔
2602
      taosHashCancelIterate(pOld, policies);
×
2603
      taosHashCleanup(*ppNew);
×
2604
      TAOS_RETURN(code);
×
2605
    }
2606
  }
2607

2608
  TAOS_RETURN(code);
33,403,678✔
2609
}
2610

2611
int32_t mndDupPrivTblHash(SHashObj *pOld, SHashObj **ppNew, bool setUpdateTimeMax) {
102,687,444✔
2612
  if (!(*ppNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true,
102,687,444✔
2613
                              HASH_ENTRY_LOCK))) {
2614
    TAOS_RETURN(terrno);
×
2615
  }
2616
  taosHashSetFreeFp(*ppNew, privTblPoliciesFree);
102,688,070✔
2617

2618
  int32_t           code = 0, lino = 0;
102,688,376✔
2619
  SPrivTblPolicies *policies = NULL, *pTmpPolicies = NULL;
102,688,376✔
2620
  SPrivTblPolicies  tmpPolicies = {0};
102,688,376✔
2621
  while ((policies = taosHashIterate(pOld, policies))) {
103,108,890✔
2622
    size_t klen = 0;
420,514✔
2623
    char  *key = taosHashGetKey(policies, &klen);
420,514✔
2624
    size_t vlen = taosHashGetValueSize(policies);
420,514✔
2625
    memset(&tmpPolicies, 0, sizeof(tmpPolicies));
420,514✔
2626
    pTmpPolicies = &tmpPolicies;
420,514✔
2627
    if (vlen > 0) {
420,514✔
2628
      TAOS_CHECK_EXIT(privTblPoliciesAdd(&tmpPolicies, policies, true, setUpdateTimeMax));
420,514✔
2629
    }
2630
    TAOS_CHECK_EXIT(taosHashPut(*ppNew, key, klen, vlen > 0 ? &tmpPolicies : NULL, vlen));
420,514✔
2631
    pTmpPolicies = NULL;
420,514✔
2632
  }
2633

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

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

2654
  pNew->passwords = NULL;
2,476,126✔
2655
  pNew->pIpWhiteListDual = NULL;
2,476,126✔
2656
  pNew->passwords = NULL;
2,476,126✔
2657
  pNew->objPrivs = NULL;
2,476,126✔
2658
  pNew->selectTbs = NULL;
2,476,126✔
2659
  pNew->insertTbs = NULL;
2,476,126✔
2660
  pNew->updateTbs = NULL;
2,476,126✔
2661
  pNew->deleteTbs = NULL;
2,476,126✔
2662
  pNew->ownedDbs = NULL;
2,476,126✔
2663
  pNew->pTimeWhiteList = NULL;
2,476,126✔
2664
  pNew->roles = NULL;
2,476,126✔
2665
  pNew->legacyPrivs = NULL;
2,476,126✔
2666

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

2704
  pNew->pTimeWhiteList = cloneDateTimeWhiteList(pUser->pTimeWhiteList);
2,476,126✔
2705
  if (pNew->pTimeWhiteList == NULL) {
2,476,126✔
2706
    code = TSDB_CODE_OUT_OF_MEMORY;
×
2707
    goto _OVER;
×
2708
  }
2709

2710
_OVER:
2,476,126✔
2711
  taosRUnLockLatch(&pUser->lock);
2,476,126✔
2712
  if (code == 0) {
2,476,126✔
2713
    dropOldPasswords(pNew);
2,476,126✔
2714
  }
2715
  TAOS_RETURN(code);
2,476,126✔
2716
}
2717

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

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

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

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

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

2798
  TSWAP(pOld->pIpWhiteListDual, pNew->pIpWhiteListDual);
2,517,493✔
2799
  pOld->ipWhiteListVer = pNew->ipWhiteListVer;
2,517,493✔
2800
  TSWAP(pOld->pTimeWhiteList, pNew->pTimeWhiteList);
2,517,493✔
2801
  pOld->timeWhiteListVer = pNew->timeWhiteListVer;
2,517,493✔
2802
  pOld->passEncryptAlgorithm = pNew->passEncryptAlgorithm;
2,517,493✔
2803

2804
  taosWUnLockLatch(&pOld->lock);
2,517,493✔
2805

2806
  return 0;
2,517,493✔
2807
}
2808

2809
int32_t mndAcquireUser(SMnode *pMnode, const char *userName, SUserObj **ppUser) {
103,121,706✔
2810
  int32_t code = 0;
103,121,706✔
2811
  SSdb   *pSdb = pMnode->pSdb;
103,121,706✔
2812

2813
  *ppUser = sdbAcquire(pSdb, SDB_USER, userName);
103,122,094✔
2814
  if (*ppUser == NULL) {
103,122,312✔
2815
    if (terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
79,677✔
2816
      code = TSDB_CODE_MND_USER_NOT_EXIST;
79,677✔
2817
    } else {
2818
      code = TSDB_CODE_MND_USER_NOT_AVAILABLE;
×
2819
    }
2820
  }
2821
  TAOS_RETURN(code);
103,122,312✔
2822
}
2823

2824
void mndReleaseUser(SMnode *pMnode, SUserObj *pUser) {
157,528,906✔
2825
  SSdb *pSdb = pMnode->pSdb;
157,528,906✔
2826
  sdbRelease(pSdb, pUser);
157,529,388✔
2827
}
157,529,429✔
2828

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

2841
int32_t mndBuildUidNamesHash(SMnode *pMnode, SSHashObj **ppHash) {
507,660✔
2842
  int32_t    code = 0;
507,660✔
2843
  void      *pIter = NULL;
507,660✔
2844
  SUserObj  *pObj;
507,660✔
2845
  SSHashObj *pHash = NULL;
507,660✔
2846

2847
  int32_t nUser = sdbGetSize(pMnode->pSdb, SDB_USER);
507,660✔
2848

2849
  pHash = tSimpleHashInit(nUser, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT));
507,660✔
2850
  if (pHash == NULL) {
507,660✔
2851
    TAOS_RETURN(terrno);
×
2852
  }
2853

2854
  while ((pIter = sdbFetch(pMnode->pSdb, SDB_USER, pIter, (void **)&pObj))) {
1,200,406✔
2855
    code = tSimpleHashPut(pHash, &pObj->uid, sizeof(pObj->uid), pObj->name, strlen(pObj->name) + 1);
692,746✔
2856
    if (code != 0) {
692,746✔
2857
      sdbRelease(pMnode->pSdb, pObj);
×
2858
      sdbCancelFetch(pMnode->pSdb, pIter);
×
2859
      tSimpleHashCleanup(pHash);
×
2860
      TAOS_RETURN(code);
×
2861
    }
2862
    sdbRelease(pMnode->pSdb, pObj);
692,746✔
2863
  }
2864

2865
  *ppHash = pHash;
507,660✔
2866
  TAOS_RETURN(code);
507,660✔
2867
}
2868

2869
int32_t mndEncryptPass(char *pass, const char *salt, int8_t *algo) {
89,495✔
2870
  int32_t code = 0;
89,495✔
2871
  if (tsMetaKey[0] == '\0') {
89,495✔
2872
    return 0;
89,433✔
2873
  }
2874

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

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

2892
  memcpy(pass, packetData, newLen);
62✔
2893
  if (algo != NULL) {
62✔
2894
    *algo = DND_CA_SM4;
62✔
2895
  }
2896

2897
  return 0;
62✔
2898
}
2899

2900
static void generateSalt(char *salt, size_t len) {
69,274✔
2901
  const char *set = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
69,274✔
2902
  int32_t     setLen = 62;
69,274✔
2903
  for (int32_t i = 0; i < len - 1; ++i) {
2,216,768✔
2904
    salt[i] = set[taosSafeRand() % setLen];
2,147,494✔
2905
  }
2906
  salt[len - 1] = 0;
69,274✔
2907
}
69,274✔
2908

2909
static int32_t addDefaultIpToTable(SHashObj *pUniqueTab) {
1,024✔
2910
  int32_t code = 0;
1,024✔
2911
  int32_t lino = 0;
1,024✔
2912
  int32_t dummy = 0;
1,024✔
2913

2914
  SIpRange ipv4 = {0}, ipv6 = {0};
1,024✔
2915
  code = createDefaultIp4Range(&ipv4);
1,024✔
2916
  TSDB_CHECK_CODE(code, lino, _error);
1,024✔
2917

2918
  code = taosHashPut(pUniqueTab, &ipv4, sizeof(ipv4), &dummy, sizeof(dummy));
1,024✔
2919
  TSDB_CHECK_CODE(code, lino, _error);
1,024✔
2920

2921
  code = createDefaultIp6Range(&ipv6);
1,024✔
2922
  TSDB_CHECK_CODE(code, lino, _error);
1,024✔
2923

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

2934
static int32_t mndCreateUser(SMnode *pMnode, char *acct, SCreateUserReq *pCreate, SRpcMsg *pReq) {
69,106✔
2935
  int32_t  code = 0;
69,106✔
2936
  int32_t  lino = 0;
69,106✔
2937
  SUserObj userObj = {0};
69,106✔
2938

2939
  userObj.passwords = taosMemoryCalloc(1, sizeof(SUserPassword));
69,106✔
2940
  if (userObj.passwords == NULL) {
69,106✔
2941
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2942
  }
2943
  userObj.numOfPasswords = 1;
69,106✔
2944

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

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

2966
  userObj.createdTime = taosGetTimestampMs();
69,106✔
2967
  userObj.updateTime = userObj.createdTime;
69,106✔
2968
  userObj.superUser = 0;  // pCreate->superUser;
69,106✔
2969
  userObj.sysInfo = pCreate->sysInfo;
69,106✔
2970
  userObj.enable = pCreate->enable;
69,106✔
2971
  userObj.createdb = pCreate->createDb;
69,106✔
2972
  userObj.uid = mndGenerateUid(userObj.user, strlen(userObj.user));
69,106✔
2973

2974
  if (userObj.createdb == 1) {
69,106✔
2975
    privAddType(&userObj.sysPrivs, PRIV_DB_CREATE);
2976
  }
2977

2978
#ifdef TD_ENTERPRISE
2979

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

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

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

3025
    if (taosHashGetSize(pUniqueTab) > MND_MAX_USER_IP_RANGE) {
1,429✔
3026
      taosHashCleanup(pUniqueTab);
×
3027
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_IP_RANGE, &lino, _OVER);
×
3028
    }
3029

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

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

3045
    taosHashCleanup(pUniqueTab);
1,429✔
3046
    p->num = numOfRanges;
1,429✔
3047
    sortIpWhiteList(p);
1,429✔
3048
    userObj.pIpWhiteListDual = p;
1,429✔
3049
  }
3050

3051
  if (pCreate->numTimeRanges == 0) {
69,106✔
3052
    userObj.pTimeWhiteList = (SDateTimeWhiteList *)taosMemoryCalloc(1, sizeof(SDateTimeWhiteList));
67,351✔
3053
    if (userObj.pTimeWhiteList == NULL) {
67,351✔
3054
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3055
    }
3056
  } else {
3057
    SHashObj *pUniqueTab = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
1,755✔
3058
    if (pUniqueTab == NULL) {
1,755✔
3059
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3060
    }
3061

3062
    for (int i = 0; i < pCreate->numTimeRanges; i++) {
3,915✔
3063
      SDateTimeRange        *src = pCreate->pTimeRanges + i;
2,160✔
3064
      SDateTimeWhiteListItem range = {0};
2,160✔
3065
      DateTimeRangeToWhiteListItem(&range, src);
2,160✔
3066

3067
      // no need to add expired range
3068
      if (isDateTimeWhiteListItemExpired(&range)) {
2,160✔
3069
        continue;
270✔
3070
      }
3071

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

3079
    if (taosHashGetSize(pUniqueTab) > MND_MAX_USER_TIME_RANGE) {
1,755✔
3080
      taosHashCleanup(pUniqueTab);
×
3081
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_TIME_RANGE, &lino, _OVER);
×
3082
    }
3083

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

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

3100
    taosHashCleanup(pUniqueTab);
1,755✔
3101
    p->num = numOfRanges;
1,755✔
3102
    sortTimeWhiteList(p);
1,755✔
3103
    userObj.pTimeWhiteList = p;
1,755✔
3104
  }
3105

3106
  userObj.ipWhiteListVer = taosGetTimestampMs();
69,106✔
3107
  userObj.timeWhiteListVer = userObj.ipWhiteListVer;
69,106✔
3108
  
3109

3110
#else  // TD_ENTERPRISE
3111

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

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

3134
  userObj.ipWhiteListVer = 0;
3135
  userObj.timeWhiteListVer = 0;
3136

3137
#endif  // TD_ENTERPRISE
3138

3139
  userObj.roles = taosHashInit(1, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
69,106✔
3140
  if (userObj.roles == NULL) {
69,106✔
3141
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3142
  }
3143

3144
  uint8_t flag = 0x01;
69,106✔
3145
  if ((code = taosHashPut(userObj.roles, TSDB_ROLE_DEFAULT, strlen(TSDB_ROLE_DEFAULT) + 1, &flag, sizeof(flag))) != 0) {
69,106✔
3146
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3147
  }
3148

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

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

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

3170
  if ((code = userCacheUpdateWhiteList(pMnode, &userObj)) != 0) {
69,106✔
3171
    mndTransDrop(pTrans);
×
3172
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3173
  }
3174

3175
  if (taosHashGet(userObj.roles, TSDB_ROLE_SYSAUDIT_LOG, strlen(TSDB_ROLE_SYSAUDIT_LOG) + 1)) {
69,106✔
3176
    (void)mndResetAuditLogUser(pMnode, userObj.user, true);
×
3177
  }
3178

3179
  mndTransDrop(pTrans);
69,106✔
3180

3181
_OVER:
69,106✔
3182
  mndUserFreeObj(&userObj);
69,106✔
3183
  TAOS_RETURN(code);
69,106✔
3184
}
3185

3186
static int32_t mndCheckPasswordFmt(const char *pwd) {
109,487✔
3187
  if (tsEnableAdvancedSecurity == 0 && strcmp(pwd, "taosdata") == 0) {
109,487✔
3188
    return 0;
×
3189
  }
3190

3191
  if (tsEnableStrongPassword == 0) {
109,487✔
3192
    for (char c = *pwd; c != 0; c = *(++pwd)) {
44,936✔
3193
      if (c == ' ' || c == '\'' || c == '\"' || c == '`' || c == '\\') {
44,444✔
3194
        return TSDB_CODE_MND_INVALID_PASS_FORMAT;
×
3195
      }
3196
    }
3197
    return 0;
492✔
3198
  }
3199

3200
  int32_t len = strlen(pwd);
108,995✔
3201
  if (len < TSDB_PASSWORD_MIN_LEN) {
108,995✔
3202
    return TSDB_CODE_PAR_PASSWD_TOO_SHORT_OR_EMPTY;
×
3203
  }
3204

3205
  if (len > TSDB_PASSWORD_MAX_LEN) {
108,995✔
3206
    return TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG;
×
3207
  }
3208

3209
  if (taosIsComplexString(pwd)) {
108,995✔
3210
    return 0;
89,323✔
3211
  }
3212

3213
  return TSDB_CODE_MND_INVALID_PASS_FORMAT;
19,672✔
3214
}
3215

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

3222
  if (taosIsComplexString(seed)) {
×
3223
    return 0;
×
3224
  }
3225

3226
  return TSDB_CODE_PAR_INVALID_OPTION_VALUE;
×
3227
}
3228

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

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

3244
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, wlReq.user, &pUser), &lino, _OVER);
×
3245
  TAOS_CHECK_GOTO(mndSetUserDateTimeWhiteListRsp(pMnode, pUser, &wlRsp), &lino, _OVER);
×
3246

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

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

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

3274
  TAOS_RETURN(code);
×
3275
  return 0;
3276
}
3277

3278
static int32_t buildRetrieveDateTimeWhiteListRsp(SRetrieveDateTimeWhiteListRsp *pRsp) {
424✔
3279
  (void)taosThreadRwlockRdlock(&userCache.rw);
424✔
3280

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

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

3297
    SUserDateTimeWhiteList *pUser = &pRsp->pUsers[count];
×
3298
    pUser->ver = userCache.verTime;
×
3299

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

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

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

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

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

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

3336
  TAOS_CHECK_GOTO(buildRetrieveDateTimeWhiteListRsp(&wlRsp), &lino, _OVER);
424✔
3337

3338
  len = tSerializeSRetrieveDateTimeWhiteListRsp(NULL, 0, &wlRsp);
424✔
3339
  if (len < 0) {
424✔
3340
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
3341
  }
3342

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

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

3363
  tFreeSRetrieveDateTimeWhiteListRsp(&wlRsp);
424✔
3364
  TAOS_RETURN(code);
424✔
3365
}
3366

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

3377
  if (tDeserializeSCreateUserReq(pReq->pCont, pReq->contLen, &createReq) != 0) {
79,418✔
3378
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
3379
  }
3380

3381
  mInfo("user:%s, start to create, createdb:%d, is_import:%d", createReq.user, createReq.createDb, createReq.isImport);
79,418✔
3382

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

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

3402
  if (createReq.user[0] == 0) {
79,418✔
3403
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
3404
  }
3405

3406
  if (createReq.isImport != 1) {
79,418✔
3407
    code = mndCheckPasswordFmt(createReq.pass);
79,418✔
3408
    TAOS_CHECK_GOTO(code, &lino, _OVER);
79,418✔
3409
  }
3410

3411
  if (createReq.totpseed[0] != 0) {
69,426✔
3412
    code = mndCheckTotpSeedFmt(createReq.totpseed);
×
3413
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3414
  }
3415

3416
  code = mndAcquireUser(pMnode, createReq.user, &pUser);
69,426✔
3417
  if (pUser != NULL) {
69,426✔
3418
    TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_ALREADY_EXIST, &lino, _OVER);
320✔
3419
  }
3420

3421
  code = mndAcquireRole(pMnode, createReq.user, &pRole);
69,106✔
3422
  if (pRole != NULL) {
69,106✔
3423
    TAOS_CHECK_GOTO(TSDB_CODE_MND_ROLE_ALREADY_EXIST, &lino, _OVER);
×
3424
  }
3425

3426
  TAOS_CHECK_GOTO(grantCheck(TSDB_GRANT_USER), &lino, _OVER);
69,106✔
3427

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

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

3447
  code = mndCreateUser(pMnode, pOperUser->acct, &createReq, pReq);
69,106✔
3448
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
69,106✔
3449

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

3461
    int64_t tse = taosGetTimestampMs();
69,106✔
3462
    double  duration = (double)(tse - tss);
69,106✔
3463
    duration = duration / 1000;
69,106✔
3464
    auditRecord(pReq, pMnode->clusterId, operation, "", createReq.user, detail, strlen(detail), duration, 0);
69,106✔
3465
  }
3466

3467
_OVER:
79,418✔
3468
  if (code == TSDB_CODE_MND_USER_ALREADY_EXIST && createReq.ignoreExists) {
79,418✔
3469
    code = 0;
×
3470
  } else if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
79,418✔
3471
    mError("user:%s, failed to create at line %d since %s", createReq.user, lino, tstrerror(code));
10,312✔
3472
  }
3473

3474
  mndReleaseRole(pMnode, pRole);
79,418✔
3475
  mndReleaseUser(pMnode, pUser);
79,418✔
3476
  mndReleaseUser(pMnode, pOperUser);
79,418✔
3477
  tFreeSCreateUserReq(&createReq);
79,418✔
3478

3479
  TAOS_RETURN(code);
79,418✔
3480
}
3481

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

3492
  int32_t (*serialFn)(void *, int32_t, SGetUserIpWhiteListRsp *) = NULL;
8,785✔
3493
  int32_t (*setRspFn)(SMnode *pMnode, SUserObj *pUser, SGetUserIpWhiteListRsp *pRsp) = NULL;
8,785✔
3494

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

3507
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, wlReq.user, &pUser), &lino, _OVER);
8,744✔
3508
  TAOS_CHECK_GOTO(setRspFn(pMnode, pUser, &wlRsp), &lino, _OVER);
8,785✔
3509

3510
  contLen = serialFn(NULL, 0, &wlRsp);
8,785✔
3511
  if (contLen < 0) {
8,744✔
3512
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3513
  }
3514
  pRsp = rpcMallocCont(contLen);
8,744✔
3515
  if (pRsp == NULL) {
8,744✔
3516
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3517
  }
3518

3519
  contLen = serialFn(pRsp, contLen, &wlRsp);
8,744✔
3520
  if (contLen < 0) {
8,744✔
3521
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3522
  }
3523

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

3537
  TAOS_RETURN(code);
8,785✔
3538
}
3539

3540
static int32_t buildRetrieveIpWhiteListRsp(SUpdateIpWhite *pUpdate) {
424✔
3541
  (void)taosThreadRwlockRdlock(&userCache.rw);
424✔
3542

3543
  int32_t count = taosHashGetSize(userCache.users);
424✔
3544
  pUpdate->pUserIpWhite = taosMemoryCalloc(count, sizeof(SUpdateUserIpWhite));
424✔
3545
  if (pUpdate->pUserIpWhite == NULL) {
424✔
3546
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
3547
    TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
3548
  }
3549

3550
  count = 0;
424✔
3551
  void *pIter = taosHashIterate(userCache.users, NULL);
424✔
3552
  while (pIter) {
848✔
3553
    SIpWhiteListDual *wl = (*(SCachedUserInfo **)pIter)->wlIp;
424✔
3554
    if (wl == NULL || wl->num <= 0) {
424✔
3555
      pIter = taosHashIterate(userCache.users, pIter);
×
3556
      continue;
×
3557
    }
3558

3559
    SUpdateUserIpWhite *pUser = &pUpdate->pUserIpWhite[count];
424✔
3560
    pUser->ver = userCache.verIp;
424✔
3561

3562
    size_t klen;
424✔
3563
    char  *key = taosHashGetKey(pIter, &klen);
424✔
3564
    (void)memcpy(pUser->user, key, klen);
424✔
3565

3566
    pUser->numOfRange = wl->num;
424✔
3567
    pUser->pIpRanges = taosMemoryCalloc(wl->num, sizeof(SIpRange));
424✔
3568
    if (pUser->pIpRanges == NULL) {
424✔
3569
      (void)taosThreadRwlockUnlock(&userCache.rw);
×
3570
      TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
3571
    }
3572

3573
    (void)memcpy(pUser->pIpRanges, wl->pIpRanges, wl->num * sizeof(SIpRange));
424✔
3574
    count++;
424✔
3575
    pIter = taosHashIterate(userCache.users, pIter);
424✔
3576
  }
3577

3578
  pUpdate->numOfUser = count;
424✔
3579
  pUpdate->ver = userCache.verIp;
424✔
3580
  (void)taosThreadRwlockUnlock(&userCache.rw);
424✔
3581
  TAOS_RETURN(0);
424✔
3582
}
3583

3584
int32_t mndProcessRetrieveIpWhiteListReq(SRpcMsg *pReq) {
424✔
3585
  int32_t        code = 0;
424✔
3586
  int32_t        lino = 0;
424✔
3587
  int32_t        len = 0;
424✔
3588
  void          *pRsp = NULL;
424✔
3589
  SUpdateIpWhite ipWhite = {0};
424✔
3590

3591
  // impl later
3592
  SRetrieveWhiteListReq req = {0};
424✔
3593
  if (tDeserializeRetrieveWhiteListReq(pReq->pCont, pReq->contLen, &req) != 0) {
424✔
3594
    code = TSDB_CODE_INVALID_MSG;
×
3595
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3596
  }
3597

3598
  int32_t (*fn)(void *, int32_t, SUpdateIpWhite *) = NULL;
424✔
3599
  if (pReq->msgType == TDMT_MND_RETRIEVE_IP_WHITELIST) {
424✔
3600
    fn = tSerializeSUpdateIpWhite;
×
3601
  } else if (pReq->msgType == TDMT_MND_RETRIEVE_IP_WHITELIST_DUAL) {
424✔
3602
    fn = tSerializeSUpdateIpWhiteDual;
424✔
3603
  }
3604

3605
  TAOS_CHECK_GOTO(buildRetrieveIpWhiteListRsp(&ipWhite), &lino, _OVER);
424✔
3606

3607
  len = fn(NULL, 0, &ipWhite);
424✔
3608
  if (len < 0) {
424✔
3609
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
3610
  }
3611

3612
  pRsp = rpcMallocCont(len);
424✔
3613
  if (!pRsp) {
424✔
3614
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3615
  }
3616
  len = fn(pRsp, len, &ipWhite);
424✔
3617
  if (len < 0) {
424✔
3618
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
3619
  }
3620

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

3632
  tFreeSUpdateIpWhiteReq(&ipWhite);
424✔
3633
  TAOS_RETURN(code);
424✔
3634
}
3635

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

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

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

3670
static int32_t mndDupObjHash(SHashObj *pOld, int32_t dataLen, SHashObj **ppNew) {
×
3671
  int32_t code = 0;
×
3672

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

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

3691
  TAOS_RETURN(code);
×
3692
}
3693

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

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

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

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

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

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

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

3726
  TAOS_RETURN(0);
×
3727
}
3728

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

3736
  if (taosHashRemove(hash, tbFName, len) != 0) {
×
3737
    TAOS_RETURN(0);  // not found
×
3738
  }
3739

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

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

3755
  return 0;
×
3756
}
3757

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

3767
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, pAlterReq->user, &pUser), &lino, _OVER);
3768
  TAOS_CHECK_GOTO(mndCheckAlterUserPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser, pAlterReq), &lino, _OVER);
3769
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
3770

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

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

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

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

3874
  SHashObj *pReadTbs = newUser.readTbs;
3875
  SHashObj *pWriteTbs = newUser.writeTbs;
3876
  SHashObj *pAlterTbs = newUser.alterTbs;
3877

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

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

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

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

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

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

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

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

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

3948
  TAOS_CHECK_GOTO(mndAlterUser(pMnode, &newUser, pReq), &lino, _OVER);
3949
  code = TSDB_CODE_ACTION_IN_PROGRESS;
3950

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

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

4001
  TAOS_CHECK_EXIT(mndAcquireUser(pMnode, pAlterReq->principal, &pUser));
1,233,112✔
4002

4003
  if (pUser->enable == 0) {
1,232,124✔
4004
    TAOS_CHECK_EXIT(TSDB_CODE_MND_USER_DISABLED);
×
4005
  }
4006

4007
  if (pAlterReq->alterType == TSDB_ALTER_ROLE_PRIVILEGES) {
1,232,124✔
4008
#ifdef TD_ENTERPRISE
4009
    TAOS_CHECK_EXIT(mndUserDupObj(pUser, &newUser));
1,228,444✔
4010
    if ((code = mndAlterUserPrivInfo(pMnode, &newUser, pAlterReq)) == TSDB_CODE_QRY_DUPLICATED_OPERATION) {
1,228,444✔
4011
      code = 0;
×
4012
      goto _exit;
×
4013
    } else {
4014
      TAOS_CHECK_EXIT(code);
1,228,444✔
4015
    }
4016
  } else if (pAlterReq->alterType == TSDB_ALTER_ROLE_ROLE) {
3,680✔
4017
    if ((code = mndAlterUserRoleInfo(pMnode, pOperUser, RPC_MSG_TOKEN(pReq), pUser, &newUser, pAlterReq)) ==
3,680✔
4018
        TSDB_CODE_QRY_DUPLICATED_OPERATION) {
4019
      code = 0;
152✔
4020
      goto _exit;
152✔
4021
    } else {
4022
      TAOS_CHECK_EXIT(code);
3,528✔
4023
    }
4024
#endif
4025
  } else {
4026
    TAOS_CHECK_EXIT(TSDB_CODE_INVALID_MSG);
×
4027
  }
4028
  code = mndAlterUser(pMnode, &newUser, pReq);
1,231,516✔
4029
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
1,231,516✔
4030

4031
_exit:
1,233,112✔
4032
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
1,233,112✔
4033
    mError("user:%s, failed to alter user at line %d since %s", pAlterReq->principal, lino, tstrerror(code));
1,444✔
4034
  }
4035
  mndReleaseUser(pMnode, pUser);
1,233,112✔
4036
  mndUserFreeObj(&newUser);
1,233,112✔
4037
  TAOS_RETURN(code);
1,233,112✔
4038
}
4039

4040
static int32_t mndProcessAlterUserBasicInfoReq(SRpcMsg *pReq, SAlterUserReq *pAlterReq) {
45,141✔
4041
  SMnode   *pMnode = pReq->info.node;
45,141✔
4042
  int32_t   code = 0, lino = 0;
45,141✔
4043
  SUserObj *pUser = NULL;
45,141✔
4044
  SUserObj  newUser = {0};
45,141✔
4045
  char      auditLog[1000] = {0};
45,141✔
4046
  int32_t   auditLen = 0;
45,141✔
4047
  int64_t   tss = taosGetTimestampMs();
45,141✔
4048

4049
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, pAlterReq->user, &pUser), &lino, _OVER);
45,141✔
4050
  TAOS_CHECK_GOTO(mndCheckAlterUserPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser, pAlterReq), &lino,
44,298✔
4051
                  _OVER);
4052
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
42,511✔
4053

4054
  if (pAlterReq->hasPassword) {
42,511✔
4055
    auditLen += tsnprintf(auditLog, sizeof(auditLog), "password,");
30,069✔
4056

4057
    TAOS_CHECK_GOTO(mndCheckPasswordFmt(pAlterReq->pass), &lino, _OVER);
30,069✔
4058
    if (newUser.salt[0] == 0) {
20,389✔
4059
      generateSalt(newUser.salt, sizeof(newUser.salt));
168✔
4060
    }
4061
    char pass[TSDB_PASSWORD_LEN] = {0};
20,389✔
4062
    taosEncryptPass_c((uint8_t *)pAlterReq->pass, strlen(pAlterReq->pass), pass);
20,389✔
4063
    pass[sizeof(pass) - 1] = 0;
20,389✔
4064
    TAOS_CHECK_GOTO(mndEncryptPass(pass, newUser.salt, &newUser.passEncryptAlgorithm), &lino, _OVER);
20,389✔
4065

4066
    if (newUser.passwordReuseMax > 0 || newUser.passwordReuseTime > 0) {
20,389✔
4067
      for (int32_t i = 0; i < newUser.numOfPasswords; ++i) {
724,005✔
4068
        if (0 == strncmp(newUser.passwords[i].pass, pass, TSDB_PASSWORD_LEN)) {
709,830✔
4069
          TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_PASSWORD_REUSE, &lino, _OVER);
405✔
4070
        }
4071
      }
4072
      SUserPassword *passwords = taosMemoryCalloc(newUser.numOfPasswords + 1, sizeof(SUserPassword));
14,175✔
4073
      if (passwords == NULL) {
14,175✔
4074
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
4075
      }
4076
      memcpy(passwords + 1, newUser.passwords, newUser.numOfPasswords * sizeof(SUserPassword));
14,175✔
4077
      memcpy(passwords[0].pass, pass, TSDB_PASSWORD_LEN);
14,175✔
4078
      passwords[0].setTime = taosGetTimestampSec();
14,175✔
4079
      taosMemoryFree(newUser.passwords);
14,175✔
4080
      newUser.passwords = passwords;
14,175✔
4081
      ++newUser.numOfPasswords;
14,175✔
4082
      ++newUser.passVersion;
14,175✔
4083
      newUser.changePass = 2;
14,175✔
4084
    } else if (0 != strncmp(newUser.passwords[0].pass, pass, TSDB_PASSWORD_LEN)) {
5,809✔
4085
      memcpy(newUser.passwords[0].pass, pass, TSDB_PASSWORD_LEN);
5,618✔
4086
      newUser.passwords[0].setTime = taosGetTimestampSec();
5,618✔
4087
      ++newUser.passVersion;
5,618✔
4088
      newUser.changePass = 2;
5,618✔
4089
    }
4090
  }
4091

4092
  if (pAlterReq->hasTotpseed) {
32,426✔
4093
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "totpseed,");
×
4094

4095
    if (pAlterReq->totpseed[0] == 0) {  // clear totp secret
×
4096
      memset(newUser.totpsecret, 0, sizeof(newUser.totpsecret));
×
4097
    } else if (taosGenerateTotpSecret(pAlterReq->totpseed, 0, newUser.totpsecret, sizeof(newUser.totpsecret)) < 0) {
×
4098
      TAOS_CHECK_GOTO(TSDB_CODE_PAR_INVALID_OPTION_VALUE, &lino, _OVER);
×
4099
    }
4100
  }
4101

4102
  if (pAlterReq->hasEnable) {
32,426✔
4103
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "enable:%d,", pAlterReq->enable);
1,285✔
4104

4105
    newUser.enable = pAlterReq->enable;  // lock or unlock user manually
1,285✔
4106
    if (newUser.enable) {
1,285✔
4107
      // reset login info to allow login immediately
4108
      userCacheResetLoginInfo(newUser.user);
801✔
4109
    }
4110
  }
4111

4112
  if (pAlterReq->hasSysinfo) {
32,426✔
4113
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "sysinfo:%d,", pAlterReq->sysinfo);
3,972✔
4114
    newUser.sysInfo = pAlterReq->sysinfo;
3,972✔
4115
  }
4116

4117
  if (pAlterReq->hasCreatedb) {
32,426✔
4118
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "createdb:%d,", pAlterReq->createdb);
5,110✔
4119
    newUser.createdb = pAlterReq->createdb;
5,110✔
4120
    if (newUser.createdb == 1) {
5,110✔
4121
      privAddType(&newUser.sysPrivs, PRIV_DB_CREATE);
4122
    } else {
4123
      privRemoveType(&newUser.sysPrivs, PRIV_DB_CREATE);
4124
    }
4125
  }
4126

4127
#ifdef TD_ENTERPRISE
4128
  if (pAlterReq->hasChangepass) {
32,426✔
4129
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "changepass:%d,", pAlterReq->changepass);
×
4130
    newUser.changePass = pAlterReq->changepass;
×
4131
  }
4132

4133
  if (pAlterReq->hasSessionPerUser) {
32,426✔
4134
    auditLen +=
270✔
4135
        tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "sessionPerUser:%d,", pAlterReq->sessionPerUser);
270✔
4136
    newUser.sessionPerUser = pAlterReq->sessionPerUser;
270✔
4137
  }
4138

4139
  if (pAlterReq->hasConnectTime) {
32,426✔
4140
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "connectTime:%d,", pAlterReq->connectTime);
135✔
4141
    newUser.connectTime = pAlterReq->connectTime;
135✔
4142
  }
4143

4144
  if (pAlterReq->hasConnectIdleTime) {
32,426✔
4145
    auditLen +=
135✔
4146
        tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "connectIdleTime:%d,", pAlterReq->connectIdleTime);
135✔
4147
    newUser.connectIdleTime = pAlterReq->connectIdleTime;
135✔
4148
  }
4149

4150
  if (pAlterReq->hasCallPerSession) {
32,426✔
4151
    auditLen +=
405✔
4152
        tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "callPerSession:%d,", pAlterReq->callPerSession);
405✔
4153
    newUser.callPerSession = pAlterReq->callPerSession;
405✔
4154
  }
4155

4156
  if (pAlterReq->hasVnodePerCall) {
32,426✔
4157
    auditLen +=
270✔
4158
        tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "vnodePerCall:%d,", pAlterReq->vnodePerCall);
270✔
4159
    newUser.vnodePerCall = pAlterReq->vnodePerCall;
270✔
4160
  }
4161

4162
  if (pAlterReq->hasFailedLoginAttempts) {
32,426✔
4163
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "failedLoginAttempts:%d,",
405✔
4164
                          pAlterReq->failedLoginAttempts);
4165
    newUser.failedLoginAttempts = pAlterReq->failedLoginAttempts;
405✔
4166
  }
4167

4168
  if (pAlterReq->hasPasswordLifeTime) {
32,426✔
4169
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordLifeTime:%d,",
135✔
4170
                          pAlterReq->passwordLifeTime);
4171
    newUser.passwordLifeTime = pAlterReq->passwordLifeTime;
135✔
4172
  }
4173

4174
  if (pAlterReq->hasPasswordReuseTime) {
32,426✔
4175
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordReuseTime:%d,",
405✔
4176
                          pAlterReq->passwordReuseTime);
4177
    newUser.passwordReuseTime = pAlterReq->passwordReuseTime;
405✔
4178
  }
4179

4180
  if (pAlterReq->hasPasswordReuseMax) {
32,426✔
4181
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordReuseMax:%d,",
405✔
4182
                          pAlterReq->passwordReuseMax);
4183
    newUser.passwordReuseMax = pAlterReq->passwordReuseMax;
405✔
4184
  }
4185

4186
  if (pAlterReq->hasPasswordLockTime) {
32,426✔
4187
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordLockTime:%d,",
135✔
4188
                          pAlterReq->passwordLockTime);
4189
    newUser.passwordLockTime = pAlterReq->passwordLockTime;
135✔
4190
  }
4191

4192
  if (pAlterReq->hasPasswordGraceTime) {
32,426✔
4193
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordGraceTime:%d,",
135✔
4194
                          pAlterReq->passwordGraceTime);
4195
    newUser.passwordGraceTime = pAlterReq->passwordGraceTime;
135✔
4196
  }
4197

4198
  if (pAlterReq->hasInactiveAccountTime) {
32,426✔
4199
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "inactiveAccountTime:%d,",
135✔
4200
                          pAlterReq->inactiveAccountTime);
4201
    newUser.inactiveAccountTime = pAlterReq->inactiveAccountTime;
135✔
4202
  }
4203

4204
  if (pAlterReq->hasAllowTokenNum) {
32,426✔
4205
    auditLen +=
270✔
4206
        tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "allowTokenNum:%d,", pAlterReq->allowTokenNum);
270✔
4207
    newUser.allowTokenNum = pAlterReq->allowTokenNum;
270✔
4208
  }
4209

4210
  if (pAlterReq->numDropIpRanges > 0 || pAlterReq->numIpRanges > 0) {
32,426✔
4211
    int32_t dummy = 0;
590✔
4212

4213
    // put previous ip whitelist into hash table
4214
    SHashObj *m = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
590✔
4215
    if (m == NULL) {
590✔
4216
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
4217
    }
4218

4219
    for (int32_t i = 0; i < newUser.pIpWhiteListDual->num; i++) {
2,520✔
4220
      SIpRange range;
1,930✔
4221
      copyIpRange(&range, newUser.pIpWhiteListDual->pIpRanges + i);
1,930✔
4222
      code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
1,930✔
4223
      if (code != 0) {
1,930✔
4224
        taosHashCleanup(m);
×
4225
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
4226
      }
4227
    }
4228

4229
    if (pAlterReq->numDropIpRanges > 0) {
590✔
4230
      auditLen +=
295✔
4231
          tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "dropIpRanges:%d,", pAlterReq->numDropIpRanges);
295✔
4232

4233
      for (int32_t i = 0; i < pAlterReq->numDropIpRanges; i++) {
725✔
4234
        if (taosHashGetSize(m) == 0) {
430✔
4235
          break;
×
4236
        }
4237

4238
        SIpRange range;
430✔
4239
        copyIpRange(&range, pAlterReq->pDropIpRanges + i);
430✔
4240

4241
        // for white list, drop default ip ranges is allowed, otherwise, we can never
4242
        // convert white list to black list.
4243

4244
        code = taosHashRemove(m, &range, sizeof(range));
430✔
4245
        if (code == TSDB_CODE_NOT_FOUND) {
430✔
4246
          // treat not exist as success
4247
          code = 0;
160✔
4248
        }
4249
        if (code != 0) {
430✔
4250
          taosHashCleanup(m);
×
4251
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
4252
        }
4253
      }
4254
    }
4255

4256
    if (pAlterReq->numIpRanges > 0) {
590✔
4257
      auditLen +=
295✔
4258
          tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "addIpRanges:%d,", pAlterReq->numIpRanges);
295✔
4259
      for (int32_t i = 0; i < pAlterReq->numIpRanges; i++) {
725✔
4260
        SIpRange range;
430✔
4261
        copyIpRange(&range, pAlterReq->pIpRanges + i);
430✔
4262
        code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
430✔
4263
        if (code != 0) {
430✔
4264
          taosHashCleanup(m);
×
4265
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
4266
        }
4267
      }
4268
    }
4269

4270
    int32_t numOfRanges = taosHashGetSize(m);
590✔
4271
    if (numOfRanges > MND_MAX_USER_IP_RANGE) {
590✔
4272
      taosHashCleanup(m);
×
4273
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_IP_RANGE, &lino, _OVER);
×
4274
    }
4275

4276
    SIpWhiteListDual *p = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + numOfRanges * sizeof(SIpRange));
590✔
4277
    if (p == NULL) {
590✔
4278
      taosHashCleanup(m);
×
4279
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
4280
    }
4281

4282
    void   *pIter = taosHashIterate(m, NULL);
590✔
4283
    int32_t i = 0;
590✔
4284
    while (pIter) {
2,680✔
4285
      size_t    len = 0;
2,090✔
4286
      SIpRange *key = taosHashGetKey(pIter, &len);
2,090✔
4287
      memcpy(p->pIpRanges + i, key, sizeof(SIpRange));
2,090✔
4288
      pIter = taosHashIterate(m, pIter);
2,090✔
4289
      i++;
2,090✔
4290
    }
4291

4292
    taosHashCleanup(m);
590✔
4293
    p->num = numOfRanges;
590✔
4294
    taosMemoryFreeClear(newUser.pIpWhiteListDual);
590✔
4295
    sortIpWhiteList(p);
590✔
4296
    newUser.pIpWhiteListDual = p;
590✔
4297

4298
    newUser.ipWhiteListVer++;
590✔
4299
  }
4300

4301
  if (pAlterReq->numTimeRanges > 0 || pAlterReq->numDropTimeRanges) {
32,426✔
4302
    int32_t dummy = 0;
540✔
4303

4304
    // put previous ip whitelist into hash table
4305
    SHashObj *m = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
540✔
4306
    if (m == NULL) {
540✔
4307
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
4308
    }
4309

4310
    for (int32_t i = 0; i < newUser.pTimeWhiteList->num; i++) {
1,350✔
4311
      SDateTimeWhiteListItem *range = &newUser.pTimeWhiteList->ranges[i];
810✔
4312
      if (isDateTimeWhiteListItemExpired(range)) {
810✔
4313
        continue;
×
4314
      }
4315
      code = taosHashPut(m, range, sizeof(*range), &dummy, sizeof(dummy));
810✔
4316
      if (code != 0) {
810✔
4317
        taosHashCleanup(m);
×
4318
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
4319
      }
4320
    }
4321

4322
    if (pAlterReq->numDropTimeRanges > 0) {
540✔
4323
      auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "dropTimeRanges:%d,",
405✔
4324
                            pAlterReq->numDropTimeRanges);
4325
      for (int32_t i = 0; i < pAlterReq->numDropTimeRanges; i++) {
945✔
4326
        if (taosHashGetSize(m) == 0) {
540✔
4327
          break;
×
4328
        }
4329
        SDateTimeWhiteListItem range = {0};
540✔
4330
        DateTimeRangeToWhiteListItem(&range, pAlterReq->pDropTimeRanges + i);
540✔
4331

4332
        code = taosHashRemove(m, &range, sizeof(range));
540✔
4333
        if (code == TSDB_CODE_NOT_FOUND) {
540✔
4334
          // treat not exist as success
4335
          code = 0;
×
4336
        }
4337
        if (code != 0) {
540✔
4338
          taosHashCleanup(m);
×
4339
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
4340
        }
4341
      }
4342
    }
4343

4344
    if (pAlterReq->numTimeRanges > 0) {
540✔
4345
      auditLen +=
405✔
4346
          tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "addTimeRanges:%d,", pAlterReq->numTimeRanges);
405✔
4347
      for (int32_t i = 0; i < pAlterReq->numTimeRanges; i++) {
945✔
4348
        SDateTimeWhiteListItem range = {0};
540✔
4349
        DateTimeRangeToWhiteListItem(&range, pAlterReq->pTimeRanges + i);
540✔
4350
        if (isDateTimeWhiteListItemExpired(&range)) {
540✔
4351
          continue;
×
4352
        }
4353
        code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
540✔
4354
        if (code != 0) {
540✔
4355
          taosHashCleanup(m);
×
4356
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
4357
        }
4358
      }
4359
    }
4360

4361
    int32_t numOfRanges = taosHashGetSize(m);
540✔
4362
    if (numOfRanges > MND_MAX_USER_TIME_RANGE) {
540✔
4363
      taosHashCleanup(m);
×
4364
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_TIME_RANGE, &lino, _OVER);
×
4365
    }
4366

4367
    SDateTimeWhiteList *p =
1,080✔
4368
        taosMemoryCalloc(1, sizeof(SDateTimeWhiteList) + numOfRanges * sizeof(SDateTimeWhiteListItem));
540✔
4369
    if (p == NULL) {
540✔
4370
      taosHashCleanup(m);
×
4371
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
4372
    }
4373

4374
    void   *pIter = taosHashIterate(m, NULL);
540✔
4375
    int32_t i = 0;
540✔
4376
    while (pIter) {
1,350✔
4377
      size_t                  len = 0;
810✔
4378
      SDateTimeWhiteListItem *key = taosHashGetKey(pIter, &len);
810✔
4379
      memcpy(&p->ranges[i], key, sizeof(SDateTimeWhiteListItem));
810✔
4380
      pIter = taosHashIterate(m, pIter);
810✔
4381
      i++;
810✔
4382
    }
4383

4384
    taosHashCleanup(m);
540✔
4385
    p->num = numOfRanges;
540✔
4386
    taosMemoryFreeClear(newUser.pTimeWhiteList);
540✔
4387
    sortTimeWhiteList(p);
540✔
4388
    newUser.pTimeWhiteList = p;
540✔
4389
    newUser.timeWhiteListVer++;
540✔
4390
  }
4391
#endif  // TD_ENTERPRISE
4392

4393
  TAOS_CHECK_GOTO(mndAlterUser(pMnode, &newUser, pReq), &lino, _OVER);
32,426✔
4394
  if (pAlterReq->hasEnable) {
32,426✔
4395
    if (newUser.enable) {
1,285✔
4396
      if (taosHashGet(newUser.roles, TSDB_ROLE_SYSAUDIT_LOG, strlen(TSDB_ROLE_SYSAUDIT_LOG) + 1)) {
801✔
4397
        (void)mndResetAuditLogUser(pMnode, newUser.user, true);
×
4398
      }
4399
    } else {
4400
      (void)mndResetAuditLogUser(pMnode, newUser.user, false);
484✔
4401
    }
4402
  }
4403
  code = TSDB_CODE_ACTION_IN_PROGRESS;
32,426✔
4404

4405
  if (auditLen > 0) {
32,426✔
4406
    auditLog[--auditLen] = 0;  // remove last ','
32,426✔
4407
  }
4408
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
32,426✔
4409
    int64_t tse = taosGetTimestampMs();
32,426✔
4410
    double  duration = (double)(tse - tss);
32,426✔
4411
    duration = duration / 1000;
32,426✔
4412
    auditRecord(pReq, pMnode->clusterId, "alterUser", "", pAlterReq->user, auditLog, auditLen, duration, 0);
32,426✔
4413
  }
4414

4415
_OVER:
45,141✔
4416
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
45,141✔
4417
    mError("user:%s, failed to alter at line %d since %s", pAlterReq->user, lino, tstrerror(code));
12,715✔
4418
  }
4419

4420
  mndReleaseUser(pMnode, pUser);
45,141✔
4421
  mndUserFreeObj(&newUser);
45,141✔
4422
  return code;
45,141✔
4423
}
4424

4425
static int32_t mndProcessAlterUserReq(SRpcMsg *pReq) {
45,141✔
4426
  SAlterUserReq alterReq = {0};
45,141✔
4427

4428
  int32_t code = tDeserializeSAlterUserReq(pReq->pCont, pReq->contLen, &alterReq);
45,141✔
4429
  if (code != 0) {
45,141✔
4430
    mError("failed to deserialize alter user request at line %d since %s", __LINE__, tstrerror(code));
×
4431
    TAOS_RETURN(code);
×
4432
  }
4433

4434
  if (alterReq.user[0] == 0) {
45,141✔
4435
    tFreeSAlterUserReq(&alterReq);
×
4436
    mError("failed to alter user at line %d since invalid user format", __LINE__);
×
4437
    TAOS_RETURN(TSDB_CODE_MND_INVALID_USER_FORMAT);
×
4438
  }
4439

4440
  mInfo("user:%s, start to alter", alterReq.user);
45,141✔
4441
  if (alterReq.alterType == TSDB_ALTER_USER_BASIC_INFO) {
45,141✔
4442
    code = mndProcessAlterUserBasicInfoReq(pReq, &alterReq);
45,141✔
4443
  } else {
4444
    // code = mndProcessAlterUserPrivilegesReq(pReq, &alterReq); // obsolete
4445
  }
4446

4447
  tFreeSAlterUserReq(&alterReq);
45,141✔
4448
  TAOS_RETURN(code);
45,141✔
4449
}
4450

4451
int32_t mndResetAuditLogUser(SMnode *pMnode, const char *user, bool isAdd) {
47,892,303✔
4452
  if (user) {
47,892,303✔
4453
    (void)taosThreadRwlockRdlock(&userCache.rw);
31,897✔
4454
    if (isAdd) {
31,897✔
4455
      if (userCache.auditLogUser[0] != 0) {
62✔
4456
        (void)taosThreadRwlockUnlock(&userCache.rw);
×
4457
        return 0;
×
4458
      }
4459
      (void)taosThreadRwlockUnlock(&userCache.rw);
62✔
4460
      (void)taosThreadRwlockWrlock(&userCache.rw);
62✔
4461
      (void)tsnprintf(userCache.auditLogUser, TSDB_USER_LEN, "%s", user);
62✔
4462
      (void)taosThreadRwlockUnlock(&userCache.rw);
62✔
4463
      return 0;
62✔
4464
    } else if (strcmp(userCache.auditLogUser, user) != 0) {
31,835✔
4465
      (void)taosThreadRwlockUnlock(&userCache.rw);
31,835✔
4466
      return 0;
31,835✔
4467
    }
4468
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
4469
  }
4470

4471
  void     *pIter = NULL;
47,860,406✔
4472
  SSdb     *pSdb = pMnode->pSdb;
47,860,406✔
4473
  SUserObj *pUser = NULL;
47,860,406✔
4474
  int32_t   len = strlen(TSDB_ROLE_SYSAUDIT_LOG) + 1;
47,860,406✔
4475
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser))) {
101,749,553✔
4476
    if (pUser->enable == 0) {
53,889,147✔
4477
      mndReleaseUser(pMnode, pUser);
18,244✔
4478
      continue;
18,244✔
4479
    }
4480
    if (taosHashGet(pUser->roles, TSDB_ROLE_SYSAUDIT_LOG, len) != NULL) {
53,870,903✔
4481
      (void)taosThreadRwlockWrlock(&userCache.rw);
×
4482
      (void)tsnprintf(userCache.auditLogUser, TSDB_USER_LEN, "%s", pUser->name);
×
4483
      (void)taosThreadRwlockUnlock(&userCache.rw);
×
4484
      sdbCancelFetch(pSdb, pIter);
×
4485
      mndReleaseUser(pMnode, pUser);
×
4486
      return 0;
×
4487
    }
4488
    mndReleaseUser(pMnode, pUser);
53,870,903✔
4489
  }
4490
  (void)taosThreadRwlockWrlock(&userCache.rw);
47,860,406✔
4491
  userCache.auditLogUser[0] = 0;
47,860,406✔
4492
  (void)taosThreadRwlockUnlock(&userCache.rw);
47,860,406✔
4493
  return TSDB_CODE_MND_USER_NOT_AVAILABLE;
47,860,406✔
4494
}
4495

4496
int32_t mndGetAuditUser(SMnode *pMnode, char *user) {
47,861,336✔
4497
  (void)taosThreadRwlockRdlock(&userCache.rw);
47,861,336✔
4498
  if (userCache.auditLogUser[0] != 0) {
47,861,336✔
4499
    (void)tsnprintf(user, TSDB_USER_LEN, "%s", userCache.auditLogUser);
930✔
4500
    (void)taosThreadRwlockUnlock(&userCache.rw);
930✔
4501
    return 0;
930✔
4502
  }
4503
  (void)taosThreadRwlockUnlock(&userCache.rw);
47,860,406✔
4504

4505
  int32_t code = 0;
47,860,406✔
4506
  if ((code = mndResetAuditLogUser(pMnode, NULL, false)) != 0) {
47,860,406✔
4507
    return code;
47,860,406✔
4508
  }
4509

4510
  (void)taosThreadRwlockRdlock(&userCache.rw);
×
4511
  (void)tsnprintf(user, TSDB_USER_LEN, "%s", userCache.auditLogUser);
×
4512
  (void)taosThreadRwlockUnlock(&userCache.rw);
×
4513

4514
  return 0;
×
4515
}
4516

4517
static int32_t mndDropUser(SMnode *pMnode, SRpcMsg *pReq, SUserObj *pUser) {
31,351✔
4518
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "drop-user");
31,351✔
4519
  if (pTrans == NULL) {
31,351✔
4520
    mError("user:%s, failed to drop since %s", pUser->user, terrstr());
×
4521
    TAOS_RETURN(terrno);
×
4522
  }
4523
  mInfo("trans:%d, used to drop user:%s", pTrans->id, pUser->user);
31,351✔
4524

4525
  SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
31,351✔
4526
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
31,351✔
4527
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
4528
    mndTransDrop(pTrans);
×
4529
    TAOS_RETURN(terrno);
×
4530
  }
4531
  if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED) < 0) {
31,351✔
4532
    mndTransDrop(pTrans);
×
4533
    TAOS_RETURN(terrno);
×
4534
  }
4535

4536
  if (mndDropTokensByUser(pMnode, pTrans, pUser->user) != 0) {
31,351✔
4537
    mndTransDrop(pTrans);
×
4538
    TAOS_RETURN(terrno);
×
4539
  }
4540

4541
  if (mndTransPrepare(pMnode, pTrans) != 0) {
31,351✔
4542
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
4543
    mndTransDrop(pTrans);
×
4544
    TAOS_RETURN(terrno);
×
4545
  }
4546

4547
  userCacheRemoveUser(pUser->user);
31,351✔
4548
  mndDropCachedTokensByUser(pUser->user);
31,351✔
4549
  (void)mndResetAuditLogUser(pMnode, pUser->user, false);
31,351✔
4550

4551
  mndTransDrop(pTrans);
31,351✔
4552
  TAOS_RETURN(0);
31,351✔
4553
}
4554

4555
static int32_t mndProcessDropUserReq(SRpcMsg *pReq) {
32,124✔
4556
  SMnode      *pMnode = pReq->info.node;
32,124✔
4557
  int32_t      code = 0;
32,124✔
4558
  int32_t      lino = 0;
32,124✔
4559
  SUserObj    *pOperUser = NULL;
32,124✔
4560
  SUserObj    *pUser = NULL;
32,124✔
4561
  SDropUserReq dropReq = {0};
32,124✔
4562
  int64_t      tss = taosGetTimestampMs();
32,124✔
4563

4564
  TAOS_CHECK_GOTO(tDeserializeSDropUserReq(pReq->pCont, pReq->contLen, &dropReq), &lino, _OVER);
32,124✔
4565

4566
  mInfo("user:%s, start to drop", dropReq.user);
32,124✔
4567

4568
  if (dropReq.user[0] == 0) {
32,124✔
4569
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
4570
  }
4571

4572
  if (0 == strcmp(dropReq.user, TSDB_DEFAULT_USER)) {
32,124✔
4573
    return TSDB_CODE_MND_NO_RIGHTS;
×
4574
  }
4575

4576
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, dropReq.user, &pUser), &lino, _OVER);
32,124✔
4577

4578
  code = mndAcquireUser(pMnode, RPC_MSG_USER(pReq), &pOperUser);
31,351✔
4579
  if (pOperUser == NULL) {
31,351✔
4580
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_USER_FROM_CONN, &lino, _OVER);
×
4581
  }
4582

4583
  // TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, RPC_MSG_USER(pReq), MND_OPER_DROP_USER), &lino, _OVER);
4584
  TAOS_CHECK_GOTO(mndCheckSysObjPrivilege(pMnode, pOperUser, RPC_MSG_TOKEN(pReq), PRIV_USER_DROP, 0, 0, NULL, NULL),
31,351✔
4585
                  &lino, _OVER);
4586

4587
  TAOS_CHECK_GOTO(mndDropUser(pMnode, pReq, pUser), &lino, _OVER);
31,351✔
4588
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
31,351✔
4589

4590
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
31,351✔
4591
    int64_t tse = taosGetTimestampMs();
31,351✔
4592
    double  duration = (double)(tse - tss);
31,351✔
4593
    duration = duration / 1000;
31,351✔
4594
    auditRecord(pReq, pMnode->clusterId, "dropUser", "", dropReq.user, dropReq.sql, dropReq.sqlLen, duration, 0);
31,351✔
4595
  }
4596

4597
_OVER:
32,124✔
4598
  if (dropReq.ignoreNotExists && code == TSDB_CODE_MND_USER_NOT_EXIST) {
32,124✔
4599
    code = 0;
480✔
4600
  } else if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
31,644✔
4601
    mError("user:%s, failed to drop at line %d since %s", dropReq.user, lino, tstrerror(code));
293✔
4602
  }
4603

4604
  mndReleaseUser(pMnode, pUser);
32,124✔
4605
  mndReleaseUser(pMnode, pOperUser);
32,124✔
4606
  tFreeSDropUserReq(&dropReq);
32,124✔
4607
  TAOS_RETURN(code);
32,124✔
4608
}
4609

4610
static int32_t mndProcessGetUserAuthReq(SRpcMsg *pReq) {
5,961,124✔
4611
  SMnode         *pMnode = pReq->info.node;
5,961,124✔
4612
  int32_t         code = 0;
5,961,124✔
4613
  int32_t         lino = 0;
5,961,124✔
4614
  int32_t         contLen = 0;
5,961,124✔
4615
  void           *pRsp = NULL;
5,961,124✔
4616
  SUserObj       *pUser = NULL;
5,961,124✔
4617
  SGetUserAuthReq authReq = {0};
5,961,124✔
4618
  SGetUserAuthRsp authRsp = {0};
5,961,124✔
4619

4620
  TAOS_CHECK_EXIT(tDeserializeSGetUserAuthReq(pReq->pCont, pReq->contLen, &authReq));
5,961,124✔
4621
  mTrace("user:%s, start to get auth", authReq.user);
5,961,124✔
4622

4623
  TAOS_CHECK_EXIT(mndAcquireUser(pMnode, authReq.user, &pUser));
5,961,124✔
4624

4625
  TAOS_CHECK_EXIT(mndSetUserAuthRsp(pMnode, pUser, &authRsp));
5,960,032✔
4626

4627
  contLen = tSerializeSGetUserAuthRsp(NULL, 0, &authRsp);
5,960,032✔
4628
  if (contLen < 0) {
5,960,032✔
4629
    TAOS_CHECK_EXIT(contLen);
×
4630
  }
4631
  pRsp = rpcMallocCont(contLen);
5,960,032✔
4632
  if (pRsp == NULL) {
5,960,032✔
4633
    TAOS_CHECK_EXIT(terrno);
×
4634
  }
4635

4636
  contLen = tSerializeSGetUserAuthRsp(pRsp, contLen, &authRsp);
5,960,032✔
4637
  if (contLen < 0) {
5,960,032✔
4638
    TAOS_CHECK_EXIT(contLen);
×
4639
  }
4640

4641
_exit:
5,961,124✔
4642
  mndReleaseUser(pMnode, pUser);
5,961,124✔
4643
  tFreeSGetUserAuthRsp(&authRsp);
5,961,124✔
4644
  if (code < 0) {
5,961,124✔
4645
    mError("user:%s, failed to get auth at line %d since %s", authReq.user, lino, tstrerror(code));
1,092✔
4646
    rpcFreeCont(pRsp);
1,092✔
4647
    pRsp = NULL;
1,092✔
4648
    contLen = 0;
1,092✔
4649
  }
4650
  pReq->info.rsp = pRsp;
5,961,124✔
4651
  pReq->info.rspLen = contLen;
5,961,124✔
4652
  pReq->code = code;
5,961,124✔
4653

4654
  TAOS_RETURN(code);
5,961,124✔
4655
}
4656

4657
static void base32Encode(const uint8_t *in, int32_t inLen, char *out) {
16,170✔
4658
  int buffer = 0, bits = 0;
16,170✔
4659
  int outLen = 0;
16,170✔
4660

4661
  // process all input bytes
4662
  for (int i = 0; i < inLen; i++) {
533,610✔
4663
    buffer = (buffer << 8) | in[i];
517,440✔
4664
    bits += 8;
517,440✔
4665

4666
    while (bits >= 5) {
1,342,110✔
4667
      int v = (buffer >> (bits - 5)) & 0x1F;
824,670✔
4668
      out[outLen++] = (v >= 26) ? (v - 26 + '2') : (v + 'A');
824,670✔
4669
      bits -= 5;
824,670✔
4670
    }
4671
  }
4672

4673
  // process remaining bits
4674
  if (bits > 0) {
16,170✔
4675
    int v = (buffer << (5 - bits)) & 0x1F;
16,170✔
4676
    out[outLen++] = (v >= 26) ? (v - 26 + '2') : (v + 'A');
16,170✔
4677
  }
4678

4679
  out[outLen] = '\0';
16,170✔
4680
}
16,170✔
4681

4682
static int32_t mndCreateTotpSecret(SMnode *pMnode, SUserObj *pUser, SRpcMsg *pReq) {
16,170✔
4683
  SCreateTotpSecretRsp rsp = {0};
16,170✔
4684

4685
  base32Encode((uint8_t *)pUser->totpsecret, sizeof(pUser->totpsecret), rsp.totpSecret);
16,170✔
4686
  tstrncpy(rsp.user, pUser->user, sizeof(rsp.user));
16,170✔
4687

4688
  int32_t len = tSerializeSCreateTotpSecretRsp(NULL, 0, &rsp);
16,170✔
4689
  if (len < 0) {
16,170✔
4690
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
4691
  }
4692

4693
  void *pData = taosMemoryMalloc(len);
16,170✔
4694
  if (pData == NULL) {
16,170✔
4695
    TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
4696
  }
4697

4698
  if (tSerializeSCreateTotpSecretRsp(pData, len, &rsp) != len) {
16,170✔
4699
    taosMemoryFree(pData);
×
4700
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
4701
  }
4702

4703
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "create-totp-secret");
16,170✔
4704
  if (pTrans == NULL) {
16,170✔
4705
    mError("user:%s, failed to create totp secret since %s", pUser->user, terrstr());
×
4706
    taosMemoryFree(pData);
×
4707
    TAOS_RETURN(terrno);
×
4708
  }
4709
  mInfo("trans:%d, used to create totp secret for user:%s", pTrans->id, pUser->user);
16,170✔
4710

4711
  mndTransSetUserData(pTrans, pData, len);
16,170✔
4712

4713
  SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
16,170✔
4714
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
16,170✔
4715
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
4716
    mndTransDrop(pTrans);
×
4717
    TAOS_RETURN(terrno);
×
4718
  }
4719
  if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY) < 0) {
16,170✔
4720
    mndTransDrop(pTrans);
×
4721
    TAOS_RETURN(terrno);
×
4722
  }
4723

4724
  if (mndTransPrepare(pMnode, pTrans) != 0) {
16,170✔
4725
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
4726
    mndTransDrop(pTrans);
×
4727
    TAOS_RETURN(terrno);
×
4728
  }
4729

4730
  mndTransDrop(pTrans);
16,170✔
4731
  TAOS_RETURN(0);
16,170✔
4732
}
4733

4734
static int32_t mndProcessCreateTotpSecretReq(SRpcMsg *pReq) {
16,318✔
4735
  SMnode              *pMnode = pReq->info.node;
16,318✔
4736
  int32_t              code = 0;
16,318✔
4737
  int32_t              lino = 0;
16,318✔
4738
  SUserObj            *pUser = NULL;
16,318✔
4739
  SUserObj             newUser = {0};
16,318✔
4740
  SCreateTotpSecretReq req = {0};
16,318✔
4741
  int64_t              tss = taosGetTimestampMs();
16,318✔
4742

4743
  TAOS_CHECK_GOTO(tDeserializeSCreateTotpSecretReq(pReq->pCont, pReq->contLen, &req), &lino, _OVER);
16,318✔
4744
  mTrace("user:%s, start to create/update totp secret", req.user);
16,318✔
4745

4746
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, req.user, &pUser), &lino, _OVER);
16,318✔
4747
  TAOS_CHECK_GOTO(mndCheckTotpSecretPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser, PRIV_TOTP_CREATE),
16,170✔
4748
                  &lino, _OVER);
4749
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
16,170✔
4750
  taosSafeRandBytes((uint8_t *)newUser.totpsecret, sizeof(newUser.totpsecret));
16,170✔
4751
  TAOS_CHECK_GOTO(mndCreateTotpSecret(pMnode, &newUser, pReq), &lino, _OVER);
16,170✔
4752

4753
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
16,170✔
4754
    double duration = (double)(taosGetTimestampMs() - tss) / 1000.0;
16,170✔
4755
    auditRecord(pReq, pMnode->clusterId, "createTotpSecret", "", req.user, req.sql, req.sqlLen, duration, 0);
16,170✔
4756
  }
4757

4758
_OVER:
16,318✔
4759
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
16,318✔
4760
    mError("user:%s, failed to create totp secret at line %d since %s", req.user, lino, tstrerror(code));
148✔
4761
  }
4762
  mndReleaseUser(pMnode, pUser);
16,318✔
4763
  mndUserFreeObj(&newUser);
16,318✔
4764
  tFreeSCreateTotpSecretReq(&req);
16,318✔
4765
  TAOS_RETURN(code);
16,318✔
4766
}
4767

4768
int32_t mndBuildSMCreateTotpSecretResp(STrans *pTrans, void **ppResp, int32_t *pRespLen) {
16,170✔
4769
  // user data is the response
4770
  *ppResp = pTrans->userData;
16,170✔
4771
  *pRespLen = pTrans->userDataLen;
16,170✔
4772
  pTrans->userData = NULL;
16,170✔
4773
  pTrans->userDataLen = 0;
16,170✔
4774
  return 0;
16,170✔
4775
}
4776

4777
static int32_t mndProcessDropTotpSecretReq(SRpcMsg *pReq) {
6,216✔
4778
  SMnode            *pMnode = pReq->info.node;
6,216✔
4779
  int32_t            code = 0;
6,216✔
4780
  int32_t            lino = 0;
6,216✔
4781
  SUserObj          *pUser = NULL;
6,216✔
4782
  SUserObj           newUser = {0};
6,216✔
4783
  SDropTotpSecretReq req = {0};
6,216✔
4784
  int64_t            tss = taosGetTimestampMs();
6,216✔
4785

4786
  TAOS_CHECK_GOTO(tDeserializeSDropTotpSecretReq(pReq->pCont, pReq->contLen, &req), &lino, _OVER);
6,216✔
4787
  mTrace("user:%s, start to drop totp secret", req.user);
6,216✔
4788

4789
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, req.user, &pUser), &lino, _OVER);
6,216✔
4790
  TAOS_CHECK_GOTO(mndCheckTotpSecretPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser, PRIV_TOTP_DROP),
4,736✔
4791
                  &lino, _OVER);
4792

4793
  if (!mndIsTotpEnabledUser(pUser)) {
4,736✔
4794
    TAOS_CHECK_GOTO(TSDB_CODE_MND_TOTP_SECRET_NOT_EXIST, &lino, _OVER);
4,440✔
4795
  }
4796

4797
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
296✔
4798
  (void)memset(newUser.totpsecret, 0, sizeof(newUser.totpsecret));
296✔
4799
  TAOS_CHECK_GOTO(mndAlterUser(pMnode, &newUser, pReq), &lino, _OVER);
296✔
4800

4801
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
296✔
4802
    double duration = (double)(taosGetTimestampMs() - tss) / 1000.0;
296✔
4803
    auditRecord(pReq, pMnode->clusterId, "dropTotpSecret", "", req.user, req.sql, req.sqlLen, duration, 0);
296✔
4804
  }
4805

4806
_OVER:
6,216✔
4807
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
6,216✔
4808
    mError("user:%s, failed to drop totp secret at line %d since %s", req.user, lino, tstrerror(code));
5,920✔
4809
  }
4810
  mndReleaseUser(pMnode, pUser);
6,216✔
4811
  mndUserFreeObj(&newUser);
6,216✔
4812
  tFreeSDropTotpSecretReq(&req);
6,216✔
4813
  TAOS_RETURN(code);
6,216✔
4814
}
4815

4816
bool mndIsTotpEnabledUser(SUserObj *pUser) {
3,870,598✔
4817
  for (int32_t i = 0; i < sizeof(pUser->totpsecret); i++) {
126,062,594✔
4818
    if (pUser->totpsecret[i] != 0) {
122,246,237✔
4819
      return true;
51,876✔
4820
    }
4821
  }
4822
  return false;
3,816,357✔
4823
}
4824

4825
static int32_t mndRetrieveUsers(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
111,343✔
4826
  SMnode   *pMnode = pReq->info.node;
111,343✔
4827
  SSdb     *pSdb = pMnode->pSdb;
111,343✔
4828
  int32_t   code = 0;
111,343✔
4829
  int32_t   lino = 0;
111,343✔
4830
  int32_t   numOfRows = 0;
111,343✔
4831
  SUserObj *pUser = NULL;
111,343✔
4832
  int32_t   cols = 0;
111,343✔
4833
  int8_t    flag = 0;
111,343✔
4834
  char     *pWrite = NULL;
111,343✔
4835
  char     *buf = NULL;
111,343✔
4836
  char     *varstr = NULL;
111,343✔
4837
  char      tBuf[TSDB_MAX_SUBROLE * TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
111,343✔
4838
  int32_t   bufSize = sizeof(tBuf) - VARSTR_HEADER_SIZE;
111,343✔
4839

4840
  while (numOfRows < rows) {
974,793✔
4841
    pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
974,793✔
4842
    if (pShow->pIter == NULL) break;
974,793✔
4843

4844
    cols = 0;
863,450✔
4845
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
863,450✔
4846
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
863,450✔
4847
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
863,450✔
4848
    COL_DATA_SET_VAL_GOTO((const char *)name, false, pUser, pShow->pIter, _exit);
863,450✔
4849

4850
    cols++;
863,450✔
4851
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
863,450✔
4852
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->superUser, false, pUser, pShow->pIter, _exit);
863,450✔
4853

4854
    cols++;
863,450✔
4855
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
863,450✔
4856
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->enable, false, pUser, pShow->pIter, _exit);
863,450✔
4857

4858
    cols++;
863,450✔
4859
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
863,450✔
4860
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sysInfo, false, pUser, pShow->pIter, _exit);
863,450✔
4861

4862
    cols++;
863,450✔
4863
    flag = pUser->createdb ? 1 : 0;
863,450✔
4864
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
863,450✔
4865
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
863,450✔
4866

4867
    cols++;
863,450✔
4868
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
863,450✔
4869
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->createdTime, false, pUser, pShow->pIter, _exit);
863,450✔
4870

4871
    cols++;
863,450✔
4872
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
863,450✔
4873
    flag = mndIsTotpEnabledUser(pUser) ? 1 : 0;
863,450✔
4874
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
863,450✔
4875

4876
    cols++;
863,450✔
4877

4878
    int32_t tlen = convertIpWhiteListToStr(pUser, &buf);
863,450✔
4879
    if (tlen != 0) {
863,450✔
4880
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
863,450✔
4881
      if (varstr == NULL) {
863,450✔
4882
        sdbRelease(pSdb, pUser);
×
4883
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
4884
      }
4885
      varDataSetLen(varstr, tlen);
863,450✔
4886
      (void)memcpy(varDataVal(varstr), buf, tlen);
863,450✔
4887

4888
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
863,450✔
4889
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
863,450✔
4890

4891
      taosMemoryFreeClear(buf);
863,450✔
4892
    } else {
4893
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4894
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
4895
    }
4896

4897
    cols++;
863,450✔
4898
    tlen = convertTimeRangesToStr(pUser, &buf);
863,450✔
4899
    if (tlen != 0) {
863,450✔
4900
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
863,450✔
4901
      if (varstr == NULL) {
863,450✔
4902
        sdbRelease(pSdb, pUser);
×
4903
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
4904
      }
4905
      varDataSetLen(varstr, tlen);
863,450✔
4906
      (void)memcpy(varDataVal(varstr), buf, tlen);
863,450✔
4907

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

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

4917
    if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
863,450✔
4918
      void  *pIter = NULL;
863,450✔
4919
      size_t klen = 0, tlen = 0;
863,450✔
4920
      char  *pBuf = POINTER_SHIFT(tBuf, VARSTR_HEADER_SIZE);
863,450✔
4921
      while ((pIter = taosHashIterate(pUser->roles, pIter))) {
1,949,890✔
4922
        char *roleName = taosHashGetKey(pIter, &klen);
1,086,440✔
4923
        tlen += snprintf(pBuf + tlen, bufSize - tlen, "%s,", roleName);
1,086,440✔
4924
      }
4925
      if (tlen > 0) {
863,450✔
4926
        pBuf[--tlen] = 0;  // remove last ','
863,450✔
4927
      } else {
4928
        pBuf[0] = 0;
×
4929
      }
4930
      varDataSetLen(tBuf, tlen);
863,450✔
4931
      COL_DATA_SET_VAL_GOTO((const char *)tBuf, false, pUser, pShow->pIter, _exit);
863,450✔
4932
    }
4933

4934
    numOfRows++;
863,450✔
4935
    sdbRelease(pSdb, pUser);
863,450✔
4936
  }
4937

4938
  pShow->numOfRows += numOfRows;
111,343✔
4939
_exit:
111,343✔
4940
  taosMemoryFreeClear(buf);
111,343✔
4941
  taosMemoryFreeClear(varstr);
111,343✔
4942
  if (code < 0) {
111,343✔
4943
    mError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4944
    TAOS_RETURN(code);
×
4945
  }
4946
  return numOfRows;
111,343✔
4947
}
4948

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

4968
  code = mndAcquireUser(pMnode, RPC_MSG_USER(pReq), &pOperUser);
12,150✔
4969
  if (pOperUser == NULL) {
12,150✔
4970
    TAOS_CHECK_EXIT(TSDB_CODE_MND_NO_USER_FROM_CONN);
×
4971
  }
4972
  if (0 == mndCheckSysObjPrivilege(pMnode, pOperUser, RPC_MSG_TOKEN(pReq), PRIV_USER_SHOW_SECURITY, 0, 0, NULL, NULL)) {
12,150✔
4973
    showSecurityInfo = true;
12,150✔
4974
  }
4975

4976
  while (numOfRows < rows) {
542,160✔
4977
    pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
542,160✔
4978
    if (pShow->pIter == NULL) break;
542,160✔
4979

4980
    cols = 0;
530,010✔
4981
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
530,010✔
4982
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
530,010✔
4983
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
530,010✔
4984
    COL_DATA_SET_VAL_GOTO((const char *)name, false, pUser, pShow->pIter, _exit);
530,010✔
4985

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

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

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

4998
    cols++;
530,010✔
4999
    flag = pUser->createdb ? 1 : 0;
530,010✔
5000
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
530,010✔
5001
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
530,010✔
5002

5003
    cols++;
530,010✔
5004
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
530,010✔
5005
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->createdTime, false, pUser, pShow->pIter, _exit);
530,010✔
5006

5007
    cols++;
530,010✔
5008
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
530,010✔
5009
    flag = mndIsTotpEnabledUser(pUser) ? 1 : 0;
530,010✔
5010
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
530,010✔
5011

5012
    cols++;
530,010✔
5013
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
530,010✔
5014
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->changePass, false, pUser, pShow->pIter, _exit);
530,010✔
5015

5016
    cols++;
530,010✔
5017
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
530,010✔
5018
    char pass[TSDB_PASSWORD_LEN + VARSTR_HEADER_SIZE] = {0};
530,010✔
5019
    STR_WITH_MAXSIZE_TO_VARSTR(pass, showSecurityInfo ? pUser->passwords[0].pass : "*",
530,010✔
5020
                               pShow->pMeta->pSchemas[cols].bytes);
5021
    COL_DATA_SET_VAL_GOTO((const char *)pass, false, pUser, pShow->pIter, _exit);
530,010✔
5022

5023
    cols++;
530,010✔
5024
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
530,010✔
5025
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sessionPerUser, false, pUser, pShow->pIter, _exit);
530,010✔
5026

5027
    cols++;
530,010✔
5028
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
530,010✔
5029
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->connectTime, false, pUser, pShow->pIter, _exit);
530,010✔
5030

5031
    cols++;
530,010✔
5032
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
530,010✔
5033
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->connectIdleTime, false, pUser, pShow->pIter, _exit);
530,010✔
5034

5035
    cols++;
530,010✔
5036
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
530,010✔
5037
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->callPerSession, false, pUser, pShow->pIter, _exit);
530,010✔
5038

5039
    cols++;
530,010✔
5040
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
530,010✔
5041
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->vnodePerCall, false, pUser, pShow->pIter, _exit);
530,010✔
5042

5043
    cols++;
530,010✔
5044
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
530,010✔
5045
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->failedLoginAttempts, false, pUser, pShow->pIter, _exit);
530,010✔
5046

5047
    cols++;
530,010✔
5048
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
530,010✔
5049
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordLifeTime, false, pUser, pShow->pIter, _exit);
530,010✔
5050

5051
    cols++;
530,010✔
5052
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
530,010✔
5053
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordReuseTime, false, pUser, pShow->pIter, _exit);
530,010✔
5054

5055
    cols++;
530,010✔
5056
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
530,010✔
5057
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordReuseMax, false, pUser, pShow->pIter, _exit);
530,010✔
5058

5059
    cols++;
530,010✔
5060
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
530,010✔
5061
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordLockTime, false, pUser, pShow->pIter, _exit);
530,010✔
5062

5063
    cols++;
530,010✔
5064
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
530,010✔
5065
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordGraceTime, false, pUser, pShow->pIter, _exit);
530,010✔
5066

5067
    cols++;
530,010✔
5068
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
530,010✔
5069
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->inactiveAccountTime, false, pUser, pShow->pIter, _exit);
530,010✔
5070

5071
    cols++;
530,010✔
5072
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
530,010✔
5073
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->allowTokenNum, false, pUser, pShow->pIter, _exit);
530,010✔
5074

5075
    cols++;
530,010✔
5076
    int32_t tlen = convertIpWhiteListToStr(pUser, &buf);
530,010✔
5077
    if (tlen != 0) {
530,010✔
5078
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
530,010✔
5079
      if (varstr == NULL) {
530,010✔
5080
        sdbRelease(pSdb, pUser);
×
5081
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
5082
      }
5083
      varDataSetLen(varstr, tlen);
530,010✔
5084
      (void)memcpy(varDataVal(varstr), buf, tlen);
530,010✔
5085

5086
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
530,010✔
5087
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
530,010✔
5088

5089
      taosMemoryFreeClear(buf);
530,010✔
5090
    } else {
5091
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
5092
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
5093
    }
5094

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

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

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

5115
    if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
530,010✔
5116
      void  *pIter = NULL;
530,010✔
5117
      size_t klen = 0, tlen = 0;
530,010✔
5118
      char  *pBuf = POINTER_SHIFT(tBuf, VARSTR_HEADER_SIZE);
530,010✔
5119
      while ((pIter = taosHashIterate(pUser->roles, pIter))) {
1,084,320✔
5120
        char *roleName = taosHashGetKey(pIter, &klen);
554,310✔
5121
        tlen += snprintf(pBuf + tlen, bufSize - tlen, "%s,", roleName);
554,310✔
5122
      }
5123
      if (tlen > 0) {
530,010✔
5124
        pBuf[--tlen] = 0;  // remove last ','
530,010✔
5125
      } else {
5126
        pBuf[0] = 0;
×
5127
      }
5128
      varDataSetLen(tBuf, tlen);
530,010✔
5129
      COL_DATA_SET_VAL_GOTO((const char *)tBuf, false, pUser, pShow->pIter, _exit);
530,010✔
5130
    }
5131

5132
    numOfRows++;
530,010✔
5133
    sdbRelease(pSdb, pUser);
530,010✔
5134
  }
5135

5136
  pShow->numOfRows += numOfRows;
12,150✔
5137
_exit:
12,150✔
5138
  taosMemoryFreeClear(buf);
12,150✔
5139
  taosMemoryFreeClear(varstr);
12,150✔
5140
  mndReleaseUser(pMnode, pOperUser);
12,150✔
5141
  if (code < 0) {
12,150✔
5142
    mError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
5143
    TAOS_RETURN(code);
×
5144
  }
5145
#endif
5146
  return numOfRows;
12,150✔
5147
}
5148

5149
static void mndCancelGetNextUser(SMnode *pMnode, void *pIter) {
×
5150
  SSdb *pSdb = pMnode->pSdb;
×
5151
  sdbCancelFetchByType(pSdb, pIter, SDB_USER);
×
5152
}
×
5153

5154
static int32_t mndLoopHash(SHashObj *hash, char *priType, SSDataBlock *pBlock, int32_t *pNumOfRows, SSdb *pSdb,
×
5155
                           SUserObj *pUser, SShowObj *pShow, char **condition, char **sql) {
5156
  char   *value = taosHashIterate(hash, NULL);
×
5157
  char   *user = pUser->user;
×
5158
  int32_t code = 0;
×
5159
  int32_t lino = 0;
×
5160
  int32_t cols = 0;
×
5161
  int32_t numOfRows = *pNumOfRows;
×
5162

5163
  while (value != NULL) {
×
5164
    cols = 0;
×
5165
    char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
×
5166
    STR_WITH_MAXSIZE_TO_VARSTR(userName, user, pShow->pMeta->pSchemas[cols].bytes);
×
5167
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
5168
    COL_DATA_SET_VAL_GOTO((const char *)userName, false, NULL, NULL, _exit);
×
5169

5170
    char privilege[20] = {0};
×
5171
    STR_WITH_MAXSIZE_TO_VARSTR(privilege, priType, pShow->pMeta->pSchemas[cols].bytes);
×
5172
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
5173
    COL_DATA_SET_VAL_GOTO((const char *)privilege, false, NULL, NULL, _exit);
×
5174

5175
    size_t keyLen = 0;
×
5176
    void  *key = taosHashGetKey(value, &keyLen);
×
5177

5178
    char dbName[TSDB_DB_NAME_LEN] = {0};
×
5179
    (void)mndExtractShortDbNameFromStbFullName(key, dbName);
×
5180
    char dbNameContent[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
×
5181
    STR_WITH_MAXSIZE_TO_VARSTR(dbNameContent, dbName, pShow->pMeta->pSchemas[cols].bytes);
×
5182
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
5183
    COL_DATA_SET_VAL_GOTO((const char *)dbNameContent, false, NULL, NULL, _exit);
×
5184

5185
    char tableName[TSDB_TABLE_NAME_LEN] = {0};
×
5186
    mndExtractTbNameFromStbFullName(key, tableName, TSDB_TABLE_NAME_LEN);
×
5187
    char tableNameContent[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
×
5188
    STR_WITH_MAXSIZE_TO_VARSTR(tableNameContent, tableName, pShow->pMeta->pSchemas[cols].bytes);
×
5189
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
5190
    COL_DATA_SET_VAL_GOTO((const char *)tableNameContent, false, NULL, NULL, _exit);
×
5191

5192
    if (strcmp("t", value) != 0 && strcmp("v", value) != 0) {
×
5193
      SNode  *pAst = NULL;
×
5194
      int32_t sqlLen = 0;
×
5195
      size_t  bufSz = strlen(value) + 1;
×
5196
      if (bufSz < 6) bufSz = 6;
×
5197
      TAOS_MEMORY_REALLOC(*sql, bufSz);
×
5198
      if (*sql == NULL) {
×
5199
        code = terrno;
×
5200
        goto _exit;
×
5201
      }
5202
      TAOS_MEMORY_REALLOC(*condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
×
5203
      if ((*condition) == NULL) {
×
5204
        code = terrno;
×
5205
        goto _exit;
×
5206
      }
5207

5208
      if (nodesStringToNode(value, &pAst) == 0) {
×
5209
        if (nodesNodeToSQLFormat(pAst, *sql, bufSz, &sqlLen, true) != 0) {
×
5210
          sqlLen = tsnprintf(*sql, bufSz, "error");
×
5211
        }
5212
        nodesDestroyNode(pAst);
×
5213
      }
5214

5215
      if (sqlLen == 0) {
×
5216
        sqlLen = tsnprintf(*sql, bufSz, "error");
×
5217
      }
5218

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

5221
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
5222
      COL_DATA_SET_VAL_GOTO((const char *)(*condition), false, NULL, NULL, _exit);
×
5223

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

5238
      char notes[64 + VARSTR_HEADER_SIZE] = {0};
×
5239
      STR_WITH_MAXSIZE_TO_VARSTR(notes, value[0] == 'v' ? "view" : "", sizeof(notes));
×
5240
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
5241
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, NULL, NULL, _exit);
×
5242
    }
5243

5244
    numOfRows++;
×
5245
    value = taosHashIterate(hash, value);
×
5246
  }
5247
  *pNumOfRows = numOfRows;
×
5248
_exit:
×
5249
  if (code < 0) {
×
5250
    mError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
5251
    sdbRelease(pSdb, pUser);
×
5252
    sdbCancelFetch(pSdb, pShow->pIter);
×
5253
  }
5254
  TAOS_RETURN(code);
×
5255
}
5256

5257
#if 0
5258
static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
5259
  int32_t   code = 0;
5260
  int32_t   lino = 0;
5261
  SMnode   *pMnode = pReq->info.node;
5262
  SSdb     *pSdb = pMnode->pSdb;
5263
  int32_t   numOfRows = 0;
5264
  SUserObj *pUser = NULL;
5265
  int32_t   cols = 0;
5266
  char     *pWrite = NULL;
5267
  char     *condition = NULL;
5268
  char     *sql = NULL;
5269

5270
  bool fetchNextUser = pShow->restore ? false : true;
5271
  pShow->restore = false;
5272

5273
  while (numOfRows < rows) {
5274
    if (fetchNextUser) {
5275
      pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
5276
      if (pShow->pIter == NULL) break;
5277
    } else {
5278
      fetchNextUser = true;
5279
      void *pKey = taosHashGetKey(pShow->pIter, NULL);
5280
      pUser = sdbAcquire(pSdb, SDB_USER, pKey);
5281
      if (!pUser) {
5282
        continue;
5283
      }
5284
    }
5285

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

5308
    if (pUser->superUser) {
5309
      cols = 0;
5310
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
5311
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
5312
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5313
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
5314

5315
      char privilege[20] = {0};
5316
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "all", pShow->pMeta->pSchemas[cols].bytes);
5317
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5318
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
5319

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

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

5330
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
5331
      if (condition == NULL) {
5332
        sdbRelease(pSdb, pUser);
5333
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
5334
      }
5335
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
5336
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5337
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
5338

5339
      char notes[2] = {0};
5340
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
5341
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5342
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
5343

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

5355
      char privilege[20] = {0};
5356
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "read", pShow->pMeta->pSchemas[cols].bytes);
5357
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5358
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
5359

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

5373
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
5374
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
5375
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5376
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
5377

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

5388
      char notes[2] = {0};
5389
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
5390
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5391
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
5392

5393
      numOfRows++;
5394
      db = taosHashIterate(pUser->readDbs, db);
5395
    }
5396

5397
    db = taosHashIterate(pUser->writeDbs, NULL);
5398
    while (db != 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, "write", 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
      SName name = {0};
5411
      char  objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
5412
      code = tNameFromString(&name, db, T_NAME_ACCT | T_NAME_DB);
5413
      if (code < 0) {
5414
        sdbRelease(pSdb, pUser);
5415
        sdbCancelFetch(pSdb, pShow->pIter);
5416
        TAOS_CHECK_GOTO(code, &lino, _exit);
5417
      }
5418
      (void)tNameGetDbName(&name, varDataVal(objName));
5419
      varDataSetLen(objName, strlen(varDataVal(objName)));
5420
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5421
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
5422

5423
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
5424
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
5425
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5426
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
5427

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

5438
      char notes[2] = {0};
5439
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
5440
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5441
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
5442

5443
      numOfRows++;
5444
      db = taosHashIterate(pUser->writeDbs, db);
5445
    }
5446
#endif
5447
    TAOS_CHECK_EXIT(mndLoopHash(pUser->selectTbs, "select", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
5448

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

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

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

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

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

5459
    char *topic = taosHashIterate(pUser->topics, NULL);
5460
    while (topic != NULL) {
5461
      cols = 0;
5462
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
5463
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
5464
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5465
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
5466

5467
      char privilege[20] = {0};
5468
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "subscribe", pShow->pMeta->pSchemas[cols].bytes);
5469
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5470
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
5471

5472
      char topicName[TSDB_TOPIC_NAME_LEN + VARSTR_HEADER_SIZE + 5] = {0};
5473
      tstrncpy(varDataVal(topicName), mndGetDbStr(topic), TSDB_TOPIC_NAME_LEN - 2);
5474
      varDataSetLen(topicName, strlen(varDataVal(topicName)));
5475
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5476
      COL_DATA_SET_VAL_GOTO((const char *)topicName, false, pUser, pShow->pIter, _exit);
5477

5478
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
5479
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
5480
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5481
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
5482

5483
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
5484
      if (condition == NULL) {
5485
        sdbRelease(pSdb, pUser);
5486
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
5487
      }
5488
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
5489
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5490
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
5491

5492
      char notes[2] = {0};
5493
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
5494
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5495
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
5496

5497
      numOfRows++;
5498
      topic = taosHashIterate(pUser->topics, topic);
5499
    }
5500

5501
    sdbRelease(pSdb, pUser);
5502
  }
5503

5504
  pShow->numOfRows += numOfRows;
5505
_exit:
5506
  taosMemoryFreeClear(condition);
5507
  taosMemoryFreeClear(sql);
5508
  if (code < 0) {
5509
    mError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
5510
    TAOS_RETURN(code);
5511
  }
5512
  return numOfRows;
5513
}
5514
#endif
5515

5516
int32_t mndShowTablePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows, void *pObj,
233,868✔
5517
                               const char *principalName, SHashObj *privTbs, EPrivType privType, char *pBuf,
5518
                               int32_t bufSize, int32_t *pNumOfRows) {
5519
  int32_t     code = 0, lino = 0;
233,868✔
5520
  SMnode     *pMnode = pReq->info.node;
233,868✔
5521
  SSdb       *pSdb = pMnode->pSdb;
233,868✔
5522
  int32_t     cols = 0, qBufSize = bufSize - VARSTR_HEADER_SIZE;
233,868✔
5523
  int32_t     numOfRows = *pNumOfRows;
233,868✔
5524
  char       *qBuf = NULL;
233,868✔
5525
  char       *sql = NULL;
233,868✔
5526
  char        roleName[TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
233,868✔
5527
  const char *privName = privInfoGetName(privType);
233,868✔
5528

5529
  STR_WITH_MAXSIZE_TO_VARSTR(roleName, principalName, pShow->pMeta->pSchemas[cols].bytes);
233,868✔
5530

5531
  void *pIter = NULL;
233,868✔
5532
  while ((pIter = taosHashIterate(privTbs, pIter))) {
271,672✔
5533
    SPrivTblPolicies *pPolices = (SPrivTblPolicies *)pIter;
37,804✔
5534
    SArray           *tblPolicies = pPolices->policy;
37,804✔
5535

5536
    char   *key = taosHashGetKey(pPolices, NULL);
37,804✔
5537
    int32_t objType = PRIV_OBJ_UNKNOWN;
37,804✔
5538
    char    dbName[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
37,804✔
5539
    char    tblName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
37,804✔
5540
    if ((code = privObjKeyParse(key, &objType, dbName, sizeof(dbName), tblName, sizeof(tblName), false))) {
37,804✔
5541
      sdbRelease(pSdb, pObj);
×
5542
      sdbCancelFetch(pSdb, pShow->pIter);
×
5543
      TAOS_CHECK_EXIT(code);
×
5544
    }
5545

5546
    int32_t nTbPolicies = taosArrayGetSize(tblPolicies);
37,804✔
5547
    for (int32_t i = 0; i < nTbPolicies; ++i) {
75,608✔
5548
      SPrivTblPolicy *tbPolicy = (SPrivTblPolicy *)TARRAY_GET_ELEM(tblPolicies, i);
37,804✔
5549
      cols = 0;
37,804✔
5550
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
37,804✔
5551
      COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
37,804✔
5552

5553
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
37,804✔
5554
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privName, pShow->pMeta->pSchemas[cols].bytes);
37,804✔
5555
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
37,804✔
5556
      }
5557

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

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

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

5637
static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
11,157✔
5638
  int32_t   code = 0, lino = 0;
11,157✔
5639
  SMnode   *pMnode = pReq->info.node;
11,157✔
5640
  SSdb     *pSdb = pMnode->pSdb;
11,157✔
5641
  int32_t   numOfRows = 0;
11,157✔
5642
  int32_t   cols = 0;
11,157✔
5643
  SUserObj *pObj = NULL;
11,157✔
5644
  char     *pBuf = NULL, *qBuf = NULL;
11,157✔
5645
  char     *sql = NULL;
11,157✔
5646
  char      roleName[TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
11,157✔
5647
  int32_t   bufSize = TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE;
11,157✔
5648

5649
  bool fetchNextInstance = pShow->restore ? false : true;
11,157✔
5650
  pShow->restore = false;
11,157✔
5651

5652
  while (numOfRows < rows) {
64,304✔
5653
    if (fetchNextInstance) {
64,304✔
5654
      pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pObj);
64,304✔
5655
      if (pShow->pIter == NULL) break;
64,304✔
5656
    } else {
5657
      fetchNextInstance = true;
×
5658
      void *pKey = taosHashGetKey(pShow->pIter, NULL);
×
5659
      if (!(pObj = sdbAcquire(pSdb, SDB_USER, pKey))) {
×
5660
        continue;
×
5661
      }
5662
    }
5663

5664
    // count total privileges for current user
5665
    int32_t nSysPrivileges = privPopCnt(&pObj->sysPrivs);
53,147✔
5666
    int32_t nObjPrivileges = 0;
53,147✔
5667
    void   *pIter = NULL;
53,147✔
5668
    while ((pIter = taosHashIterate(pObj->objPrivs, pIter))) {
1,004,634✔
5669
      SPrivObjPolicies *pPolices = (SPrivObjPolicies *)pIter;
951,487✔
5670
      nObjPrivileges += privPopCnt(&pPolices->policy);
1,902,974✔
5671
    }
5672
    int32_t nTblPrivileges = privTblPrivCnt(pObj->selectTbs);
53,147✔
5673
    nTblPrivileges += privTblPrivCnt(pObj->insertTbs);
53,147✔
5674
    nTblPrivileges += privTblPrivCnt(pObj->updateTbs);
53,147✔
5675
    nTblPrivileges += privTblPrivCnt(pObj->deleteTbs);
53,147✔
5676

5677
    int32_t totalPrivileges = nSysPrivileges + nObjPrivileges + nTblPrivileges;
53,147✔
5678

5679
    if (numOfRows + totalPrivileges >= rows) {
53,147✔
5680
      if (totalPrivileges >= SHOW_PRIVILEGES_STEP_SIZE) {
×
5681
        mError("user:%s, has too many privileges:%d to show", pObj->name, totalPrivileges);
×
5682
        sdbRelease(pSdb, pObj);
×
5683
        TAOS_CHECK_EXIT(TSDB_CODE_MND_TOO_MANY_PRIVS);
×
5684
      }
5685
      pShow->restore = true;
×
5686
      sdbRelease(pSdb, pObj);
×
5687
      break;
×
5688
    }
5689

5690
    if (!pBuf && !(pBuf = taosMemoryMalloc(bufSize))) {
53,147✔
5691
      sdbRelease(pSdb, pObj);
×
5692
      TAOS_CHECK_EXIT(terrno);
×
5693
    }
5694

5695
    cols = 0;
53,147✔
5696
    STR_WITH_MAXSIZE_TO_VARSTR(roleName, pObj->name, pShow->pMeta->pSchemas[cols].bytes);
53,147✔
5697

5698
    // system privileges
5699
    SPrivIter privIter = {0};
53,147✔
5700
    privIterInit(&privIter, &pObj->sysPrivs);
53,147✔
5701
    SPrivInfo *pPrivInfo = NULL;
53,147✔
5702
    while (privIterNext(&privIter, &pPrivInfo)) {
57,517✔
5703
      cols = 0;
4,370✔
5704
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
4,370✔
5705
      COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
4,370✔
5706

5707
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
4,370✔
5708
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, pPrivInfo->name, pShow->pMeta->pSchemas[cols].bytes);
4,370✔
5709
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
4,370✔
5710
      }
5711
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
4,370✔
5712
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privObjGetName(PRIV_OBJ_CLUSTER), pShow->pMeta->pSchemas[cols].bytes);
4,370✔
5713
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
4,370✔
5714
      }
5715
      // skip db, table, condition, notes, columns, update_time
5716
      COL_DATA_SET_EMPTY_VARCHAR(pBuf, 6);
30,590✔
5717
      numOfRows++;
4,370✔
5718
    }
5719

5720
    // object privileges
5721
    pIter = NULL;
53,147✔
5722
    while ((pIter = taosHashIterate(pObj->objPrivs, pIter))) {
1,004,634✔
5723
      SPrivObjPolicies *pPolices = (SPrivObjPolicies *)pIter;
951,487✔
5724

5725
      char   *key = taosHashGetKey(pPolices, NULL);
951,487✔
5726
      int32_t objType = PRIV_OBJ_UNKNOWN;
951,487✔
5727
      char    dbName[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
951,487✔
5728
      char    tblName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
951,487✔
5729
      if ((code = privObjKeyParse(key, &objType, dbName, sizeof(dbName), tblName, sizeof(tblName), false))) {
951,487✔
5730
        sdbRelease(pSdb, pObj);
×
5731
        TAOS_CHECK_EXIT(code);
×
5732
      }
5733

5734
      SPrivIter privIter = {0};
951,487✔
5735
      privIterInit(&privIter, &pPolices->policy);
951,487✔
5736
      SPrivInfo *pPrivInfo = NULL;
951,487✔
5737
      while (privIterNext(&privIter, &pPrivInfo)) {
2,894,842✔
5738
        cols = 0;
1,943,355✔
5739
        SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
1,943,355✔
5740
        COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
1,943,355✔
5741

5742
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
1,943,355✔
5743
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, pPrivInfo->name, pShow->pMeta->pSchemas[cols].bytes);
1,943,355✔
5744
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
1,943,355✔
5745
        }
5746

5747
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
1,943,355✔
5748
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privObjGetName(objType), pShow->pMeta->pSchemas[cols].bytes);
1,943,355✔
5749
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
1,943,355✔
5750
        }
5751

5752
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
1,943,355✔
5753
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, dbName, pShow->pMeta->pSchemas[cols].bytes);
1,943,355✔
5754
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
1,943,355✔
5755
        }
5756

5757
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
1,943,355✔
5758
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, tblName, pShow->pMeta->pSchemas[cols].bytes);
1,943,355✔
5759
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
1,943,355✔
5760
        }
5761

5762
        // skip condition, notes, columns, update_time
5763
        COL_DATA_SET_EMPTY_VARCHAR(pBuf, 4);
9,716,775✔
5764

5765
        numOfRows++;
1,943,355✔
5766
      }
5767
    }
5768

5769
    // table level privileges
5770
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->name, pObj->selectTbs,
53,147✔
5771
                                           PRIV_TBL_SELECT, pBuf, bufSize, &numOfRows));
5772
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->name, pObj->insertTbs,
53,147✔
5773
                                           PRIV_TBL_INSERT, pBuf, bufSize, &numOfRows));
5774
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->name, pObj->updateTbs,
53,147✔
5775
                                           PRIV_TBL_UPDATE, pBuf, bufSize, &numOfRows));
5776
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->name, pObj->deleteTbs,
53,147✔
5777
                                           PRIV_TBL_DELETE, pBuf, bufSize, &numOfRows));
5778
    sdbRelease(pSdb, pObj);
53,147✔
5779
  }
5780

5781
  pShow->numOfRows += numOfRows;
11,157✔
5782
_exit:
11,157✔
5783
  taosMemoryFreeClear(pBuf);
11,157✔
5784
  taosMemoryFreeClear(sql);
11,157✔
5785
  if (code < 0) {
11,157✔
5786
    mError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
5787
    TAOS_RETURN(code);
×
5788
  }
5789
  return numOfRows;
11,157✔
5790
}
5791

5792
static void mndCancelGetNextPrivileges(SMnode *pMnode, void *pIter) {
×
5793
  SSdb *pSdb = pMnode->pSdb;
×
5794
  sdbCancelFetchByType(pSdb, pIter, SDB_USER);
×
5795
}
×
5796

5797
int32_t mndValidateUserAuthInfo(SMnode *pMnode, SUserAuthVersion *pUsers, int32_t numOfUses, void **ppRsp,
24,603,071✔
5798
                                int32_t *pRspLen, int64_t ipWhiteListVer) {
5799
  int32_t           code = 0;
24,603,071✔
5800
  int32_t           lino = 0;
24,603,071✔
5801
  int32_t           rspLen = 0;
24,603,040✔
5802
  void             *pRsp = NULL;
24,603,040✔
5803
  SUserAuthBatchRsp batchRsp = {0};
24,603,040✔
5804

5805
  batchRsp.pArray = taosArrayInit(numOfUses, sizeof(SGetUserAuthRsp));
24,603,040✔
5806
  if (batchRsp.pArray == NULL) {
24,603,346✔
5807
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
5808
  }
5809
  int64_t now = taosGetTimestampMs();
24,603,346✔
5810
  for (int32_t i = 0; i < numOfUses; ++i) {
49,574,355✔
5811
    SUserObj *pUser = NULL;
24,971,009✔
5812
    code = mndAcquireUser(pMnode, pUsers[i].user, &pUser);
24,971,009✔
5813
    if (pUser == NULL) {
24,971,009✔
5814
      if (TSDB_CODE_MND_USER_NOT_EXIST == code) {
3,915✔
5815
        SGetUserAuthRsp rsp = {.dropped = 1};
3,915✔
5816
        (void)memcpy(rsp.user, pUsers[i].user, TSDB_USER_LEN);
3,915✔
5817
        TSDB_CHECK_NULL(taosArrayPush(batchRsp.pArray, &rsp), code, lino, _OVER, TSDB_CODE_OUT_OF_MEMORY);
7,830✔
5818
      }
5819
      mError("user:%s, failed to auth user since %s", pUsers[i].user, tstrerror(code));
3,915✔
5820
      code = 0;
3,915✔
5821
      continue;
3,915✔
5822
    }
5823

5824
    pUsers[i].version = ntohl(pUsers[i].version);
24,967,094✔
5825
    if ((pUser->authVersion <= pUsers[i].version) && (ipWhiteListVer == pMnode->ipWhiteVer) &&
24,967,094✔
5826
        !mndNeedRetrieveRole(pUser)) {
×
5827
      mndReleaseUser(pMnode, pUser);
×
5828
      continue;
×
5829
    }
5830

5831
    SGetUserAuthRsp rsp = {0};
24,967,094✔
5832
    code = mndSetUserAuthRsp(pMnode, pUser, &rsp);
24,967,094✔
5833
    if (code) {
24,966,613✔
5834
      mndReleaseUser(pMnode, pUser);
×
5835
      tFreeSGetUserAuthRsp(&rsp);
×
5836
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
5837
    }
5838

5839
    if (!(taosArrayPush(batchRsp.pArray, &rsp))) {
49,933,043✔
5840
      code = terrno;
×
5841
      mndReleaseUser(pMnode, pUser);
×
5842
      tFreeSGetUserAuthRsp(&rsp);
×
5843
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
5844
    }
5845
    pUser->lastRoleRetrieve = now;  // update user's last retrieve time
24,966,430✔
5846
    mndReleaseUser(pMnode, pUser);
24,967,094✔
5847
  }
5848

5849
  if (taosArrayGetSize(batchRsp.pArray) <= 0) {
24,603,346✔
5850
    *ppRsp = NULL;
×
5851
    *pRspLen = 0;
×
5852

5853
    tFreeSUserAuthBatchRsp(&batchRsp);
×
5854
    return 0;
×
5855
  }
5856

5857
  rspLen = tSerializeSUserAuthBatchRsp(NULL, 0, &batchRsp);
24,603,346✔
5858
  if (rspLen < 0) {
24,603,198✔
5859
    TAOS_CHECK_GOTO(rspLen, &lino, _OVER);
×
5860
  }
5861
  pRsp = taosMemoryMalloc(rspLen);
24,603,198✔
5862
  if (pRsp == NULL) {
24,602,923✔
5863
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
5864
  }
5865
  rspLen = tSerializeSUserAuthBatchRsp(pRsp, rspLen, &batchRsp);
24,602,923✔
5866
  if (rspLen < 0) {
24,602,758✔
5867
    TAOS_CHECK_GOTO(rspLen, &lino, _OVER);
×
5868
  }
5869
_OVER:
24,602,758✔
5870
  tFreeSUserAuthBatchRsp(&batchRsp);
24,602,758✔
5871
  if (code < 0) {
24,602,229✔
5872
    for (int32_t i = 0; i < numOfUses; ++i) {
×
5873
      SUserObj *pUser = NULL;
×
5874
      if (mndAcquireUser(pMnode, pUsers[i].user, &pUser) != 0) {
×
5875
        continue;
×
5876
      }
5877
      pUser->lastRoleRetrieve = 0;  // reset last retrieve time on error
×
5878
      mndReleaseUser(pMnode, pUser);
×
5879
    }
5880
    mError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
5881
    taosMemoryFreeClear(pRsp);
×
5882
    rspLen = 0;
×
5883
  }
5884
  *ppRsp = pRsp;
24,602,229✔
5885
  *pRspLen = rspLen;
24,602,758✔
5886

5887
  TAOS_RETURN(code);
24,599,572✔
5888
}
5889

5890
int32_t mndUserDropRole(SMnode *pMnode, STrans *pTrans, SRoleObj *pObj) {
×
5891
  int32_t   code = 0, lino = 0;
×
5892
  SSdb     *pSdb = pMnode->pSdb;
×
5893
  SUserObj *pUser = NULL;
×
5894
  void     *pIter = NULL;
×
5895

5896
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser))) {
×
5897
    SHashObj *pRole = taosHashGet(pUser->roles, pObj->name, strlen(pObj->name) + 1);
×
5898
    if (!pRole) {
×
5899
      sdbRelease(pSdb, pUser);
×
5900
      pUser = NULL;
×
5901
      continue;
×
5902
    }
5903

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

5939
static int32_t mndUserPrivHashRemoveDb(SHashObj *pHash, const char *dbFName, int32_t dbFNameLen, bool *found) {
3,545,475✔
5940
  void *pVal = NULL;
3,545,475✔
5941
  while ((pVal = taosHashIterate(pHash, pVal))) {
3,718,362✔
5942
    size_t klen = 0;
172,887✔
5943
    char  *key = taosHashGetKey(pVal, &klen);
172,887✔
5944
    if (key && privDbKeyMatch(key, dbFName, dbFNameLen)) {
345,774✔
5945
      TAOS_CHECK_RETURN(taosHashRemove(pHash, key, klen));
10,155✔
5946
      if (found) *found = true;
10,155✔
5947
    }
5948
  }
5949
  TAOS_RETURN(0);
3,545,475✔
5950
}
5951

5952
static int32_t mndUserRemoveDbPrivsImpl(SUserObj *pUser, const char *key, int32_t keyLen, bool *pFound) {
709,095✔
5953
  bool found = false;
709,095✔
5954
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pUser->objPrivs, (char *)key, keyLen, found ? NULL : &found));
709,095✔
5955
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pUser->selectTbs, (char *)key, keyLen, found ? NULL : &found));
709,095✔
5956
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pUser->insertTbs, (char *)key, keyLen, found ? NULL : &found));
709,095✔
5957
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pUser->updateTbs, (char *)key, keyLen, found ? NULL : &found));
709,095✔
5958
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pUser->deleteTbs, (char *)key, keyLen, found ? NULL : &found));
709,095✔
5959
  if (taosHashGet(pUser->ownedDbs, key, keyLen)) {
709,095✔
5960
    TAOS_CHECK_RETURN(taosHashRemove(pUser->ownedDbs, (char *)key, keyLen));
×
5961
    if (!found) found = true;
×
5962
  }
5963
  if (pFound) *pFound = found;
709,095✔
5964
  TAOS_RETURN(0);
709,095✔
5965
}
5966

5967
static int32_t mndUserRemoveDbPrivs(SMnode *pMnode, STrans *pTrans, const char *key, int32_t keyLen,
637,103✔
5968
                                    SSHashObj **ppUsers) {
5969
  int32_t    code = 0, lino = 0;
637,103✔
5970
  SSdb      *pSdb = pMnode->pSdb;
637,103✔
5971
  void      *pIter = NULL;
637,103✔
5972
  SUserObj  *pUser = NULL;
637,103✔
5973
  SSHashObj *pUsers = ppUsers ? *ppUsers : NULL;
637,103✔
5974
  bool       output = (ppUsers != NULL);
637,103✔
5975
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser))) {
1,345,949✔
5976
    bool found = false;
708,846✔
5977
    TAOS_CHECK_EXIT(mndUserRemoveDbPrivsImpl(pUser, key, keyLen, &found));
708,846✔
5978
    if (!found) {
708,846✔
5979
      sdbRelease(pSdb, pUser);
701,523✔
5980
      pUser = NULL;
701,523✔
5981
      continue;
701,523✔
5982
    }
5983

5984
    if (output) {
7,323✔
5985
      if (!pUsers) {
498✔
5986
        TSDB_CHECK_NULL(pUsers = tSimpleHashInit(32, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY)), code, lino,
249✔
5987
                        _exit, TSDB_CODE_OUT_OF_MEMORY);
5988
        tSimpleHashSetFreeFp(pUsers, (_hash_free_fn_t)mndUserFreeObj);
249✔
5989
        *ppUsers = pUsers;
249✔
5990
      }
5991
      void   *pVal = NULL;
498✔
5992
      int32_t userLen = strlen(pUser->name) + 1;
498✔
5993
      if ((pVal = tSimpleHashGet(pUsers, pUser->name, userLen)) != NULL) {
498✔
5994
        TAOS_CHECK_EXIT(mndUserRemoveDbPrivsImpl((SUserObj *)pVal, key, keyLen, NULL));
249✔
5995
      } else {
5996
        SUserObj newUser = {0};
249✔
5997
        if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
249✔
5998
          mndUserFreeObj(&newUser);
×
5999
          TAOS_CHECK_EXIT(code);
×
6000
        }
6001
        if ((code = tSimpleHashPut(pUsers, pUser->name, userLen, &newUser, sizeof(SUserObj)))) {
249✔
6002
          mndUserFreeObj(&newUser);
×
6003
          TAOS_CHECK_EXIT(code);
×
6004
        }
6005
      }
6006
    } else {
6007
      int64_t now = taosGetTimestampMs();
6,825✔
6008
      taosWLockLatch(&pUser->lock);
6,825✔
6009
      pUser->updateTime = now;
6,825✔
6010
      ++pUser->authVersion;
6,825✔
6011
      taosWUnLockLatch(&pUser->lock);
6,825✔
6012

6013
      SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
6,825✔
6014
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
6,825✔
6015
        TAOS_CHECK_EXIT(TSDB_CODE_OUT_OF_MEMORY);
×
6016
      }
6017
      TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
6,825✔
6018
    }
6019

6020
    sdbRelease(pSdb, pUser);
7,323✔
6021
    pUser = NULL;
7,323✔
6022
  }
6023
_exit:
637,103✔
6024
  if (pUser != NULL) sdbRelease(pSdb, pUser);
637,103✔
6025
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
637,103✔
6026
  TAOS_RETURN(code);
637,103✔
6027
}
6028

6029
static int32_t mndRoleRemoveDbPrivsImpl(SRoleObj *pRole, const char *key, int32_t keyLen, bool *pFound) {
×
6030
  bool found = false;
×
6031
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pRole->objPrivs, (char *)key, keyLen, found ? NULL : &found));
×
6032
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pRole->selectTbs, (char *)key, keyLen, found ? NULL : &found));
×
6033
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pRole->insertTbs, (char *)key, keyLen, found ? NULL : &found));
×
6034
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pRole->updateTbs, (char *)key, keyLen, found ? NULL : &found));
×
6035
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pRole->deleteTbs, (char *)key, keyLen, found ? NULL : &found));
×
6036
  if (pFound) *pFound = found;
×
6037
  TAOS_RETURN(0);
×
6038
}
6039

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

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

6086
      SSdbRaw *pCommitRaw = mndRoleActionEncode(pRole);
×
6087
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
×
6088
        TAOS_CHECK_EXIT(TSDB_CODE_OUT_OF_MEMORY);
×
6089
      }
6090
      TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
×
6091
    }
6092

6093
    sdbRelease(pSdb, pRole);
×
6094
    pRole = NULL;
×
6095
  }
6096
_exit:
×
6097
  if (pRole != NULL) sdbRelease(pSdb, pRole);
×
6098
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
×
6099
  TAOS_RETURN(code);
×
6100
}
6101

6102
int32_t mndPrincipalRemoveDb(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SSHashObj **ppUsers, SSHashObj **ppRoles) {
637,103✔
6103
  TAOS_RETURN(mndUserRemoveDbPrivs(pMnode, pTrans, pDb->name, strlen(pDb->name), ppUsers));
637,103✔
6104
  return mndRoleRemoveDbPrivs(pMnode, pTrans, pDb->name, strlen(pDb->name), ppRoles);
6105
}
6106

6107
int32_t mndUserRemoveStb(SMnode *pMnode, STrans *pTrans, char *stb) {
447,753✔
6108
  return mndPrincipalRemoveObjPrivs(pMnode, pTrans, stb, PRIV_OBJ_TBL);
447,753✔
6109
}
6110

6111
static int32_t mndUserRemoveObjPrivs(SMnode *pMnode, STrans *pTrans, const char *key, int32_t keyLen,
689,259✔
6112
                                     EPrivObjType objType) {
6113
  int32_t   code = 0, lino = 0;
689,259✔
6114
  SSdb     *pSdb = pMnode->pSdb;
689,259✔
6115
  void     *pIter = NULL;
689,259✔
6116
  SUserObj *pUser = NULL;
689,259✔
6117
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser))) {
1,386,224✔
6118
    bool found = false;
696,965✔
6119
    if (taosHashGet(pUser->objPrivs, key, keyLen)) {
696,965✔
6120
      TAOS_CHECK_EXIT(taosHashRemove(pUser->objPrivs, key, keyLen));
2,331✔
6121
      found = true;
2,331✔
6122
    }
6123
    if (objType == PRIV_OBJ_TBL) {
696,965✔
6124
      SPrivTblPolicies *pTblPrivs = taosHashGet(pUser->selectTbs, key, keyLen);
448,041✔
6125
      if (pTblPrivs) {
448,041✔
6126
        TAOS_CHECK_EXIT(taosHashRemove(pUser->selectTbs, key, keyLen));
×
6127
        found = true;
×
6128
      }
6129
      pTblPrivs = taosHashGet(pUser->insertTbs, key, keyLen);
448,041✔
6130
      if (pTblPrivs) {
448,041✔
6131
        TAOS_CHECK_EXIT(taosHashRemove(pUser->insertTbs, key, keyLen));
×
6132
        found = true;
×
6133
      }
6134
      pTblPrivs = taosHashGet(pUser->updateTbs, key, keyLen);
448,041✔
6135
      if (pTblPrivs) {
448,041✔
6136
        TAOS_CHECK_EXIT(taosHashRemove(pUser->updateTbs, key, keyLen));
×
6137
        found = true;
×
6138
      }
6139
      pTblPrivs = taosHashGet(pUser->deleteTbs, key, keyLen);
448,041✔
6140
      if (pTblPrivs) {
448,041✔
6141
        TAOS_CHECK_EXIT(taosHashRemove(pUser->deleteTbs, key, keyLen));
×
6142
        found = true;
×
6143
      }
6144
    }
6145
    if (!found) {
696,965✔
6146
      sdbRelease(pSdb, pUser);
694,634✔
6147
      pUser = NULL;
694,634✔
6148
      continue;
694,634✔
6149
    }
6150

6151
    int64_t now = taosGetTimestampMs();
2,331✔
6152
    taosWLockLatch(&pUser->lock);
2,331✔
6153
    pUser->updateTime = now;
2,331✔
6154
    ++pUser->authVersion;
2,331✔
6155
    taosWUnLockLatch(&pUser->lock);
2,331✔
6156

6157
    SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
2,331✔
6158
    if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
2,331✔
6159
      TAOS_CHECK_EXIT(TSDB_CODE_OUT_OF_MEMORY);
×
6160
    }
6161
    TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
2,331✔
6162

6163
    sdbRelease(pSdb, pUser);
2,331✔
6164
    pUser = NULL;
2,331✔
6165
  }
6166
_exit:
689,259✔
6167
  if (pUser != NULL) sdbRelease(pSdb, pUser);
689,259✔
6168
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
689,259✔
6169
  TAOS_RETURN(code);
689,259✔
6170
}
6171

6172
static int32_t mndRoleRemoveObjPrivs(SMnode *pMnode, STrans *pTrans, const char *key, int32_t keyLen,
689,259✔
6173
                                     EPrivObjType objType) {
6174
  int32_t   code = 0, lino = 0;
689,259✔
6175
  SSdb     *pSdb = pMnode->pSdb;
689,259✔
6176
  void     *pIter = NULL;
689,259✔
6177
  SRoleObj *pRole = NULL;
689,259✔
6178
  while ((pIter = sdbFetch(pSdb, SDB_ROLE, pIter, (void **)&pRole))) {
4,824,813✔
6179
    // inherit system roles have no direct privileges
6180
    if (taosStrncasecmp(pRole->name, "sys", 3) == 0) {
4,135,554✔
6181
      sdbRelease(pSdb, pRole);
4,135,554✔
6182
      pRole = NULL;
4,135,554✔
6183
      continue;
4,135,554✔
6184
    }
6185
    bool found = false;
×
6186
    if (taosHashGet(pRole->objPrivs, key, keyLen)) {
×
6187
      TAOS_CHECK_EXIT(taosHashRemove(pRole->objPrivs, key, keyLen));
×
6188
      found = true;
×
6189
    }
6190

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

6224
    SSdbRaw *pCommitRaw = mndRoleActionEncode(pRole);
×
6225
    if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
×
6226
      TAOS_CHECK_EXIT(TSDB_CODE_OUT_OF_MEMORY);
×
6227
    }
6228
    TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
×
6229

6230
    sdbRelease(pSdb, pRole);
×
6231
    pRole = NULL;
×
6232
  }
6233
_exit:
689,259✔
6234
  if (pRole != NULL) sdbRelease(pSdb, pRole);
689,259✔
6235
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
689,259✔
6236
  TAOS_RETURN(code);
689,259✔
6237
}
6238

6239
static int32_t mndPrincipalRemoveObjPrivs(SMnode *pMnode, STrans *pTrans, char *objFName, EPrivObjType objType) {
689,259✔
6240
  int32_t code = 0;
689,259✔
6241
  char    key[TSDB_PRIV_MAX_KEY_LEN] = {0};
689,259✔
6242
  int32_t keyLen = snprintf(key, sizeof(key), "%d.%s", objType, objFName) + 1;
689,259✔
6243
  TAOS_CHECK_RETURN(mndUserRemoveObjPrivs(pMnode, pTrans, key, keyLen, objType));
689,259✔
6244
  TAOS_CHECK_RETURN(mndRoleRemoveObjPrivs(pMnode, pTrans, key, keyLen, objType));
689,259✔
6245
  TAOS_RETURN(code);
689,259✔
6246
}
6247

6248
int32_t mndUserRemoveView(SMnode *pMnode, STrans *pTrans, char *view) {
142,222✔
6249
  return mndPrincipalRemoveObjPrivs(pMnode, pTrans, view, PRIV_OBJ_VIEW);
142,222✔
6250
}
6251

6252
int32_t mndUserRemoveTopic(SMnode *pMnode, STrans *pTrans, char *topic) {
99,284✔
6253
  return mndPrincipalRemoveObjPrivs(pMnode, pTrans, topic, PRIV_OBJ_TOPIC);
99,284✔
6254
}
6255

6256
int64_t mndGetUserIpWhiteListVer(SMnode *pMnode, SUserObj *pUser) {
×
6257
  // ver = 0, disable ip white list
6258
  // ver > 0, enable ip white list
6259
  return tsEnableWhiteList ? pUser->ipWhiteListVer : 0;
×
6260
}
6261

6262
int64_t mndGetUserTimeWhiteListVer(SMnode *pMnode, SUserObj *pUser) {
×
6263
  // ver = 0, disable datetime white list
6264
  // ver > 0, enable datetime white list
6265
  return tsEnableWhiteList ? pUser->timeWhiteListVer : 0;
×
6266
}
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