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

taosdata / TDengine / #4887

16 Dec 2025 08:27AM UTC coverage: 65.289% (-0.003%) from 65.292%
#4887

push

travis-ci

web-flow
feat[TS-7233]: audit (#33850)

377 of 536 new or added lines in 28 files covered. (70.34%)

1025 existing lines in 111 files now uncovered.

178977 of 274129 relevant lines covered (65.29%)

102580217.43 hits per line

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

72.49
/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 "mndUser.h"
23
#include "audit.h"
24
#include "mndDb.h"
25
#include "mndPrivilege.h"
26
#include "mndShow.h"
27
#include "mndStb.h"
28
#include "mndTopic.h"
29
#include "mndTrans.h"
30
#include "tbase64.h"
31
#include "totp.h"
32

33
// clang-format on
34

35
#define USER_VER_SUPPORT_WHITELIST           5
36
#define USER_VER_SUPPORT_WHITELIT_DUAL_STACK 7
37
#define USER_VER_SUPPORT_ADVANCED_SECURITY   8
38
#define USER_VER_NUMBER                      USER_VER_SUPPORT_ADVANCED_SECURITY 
39
#define USER_RESERVE_SIZE                    63
40

41
#define BIT_FLAG_MASK(n)              (1 << n)
42
#define BIT_FLAG_SET_MASK(val, mask)  ((val) |= (mask))
43
#define BIT_FLAG_TEST_MASK(val, mask) (((val) & (mask)) != 0)
44

45
#define PRIVILEGE_TYPE_ALL       BIT_FLAG_MASK(0)
46
#define PRIVILEGE_TYPE_READ      BIT_FLAG_MASK(1)
47
#define PRIVILEGE_TYPE_WRITE     BIT_FLAG_MASK(2)
48
#define PRIVILEGE_TYPE_SUBSCRIBE BIT_FLAG_MASK(3)
49
#define PRIVILEGE_TYPE_ALTER     BIT_FLAG_MASK(4)
50

51
#define ALTER_USER_ADD_PRIVS(_type) ((_type) == TSDB_ALTER_USER_ADD_PRIVILEGES)
52
#define ALTER_USER_DEL_PRIVS(_type) ((_type) == TSDB_ALTER_USER_DEL_PRIVILEGES)
53

54
#define ALTER_USER_ALL_PRIV(_priv) (BIT_FLAG_TEST_MASK((_priv), PRIVILEGE_TYPE_ALL))
55
#define ALTER_USER_READ_PRIV(_priv) \
56
  (BIT_FLAG_TEST_MASK((_priv), PRIVILEGE_TYPE_READ) || BIT_FLAG_TEST_MASK((_priv), PRIVILEGE_TYPE_ALL))
57
#define ALTER_USER_WRITE_PRIV(_priv) \
58
  (BIT_FLAG_TEST_MASK((_priv), PRIVILEGE_TYPE_WRITE) || BIT_FLAG_TEST_MASK((_priv), PRIVILEGE_TYPE_ALL))
59
#define ALTER_USER_ALTER_PRIV(_priv) \
60
  (BIT_FLAG_TEST_MASK((_priv), PRIVILEGE_TYPE_ALTER) || BIT_FLAG_TEST_MASK((_priv), PRIVILEGE_TYPE_ALL))
61
#define ALTER_USER_SUBSCRIBE_PRIV(_priv) (BIT_FLAG_TEST_MASK((_priv), PRIVILEGE_TYPE_SUBSCRIBE))
62

63
#define ALTER_USER_TARGET_DB(_tbname) (0 == (_tbname)[0])
64
#define ALTER_USER_TARGET_TB(_tbname) (0 != (_tbname)[0])
65

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

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

100
#define ALTER_USER_ADD_SUBSCRIBE_TOPIC_PRIV(_type, _priv) \
101
  (ALTER_USER_ADD_PRIVS(_type) && ALTER_USER_SUBSCRIBE_PRIV(_priv))
102
#define ALTER_USER_DEL_SUBSCRIBE_TOPIC_PRIV(_type, _priv) \
103
  (ALTER_USER_DEL_PRIVS(_type) && ALTER_USER_SUBSCRIBE_PRIV(_priv))
104

105
static void generateSalt(char *salt, size_t len);
106

107
static int32_t createDefaultIpWhiteList(SIpWhiteListDual **ppWhiteList);
108
static int32_t createIpWhiteList(void *buf, int32_t len, SIpWhiteListDual **ppWhiteList, bool supportNeg);
109

110
static bool isIpWhiteListEqual(SIpWhiteListDual *a, SIpWhiteListDual *b);
111
static bool isIpRangeEqual(SIpRange *a, SIpRange *b);
112

113
#define MND_MAX_USER_IP_RANGE   (TSDB_PRIVILEDGE_HOST_LEN / 24)
114
#define MND_MAX_USER_TIME_RANGE 2048
115

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

132
static int32_t  mndProcessGetUserIpWhiteListReq(SRpcMsg *pReq);
133
static int32_t  mndProcessRetrieveIpWhiteListReq(SRpcMsg *pReq);
134
static int32_t  mndProcessGetUserDateTimeWhiteListReq(SRpcMsg *pReq);
135
static int32_t  mndProcessRetrieveDateTimeWhiteListReq(SRpcMsg *pReq);
136

137
static int32_t createIpWhiteListFromOldVer(void *buf, int32_t len, SIpWhiteList **ppList);
138
static int32_t tDerializeIpWhileListFromOldVer(void *buf, int32_t len, SIpWhiteList *pList);
139

140

141
typedef struct {
142
  SIpWhiteListDual   *wlIp;
143
  SDateTimeWhiteList *wlTime;
144
  SLoginInfo          loginInfo;
145
} SCachedUserInfo;
146

147
typedef struct {
148
  SHashObj      *users;  // key: user, value: SCachedUserInfo*
149
  int64_t        verIp;
150
  int64_t        verTime;
151
  TdThreadRwlock rw;
152
} SUserCache;
153

154
static SUserCache userCache;
155

156

157
static int32_t userCacheInit() {
516,782✔
158
  _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
516,782✔
159

160
  SHashObj *users = taosHashInit(8, hashFn, 1, HASH_ENTRY_LOCK);
516,782✔
161
  if (users == NULL) {
516,782✔
162
    TAOS_RETURN(terrno);
×
163
  }
164

165
  userCache.users = users;
516,782✔
166
  userCache.verIp = 0;
516,782✔
167
  userCache.verTime = 0;
516,782✔
168

169
  (void)taosThreadRwlockInit(&userCache.rw, NULL);
516,782✔
170
  TAOS_RETURN(0);
516,782✔
171
}
172

173

174

175
static void userCacheCleanup() {
516,665✔
176
  if (userCache.users == NULL) {
516,665✔
177
    return;
×
178
  }
179

180
  void *pIter = taosHashIterate(userCache.users, NULL);
516,665✔
181
  while (pIter) {
1,042,927✔
182
    SCachedUserInfo *pInfo = *(SCachedUserInfo **)pIter;
526,262✔
183
    if (pInfo != NULL) {
526,262✔
184
      taosMemoryFree(pInfo->wlIp);
526,262✔
185
      taosMemoryFree(pInfo->wlTime);
526,262✔
186
      taosMemoryFree(pInfo);
526,262✔
187
    }
188
    pIter = taosHashIterate(userCache.users, pIter);
526,262✔
189
  }
190
  taosHashCleanup(userCache.users);
516,665✔
191

192
  (void)taosThreadRwlockDestroy(&userCache.rw);
516,665✔
193
}
194

195

196

197
static void userCacheRemoveUser(const char *user) {
61,608✔
198
  size_t userLen = strlen(user);
61,608✔
199

200
  (void)taosThreadRwlockWrlock(&userCache.rw);
61,608✔
201

202
  SCachedUserInfo **ppInfo = taosHashGet(userCache.users, user, userLen);
61,608✔
203
  if (ppInfo != NULL) {
61,608✔
204
    if (*ppInfo != NULL) {
61,608✔
205
      taosMemoryFree((*ppInfo)->wlIp);
61,608✔
206
      taosMemoryFree((*ppInfo)->wlTime);
61,608✔
207
      taosMemoryFree(*ppInfo);
61,608✔
208
    }
209
    if (taosHashRemove(userCache.users, user, userLen) != 0) {
61,608✔
210
      mDebug("failed to remove user %s from user cache", user);
×
211
    }
212
    userCache.verIp++;
61,608✔
213
    userCache.verTime++;
61,608✔
214
  }
215

216
  (void)taosThreadRwlockUnlock(&userCache.rw);
61,608✔
217
}
61,608✔
218

219

220

221
static void userCacheResetLoginInfo(const char *user) {
1,355✔
222
  size_t userLen = strlen(user);
1,355✔
223

224
  (void)taosThreadRwlockWrlock(&userCache.rw);
1,355✔
225

226
  SCachedUserInfo **ppInfo = taosHashGet(userCache.users, user, userLen);
1,355✔
227
  if (ppInfo != NULL && *ppInfo != NULL) {
1,355✔
228
    (*ppInfo)->loginInfo.lastLoginTime = taosGetTimestampSec();
1,355✔
229
    (*ppInfo)->loginInfo.failedLoginCount = 0;
1,355✔
230
    (*ppInfo)->loginInfo.lastFailedLoginTime = 0;
1,355✔
231
  }
232

233
  (void)taosThreadRwlockUnlock(&userCache.rw);
1,355✔
234
}
1,355✔
235

236

237

238
static SCachedUserInfo* getCachedUserInfo(const char* user) {
4,650,537✔
239
  size_t userLen = strlen(user);
4,650,537✔
240
  SCachedUserInfo **ppInfo = taosHashGet(userCache.users, user, userLen);
4,650,537✔
241
  if (ppInfo != NULL) {
4,650,537✔
242
    return *ppInfo;
4,062,667✔
243
  }
244

245
  SCachedUserInfo  *pInfo = (SCachedUserInfo *)taosMemoryCalloc(1, sizeof(SCachedUserInfo));
587,870✔
246
  if (pInfo == NULL) {
587,870✔
247
    return NULL;
×
248
  }
249

250
  if (taosHashPut(userCache.users, user, userLen, &pInfo, sizeof(pInfo)) != 0) {
587,870✔
251
    taosMemoryFree(pInfo);
×
252
    return NULL;
×
253
  }
254

255
  return pInfo;
587,870✔
256
}
257

258

259

260
void mndGetUserLoginInfo(const char *user, SLoginInfo *pLoginInfo) {
3,100,440✔
261
  size_t userLen = strlen(user);
3,100,440✔
262

263
  (void)taosThreadRwlockRdlock(&userCache.rw);
3,100,440✔
264

265
  SCachedUserInfo **ppInfo = taosHashGet(userCache.users, user, userLen);
3,100,954✔
266
  if (ppInfo != NULL && *ppInfo != NULL) {
3,099,414✔
267
    pLoginInfo->lastLoginTime = (*ppInfo)->loginInfo.lastLoginTime;
2,769,896✔
268
    pLoginInfo->failedLoginCount = (*ppInfo)->loginInfo.failedLoginCount;
2,770,313✔
269
    pLoginInfo->lastFailedLoginTime = (*ppInfo)->loginInfo.lastFailedLoginTime;
2,769,620✔
270
  } else {
271
    pLoginInfo->lastLoginTime = taosGetTimestampSec();
329,518✔
272
    pLoginInfo->failedLoginCount = 0;
329,518✔
273
    pLoginInfo->lastFailedLoginTime = 0;
329,518✔
274
  }
275

276
  (void)taosThreadRwlockUnlock(&userCache.rw);
3,099,935✔
277

278
  if (pLoginInfo->lastLoginTime == 0) {
3,099,650✔
279
    pLoginInfo->lastLoginTime = taosGetTimestampSec();
47,675✔
280
  }
281
}
3,099,650✔
282

283

284

285
void mndSetUserLoginInfo(const char *user, const SLoginInfo *pLoginInfo) {
3,100,340✔
286
  size_t userLen = strlen(user);
3,100,340✔
287

288
  (void)taosThreadRwlockWrlock(&userCache.rw);
3,100,340✔
289

290
  SCachedUserInfo  *pInfo = getCachedUserInfo(user);
3,100,954✔
291
  if (pInfo != NULL) {
3,100,954✔
292
    pInfo->loginInfo.lastLoginTime = pLoginInfo->lastLoginTime;
3,100,954✔
293
    pInfo->loginInfo.failedLoginCount = pLoginInfo->failedLoginCount;
3,100,954✔
294
    pInfo->loginInfo.lastFailedLoginTime = pLoginInfo->lastFailedLoginTime;
3,100,954✔
295
  }
296

297
  (void)taosThreadRwlockUnlock(&userCache.rw);
3,100,954✔
298
}
3,100,954✔
299

300

301

302
static bool isDateTimeWhiteListEqual(SDateTimeWhiteList *a, SDateTimeWhiteList *b) {
1,035,145✔
303
  if (a == NULL && b == NULL) {
1,035,145✔
304
    return true;
×
305
  }
306

307
  if (a == NULL || b == NULL) {
1,035,145✔
308
    return false;
103,995✔
309
  }
310

311
  if (a->num != b->num) {
931,150✔
312
    return false;
×
313
  }
314

315
  for (int i = 0; i < a->num; i++) {
931,150✔
316
    if (a->ranges[i].start != b->ranges[i].start ||
×
317
        a->ranges[i].duration != b->ranges[i].duration ||
×
318
        a->ranges[i].neg != b->ranges[i].neg ||
×
319
        a->ranges[i].absolute != b->ranges[i].absolute) {
×
320
      return false;
×
321
    }
322
  }
323

324
  return true;
931,150✔
325
}
326

327

328

329
static int32_t userCacheUpdateWhiteList(SMnode* pMnode, SUserObj* pUser) {
1,035,145✔
330
  int32_t code = 0, lino = 0;
1,035,145✔
331

332
  (void)taosThreadRwlockWrlock(&userCache.rw);
1,035,145✔
333

334
  SCachedUserInfo *pInfo = getCachedUserInfo(pUser->user);
1,035,145✔
335
  if (pInfo == NULL) {
1,035,145✔
336
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
337
  }
338

339
  if (!isIpWhiteListEqual(pInfo->wlIp, pUser->pIpWhiteListDual)) {
1,035,145✔
340
    SIpWhiteListDual *p = cloneIpWhiteList(pUser->pIpWhiteListDual);
104,360✔
341
    if (p == NULL) {
104,360✔
342
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
343
    }
344
    taosMemoryFree(pInfo->wlIp);
104,360✔
345
    pInfo->wlIp = p;
104,360✔
346
    userCache.verIp++;
104,360✔
347
  }
348

349
  if (!isDateTimeWhiteListEqual(pInfo->wlTime, pUser->pTimeWhiteList)) {
1,035,145✔
350
    SDateTimeWhiteList *p = cloneDateTimeWhiteList(pUser->pTimeWhiteList);
103,995✔
351
    if (p == NULL) {
103,995✔
352
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
353
    }
354
    taosMemoryFree(pInfo->wlTime);
103,995✔
355
    pInfo->wlTime = p;
103,995✔
356
    userCache.verTime++;
103,995✔
357
  }
358

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

367

368

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

372
  SSdb     *pSdb = pMnode->pSdb;
621,523✔
373
  void     *pIter = NULL;
621,523✔
374
  while (1) {
263,212✔
375
    SUserObj *pUser = NULL;
884,735✔
376
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
884,735✔
377
    if (pIter == NULL) {
884,735✔
378
      break;
621,523✔
379
    }
380

381
    SCachedUserInfo *pInfo = getCachedUserInfo(pUser->user);
263,212✔
382
    if (pInfo == NULL) {
263,212✔
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);
263,212✔
389
    if (wl == NULL) {
263,212✔
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);
263,212✔
396
    pInfo->wlIp = wl;
263,212✔
397

398
    sdbRelease(pSdb, pUser);
263,212✔
399
  }
400

401
  userCache.verIp++;
621,523✔
402

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

410

411

412
int64_t mndGetIpWhiteListVersion(SMnode *pMnode) {
41,292,263✔
413
  int64_t ver = 0;
41,292,263✔
414
  int32_t code = 0;
41,292,263✔
415

416
  if (mndEnableIpWhiteList(pMnode) != 0 && tsEnableWhiteList) {
41,292,263✔
417
    (void)taosThreadRwlockWrlock(&userCache.rw);
13,676✔
418

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

430
    (void)taosThreadRwlockUnlock(&userCache.rw);
13,676✔
431
  }
432

433
  mDebug("ip-white-list on mnode ver: %" PRId64, ver);
41,292,263✔
434
  return ver;
41,292,263✔
435
}
436

437

438

439
int32_t mndRefreshUserIpWhiteList(SMnode *pMnode) {
621,523✔
440
  int32_t code = 0;
621,523✔
441
  (void)taosThreadRwlockWrlock(&userCache.rw);
621,523✔
442

443
  if ((code = userCacheRebuildIpWhiteList(pMnode)) != 0) {
621,523✔
444
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
445
    TAOS_RETURN(code);
×
446
  }
447
  userCache.verIp = taosGetTimestampMs();
621,523✔
448
  (void)taosThreadRwlockUnlock(&userCache.rw);
621,523✔
449

450
  TAOS_RETURN(code);
621,523✔
451
}
452

453

454

455
static int32_t userCacheRebuildTimeWhiteList(SMnode *pMnode) {
609,537✔
456
  int32_t   code = 0, lino = 0;
609,537✔
457

458
  SSdb     *pSdb = pMnode->pSdb;
609,537✔
459
  void     *pIter = NULL;
609,537✔
460
  while (1) {
251,226✔
461
    SUserObj *pUser = NULL;
860,763✔
462
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
860,763✔
463
    if (pIter == NULL) {
860,763✔
464
      break;
609,537✔
465
    }
466

467
    SCachedUserInfo *pInfo = getCachedUserInfo(pUser->user);
251,226✔
468
    if (pInfo == NULL) {
251,226✔
469
      sdbRelease(pSdb, pUser);
×
470
      sdbCancelFetch(pSdb, pIter);
×
471
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
472
    }
473

474
    SDateTimeWhiteList *wl = cloneDateTimeWhiteList(pUser->pTimeWhiteList);
251,226✔
475
    if (wl == NULL) {
251,226✔
476
      sdbRelease(pSdb, pUser);
×
477
      sdbCancelFetch(pSdb, pIter);
×
478
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
479
    }
480

481
    taosMemoryFree(pInfo->wlTime);
251,226✔
482
    pInfo->wlTime = wl;
251,226✔
483

484
    sdbRelease(pSdb, pUser);
251,226✔
485
  }
486

487
  userCache.verTime++;
609,537✔
488

489
_OVER:
609,537✔
490
  if (code < 0) {
609,537✔
491
    mError("failed to rebuild time white list at line %d since %s", lino, tstrerror(code));
×
492
  }
493
  TAOS_RETURN(code);
609,537✔
494
}
495

496

497

498
int32_t mndRefreshUserDateTimeWhiteList(SMnode *pMnode) {
609,537✔
499
  int32_t code = 0;
609,537✔
500
  (void)taosThreadRwlockWrlock(&userCache.rw);
609,537✔
501

502
  if ((code = userCacheRebuildTimeWhiteList(pMnode)) != 0) {
609,537✔
503
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
504
    TAOS_RETURN(code);
×
505
  }
506
  userCache.verTime = taosGetTimestampMs();
609,537✔
507
  (void)taosThreadRwlockUnlock(&userCache.rw);
609,537✔
508

509
  TAOS_RETURN(code);
609,537✔
510
}
511

512

513

514
int64_t mndGetTimeWhiteListVersion(SMnode *pMnode) {
41,292,263✔
515
  int64_t ver = 0;
41,292,263✔
516
  int32_t code = 0;
41,292,263✔
517

518
  if (mndEnableTimeWhiteList(pMnode) != 0 && tsEnableWhiteList) {
41,292,263✔
519
    (void)taosThreadRwlockWrlock(&userCache.rw);
13,676✔
520

521
    if (userCache.verIp == 0) {
13,676✔
522
      // get user and dnode datetime white list
523
      if ((code = userCacheRebuildTimeWhiteList(pMnode)) != 0) {
×
524
        (void)taosThreadRwlockUnlock(&userCache.rw);
×
525
        mError("%s failed to update datetime white list since %s", __func__, tstrerror(code));
×
526
        return ver;
×
527
      }
528
      userCache.verTime = taosGetTimestampMs();
×
529
    }
530
    ver = userCache.verTime;
13,676✔
531

532
    (void)taosThreadRwlockUnlock(&userCache.rw);
13,676✔
533
  }
534

535
  mDebug("datetime-white-list on mnode ver: %" PRId64, ver);
41,292,263✔
536
  return ver;
41,292,263✔
537
}
538

539

540

541
int32_t mndInitUser(SMnode *pMnode) {
516,782✔
542
  TAOS_CHECK_RETURN(userCacheInit());
516,782✔
543

544
  SSdbTable table = {
516,782✔
545
      .sdbType = SDB_USER,
546
      .keyType = SDB_KEY_BINARY,
547
      .deployFp = (SdbDeployFp)mndCreateDefaultUsers,
548
      .encodeFp = (SdbEncodeFp)mndUserActionEncode,
549
      .decodeFp = (SdbDecodeFp)mndUserActionDecode,
550
      .insertFp = (SdbInsertFp)mndUserActionInsert,
551
      .updateFp = (SdbUpdateFp)mndUserActionUpdate,
552
      .deleteFp = (SdbDeleteFp)mndUserActionDelete,
553
  };
554

555
  mndSetMsgHandle(pMnode, TDMT_MND_CREATE_USER, mndProcessCreateUserReq);
516,782✔
556
  mndSetMsgHandle(pMnode, TDMT_MND_ALTER_USER, mndProcessAlterUserReq);
516,782✔
557
  mndSetMsgHandle(pMnode, TDMT_MND_DROP_USER, mndProcessDropUserReq);
516,782✔
558
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_AUTH, mndProcessGetUserAuthReq);
516,782✔
559

560
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_IP_WHITELIST, mndProcessGetUserIpWhiteListReq);
516,782✔
561
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_IP_WHITELIST_DUAL, mndProcessGetUserIpWhiteListReq);
516,782✔
562
  mndSetMsgHandle(pMnode, TDMT_MND_RETRIEVE_IP_WHITELIST, mndProcessRetrieveIpWhiteListReq);
516,782✔
563
  mndSetMsgHandle(pMnode, TDMT_MND_RETRIEVE_IP_WHITELIST_DUAL, mndProcessRetrieveIpWhiteListReq);
516,782✔
564
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_DATETIME_WHITELIST, mndProcessGetUserDateTimeWhiteListReq);
516,782✔
565
  mndSetMsgHandle(pMnode, TDMT_MND_RETRIEVE_DATETIME_WHITELIST, mndProcessRetrieveDateTimeWhiteListReq);
516,782✔
566

567
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_USER, mndRetrieveUsers);
516,782✔
568
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_USER, mndCancelGetNextUser);
516,782✔
569
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_USER_FULL, mndRetrieveUsersFull);
516,782✔
570
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_USER_FULL, mndCancelGetNextUser);
516,782✔
571
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_PRIVILEGES, mndRetrievePrivileges);
516,782✔
572
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_PRIVILEGES, mndCancelGetNextPrivileges);
516,782✔
573
  return sdbSetTable(pMnode->pSdb, table);
516,782✔
574
}
575

576

577

578
void mndCleanupUser(SMnode *pMnode) {
516,665✔
579
  userCacheCleanup();
516,665✔
580
}
516,665✔
581

582

583

584
static bool isDefaultRange(SIpRange *pRange) {
×
585
  int32_t code = 0;
×
586
  int32_t lino = 0;
×
587

588
  SIpRange range4 = {0};
×
589
  SIpRange range6 = {0};
×
590

591
  code = createDefaultIp4Range(&range4);
×
592
  TSDB_CHECK_CODE(code, lino, _error);
×
593

594
  code = createDefaultIp6Range(&range6);
×
595
  TSDB_CHECK_CODE(code, lino, _error);
×
596

597
  if (isIpRangeEqual(pRange, &range4) || (isIpRangeEqual(pRange, &range6))) {
×
598
    return true;
×
599
  }
600
_error:
×
601
  return false;
×
602
};
603

604

605

606
static int32_t ipRangeListToStr(SIpRange *range, int32_t num, char *buf, int64_t bufLen) {
54,189✔
607
  int32_t len = 0;
54,189✔
608
  for (int i = 0; i < num; i++) {
164,027✔
609
    SIpRange *pRange = &range[i];
109,838✔
610
    SIpAddr   addr = {0};
109,838✔
611
    int32_t code = tIpUintToStr(pRange, &addr);
109,838✔
612
    if (code != 0) {
109,838✔
613
      mError("%s failed to convert ip range to str, code: %d", __func__, code);
×
614
    }
615

616
    len += tsnprintf(buf + len, bufLen - len, "%c%s/%d, ", pRange->neg ? '-' : '+', IP_ADDR_STR(&addr), addr.mask);
109,838✔
617
  }
618
  if (len > 0) buf[len - 2] = 0;
54,189✔
619
  return len;
54,189✔
620
}
621

622

623

624
static bool isIpRangeEqual(SIpRange *a, SIpRange *b) {
1,861,570✔
625
  if (a->type != b->type || a->neg != b->neg) {
1,861,570✔
626
    return false;
×
627
  }
628

629
  if (a->type == 0) {
1,861,570✔
630
    SIpV4Range *a4 = &a->ipV4;
931,150✔
631
    SIpV4Range *b4 = &b->ipV4;
931,150✔
632
    return (a4->ip == b4->ip && a4->mask == b4->mask);
931,150✔
633
  }
634
  
635
  SIpV6Range *a6 = &a->ipV6;
930,420✔
636
  SIpV6Range *b6 = &b->ipV6;
930,420✔
637
  return (a6->addr[0] == b6->addr[0] && a6->addr[1] == b6->addr[1] && a6->mask == b6->mask);
930,420✔
638
}
639

640

641

642
static bool isIpWhiteListEqual(SIpWhiteListDual *a, SIpWhiteListDual *b) {
1,035,145✔
643
  if (a == NULL && b == NULL) {
1,035,145✔
644
    return true;
×
645
  }
646
  
647
  if (a == NULL || b == NULL) {
1,035,145✔
648
    return false;
103,995✔
649
  }
650

651
  if (a->num != b->num) {
931,150✔
652
    return false;
365✔
653
  }
654
  for (int i = 0; i < a->num; i++) {
2,792,355✔
655
    if (!isIpRangeEqual(&a->pIpRanges[i], &b->pIpRanges[i])) {
1,861,570✔
656
      return false;
×
657
    }
658
  }
659
  return true;
930,785✔
660
}
661

662

663
static int32_t compareIpRange(const void *a, const void *b, const void* arg) {
4,015✔
664
  SIpRange *ra = (SIpRange *)a;
4,015✔
665
  SIpRange *rb = (SIpRange *)b;
4,015✔
666

667
  if (ra->neg != rb->neg) {
4,015✔
668
    return (ra->neg) ? -1 : 1;
×
669
  }
670

671
  if (ra->type != rb->type) {
4,015✔
672
    return (ra->type == 0) ? -1 : 1;
×
673
  }
674

675
  if (ra->type == 0) {
4,015✔
676
    if (ra->ipV4.ip != rb->ipV4.ip) {
4,015✔
677
      return (ra->ipV4.ip < rb->ipV4.ip) ? -1 : 1;
3,285✔
678
    }
679
    return (ra->ipV4.mask < rb->ipV4.mask) ? -1 : 1;
730✔
680
  }
681

682
  if (ra->ipV6.addr[0] != rb->ipV6.addr[0]) {
×
683
    return (ra->ipV6.addr[0] < rb->ipV6.addr[0]) ? -1 : 1;
×
684
  }
685
  if (ra->ipV6.addr[1] != rb->ipV6.addr[1]) {
×
686
    return (ra->ipV6.addr[1] < rb->ipV6.addr[1]) ? -1 : 1;
×
687
  }
688
  return (ra->ipV6.mask < rb->ipV6.mask) ? -1 : 1;
×
689
}
690

691
static void sortIpWhiteList(SIpWhiteListDual *pList) {
1,825✔
692
  (void)taosqsort(pList->pIpRanges, pList->num, sizeof(SIpRange), NULL, compareIpRange);
1,825✔
693
}
1,825✔
694

695

696

697
static int32_t convertIpWhiteListToStr(SUserObj *pUser, char **buf) {
54,189✔
698
  SIpWhiteListDual *pList = pUser->pIpWhiteListDual;
54,189✔
699

700
  int64_t bufLen = pList->num * 128 + 8;
54,189✔
701
  *buf = taosMemoryCalloc(1, bufLen);
54,189✔
702
  if (*buf == NULL) {
54,189✔
703
    return 0;
×
704
  }
705

706
  if (pList->num == 0) {
54,189✔
707
    return tsnprintf(*buf, bufLen, "+ALL");
×
708
  }
709

710
  int32_t len = ipRangeListToStr(pList->pIpRanges, pList->num, *buf, bufLen - 2);
54,189✔
711
  if (len == 0) {
54,189✔
712
    taosMemoryFreeClear(*buf);
×
713
    return 0;
×
714
  }
715
  return len;
54,189✔
716
}
717

718

719

720
static int32_t tSerializeIpWhiteList(void *buf, int32_t len, SIpWhiteListDual *pList, uint32_t *pLen) {
2,569,662✔
721
  int32_t  code = 0;
2,569,662✔
722
  int32_t  lino = 0;
2,569,662✔
723
  int32_t  tlen = 0;
2,569,662✔
724
  SEncoder encoder = {0};
2,569,662✔
725
  tEncoderInit(&encoder, buf, len);
2,569,662✔
726

727
  TAOS_CHECK_GOTO(tStartEncode(&encoder), &lino, _OVER);
2,569,662✔
728
  TAOS_CHECK_GOTO(tEncodeI32(&encoder, pList->num), &lino, _OVER);
5,139,324✔
729

730
  for (int i = 0; i < pList->num; i++) {
7,710,081✔
731
    SIpRange *pRange = &(pList->pIpRanges[i]);
5,140,419✔
732
    TAOS_CHECK_GOTO(tSerializeIpRange(&encoder, pRange), &lino, _OVER);
5,140,419✔
733
  }
734

735
  tEndEncode(&encoder);
2,569,662✔
736

737
  tlen = encoder.pos;
2,569,662✔
738
_OVER:
2,569,662✔
739
  tEncoderClear(&encoder);
2,569,662✔
740
  if (code < 0) {
2,569,662✔
741
    mError("failed to serialize ip white list at line %d since %s", lino, tstrerror(code));
×
742
  }
743
  if (pLen) *pLen = tlen;
2,569,662✔
744
  TAOS_RETURN(code);
2,569,662✔
745
}
746

747
static int32_t tDerializeIpWhiteList(void *buf, int32_t len, SIpWhiteListDual *pList, bool supportNeg) {
1,674,391✔
748
  int32_t  code = 0;
1,674,391✔
749
  int32_t  lino = 0;
1,674,391✔
750
  SDecoder decoder = {0};
1,674,391✔
751
  tDecoderInit(&decoder, buf, len);
1,674,391✔
752

753
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
1,674,391✔
754
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &pList->num), &lino, _OVER);
3,348,782✔
755

756
  for (int i = 0; i < pList->num; i++) {
5,023,903✔
757
    SIpRange *pRange = &(pList->pIpRanges[i]);
3,349,512✔
758
    TAOS_CHECK_GOTO(tDeserializeIpRange(&decoder, pRange, supportNeg), &lino, _OVER);
3,349,512✔
759
  }
760

761
_OVER:
1,674,391✔
762
  tEndDecode(&decoder);
1,674,391✔
763
  tDecoderClear(&decoder);
1,674,391✔
764
  if (code < 0) {
1,674,391✔
765
    mError("failed to deserialize ip white list at line %d since %s", lino, tstrerror(code));
×
766
  }
767
  TAOS_RETURN(code);
1,674,391✔
768
}
769

770
static int32_t tDerializeIpWhileListFromOldVer(void *buf, int32_t len, SIpWhiteList *pList) {
×
771
  int32_t  code = 0;
×
772
  int32_t  lino = 0;
×
773
  SDecoder decoder = {0};
×
774
  tDecoderInit(&decoder, buf, len);
×
775

776
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
×
777
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &pList->num), &lino, _OVER);
×
778

779
  for (int i = 0; i < pList->num; i++) {
×
780
    SIpV4Range *pIp4 = &(pList->pIpRange[i]);
×
781
    TAOS_CHECK_GOTO(tDecodeU32(&decoder, &pIp4->ip), &lino, _OVER);
×
782
    TAOS_CHECK_GOTO(tDecodeU32(&decoder, &pIp4->mask), &lino, _OVER);
×
783
  }
784

785
_OVER:
×
786
  tEndDecode(&decoder);
×
787
  tDecoderClear(&decoder);
×
788
  if (code < 0) {
×
789
    mError("failed to deserialize ip white list at line %d since %s", lino, tstrerror(code));
×
790
  }
791
  TAOS_RETURN(code);
×
792
}
793

794
static int32_t createIpWhiteList(void *buf, int32_t len, SIpWhiteListDual **ppList, bool supportNeg) {
1,674,391✔
795
  int32_t           code = 0;
1,674,391✔
796
  int32_t           lino = 0;
1,674,391✔
797
  int32_t           num = 0;
1,674,391✔
798
  SIpWhiteListDual *p = NULL;
1,674,391✔
799
  SDecoder          decoder = {0};
1,674,391✔
800
  tDecoderInit(&decoder, buf, len);
1,674,391✔
801

802
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
1,674,391✔
803
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &num), &lino, _OVER);
1,674,391✔
804

805
  p = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + num * sizeof(SIpRange));
1,674,391✔
806
  if (p == NULL) {
1,674,391✔
807
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
808
  }
809
  TAOS_CHECK_GOTO(tDerializeIpWhiteList(buf, len, p, supportNeg), &lino, _OVER);
1,674,391✔
810

811
_OVER:
1,674,391✔
812
  tEndDecode(&decoder);
1,674,391✔
813
  tDecoderClear(&decoder);
1,674,391✔
814
  if (code < 0) {
1,674,391✔
815
    taosMemoryFreeClear(p);
×
816
    mError("failed to create ip white list at line %d since %s", lino, tstrerror(code));
×
817
  }
818
  *ppList = p;
1,674,391✔
819
  TAOS_RETURN(code);
1,674,391✔
820
}
821

822
static int32_t createIpWhiteListFromOldVer(void *buf, int32_t len, SIpWhiteList **ppList) {
×
823
  int32_t       code = 0;
×
824
  int32_t       lino = 0;
×
825
  int32_t       num = 0;
×
826
  SIpWhiteList *p = NULL;
×
827
  SDecoder      decoder = {0};
×
828
  tDecoderInit(&decoder, buf, len);
×
829

830
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
×
831
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &num), &lino, _OVER);
×
832

833
  p = taosMemoryCalloc(1, sizeof(SIpWhiteList) + num * sizeof(SIpV4Range));
×
834
  if (p == NULL) {
×
835
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
836
  }
837
  TAOS_CHECK_GOTO(tDerializeIpWhileListFromOldVer(buf, len, p), &lino, _OVER);
×
838

839
_OVER:
×
840
  tEndDecode(&decoder);
×
841
  tDecoderClear(&decoder);
×
842
  if (code < 0) {
×
843
    taosMemoryFreeClear(p);
×
844
    mError("failed to create ip white list at line %d since %s", lino, tstrerror(code));
×
845
  }
846
  *ppList = p;
×
847
  TAOS_RETURN(code);
×
848
}
849

850
static int32_t createDefaultIpWhiteList(SIpWhiteListDual **ppWhiteList) {
436,972✔
851
  int32_t code = 0;
436,972✔
852
  int32_t lino = 0;
436,972✔
853
  *ppWhiteList = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + sizeof(SIpRange) * 2);
436,972✔
854
  if (*ppWhiteList == NULL) {
436,972✔
855
    TAOS_RETURN(terrno);
×
856
  }
857
  (*ppWhiteList)->num = 2;
436,972✔
858

859
  SIpRange v4 = {0};
436,972✔
860
  SIpRange v6 = {0};
436,972✔
861

862
#ifndef TD_ASTRA
863
  code = createDefaultIp4Range(&v4);
436,972✔
864
  TSDB_CHECK_CODE(code, lino, _error);
436,972✔
865

866
  code = createDefaultIp6Range(&v6);
436,972✔
867
  TSDB_CHECK_CODE(code, lino, _error);
436,972✔
868

869
#endif
870

871
_error:
436,972✔
872
  if (code != 0) {
436,972✔
873
    taosMemoryFree(*ppWhiteList);
×
874
    *ppWhiteList = NULL;
×
875
    mError("failed to create default ip white list at line %d since %s", __LINE__, tstrerror(code));
×
876
  } else {
877
    memcpy(&(*ppWhiteList)->pIpRanges[0], &v4, sizeof(SIpRange));
436,972✔
878
    memcpy(&(*ppWhiteList)->pIpRanges[1], &v6, sizeof(SIpRange));
436,972✔
879
  }
880
  return 0;
436,972✔
881
}
882

883

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

886
static int32_t convertTimeRangesToStr(SUserObj *pUser, char **buf) {
54,189✔
887
  int32_t bufLen = pUser->pTimeWhiteList->num * 32 + 8;
54,189✔
888
  *buf = taosMemoryCalloc(1, bufLen);
54,189✔
889
  if (*buf == NULL) {
54,189✔
890
    return 0;
×
891
  }
892

893
  int32_t pos = 0;
54,189✔
894
  if (pUser->pTimeWhiteList->num == 0) {
54,189✔
895
    pos += tsnprintf(*buf + pos, bufLen - pos, "+ALL");
54,189✔
896
    return pos;
54,189✔
897
  }
898

899
  for (int32_t i = 0; i < pUser->pTimeWhiteList->num; i++) {
×
900
    SDateTimeWhiteListItem *range = &pUser->pTimeWhiteList->ranges[i];
×
901
    int duration = range->duration / 60;
×
902

903
    if (range->absolute) {
×
904
      struct STm tm;
×
905
      (void)taosTs2Tm(range->start, TSDB_TIME_PRECISION_SECONDS, &tm, NULL);
×
906
      pos += tsnprintf(*buf + pos, bufLen - pos, "%c%04d-%02d-%02d %02d:%02d %dm, ", range->neg ? '-' : '+', tm.tm.tm_year + 1900, tm.tm.tm_mon + 1, tm.tm.tm_mday, tm.tm.tm_hour, tm.tm.tm_min, duration);
×
907
    } else {
908
      int day = range->start / 86400;
×
909
      int hour = (range->start % 86400) / 3600;
×
910
      int minute = (range->start % 3600) / 60;
×
911
      pos += tsnprintf(*buf + pos, bufLen - pos, "%c%s %02d:%02d %dm, ", range->neg ? '-' : '+', weekdays[day], hour, minute, duration);
×
912
    }
913
  }
914

915
  if (pos > 0) {
×
916
    (*buf)[pos - 2] = 0; // remove last ", "
×
917
  }
918

919
  return pos;
×
920
}
921

922

923
static int32_t compareDateTimeInterval(const void *a, const void *b, const void* arg) {
×
924
  SDateTimeWhiteListItem *pA = (SDateTimeWhiteListItem *)a;
×
925
  SDateTimeWhiteListItem *pB = (SDateTimeWhiteListItem *)b;
×
926

927
  if (pA->neg != pB->neg) {
×
928
    return pA->neg ? -1 : 1;
×
929
  }
930

931
  if (pA->absolute != pB->absolute) {
×
932
    return pA->absolute ? 1 : -1;
×
933
  }
934

935
  if (pA->start != pB->start) {
×
936
    return (pA->start < pB->start) ? -1 : 1;
×
937
  }
938

939
  if (pA->duration != pB->duration) {
×
940
    return (pA->duration < pB->duration) ? -1 : 1;
×
941
  }
942

943
  return 0;
×
944
}
945

946
static void sortTimeWhiteList(SDateTimeWhiteList *pList) {
×
947
  (void)taosqsort(pList->ranges, pList->num, sizeof(SDateTimeWhiteListItem), NULL, compareDateTimeInterval);
×
948
}
×
949

950

951

952

953
static void dropOldPasswords(SUserObj *pUser) {
4,244,053✔
954
  if (pUser->numOfPasswords <= pUser->passwordReuseMax) {
4,244,053✔
955
    return;
4,191,802✔
956
  }
957

958
  int32_t reuseMax = pUser->passwordReuseMax;
52,251✔
959
  if (reuseMax == 0) {
52,251✔
960
    reuseMax = 1; // keep at least one password
48,601✔
961
  }
962

963
  int32_t now = taosGetTimestampSec();
52,251✔
964
  int32_t index = reuseMax;
52,251✔
965
  while(index < pUser->numOfPasswords) {
62,471✔
966
    SUserPassword *pPass = &pUser->passwords[index];
10,220✔
967
    if (now - pPass->setTime >= pUser->passwordReuseTime) {
10,220✔
968
      break;
×
969
    }
970
    index++;
10,220✔
971
  }
972

973
  if (index == pUser->numOfPasswords) {
52,251✔
974
    return;
52,251✔
975
  }
976
  pUser->numOfPasswords = index;
×
977
  // this is a shrink operation, no need to check return value
978
  pUser->passwords = taosMemoryRealloc(pUser->passwords, sizeof(SUserPassword) * pUser->numOfPasswords);
×
979
}
980

981

982

983

984
static int32_t mndCreateDefaultUser(SMnode *pMnode, char *acct, char *user, char *pass) {
334,438✔
985
  int32_t  code = 0;
334,438✔
986
  int32_t  lino = 0;
334,438✔
987
  SUserObj userObj = {0};
334,438✔
988

989
  userObj.passwords = taosMemCalloc(1, sizeof(SUserPassword));
334,438✔
990
  if (userObj.passwords == NULL) {
334,438✔
991
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _ERROR);
×
992
  }
993
  taosEncryptPass_c((uint8_t *)pass, strlen(pass), userObj.passwords[0].pass);
334,438✔
994
  userObj.passwords[0].pass[sizeof(userObj.passwords[0].pass) - 1] = 0;
334,438✔
995
  if (tsiEncryptPassAlgorithm == DND_CA_SM4 && strlen(tsEncryptKey) > 0) {
334,438✔
996
    generateSalt(userObj.salt, sizeof(userObj.salt));
×
997
    TAOS_CHECK_GOTO(mndEncryptPass(userObj.passwords[0].pass, userObj.salt, &userObj.passEncryptAlgorithm), &lino, _ERROR);
×
998
  }
999

1000
  userObj.passwords[0].setTime = taosGetTimestampSec();
334,438✔
1001
  userObj.numOfPasswords = 1;
334,438✔
1002

1003
  tstrncpy(userObj.user, user, TSDB_USER_LEN);
334,438✔
1004
  tstrncpy(userObj.acct, acct, TSDB_USER_LEN);
334,438✔
1005
  userObj.createdTime = taosGetTimestampMs();
334,438✔
1006
  userObj.updateTime = userObj.createdTime;
334,438✔
1007
  userObj.sysInfo = 1;
334,438✔
1008
  userObj.enable = 1;
334,438✔
1009
  userObj.changePass = 2;
334,438✔
1010
  userObj.ipWhiteListVer = taosGetTimestampMs();
334,438✔
1011
  userObj.connectTime = TSDB_USER_CONNECT_TIME_DEFAULT;
334,438✔
1012
  userObj.connectIdleTime = TSDB_USER_CONNECT_IDLE_TIME_DEFAULT;
334,438✔
1013
  userObj.callPerSession = TSDB_USER_CALL_PER_SESSION_DEFAULT;
334,438✔
1014
  userObj.vnodePerCall = TSDB_USER_VNODE_PER_CALL_DEFAULT;
334,438✔
1015
  userObj.passwordReuseTime = TSDB_USER_PASSWORD_REUSE_TIME_DEFAULT;
334,438✔
1016
  userObj.passwordReuseMax = TSDB_USER_PASSWORD_REUSE_MAX_DEFAULT;
334,438✔
1017
  userObj.passwordLockTime = TSDB_USER_PASSWORD_LOCK_TIME_DEFAULT;
334,438✔
1018
  // this is the root user, set some fields to -1 to allow the user login without restriction
1019
  userObj.sessionPerUser = -1;
334,438✔
1020
  userObj.failedLoginAttempts = -1;
334,438✔
1021
  userObj.passwordLifeTime = -1;
334,438✔
1022
  userObj.passwordGraceTime = -1;
334,438✔
1023
  userObj.inactiveAccountTime = -1;
334,438✔
1024
  userObj.allowTokenNum = TSDB_USER_ALLOW_TOKEN_NUM_DEFAULT;
334,438✔
1025
  userObj.pTimeWhiteList = taosMemoryCalloc(1, sizeof(SDateTimeWhiteList));
334,438✔
1026
  if (userObj.pTimeWhiteList == NULL) {
334,438✔
1027
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _ERROR);
×
1028
  }
1029
  
1030
  TAOS_CHECK_GOTO(createDefaultIpWhiteList(&userObj.pIpWhiteListDual), &lino, _ERROR);
334,438✔
1031
  if (strcmp(user, TSDB_DEFAULT_USER) == 0) {
334,438✔
1032
    userObj.superUser = 1;
334,438✔
1033
    userObj.createdb = 1;
334,438✔
1034
    userObj.sessionPerUser = -1;
334,438✔
1035
    userObj.callPerSession = -1;
334,438✔
1036
    userObj.vnodePerCall = -1;
334,438✔
1037
    userObj.failedLoginAttempts = -1;
334,438✔
1038
    userObj.passwordLifeTime = -1;
334,438✔
1039
    userObj.passwordLockTime = -1;
334,438✔
1040
    userObj.inactiveAccountTime = -1;
334,438✔
1041
    userObj.allowTokenNum = -1;
334,438✔
1042
  }
1043

1044
  SSdbRaw *pRaw = mndUserActionEncode(&userObj);
334,438✔
1045
  if (pRaw == NULL) goto _ERROR;
334,438✔
1046
  TAOS_CHECK_GOTO(sdbSetRawStatus(pRaw, SDB_STATUS_READY), &lino, _ERROR);
334,438✔
1047

1048
  mInfo("user:%s, will be created when deploying, raw:%p", userObj.user, pRaw);
334,438✔
1049

1050
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, NULL, "create-user");
334,438✔
1051
  if (pTrans == NULL) {
334,438✔
1052
    sdbFreeRaw(pRaw);
×
1053
    mError("user:%s, failed to create since %s", userObj.user, terrstr());
×
1054
    goto _ERROR;
×
1055
  }
1056
  mInfo("trans:%d, used to create user:%s", pTrans->id, userObj.user);
334,438✔
1057

1058
  if (mndTransAppendCommitlog(pTrans, pRaw) != 0) {
334,438✔
1059
    mError("trans:%d, failed to commit redo log since %s", pTrans->id, terrstr());
×
1060
    mndTransDrop(pTrans);
×
1061
    goto _ERROR;
×
1062
  }
1063
  TAOS_CHECK_GOTO(sdbSetRawStatus(pRaw, SDB_STATUS_READY), &lino, _ERROR);
334,438✔
1064

1065
  if (mndTransPrepare(pMnode, pTrans) != 0) {
334,438✔
1066
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
1067
    mndTransDrop(pTrans);
×
1068
    goto _ERROR;
×
1069
  }
1070

1071
  mndTransDrop(pTrans);
334,438✔
1072
  taosMemoryFree(userObj.passwords);
334,438✔
1073
  taosMemoryFree(userObj.pIpWhiteListDual);
334,438✔
1074
  taosMemoryFree(userObj.pTimeWhiteList);
334,438✔
1075
  return 0;
334,438✔
1076

1077
_ERROR:
×
1078
  taosMemoryFree(userObj.passwords);
×
1079
  taosMemoryFree(userObj.pIpWhiteListDual);
×
1080
  taosMemoryFree(userObj.pTimeWhiteList);
×
1081
  TAOS_RETURN(terrno ? terrno : TSDB_CODE_APP_ERROR);
×
1082
}
1083

1084
static int32_t mndCreateDefaultUsers(SMnode *pMnode) {
334,438✔
1085
  return mndCreateDefaultUser(pMnode, TSDB_DEFAULT_USER, TSDB_DEFAULT_USER, TSDB_DEFAULT_PASS);
334,438✔
1086
}
1087

1088
SSdbRaw *mndUserActionEncode(SUserObj *pUser) {
2,569,662✔
1089
  int32_t code = 0;
2,569,662✔
1090
  int32_t lino = 0;
2,569,662✔
1091
  int32_t passReserve = (sizeof(SUserPassword) + 8) * pUser->numOfPasswords + 4;
2,569,662✔
1092
  int32_t ipWhiteReserve = pUser->pIpWhiteListDual ? (sizeof(SIpRange) * pUser->pIpWhiteListDual->num + sizeof(SIpWhiteListDual) + 4) : 16;
2,569,662✔
1093
  int32_t timeWhiteReserve = pUser->pTimeWhiteList ? (sizeof(SDateTimeWhiteListItem) * pUser->pTimeWhiteList->num + sizeof(SDateTimeWhiteList) + 4) : 16;
2,569,662✔
1094
  int32_t numOfReadDbs = taosHashGetSize(pUser->readDbs);
2,569,662✔
1095
  int32_t numOfWriteDbs = taosHashGetSize(pUser->writeDbs);
2,569,662✔
1096
  int32_t numOfReadTbs = taosHashGetSize(pUser->readTbs);
2,569,662✔
1097
  int32_t numOfWriteTbs = taosHashGetSize(pUser->writeTbs);
2,569,662✔
1098
  int32_t numOfAlterTbs = taosHashGetSize(pUser->alterTbs);
2,569,662✔
1099
  int32_t numOfReadViews = taosHashGetSize(pUser->readViews);
2,569,662✔
1100
  int32_t numOfWriteViews = taosHashGetSize(pUser->writeViews);
2,569,662✔
1101
  int32_t numOfAlterViews = taosHashGetSize(pUser->alterViews);
2,569,662✔
1102
  int32_t numOfTopics = taosHashGetSize(pUser->topics);
2,569,662✔
1103
  int32_t numOfUseDbs = taosHashGetSize(pUser->useDbs);
2,569,662✔
1104
  int32_t size = sizeof(SUserObj) + USER_RESERVE_SIZE + (numOfReadDbs + numOfWriteDbs) * TSDB_DB_FNAME_LEN +
2,569,662✔
1105
                 numOfTopics * TSDB_TOPIC_FNAME_LEN + ipWhiteReserve + timeWhiteReserve + passReserve;
2,569,662✔
1106
  char    *buf = NULL;
2,569,662✔
1107
  SSdbRaw *pRaw = NULL;
2,569,662✔
1108

1109
  char *stb = taosHashIterate(pUser->readTbs, NULL);
2,569,662✔
1110
  while (stb != NULL) {
3,019,630✔
1111
    size_t keyLen = 0;
449,968✔
1112
    void  *key = taosHashGetKey(stb, &keyLen);
449,968✔
1113
    size += sizeof(int32_t);
449,968✔
1114
    size += keyLen;
449,968✔
1115

1116
    size_t valueLen = 0;
449,968✔
1117
    valueLen = strlen(stb) + 1;
449,968✔
1118
    size += sizeof(int32_t);
449,968✔
1119
    size += valueLen;
449,968✔
1120
    stb = taosHashIterate(pUser->readTbs, stb);
449,968✔
1121
  }
1122

1123
  stb = taosHashIterate(pUser->writeTbs, NULL);
2,569,662✔
1124
  while (stb != NULL) {
3,031,461✔
1125
    size_t keyLen = 0;
461,799✔
1126
    void  *key = taosHashGetKey(stb, &keyLen);
461,799✔
1127
    size += sizeof(int32_t);
461,799✔
1128
    size += keyLen;
461,799✔
1129

1130
    size_t valueLen = 0;
461,799✔
1131
    valueLen = strlen(stb) + 1;
461,799✔
1132
    size += sizeof(int32_t);
461,799✔
1133
    size += valueLen;
461,799✔
1134
    stb = taosHashIterate(pUser->writeTbs, stb);
461,799✔
1135
  }
1136

1137
  stb = taosHashIterate(pUser->alterTbs, NULL);
2,569,662✔
1138
  while (stb != NULL) {
2,807,277✔
1139
    size_t keyLen = 0;
237,615✔
1140
    void  *key = taosHashGetKey(stb, &keyLen);
237,615✔
1141
    size += sizeof(int32_t);
237,615✔
1142
    size += keyLen;
237,615✔
1143

1144
    size_t valueLen = 0;
237,615✔
1145
    valueLen = strlen(stb) + 1;
237,615✔
1146
    size += sizeof(int32_t);
237,615✔
1147
    size += valueLen;
237,615✔
1148
    stb = taosHashIterate(pUser->alterTbs, stb);
237,615✔
1149
  }
1150

1151
  stb = taosHashIterate(pUser->readViews, NULL);
2,569,662✔
1152
  while (stb != NULL) {
2,619,522✔
1153
    size_t keyLen = 0;
49,860✔
1154
    void  *key = taosHashGetKey(stb, &keyLen);
49,860✔
1155
    size += sizeof(int32_t);
49,860✔
1156
    size += keyLen;
49,860✔
1157

1158
    size_t valueLen = 0;
49,860✔
1159
    valueLen = strlen(stb) + 1;
49,860✔
1160
    size += sizeof(int32_t);
49,860✔
1161
    size += valueLen;
49,860✔
1162
    stb = taosHashIterate(pUser->readViews, stb);
49,860✔
1163
  }
1164

1165
  stb = taosHashIterate(pUser->writeViews, NULL);
2,569,662✔
1166
  while (stb != NULL) {
2,607,849✔
1167
    size_t keyLen = 0;
38,187✔
1168
    void  *key = taosHashGetKey(stb, &keyLen);
38,187✔
1169
    size += sizeof(int32_t);
38,187✔
1170
    size += keyLen;
38,187✔
1171

1172
    size_t valueLen = 0;
38,187✔
1173
    valueLen = strlen(stb) + 1;
38,187✔
1174
    size += sizeof(int32_t);
38,187✔
1175
    size += valueLen;
38,187✔
1176
    stb = taosHashIterate(pUser->writeViews, stb);
38,187✔
1177
  }
1178

1179
  stb = taosHashIterate(pUser->alterViews, NULL);
2,569,662✔
1180
  while (stb != NULL) {
2,607,282✔
1181
    size_t keyLen = 0;
37,620✔
1182
    void  *key = taosHashGetKey(stb, &keyLen);
37,620✔
1183
    size += sizeof(int32_t);
37,620✔
1184
    size += keyLen;
37,620✔
1185

1186
    size_t valueLen = 0;
37,620✔
1187
    valueLen = strlen(stb) + 1;
37,620✔
1188
    size += sizeof(int32_t);
37,620✔
1189
    size += valueLen;
37,620✔
1190
    stb = taosHashIterate(pUser->alterViews, stb);
37,620✔
1191
  }
1192

1193
  int32_t *useDb = taosHashIterate(pUser->useDbs, NULL);
2,569,662✔
1194
  while (useDb != NULL) {
3,144,931✔
1195
    size_t keyLen = 0;
575,269✔
1196
    void  *key = taosHashGetKey(useDb, &keyLen);
575,269✔
1197
    size += sizeof(int32_t);
575,269✔
1198
    size += keyLen;
575,269✔
1199
    size += sizeof(int32_t);
575,269✔
1200
    useDb = taosHashIterate(pUser->useDbs, useDb);
575,269✔
1201
  }
1202

1203
  pRaw = sdbAllocRaw(SDB_USER, USER_VER_NUMBER, size);
2,569,662✔
1204
  if (pRaw == NULL) {
2,569,662✔
1205
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1206
  }
1207

1208
  int32_t dataPos = 0;
2,569,662✔
1209
  SDB_SET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN, _OVER)
2,569,662✔
1210

1211
  dropOldPasswords(pUser);
2,569,662✔
1212
  SDB_SET_INT32(pRaw, dataPos, pUser->numOfPasswords, _OVER)
2,569,662✔
1213
  for (int32_t i = 0; i < pUser->numOfPasswords; i++) {
5,170,646✔
1214
    SDB_SET_BINARY(pRaw, dataPos, pUser->passwords[i].pass, sizeof(pUser->passwords[i].pass), _OVER)
2,600,984✔
1215
    SDB_SET_INT32(pRaw, dataPos, pUser->passwords[i].setTime, _OVER)
2,600,984✔
1216
  }
1217
  SDB_SET_BINARY(pRaw, dataPos, pUser->salt, sizeof(pUser->salt), _OVER)
2,569,662✔
1218

1219
  SDB_SET_BINARY(pRaw, dataPos, pUser->acct, TSDB_USER_LEN, _OVER)
2,569,662✔
1220
  SDB_SET_INT64(pRaw, dataPos, pUser->createdTime, _OVER)
2,569,662✔
1221
  SDB_SET_INT64(pRaw, dataPos, pUser->updateTime, _OVER)
2,569,662✔
1222
  SDB_SET_INT8(pRaw, dataPos, pUser->superUser, _OVER)
2,569,662✔
1223
  SDB_SET_INT8(pRaw, dataPos, pUser->sysInfo, _OVER)
2,569,662✔
1224
  SDB_SET_INT8(pRaw, dataPos, pUser->enable, _OVER)
2,569,662✔
1225
  SDB_SET_UINT8(pRaw, dataPos, pUser->flag, _OVER)
2,569,662✔
1226
  SDB_SET_INT32(pRaw, dataPos, pUser->authVersion, _OVER)
2,569,662✔
1227
  SDB_SET_INT32(pRaw, dataPos, pUser->passVersion, _OVER)
2,569,662✔
1228
  SDB_SET_INT32(pRaw, dataPos, numOfReadDbs, _OVER)
2,569,662✔
1229
  SDB_SET_INT32(pRaw, dataPos, numOfWriteDbs, _OVER)
2,569,662✔
1230
  SDB_SET_INT32(pRaw, dataPos, numOfTopics, _OVER)
2,569,662✔
1231

1232
  char *db = taosHashIterate(pUser->readDbs, NULL);
2,569,662✔
1233
  while (db != NULL) {
2,908,675✔
1234
    SDB_SET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER);
339,013✔
1235
    db = taosHashIterate(pUser->readDbs, db);
339,013✔
1236
  }
1237

1238
  db = taosHashIterate(pUser->writeDbs, NULL);
2,569,662✔
1239
  while (db != NULL) {
2,899,880✔
1240
    SDB_SET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER);
330,218✔
1241
    db = taosHashIterate(pUser->writeDbs, db);
330,218✔
1242
  }
1243

1244
  char *topic = taosHashIterate(pUser->topics, NULL);
2,569,662✔
1245
  while (topic != NULL) {
2,586,943✔
1246
    SDB_SET_BINARY(pRaw, dataPos, topic, TSDB_TOPIC_FNAME_LEN, _OVER);
17,281✔
1247
    topic = taosHashIterate(pUser->topics, topic);
17,281✔
1248
  }
1249

1250
  SDB_SET_INT32(pRaw, dataPos, numOfReadTbs, _OVER)
2,569,662✔
1251
  SDB_SET_INT32(pRaw, dataPos, numOfWriteTbs, _OVER)
2,569,662✔
1252
  SDB_SET_INT32(pRaw, dataPos, numOfAlterTbs, _OVER)
2,569,662✔
1253
  SDB_SET_INT32(pRaw, dataPos, numOfReadViews, _OVER)
2,569,662✔
1254
  SDB_SET_INT32(pRaw, dataPos, numOfWriteViews, _OVER)
2,569,662✔
1255
  SDB_SET_INT32(pRaw, dataPos, numOfAlterViews, _OVER)
2,569,662✔
1256
  SDB_SET_INT32(pRaw, dataPos, numOfUseDbs, _OVER)
2,569,662✔
1257

1258
  stb = taosHashIterate(pUser->readTbs, NULL);
2,569,662✔
1259
  while (stb != NULL) {
3,019,630✔
1260
    size_t keyLen = 0;
449,968✔
1261
    void  *key = taosHashGetKey(stb, &keyLen);
449,968✔
1262
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
449,968✔
1263
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
449,968✔
1264

1265
    size_t valueLen = 0;
449,968✔
1266
    valueLen = strlen(stb) + 1;
449,968✔
1267
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
449,968✔
1268
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
449,968✔
1269
    stb = taosHashIterate(pUser->readTbs, stb);
449,968✔
1270
  }
1271

1272
  stb = taosHashIterate(pUser->writeTbs, NULL);
2,569,662✔
1273
  while (stb != NULL) {
3,031,461✔
1274
    size_t keyLen = 0;
461,799✔
1275
    void  *key = taosHashGetKey(stb, &keyLen);
461,799✔
1276
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
461,799✔
1277
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
461,799✔
1278

1279
    size_t valueLen = 0;
461,799✔
1280
    valueLen = strlen(stb) + 1;
461,799✔
1281
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
461,799✔
1282
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
461,799✔
1283
    stb = taosHashIterate(pUser->writeTbs, stb);
461,799✔
1284
  }
1285

1286
  stb = taosHashIterate(pUser->alterTbs, NULL);
2,569,662✔
1287
  while (stb != NULL) {
2,807,277✔
1288
    size_t keyLen = 0;
237,615✔
1289
    void  *key = taosHashGetKey(stb, &keyLen);
237,615✔
1290
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
237,615✔
1291
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
237,615✔
1292

1293
    size_t valueLen = 0;
237,615✔
1294
    valueLen = strlen(stb) + 1;
237,615✔
1295
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
237,615✔
1296
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
237,615✔
1297
    stb = taosHashIterate(pUser->alterTbs, stb);
237,615✔
1298
  }
1299

1300
  stb = taosHashIterate(pUser->readViews, NULL);
2,569,662✔
1301
  while (stb != NULL) {
2,619,522✔
1302
    size_t keyLen = 0;
49,860✔
1303
    void  *key = taosHashGetKey(stb, &keyLen);
49,860✔
1304
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
49,860✔
1305
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
49,860✔
1306

1307
    size_t valueLen = 0;
49,860✔
1308
    valueLen = strlen(stb) + 1;
49,860✔
1309
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
49,860✔
1310
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
49,860✔
1311
    stb = taosHashIterate(pUser->readViews, stb);
49,860✔
1312
  }
1313

1314
  stb = taosHashIterate(pUser->writeViews, NULL);
2,569,662✔
1315
  while (stb != NULL) {
2,607,849✔
1316
    size_t keyLen = 0;
38,187✔
1317
    void  *key = taosHashGetKey(stb, &keyLen);
38,187✔
1318
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
38,187✔
1319
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
38,187✔
1320

1321
    size_t valueLen = 0;
38,187✔
1322
    valueLen = strlen(stb) + 1;
38,187✔
1323
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
38,187✔
1324
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
38,187✔
1325
    stb = taosHashIterate(pUser->writeViews, stb);
38,187✔
1326
  }
1327

1328
  stb = taosHashIterate(pUser->alterViews, NULL);
2,569,662✔
1329
  while (stb != NULL) {
2,607,282✔
1330
    size_t keyLen = 0;
37,620✔
1331
    void  *key = taosHashGetKey(stb, &keyLen);
37,620✔
1332
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
37,620✔
1333
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
37,620✔
1334

1335
    size_t valueLen = 0;
37,620✔
1336
    valueLen = strlen(stb) + 1;
37,620✔
1337
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
37,620✔
1338
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
37,620✔
1339
    stb = taosHashIterate(pUser->alterViews, stb);
37,620✔
1340
  }
1341

1342
  useDb = taosHashIterate(pUser->useDbs, NULL);
2,569,662✔
1343
  while (useDb != NULL) {
3,144,931✔
1344
    size_t keyLen = 0;
575,269✔
1345
    void  *key = taosHashGetKey(useDb, &keyLen);
575,269✔
1346
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
575,269✔
1347
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
575,269✔
1348

1349
    SDB_SET_INT32(pRaw, dataPos, *useDb, _OVER)
575,269✔
1350
    useDb = taosHashIterate(pUser->useDbs, useDb);
575,269✔
1351
  }
1352

1353
  // save white list
1354
  int32_t num = pUser->pIpWhiteListDual->num;
2,569,662✔
1355
  int32_t tlen = sizeof(SIpWhiteListDual) + num * sizeof(SIpRange) + 4;
2,569,662✔
1356
  if ((buf = taosMemoryCalloc(1, tlen)) == NULL) {
2,569,662✔
1357
    TAOS_CHECK_GOTO(terrno, NULL, _OVER);
×
1358
  }
1359
  int32_t len = 0;
2,569,662✔
1360
  TAOS_CHECK_GOTO(tSerializeIpWhiteList(buf, tlen, pUser->pIpWhiteListDual, &len), &lino, _OVER);
2,569,662✔
1361

1362
  SDB_SET_INT32(pRaw, dataPos, len, _OVER);
2,569,662✔
1363
  SDB_SET_BINARY(pRaw, dataPos, buf, len, _OVER);
2,569,662✔
1364

1365
  SDB_SET_INT64(pRaw, dataPos, pUser->ipWhiteListVer, _OVER);
2,569,662✔
1366
  SDB_SET_INT8(pRaw, dataPos, pUser->passEncryptAlgorithm, _OVER);
2,569,662✔
1367

1368
  SDB_SET_BINARY(pRaw, dataPos, pUser->totpsecret, sizeof(pUser->totpsecret), _OVER);
2,569,662✔
1369
  SDB_SET_INT8(pRaw, dataPos, pUser->changePass, _OVER);
2,569,662✔
1370
  SDB_SET_INT32(pRaw, dataPos, pUser->sessionPerUser, _OVER);
2,569,662✔
1371
  SDB_SET_INT32(pRaw, dataPos, pUser->connectTime, _OVER);
2,569,662✔
1372
  SDB_SET_INT32(pRaw, dataPos, pUser->connectIdleTime, _OVER);
2,569,662✔
1373
  SDB_SET_INT32(pRaw, dataPos, pUser->callPerSession, _OVER);
2,569,662✔
1374
  SDB_SET_INT32(pRaw, dataPos, pUser->vnodePerCall, _OVER);
2,569,662✔
1375
  SDB_SET_INT32(pRaw, dataPos, pUser->failedLoginAttempts, _OVER);
2,569,662✔
1376
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordLifeTime, _OVER);
2,569,662✔
1377
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordReuseTime, _OVER);
2,569,662✔
1378
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordReuseMax, _OVER);
2,569,662✔
1379
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordLockTime, _OVER);
2,569,662✔
1380
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordGraceTime, _OVER);
2,569,662✔
1381
  SDB_SET_INT32(pRaw, dataPos, pUser->inactiveAccountTime, _OVER);
2,569,662✔
1382
  SDB_SET_INT32(pRaw, dataPos, pUser->allowTokenNum, _OVER);
2,569,662✔
1383

1384
  SDB_SET_INT32(pRaw, dataPos, pUser->pTimeWhiteList->num, _OVER);
2,569,662✔
1385
  for (int32_t i = 0; i < pUser->pTimeWhiteList->num; i++) {
2,569,662✔
1386
    SDateTimeWhiteListItem *range = &pUser->pTimeWhiteList->ranges[i];
×
1387
    SDB_SET_BOOL(pRaw, dataPos, range->absolute, _OVER);
×
1388
    SDB_SET_BOOL(pRaw, dataPos, range->neg, _OVER);
×
1389
    SDB_SET_INT64(pRaw, dataPos, range->start, _OVER);
×
1390
    SDB_SET_INT32(pRaw, dataPos, range->duration, _OVER);
×
1391
  }
1392

1393
  SDB_SET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
2,569,662✔
1394
  SDB_SET_DATALEN(pRaw, dataPos, _OVER)
2,569,662✔
1395

1396
_OVER:
2,569,662✔
1397
  taosMemoryFree(buf);
2,569,662✔
1398
  if (code < 0) {
2,569,662✔
1399
    mError("user:%s, failed to encode user action to raw:%p at line %d since %s", pUser->user, pRaw, lino,
×
1400
           tstrerror(code));
1401
    sdbFreeRaw(pRaw);
×
1402
    pRaw = NULL;
×
1403
    terrno = code;
×
1404
  }
1405

1406
  mTrace("user:%s, encode user action to raw:%p, row:%p", pUser->user, pRaw, pUser);
2,569,662✔
1407
  return pRaw;
2,569,662✔
1408
}
1409

1410
static SSdbRow *mndUserActionDecode(SSdbRaw *pRaw) {
1,674,391✔
1411
  int32_t   code = 0;
1,674,391✔
1412
  int32_t   lino = 0;
1,674,391✔
1413
  SSdbRow  *pRow = NULL;
1,674,391✔
1414
  SUserObj *pUser = NULL;
1,674,391✔
1415
  char     *key = NULL;
1,674,391✔
1416
  char     *value = NULL;
1,674,391✔
1417

1418
  int8_t sver = 0;
1,674,391✔
1419
  if (sdbGetRawSoftVer(pRaw, &sver) != 0) {
1,674,391✔
1420
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_PTR, &lino, _OVER);
×
1421
  }
1422

1423
  if (sver < 1 || sver > USER_VER_NUMBER) {
1,674,391✔
1424
    TAOS_CHECK_GOTO(TSDB_CODE_SDB_INVALID_DATA_VER, &lino, _OVER);
×
1425
  }
1426

1427
  pRow = sdbAllocRow(sizeof(SUserObj));
1,674,391✔
1428
  if (pRow == NULL) {
1,674,391✔
1429
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1430
  }
1431

1432
  pUser = sdbGetRowObj(pRow);
1,674,391✔
1433
  if (pUser == NULL) {
1,674,391✔
1434
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1435
  }
1436

1437
  int32_t dataPos = 0;
1,674,391✔
1438
  SDB_GET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN, _OVER)
1,674,391✔
1439

1440
  if (sver < USER_VER_SUPPORT_ADVANCED_SECURITY) {
1,674,391✔
1441
    pUser->passwords = taosMemoryCalloc(1, sizeof(SUserPassword));
×
1442
    if (pUser->passwords == NULL) {
×
1443
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
1444
    }
1445
    SDB_GET_BINARY(pRaw, dataPos, pUser->passwords[0].pass, TSDB_PASSWORD_LEN, _OVER)
×
1446
    pUser->numOfPasswords = 1;
×
1447
    memset(pUser->salt, 0, sizeof(pUser->salt));
×
1448
  } else {
1449
    SDB_GET_INT32(pRaw, dataPos, &pUser->numOfPasswords, _OVER)
1,674,391✔
1450
    pUser->passwords = taosMemoryCalloc(pUser->numOfPasswords, sizeof(SUserPassword));
1,674,391✔
1451
    if (pUser->passwords == NULL) {
1,674,391✔
1452
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
1453
    }
1454
    for (int32_t i = 0; i < pUser->numOfPasswords; ++i) {
3,401,653✔
1455
      SDB_GET_BINARY(pRaw, dataPos, pUser->passwords[i].pass, sizeof(pUser->passwords[i].pass), _OVER);
1,727,262✔
1456
      SDB_GET_INT32(pRaw, dataPos, &pUser->passwords[i].setTime, _OVER);
1,727,262✔
1457
    }
1458
    SDB_GET_BINARY(pRaw, dataPos, pUser->salt, sizeof(pUser->salt), _OVER)
1,674,391✔
1459
  }
1460
  
1461
  SDB_GET_BINARY(pRaw, dataPos, pUser->acct, TSDB_USER_LEN, _OVER)
1,674,391✔
1462
  SDB_GET_INT64(pRaw, dataPos, &pUser->createdTime, _OVER)
1,674,391✔
1463
  SDB_GET_INT64(pRaw, dataPos, &pUser->updateTime, _OVER)
1,674,391✔
1464
  if (sver < USER_VER_SUPPORT_ADVANCED_SECURITY) {
1,674,391✔
1465
    pUser->passwords[0].setTime = (int32_t)(pUser->updateTime / 1000);
×
1466
  }
1467

1468
  SDB_GET_INT8(pRaw, dataPos, &pUser->superUser, _OVER)
1,674,391✔
1469
  SDB_GET_INT8(pRaw, dataPos, &pUser->sysInfo, _OVER)
1,674,391✔
1470
  SDB_GET_INT8(pRaw, dataPos, &pUser->enable, _OVER)
1,674,391✔
1471
  SDB_GET_UINT8(pRaw, dataPos, &pUser->flag, _OVER)
1,674,391✔
1472
  if (pUser->superUser) pUser->createdb = 1;
1,674,391✔
1473
  SDB_GET_INT32(pRaw, dataPos, &pUser->authVersion, _OVER)
1,674,391✔
1474
  if (sver >= 4) {
1,674,391✔
1475
    SDB_GET_INT32(pRaw, dataPos, &pUser->passVersion, _OVER)
1,674,391✔
1476
  }
1477

1478
  int32_t numOfReadDbs = 0;
1,674,391✔
1479
  int32_t numOfWriteDbs = 0;
1,674,391✔
1480
  int32_t numOfTopics = 0;
1,674,391✔
1481
  SDB_GET_INT32(pRaw, dataPos, &numOfReadDbs, _OVER)
1,674,391✔
1482
  SDB_GET_INT32(pRaw, dataPos, &numOfWriteDbs, _OVER)
1,674,391✔
1483
  if (sver >= 2) {
1,674,391✔
1484
    SDB_GET_INT32(pRaw, dataPos, &numOfTopics, _OVER)
1,674,391✔
1485
  }
1486

1487
  pUser->readDbs = taosHashInit(numOfReadDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,674,391✔
1488
  pUser->writeDbs =
1,674,391✔
1489
      taosHashInit(numOfWriteDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,674,391✔
1490
  pUser->topics = taosHashInit(numOfTopics, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,674,391✔
1491
  if (pUser->readDbs == NULL || pUser->writeDbs == NULL || pUser->topics == NULL) {
1,674,391✔
1492
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1493
    goto _OVER;
×
1494
  }
1495

1496
  for (int32_t i = 0; i < numOfReadDbs; ++i) {
2,002,405✔
1497
    char db[TSDB_DB_FNAME_LEN] = {0};
328,014✔
1498
    SDB_GET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER)
328,014✔
1499
    int32_t len = strlen(db) + 1;
328,014✔
1500
    TAOS_CHECK_GOTO(taosHashPut(pUser->readDbs, db, len, db, TSDB_DB_FNAME_LEN), &lino, _OVER);
328,014✔
1501
  }
1502

1503
  for (int32_t i = 0; i < numOfWriteDbs; ++i) {
1,995,363✔
1504
    char db[TSDB_DB_FNAME_LEN] = {0};
320,972✔
1505
    SDB_GET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER)
320,972✔
1506
    int32_t len = strlen(db) + 1;
320,972✔
1507
    TAOS_CHECK_GOTO(taosHashPut(pUser->writeDbs, db, len, db, TSDB_DB_FNAME_LEN), &lino, _OVER);
320,972✔
1508
  }
1509

1510
  if (sver >= 2) {
1,674,391✔
1511
    for (int32_t i = 0; i < numOfTopics; ++i) {
1,690,217✔
1512
      char topic[TSDB_TOPIC_FNAME_LEN] = {0};
15,826✔
1513
      SDB_GET_BINARY(pRaw, dataPos, topic, TSDB_TOPIC_FNAME_LEN, _OVER)
15,826✔
1514
      int32_t len = strlen(topic) + 1;
15,826✔
1515
      TAOS_CHECK_GOTO(taosHashPut(pUser->topics, topic, len, topic, TSDB_TOPIC_FNAME_LEN), &lino, _OVER);
15,826✔
1516
    }
1517
  }
1518

1519
  if (sver >= 3) {
1,674,391✔
1520
    int32_t numOfReadTbs = 0;
1,674,391✔
1521
    int32_t numOfWriteTbs = 0;
1,674,391✔
1522
    int32_t numOfAlterTbs = 0;
1,674,391✔
1523
    int32_t numOfReadViews = 0;
1,674,391✔
1524
    int32_t numOfWriteViews = 0;
1,674,391✔
1525
    int32_t numOfAlterViews = 0;
1,674,391✔
1526
    int32_t numOfUseDbs = 0;
1,674,391✔
1527
    SDB_GET_INT32(pRaw, dataPos, &numOfReadTbs, _OVER)
1,674,391✔
1528
    SDB_GET_INT32(pRaw, dataPos, &numOfWriteTbs, _OVER)
1,674,391✔
1529
    if (sver >= 6) {
1,674,391✔
1530
      SDB_GET_INT32(pRaw, dataPos, &numOfAlterTbs, _OVER)
1,674,391✔
1531
      SDB_GET_INT32(pRaw, dataPos, &numOfReadViews, _OVER)
1,674,391✔
1532
      SDB_GET_INT32(pRaw, dataPos, &numOfWriteViews, _OVER)
1,674,391✔
1533
      SDB_GET_INT32(pRaw, dataPos, &numOfAlterViews, _OVER)
1,674,391✔
1534
    }
1535
    SDB_GET_INT32(pRaw, dataPos, &numOfUseDbs, _OVER)
1,674,391✔
1536

1537
    pUser->readTbs =
1,674,391✔
1538
        taosHashInit(numOfReadTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,674,391✔
1539
    pUser->writeTbs =
1,674,391✔
1540
        taosHashInit(numOfWriteTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,674,391✔
1541
    pUser->alterTbs =
1,674,391✔
1542
        taosHashInit(numOfAlterTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,674,391✔
1543

1544
    pUser->readViews =
1,674,391✔
1545
        taosHashInit(numOfReadViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,674,391✔
1546
    pUser->writeViews =
1,674,391✔
1547
        taosHashInit(numOfWriteViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,674,391✔
1548
    pUser->alterViews =
1,674,391✔
1549
        taosHashInit(numOfAlterViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,674,391✔
1550

1551
    pUser->useDbs = taosHashInit(numOfUseDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,674,391✔
1552

1553
    if (pUser->readTbs == NULL || pUser->writeTbs == NULL || pUser->alterTbs == NULL || pUser->readViews == NULL ||
1,674,391✔
1554
        pUser->writeViews == NULL || pUser->alterViews == NULL || pUser->useDbs == NULL) {
1,674,391✔
1555
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1556
      goto _OVER;
×
1557
    }
1558

1559
    for (int32_t i = 0; i < numOfReadTbs; ++i) {
2,097,864✔
1560
      int32_t keyLen = 0;
423,473✔
1561
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
423,473✔
1562

1563
      TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
423,473✔
1564
      if (key == NULL) {
423,473✔
1565
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1566
      }
1567
      (void)memset(key, 0, keyLen);
423,473✔
1568
      SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
423,473✔
1569

1570
      int32_t valuelen = 0;
423,473✔
1571
      SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
423,473✔
1572
      TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
423,473✔
1573
      if (value == NULL) {
423,473✔
1574
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1575
      }
1576
      (void)memset(value, 0, valuelen);
423,473✔
1577
      SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
423,473✔
1578

1579
      TAOS_CHECK_GOTO(taosHashPut(pUser->readTbs, key, keyLen, value, valuelen), &lino, _OVER);
423,473✔
1580
    }
1581

1582
    for (int32_t i = 0; i < numOfWriteTbs; ++i) {
2,108,001✔
1583
      int32_t keyLen = 0;
433,610✔
1584
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
433,610✔
1585

1586
      TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
433,610✔
1587
      if (key == NULL) {
433,610✔
1588
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1589
      }
1590
      (void)memset(key, 0, keyLen);
433,610✔
1591
      SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
433,610✔
1592

1593
      int32_t valuelen = 0;
433,610✔
1594
      SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
433,610✔
1595
      TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
433,610✔
1596
      if (value == NULL) {
433,610✔
1597
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1598
      }
1599
      (void)memset(value, 0, valuelen);
433,610✔
1600
      SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
433,610✔
1601

1602
      TAOS_CHECK_GOTO(taosHashPut(pUser->writeTbs, key, keyLen, value, valuelen), &lino, _OVER);
433,610✔
1603
    }
1604

1605
    if (sver >= 6) {
1,674,391✔
1606
      for (int32_t i = 0; i < numOfAlterTbs; ++i) {
1,901,194✔
1607
        int32_t keyLen = 0;
226,803✔
1608
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
226,803✔
1609

1610
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
226,803✔
1611
        if (key == NULL) {
226,803✔
1612
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1613
        }
1614
        (void)memset(key, 0, keyLen);
226,803✔
1615
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
226,803✔
1616

1617
        int32_t valuelen = 0;
226,803✔
1618
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
226,803✔
1619
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
226,803✔
1620
        if (value == NULL) {
226,803✔
1621
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1622
        }
1623
        (void)memset(value, 0, valuelen);
226,803✔
1624
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
226,803✔
1625

1626
        TAOS_CHECK_GOTO(taosHashPut(pUser->alterTbs, key, keyLen, value, valuelen), &lino, _OVER);
226,803✔
1627
      }
1628

1629
      for (int32_t i = 0; i < numOfReadViews; ++i) {
1,724,251✔
1630
        int32_t keyLen = 0;
49,860✔
1631
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
49,860✔
1632

1633
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
49,860✔
1634
        if (key == NULL) {
49,860✔
1635
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1636
        }
1637
        (void)memset(key, 0, keyLen);
49,860✔
1638
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
49,860✔
1639

1640
        int32_t valuelen = 0;
49,860✔
1641
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
49,860✔
1642
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
49,860✔
1643
        if (value == NULL) {
49,860✔
1644
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1645
        }
1646
        (void)memset(value, 0, valuelen);
49,860✔
1647
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
49,860✔
1648

1649
        TAOS_CHECK_GOTO(taosHashPut(pUser->readViews, key, keyLen, value, valuelen), &lino, _OVER);
49,860✔
1650
      }
1651

1652
      for (int32_t i = 0; i < numOfWriteViews; ++i) {
1,712,578✔
1653
        int32_t keyLen = 0;
38,187✔
1654
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
38,187✔
1655

1656
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
38,187✔
1657
        if (key == NULL) {
38,187✔
1658
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1659
        }
1660
        (void)memset(key, 0, keyLen);
38,187✔
1661
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
38,187✔
1662

1663
        int32_t valuelen = 0;
38,187✔
1664
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
38,187✔
1665
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
38,187✔
1666
        if (value == NULL) {
38,187✔
1667
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1668
        }
1669
        (void)memset(value, 0, valuelen);
38,187✔
1670
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
38,187✔
1671

1672
        TAOS_CHECK_GOTO(taosHashPut(pUser->writeViews, key, keyLen, value, valuelen), &lino, _OVER);
38,187✔
1673
      }
1674

1675
      for (int32_t i = 0; i < numOfAlterViews; ++i) {
1,712,011✔
1676
        int32_t keyLen = 0;
37,620✔
1677
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
37,620✔
1678

1679
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
37,620✔
1680
        if (key == NULL) {
37,620✔
1681
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1682
        }
1683
        (void)memset(key, 0, keyLen);
37,620✔
1684
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
37,620✔
1685

1686
        int32_t valuelen = 0;
37,620✔
1687
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
37,620✔
1688
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
37,620✔
1689
        if (value == NULL) {
37,620✔
1690
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1691
        }
1692
        (void)memset(value, 0, valuelen);
37,620✔
1693
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
37,620✔
1694

1695
        TAOS_CHECK_GOTO(taosHashPut(pUser->alterViews, key, keyLen, value, valuelen), &lino, _OVER);
37,620✔
1696
      }
1697
    }
1698

1699
    for (int32_t i = 0; i < numOfUseDbs; ++i) {
2,206,475✔
1700
      int32_t keyLen = 0;
532,084✔
1701
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
532,084✔
1702

1703
      TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
532,084✔
1704
      if (key == NULL) {
532,084✔
1705
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1706
      }
1707
      (void)memset(key, 0, keyLen);
532,084✔
1708
      SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
532,084✔
1709

1710
      int32_t ref = 0;
532,084✔
1711
      SDB_GET_INT32(pRaw, dataPos, &ref, _OVER);
532,084✔
1712

1713
      TAOS_CHECK_GOTO(taosHashPut(pUser->useDbs, key, keyLen, &ref, sizeof(ref)), &lino, _OVER);
532,084✔
1714
    }
1715
  }
1716
  // decoder white list
1717
  if (sver >= USER_VER_SUPPORT_WHITELIST) {
1,674,391✔
1718
    if (sver < USER_VER_SUPPORT_WHITELIT_DUAL_STACK) {
1,674,391✔
1719
      int32_t len = 0;
×
1720
      SDB_GET_INT32(pRaw, dataPos, &len, _OVER);
×
1721

1722
      TAOS_MEMORY_REALLOC(key, len);
×
1723
      if (key == NULL) {
×
1724
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1725
      }
1726
      SDB_GET_BINARY(pRaw, dataPos, key, len, _OVER);
×
1727

1728
      SIpWhiteList *pIpWhiteList = NULL;
×
1729
      TAOS_CHECK_GOTO(createIpWhiteListFromOldVer(key, len, &pIpWhiteList), &lino, _OVER);
×
1730

1731
      SDB_GET_INT64(pRaw, dataPos, &pUser->ipWhiteListVer, _OVER);
×
1732

1733
      code = cvtIpWhiteListToDual(pIpWhiteList, &pUser->pIpWhiteListDual);
×
1734
      if (code != 0) {
×
1735
        taosMemoryFreeClear(pIpWhiteList);
×
1736
      }
1737
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
1738

1739
      taosMemoryFreeClear(pIpWhiteList);
×
1740

1741
    } else if (sver >= USER_VER_SUPPORT_WHITELIT_DUAL_STACK) {
1,674,391✔
1742
      int32_t len = 0;
1,674,391✔
1743
      SDB_GET_INT32(pRaw, dataPos, &len, _OVER);
1,674,391✔
1744

1745
      TAOS_MEMORY_REALLOC(key, len);
1,674,391✔
1746
      if (key == NULL) {
1,674,391✔
1747
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1748
      }
1749
      SDB_GET_BINARY(pRaw, dataPos, key, len, _OVER);
1,674,391✔
1750

1751
      TAOS_CHECK_GOTO(createIpWhiteList(key, len, &pUser->pIpWhiteListDual, sver >= USER_VER_SUPPORT_ADVANCED_SECURITY), &lino, _OVER);
1,674,391✔
1752
      SDB_GET_INT64(pRaw, dataPos, &pUser->ipWhiteListVer, _OVER);
1,674,391✔
1753
    }
1754
  }
1755

1756
  if (pUser->pIpWhiteListDual == NULL) {
1,674,391✔
1757
    TAOS_CHECK_GOTO(createDefaultIpWhiteList(&pUser->pIpWhiteListDual), &lino, _OVER);
×
1758
    pUser->ipWhiteListVer = taosGetTimestampMs();
×
1759
  }
1760

1761
  SDB_GET_INT8(pRaw, dataPos, &pUser->passEncryptAlgorithm, _OVER);
1,674,391✔
1762

1763
  if (sver < USER_VER_SUPPORT_ADVANCED_SECURITY) {
1,674,391✔
1764
    memset(pUser->totpsecret, 0, sizeof(pUser->totpsecret));
×
1765
    pUser->changePass = 2;
×
1766
    pUser->sessionPerUser = pUser->superUser ? -1 : TSDB_USER_SESSION_PER_USER_DEFAULT;
×
1767
    pUser->connectTime = TSDB_USER_CONNECT_TIME_DEFAULT;
×
1768
    pUser->connectIdleTime = TSDB_USER_CONNECT_IDLE_TIME_DEFAULT;
×
1769
    pUser->callPerSession = TSDB_USER_CALL_PER_SESSION_DEFAULT;
×
1770
    pUser->vnodePerCall = TSDB_USER_VNODE_PER_CALL_DEFAULT;
×
1771
    pUser->failedLoginAttempts = TSDB_USER_FAILED_LOGIN_ATTEMPTS_DEFAULT;
×
1772
    pUser->passwordLifeTime = TSDB_USER_PASSWORD_LIFE_TIME_DEFAULT;
×
1773
    pUser->passwordReuseTime = TSDB_USER_PASSWORD_REUSE_TIME_DEFAULT;
×
1774
    pUser->passwordLockTime = TSDB_USER_PASSWORD_LOCK_TIME_DEFAULT;
×
1775
    pUser->passwordGraceTime = pUser->superUser ? -1 : TSDB_USER_PASSWORD_GRACE_TIME_DEFAULT;
×
1776
    pUser->inactiveAccountTime = pUser->superUser ? -1 : TSDB_USER_INACTIVE_ACCOUNT_TIME_DEFAULT;
×
1777
    pUser->allowTokenNum = TSDB_USER_ALLOW_TOKEN_NUM_DEFAULT;
×
1778
    pUser->pTimeWhiteList = taosMemCalloc(1, sizeof(SDateTimeWhiteList));
×
1779
    if (pUser->pTimeWhiteList == NULL) {
×
1780
    }
1781
  } else {
1782
    SDB_GET_BINARY(pRaw, dataPos, pUser->totpsecret, sizeof(pUser->totpsecret), _OVER);
1,674,391✔
1783
    SDB_GET_INT8(pRaw, dataPos, &pUser->changePass, _OVER);
1,674,391✔
1784
    SDB_GET_INT32(pRaw, dataPos, &pUser->sessionPerUser, _OVER);
1,674,391✔
1785
    SDB_GET_INT32(pRaw, dataPos, &pUser->connectTime, _OVER);
1,674,391✔
1786
    SDB_GET_INT32(pRaw, dataPos, &pUser->connectIdleTime, _OVER);
1,674,391✔
1787
    SDB_GET_INT32(pRaw, dataPos, &pUser->callPerSession, _OVER);
1,674,391✔
1788
    SDB_GET_INT32(pRaw, dataPos, &pUser->vnodePerCall, _OVER);
1,674,391✔
1789
    SDB_GET_INT32(pRaw, dataPos, &pUser->failedLoginAttempts, _OVER);
1,674,391✔
1790
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordLifeTime, _OVER);
1,674,391✔
1791
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordReuseTime, _OVER);
1,674,391✔
1792
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordReuseMax, _OVER);
1,674,391✔
1793
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordLockTime, _OVER);
1,674,391✔
1794
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordGraceTime, _OVER);
1,674,391✔
1795
    SDB_GET_INT32(pRaw, dataPos, &pUser->inactiveAccountTime, _OVER);
1,674,391✔
1796
    SDB_GET_INT32(pRaw, dataPos, &pUser->allowTokenNum, _OVER);
1,674,391✔
1797

1798
    int32_t num = 0;
1,674,391✔
1799
    SDB_GET_INT32(pRaw, dataPos, &num, _OVER);
1,674,391✔
1800
    pUser->pTimeWhiteList = taosMemCalloc(1, sizeof(SDateTimeWhiteList) + num * sizeof(SDateTimeWhiteListItem));
1,674,391✔
1801
    if (pUser->pTimeWhiteList == NULL) {
1,674,391✔
1802
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1803
    }
1804

1805
    pUser->pTimeWhiteList->num = num;
1,674,391✔
1806
    for (int32_t i = 0; i < num; i++) {
1,674,391✔
1807
      SDateTimeWhiteListItem *range = &pUser->pTimeWhiteList->ranges[i];
×
1808
      SDB_GET_BOOL(pRaw, dataPos, &range->absolute, _OVER);
×
1809
      SDB_GET_BOOL(pRaw, dataPos, &range->neg, _OVER);
×
1810
      SDB_GET_INT64(pRaw, dataPos, &range->start, _OVER);
×
1811
      SDB_GET_INT32(pRaw, dataPos, &range->duration, _OVER);
×
1812
    }
1813
  }
1814

1815
  SDB_GET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
1,674,391✔
1816
  taosInitRWLatch(&pUser->lock);
1,674,391✔
1817
  dropOldPasswords(pUser);
1,674,391✔
1818

1819
_OVER:
1,674,391✔
1820
  taosMemoryFree(key);
1,674,391✔
1821
  taosMemoryFree(value);
1,674,391✔
1822
  if (code < 0) {
1,674,391✔
1823
    terrno = code;
×
1824
    mError("user:%s, failed to decode at line %d from raw:%p since %s", pUser == NULL ? "null" : pUser->user, lino,
×
1825
           pRaw, tstrerror(code));
1826
    if (pUser != NULL) {
×
1827
      taosHashCleanup(pUser->readDbs);
×
1828
      taosHashCleanup(pUser->writeDbs);
×
1829
      taosHashCleanup(pUser->topics);
×
1830
      taosHashCleanup(pUser->readTbs);
×
1831
      taosHashCleanup(pUser->writeTbs);
×
1832
      taosHashCleanup(pUser->alterTbs);
×
1833
      taosHashCleanup(pUser->readViews);
×
1834
      taosHashCleanup(pUser->writeViews);
×
1835
      taosHashCleanup(pUser->alterViews);
×
1836
      taosHashCleanup(pUser->useDbs);
×
1837
      taosMemoryFreeClear(pUser->pIpWhiteListDual);
×
1838
      taosMemoryFreeClear(pUser->pTimeWhiteList);
×
1839
    }
1840
    taosMemoryFreeClear(pRow);
×
1841
    return NULL;
×
1842
  }
1843

1844
  mTrace("user:%s, decode from raw:%p, row:%p", pUser->user, pRaw, pUser);
1,674,391✔
1845
  return pRow;
1,674,391✔
1846
}
1847

1848
static int32_t mndUserActionInsert(SSdb *pSdb, SUserObj *pUser) {
638,860✔
1849
  mTrace("user:%s, perform insert action, row:%p", pUser->user, pUser);
638,860✔
1850

1851
  SAcctObj *pAcct = sdbAcquire(pSdb, SDB_ACCT, pUser->acct);
638,860✔
1852
  if (pAcct == NULL) {
638,860✔
1853
    terrno = TSDB_CODE_MND_ACCT_NOT_EXIST;
×
1854
    mError("user:%s, failed to perform insert action since %s", pUser->user, terrstr());
×
1855
    TAOS_RETURN(terrno);
×
1856
  }
1857
  pUser->acctId = pAcct->acctId;
638,860✔
1858
  sdbRelease(pSdb, pAcct);
638,860✔
1859

1860
  return 0;
638,860✔
1861
}
1862

1863
int32_t mndDupTableHash(SHashObj *pOld, SHashObj **ppNew) {
42,730,977✔
1864
  int32_t code = 0;
42,730,977✔
1865
  *ppNew =
42,731,417✔
1866
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
42,730,977✔
1867
  if (*ppNew == NULL) {
42,731,417✔
1868
    TAOS_RETURN(terrno);
×
1869
  }
1870

1871
  char *tb = taosHashIterate(pOld, NULL);
42,731,417✔
1872
  while (tb != NULL) {
45,132,374✔
1873
    size_t keyLen = 0;
2,400,957✔
1874
    char  *key = taosHashGetKey(tb, &keyLen);
2,400,957✔
1875

1876
    int32_t valueLen = strlen(tb) + 1;
2,400,957✔
1877
    if ((code = taosHashPut(*ppNew, key, keyLen, tb, valueLen)) != 0) {
2,400,957✔
1878
      taosHashCancelIterate(pOld, tb);
×
1879
      taosHashCleanup(*ppNew);
×
1880
      TAOS_RETURN(code);
×
1881
    }
1882
    tb = taosHashIterate(pOld, tb);
2,400,957✔
1883
  }
1884

1885
  TAOS_RETURN(code);
42,731,417✔
1886
}
1887

1888
int32_t mndDupUseDbHash(SHashObj *pOld, SHashObj **ppNew) {
1,710,568✔
1889
  int32_t code = 0;
1,710,568✔
1890
  *ppNew =
1,710,568✔
1891
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,710,568✔
1892
  if (*ppNew == NULL) {
1,710,568✔
1893
    TAOS_RETURN(terrno);
×
1894
  }
1895

1896
  int32_t *db = taosHashIterate(pOld, NULL);
1,710,568✔
1897
  while (db != NULL) {
2,221,402✔
1898
    size_t keyLen = 0;
510,834✔
1899
    char  *key = taosHashGetKey(db, &keyLen);
510,834✔
1900

1901
    if ((code = taosHashPut(*ppNew, key, keyLen, db, sizeof(*db))) != 0) {
510,834✔
1902
      taosHashCancelIterate(pOld, db);
×
1903
      taosHashCleanup(*ppNew);
×
1904
      TAOS_RETURN(code);
×
1905
    }
1906
    db = taosHashIterate(pOld, db);
510,834✔
1907
  }
1908

1909
  TAOS_RETURN(code);
1,710,568✔
1910
}
1911

1912
int32_t mndUserDupObj(SUserObj *pUser, SUserObj *pNew) {
1,710,568✔
1913
  int32_t code = 0;
1,710,568✔
1914
  (void)memcpy(pNew, pUser, sizeof(SUserObj));
1,710,568✔
1915
  pNew->authVersion++;
1,710,568✔
1916
  pNew->updateTime = taosGetTimestampMs();
1,710,568✔
1917

1918
  pNew->passwords = NULL;
1,710,568✔
1919
  pNew->readDbs = NULL;
1,710,568✔
1920
  pNew->writeDbs = NULL;
1,710,568✔
1921
  pNew->readTbs = NULL;
1,710,568✔
1922
  pNew->writeTbs = NULL;
1,710,568✔
1923
  pNew->alterTbs = NULL;
1,710,568✔
1924
  pNew->readViews = NULL;
1,710,568✔
1925
  pNew->writeViews = NULL;
1,710,568✔
1926
  pNew->alterViews = NULL;
1,710,568✔
1927
  pNew->topics = NULL;
1,710,568✔
1928
  pNew->useDbs = NULL;
1,710,568✔
1929
  pNew->pIpWhiteListDual = NULL;
1,710,568✔
1930
  pNew->pTimeWhiteList = NULL;
1,710,568✔
1931

1932
  taosRLockLatch(&pUser->lock);
1,710,568✔
1933
  pNew->passwords = taosMemoryCalloc(pUser->numOfPasswords, sizeof(SUserPassword));
1,710,568✔
1934
  if (pNew->passwords == NULL) {
1,710,568✔
1935
    code = TSDB_CODE_OUT_OF_MEMORY;
×
1936
    goto _OVER;
×
1937
  }
1938
  (void)memcpy(pNew->passwords, pUser->passwords, pUser->numOfPasswords * sizeof(SUserPassword));
1,710,568✔
1939

1940
  TAOS_CHECK_GOTO(mndDupDbHash(pUser->readDbs, &pNew->readDbs), NULL, _OVER);
1,710,568✔
1941
  TAOS_CHECK_GOTO(mndDupDbHash(pUser->writeDbs, &pNew->writeDbs), NULL, _OVER);
1,710,568✔
1942
  TAOS_CHECK_GOTO(mndDupTableHash(pUser->readTbs, &pNew->readTbs), NULL, _OVER);
1,710,568✔
1943
  TAOS_CHECK_GOTO(mndDupTableHash(pUser->writeTbs, &pNew->writeTbs), NULL, _OVER);
1,710,568✔
1944
  TAOS_CHECK_GOTO(mndDupTableHash(pUser->alterTbs, &pNew->alterTbs), NULL, _OVER);
1,710,568✔
1945
  TAOS_CHECK_GOTO(mndDupTableHash(pUser->readViews, &pNew->readViews), NULL, _OVER);
1,710,568✔
1946
  TAOS_CHECK_GOTO(mndDupTableHash(pUser->writeViews, &pNew->writeViews), NULL, _OVER);
1,710,568✔
1947
  TAOS_CHECK_GOTO(mndDupTableHash(pUser->alterViews, &pNew->alterViews), NULL, _OVER);
1,710,568✔
1948
  TAOS_CHECK_GOTO(mndDupTopicHash(pUser->topics, &pNew->topics), NULL, _OVER);
1,710,568✔
1949
  TAOS_CHECK_GOTO(mndDupUseDbHash(pUser->useDbs, &pNew->useDbs), NULL, _OVER);
1,710,568✔
1950
  pNew->pIpWhiteListDual = cloneIpWhiteList(pUser->pIpWhiteListDual);
1,710,568✔
1951
  if (pNew->pIpWhiteListDual == NULL) {
1,710,568✔
1952
    code = TSDB_CODE_OUT_OF_MEMORY;
×
1953
    goto _OVER;
×
1954
  }
1955

1956
  pNew->pTimeWhiteList = cloneDateTimeWhiteList(pUser->pTimeWhiteList);
1,710,568✔
1957
  if (pNew->pTimeWhiteList == NULL) {
1,710,568✔
1958
    code = TSDB_CODE_OUT_OF_MEMORY;
×
1959
    goto _OVER;
×
1960
  }
1961

1962
_OVER:
1,710,568✔
1963
  taosRUnLockLatch(&pUser->lock);
1,710,568✔
1964
  TAOS_RETURN(code);
1,710,568✔
1965
}
1966

1967
void mndUserFreeObj(SUserObj *pUser) {
6,307,728✔
1968
  taosHashCleanup(pUser->readDbs);
6,307,728✔
1969
  taosHashCleanup(pUser->writeDbs);
6,307,728✔
1970
  taosHashCleanup(pUser->topics);
6,307,728✔
1971
  taosHashCleanup(pUser->readTbs);
6,307,728✔
1972
  taosHashCleanup(pUser->writeTbs);
6,307,728✔
1973
  taosHashCleanup(pUser->alterTbs);
6,307,728✔
1974
  taosHashCleanup(pUser->readViews);
6,307,728✔
1975
  taosHashCleanup(pUser->writeViews);
6,307,728✔
1976
  taosHashCleanup(pUser->alterViews);
6,307,728✔
1977
  taosHashCleanup(pUser->useDbs);
6,307,728✔
1978
  taosMemoryFreeClear(pUser->passwords);
6,307,728✔
1979
  taosMemoryFreeClear(pUser->pIpWhiteListDual);
6,307,728✔
1980
  taosMemoryFreeClear(pUser->pTimeWhiteList);
6,307,728✔
1981
  pUser->readDbs = NULL;
6,307,728✔
1982
  pUser->writeDbs = NULL;
6,307,728✔
1983
  pUser->topics = NULL;
6,307,728✔
1984
  pUser->readTbs = NULL;
6,307,728✔
1985
  pUser->writeTbs = NULL;
6,307,728✔
1986
  pUser->alterTbs = NULL;
6,307,728✔
1987
  pUser->readViews = NULL;
6,307,728✔
1988
  pUser->writeViews = NULL;
6,307,728✔
1989
  pUser->alterViews = NULL;
6,307,728✔
1990
  pUser->useDbs = NULL;
6,307,728✔
1991
}
6,307,728✔
1992

1993
static int32_t mndUserActionDelete(SSdb *pSdb, SUserObj *pUser) {
1,674,308✔
1994
  mTrace("user:%s, perform delete action, row:%p", pUser->user, pUser);
1,674,308✔
1995
  mndUserFreeObj(pUser);
1,674,308✔
1996
  return 0;
1,674,308✔
1997
}
1998

1999
static int32_t mndUserActionUpdate(SSdb *pSdb, SUserObj *pOld, SUserObj *pNew) {
962,063✔
2000
  mTrace("user:%s, perform update action, old row:%p new row:%p", pOld->user, pOld, pNew);
962,063✔
2001
  taosWLockLatch(&pOld->lock);
962,063✔
2002
  pOld->updateTime = pNew->updateTime;
962,063✔
2003
  pOld->authVersion = pNew->authVersion;
962,063✔
2004
  pOld->passVersion = pNew->passVersion;
962,063✔
2005
  pOld->sysInfo = pNew->sysInfo;
962,063✔
2006
  pOld->enable = pNew->enable;
962,063✔
2007
  pOld->flag = pNew->flag;
962,063✔
2008
  pOld->changePass = pNew->changePass;
962,063✔
2009

2010
  pOld->sessionPerUser = pNew->sessionPerUser;
962,063✔
2011
  pOld->connectTime = pNew->connectTime;
962,063✔
2012
  pOld->connectIdleTime = pNew->connectIdleTime;
962,063✔
2013
  pOld->callPerSession = pNew->callPerSession;
962,063✔
2014
  pOld->vnodePerCall = pNew->vnodePerCall;
962,063✔
2015
  pOld->failedLoginAttempts = pNew->failedLoginAttempts;
962,063✔
2016
  pOld->passwordLifeTime = pNew->passwordLifeTime;
962,063✔
2017
  pOld->passwordReuseTime = pNew->passwordReuseTime;
962,063✔
2018
  pOld->passwordReuseMax = pNew->passwordReuseMax;
962,063✔
2019
  pOld->passwordLockTime = pNew->passwordLockTime;
962,063✔
2020
  pOld->passwordGraceTime = pNew->passwordGraceTime;
962,063✔
2021
  pOld->inactiveAccountTime = pNew->inactiveAccountTime;
962,063✔
2022
  pOld->allowTokenNum = pNew->allowTokenNum;
962,063✔
2023

2024
  pOld->numOfPasswords = pNew->numOfPasswords;
962,063✔
2025
  TSWAP(pOld->passwords, pNew->passwords);
962,063✔
2026
  (void)memcpy(pOld->salt, pNew->salt, sizeof(pOld->salt));
962,063✔
2027
  (void)memcpy(pOld->totpsecret, pNew->totpsecret, sizeof(pOld->totpsecret));
962,063✔
2028
  TSWAP(pOld->readDbs, pNew->readDbs);
962,063✔
2029
  TSWAP(pOld->writeDbs, pNew->writeDbs);
962,063✔
2030
  TSWAP(pOld->topics, pNew->topics);
962,063✔
2031
  TSWAP(pOld->readTbs, pNew->readTbs);
962,063✔
2032
  TSWAP(pOld->writeTbs, pNew->writeTbs);
962,063✔
2033
  TSWAP(pOld->alterTbs, pNew->alterTbs);
962,063✔
2034
  TSWAP(pOld->readViews, pNew->readViews);
962,063✔
2035
  TSWAP(pOld->writeViews, pNew->writeViews);
962,063✔
2036
  TSWAP(pOld->alterViews, pNew->alterViews);
962,063✔
2037
  TSWAP(pOld->useDbs, pNew->useDbs);
962,063✔
2038

2039
  TSWAP(pOld->pIpWhiteListDual, pNew->pIpWhiteListDual);
962,063✔
2040
  pOld->ipWhiteListVer = pNew->ipWhiteListVer;
962,063✔
2041
  TSWAP(pOld->pTimeWhiteList, pNew->pTimeWhiteList);
962,063✔
2042
  pOld->timeWhiteListVer = pNew->timeWhiteListVer;
962,063✔
2043
  pOld->passEncryptAlgorithm = pNew->passEncryptAlgorithm;
962,063✔
2044

2045
  taosWUnLockLatch(&pOld->lock);
962,063✔
2046

2047
  return 0;
962,063✔
2048
}
2049

2050
int32_t mndAcquireUser(SMnode *pMnode, const char *userName, SUserObj **ppUser) {
86,443,519✔
2051
  int32_t code = 0;
86,443,519✔
2052
  SSdb   *pSdb = pMnode->pSdb;
86,443,519✔
2053

2054
  *ppUser = sdbAcquire(pSdb, SDB_USER, userName);
86,444,060✔
2055
  if (*ppUser == NULL) {
86,442,267✔
2056
    if (terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
122,036✔
2057
      code = TSDB_CODE_MND_USER_NOT_EXIST;
122,036✔
2058
    } else {
2059
      code = TSDB_CODE_MND_USER_NOT_AVAILABLE;
×
2060
    }
2061
  }
2062
  TAOS_RETURN(code);
86,442,267✔
2063
}
2064

2065
void mndReleaseUser(SMnode *pMnode, SUserObj *pUser) {
86,497,769✔
2066
  SSdb *pSdb = pMnode->pSdb;
86,497,769✔
2067
  sdbRelease(pSdb, pUser);
86,498,283✔
2068
}
86,500,902✔
2069

2070

2071

2072
int32_t mndEncryptPass(char *pass, const char* salt, int8_t *algo) {
118,266✔
2073
  int32_t code = 0;
118,266✔
2074
  if (tsiEncryptPassAlgorithm != DND_CA_SM4) {
118,266✔
2075
    return 0;
117,534✔
2076
  }
2077

2078
  if (strlen(tsEncryptKey) == 0) {
732✔
2079
    return TSDB_CODE_DNODE_INVALID_ENCRYPTKEY;
×
2080
  }
2081

2082
  if (salt[0] != 0) {
732✔
2083
    char passAndSalt[TSDB_PASSWORD_LEN - 1 + TSDB_PASSWORD_SALT_LEN];
732✔
2084
    (void)memcpy(passAndSalt, pass, TSDB_PASSWORD_LEN - 1);
732✔
2085
    (void)memcpy(passAndSalt + TSDB_PASSWORD_LEN - 1, salt, TSDB_PASSWORD_SALT_LEN);
732✔
2086
    taosEncryptPass_c((uint8_t *)passAndSalt, sizeof(passAndSalt), pass);
2087
  }
2088

2089
  unsigned char packetData[TSDB_PASSWORD_LEN] = {0};
732✔
2090
  SCryptOpts opts = {0};
732✔
2091
  opts.len = TSDB_PASSWORD_LEN;
732✔
2092
  opts.source = pass;
732✔
2093
  opts.result = packetData;
732✔
2094
  opts.unitLen = TSDB_PASSWORD_LEN;
732✔
2095
  tstrncpy(opts.key, tsEncryptKey, ENCRYPT_KEY_LEN + 1);
732✔
2096
  int newLen = Builtin_CBC_Encrypt(&opts);
732✔
2097
  if (newLen <= 0) return terrno;
732✔
2098

2099
  memcpy(pass, packetData, newLen);
732✔
2100
  if (algo != NULL) {
732✔
2101
    *algo = DND_CA_SM4;
366✔
2102
  }
2103

2104
  return 0;
732✔
2105
}
2106

2107

2108

2109
static void generateSalt(char *salt, size_t len) {
104,361✔
2110
  const char* set = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
104,361✔
2111
  int32_t     setLen = 62;
104,361✔
2112
  for (int32_t i = 0; i < len - 1; ++i) {
3,339,552✔
2113
    salt[i] = set[taosSafeRand() % setLen];
3,235,191✔
2114
  }
2115
  salt[len - 1] = 0;
104,361✔
2116
}
104,361✔
2117

2118

2119

2120
static int32_t addDefaultIpToTable(int8_t enableIpv6, SHashObj *pUniqueTab) {
1,095✔
2121
  int32_t code = 0;
1,095✔
2122
  int32_t lino = 0;
1,095✔
2123
  int32_t dummpy = 0;
1,095✔
2124

2125
  SIpRange ipv4 = {0}, ipv6 = {0};
1,095✔
2126
  code = createDefaultIp4Range(&ipv4);
1,095✔
2127
  TSDB_CHECK_CODE(code, lino, _error);
1,095✔
2128

2129
  code = taosHashPut(pUniqueTab, &ipv4, sizeof(ipv4), &dummpy, sizeof(dummpy));
1,095✔
2130
  TSDB_CHECK_CODE(code, lino, _error);
1,095✔
2131

2132
  if (enableIpv6) {
1,095✔
2133
    code = createDefaultIp6Range(&ipv6);
×
2134
    TSDB_CHECK_CODE(code, lino, _error);
×
2135

2136
    code = taosHashPut(pUniqueTab, &ipv6, sizeof(ipv6), &dummpy, sizeof(dummpy));
×
2137
    TSDB_CHECK_CODE(code, lino, _error);
×
2138
  }
2139
_error:
1,095✔
2140
  if (code != 0) {
1,095✔
2141
    mError("failed to add default ip range to table since %s", tstrerror(code));
×
2142
  }
2143
  return code;
1,095✔
2144
}
2145

2146
static int32_t mndCreateUser(SMnode *pMnode, char *acct, SCreateUserReq *pCreate, SRpcMsg *pReq) {
103,629✔
2147
  int32_t  code = 0;
103,629✔
2148
  int32_t  lino = 0;
103,629✔
2149
  SUserObj userObj = {0};
103,629✔
2150

2151
  userObj.passwords = taosMemoryCalloc(1, sizeof(SUserPassword));
103,629✔
2152
  if (userObj.passwords == NULL) {
103,629✔
2153
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2154
  }
2155
  userObj.numOfPasswords = 1;
103,629✔
2156

2157
  if (pCreate->isImport == 1) {
103,629✔
2158
    memset(userObj.salt, 0, sizeof(userObj.salt));
×
2159
    memcpy(userObj.passwords[0].pass, pCreate->pass, TSDB_PASSWORD_LEN);
×
2160
  } else {
2161
    generateSalt(userObj.salt, sizeof(userObj.salt));
103,629✔
2162
    taosEncryptPass_c((uint8_t *)pCreate->pass, strlen(pCreate->pass), userObj.passwords[0].pass);
103,629✔
2163
    userObj.passwords[0].pass[sizeof(userObj.passwords[0].pass) - 1] = 0;
103,629✔
2164
    TAOS_CHECK_GOTO(mndEncryptPass(userObj.passwords[0].pass, userObj.salt, &userObj.passEncryptAlgorithm), &lino, _OVER);
103,629✔
2165
  }
2166
  userObj.passwords[0].setTime = taosGetTimestampSec();
103,629✔
2167

2168
  tstrncpy(userObj.user, pCreate->user, TSDB_USER_LEN);
103,629✔
2169
  tstrncpy(userObj.acct, acct, TSDB_USER_LEN);
103,629✔
2170
  if (pCreate->totpseed[0] != 0) {
103,629✔
2171
    int len = taosGenerateTotpSecret(pCreate->totpseed, 0, userObj.totpsecret, sizeof(userObj.totpsecret));
×
2172
    if (len < 0) {
×
2173
      TAOS_CHECK_GOTO(TSDB_CODE_PAR_INVALID_OPTION_VALUE, &lino, _OVER);
×
2174
    }
2175
  }
2176

2177
  userObj.createdTime = taosGetTimestampMs();
103,629✔
2178
  userObj.updateTime = userObj.createdTime;
103,629✔
2179
  userObj.superUser = 0;  // pCreate->superUser;
103,629✔
2180
  userObj.sysInfo = pCreate->sysInfo;
103,629✔
2181
  userObj.enable = pCreate->enable;
103,629✔
2182
  userObj.createdb = pCreate->createDb;
103,629✔
2183

2184
  userObj.changePass = pCreate->changepass;
103,629✔
2185
  userObj.sessionPerUser = pCreate->sessionPerUser;
103,629✔
2186
  userObj.connectTime = pCreate->connectTime;
103,629✔
2187
  userObj.connectIdleTime = pCreate->connectIdleTime;
103,629✔
2188
  userObj.callPerSession = pCreate->callPerSession;
103,629✔
2189
  userObj.vnodePerCall = pCreate->vnodePerCall;
103,629✔
2190
  userObj.failedLoginAttempts = pCreate->failedLoginAttempts;
103,629✔
2191
  userObj.passwordLifeTime = pCreate->passwordLifeTime;
103,629✔
2192
  userObj.passwordReuseTime = pCreate->passwordReuseTime;
103,629✔
2193
  userObj.passwordReuseMax = pCreate->passwordReuseMax;
103,629✔
2194
  userObj.passwordLockTime = pCreate->passwordLockTime;
103,629✔
2195
  userObj.passwordGraceTime = pCreate->passwordGraceTime;
103,629✔
2196
  userObj.inactiveAccountTime = pCreate->inactiveAccountTime;
103,629✔
2197
  userObj.allowTokenNum = pCreate->allowTokenNum;
103,629✔
2198

2199
  if (pCreate->numIpRanges == 0) {
103,629✔
2200
    TAOS_CHECK_GOTO(createDefaultIpWhiteList(&userObj.pIpWhiteListDual), &lino, _OVER);
102,534✔
2201
  } else {
2202
    SHashObj *pUniqueTab = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
1,095✔
2203
    if (pUniqueTab == NULL) {
1,095✔
2204
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2205
    }
2206
    int32_t dummpy = 0;
1,095✔
2207
    
2208
    for (int i = 0; i < pCreate->numIpRanges; i++) {
2,920✔
2209
      SIpRange range = {0};
1,825✔
2210
      copyIpRange(&range, pCreate->pIpDualRanges + i);
1,825✔
2211
      if ((code = taosHashPut(pUniqueTab, &range, sizeof(range), &dummpy, sizeof(dummpy))) != 0) {
1,825✔
2212
        taosHashCleanup(pUniqueTab);
×
2213
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2214
      }
2215
    }
2216

2217
    code = addDefaultIpToTable(tsEnableIpv6, pUniqueTab);
1,095✔
2218
    if (code != 0) {
1,095✔
2219
      taosHashCleanup(pUniqueTab);
×
2220
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2221
    }
2222

2223
    if (taosHashGetSize(pUniqueTab) > MND_MAX_USER_IP_RANGE) {
1,095✔
2224
      taosHashCleanup(pUniqueTab);
×
2225
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_IP_RANGE, &lino, _OVER);
×
2226
    }
2227

2228
    int32_t           numOfRanges = taosHashGetSize(pUniqueTab);
1,095✔
2229
    SIpWhiteListDual *p = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + numOfRanges * sizeof(SIpRange));
1,095✔
2230
    if (p == NULL) {
1,095✔
2231
      taosHashCleanup(pUniqueTab);
×
2232
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2233
    }
2234

2235
    void   *pIter = taosHashIterate(pUniqueTab, NULL);
1,095✔
2236
    for (int32_t i = 0; i < numOfRanges; i++) {
3,285✔
2237
      size_t    len = 0;
2,190✔
2238
      SIpRange *key = taosHashGetKey(pIter, &len);
2,190✔
2239
      memcpy(&p->pIpRanges[i], key, sizeof(SIpRange));
2,190✔
2240
      pIter = taosHashIterate(pUniqueTab, pIter);
2,190✔
2241
    }
2242

2243
    taosHashCleanup(pUniqueTab);
1,095✔
2244
    p->num = numOfRanges;
1,095✔
2245
    sortIpWhiteList(p);
1,095✔
2246
    userObj.pIpWhiteListDual = p;
1,095✔
2247
  }
2248

2249
  if (pCreate->numTimeRanges == 0) {
103,629✔
2250
    userObj.pTimeWhiteList = (SDateTimeWhiteList*)taosMemoryCalloc(1, sizeof(SDateTimeWhiteList));
103,629✔
2251
    if (userObj.pTimeWhiteList == NULL) {
103,629✔
2252
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2253
    }
2254
  } else {
2255
    SHashObj *pUniqueTab = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
×
2256
    if (pUniqueTab == NULL) {
×
2257
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2258
    }
2259
    int32_t dummpy = 0;
×
2260
    
2261
    for (int i = 0; i < pCreate->numIpRanges; i++) {
×
2262
      SDateTimeRange* src = pCreate->pTimeRanges + i;
×
2263
      SDateTimeWhiteListItem range = {0};
×
2264
      DateTimeRangeToWhiteListItem(&range, src);
×
2265

2266
      // no need to add expired range
2267
      if (isDateTimeWhiteListItemExpired(&range)) {
×
2268
        continue;
×
2269
      }
2270

2271
      if ((code = taosHashPut(pUniqueTab, &range, sizeof(range), &dummpy, sizeof(dummpy))) != 0) {
×
2272
        taosHashCleanup(pUniqueTab);
×
2273
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2274
      }
2275
    }
2276

2277
    if (taosHashGetSize(pUniqueTab) > MND_MAX_USER_TIME_RANGE) {
×
2278
      taosHashCleanup(pUniqueTab);
×
2279
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_TIME_RANGE, &lino, _OVER);
×
2280
    }
2281

2282
    int32_t           numOfRanges = taosHashGetSize(pUniqueTab);
×
2283
    SDateTimeWhiteList *p = taosMemoryCalloc(1, sizeof(SDateTimeWhiteList) + numOfRanges * sizeof(SDateTimeWhiteListItem));
×
2284
    if (p == NULL) {
×
2285
      taosHashCleanup(pUniqueTab);
×
2286
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2287
    }
2288

2289
    void   *pIter = taosHashIterate(pUniqueTab, NULL);
×
2290
    for (int32_t i = 0; i < numOfRanges; i++) {
×
2291
      size_t    len = 0;
×
2292
      SDateTimeWhiteListItem *key = taosHashGetKey(pIter, &len);
×
2293
      memcpy(p->ranges + i, key, sizeof(SDateTimeWhiteListItem));
×
2294
      pIter = taosHashIterate(pUniqueTab, pIter);
×
2295
    }
2296

2297
    taosHashCleanup(pUniqueTab);
×
2298
    p->num = numOfRanges;
×
2299
    sortTimeWhiteList(p);
×
2300
    userObj.pTimeWhiteList = p;
×
2301
  }
2302

2303
  userObj.ipWhiteListVer = taosGetTimestampMs();
103,629✔
2304
  userObj.timeWhiteListVer = userObj.ipWhiteListVer;
103,629✔
2305

2306
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "create-user");
103,629✔
2307
  if (pTrans == NULL) {
103,629✔
2308
    mError("user:%s, failed to create since %s", pCreate->user, terrstr());
×
2309
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2310
  }
2311
  mInfo("trans:%d, used to create user:%s", pTrans->id, pCreate->user);
103,629✔
2312

2313
  SSdbRaw *pCommitRaw = mndUserActionEncode(&userObj);
103,629✔
2314
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
103,629✔
2315
    mError("trans:%d, failed to commit redo log since %s", pTrans->id, terrstr());
×
2316
    mndTransDrop(pTrans);
×
2317
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2318
  }
2319
  TAOS_CHECK_GOTO(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY), &lino, _OVER);
103,629✔
2320

2321
  if (mndTransPrepare(pMnode, pTrans) != 0) {
103,629✔
2322
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
2323
    mndTransDrop(pTrans);
×
2324
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2325
  }
2326

2327
  if ((code = userCacheUpdateWhiteList(pMnode, &userObj)) != 0) {
103,629✔
2328
    mndTransDrop(pTrans);
×
2329
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2330
  }
2331

2332
  mndTransDrop(pTrans);
103,629✔
2333

2334
_OVER:
103,629✔
2335
  taosMemoryFree(userObj.passwords);
103,629✔
2336
  taosMemoryFree(userObj.pIpWhiteListDual);
103,629✔
2337
  taosMemoryFree(userObj.pTimeWhiteList);
103,629✔
2338
  TAOS_RETURN(code);
103,629✔
2339
}
2340

2341

2342
static int32_t mndCheckPasswordFmt(const char *pwd) {
118,624✔
2343
  if (strcmp(pwd, "taosdata") == 0) {
118,624✔
2344
    return 0;
28,546✔
2345
  }
2346

2347
  if (tsEnableStrongPassword == 0) {
90,078✔
2348
    for (char c = *pwd; c != 0; c = *(++pwd)) {
100,010✔
2349
      if (c == ' ' || c == '\'' || c == '\"' || c == '`' || c == '\\') {
98,915✔
2350
        return TSDB_CODE_MND_INVALID_PASS_FORMAT;
×
2351
      }
2352
    }
2353
    return 0;
1,095✔
2354
  }
2355

2356
  int32_t len = strlen(pwd);
88,983✔
2357
  if (len < TSDB_PASSWORD_MIN_LEN) {
88,983✔
2358
    return TSDB_CODE_PAR_PASSWD_TOO_SHORT_OR_EMPTY;
×
2359
  }
2360

2361
  if (len > TSDB_PASSWORD_MAX_LEN) {
88,983✔
2362
    return TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG;
×
2363
  }
2364

2365
  if (taosIsComplexString(pwd)) {
88,983✔
2366
    return 0;
88,983✔
2367
  }
2368

2369
  return TSDB_CODE_MND_INVALID_PASS_FORMAT;
×
2370
}
2371

2372

2373

2374
static int32_t mndCheckTotpSeedFmt(const char *seed) {
×
2375
  int32_t len = strlen(seed);
×
2376
  if (len < TSDB_USER_TOTPSEED_MIN_LEN) {
×
2377
    return TSDB_CODE_PAR_OPTION_VALUE_TOO_SHORT;
×
2378
  }
2379

2380
  if (taosIsComplexString(seed)) {
×
2381
    return 0;
×
2382
  }
2383

2384
  return TSDB_CODE_PAR_INVALID_OPTION_VALUE;
×
2385
}
2386

2387

2388

2389
static int32_t mndProcessGetUserDateTimeWhiteListReq(SRpcMsg *pReq) {
×
2390
  SMnode              *pMnode = pReq->info.node;
×
2391
  int32_t              code = 0;
×
2392
  int32_t              lino = 0;
×
2393
  int32_t              contLen = 0;
×
2394
  void                *pRsp = NULL;
×
2395
  SUserObj            *pUser = NULL;
×
2396
  SGetUserWhiteListReq wlReq = {0};
×
2397
  SUserDateTimeWhiteList wlRsp = {0};
×
2398

2399
  if (tDeserializeSGetUserWhiteListReq(pReq->pCont, pReq->contLen, &wlReq) != 0) {
×
2400
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
2401
  }
2402
  mTrace("user: %s, start to get date time whitelist", wlReq.user);
×
2403

2404
  code = mndAcquireUser(pMnode, wlReq.user, &pUser);
×
2405
  if (pUser == NULL) {
×
2406
    TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_NOT_EXIST, &lino, _OVER);
×
2407
  }
2408

2409
  TAOS_CHECK_GOTO(mndSetUserDateTimeWhiteListRsp(pMnode, pUser, &wlRsp), &lino, _OVER);
×
2410

2411
  contLen = tSerializeSUserDateTimeWhiteList(NULL, 0, &wlRsp);
×
2412
  if (contLen < 0) {
×
2413
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2414
  }
2415
  pRsp = rpcMallocCont(contLen);
×
2416
  if (pRsp == NULL) {
×
2417
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2418
  }
2419
  
2420
  contLen = tSerializeSUserDateTimeWhiteList(pRsp, contLen, &wlRsp);
×
2421
  if (contLen < 0) {
×
2422
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2423
  }
2424

2425
_OVER:
×
2426
  mndReleaseUser(pMnode, pUser);
×
2427
  tFreeSUserDateTimeWhiteList(&wlRsp);
×
2428
  if (code < 0) {
×
2429
    mError("user:%s, failed to get whitelist at line %d since %s", wlReq.user, lino, tstrerror(code));
×
2430
    rpcFreeCont(pRsp);
×
2431
    pRsp = NULL;
×
2432
    contLen = 0;
×
2433
  }
2434
  pReq->code = code;
×
2435
  pReq->info.rsp = pRsp;
×
2436
  pReq->info.rspLen = contLen;
×
2437

2438
  TAOS_RETURN(code);
×
2439
  return 0;
2440
}
2441

2442

2443

2444
static int32_t buildRetrieveDateTimeWhiteListRsp(SRetrieveDateTimeWhiteListRsp *pRsp) {
1,893✔
2445
  (void)taosThreadRwlockWrlock(&userCache.rw);
1,893✔
2446
  
2447
  int32_t count = taosHashGetSize(userCache.users);
1,893✔
2448
  pRsp->pUsers = taosMemoryCalloc(count, sizeof(SUserDateTimeWhiteList));
1,893✔
2449
  if (pRsp->pUsers == NULL) {
1,893✔
2450
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
2451
    TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
2452
  }
2453

2454
  count = 0;
1,893✔
2455
  void   *pIter = taosHashIterate(userCache.users, NULL);
1,893✔
2456
  while (pIter) {
3,786✔
2457
    SDateTimeWhiteList *wl = (*(SCachedUserInfo **)pIter)->wlTime;
1,893✔
2458
    if (wl == NULL || wl->num <= 0) {
1,893✔
2459
      pIter = taosHashIterate(userCache.users, pIter);
1,893✔
2460
      continue;
1,893✔
2461
    }
2462

2463
    SUserDateTimeWhiteList *pUser = &pRsp->pUsers[count];
×
2464
    pUser->ver = userCache.verTime;
×
2465

2466
    size_t klen;
×
2467
    char  *key = taosHashGetKey(pIter, &klen);
×
2468
    (void)memcpy(pUser->user, key, klen);
×
2469

2470
    pUser->numWhiteLists = wl->num;
×
2471
    pUser->pWhiteLists = taosMemoryCalloc(wl->num, sizeof(SDateTimeWhiteListItem));
×
2472
    if (pUser->pWhiteLists == NULL) {
×
2473
      (void)taosThreadRwlockUnlock(&userCache.rw);
×
2474
      TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
2475
    }
2476

2477
    (void)memcpy(pUser->pWhiteLists, wl->ranges, wl->num * sizeof(SDateTimeWhiteListItem));
×
2478
    count++;
×
2479
    pIter = taosHashIterate(userCache.users, pIter);
×
2480
  }
2481

2482
  pRsp->numOfUser = count;
1,893✔
2483
  pRsp->ver = userCache.verTime;
1,893✔
2484
  (void)taosThreadRwlockUnlock(&userCache.rw);
1,893✔
2485
  TAOS_RETURN(0);
1,893✔
2486
}
2487

2488

2489

2490
static int32_t mndProcessRetrieveDateTimeWhiteListReq(SRpcMsg *pReq) {
1,893✔
2491
  int32_t        code = 0;
1,893✔
2492
  int32_t        lino = 0;
1,893✔
2493
  int32_t        len = 0;
1,893✔
2494
  void          *pRsp = NULL;
1,893✔
2495
  SRetrieveDateTimeWhiteListRsp wlRsp = {0};
1,893✔
2496

2497
  // impl later
2498
  SRetrieveWhiteListReq req = {0};
1,893✔
2499
  if (tDeserializeRetrieveWhiteListReq(pReq->pCont, pReq->contLen, &req) != 0) {
1,893✔
2500
    code = TSDB_CODE_INVALID_MSG;
×
2501
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2502
  }
2503

2504
  TAOS_CHECK_GOTO(buildRetrieveDateTimeWhiteListRsp(&wlRsp), &lino, _OVER);
1,893✔
2505

2506
  len = tSerializeSRetrieveDateTimeWhiteListRsp(NULL, 0, &wlRsp);
1,893✔
2507
  if (len < 0) {
1,893✔
2508
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
2509
  }
2510

2511
  pRsp = rpcMallocCont(len);
1,893✔
2512
  if (!pRsp) {
1,893✔
2513
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2514
  }
2515
  len = tSerializeSRetrieveDateTimeWhiteListRsp(pRsp, len, &wlRsp);
1,893✔
2516
  if (len < 0) {
1,893✔
2517
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
2518
  }
2519

2520
_OVER:
1,893✔
2521
  if (code < 0) {
1,893✔
2522
    mError("failed to process retrieve ip white request at line %d since %s", lino, tstrerror(code));
×
2523
    rpcFreeCont(pRsp);
×
2524
    pRsp = NULL;
×
2525
    len = 0;
×
2526
  }
2527
  pReq->code = code;
1,893✔
2528
  pReq->info.rsp = pRsp;
1,893✔
2529
  pReq->info.rspLen = len;
1,893✔
2530

2531
  tFreeSRetrieveDateTimeWhiteListRsp(&wlRsp);
1,893✔
2532
  TAOS_RETURN(code);
1,893✔
2533
}
2534

2535

2536

2537
static int32_t mndProcessCreateUserReq(SRpcMsg *pReq) {
104,353✔
2538
  SMnode        *pMnode = pReq->info.node;
104,353✔
2539
  int32_t        code = 0;
104,353✔
2540
  int32_t        lino = 0;
104,353✔
2541
  SUserObj      *pUser = NULL;
104,353✔
2542
  SUserObj      *pOperUser = NULL;
104,353✔
2543
  SCreateUserReq createReq = {0};
104,353✔
2544
  int64_t        tss = taosGetTimestampMs();
104,353✔
2545

2546
  if (tDeserializeSCreateUserReq(pReq->pCont, pReq->contLen, &createReq) != 0) {
104,353✔
2547
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
2548
  }
2549

2550
  mInfo("user:%s, start to create, createdb:%d, is_import:%d", createReq.user, createReq.createDb, createReq.isImport);
104,353✔
2551

2552
#ifndef TD_ENTERPRISE
2553
  if (createReq.isImport == 1) {
2554
    TAOS_CHECK_GOTO(TSDB_CODE_OPS_NOT_SUPPORT, &lino, _OVER);  // enterprise feature
2555
  }
2556
#endif
2557

2558
  if (createReq.isImport != 1) {
104,353✔
2559
    TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CREATE_USER), &lino, _OVER);
104,353✔
2560
  } else if (strcmp(pReq->info.conn.user, "root") != 0) {
×
2561
    mError("The operation is not permitted, user:%s", pReq->info.conn.user);
×
2562
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_RIGHTS, &lino, _OVER);
×
2563
  }
2564

2565
  if (createReq.user[0] == 0) {
104,353✔
2566
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
2567
  }
2568

2569
  if (createReq.isImport != 1) {
104,353✔
2570
    code = mndCheckPasswordFmt(createReq.pass);
104,353✔
2571
    TAOS_CHECK_GOTO(code, &lino, _OVER);
104,353✔
2572
  }
2573

2574
  if (createReq.totpseed[0] != 0) {
104,353✔
2575
    code = mndCheckTotpSeedFmt(createReq.totpseed);
×
2576
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2577
  }
2578

2579
  code = mndAcquireUser(pMnode, createReq.user, &pUser);
104,353✔
2580
  if (pUser != NULL) {
104,353✔
2581
    TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_ALREADY_EXIST, &lino, _OVER);
724✔
2582
  }
2583

2584
  code = mndAcquireUser(pMnode, pReq->info.conn.user, &pOperUser);
103,629✔
2585
  if (pOperUser == NULL) {
103,629✔
2586
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_USER_FROM_CONN, &lino, _OVER);
×
2587
  }
2588

2589
  TAOS_CHECK_GOTO(grantCheck(TSDB_GRANT_USER), &lino, _OVER);
103,629✔
2590

2591
  code = mndCreateUser(pMnode, pOperUser->acct, &createReq, pReq);
103,629✔
2592
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
103,629✔
2593

2594
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
103,629✔
2595
    char detail[1000] = {0};
103,629✔
2596
    (void)tsnprintf(detail, sizeof(detail), "enable:%d, superUser:%d, sysInfo:%d, password:xxx", createReq.enable,
103,629✔
2597
                    createReq.superUser, createReq.sysInfo);
103,629✔
2598
    char operation[15] = {0};
103,629✔
2599
    if (createReq.isImport == 1) {
103,629✔
NEW
2600
      tstrncpy(operation, "importUser", sizeof(operation));
×
2601
    } else {
2602
      tstrncpy(operation, "createUser", sizeof(operation));
103,629✔
2603
    }
2604

2605
    int64_t tse = taosGetTimestampMs();
103,629✔
2606
    double  duration = (double)(tse - tss);
103,629✔
2607
    duration = duration / 1000;
103,629✔
2608
    auditRecord(pReq, pMnode->clusterId, operation, "", createReq.user, detail, strlen(detail), duration, 0);
103,629✔
2609
  }
2610
_OVER:
104,353✔
2611
  if (code == TSDB_CODE_MND_USER_ALREADY_EXIST && createReq.ignoreExisting) {
104,353✔
2612
    code = 0;
×
2613
  } else if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
104,353✔
2614
    mError("user:%s, failed to create at line %d since %s", createReq.user, lino, tstrerror(code));
724✔
2615
  }
2616

2617
  mndReleaseUser(pMnode, pUser);
104,353✔
2618
  mndReleaseUser(pMnode, pOperUser);
104,353✔
2619
  tFreeSCreateUserReq(&createReq);
104,353✔
2620

2621
  TAOS_RETURN(code);
104,353✔
2622
}
2623

2624

2625

2626
static int32_t mndProcessGetUserIpWhiteListReq(SRpcMsg *pReq) {
146,181✔
2627
  SMnode              *pMnode = pReq->info.node;
146,181✔
2628
  int32_t              code = 0;
146,181✔
2629
  int32_t              lino = 0;
146,181✔
2630
  int32_t              contLen = 0;
146,181✔
2631
  void                *pRsp = NULL;
146,181✔
2632
  SUserObj            *pUser = NULL;
146,181✔
2633
  SGetUserWhiteListReq wlReq = {0};
145,925✔
2634
  SGetUserIpWhiteListRsp wlRsp = {0};
145,925✔
2635

2636
  int32_t (*serialFn)(void *, int32_t, SGetUserIpWhiteListRsp *) = NULL;
145,925✔
2637
  int32_t (*setRspFn)(SMnode * pMnode, SUserObj * pUser, SGetUserIpWhiteListRsp * pRsp) = NULL;
145,925✔
2638

2639
  if (pReq->msgType == TDMT_MND_GET_USER_IP_WHITELIST_DUAL) {
145,925✔
2640
    serialFn = tSerializeSGetUserIpWhiteListDualRsp;
146,181✔
2641
    setRspFn = mndSetUserIpWhiteListDualRsp;
146,181✔
2642
  } else {
2643
    serialFn = tSerializeSGetUserIpWhiteListRsp;
×
2644
    setRspFn = mndSetUserIpWhiteListRsp;
×
2645
  }
2646
  if (tDeserializeSGetUserWhiteListReq(pReq->pCont, pReq->contLen, &wlReq) != 0) {
146,181✔
2647
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
2648
  }
2649
  mTrace("user: %s, start to get ip whitelist", wlReq.user);
146,181✔
2650

2651
  code = mndAcquireUser(pMnode, wlReq.user, &pUser);
146,181✔
2652
  if (pUser == NULL) {
146,181✔
2653
    TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_NOT_EXIST, &lino, _OVER);
×
2654
  }
2655

2656
  TAOS_CHECK_GOTO(setRspFn(pMnode, pUser, &wlRsp), &lino, _OVER);
146,181✔
2657
  contLen = serialFn(NULL, 0, &wlRsp);
146,181✔
2658
  if (contLen < 0) {
146,181✔
2659
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2660
  }
2661
  pRsp = rpcMallocCont(contLen);
146,181✔
2662
  if (pRsp == NULL) {
145,925✔
2663
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2664
  }
2665

2666
  contLen = serialFn(pRsp, contLen, &wlRsp);
145,925✔
2667
  if (contLen < 0) {
146,181✔
2668
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2669
  }
2670

2671
_OVER:
146,181✔
2672
  mndReleaseUser(pMnode, pUser);
146,181✔
2673
  tFreeSGetUserIpWhiteListDualRsp(&wlRsp);
146,181✔
2674
  if (code < 0) {
146,181✔
2675
    mError("user:%s, failed to get whitelist at line %d since %s", wlReq.user, lino, tstrerror(code));
×
2676
    rpcFreeCont(pRsp);
×
2677
    pRsp = NULL;
×
2678
    contLen = 0;
×
2679
  }
2680
  pReq->code = code;
146,181✔
2681
  pReq->info.rsp = pRsp;
146,181✔
2682
  pReq->info.rspLen = contLen;
146,181✔
2683

2684
  TAOS_RETURN(code);
146,181✔
2685
}
2686

2687

2688

2689
static int32_t buildRetrieveIpWhiteListRsp(SUpdateIpWhite *pUpdate) {
1,893✔
2690
  (void)taosThreadRwlockWrlock(&userCache.rw);
1,893✔
2691

2692
  int32_t count = taosHashGetSize(userCache.users);
1,893✔
2693
  pUpdate->pUserIpWhite = taosMemoryCalloc(count, sizeof(SUpdateUserIpWhite));
1,893✔
2694
  if (pUpdate->pUserIpWhite == NULL) {
1,893✔
2695
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
2696
    TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
2697
  }
2698

2699
  count = 0;
1,893✔
2700
  void   *pIter = taosHashIterate(userCache.users, NULL);
1,893✔
2701
  while (pIter) {
3,786✔
2702
    SIpWhiteListDual   *wl = (*(SCachedUserInfo**)pIter)->wlIp;
1,893✔
2703
    if (wl == NULL || wl->num <= 0) {
1,893✔
2704
      pIter = taosHashIterate(userCache.users, pIter);
×
2705
      continue;
×
2706
    }
2707

2708
    SUpdateUserIpWhite *pUser = &pUpdate->pUserIpWhite[count];
1,893✔
2709
    pUser->ver = userCache.verIp;
1,893✔
2710

2711
    size_t klen;
1,893✔
2712
    char  *key = taosHashGetKey(pIter, &klen);
1,893✔
2713
    (void)memcpy(pUser->user, key, klen);
1,893✔
2714

2715
    pUser->numOfRange = wl->num;
1,893✔
2716
    pUser->pIpRanges = taosMemoryCalloc(wl->num, sizeof(SIpRange));
1,893✔
2717
    if (pUser->pIpRanges == NULL) {
1,893✔
2718
      (void)taosThreadRwlockUnlock(&userCache.rw);
×
2719
      TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
2720
    }
2721

2722
    (void)memcpy(pUser->pIpRanges, wl->pIpRanges, wl->num * sizeof(SIpRange));
1,893✔
2723
    count++;
1,893✔
2724
    pIter = taosHashIterate(userCache.users, pIter);
1,893✔
2725
  }
2726

2727
  pUpdate->numOfUser = count;
1,893✔
2728
  pUpdate->ver = userCache.verIp;
1,893✔
2729
  (void)taosThreadRwlockUnlock(&userCache.rw);
1,893✔
2730
  TAOS_RETURN(0);
1,893✔
2731
}
2732

2733

2734

2735
int32_t mndProcessRetrieveIpWhiteListReq(SRpcMsg *pReq) {
1,893✔
2736
  int32_t        code = 0;
1,893✔
2737
  int32_t        lino = 0;
1,893✔
2738
  int32_t        len = 0;
1,893✔
2739
  void          *pRsp = NULL;
1,893✔
2740
  SUpdateIpWhite ipWhite = {0};
1,893✔
2741

2742
  // impl later
2743
  SRetrieveWhiteListReq req = {0};
1,893✔
2744
  if (tDeserializeRetrieveWhiteListReq(pReq->pCont, pReq->contLen, &req) != 0) {
1,893✔
2745
    code = TSDB_CODE_INVALID_MSG;
×
2746
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2747
  }
2748

2749
  int32_t (*fn)(void *, int32_t, SUpdateIpWhite *) = NULL;
1,893✔
2750
  if (pReq->msgType == TDMT_MND_RETRIEVE_IP_WHITELIST) {
1,893✔
2751
    fn = tSerializeSUpdateIpWhite;
×
2752
  } else if (pReq->msgType == TDMT_MND_RETRIEVE_IP_WHITELIST_DUAL) {
1,893✔
2753
    fn = tSerializeSUpdateIpWhiteDual;
1,893✔
2754
  }
2755

2756
  TAOS_CHECK_GOTO(buildRetrieveIpWhiteListRsp(&ipWhite), &lino, _OVER);
1,893✔
2757

2758
  len = fn(NULL, 0, &ipWhite);
1,893✔
2759
  if (len < 0) {
1,893✔
2760
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
2761
  }
2762

2763
  pRsp = rpcMallocCont(len);
1,893✔
2764
  if (!pRsp) {
1,893✔
2765
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2766
  }
2767
  len = fn(pRsp, len, &ipWhite);
1,893✔
2768
  if (len < 0) {
1,893✔
2769
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
2770
  }
2771

2772
_OVER:
1,893✔
2773
  if (code < 0) {
1,893✔
2774
    mError("failed to process retrieve ip white request at line %d since %s", lino, tstrerror(code));
×
2775
    rpcFreeCont(pRsp);
×
2776
    pRsp = NULL;
×
2777
    len = 0;
×
2778
  }
2779
  pReq->code = code;
1,893✔
2780
  pReq->info.rsp = pRsp;
1,893✔
2781
  pReq->info.rspLen = len;
1,893✔
2782

2783
  tFreeSUpdateIpWhiteReq(&ipWhite);
1,893✔
2784
  TAOS_RETURN(code);
1,893✔
2785
}
2786

2787

2788

2789
void mndUpdateUser(SMnode *pMnode, SUserObj *pUser, SRpcMsg *pReq) {
×
2790
  int32_t code = 0;
×
2791
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "update-user");
×
2792
  if (pTrans == NULL) {
×
2793
    mError("user:%s, failed to update since %s", pUser->user, terrstr());
×
2794
    return;
×
2795
  }
2796
  mInfo("trans:%d, used to update user:%s", pTrans->id, pUser->user);
×
2797

2798
  SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
×
2799
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
×
2800
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
2801
    mndTransDrop(pTrans);
×
2802
    return;
×
2803
  }
2804
  code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
×
2805
  if (code < 0) {
×
2806
    mndTransDrop(pTrans);
×
2807
    return;
×
2808
  }
2809

2810
  if (mndTransPrepare(pMnode, pTrans) != 0) {
×
2811
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
2812
    mndTransDrop(pTrans);
×
2813
    return;
×
2814
  }
2815

2816
  mndTransDrop(pTrans);
×
2817
}
2818

2819

2820

2821
static int32_t mndAlterUser(SMnode *pMnode, SUserObj *pOld, SUserObj *pNew, SRpcMsg *pReq) {
931,516✔
2822
  int32_t code = 0;
931,516✔
2823
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "alter-user");
931,516✔
2824
  if (pTrans == NULL) {
931,516✔
2825
    mError("user:%s, failed to alter since %s", pOld->user, terrstr());
×
2826
    TAOS_RETURN(terrno);
×
2827
  }
2828
  mInfo("trans:%d, used to alter user:%s", pTrans->id, pOld->user);
931,516✔
2829

2830
  SSdbRaw *pCommitRaw = mndUserActionEncode(pNew);
931,516✔
2831
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
931,516✔
2832
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
2833
    mndTransDrop(pTrans);
×
2834
    TAOS_RETURN(terrno);
×
2835
  }
2836
  code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
931,516✔
2837
  if (code < 0) {
931,516✔
2838
    mndTransDrop(pTrans);
×
2839
    TAOS_RETURN(code);
×
2840
  }
2841

2842
  if (mndTransPrepare(pMnode, pTrans) != 0) {
931,516✔
2843
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
2844
    mndTransDrop(pTrans);
×
2845
    TAOS_RETURN(terrno);
×
2846
  }
2847
  if ((code = userCacheUpdateWhiteList(pMnode, pNew)) != 0) {
931,516✔
2848
    mndTransDrop(pTrans);
×
2849
    TAOS_RETURN(code);
×
2850
  }
2851
  mndTransDrop(pTrans);
931,516✔
2852
  return 0;
931,516✔
2853
}
2854

2855
static int32_t mndDupObjHash(SHashObj *pOld, int32_t dataLen, SHashObj **ppNew) {
14,408,278✔
2856
  int32_t code = 0;
14,408,278✔
2857

2858
  *ppNew =
14,408,278✔
2859
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
14,408,278✔
2860
  if (*ppNew == NULL) {
14,408,278✔
2861
    code = terrno ? terrno : TSDB_CODE_OUT_OF_MEMORY;
×
2862
    TAOS_RETURN(code);
×
2863
  }
2864

2865
  char *db = taosHashIterate(pOld, NULL);
14,408,278✔
2866
  while (db != NULL) {
15,581,673✔
2867
    int32_t len = strlen(db) + 1;
1,173,395✔
2868
    if ((code = taosHashPut(*ppNew, db, len, db, dataLen)) != 0) {
1,173,395✔
2869
      taosHashCancelIterate(pOld, db);
×
2870
      taosHashCleanup(*ppNew);
×
2871
      TAOS_RETURN(code);
×
2872
    }
2873
    db = taosHashIterate(pOld, db);
1,173,395✔
2874
  }
2875

2876
  TAOS_RETURN(code);
14,408,278✔
2877
}
2878

2879
int32_t mndDupDbHash(SHashObj *pOld, SHashObj **ppNew) { return mndDupObjHash(pOld, TSDB_DB_FNAME_LEN, ppNew); }
12,697,710✔
2880

2881
int32_t mndDupTopicHash(SHashObj *pOld, SHashObj **ppNew) { return mndDupObjHash(pOld, TSDB_TOPIC_FNAME_LEN, ppNew); }
1,710,568✔
2882

2883
static int32_t mndTablePriviledge(SMnode *pMnode, SHashObj *hash, SHashObj *useDbHash, SAlterUserReq *alterReq,
451,078✔
2884
                                  SSdb *pSdb) {
2885
  void *pIter = NULL;
451,078✔
2886
  char  tbFName[TSDB_TABLE_FNAME_LEN] = {0};
451,078✔
2887

2888
  (void)snprintf(tbFName, sizeof(tbFName), "%s.%s", alterReq->objname, alterReq->tabName);
451,078✔
2889
  int32_t len = strlen(tbFName) + 1;
451,078✔
2890

2891
  if (alterReq->tagCond != NULL && alterReq->tagCondLen != 0) {
523,124✔
2892
    char *value = taosHashGet(hash, tbFName, len);
72,046✔
2893
    if (value != NULL) {
72,046✔
2894
      TAOS_RETURN(TSDB_CODE_MND_PRIVILEDGE_EXIST);
×
2895
    }
2896

2897
    int32_t condLen = alterReq->tagCondLen;
72,046✔
2898
    TAOS_CHECK_RETURN(taosHashPut(hash, tbFName, len, alterReq->tagCond, condLen));
72,046✔
2899
  } else {
2900
    TAOS_CHECK_RETURN(taosHashPut(hash, tbFName, len, alterReq->isView ? "v" : "t", 2));
379,032✔
2901
  }
2902

2903
  int32_t  dbKeyLen = strlen(alterReq->objname) + 1;
451,078✔
2904
  int32_t  ref = 1;
451,078✔
2905
  int32_t *currRef = taosHashGet(useDbHash, alterReq->objname, dbKeyLen);
451,078✔
2906
  if (NULL != currRef) {
451,078✔
2907
    ref = (*currRef) + 1;
261,407✔
2908
  }
2909
  TAOS_CHECK_RETURN(taosHashPut(useDbHash, alterReq->objname, dbKeyLen, &ref, sizeof(ref)));
451,078✔
2910

2911
  TAOS_RETURN(0);
451,078✔
2912
}
2913

2914
static int32_t mndRemoveTablePriviledge(SMnode *pMnode, SHashObj *hash, SHashObj *useDbHash, SAlterUserReq *alterReq,
412,770✔
2915
                                        SSdb *pSdb) {
2916
  void *pIter = NULL;
412,770✔
2917
  char  tbFName[TSDB_TABLE_FNAME_LEN] = {0};
412,770✔
2918
  (void)snprintf(tbFName, sizeof(tbFName), "%s.%s", alterReq->objname, alterReq->tabName);
412,770✔
2919
  int32_t len = strlen(tbFName) + 1;
412,770✔
2920

2921
  if (taosHashRemove(hash, tbFName, len) != 0) {
412,770✔
2922
    TAOS_RETURN(0);  // not found
1,389✔
2923
  }
2924

2925
  int32_t  dbKeyLen = strlen(alterReq->objname) + 1;
411,381✔
2926
  int32_t *currRef = taosHashGet(useDbHash, alterReq->objname, dbKeyLen);
411,381✔
2927
  if (NULL == currRef) {
411,381✔
2928
    return 0;
×
2929
  }
2930

2931
  if (1 == *currRef) {
411,381✔
2932
    if (taosHashRemove(useDbHash, alterReq->objname, dbKeyLen) != 0) {
175,910✔
2933
      TAOS_RETURN(0);  // not found
×
2934
    }
2935
    return 0;
175,910✔
2936
  }
2937
  int32_t ref = (*currRef) - 1;
235,471✔
2938
  TAOS_CHECK_RETURN(taosHashPut(useDbHash, alterReq->objname, dbKeyLen, &ref, sizeof(ref)));
235,471✔
2939

2940
  return 0;
235,471✔
2941
}
2942

2943
static char *mndUserAuditTypeStr(int32_t type) {
×
2944
  #if 0
2945
  if (type == TSDB_ALTER_USER_PASSWD) {
2946
    return "changePassword";
2947
  }
2948
  if (type == TSDB_ALTER_USER_SUPERUSER) {
2949
    return "changeSuperUser";
2950
  }
2951
  if (type == TSDB_ALTER_USER_ENABLE) {
2952
    return "enableUser";
2953
  }
2954
  if (type == TSDB_ALTER_USER_SYSINFO) {
2955
    return "userSysInfo";
2956
  }
2957
  if (type == TSDB_ALTER_USER_CREATEDB) {
2958
    return "userCreateDB";
2959
  }
2960
    #endif
2961
  return "error";
×
2962
}
2963

2964
static int32_t mndProcessAlterUserPrivilegesReq(SAlterUserReq *pAlterReq, SMnode *pMnode, SUserObj *pNewUser) {
895,960✔
2965
  SSdb   *pSdb = pMnode->pSdb;
895,960✔
2966
  void   *pIter = NULL;
895,960✔
2967
  int32_t code = 0;
895,960✔
2968
  int32_t lino = 0;
895,960✔
2969

2970
  if (ALTER_USER_ADD_READ_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
895,960✔
2971
      ALTER_USER_ADD_ALL_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
766,789✔
2972
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
129,171✔
2973
      int32_t len = strlen(pAlterReq->objname) + 1;
125,542✔
2974
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
125,542✔
2975
      if (pDb == NULL) {
125,542✔
2976
        mndReleaseDb(pMnode, pDb);
2,884✔
2977
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
2,884✔
2978
      }
2979
      if ((code = taosHashPut(pNewUser->readDbs, pAlterReq->objname, len, pAlterReq->objname, TSDB_DB_FNAME_LEN)) !=
122,658✔
2980
          0) {
2981
        mndReleaseDb(pMnode, pDb);
×
2982
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2983
      }
2984
      mndReleaseDb(pMnode, pDb);
122,658✔
2985
    } else {
2986
      while (1) {
5,819✔
2987
        SDbObj *pDb = NULL;
9,448✔
2988
        pIter = sdbFetch(pSdb, SDB_DB, pIter, (void **)&pDb);
9,448✔
2989
        if (pIter == NULL) break;
9,448✔
2990
        int32_t len = strlen(pDb->name) + 1;
5,819✔
2991
        if ((code = taosHashPut(pNewUser->readDbs, pDb->name, len, pDb->name, TSDB_DB_FNAME_LEN)) != 0) {
5,819✔
2992
          sdbRelease(pSdb, pDb);
×
2993
          sdbCancelFetch(pSdb, pIter);
×
2994
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2995
        }
2996
        sdbRelease(pSdb, pDb);
5,819✔
2997
      }
2998
    }
2999
  }
3000

3001
  if (ALTER_USER_ADD_WRITE_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
893,076✔
3002
      ALTER_USER_ADD_ALL_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
768,312✔
3003
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
124,764✔
3004
      int32_t len = strlen(pAlterReq->objname) + 1;
121,497✔
3005
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
121,497✔
3006
      if (pDb == NULL) {
121,497✔
3007
        mndReleaseDb(pMnode, pDb);
365✔
3008
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
365✔
3009
      }
3010
      if ((code = taosHashPut(pNewUser->writeDbs, pAlterReq->objname, len, pAlterReq->objname, TSDB_DB_FNAME_LEN)) !=
121,132✔
3011
          0) {
3012
        mndReleaseDb(pMnode, pDb);
×
3013
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3014
      }
3015
      mndReleaseDb(pMnode, pDb);
121,132✔
3016
    } else {
3017
      while (1) {
5,457✔
3018
        SDbObj *pDb = NULL;
8,724✔
3019
        pIter = sdbFetch(pSdb, SDB_DB, pIter, (void **)&pDb);
8,724✔
3020
        if (pIter == NULL) break;
8,724✔
3021
        int32_t len = strlen(pDb->name) + 1;
5,457✔
3022
        if ((code = taosHashPut(pNewUser->writeDbs, pDb->name, len, pDb->name, TSDB_DB_FNAME_LEN)) != 0) {
5,457✔
3023
          sdbRelease(pSdb, pDb);
×
3024
          sdbCancelFetch(pSdb, pIter);
×
3025
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3026
        }
3027
        sdbRelease(pSdb, pDb);
5,457✔
3028
      }
3029
    }
3030
  }
3031

3032
  if (ALTER_USER_DEL_READ_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
892,711✔
3033
      ALTER_USER_DEL_ALL_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
777,573✔
3034
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
115,138✔
3035
      int32_t len = strlen(pAlterReq->objname) + 1;
111,509✔
3036
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
111,509✔
3037
      if (pDb == NULL) {
111,509✔
3038
        mndReleaseDb(pMnode, pDb);
362✔
3039
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
362✔
3040
      }
3041
      code = taosHashRemove(pNewUser->readDbs, pAlterReq->objname, len);
111,147✔
3042
      if (code < 0) {
111,147✔
3043
        mError("read db:%s, failed to remove db:%s since %s", pNewUser->user, pAlterReq->objname, terrstr());
×
3044
      }
3045
      mndReleaseDb(pMnode, pDb);
111,147✔
3046
    } else {
3047
      taosHashClear(pNewUser->readDbs);
3,629✔
3048
    }
3049
  }
3050

3051
  if (ALTER_USER_DEL_WRITE_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
892,349✔
3052
      ALTER_USER_DEL_ALL_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
777,524✔
3053
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
114,825✔
3054
      int32_t len = strlen(pAlterReq->objname) + 1;
110,834✔
3055
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
110,834✔
3056
      if (pDb == NULL) {
110,834✔
3057
        mndReleaseDb(pMnode, pDb);
×
3058
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
×
3059
      }
3060
      code = taosHashRemove(pNewUser->writeDbs, pAlterReq->objname, len);
110,834✔
3061
      if (code < 0) {
110,834✔
3062
        mError("user:%s, failed to remove db:%s since %s", pNewUser->user, pAlterReq->objname, terrstr());
×
3063
      }
3064
      mndReleaseDb(pMnode, pDb);
110,834✔
3065
    } else {
3066
      taosHashClear(pNewUser->writeDbs);
3,991✔
3067
    }
3068
  }
3069

3070
  SHashObj *pReadTbs = pNewUser->readTbs;
892,349✔
3071
  SHashObj *pWriteTbs = pNewUser->writeTbs;
892,349✔
3072
  SHashObj *pAlterTbs = pNewUser->alterTbs;
892,349✔
3073

3074
#ifdef TD_ENTERPRISE
3075
  if (pAlterReq->isView) {
892,349✔
3076
    pReadTbs = pNewUser->readViews;
14,358✔
3077
    pWriteTbs = pNewUser->writeViews;
14,358✔
3078
    pAlterTbs = pNewUser->alterViews;
14,358✔
3079
  }
3080
#endif
3081

3082
  if (ALTER_USER_ADD_READ_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
892,349✔
3083
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
713,076✔
3084
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pReadTbs, pNewUser->useDbs, pAlterReq, pSdb), &lino, _OVER);
179,273✔
3085
  }
3086

3087
  if (ALTER_USER_ADD_WRITE_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
892,349✔
3088
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
714,169✔
3089
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pWriteTbs, pNewUser->useDbs, pAlterReq, pSdb), &lino, _OVER);
178,180✔
3090
  }
3091

3092
  if (ALTER_USER_ADD_ALTER_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
892,349✔
3093
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
798,724✔
3094
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pAlterTbs, pNewUser->useDbs, pAlterReq, pSdb), &lino, _OVER);
93,625✔
3095
  }
3096

3097
  if (ALTER_USER_DEL_READ_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
892,349✔
3098
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
726,914✔
3099
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pReadTbs, pNewUser->useDbs, pAlterReq, pSdb), &lino, _OVER);
165,435✔
3100
  }
3101

3102
  if (ALTER_USER_DEL_WRITE_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
892,349✔
3103
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
726,045✔
3104
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pWriteTbs, pNewUser->useDbs, pAlterReq, pSdb), &lino, _OVER);
166,304✔
3105
  }
3106

3107
  if (ALTER_USER_DEL_ALTER_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
892,349✔
3108
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
811,318✔
3109
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pAlterTbs, pNewUser->useDbs, pAlterReq, pSdb), &lino, _OVER);
81,031✔
3110
  }
3111

3112
#ifdef USE_TOPIC
3113
  if (ALTER_USER_ADD_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, pAlterReq->privileges)) {
892,349✔
3114
    int32_t      len = strlen(pAlterReq->objname) + 1;
6,336✔
3115
    SMqTopicObj *pTopic = NULL;
6,336✔
3116
    if ((code = mndAcquireTopic(pMnode, pAlterReq->objname, &pTopic)) != 0) {
6,336✔
3117
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3118
    }
3119
    taosRLockLatch(&pTopic->lock);
6,336✔
3120
    code = taosHashPut(pNewUser->topics, pTopic->name, len, pTopic->name, TSDB_TOPIC_FNAME_LEN);
6,336✔
3121
    taosRUnLockLatch(&pTopic->lock);
6,336✔
3122
    mndReleaseTopic(pMnode, pTopic);
6,336✔
3123
    TAOS_CHECK_GOTO(code, &lino, _OVER);
6,336✔
3124
  }
3125

3126
  if (ALTER_USER_DEL_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, pAlterReq->privileges)) {
892,349✔
3127
    int32_t      len = strlen(pAlterReq->objname) + 1;
4,151✔
3128
    SMqTopicObj *pTopic = NULL;
4,151✔
3129
    if ((code = mndAcquireTopic(pMnode, pAlterReq->objname, &pTopic)) != 0) {
4,151✔
3130
      TAOS_CHECK_GOTO(code, &lino, _OVER);
365✔
3131
    }
3132
    taosRLockLatch(&pTopic->lock);
3,786✔
3133
    code = taosHashRemove(pNewUser->topics, pAlterReq->objname, len);
3,786✔
3134
    if (code < 0) {
3,786✔
3135
      mError("user:%s, failed to remove topic:%s since %s", pNewUser->user, pAlterReq->objname, tstrerror(code));
×
3136
    }
3137
    taosRUnLockLatch(&pTopic->lock);
3,786✔
3138
    mndReleaseTopic(pMnode, pTopic);
3,786✔
3139
  }
3140
#endif
3141
_OVER:
895,960✔
3142
  if (code < 0) {
895,960✔
3143
    mError("user:%s, failed to alter user privileges at line %d since %s", pAlterReq->user, lino, tstrerror(code));
3,976✔
3144
  }
3145
  TAOS_RETURN(code);
895,960✔
3146
}
3147

3148
static int32_t mndProcessAlterUserReq(SRpcMsg *pReq) {
963,371✔
3149
  SMnode       *pMnode = pReq->info.node;
963,371✔
3150
  SSdb         *pSdb = pMnode->pSdb;
963,371✔
3151
  void         *pIter = NULL;
963,371✔
3152
  int32_t       code = 0;
963,371✔
3153
  int32_t       lino = 0;
963,371✔
3154
  SUserObj     *pUser = NULL;
963,371✔
3155
  SUserObj     *pOperUser = NULL;
963,371✔
3156
  SUserObj      newUser = {0};
963,371✔
3157
  SAlterUserReq alterReq = {0};
963,371✔
3158
  int64_t       tss = taosGetTimestampMs();
963,371✔
3159
  TAOS_CHECK_GOTO(tDeserializeSAlterUserReq(pReq->pCont, pReq->contLen, &alterReq), &lino, _OVER);
963,371✔
3160

3161
  mInfo("user:%s, start to alter", alterReq.user);
963,371✔
3162

3163
  if (alterReq.user[0] == 0) {
963,371✔
3164
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
3165
  }
3166

3167
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, alterReq.user, &pUser), &lino, _OVER);
963,371✔
3168

3169
  (void)mndAcquireUser(pMnode, pReq->info.conn.user, &pOperUser);
955,087✔
3170
  if (pOperUser == NULL) {
955,087✔
3171
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_USER_FROM_CONN, &lino, _OVER);
×
3172
  }
3173

3174
  TAOS_CHECK_GOTO(mndCheckAlterUserPrivilege(pOperUser, pUser, &alterReq), &lino, _OVER);
955,087✔
3175
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
935,858✔
3176

3177
  if (alterReq.hasPassword) {
935,858✔
3178
    TAOS_CHECK_GOTO(mndCheckPasswordFmt(alterReq.pass), &lino, _OVER);
14,271✔
3179
    if (newUser.salt[0] == 0) {
14,271✔
3180
      generateSalt(newUser.salt, sizeof(newUser.salt));
732✔
3181
    }
3182
    char pass[TSDB_PASSWORD_LEN] = {0};
14,271✔
3183
    taosEncryptPass_c((uint8_t *)alterReq.pass, strlen(alterReq.pass), pass);
14,271✔
3184
    pass[sizeof(pass) - 1] = 0;
14,271✔
3185
    TAOS_CHECK_GOTO(mndEncryptPass(pass, newUser.salt, &newUser.passEncryptAlgorithm), &lino, _OVER);
14,271✔
3186

3187
    if (newUser.passwordReuseMax > 0 || newUser.passwordReuseTime > 0) {
23,922✔
3188
      for(int32_t i = 0; i < newUser.numOfPasswords; ++i) {
29,888✔
3189
        if (0 == strncmp(newUser.passwords[i].pass, pass, TSDB_PASSWORD_LEN)) {
20,237✔
3190
          TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_PASSWORD_REUSE, &lino, _OVER);
366✔
3191
        }
3192
      }
3193
      SUserPassword *passwords = taosMemoryCalloc(newUser.numOfPasswords + 1, sizeof(SUserPassword));
9,651✔
3194
      if (passwords == NULL) {
9,651✔
3195
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3196
      }
3197
      memcpy(passwords + 1, newUser.passwords, newUser.numOfPasswords * sizeof(SUserPassword));
9,651✔
3198
      memcpy(passwords[0].pass, pass, TSDB_PASSWORD_LEN);
9,651✔
3199
      passwords[0].setTime = taosGetTimestampSec();
9,651✔
3200
      taosMemoryFree(newUser.passwords);
9,651✔
3201
      newUser.passwords = passwords;
9,651✔
3202
      ++newUser.numOfPasswords;
9,651✔
3203
      ++newUser.passVersion;
9,651✔
3204
      if (strcmp(newUser.user, pOperUser->user) == 0) {
9,651✔
3205
        // if user change own password, set changePass to 2 so that user won't be
3206
        // forced to change password at next login
3207
        newUser.changePass = 2;
6,366✔
3208
      }
3209
    } else if (0 != strncmp(newUser.passwords[0].pass, pass, TSDB_PASSWORD_LEN)) {
4,254✔
3210
      memcpy(newUser.passwords[0].pass, pass, TSDB_PASSWORD_LEN);
2,902✔
3211
      newUser.passwords[0].setTime = taosGetTimestampSec();
2,902✔
3212
      ++newUser.passVersion;
2,902✔
3213
      if (strcmp(newUser.user, pOperUser->user) == 0) {
2,902✔
3214
        newUser.changePass = 2;
362✔
3215
      }
3216
    }
3217
  }
3218

3219
  if (alterReq.hasTotpseed) {
935,492✔
3220
    if (alterReq.totpseed[0] == 0) { // clear totp secret
×
3221
      memset(newUser.totpsecret, 0, sizeof(newUser.totpsecret));
×
3222
    } else if (taosGenerateTotpSecret(alterReq.totpseed, 0, newUser.totpsecret, sizeof(newUser.totpsecret)) < 0) {
×
3223
      TAOS_CHECK_GOTO(TSDB_CODE_PAR_INVALID_OPTION_VALUE, &lino, _OVER);
×
3224
    }
3225
  }
3226

3227
  if (alterReq.hasEnable) {
935,492✔
3228
    newUser.enable = alterReq.enable; // lock or unlock user manually
2,445✔
3229
    if (newUser.enable) {
2,445✔
3230
      // reset login info to allow login immediately
3231
      userCacheResetLoginInfo(newUser.user);
1,355✔
3232
    }
3233
  }
3234

3235
  if (alterReq.hasSysinfo) newUser.sysInfo = alterReq.sysinfo;
935,492✔
3236
  if (alterReq.hasCreatedb) newUser.createdb = alterReq.createdb;
935,492✔
3237
  if (alterReq.hasChangepass) newUser.changePass = alterReq.changepass;
935,492✔
3238
  if (alterReq.hasSessionPerUser) newUser.sessionPerUser = alterReq.sessionPerUser;
935,492✔
3239
  if (alterReq.hasConnectTime) newUser.connectTime = alterReq.connectTime;
935,492✔
3240
  if (alterReq.hasConnectIdleTime) newUser.connectIdleTime = alterReq.connectIdleTime;
935,492✔
3241
  if (alterReq.hasCallPerSession) newUser.callPerSession = alterReq.callPerSession;
935,492✔
3242
  if (alterReq.hasVnodePerCall) newUser.vnodePerCall = alterReq.vnodePerCall;
935,492✔
3243
  if (alterReq.hasFailedLoginAttempts) newUser.failedLoginAttempts = alterReq.failedLoginAttempts;
935,492✔
3244
  if (alterReq.hasPasswordLifeTime) newUser.passwordLifeTime = alterReq.passwordLifeTime;
935,492✔
3245
  if (alterReq.hasPasswordReuseTime) newUser.passwordReuseTime = alterReq.passwordReuseTime;
935,492✔
3246
  if (alterReq.hasPasswordReuseMax) newUser.passwordReuseMax = alterReq.passwordReuseMax;
935,492✔
3247
  if (alterReq.hasPasswordLockTime) newUser.passwordLockTime = alterReq.passwordLockTime;
935,492✔
3248
  if (alterReq.hasPasswordGraceTime) newUser.passwordGraceTime = alterReq.passwordGraceTime;
935,492✔
3249
  if (alterReq.hasInactiveAccountTime) newUser.inactiveAccountTime = alterReq.inactiveAccountTime;
935,492✔
3250
  if (alterReq.hasAllowTokenNum) newUser.allowTokenNum = alterReq.allowTokenNum;
935,492✔
3251

3252

3253
  if (alterReq.numDropIpRanges > 0 || alterReq.numIpRanges > 0) {
935,492✔
3254
    int32_t dummy = 0;
730✔
3255

3256
    // put previous ip whitelist into hash table
3257
    SHashObj *m = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
730✔
3258
    if (m == NULL) {
730✔
3259
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3260
    }
3261

3262
    for (int32_t i = 0; i < newUser.pIpWhiteListDual->num; i++) {
2,555✔
3263
      SIpRange range;
1,825✔
3264
      copyIpRange(&range, newUser.pIpWhiteListDual->pIpRanges + i);
1,825✔
3265
      code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
1,825✔
3266
      if (code != 0) {
1,825✔
3267
        taosHashCleanup(m);
×
3268
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3269
      }
3270
    }
3271

3272
    if (alterReq.numDropIpRanges > 0) {
730✔
3273
      for (int32_t i = 0; i < alterReq.numDropIpRanges; i++) {
730✔
3274
        if (taosHashGetSize(m) == 0) {
365✔
3275
          break;
×
3276
        }
3277

3278
        SIpRange range;
365✔
3279
        copyIpRange(&range, alterReq.pDropIpRanges + i);
365✔
3280

3281
        // for white list, drop default ip ranges is allowed, otherwise, we can never
3282
        // convert white list to black list.
3283

3284
        code = taosHashRemove(m, &range, sizeof(range));
365✔
3285
        if (code == TSDB_CODE_NOT_FOUND) {
365✔
3286
          // treat not exist as success
3287
          code = 0;
365✔
3288
        }
3289
        if (code != 0) {
365✔
3290
          taosHashCleanup(m);
×
3291
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3292
        }
3293
      }
3294
    }
3295

3296
    if (alterReq.numIpRanges > 0) {
730✔
3297
      for (int32_t i = 0; i < alterReq.numIpRanges; i++) {
730✔
3298
        SIpRange range;
365✔
3299
        copyIpRange(&range, alterReq.pIpRanges + i);
365✔
3300
        code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
365✔
3301
        if (code != 0) {
365✔
3302
          taosHashCleanup(m);
×
3303
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3304
        }
3305
      }
3306
    }
3307

3308
    int32_t numOfRanges = taosHashGetSize(m);
730✔
3309
    if (numOfRanges > MND_MAX_USER_IP_RANGE) {
730✔
3310
      taosHashCleanup(m);
×
3311
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_IP_RANGE, &lino, _OVER);
×
3312
    }
3313

3314
    SIpWhiteListDual *p = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + numOfRanges * sizeof(SIpRange));
730✔
3315
    if (p == NULL) {
730✔
3316
      taosHashCleanup(m);
×
3317
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3318
    }
3319

3320
    void *pIter = taosHashIterate(m, NULL);
730✔
3321
    int32_t i = 0;
730✔
3322
    while (pIter) {
2,920✔
3323
      size_t len = 0;
2,190✔
3324
      SIpRange *key = taosHashGetKey(pIter, &len);
2,190✔
3325
      memcpy(p->pIpRanges + i, key, sizeof(SIpRange));
2,190✔
3326
      pIter = taosHashIterate(m, pIter);
2,190✔
3327
      i++;
2,190✔
3328
    }
3329

3330
    taosHashCleanup(m);
730✔
3331
    p->num = numOfRanges;
730✔
3332
    taosMemoryFreeClear(newUser.pIpWhiteListDual);
730✔
3333
    sortIpWhiteList(p);
730✔
3334
    newUser.pIpWhiteListDual = p;
730✔
3335

3336
    newUser.ipWhiteListVer++;
730✔
3337
  }
3338

3339

3340
  if (alterReq.numTimeRanges > 0 || alterReq.numDropTimeRanges) {
935,492✔
3341
    int32_t dummy = 0;
×
3342

3343
    // put previous ip whitelist into hash table
3344
    SHashObj *m = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
×
3345
    if (m == NULL) {
×
3346
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3347
    }
3348

3349
    for (int32_t i = 0; i < newUser.pTimeWhiteList->num; i++) {
×
3350
      SDateTimeWhiteListItem *range = &newUser.pTimeWhiteList->ranges[i];
×
3351
      if (isDateTimeWhiteListItemExpired(range)) {
×
3352
        continue;
×
3353
      }
3354
      code = taosHashPut(m, range, sizeof(*range), &dummy, sizeof(dummy));
×
3355
      if (code != 0) {
×
3356
        taosHashCleanup(m);
×
3357
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3358
      }
3359
    }
3360

3361
    if (alterReq.numDropTimeRanges > 0) {
×
3362
      for (int32_t i = 0; i < alterReq.numDropTimeRanges; i++) {
×
3363
        if (taosHashGetSize(m) == 0) {
×
3364
          break;
×
3365
        }
3366
        SDateTimeWhiteListItem range = { 0 };
×
3367
        DateTimeRangeToWhiteListItem(&range, alterReq.pDropTimeRanges + i);
×
3368

3369
        code = taosHashRemove(m, &range, sizeof(range));
×
3370
        if (code == TSDB_CODE_NOT_FOUND) {
×
3371
          // treat not exist as success
3372
          code = 0;
×
3373
        }
3374
        if (code != 0) {
×
3375
          taosHashCleanup(m);
×
3376
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3377
        }
3378
      }
3379
    }
3380

3381
    if (alterReq.numTimeRanges > 0) {
×
3382
      for (int32_t i = 0; i < alterReq.numTimeRanges; i++) {
×
3383
        SDateTimeWhiteListItem range = { 0 };
×
3384
        DateTimeRangeToWhiteListItem(&range, alterReq.pTimeRanges + i);
×
3385
        if (isDateTimeWhiteListItemExpired(&range)) {
×
3386
          continue;
×
3387
        }
3388
        code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
×
3389
        if (code != 0) {
×
3390
          taosHashCleanup(m);
×
3391
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3392
        }
3393
      }
3394
    }
3395

3396
    int32_t numOfRanges = taosHashGetSize(m);
×
3397
    if (numOfRanges > MND_MAX_USER_TIME_RANGE) {
×
3398
      taosHashCleanup(m);
×
3399
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_TIME_RANGE, &lino, _OVER);
×
3400
    }
3401

3402
    SDateTimeWhiteList *p = taosMemoryCalloc(1, sizeof(SDateTimeWhiteList) + numOfRanges * sizeof(SDateTimeWhiteListItem));
×
3403
    if (p == NULL) {
×
3404
      taosHashCleanup(m);
×
3405
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3406
    }
3407

3408
    void *pIter = taosHashIterate(m, NULL);
×
3409
    int32_t i = 0;
×
3410
    while (pIter) {
×
3411
      size_t len = 0;
×
3412
      SDateTimeWhiteListItem *key = taosHashGetKey(pIter, &len);
×
3413
      memcpy(&p->ranges[i], key, sizeof(SDateTimeWhiteListItem));
×
3414
      pIter = taosHashIterate(m, pIter);
×
3415
      i++;
×
3416
    }
3417

3418
    taosHashCleanup(m);
×
3419
    p->num = numOfRanges;
×
3420
    taosMemoryFreeClear(newUser.pTimeWhiteList);
×
3421
    sortTimeWhiteList(p);
×
3422
    newUser.pTimeWhiteList = p;
×
3423
    newUser.timeWhiteListVer++;
×
3424
  }
3425

3426

3427
  if (ALTER_USER_ADD_PRIVS(alterReq.alterType) || ALTER_USER_DEL_PRIVS(alterReq.alterType)) {
935,492✔
3428
    TAOS_CHECK_GOTO(mndProcessAlterUserPrivilegesReq(&alterReq, pMnode, &newUser), &lino, _OVER);
895,960✔
3429
  }
3430

3431
  code = mndAlterUser(pMnode, pUser, &newUser, pReq);
931,516✔
3432
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
931,516✔
3433

3434
#if 0
3435
  if (alterReq.passIsMd5 == 0) {
3436
    if (TSDB_ALTER_USER_PASSWD == alterReq.alterType) {
3437
      code = mndCheckPasswordFmt(alterReq.pass, len);
3438
      TAOS_CHECK_GOTO(code, &lino, _OVER);
3439
    }
3440
  }
3441

3442
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, alterReq.user, &pUser), &lino, _OVER);
3443

3444
  (void)mndAcquireUser(pMnode, pReq->info.conn.user, &pOperUser);
3445
  if (pOperUser == NULL) {
3446
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_USER_FROM_CONN, &lino, _OVER);
3447
  }
3448

3449
  TAOS_CHECK_GOTO(mndCheckAlterUserPrivilege(pOperUser, pUser, &alterReq), &lino, _OVER);
3450

3451
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
3452

3453
  if (alterReq.alterType == TSDB_ALTER_USER_PASSWD) {
3454
    if (alterReq.passIsMd5 == 1) {
3455
      (void)memcpy(newUser.pass, alterReq.pass, TSDB_PASSWORD_LEN);
3456
    } else {
3457
      taosEncryptPass_c((uint8_t *)alterReq.pass, strlen(alterReq.pass), newUser.pass);
3458
    }
3459

3460
    TAOS_CHECK_GOTO(mndEncryptPass(newUser.pass, &newUser.passEncryptAlgorithm), &lino, _OVER);
3461

3462
    if (0 != strncmp(pUser->pass, newUser.pass, TSDB_PASSWORD_LEN)) {
3463
      ++newUser.passVersion;
3464
    }
3465
  }
3466

3467
  if (alterReq.alterType == TSDB_ALTER_USER_SUPERUSER) {
3468
    newUser.superUser = alterReq.superUser;
3469
  }
3470

3471
  if (alterReq.alterType == TSDB_ALTER_USER_ENABLE) {
3472
    newUser.enable = alterReq.enable;
3473
  }
3474

3475
  if (alterReq.alterType == TSDB_ALTER_USER_SYSINFO) {
3476
    newUser.sysInfo = alterReq.sysInfo;
3477
  }
3478

3479
  if (alterReq.alterType == TSDB_ALTER_USER_CREATEDB) {
3480
    newUser.createdb = alterReq.createdb;
3481
  }
3482

3483
   
3484

3485
  if (ALTER_USER_ADD_PRIVS(alterReq.alterType) || ALTER_USER_DEL_PRIVS(alterReq.alterType)) {
3486
    TAOS_CHECK_GOTO(mndProcessAlterUserPrivilegesReq(&alterReq, pMnode, &newUser), &lino, _OVER);
3487
  }
3488

3489
  if (alterReq.alterType == TSDB_ALTER_USER_ADD_ALLOWED_HOST) {
3490
    taosMemoryFreeClear(newUser.pIpWhiteListDual);
3491

3492
    int32_t           num = pUser->pIpWhiteListDual->num + alterReq.numIpRanges;
3493
    int32_t           idx = pUser->pIpWhiteListDual->num;
3494
    SIpWhiteListDual *pNew = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + sizeof(SIpRange) * num);
3495

3496
    if (pNew == NULL) {
3497
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
3498
    }
3499

3500
    bool exist = false;
3501
    (void)memcpy(pNew->pIpRanges, pUser->pIpWhiteListDual->pIpRanges, sizeof(SIpRange) * idx);
3502
    for (int i = 0; i < alterReq.numIpRanges; i++) {
3503
      SIpRange range = {0};
3504
      if (alterReq.pIpDualRanges == NULL) {
3505
        range.type = 0;
3506
        memcpy(&range.ipV4, &alterReq.pIpRanges[i], sizeof(SIpV4Range));
3507
      } else {
3508
        memcpy(&range, &alterReq.pIpDualRanges[i], sizeof(SIpRange));
3509
        range = alterReq.pIpDualRanges[i];
3510
      }
3511
      if (!isRangeInIpWhiteList(pUser->pIpWhiteListDual, &range)) {
3512
        // already exist, just ignore;
3513
        (void)memcpy(&pNew->pIpRanges[idx], &range, sizeof(SIpRange));
3514
        idx++;
3515
        continue;
3516
      } else {
3517
        exist = true;
3518
      }
3519
    }
3520
    if (exist) {
3521
      taosMemoryFree(pNew);
3522
      TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_HOST_EXIST, &lino, _OVER);
3523
    }
3524
    pNew->num = idx;
3525
    newUser.pIpWhiteListDual = pNew;
3526
    newUser.ipWhiteListVer = pUser->ipWhiteListVer + 1;
3527

3528
    if (pNew->num > MND_MAX_USER_IP_RANGE) {
3529
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_IP_RANGE, &lino, _OVER);
3530
    }
3531
  }
3532
  if (alterReq.alterType == TSDB_ALTER_USER_DROP_ALLOWED_HOST) {
3533
    taosMemoryFreeClear(newUser.pIpWhiteListDual);
3534

3535
    int32_t           num = pUser->pIpWhiteListDual->num;
3536
    bool              noexist = true;
3537
    bool              localHost = false;
3538
    SIpWhiteListDual *pNew = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + sizeof(SIpRange) * num);
3539

3540
    if (pNew == NULL) {
3541
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
3542
    }
3543

3544
    if (pUser->pIpWhiteListDual->num > 0) {
3545
      int idx = 0;
3546
      for (int i = 0; i < pUser->pIpWhiteListDual->num; i++) {
3547
        SIpRange *oldRange = &pUser->pIpWhiteListDual->pIpRanges[i];
3548

3549
        bool found = false;
3550
        for (int j = 0; j < alterReq.numIpRanges; j++) {
3551
          SIpRange range = {0};
3552
          if (alterReq.pIpDualRanges == NULL) {
3553
            SIpV4Range *trange = &alterReq.pIpRanges[j];
3554
            memcpy(&range.ipV4, trange, sizeof(SIpV4Range));
3555
          } else {
3556
            memcpy(&range, &alterReq.pIpDualRanges[j], sizeof(SIpRange));
3557
          }
3558

3559
          if (isDefaultRange(&range)) {
3560
            localHost = true;
3561
            break;
3562
          }
3563
          if (isIpRangeEqual(oldRange, &range)) {
3564
            found = true;
3565
            break;
3566
          }
3567
        }
3568
        if (localHost) break;
3569

3570
        if (found == false) {
3571
          (void)memcpy(&pNew->pIpRanges[idx], oldRange, sizeof(SIpRange));
3572
          idx++;
3573
        } else {
3574
          noexist = false;
3575
        }
3576
      }
3577
      pNew->num = idx;
3578
      newUser.pIpWhiteListDual = pNew;
3579
      newUser.ipWhiteListVer = pUser->ipWhiteListVer + 1;
3580

3581
    } else {
3582
      pNew->num = 0;
3583
      newUser.pIpWhiteListDual = pNew;
3584
      newUser.ipWhiteListVer = pUser->ipWhiteListVer + 1;
3585
    }
3586

3587
    if (localHost) {
3588
      TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_LOCAL_HOST_NOT_DROP, &lino, _OVER);
3589
    }
3590
    if (noexist) {
3591
      TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_HOST_NOT_EXIST, &lino, _OVER);
3592
    }
3593
  }
3594

3595
  code = mndAlterUser(pMnode, pUser, &newUser, pReq);
3596
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
3597

3598
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
3599
    int64_t tse = taosGetTimestampMs();
3600
    double  duration = (double)(tse - tss);
3601
    duration = duration / 1000;
3602
    if (alterReq.alterType == TSDB_ALTER_USER_PASSWD) {
3603
      char detail[1000] = {0};
3604
      (void)tsnprintf(detail, sizeof(detail),
3605
                      "alterType:%s, enable:%d, superUser:%d, sysInfo:%d, createdb:%d, tabName:%s, password:xxx",
3606
                      mndUserAuditTypeStr(alterReq.alterType), alterReq.enable, alterReq.superUser, alterReq.sysInfo,
3607
                      alterReq.createdb ? 1 : 0, alterReq.tabName);
3608
      auditRecord(pReq, pMnode->clusterId, "alterUser", "", alterReq.user, detail, strlen(detail), duration, 0);
3609
    } else if (alterReq.alterType == TSDB_ALTER_USER_SUPERUSER || alterReq.alterType == TSDB_ALTER_USER_ENABLE ||
3610
               alterReq.alterType == TSDB_ALTER_USER_SYSINFO || alterReq.alterType == TSDB_ALTER_USER_CREATEDB) {
3611
      auditRecord(pReq, pMnode->clusterId, "alterUser", "", alterReq.user, alterReq.sql, alterReq.sqlLen, duration, 0);
3612
    } else if (ALTER_USER_ADD_READ_DB_PRIV(alterReq.alterType, alterReq.privileges, alterReq.tabName) ||
3613
               ALTER_USER_ADD_WRITE_DB_PRIV(alterReq.alterType, alterReq.privileges, alterReq.tabName) ||
3614
               ALTER_USER_ADD_ALL_DB_PRIV(alterReq.alterType, alterReq.privileges, alterReq.tabName) ||
3615
               ALTER_USER_ADD_READ_TB_PRIV(alterReq.alterType, alterReq.privileges, alterReq.tabName) ||
3616
               ALTER_USER_ADD_WRITE_TB_PRIV(alterReq.alterType, alterReq.privileges, alterReq.tabName) ||
3617
               ALTER_USER_ADD_ALL_TB_PRIV(alterReq.alterType, alterReq.privileges, alterReq.tabName)) {
3618
      if (strcmp(alterReq.objname, "1.*") != 0) {
3619
        SName name = {0};
3620
        TAOS_CHECK_GOTO(tNameFromString(&name, alterReq.objname, T_NAME_ACCT | T_NAME_DB), &lino, _OVER);
3621
        auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", name.dbname, alterReq.user, alterReq.sql,
3622
                    alterReq.sqlLen, duration, 0);
3623
      } else {
3624
        auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", "", alterReq.user, alterReq.sql, alterReq.sqlLen,
3625
                    duration, 0);
3626
      }
3627
    } else if (ALTER_USER_ADD_SUBSCRIBE_TOPIC_PRIV(alterReq.alterType, alterReq.privileges)) {
3628
      auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", alterReq.objname, alterReq.user, alterReq.sql,
3629
                  alterReq.sqlLen, duration, 0);
3630
    } else if (ALTER_USER_DEL_SUBSCRIBE_TOPIC_PRIV(alterReq.alterType, alterReq.privileges)) {
3631
      auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", alterReq.objname, alterReq.user, alterReq.sql,
3632
                  alterReq.sqlLen, duration, 0);
3633
    } else {
3634
      if (strcmp(alterReq.objname, "1.*") != 0) {
3635
        SName name = {0};
3636
        TAOS_CHECK_GOTO(tNameFromString(&name, alterReq.objname, T_NAME_ACCT | T_NAME_DB), &lino, _OVER);
3637
        auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", name.dbname, alterReq.user, alterReq.sql,
3638
                    alterReq.sqlLen, duration, 0);
3639
      } else {
3640
        auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", "", alterReq.user, alterReq.sql, alterReq.sqlLen,
3641
                    duration, 0);
3642
      }
3643
    }
3644
  }
3645

3646
#endif
3647

3648
_OVER:
963,371✔
3649
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
963,371✔
3650
    mError("user:%s, failed to alter at line %d since %s", alterReq.user, lino, tstrerror(code));
31,855✔
3651
  }
3652

3653
  tFreeSAlterUserReq(&alterReq);
963,371✔
3654
  mndReleaseUser(pMnode, pOperUser);
963,371✔
3655
  mndReleaseUser(pMnode, pUser);
963,371✔
3656
  mndUserFreeObj(&newUser);
963,371✔
3657
  TAOS_RETURN(code);
963,371✔
3658
}
3659

3660
static int32_t mndDropUser(SMnode *pMnode, SRpcMsg *pReq, SUserObj *pUser) {
61,608✔
3661
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "drop-user");
61,608✔
3662
  if (pTrans == NULL) {
61,608✔
3663
    mError("user:%s, failed to drop since %s", pUser->user, terrstr());
×
3664
    TAOS_RETURN(terrno);
×
3665
  }
3666
  mInfo("trans:%d, used to drop user:%s", pTrans->id, pUser->user);
61,608✔
3667

3668
  SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
61,608✔
3669
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
61,608✔
3670
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
3671
    mndTransDrop(pTrans);
×
3672
    TAOS_RETURN(terrno);
×
3673
  }
3674
  if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED) < 0) {
61,608✔
3675
    mndTransDrop(pTrans);
×
3676
    TAOS_RETURN(terrno);
×
3677
  }
3678

3679
  if (mndTransPrepare(pMnode, pTrans) != 0) {
61,608✔
3680
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
3681
    mndTransDrop(pTrans);
×
3682
    TAOS_RETURN(terrno);
×
3683
  }
3684

3685
  userCacheRemoveUser(pUser->user);
61,608✔
3686

3687
  mndTransDrop(pTrans);
61,608✔
3688
  TAOS_RETURN(0);
61,608✔
3689
}
3690

3691
static int32_t mndProcessDropUserReq(SRpcMsg *pReq) {
61,970✔
3692
  SMnode      *pMnode = pReq->info.node;
61,970✔
3693
  int32_t      code = 0;
61,970✔
3694
  int32_t      lino = 0;
61,970✔
3695
  SUserObj    *pUser = NULL;
61,970✔
3696
  SDropUserReq dropReq = {0};
61,970✔
3697
  int64_t      tss = taosGetTimestampMs();
61,970✔
3698

3699
  TAOS_CHECK_GOTO(tDeserializeSDropUserReq(pReq->pCont, pReq->contLen, &dropReq), &lino, _OVER);
61,970✔
3700

3701
  mInfo("user:%s, start to drop", dropReq.user);
61,970✔
3702
  TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_DROP_USER), &lino, _OVER);
61,970✔
3703

3704
  if (dropReq.user[0] == 0) {
61,970✔
3705
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
3706
  }
3707

3708
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, dropReq.user, &pUser), &lino, _OVER);
61,970✔
3709

3710
  TAOS_CHECK_GOTO(mndDropUser(pMnode, pReq, pUser), &lino, _OVER);
61,608✔
3711
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
61,608✔
3712

3713
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
61,608✔
3714
    int64_t tse = taosGetTimestampMs();
61,608✔
3715
    double  duration = (double)(tse - tss);
61,608✔
3716
    duration = duration / 1000;
61,608✔
3717
    auditRecord(pReq, pMnode->clusterId, "dropUser", "", dropReq.user, dropReq.sql, dropReq.sqlLen, duration, 0);
61,608✔
3718
  }
3719
_OVER:
61,970✔
3720
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
61,970✔
3721
    mError("user:%s, failed to drop at line %d since %s", dropReq.user, lino, tstrerror(code));
362✔
3722
  }
3723

3724
  mndReleaseUser(pMnode, pUser);
61,970✔
3725
  tFreeSDropUserReq(&dropReq);
61,970✔
3726
  TAOS_RETURN(code);
61,970✔
3727
}
3728

3729
static int32_t mndProcessGetUserAuthReq(SRpcMsg *pReq) {
3,779,622✔
3730
  SMnode         *pMnode = pReq->info.node;
3,779,622✔
3731
  int32_t         code = 0;
3,779,622✔
3732
  int32_t         lino = 0;
3,779,622✔
3733
  int32_t         contLen = 0;
3,779,622✔
3734
  void           *pRsp = NULL;
3,779,622✔
3735
  SUserObj       *pUser = NULL;
3,779,622✔
3736
  SGetUserAuthReq authReq = {0};
3,779,622✔
3737
  SGetUserAuthRsp authRsp = {0};
3,779,622✔
3738

3739
  TAOS_CHECK_EXIT(tDeserializeSGetUserAuthReq(pReq->pCont, pReq->contLen, &authReq));
3,779,622✔
3740
  mTrace("user:%s, start to get auth", authReq.user);
3,779,622✔
3741

3742
  TAOS_CHECK_EXIT(mndAcquireUser(pMnode, authReq.user, &pUser));
3,779,622✔
3743

3744
  TAOS_CHECK_EXIT(mndSetUserAuthRsp(pMnode, pUser, &authRsp));
3,778,195✔
3745

3746
  contLen = tSerializeSGetUserAuthRsp(NULL, 0, &authRsp);
3,778,195✔
3747
  if (contLen < 0) {
3,777,988✔
3748
    TAOS_CHECK_EXIT(contLen);
×
3749
  }
3750
  pRsp = rpcMallocCont(contLen);
3,777,988✔
3751
  if (pRsp == NULL) {
3,777,988✔
3752
    TAOS_CHECK_EXIT(terrno);
×
3753
  }
3754

3755
  contLen = tSerializeSGetUserAuthRsp(pRsp, contLen, &authRsp);
3,777,988✔
3756
  if (contLen < 0) {
3,778,195✔
3757
    TAOS_CHECK_EXIT(contLen);
×
3758
  }
3759

3760
_exit:
3,779,622✔
3761
  mndReleaseUser(pMnode, pUser);
3,779,622✔
3762
  tFreeSGetUserAuthRsp(&authRsp);
3,779,622✔
3763
  if (code < 0) {
3,779,622✔
3764
    mError("user:%s, failed to get auth at line %d since %s", authReq.user, lino, tstrerror(code));
1,427✔
3765
    rpcFreeCont(pRsp);
1,427✔
3766
    pRsp = NULL;
1,427✔
3767
    contLen = 0;
1,427✔
3768
  }
3769
  pReq->info.rsp = pRsp;
3,779,622✔
3770
  pReq->info.rspLen = contLen;
3,779,622✔
3771
  pReq->code = code;
3,779,622✔
3772

3773
  TAOS_RETURN(code);
3,779,622✔
3774
}
3775

3776

3777
bool mndIsTotpEnabledUser(SUserObj *pUser) {
3,154,629✔
3778
  for (int32_t i = 0; i < sizeof(pUser->totpsecret); i++) {
103,959,118✔
3779
    if (pUser->totpsecret[i] != 0) {
100,792,903✔
3780
      return true;
×
3781
    }
3782
  }
3783
  return false;
3,166,215✔
3784
}
3785

3786

3787
static int32_t mndRetrieveUsers(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
20,610✔
3788
  SMnode   *pMnode = pReq->info.node;
20,610✔
3789
  SSdb     *pSdb = pMnode->pSdb;
20,610✔
3790
  int32_t   code = 0;
20,610✔
3791
  int32_t   lino = 0;
20,610✔
3792
  int32_t   numOfRows = 0;
20,610✔
3793
  SUserObj *pUser = NULL;
20,610✔
3794
  int32_t   cols = 0;
20,610✔
3795
  int8_t    flag = 0;
20,610✔
3796
  char     *pWrite = NULL;
20,610✔
3797
  char     *buf = NULL;
20,610✔
3798
  char     *varstr = NULL;
20,610✔
3799

3800
  while (numOfRows < rows) {
74,799✔
3801
    pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
74,799✔
3802
    if (pShow->pIter == NULL) break;
74,799✔
3803

3804
    cols = 0;
54,189✔
3805
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
54,189✔
3806
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
54,189✔
3807
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
54,189✔
3808
    COL_DATA_SET_VAL_GOTO((const char *)name, false, pUser, pShow->pIter, _exit);
54,189✔
3809

3810
    cols++;
54,189✔
3811
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
54,189✔
3812
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->superUser, false, pUser, pShow->pIter, _exit);
54,189✔
3813

3814
    cols++;
54,189✔
3815
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
54,189✔
3816
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->enable, false, pUser, pShow->pIter, _exit);
54,189✔
3817

3818
    cols++;
54,189✔
3819
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
54,189✔
3820
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sysInfo, false, pUser, pShow->pIter, _exit);
54,189✔
3821

3822
    cols++;
54,189✔
3823
    flag = pUser->createdb ? 1 : 0;
54,189✔
3824
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
54,189✔
3825
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
54,189✔
3826

3827
    cols++;
54,189✔
3828
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
54,189✔
3829
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->createdTime, false, pUser, pShow->pIter, _exit);
54,189✔
3830

3831
    cols++;
54,189✔
3832
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
54,189✔
3833
    flag = mndIsTotpEnabledUser(pUser) ? 1 : 0;
54,189✔
3834
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
54,189✔
3835

3836
    cols++;
54,189✔
3837

3838
    int32_t tlen = convertIpWhiteListToStr(pUser, &buf);
54,189✔
3839
    if (tlen != 0) {
54,189✔
3840
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
54,189✔
3841
      if (varstr == NULL) {
54,189✔
3842
        sdbRelease(pSdb, pUser);
×
3843
        sdbCancelFetch(pSdb, pShow->pIter);
×
3844
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
3845
      }
3846
      varDataSetLen(varstr, tlen);
54,189✔
3847
      (void)memcpy(varDataVal(varstr), buf, tlen);
54,189✔
3848

3849
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
54,189✔
3850
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
54,189✔
3851

3852
      taosMemoryFreeClear(buf);
54,189✔
3853
    } else {
3854
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3855
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
3856
    }
3857

3858
    cols++;
54,189✔
3859
    tlen = convertTimeRangesToStr(pUser, &buf);
54,189✔
3860
    if (tlen != 0) {
54,189✔
3861
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
54,189✔
3862
      if (varstr == NULL) {
54,189✔
3863
        sdbRelease(pSdb, pUser);
×
3864
        sdbCancelFetch(pSdb, pShow->pIter);
×
3865
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
3866
      }
3867
      varDataSetLen(varstr, tlen);
54,189✔
3868
      (void)memcpy(varDataVal(varstr), buf, tlen);
54,189✔
3869

3870
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
54,189✔
3871
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
54,189✔
3872

3873
      taosMemoryFreeClear(buf);
54,189✔
3874
    } else {
3875
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3876
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
3877
    }
3878

3879
    numOfRows++;
54,189✔
3880
    sdbRelease(pSdb, pUser);
54,189✔
3881
  }
3882

3883
  pShow->numOfRows += numOfRows;
20,610✔
3884
_exit:
20,610✔
3885
  taosMemoryFreeClear(buf);
20,610✔
3886
  taosMemoryFreeClear(varstr);
20,610✔
3887
  if (code < 0) {
20,610✔
3888
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
3889
    TAOS_RETURN(code);
×
3890
  }
3891
  return numOfRows;
20,610✔
3892
}
3893

3894
static int32_t mndRetrieveUsersFull(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
×
3895
  int32_t numOfRows = 0;
×
3896
#ifdef TD_ENTERPRISE
3897
  SMnode   *pMnode = pReq->info.node;
×
3898
  SSdb     *pSdb = pMnode->pSdb;
×
3899
  SUserObj *pUser = NULL;
×
3900
  int32_t   code = 0;
×
3901
  int32_t   lino = 0;
×
3902
  int32_t   cols = 0;
×
3903
  int8_t    flag = 0;
×
3904
  char     *pWrite = NULL;
×
3905
  char     *buf = NULL;
×
3906
  char     *varstr = NULL;
×
3907

3908
  while (numOfRows < rows) {
×
3909
    pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
×
3910
    if (pShow->pIter == NULL) break;
×
3911

3912
    cols = 0;
×
3913
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3914
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
×
3915
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
×
3916
    COL_DATA_SET_VAL_GOTO((const char *)name, false, pUser, pShow->pIter, _exit);
×
3917

3918
    cols++;
×
3919
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3920
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->superUser, false, pUser, pShow->pIter, _exit);
×
3921

3922
    cols++;
×
3923
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3924
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->enable, false, pUser, pShow->pIter, _exit);
×
3925

3926
    cols++;
×
3927
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3928
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sysInfo, false, pUser, pShow->pIter, _exit);
×
3929

3930
    cols++;
×
3931
    flag = pUser->createdb ? 1 : 0;
×
3932
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3933
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
×
3934

3935
    cols++;
×
3936
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3937
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->createdTime, false, pUser, pShow->pIter, _exit);
×
3938

3939
    cols++;
×
3940
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3941
    flag = mndIsTotpEnabledUser(pUser) ? 1 : 0;
×
3942
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
×
3943

3944
    cols++;
×
3945
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3946
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->changePass, false, pUser, pShow->pIter, _exit);
×
3947

3948
    cols++;
×
3949
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3950
    char pass[TSDB_PASSWORD_LEN + VARSTR_HEADER_SIZE] = {0};
×
3951
    STR_WITH_MAXSIZE_TO_VARSTR(pass, pUser->passwords[0].pass, pShow->pMeta->pSchemas[cols].bytes);
×
3952
    COL_DATA_SET_VAL_GOTO((const char *)pass, false, pUser, pShow->pIter, _exit);
×
3953

3954
    cols++;
×
3955
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3956
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sessionPerUser, false, pUser, pShow->pIter, _exit);
×
3957

3958
    cols++;
×
3959
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3960
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->connectTime, false, pUser, pShow->pIter, _exit);
×
3961

3962
    cols++;
×
3963
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3964
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->connectIdleTime, false, pUser, pShow->pIter, _exit);
×
3965

3966
    cols++;
×
3967
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3968
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->callPerSession, false, pUser, pShow->pIter, _exit);
×
3969

3970
    /* not supported yet
3971
    cols++;
3972
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
3973
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->vnodePerSession, false, pUser, pShow->pIter, _exit);
3974
*/
3975

3976
    cols++;
×
3977
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3978
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->failedLoginAttempts, false, pUser, pShow->pIter, _exit);
×
3979

3980
    cols++;
×
3981
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3982
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordLifeTime, false, pUser, pShow->pIter, _exit);
×
3983

3984
    cols++;
×
3985
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3986
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordReuseTime, false, pUser, pShow->pIter, _exit);
×
3987

3988
    cols++;
×
3989
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3990
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordReuseMax, false, pUser, pShow->pIter, _exit);
×
3991

3992
    cols++;
×
3993
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3994
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordLockTime, false, pUser, pShow->pIter, _exit);
×
3995

3996
    cols++;
×
3997
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3998
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordGraceTime, false, pUser, pShow->pIter, _exit);
×
3999

4000
    cols++;
×
4001
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4002
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->inactiveAccountTime, false, pUser, pShow->pIter, _exit);
×
4003

4004
    cols++;
×
4005
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4006
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->allowTokenNum, false, pUser, pShow->pIter, _exit);
×
4007

4008
    cols++;
×
4009
    int32_t tlen = convertIpWhiteListToStr(pUser, &buf);
×
4010
    if (tlen != 0) {
×
4011
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
×
4012
      if (varstr == NULL) {
×
4013
        sdbRelease(pSdb, pUser);
×
4014
        sdbCancelFetch(pSdb, pShow->pIter);
×
4015
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
4016
      }
4017
      varDataSetLen(varstr, tlen);
×
4018
      (void)memcpy(varDataVal(varstr), buf, tlen);
×
4019

4020
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4021
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
×
4022

4023
      taosMemoryFreeClear(buf);
×
4024
    } else {
4025
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4026
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
4027
    }
4028

4029
    cols++;
×
4030
    tlen = convertTimeRangesToStr(pUser, &buf);
×
4031
    if (tlen != 0) {
×
4032
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
×
4033
      if (varstr == NULL) {
×
4034
        sdbRelease(pSdb, pUser);
×
4035
        sdbCancelFetch(pSdb, pShow->pIter);
×
4036
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
4037
      }
4038
      varDataSetLen(varstr, tlen);
×
4039
      (void)memcpy(varDataVal(varstr), buf, tlen);
×
4040

4041
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4042
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
×
4043

4044
      taosMemoryFreeClear(buf);
×
4045
    } else {
4046
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4047
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
4048
    }
4049

4050
    numOfRows++;
×
4051
    sdbRelease(pSdb, pUser);
×
4052
  }
4053

4054
  pShow->numOfRows += numOfRows;
×
4055
_exit:
×
4056
  taosMemoryFreeClear(buf);
×
4057
  taosMemoryFreeClear(varstr);
×
4058
  if (code < 0) {
×
4059
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4060
    TAOS_RETURN(code);
×
4061
  }
4062
#endif
4063
  return numOfRows;
×
4064
}
4065

4066
static void mndCancelGetNextUser(SMnode *pMnode, void *pIter) {
×
4067
  SSdb *pSdb = pMnode->pSdb;
×
4068
  sdbCancelFetchByType(pSdb, pIter, SDB_USER);
×
4069
}
×
4070

4071
static int32_t mndLoopHash(SHashObj *hash, char *priType, SSDataBlock *pBlock, int32_t *pNumOfRows, SSdb *pSdb,
625,038✔
4072
                           SUserObj *pUser, SShowObj *pShow, char **condition, char **sql) {
4073
  char   *value = taosHashIterate(hash, NULL);
625,038✔
4074
  char   *user = pUser->user;
625,038✔
4075
  int32_t code = 0;
625,038✔
4076
  int32_t lino = 0;
625,038✔
4077
  int32_t cols = 0;
625,038✔
4078
  int32_t numOfRows = *pNumOfRows;
625,038✔
4079

4080
  while (value != NULL) {
711,405✔
4081
    cols = 0;
86,367✔
4082
    char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
86,367✔
4083
    STR_WITH_MAXSIZE_TO_VARSTR(userName, user, pShow->pMeta->pSchemas[cols].bytes);
86,367✔
4084
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
86,367✔
4085
    COL_DATA_SET_VAL_GOTO((const char *)userName, false, NULL, NULL, _exit);
86,367✔
4086

4087
    char privilege[20] = {0};
86,367✔
4088
    STR_WITH_MAXSIZE_TO_VARSTR(privilege, priType, pShow->pMeta->pSchemas[cols].bytes);
86,367✔
4089
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
86,367✔
4090
    COL_DATA_SET_VAL_GOTO((const char *)privilege, false, NULL, NULL, _exit);
86,367✔
4091

4092
    size_t keyLen = 0;
86,367✔
4093
    void  *key = taosHashGetKey(value, &keyLen);
86,367✔
4094

4095
    char dbName[TSDB_DB_NAME_LEN] = {0};
86,367✔
4096
    (void)mndExtractShortDbNameFromStbFullName(key, dbName);
86,367✔
4097
    char dbNameContent[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
86,367✔
4098
    STR_WITH_MAXSIZE_TO_VARSTR(dbNameContent, dbName, pShow->pMeta->pSchemas[cols].bytes);
86,367✔
4099
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
86,367✔
4100
    COL_DATA_SET_VAL_GOTO((const char *)dbNameContent, false, NULL, NULL, _exit);
86,367✔
4101

4102
    char tableName[TSDB_TABLE_NAME_LEN] = {0};
86,367✔
4103
    mndExtractTbNameFromStbFullName(key, tableName, TSDB_TABLE_NAME_LEN);
86,367✔
4104
    char tableNameContent[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
86,367✔
4105
    STR_WITH_MAXSIZE_TO_VARSTR(tableNameContent, tableName, pShow->pMeta->pSchemas[cols].bytes);
86,367✔
4106
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
86,367✔
4107
    COL_DATA_SET_VAL_GOTO((const char *)tableNameContent, false, NULL, NULL, _exit);
86,367✔
4108

4109
    if (strcmp("t", value) != 0 && strcmp("v", value) != 0) {
146,145✔
4110
      SNode  *pAst = NULL;
59,778✔
4111
      int32_t sqlLen = 0;
59,778✔
4112
      size_t  bufSz = strlen(value) + 1;
59,778✔
4113
      if (bufSz < 6) bufSz = 6;
59,778✔
4114
      TAOS_MEMORY_REALLOC(*sql, bufSz);
59,778✔
4115
      if (*sql == NULL) {
59,778✔
4116
        code = terrno;
×
4117
        goto _exit;
×
4118
      }
4119
      TAOS_MEMORY_REALLOC(*condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
59,778✔
4120
      if ((*condition) == NULL) {
59,778✔
4121
        code = terrno;
×
4122
        goto _exit;
×
4123
      }
4124

4125
      if (nodesStringToNode(value, &pAst) == 0) {
59,778✔
4126
        if (nodesNodeToSQLFormat(pAst, *sql, bufSz, &sqlLen, true) != 0) {
59,778✔
4127
          sqlLen = tsnprintf(*sql, bufSz, "error");
×
4128
        }
4129
        nodesDestroyNode(pAst);
59,778✔
4130
      }
4131

4132
      if (sqlLen == 0) {
59,778✔
4133
        sqlLen = tsnprintf(*sql, bufSz, "error");
×
4134
      }
4135

4136
      STR_WITH_MAXSIZE_TO_VARSTR((*condition), (*sql), pShow->pMeta->pSchemas[cols].bytes);
59,778✔
4137

4138
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
59,778✔
4139
      COL_DATA_SET_VAL_GOTO((const char *)(*condition), false, NULL, NULL, _exit);
59,778✔
4140

4141
      char notes[2] = {0};
59,778✔
4142
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
59,778✔
4143
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
59,778✔
4144
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, NULL, NULL, _exit);
59,778✔
4145
    } else {
4146
      TAOS_MEMORY_REALLOC(*condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
26,589✔
4147
      if ((*condition) == NULL) {
26,589✔
4148
        code = terrno;
×
4149
        goto _exit;
×
4150
      }
4151
      STR_WITH_MAXSIZE_TO_VARSTR((*condition), "", pShow->pMeta->pSchemas[cols].bytes);
26,589✔
4152
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
26,589✔
4153
      COL_DATA_SET_VAL_GOTO((const char *)(*condition), false, NULL, NULL, _exit);
26,589✔
4154

4155
      char notes[64 + VARSTR_HEADER_SIZE] = {0};
26,589✔
4156
      STR_WITH_MAXSIZE_TO_VARSTR(notes, value[0] == 'v' ? "view" : "", sizeof(notes));
26,589✔
4157
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
26,589✔
4158
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, NULL, NULL, _exit);
26,589✔
4159
    }
4160

4161
    numOfRows++;
86,367✔
4162
    value = taosHashIterate(hash, value);
86,367✔
4163
  }
4164
  *pNumOfRows = numOfRows;
625,038✔
4165
_exit:
625,038✔
4166
  if (code < 0) {
625,038✔
4167
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4168
    sdbRelease(pSdb, pUser);
×
4169
    sdbCancelFetch(pSdb, pShow->pIter);
×
4170
  }
4171
  TAOS_RETURN(code);
625,038✔
4172
}
4173

4174
static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
20,525✔
4175
  int32_t   code = 0;
20,525✔
4176
  int32_t   lino = 0;
20,525✔
4177
  SMnode   *pMnode = pReq->info.node;
20,525✔
4178
  SSdb     *pSdb = pMnode->pSdb;
20,525✔
4179
  int32_t   numOfRows = 0;
20,525✔
4180
  SUserObj *pUser = NULL;
20,525✔
4181
  int32_t   cols = 0;
20,525✔
4182
  char     *pWrite = NULL;
20,525✔
4183
  char     *condition = NULL;
20,525✔
4184
  char     *sql = NULL;
20,525✔
4185

4186
  bool fetchNextUser = pShow->restore ? false : true;
20,525✔
4187
  pShow->restore = false;
20,525✔
4188

4189
  while (numOfRows < rows) {
124,698✔
4190
    if (fetchNextUser) {
124,698✔
4191
      pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
124,698✔
4192
      if (pShow->pIter == NULL) break;
124,698✔
4193
    } else {
4194
      fetchNextUser = true;
×
4195
      void *pKey = taosHashGetKey(pShow->pIter, NULL);
×
4196
      pUser = sdbAcquire(pSdb, SDB_USER, pKey);
×
4197
      if (!pUser) {
×
4198
        continue;
×
4199
      }
4200
    }
4201

4202
    int32_t numOfReadDbs = taosHashGetSize(pUser->readDbs);
104,173✔
4203
    int32_t numOfWriteDbs = taosHashGetSize(pUser->writeDbs);
104,173✔
4204
    int32_t numOfTopics = taosHashGetSize(pUser->topics);
104,173✔
4205
    int32_t numOfReadTbs = taosHashGetSize(pUser->readTbs);
104,173✔
4206
    int32_t numOfWriteTbs = taosHashGetSize(pUser->writeTbs);
104,173✔
4207
    int32_t numOfAlterTbs = taosHashGetSize(pUser->alterTbs);
104,173✔
4208
    int32_t numOfReadViews = taosHashGetSize(pUser->readViews);
104,173✔
4209
    int32_t numOfWriteViews = taosHashGetSize(pUser->writeViews);
104,173✔
4210
    int32_t numOfAlterViews = taosHashGetSize(pUser->alterViews);
104,173✔
4211
    if (numOfRows + numOfReadDbs + numOfWriteDbs + numOfTopics + numOfReadTbs + numOfWriteTbs + numOfAlterTbs +
104,173✔
4212
            numOfReadViews + numOfWriteViews + numOfAlterViews >=
104,173✔
4213
        rows) {
4214
      mInfo(
×
4215
          "will restore. current num of rows: %d, read dbs %d, write dbs %d, topics %d, read tables %d, write tables "
4216
          "%d, alter tables %d, read views %d, write views %d, alter views %d",
4217
          numOfRows, numOfReadDbs, numOfWriteDbs, numOfTopics, numOfReadTbs, numOfWriteTbs, numOfAlterTbs,
4218
          numOfReadViews, numOfWriteViews, numOfAlterViews);
4219
      pShow->restore = true;
×
4220
      sdbRelease(pSdb, pUser);
×
4221
      break;
×
4222
    }
4223

4224
    if (pUser->superUser) {
104,173✔
4225
      cols = 0;
20,525✔
4226
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
20,525✔
4227
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
20,525✔
4228
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
20,525✔
4229
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
20,525✔
4230

4231
      char privilege[20] = {0};
20,525✔
4232
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "all", pShow->pMeta->pSchemas[cols].bytes);
20,525✔
4233
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
20,525✔
4234
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
20,525✔
4235

4236
      char objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
20,525✔
4237
      STR_WITH_MAXSIZE_TO_VARSTR(objName, "all", pShow->pMeta->pSchemas[cols].bytes);
20,525✔
4238
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
20,525✔
4239
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
20,525✔
4240

4241
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
20,525✔
4242
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
20,525✔
4243
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
20,525✔
4244
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
20,525✔
4245

4246
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
20,525✔
4247
      if (condition == NULL) {
20,525✔
4248
        sdbRelease(pSdb, pUser);
×
4249
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
4250
      }
4251
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
20,525✔
4252
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
20,525✔
4253
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
20,525✔
4254

4255
      char notes[2] = {0};
20,525✔
4256
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
20,525✔
4257
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
20,525✔
4258
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
20,525✔
4259

4260
      numOfRows++;
20,525✔
4261
    }
4262

4263
    char *db = taosHashIterate(pUser->readDbs, NULL);
104,173✔
4264
    while (db != NULL) {
123,925✔
4265
      cols = 0;
19,752✔
4266
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
19,752✔
4267
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
19,752✔
4268
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19,752✔
4269
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
19,752✔
4270

4271
      char privilege[20] = {0};
19,752✔
4272
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "read", pShow->pMeta->pSchemas[cols].bytes);
19,752✔
4273
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19,752✔
4274
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
19,752✔
4275

4276
      SName name = {0};
19,752✔
4277
      char  objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
19,752✔
4278
      code = tNameFromString(&name, db, T_NAME_ACCT | T_NAME_DB);
19,752✔
4279
      if (code < 0) {
19,752✔
4280
        sdbRelease(pSdb, pUser);
×
4281
        sdbCancelFetch(pSdb, pShow->pIter);
×
4282
        TAOS_CHECK_GOTO(code, &lino, _exit);
×
4283
      }
4284
      (void)tNameGetDbName(&name, varDataVal(objName));
19,752✔
4285
      varDataSetLen(objName, strlen(varDataVal(objName)));
19,752✔
4286
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19,752✔
4287
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
19,752✔
4288

4289
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
19,752✔
4290
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
19,752✔
4291
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19,752✔
4292
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
19,752✔
4293

4294
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
19,752✔
4295
      if (condition == NULL) {
19,752✔
4296
        sdbRelease(pSdb, pUser);
×
4297
        sdbCancelFetch(pSdb, pShow->pIter);
×
4298
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
4299
      }
4300
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
19,752✔
4301
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19,752✔
4302
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
19,752✔
4303

4304
      char notes[2] = {0};
19,752✔
4305
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
19,752✔
4306
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19,752✔
4307
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
19,752✔
4308

4309
      numOfRows++;
19,752✔
4310
      db = taosHashIterate(pUser->readDbs, db);
19,752✔
4311
    }
4312

4313
    db = taosHashIterate(pUser->writeDbs, NULL);
104,173✔
4314
    while (db != NULL) {
121,684✔
4315
      cols = 0;
17,511✔
4316
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
17,511✔
4317
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
17,511✔
4318
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
17,511✔
4319
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
17,511✔
4320

4321
      char privilege[20] = {0};
17,511✔
4322
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "write", pShow->pMeta->pSchemas[cols].bytes);
17,511✔
4323
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
17,511✔
4324
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
17,511✔
4325

4326
      SName name = {0};
17,511✔
4327
      char  objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
17,511✔
4328
      code = tNameFromString(&name, db, T_NAME_ACCT | T_NAME_DB);
17,511✔
4329
      if (code < 0) {
17,511✔
4330
        sdbRelease(pSdb, pUser);
×
4331
        sdbCancelFetch(pSdb, pShow->pIter);
×
4332
        TAOS_CHECK_GOTO(code, &lino, _exit);
×
4333
      }
4334
      (void)tNameGetDbName(&name, varDataVal(objName));
17,511✔
4335
      varDataSetLen(objName, strlen(varDataVal(objName)));
17,511✔
4336
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
17,511✔
4337
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
17,511✔
4338

4339
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
17,511✔
4340
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
17,511✔
4341
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
17,511✔
4342
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
17,511✔
4343

4344
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
17,511✔
4345
      if (condition == NULL) {
17,511✔
4346
        sdbRelease(pSdb, pUser);
×
4347
        sdbCancelFetch(pSdb, pShow->pIter);
×
4348
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
4349
      }
4350
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
17,511✔
4351
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
17,511✔
4352
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
17,511✔
4353

4354
      char notes[2] = {0};
17,511✔
4355
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
17,511✔
4356
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
17,511✔
4357
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
17,511✔
4358

4359
      numOfRows++;
17,511✔
4360
      db = taosHashIterate(pUser->writeDbs, db);
17,511✔
4361
    }
4362

4363
    TAOS_CHECK_EXIT(mndLoopHash(pUser->readTbs, "read", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
104,173✔
4364

4365
    TAOS_CHECK_EXIT(mndLoopHash(pUser->writeTbs, "write", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
104,173✔
4366

4367
    TAOS_CHECK_EXIT(mndLoopHash(pUser->alterTbs, "alter", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
104,173✔
4368

4369
    TAOS_CHECK_EXIT(mndLoopHash(pUser->readViews, "read", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
104,173✔
4370

4371
    TAOS_CHECK_EXIT(mndLoopHash(pUser->writeViews, "write", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
104,173✔
4372

4373
    TAOS_CHECK_EXIT(mndLoopHash(pUser->alterViews, "alter", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
104,173✔
4374

4375
    char *topic = taosHashIterate(pUser->topics, NULL);
104,173✔
4376
    while (topic != NULL) {
107,594✔
4377
      cols = 0;
3,421✔
4378
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
3,421✔
4379
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
3,421✔
4380
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
3,421✔
4381
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
3,421✔
4382

4383
      char privilege[20] = {0};
3,421✔
4384
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "subscribe", pShow->pMeta->pSchemas[cols].bytes);
3,421✔
4385
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
3,421✔
4386
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
3,421✔
4387

4388
      char topicName[TSDB_TOPIC_NAME_LEN + VARSTR_HEADER_SIZE + 5] = {0};
3,421✔
4389
      tstrncpy(varDataVal(topicName), mndGetDbStr(topic), TSDB_TOPIC_NAME_LEN - 2);
3,421✔
4390
      varDataSetLen(topicName, strlen(varDataVal(topicName)));
3,421✔
4391
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
3,421✔
4392
      COL_DATA_SET_VAL_GOTO((const char *)topicName, false, pUser, pShow->pIter, _exit);
3,421✔
4393

4394
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
3,421✔
4395
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
3,421✔
4396
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
3,421✔
4397
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
3,421✔
4398

4399
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
3,421✔
4400
      if (condition == NULL) {
3,421✔
4401
        sdbRelease(pSdb, pUser);
×
4402
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
4403
      }
4404
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
3,421✔
4405
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
3,421✔
4406
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
3,421✔
4407

4408
      char notes[2] = {0};
3,421✔
4409
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
3,421✔
4410
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
3,421✔
4411
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
3,421✔
4412

4413
      numOfRows++;
3,421✔
4414
      topic = taosHashIterate(pUser->topics, topic);
3,421✔
4415
    }
4416

4417
    sdbRelease(pSdb, pUser);
104,173✔
4418
  }
4419

4420
  pShow->numOfRows += numOfRows;
20,525✔
4421
_exit:
20,525✔
4422
  taosMemoryFreeClear(condition);
20,525✔
4423
  taosMemoryFreeClear(sql);
20,525✔
4424
  if (code < 0) {
20,525✔
4425
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4426
    TAOS_RETURN(code);
×
4427
  }
4428
  return numOfRows;
20,525✔
4429
}
4430

4431
static void mndCancelGetNextPrivileges(SMnode *pMnode, void *pIter) {
×
4432
  SSdb *pSdb = pMnode->pSdb;
×
4433
  sdbCancelFetchByType(pSdb, pIter, SDB_USER);
×
4434
}
×
4435

4436
int32_t mndValidateUserAuthInfo(SMnode *pMnode, SUserAuthVersion *pUsers, int32_t numOfUses, void **ppRsp,
14,351,475✔
4437
                                int32_t *pRspLen, int64_t ipWhiteListVer) {
4438
  int32_t           code = 0;
14,351,475✔
4439
  int32_t           lino = 0;
14,351,475✔
4440
  int32_t           rspLen = 0;
14,351,917✔
4441
  void             *pRsp = NULL;
14,351,917✔
4442
  SUserAuthBatchRsp batchRsp = {0};
14,351,917✔
4443

4444
  batchRsp.pArray = taosArrayInit(numOfUses, sizeof(SGetUserAuthRsp));
14,351,917✔
4445
  if (batchRsp.pArray == NULL) {
14,351,917✔
4446
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
4447
  }
4448

4449
  for (int32_t i = 0; i < numOfUses; ++i) {
29,049,986✔
4450
    SUserObj *pUser = NULL;
14,698,069✔
4451
    code = mndAcquireUser(pMnode, pUsers[i].user, &pUser);
14,698,069✔
4452
    if (pUser == NULL) {
14,697,565✔
4453
      if (TSDB_CODE_MND_USER_NOT_EXIST == code) {
6,030✔
4454
        SGetUserAuthRsp rsp = {.dropped = 1};
6,030✔
4455
        (void)memcpy(rsp.user, pUsers[i].user, TSDB_USER_LEN);
6,030✔
4456
        TSDB_CHECK_NULL(taosArrayPush(batchRsp.pArray, &rsp), code, lino, _OVER, TSDB_CODE_OUT_OF_MEMORY);
12,060✔
4457
      }
4458
      mError("user:%s, failed to auth user since %s", pUsers[i].user, tstrerror(code));
6,030✔
4459
      code = 0;
6,030✔
4460
      continue;
8,533✔
4461
    }
4462

4463
    pUsers[i].version = ntohl(pUsers[i].version);
14,691,535✔
4464
    if (pUser->authVersion <= pUsers[i].version && ipWhiteListVer == pMnode->ipWhiteVer) {
14,691,535✔
4465
      mndReleaseUser(pMnode, pUser);
13,831,505✔
4466
      continue;
13,831,947✔
4467
    }
4468

4469
    SGetUserAuthRsp rsp = {0};
860,534✔
4470
    code = mndSetUserAuthRsp(pMnode, pUser, &rsp);
860,092✔
4471
    if (code) {
860,092✔
4472
      mndReleaseUser(pMnode, pUser);
×
4473
      tFreeSGetUserAuthRsp(&rsp);
×
4474
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
4475
    }
4476

4477
    if (!(taosArrayPush(batchRsp.pArray, &rsp))) {
1,720,184✔
4478
      code = terrno;
×
4479
      mndReleaseUser(pMnode, pUser);
×
4480
      tFreeSGetUserAuthRsp(&rsp);
×
4481
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
4482
    }
4483
    mndReleaseUser(pMnode, pUser);
860,092✔
4484
  }
4485

4486
  if (taosArrayGetSize(batchRsp.pArray) <= 0) {
14,351,917✔
4487
    *ppRsp = NULL;
13,500,725✔
4488
    *pRspLen = 0;
13,500,725✔
4489

4490
    tFreeSUserAuthBatchRsp(&batchRsp);
13,500,725✔
4491
    return 0;
13,500,725✔
4492
  }
4493

4494
  rspLen = tSerializeSUserAuthBatchRsp(NULL, 0, &batchRsp);
851,192✔
4495
  if (rspLen < 0) {
851,192✔
4496
    TAOS_CHECK_GOTO(rspLen, &lino, _OVER);
×
4497
  }
4498
  pRsp = taosMemoryMalloc(rspLen);
851,192✔
4499
  if (pRsp == NULL) {
851,192✔
4500
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
4501
  }
4502
  rspLen = tSerializeSUserAuthBatchRsp(pRsp, rspLen, &batchRsp);
851,192✔
4503
  if (rspLen < 0) {
851,192✔
4504
    TAOS_CHECK_GOTO(rspLen, &lino, _OVER);
×
4505
  }
4506
_OVER:
851,192✔
4507
  tFreeSUserAuthBatchRsp(&batchRsp);
851,192✔
4508
  if (code < 0) {
851,192✔
4509
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4510
    taosMemoryFreeClear(pRsp);
×
4511
    rspLen = 0;
×
4512
  }
4513
  *ppRsp = pRsp;
851,192✔
4514
  *pRspLen = rspLen;
851,192✔
4515

4516
  TAOS_RETURN(code);
851,192✔
4517
}
4518

4519
static int32_t mndRemoveDbPrivileges(SHashObj *pHash, const char *dbFName, int32_t dbFNameLen, int32_t *nRemoved) {
31,218✔
4520
  void *pVal = NULL;
31,218✔
4521
  while ((pVal = taosHashIterate(pHash, pVal))) {
55,075✔
4522
    size_t keyLen = 0;
23,857✔
4523
    char  *pKey = (char *)taosHashGetKey(pVal, &keyLen);
23,857✔
4524
    if (pKey == NULL || keyLen <= dbFNameLen) continue;
23,857✔
4525
    if ((*(pKey + dbFNameLen) == '.') && strncmp(pKey, dbFName, dbFNameLen) == 0) {
23,857✔
4526
      TAOS_CHECK_RETURN(taosHashRemove(pHash, pKey, keyLen));
12,159✔
4527
      if (nRemoved) ++(*nRemoved);
12,159✔
4528
    }
4529
  }
4530
  TAOS_RETURN(0);
31,218✔
4531
}
4532

4533
int32_t mndUserRemoveDb(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SSHashObj **ppUsers) {
722,941✔
4534
  int32_t    code = 0, lino = 0;
722,941✔
4535
  SSdb      *pSdb = pMnode->pSdb;
722,941✔
4536
  int32_t    dbLen = strlen(pDb->name);
722,941✔
4537
  void      *pIter = NULL;
722,941✔
4538
  SUserObj  *pUser = NULL;
722,941✔
4539
  SUserObj   newUser = {0};
722,941✔
4540
  SSHashObj *pUsers = ppUsers ? *ppUsers : NULL;
722,941✔
4541
  bool       output = (ppUsers != NULL);
722,941✔
4542

4543
  while (1) {
786,998✔
4544
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
1,509,939✔
4545
    if (pIter == NULL) break;
1,509,939✔
4546

4547
    bool update = false;
786,998✔
4548
    bool inReadDb = (taosHashGet(pUser->readDbs, pDb->name, dbLen + 1) != NULL);
786,998✔
4549
    bool inWriteDb = (taosHashGet(pUser->writeDbs, pDb->name, dbLen + 1) != NULL);
786,998✔
4550
    bool inUseDb = (taosHashGet(pUser->useDbs, pDb->name, dbLen + 1) != NULL);
786,998✔
4551
    bool inReadTbs = taosHashGetSize(pUser->readTbs) > 0;
786,998✔
4552
    bool inWriteTbs = taosHashGetSize(pUser->writeTbs) > 0;
786,998✔
4553
    bool inAlterTbs = taosHashGetSize(pUser->alterTbs) > 0;
786,998✔
4554
    bool inReadViews = taosHashGetSize(pUser->readViews) > 0;
786,998✔
4555
    bool inWriteViews = taosHashGetSize(pUser->writeViews) > 0;
786,998✔
4556
    bool inAlterViews = taosHashGetSize(pUser->alterViews) > 0;
786,998✔
4557
    // no need remove pUser->topics since topics must be dropped ahead of db
4558
    if (!inReadDb && !inWriteDb && !inReadTbs && !inWriteTbs && !inAlterTbs && !inReadViews && !inWriteViews &&
786,998✔
4559
        !inAlterViews) {
775,971✔
4560
      sdbRelease(pSdb, pUser);
775,971✔
4561
      continue;
775,971✔
4562
    }
4563
    SUserObj *pTargetUser = &newUser;
11,027✔
4564
    if (output) {
11,027✔
4565
      if (!pUsers) {
1,348✔
4566
        TSDB_CHECK_NULL(pUsers = tSimpleHashInit(32, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY)), code, lino,
674✔
4567
                        _exit, TSDB_CODE_OUT_OF_MEMORY);
4568
        *ppUsers = pUsers;
674✔
4569
      }
4570
      void   *pVal = NULL;
1,348✔
4571
      int32_t userLen = strlen(pUser->user) + 1;
1,348✔
4572
      if ((pVal = tSimpleHashGet(pUsers, pUser->user, userLen)) != NULL) {
1,348✔
4573
        pTargetUser = (SUserObj *)pVal;
674✔
4574
      } else {
4575
        TAOS_CHECK_EXIT(mndUserDupObj(pUser, &newUser));
674✔
4576
        TAOS_CHECK_EXIT(tSimpleHashPut(pUsers, pUser->user, userLen, &newUser, sizeof(SUserObj)));
674✔
4577
        TSDB_CHECK_NULL((pVal = tSimpleHashGet(pUsers, pUser->user, userLen)), code, lino, _exit,
674✔
4578
                        TSDB_CODE_OUT_OF_MEMORY);
4579
        pTargetUser = (SUserObj *)pVal;
674✔
4580
      }
4581
    } else {
4582
      TAOS_CHECK_EXIT(mndUserDupObj(pUser, &newUser));
9,679✔
4583
    }
4584
    if (inReadDb) {
11,027✔
4585
      TAOS_CHECK_EXIT(taosHashRemove(pTargetUser->readDbs, pDb->name, dbLen + 1));
2,699✔
4586
    }
4587
    if (inWriteDb) {
11,027✔
4588
      TAOS_CHECK_EXIT(taosHashRemove(pTargetUser->writeDbs, pDb->name, dbLen + 1));
2,334✔
4589
    }
4590
    if (inUseDb) {
11,027✔
4591
      TAOS_CHECK_EXIT(taosHashRemove(pTargetUser->useDbs, pDb->name, dbLen + 1));
1,713✔
4592
    }
4593
    update = inReadDb || inWriteDb || inUseDb;
11,027✔
4594

4595
    int32_t nRemovedReadTbs = 0;
11,027✔
4596
    int32_t nRemovedWriteTbs = 0;
11,027✔
4597
    int32_t nRemovedAlterTbs = 0;
11,027✔
4598
    if (inReadTbs || inWriteTbs || inAlterTbs) {
11,027✔
4599
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->readTbs, pDb->name, dbLen, &nRemovedReadTbs));
10,041✔
4600
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->writeTbs, pDb->name, dbLen, &nRemovedWriteTbs));
10,041✔
4601
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->alterTbs, pDb->name, dbLen, &nRemovedAlterTbs));
10,041✔
4602
      if (!update) update = nRemovedReadTbs > 0 || nRemovedWriteTbs > 0 || nRemovedAlterTbs > 0;
10,041✔
4603
    }
4604

4605
    int32_t nRemovedReadViews = 0;
11,027✔
4606
    int32_t nRemovedWriteViews = 0;
11,027✔
4607
    int32_t nRemovedAlterViews = 0;
11,027✔
4608
    if (inReadViews || inWriteViews || inAlterViews) {
11,027✔
4609
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->readViews, pDb->name, dbLen, &nRemovedReadViews));
365✔
4610
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->writeViews, pDb->name, dbLen, &nRemovedWriteViews));
365✔
4611
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->alterViews, pDb->name, dbLen, &nRemovedAlterViews));
365✔
4612
      if (!update) update = nRemovedReadViews > 0 || nRemovedWriteViews > 0 || nRemovedAlterViews > 0;
365✔
4613
    }
4614

4615
    if (!output) {
11,027✔
4616
      if (update) {
9,679✔
4617
        SSdbRaw *pCommitRaw = mndUserActionEncode(pTargetUser);
1,351✔
4618
        if (pCommitRaw == NULL) {
1,351✔
4619
          TAOS_CHECK_EXIT(terrno);
×
4620
        }
4621
        TAOS_CHECK_EXIT(mndTransAppendCommitlog(pTrans, pCommitRaw));
1,351✔
4622
        TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
1,351✔
4623
      }
4624
      mndUserFreeObj(&newUser);
9,679✔
4625
    }
4626
    sdbRelease(pSdb, pUser);
11,027✔
4627
  }
4628

4629
_exit:
722,941✔
4630
  if (code < 0) {
722,941✔
4631
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4632
    mndUserFreeObj(&newUser);
×
4633
  }
4634
  if (pUser != NULL) sdbRelease(pSdb, pUser);
722,941✔
4635
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
722,941✔
4636
  if (!output) mndUserFreeObj(&newUser);
722,941✔
4637
  TAOS_RETURN(code);
722,941✔
4638
}
4639

4640
int32_t mndUserRemoveStb(SMnode *pMnode, STrans *pTrans, char *stb) {
511,592✔
4641
  int32_t   code = 0;
511,592✔
4642
  SSdb     *pSdb = pMnode->pSdb;
511,592✔
4643
  int32_t   len = strlen(stb) + 1;
511,592✔
4644
  void     *pIter = NULL;
511,592✔
4645
  SUserObj *pUser = NULL;
511,592✔
4646
  SUserObj  newUser = {0};
511,592✔
4647

4648
  while (1) {
511,592✔
4649
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
1,023,184✔
4650
    if (pIter == NULL) break;
1,023,184✔
4651

4652
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
511,592✔
4653
      break;
×
4654
    }
4655

4656
    bool inRead = (taosHashGet(newUser.readTbs, stb, len) != NULL);
511,592✔
4657
    bool inWrite = (taosHashGet(newUser.writeTbs, stb, len) != NULL);
511,592✔
4658
    bool inAlter = (taosHashGet(newUser.alterTbs, stb, len) != NULL);
511,592✔
4659
    if (inRead || inWrite || inAlter) {
511,592✔
4660
      code = taosHashRemove(newUser.readTbs, stb, len);
×
4661
      if (code < 0) {
×
4662
        mError("failed to remove readTbs:%s from user:%s", stb, pUser->user);
×
4663
      }
4664
      code = taosHashRemove(newUser.writeTbs, stb, len);
×
4665
      if (code < 0) {
×
4666
        mError("failed to remove writeTbs:%s from user:%s", stb, pUser->user);
×
4667
      }
4668
      code = taosHashRemove(newUser.alterTbs, stb, len);
×
4669
      if (code < 0) {
×
4670
        mError("failed to remove alterTbs:%s from user:%s", stb, pUser->user);
×
4671
      }
4672

4673
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
×
4674
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
×
4675
        code = TSDB_CODE_OUT_OF_MEMORY;
×
4676
        break;
×
4677
      }
4678
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
×
4679
      if (code != 0) {
×
4680
        mndUserFreeObj(&newUser);
×
4681
        sdbRelease(pSdb, pUser);
×
4682
        TAOS_RETURN(code);
×
4683
      }
4684
    }
4685

4686
    mndUserFreeObj(&newUser);
511,592✔
4687
    sdbRelease(pSdb, pUser);
511,592✔
4688
  }
4689

4690
  if (pUser != NULL) sdbRelease(pSdb, pUser);
511,592✔
4691
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
511,592✔
4692
  mndUserFreeObj(&newUser);
511,592✔
4693
  TAOS_RETURN(code);
511,592✔
4694
}
4695

4696
int32_t mndUserRemoveView(SMnode *pMnode, STrans *pTrans, char *view) {
184,125✔
4697
  int32_t   code = 0;
184,125✔
4698
  SSdb     *pSdb = pMnode->pSdb;
184,125✔
4699
  int32_t   len = strlen(view) + 1;
184,125✔
4700
  void     *pIter = NULL;
184,125✔
4701
  SUserObj *pUser = NULL;
184,125✔
4702
  SUserObj  newUser = {0};
184,125✔
4703

4704
  while (1) {
191,647✔
4705
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
375,772✔
4706
    if (pIter == NULL) break;
375,772✔
4707

4708
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
191,647✔
4709
      break;
×
4710
    }
4711

4712
    bool inRead = (taosHashGet(newUser.readViews, view, len) != NULL);
191,647✔
4713
    bool inWrite = (taosHashGet(newUser.writeViews, view, len) != NULL);
191,647✔
4714
    bool inAlter = (taosHashGet(newUser.alterViews, view, len) != NULL);
191,647✔
4715
    if (inRead || inWrite || inAlter) {
191,647✔
4716
      code = taosHashRemove(newUser.readViews, view, len);
4,668✔
4717
      if (code < 0) {
4,668✔
4718
        mError("failed to remove readViews:%s from user:%s", view, pUser->user);
926✔
4719
      }
4720
      code = taosHashRemove(newUser.writeViews, view, len);
4,668✔
4721
      if (code < 0) {
4,668✔
4722
        mError("failed to remove writeViews:%s from user:%s", view, pUser->user);
2,353✔
4723
      }
4724
      code = taosHashRemove(newUser.alterViews, view, len);
4,668✔
4725
      if (code < 0) {
4,668✔
4726
        mError("failed to remove alterViews:%s from user:%s", view, pUser->user);
1,427✔
4727
      }
4728

4729
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
4,668✔
4730
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
4,668✔
4731
        code = TSDB_CODE_OUT_OF_MEMORY;
×
4732
        break;
×
4733
      }
4734
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
4,668✔
4735
      if (code < 0) {
4,668✔
4736
        mndUserFreeObj(&newUser);
×
4737
        sdbRelease(pSdb, pUser);
×
4738
        TAOS_RETURN(code);
×
4739
      }
4740
    }
4741

4742
    mndUserFreeObj(&newUser);
191,647✔
4743
    sdbRelease(pSdb, pUser);
191,647✔
4744
  }
4745

4746
  if (pUser != NULL) sdbRelease(pSdb, pUser);
184,125✔
4747
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
184,125✔
4748
  mndUserFreeObj(&newUser);
184,125✔
4749
  TAOS_RETURN(code);
184,125✔
4750
}
4751

4752
int32_t mndUserRemoveTopic(SMnode *pMnode, STrans *pTrans, char *topic) {
34,339✔
4753
  int32_t   code = 0;
34,339✔
4754
  SSdb     *pSdb = pMnode->pSdb;
34,339✔
4755
  int32_t   len = strlen(topic) + 1;
34,339✔
4756
  void     *pIter = NULL;
34,339✔
4757
  SUserObj *pUser = NULL;
34,339✔
4758
  SUserObj  newUser = {0};
34,339✔
4759

4760
  while (1) {
49,489✔
4761
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
83,828✔
4762
    if (pIter == NULL) {
83,828✔
4763
      break;
34,339✔
4764
    }
4765

4766
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
49,489✔
4767
      break;
×
4768
    }
4769

4770
    bool inTopic = (taosHashGet(newUser.topics, topic, len) != NULL);
49,489✔
4771
    if (inTopic) {
49,489✔
4772
      code = taosHashRemove(newUser.topics, topic, len);
365✔
4773
      if (code < 0) {
365✔
4774
        mError("failed to remove topic:%s from user:%s", topic, pUser->user);
×
4775
      }
4776
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
365✔
4777
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
365✔
4778
        code = TSDB_CODE_OUT_OF_MEMORY;
×
4779
        break;
×
4780
      }
4781
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
365✔
4782
      if (code < 0) {
365✔
4783
        mndUserFreeObj(&newUser);
×
4784
        sdbRelease(pSdb, pUser);
×
4785
        TAOS_RETURN(code);
×
4786
      }
4787
    }
4788

4789
    mndUserFreeObj(&newUser);
49,489✔
4790
    sdbRelease(pSdb, pUser);
49,489✔
4791
  }
4792

4793
  if (pUser != NULL) sdbRelease(pSdb, pUser);
34,339✔
4794
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
34,339✔
4795
  mndUserFreeObj(&newUser);
34,339✔
4796
  TAOS_RETURN(code);
34,339✔
4797
}
4798

4799
int64_t mndGetUserIpWhiteListVer(SMnode *pMnode, SUserObj *pUser) {
×
4800
  // ver = 0, disable ip white list
4801
  // ver > 0, enable ip white list
4802
  return tsEnableWhiteList ? pUser->ipWhiteListVer : 0;
×
4803
}
4804

4805
int64_t mndGetUserTimeWhiteListVer(SMnode *pMnode, SUserObj *pUser) {
×
4806
  // ver = 0, disable datetime white list
4807
  // ver > 0, enable datetime white list
4808
  return tsEnableWhiteList ? pUser->timeWhiteListVer : 0;
×
4809
}
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