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

taosdata / TDengine / #4881

14 Dec 2025 03:48AM UTC coverage: 60.617% (+0.5%) from 60.092%
#4881

push

travis-ci

web-flow
test: update coverage workflow time (#33918)

156854 of 258761 relevant lines covered (60.62%)

75258957.81 hits per line

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

72.25
/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() {
228,054✔
158
  _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
228,054✔
159

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

165
  userCache.users = users;
228,054✔
166
  userCache.verIp = 0;
228,054✔
167
  userCache.verTime = 0;
228,054✔
168

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

173

174

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

180
  void *pIter = taosHashIterate(userCache.users, NULL);
228,003✔
181
  while (pIter) {
471,193✔
182
    SCachedUserInfo *pInfo = *(SCachedUserInfo **)pIter;
243,190✔
183
    if (pInfo != NULL) {
243,190✔
184
      taosMemoryFree(pInfo->wlIp);
243,190✔
185
      taosMemoryFree(pInfo->wlTime);
243,190✔
186
      taosMemoryFree(pInfo);
243,190✔
187
    }
188
    pIter = taosHashIterate(userCache.users, pIter);
243,190✔
189
  }
190
  taosHashCleanup(userCache.users);
228,003✔
191

192
  (void)taosThreadRwlockDestroy(&userCache.rw);
228,003✔
193
}
194

195

196

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

200
  (void)taosThreadRwlockWrlock(&userCache.rw);
28,777✔
201

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

216
  (void)taosThreadRwlockUnlock(&userCache.rw);
28,777✔
217
}
28,777✔
218

219

220

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

224
  (void)taosThreadRwlockWrlock(&userCache.rw);
773✔
225

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

233
  (void)taosThreadRwlockUnlock(&userCache.rw);
773✔
234
}
773✔
235

236

237

238
static SCachedUserInfo* getCachedUserInfo(const char* user) {
2,171,045✔
239
  size_t userLen = strlen(user);
2,171,045✔
240
  SCachedUserInfo **ppInfo = taosHashGet(userCache.users, user, userLen);
2,171,045✔
241
  if (ppInfo != NULL) {
2,171,045✔
242
    return *ppInfo;
1,899,078✔
243
  }
244

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

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

255
  return pInfo;
271,967✔
256
}
257

258

259

260
void mndGetUserLoginInfo(const char *user, SLoginInfo *pLoginInfo) {
1,336,064✔
261
  size_t userLen = strlen(user);
1,336,064✔
262

263
  (void)taosThreadRwlockRdlock(&userCache.rw);
1,336,064✔
264

265
  SCachedUserInfo **ppInfo = taosHashGet(userCache.users, user, userLen);
1,336,456✔
266
  if (ppInfo != NULL && *ppInfo != NULL) {
1,336,456✔
267
    pLoginInfo->lastLoginTime = (*ppInfo)->loginInfo.lastLoginTime;
1,173,918✔
268
    pLoginInfo->failedLoginCount = (*ppInfo)->loginInfo.failedLoginCount;
1,173,803✔
269
    pLoginInfo->lastFailedLoginTime = (*ppInfo)->loginInfo.lastFailedLoginTime;
1,173,923✔
270
  } else {
271
    pLoginInfo->lastLoginTime = taosGetTimestampSec();
162,538✔
272
    pLoginInfo->failedLoginCount = 0;
162,400✔
273
    pLoginInfo->lastFailedLoginTime = 0;
162,400✔
274
  }
275

276
  (void)taosThreadRwlockUnlock(&userCache.rw);
1,336,303✔
277

278
  if (pLoginInfo->lastLoginTime == 0) {
1,335,544✔
279
    pLoginInfo->lastLoginTime = taosGetTimestampSec();
19,926✔
280
  }
281
}
1,335,544✔
282

283

284

285
void mndSetUserLoginInfo(const char *user, const SLoginInfo *pLoginInfo) {
1,336,064✔
286
  size_t userLen = strlen(user);
1,336,064✔
287

288
  (void)taosThreadRwlockWrlock(&userCache.rw);
1,336,064✔
289

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

297
  (void)taosThreadRwlockUnlock(&userCache.rw);
1,336,456✔
298
}
1,336,456✔
299

300

301

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

307
  if (a == NULL || b == NULL) {
613,350✔
308
    return false;
49,645✔
309
  }
310

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

315
  for (int i = 0; i < a->num; i++) {
563,705✔
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;
563,705✔
325
}
326

327

328

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

332
  (void)taosThreadRwlockWrlock(&userCache.rw);
613,350✔
333

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

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

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

359
_OVER:
613,350✔
360
  (void)taosThreadRwlockUnlock(&userCache.rw);
613,350✔
361
  if (code < 0) {
613,350✔
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);
613,350✔
365
}
366

367

368

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

372
  SSdb     *pSdb = pMnode->pSdb;
279,993✔
373
  void     *pIter = NULL;
279,993✔
374
  while (1) {
113,969✔
375
    SUserObj *pUser = NULL;
393,962✔
376
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
393,962✔
377
    if (pIter == NULL) {
393,962✔
378
      break;
279,993✔
379
    }
380

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

398
    sdbRelease(pSdb, pUser);
113,969✔
399
  }
400

401
  userCache.verIp++;
279,993✔
402

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

410

411

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

416
  if (mndEnableIpWhiteList(pMnode) != 0 && tsEnableWhiteList) {
18,928,292✔
417
    (void)taosThreadRwlockWrlock(&userCache.rw);
7,460✔
418

419
    if (userCache.verIp == 0) {
7,460✔
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;
7,460✔
429

430
    (void)taosThreadRwlockUnlock(&userCache.rw);
7,460✔
431
  }
432

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

437

438

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

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

450
  TAOS_RETURN(code);
279,993✔
451
}
452

453

454

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

458
  SSdb     *pSdb = pMnode->pSdb;
273,294✔
459
  void     *pIter = NULL;
273,294✔
460
  while (1) {
107,270✔
461
    SUserObj *pUser = NULL;
380,564✔
462
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
380,564✔
463
    if (pIter == NULL) {
380,564✔
464
      break;
273,294✔
465
    }
466

467
    SCachedUserInfo *pInfo = getCachedUserInfo(pUser->user);
107,270✔
468
    if (pInfo == NULL) {
107,270✔
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);
107,270✔
475
    if (wl == NULL) {
107,270✔
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);
107,270✔
482
    pInfo->wlTime = wl;
107,270✔
483

484
    sdbRelease(pSdb, pUser);
107,270✔
485
  }
486

487
  userCache.verTime++;
273,294✔
488

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

496

497

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

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

509
  TAOS_RETURN(code);
273,294✔
510
}
511

512

513

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

518
  if (mndEnableTimeWhiteList(pMnode) != 0 && tsEnableWhiteList) {
18,928,292✔
519
    (void)taosThreadRwlockWrlock(&userCache.rw);
7,460✔
520

521
    if (userCache.verIp == 0) {
7,460✔
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;
7,460✔
531

532
    (void)taosThreadRwlockUnlock(&userCache.rw);
7,460✔
533
  }
534

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

539

540

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

544
  SSdbTable table = {
228,054✔
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);
228,054✔
556
  mndSetMsgHandle(pMnode, TDMT_MND_ALTER_USER, mndProcessAlterUserReq);
228,054✔
557
  mndSetMsgHandle(pMnode, TDMT_MND_DROP_USER, mndProcessDropUserReq);
228,054✔
558
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_AUTH, mndProcessGetUserAuthReq);
228,054✔
559

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

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

576

577

578
void mndCleanupUser(SMnode *pMnode) {
228,003✔
579
  userCacheCleanup();
228,003✔
580
}
228,003✔
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) {
25,913✔
607
  int32_t len = 0;
25,913✔
608
  for (int i = 0; i < num; i++) {
78,531✔
609
    SIpRange *pRange = &range[i];
52,618✔
610
    SIpAddr   addr = {0};
52,618✔
611
    (void)tIpUintToStr(pRange, &addr);
52,618✔
612

613
    len += tsnprintf(buf + len, bufLen - len, "%c%s/%d, ", pRange->neg ? '-' : '+', IP_ADDR_STR(&addr), addr.mask);
52,618✔
614
  }
615
  if (len > 0) buf[len - 2] = 0;
25,913✔
616
  return len;
25,913✔
617
}
618

619

620

621
static bool isIpRangeEqual(SIpRange *a, SIpRange *b) {
1,127,014✔
622
  if (a->type != b->type || a->neg != b->neg) {
1,127,014✔
623
    return false;
×
624
  }
625

626
  if (a->type == 0) {
1,127,014✔
627
    SIpV4Range *a4 = &a->ipV4;
563,705✔
628
    SIpV4Range *b4 = &b->ipV4;
563,705✔
629
    return (a4->ip == b4->ip && a4->mask == b4->mask);
563,705✔
630
  }
631
  
632
  SIpV6Range *a6 = &a->ipV6;
563,309✔
633
  SIpV6Range *b6 = &b->ipV6;
563,309✔
634
  return (a6->addr[0] == b6->addr[0] && a6->addr[1] == b6->addr[1] && a6->mask == b6->mask);
563,309✔
635
}
636

637

638

639
static bool isIpWhiteListEqual(SIpWhiteListDual *a, SIpWhiteListDual *b) {
613,350✔
640
  if (a == NULL && b == NULL) {
613,350✔
641
    return true;
×
642
  }
643
  
644
  if (a == NULL || b == NULL) {
613,350✔
645
    return false;
49,645✔
646
  }
647

648
  if (a->num != b->num) {
563,705✔
649
    return false;
198✔
650
  }
651
  for (int i = 0; i < a->num; i++) {
1,690,521✔
652
    if (!isIpRangeEqual(&a->pIpRanges[i], &b->pIpRanges[i])) {
1,127,014✔
653
      return false;
×
654
    }
655
  }
656
  return true;
563,507✔
657
}
658

659

660
static int32_t compareIpRange(const void *a, const void *b, const void* arg) {
2,178✔
661
  SIpRange *ra = (SIpRange *)a;
2,178✔
662
  SIpRange *rb = (SIpRange *)b;
2,178✔
663

664
  if (ra->neg != rb->neg) {
2,178✔
665
    return (ra->neg) ? -1 : 1;
×
666
  }
667

668
  if (ra->type != rb->type) {
2,178✔
669
    return (ra->type == 0) ? -1 : 1;
×
670
  }
671

672
  if (ra->type == 0) {
2,178✔
673
    if (ra->ipV4.ip != rb->ipV4.ip) {
2,178✔
674
      return (ra->ipV4.ip < rb->ipV4.ip) ? -1 : 1;
1,782✔
675
    }
676
    return (ra->ipV4.mask < rb->ipV4.mask) ? -1 : 1;
396✔
677
  }
678

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

688
static void sortIpWhiteList(SIpWhiteListDual *pList) {
1,003✔
689
  (void)taosqsort(pList->pIpRanges, pList->num, sizeof(SIpRange), NULL, compareIpRange);
1,003✔
690
}
1,003✔
691

692

693

694
static int32_t convertIpWhiteListToStr(SUserObj *pUser, char **buf) {
25,913✔
695
  SIpWhiteListDual *pList = pUser->pIpWhiteListDual;
25,913✔
696

697
  int64_t bufLen = pList->num * 128 + 8;
25,913✔
698
  *buf = taosMemoryCalloc(1, bufLen);
25,913✔
699
  if (*buf == NULL) {
25,913✔
700
    return 0;
×
701
  }
702

703
  if (pList->num == 0) {
25,913✔
704
    return tsnprintf(*buf, bufLen, "+ALL");
×
705
  }
706

707
  int32_t len = ipRangeListToStr(pList->pIpRanges, pList->num, *buf, bufLen - 2);
25,913✔
708
  if (len == 0) {
25,913✔
709
    taosMemoryFreeClear(*buf);
×
710
    return 0;
×
711
  }
712
  return len;
25,913✔
713
}
714

715

716

717
static int32_t tSerializeIpWhiteList(void *buf, int32_t len, SIpWhiteListDual *pList, uint32_t *pLen) {
1,350,791✔
718
  int32_t  code = 0;
1,350,791✔
719
  int32_t  lino = 0;
1,350,791✔
720
  int32_t  tlen = 0;
1,350,791✔
721
  SEncoder encoder = {0};
1,350,791✔
722
  tEncoderInit(&encoder, buf, len);
1,350,791✔
723

724
  TAOS_CHECK_GOTO(tStartEncode(&encoder), &lino, _OVER);
1,350,791✔
725
  TAOS_CHECK_GOTO(tEncodeI32(&encoder, pList->num), &lino, _OVER);
2,701,582✔
726

727
  for (int i = 0; i < pList->num; i++) {
4,052,941✔
728
    SIpRange *pRange = &(pList->pIpRanges[i]);
2,702,150✔
729
    TAOS_CHECK_GOTO(tSerializeIpRange(&encoder, pRange), &lino, _OVER);
2,702,150✔
730
  }
731

732
  tEndEncode(&encoder);
1,350,791✔
733

734
  tlen = encoder.pos;
1,350,791✔
735
_OVER:
1,350,791✔
736
  tEncoderClear(&encoder);
1,350,791✔
737
  if (code < 0) {
1,350,791✔
738
    mError("failed to serialize ip white list at line %d since %s", lino, tstrerror(code));
×
739
  }
740
  if (pLen) *pLen = tlen;
1,350,791✔
741
  TAOS_RETURN(code);
1,350,791✔
742
}
743

744
static int32_t tDerializeIpWhiteList(void *buf, int32_t len, SIpWhiteListDual *pList, bool supportNeg) {
881,704✔
745
  int32_t  code = 0;
881,704✔
746
  int32_t  lino = 0;
881,704✔
747
  SDecoder decoder = {0};
881,704✔
748
  tDecoderInit(&decoder, buf, len);
881,704✔
749

750
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
881,704✔
751
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &pList->num), &lino, _OVER);
1,763,408✔
752

753
  for (int i = 0; i < pList->num; i++) {
2,645,495✔
754
    SIpRange *pRange = &(pList->pIpRanges[i]);
1,763,791✔
755
    TAOS_CHECK_GOTO(tDeserializeIpRange(&decoder, pRange, supportNeg), &lino, _OVER);
1,763,791✔
756
  }
757

758
_OVER:
881,704✔
759
  tEndDecode(&decoder);
881,704✔
760
  tDecoderClear(&decoder);
881,704✔
761
  if (code < 0) {
881,704✔
762
    mError("failed to deserialize ip white list at line %d since %s", lino, tstrerror(code));
×
763
  }
764
  TAOS_RETURN(code);
881,704✔
765
}
766

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

773
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
×
774
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &pList->num), &lino, _OVER);
×
775

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

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

791
static int32_t createIpWhiteList(void *buf, int32_t len, SIpWhiteListDual **ppList, bool supportNeg) {
881,704✔
792
  int32_t           code = 0;
881,704✔
793
  int32_t           lino = 0;
881,704✔
794
  int32_t           num = 0;
881,704✔
795
  SIpWhiteListDual *p = NULL;
881,704✔
796
  SDecoder          decoder = {0};
881,704✔
797
  tDecoderInit(&decoder, buf, len);
881,704✔
798

799
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
881,704✔
800
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &num), &lino, _OVER);
881,704✔
801

802
  p = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + num * sizeof(SIpRange));
881,704✔
803
  if (p == NULL) {
881,704✔
804
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
805
  }
806
  TAOS_CHECK_GOTO(tDerializeIpWhiteList(buf, len, p, supportNeg), &lino, _OVER);
881,704✔
807

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

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

827
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
×
828
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &num), &lino, _OVER);
×
829

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

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

847
static int32_t createDefaultIpWhiteList(SIpWhiteListDual **ppWhiteList) {
213,952✔
848
  int32_t code = 0;
213,952✔
849
  int32_t lino = 0;
213,952✔
850
  *ppWhiteList = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + sizeof(SIpRange) * 2);
213,952✔
851
  if (*ppWhiteList == NULL) {
213,952✔
852
    TAOS_RETURN(terrno);
×
853
  }
854
  (*ppWhiteList)->num = 2;
213,952✔
855

856
  SIpRange v4 = {0};
213,952✔
857
  SIpRange v6 = {0};
213,952✔
858

859
#ifndef TD_ASTRA
860
  code = createDefaultIp4Range(&v4);
213,952✔
861
  TSDB_CHECK_CODE(code, lino, _error);
213,952✔
862

863
  code = createDefaultIp6Range(&v6);
213,952✔
864
  TSDB_CHECK_CODE(code, lino, _error);
213,952✔
865

866
#endif
867

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

880

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

883
static int32_t convertTimeRangesToStr(SUserObj *pUser, char **buf) {
25,913✔
884
  int32_t bufLen = pUser->pTimeWhiteList->num * 32 + 8;
25,913✔
885
  *buf = taosMemoryCalloc(1, bufLen);
25,913✔
886
  if (*buf == NULL) {
25,913✔
887
    return 0;
×
888
  }
889

890
  int32_t pos = 0;
25,913✔
891
  if (pUser->pTimeWhiteList->num == 0) {
25,913✔
892
    pos += tsnprintf(*buf + pos, bufLen - pos, "+ALL");
25,913✔
893
    return pos;
25,913✔
894
  }
895

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

900
    if (range->absolute) {
×
901
      struct STm tm;
×
902
      (void)taosTs2Tm(range->start, TSDB_TIME_PRECISION_SECONDS, &tm, NULL);
×
903
      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);
×
904
    } else {
905
      int day = range->start / 86400;
×
906
      int hour = (range->start % 86400) / 3600;
×
907
      int minute = (range->start % 3600) / 60;
×
908
      pos += tsnprintf(*buf + pos, bufLen - pos, "%c%s %02d:%02d %dm, ", range->neg ? '-' : '+', weekdays[day], hour, minute, duration);
×
909
    }
910
  }
911

912
  if (pos > 0) {
×
913
    (*buf)[pos - 2] = 0; // remove last ", "
×
914
  }
915

916
  return pos;
×
917
}
918

919

920
static int32_t compareDateTimeInterval(const void *a, const void *b, const void* arg) {
×
921
  SDateTimeWhiteListItem *pA = (SDateTimeWhiteListItem *)a;
×
922
  SDateTimeWhiteListItem *pB = (SDateTimeWhiteListItem *)b;
×
923

924
  if (pA->neg != pB->neg) {
×
925
    return pA->neg ? -1 : 1;
×
926
  }
927

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

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

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

940
  return 0;
×
941
}
942

943
static void sortTimeWhiteList(SDateTimeWhiteList *pList) {
×
944
  (void)taosqsort(pList->ranges, pList->num, sizeof(SDateTimeWhiteListItem), NULL, compareDateTimeInterval);
×
945
}
×
946

947

948

949

950
static void dropOldPasswords(SUserObj *pUser) {
2,232,495✔
951
  if (pUser->numOfPasswords <= pUser->passwordReuseMax) {
2,232,495✔
952
    return;
2,204,171✔
953
  }
954

955
  int32_t reuseMax = pUser->passwordReuseMax;
28,324✔
956
  if (reuseMax == 0) {
28,324✔
957
    reuseMax = 1; // keep at least one password
26,214✔
958
  }
959

960
  int32_t now = taosGetTimestampSec();
28,324✔
961
  int32_t index = reuseMax;
28,324✔
962
  while(index < pUser->numOfPasswords) {
34,232✔
963
    SUserPassword *pPass = &pUser->passwords[index];
5,908✔
964
    if (now - pPass->setTime >= pUser->passwordReuseTime) {
5,908✔
965
      break;
×
966
    }
967
    index++;
5,908✔
968
  }
969

970
  if (index == pUser->numOfPasswords) {
28,324✔
971
    return;
28,324✔
972
  }
973
  pUser->numOfPasswords = index;
×
974
  // this is a shrink operation, no need to check return value
975
  pUser->passwords = taosMemoryRealloc(pUser->passwords, sizeof(SUserPassword) * pUser->numOfPasswords);
×
976
}
977

978

979

980

981
static int32_t mndCreateDefaultUser(SMnode *pMnode, char *acct, char *user, char *pass) {
165,125✔
982
  int32_t  code = 0;
165,125✔
983
  int32_t  lino = 0;
165,125✔
984
  SUserObj userObj = {0};
165,125✔
985

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

997
  userObj.passwords[0].setTime = taosGetTimestampSec();
165,125✔
998
  userObj.numOfPasswords = 1;
165,125✔
999

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

1041
  SSdbRaw *pRaw = mndUserActionEncode(&userObj);
165,125✔
1042
  if (pRaw == NULL) goto _ERROR;
165,125✔
1043
  TAOS_CHECK_GOTO(sdbSetRawStatus(pRaw, SDB_STATUS_READY), &lino, _ERROR);
165,125✔
1044

1045
  mInfo("user:%s, will be created when deploying, raw:%p", userObj.user, pRaw);
165,125✔
1046

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

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

1062
  if (mndTransPrepare(pMnode, pTrans) != 0) {
165,125✔
1063
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
1064
    mndTransDrop(pTrans);
×
1065
    goto _ERROR;
×
1066
  }
1067

1068
  mndTransDrop(pTrans);
165,125✔
1069
  taosMemoryFree(userObj.passwords);
165,125✔
1070
  taosMemoryFree(userObj.pIpWhiteListDual);
165,125✔
1071
  taosMemoryFree(userObj.pTimeWhiteList);
165,125✔
1072
  return 0;
165,125✔
1073

1074
_ERROR:
×
1075
  taosMemoryFree(userObj.passwords);
×
1076
  taosMemoryFree(userObj.pIpWhiteListDual);
×
1077
  taosMemoryFree(userObj.pTimeWhiteList);
×
1078
  TAOS_RETURN(terrno ? terrno : TSDB_CODE_APP_ERROR);
×
1079
}
1080

1081
static int32_t mndCreateDefaultUsers(SMnode *pMnode) {
165,125✔
1082
  return mndCreateDefaultUser(pMnode, TSDB_DEFAULT_USER, TSDB_DEFAULT_USER, TSDB_DEFAULT_PASS);
165,125✔
1083
}
1084

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

1106
  char *stb = taosHashIterate(pUser->readTbs, NULL);
1,350,791✔
1107
  while (stb != NULL) {
1,638,833✔
1108
    size_t keyLen = 0;
288,042✔
1109
    void  *key = taosHashGetKey(stb, &keyLen);
288,042✔
1110
    size += sizeof(int32_t);
288,042✔
1111
    size += keyLen;
288,042✔
1112

1113
    size_t valueLen = 0;
288,042✔
1114
    valueLen = strlen(stb) + 1;
288,042✔
1115
    size += sizeof(int32_t);
288,042✔
1116
    size += valueLen;
288,042✔
1117
    stb = taosHashIterate(pUser->readTbs, stb);
288,042✔
1118
  }
1119

1120
  stb = taosHashIterate(pUser->writeTbs, NULL);
1,350,791✔
1121
  while (stb != NULL) {
1,642,604✔
1122
    size_t keyLen = 0;
291,813✔
1123
    void  *key = taosHashGetKey(stb, &keyLen);
291,813✔
1124
    size += sizeof(int32_t);
291,813✔
1125
    size += keyLen;
291,813✔
1126

1127
    size_t valueLen = 0;
291,813✔
1128
    valueLen = strlen(stb) + 1;
291,813✔
1129
    size += sizeof(int32_t);
291,813✔
1130
    size += valueLen;
291,813✔
1131
    stb = taosHashIterate(pUser->writeTbs, stb);
291,813✔
1132
  }
1133

1134
  stb = taosHashIterate(pUser->alterTbs, NULL);
1,350,791✔
1135
  while (stb != NULL) {
1,505,192✔
1136
    size_t keyLen = 0;
154,401✔
1137
    void  *key = taosHashGetKey(stb, &keyLen);
154,401✔
1138
    size += sizeof(int32_t);
154,401✔
1139
    size += keyLen;
154,401✔
1140

1141
    size_t valueLen = 0;
154,401✔
1142
    valueLen = strlen(stb) + 1;
154,401✔
1143
    size += sizeof(int32_t);
154,401✔
1144
    size += valueLen;
154,401✔
1145
    stb = taosHashIterate(pUser->alterTbs, stb);
154,401✔
1146
  }
1147

1148
  stb = taosHashIterate(pUser->readViews, NULL);
1,350,791✔
1149
  while (stb != NULL) {
1,375,395✔
1150
    size_t keyLen = 0;
24,604✔
1151
    void  *key = taosHashGetKey(stb, &keyLen);
24,604✔
1152
    size += sizeof(int32_t);
24,604✔
1153
    size += keyLen;
24,604✔
1154

1155
    size_t valueLen = 0;
24,604✔
1156
    valueLen = strlen(stb) + 1;
24,604✔
1157
    size += sizeof(int32_t);
24,604✔
1158
    size += valueLen;
24,604✔
1159
    stb = taosHashIterate(pUser->readViews, stb);
24,604✔
1160
  }
1161

1162
  stb = taosHashIterate(pUser->writeViews, NULL);
1,350,791✔
1163
  while (stb != NULL) {
1,369,464✔
1164
    size_t keyLen = 0;
18,673✔
1165
    void  *key = taosHashGetKey(stb, &keyLen);
18,673✔
1166
    size += sizeof(int32_t);
18,673✔
1167
    size += keyLen;
18,673✔
1168

1169
    size_t valueLen = 0;
18,673✔
1170
    valueLen = strlen(stb) + 1;
18,673✔
1171
    size += sizeof(int32_t);
18,673✔
1172
    size += valueLen;
18,673✔
1173
    stb = taosHashIterate(pUser->writeViews, stb);
18,673✔
1174
  }
1175

1176
  stb = taosHashIterate(pUser->alterViews, NULL);
1,350,791✔
1177
  while (stb != NULL) {
1,368,918✔
1178
    size_t keyLen = 0;
18,127✔
1179
    void  *key = taosHashGetKey(stb, &keyLen);
18,127✔
1180
    size += sizeof(int32_t);
18,127✔
1181
    size += keyLen;
18,127✔
1182

1183
    size_t valueLen = 0;
18,127✔
1184
    valueLen = strlen(stb) + 1;
18,127✔
1185
    size += sizeof(int32_t);
18,127✔
1186
    size += valueLen;
18,127✔
1187
    stb = taosHashIterate(pUser->alterViews, stb);
18,127✔
1188
  }
1189

1190
  int32_t *useDb = taosHashIterate(pUser->useDbs, NULL);
1,350,791✔
1191
  while (useDb != NULL) {
1,702,978✔
1192
    size_t keyLen = 0;
352,187✔
1193
    void  *key = taosHashGetKey(useDb, &keyLen);
352,187✔
1194
    size += sizeof(int32_t);
352,187✔
1195
    size += keyLen;
352,187✔
1196
    size += sizeof(int32_t);
352,187✔
1197
    useDb = taosHashIterate(pUser->useDbs, useDb);
352,187✔
1198
  }
1199

1200
  pRaw = sdbAllocRaw(SDB_USER, USER_VER_NUMBER, size);
1,350,791✔
1201
  if (pRaw == NULL) {
1,350,791✔
1202
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1203
  }
1204

1205
  int32_t dataPos = 0;
1,350,791✔
1206
  SDB_SET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN, _OVER)
1,350,791✔
1207

1208
  dropOldPasswords(pUser);
1,350,791✔
1209
  SDB_SET_INT32(pRaw, dataPos, pUser->numOfPasswords, _OVER)
1,350,791✔
1210
  for (int32_t i = 0; i < pUser->numOfPasswords; i++) {
2,712,660✔
1211
    SDB_SET_BINARY(pRaw, dataPos, pUser->passwords[i].pass, sizeof(pUser->passwords[i].pass), _OVER)
1,361,869✔
1212
    SDB_SET_INT32(pRaw, dataPos, pUser->passwords[i].setTime, _OVER)
1,361,869✔
1213
  }
1214
  SDB_SET_BINARY(pRaw, dataPos, pUser->salt, sizeof(pUser->salt), _OVER)
1,350,791✔
1215

1216
  SDB_SET_BINARY(pRaw, dataPos, pUser->acct, TSDB_USER_LEN, _OVER)
1,350,791✔
1217
  SDB_SET_INT64(pRaw, dataPos, pUser->createdTime, _OVER)
1,350,791✔
1218
  SDB_SET_INT64(pRaw, dataPos, pUser->updateTime, _OVER)
1,350,791✔
1219
  SDB_SET_INT8(pRaw, dataPos, pUser->superUser, _OVER)
1,350,791✔
1220
  SDB_SET_INT8(pRaw, dataPos, pUser->sysInfo, _OVER)
1,350,791✔
1221
  SDB_SET_INT8(pRaw, dataPos, pUser->enable, _OVER)
1,350,791✔
1222
  SDB_SET_UINT8(pRaw, dataPos, pUser->flag, _OVER)
1,350,791✔
1223
  SDB_SET_INT32(pRaw, dataPos, pUser->authVersion, _OVER)
1,350,791✔
1224
  SDB_SET_INT32(pRaw, dataPos, pUser->passVersion, _OVER)
1,350,791✔
1225
  SDB_SET_INT32(pRaw, dataPos, numOfReadDbs, _OVER)
1,350,791✔
1226
  SDB_SET_INT32(pRaw, dataPos, numOfWriteDbs, _OVER)
1,350,791✔
1227
  SDB_SET_INT32(pRaw, dataPos, numOfTopics, _OVER)
1,350,791✔
1228

1229
  char *db = taosHashIterate(pUser->readDbs, NULL);
1,350,791✔
1230
  while (db != NULL) {
1,546,199✔
1231
    SDB_SET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER);
195,408✔
1232
    db = taosHashIterate(pUser->readDbs, db);
195,408✔
1233
  }
1234

1235
  db = taosHashIterate(pUser->writeDbs, NULL);
1,350,791✔
1236
  while (db != NULL) {
1,546,431✔
1237
    SDB_SET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER);
195,640✔
1238
    db = taosHashIterate(pUser->writeDbs, db);
195,640✔
1239
  }
1240

1241
  char *topic = taosHashIterate(pUser->topics, NULL);
1,350,791✔
1242
  while (topic != NULL) {
1,360,187✔
1243
    SDB_SET_BINARY(pRaw, dataPos, topic, TSDB_TOPIC_FNAME_LEN, _OVER);
9,396✔
1244
    topic = taosHashIterate(pUser->topics, topic);
9,396✔
1245
  }
1246

1247
  SDB_SET_INT32(pRaw, dataPos, numOfReadTbs, _OVER)
1,350,791✔
1248
  SDB_SET_INT32(pRaw, dataPos, numOfWriteTbs, _OVER)
1,350,791✔
1249
  SDB_SET_INT32(pRaw, dataPos, numOfAlterTbs, _OVER)
1,350,791✔
1250
  SDB_SET_INT32(pRaw, dataPos, numOfReadViews, _OVER)
1,350,791✔
1251
  SDB_SET_INT32(pRaw, dataPos, numOfWriteViews, _OVER)
1,350,791✔
1252
  SDB_SET_INT32(pRaw, dataPos, numOfAlterViews, _OVER)
1,350,791✔
1253
  SDB_SET_INT32(pRaw, dataPos, numOfUseDbs, _OVER)
1,350,791✔
1254

1255
  stb = taosHashIterate(pUser->readTbs, NULL);
1,350,791✔
1256
  while (stb != NULL) {
1,638,833✔
1257
    size_t keyLen = 0;
288,042✔
1258
    void  *key = taosHashGetKey(stb, &keyLen);
288,042✔
1259
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
288,042✔
1260
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
288,042✔
1261

1262
    size_t valueLen = 0;
288,042✔
1263
    valueLen = strlen(stb) + 1;
288,042✔
1264
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
288,042✔
1265
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
288,042✔
1266
    stb = taosHashIterate(pUser->readTbs, stb);
288,042✔
1267
  }
1268

1269
  stb = taosHashIterate(pUser->writeTbs, NULL);
1,350,791✔
1270
  while (stb != NULL) {
1,642,604✔
1271
    size_t keyLen = 0;
291,813✔
1272
    void  *key = taosHashGetKey(stb, &keyLen);
291,813✔
1273
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
291,813✔
1274
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
291,813✔
1275

1276
    size_t valueLen = 0;
291,813✔
1277
    valueLen = strlen(stb) + 1;
291,813✔
1278
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
291,813✔
1279
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
291,813✔
1280
    stb = taosHashIterate(pUser->writeTbs, stb);
291,813✔
1281
  }
1282

1283
  stb = taosHashIterate(pUser->alterTbs, NULL);
1,350,791✔
1284
  while (stb != NULL) {
1,505,192✔
1285
    size_t keyLen = 0;
154,401✔
1286
    void  *key = taosHashGetKey(stb, &keyLen);
154,401✔
1287
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
154,401✔
1288
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
154,401✔
1289

1290
    size_t valueLen = 0;
154,401✔
1291
    valueLen = strlen(stb) + 1;
154,401✔
1292
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
154,401✔
1293
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
154,401✔
1294
    stb = taosHashIterate(pUser->alterTbs, stb);
154,401✔
1295
  }
1296

1297
  stb = taosHashIterate(pUser->readViews, NULL);
1,350,791✔
1298
  while (stb != NULL) {
1,375,395✔
1299
    size_t keyLen = 0;
24,604✔
1300
    void  *key = taosHashGetKey(stb, &keyLen);
24,604✔
1301
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
24,604✔
1302
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
24,604✔
1303

1304
    size_t valueLen = 0;
24,604✔
1305
    valueLen = strlen(stb) + 1;
24,604✔
1306
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
24,604✔
1307
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
24,604✔
1308
    stb = taosHashIterate(pUser->readViews, stb);
24,604✔
1309
  }
1310

1311
  stb = taosHashIterate(pUser->writeViews, NULL);
1,350,791✔
1312
  while (stb != NULL) {
1,369,464✔
1313
    size_t keyLen = 0;
18,673✔
1314
    void  *key = taosHashGetKey(stb, &keyLen);
18,673✔
1315
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
18,673✔
1316
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
18,673✔
1317

1318
    size_t valueLen = 0;
18,673✔
1319
    valueLen = strlen(stb) + 1;
18,673✔
1320
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
18,673✔
1321
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
18,673✔
1322
    stb = taosHashIterate(pUser->writeViews, stb);
18,673✔
1323
  }
1324

1325
  stb = taosHashIterate(pUser->alterViews, NULL);
1,350,791✔
1326
  while (stb != NULL) {
1,368,918✔
1327
    size_t keyLen = 0;
18,127✔
1328
    void  *key = taosHashGetKey(stb, &keyLen);
18,127✔
1329
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
18,127✔
1330
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
18,127✔
1331

1332
    size_t valueLen = 0;
18,127✔
1333
    valueLen = strlen(stb) + 1;
18,127✔
1334
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
18,127✔
1335
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
18,127✔
1336
    stb = taosHashIterate(pUser->alterViews, stb);
18,127✔
1337
  }
1338

1339
  useDb = taosHashIterate(pUser->useDbs, NULL);
1,350,791✔
1340
  while (useDb != NULL) {
1,702,978✔
1341
    size_t keyLen = 0;
352,187✔
1342
    void  *key = taosHashGetKey(useDb, &keyLen);
352,187✔
1343
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
352,187✔
1344
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
352,187✔
1345

1346
    SDB_SET_INT32(pRaw, dataPos, *useDb, _OVER)
352,187✔
1347
    useDb = taosHashIterate(pUser->useDbs, useDb);
352,187✔
1348
  }
1349

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

1359
  SDB_SET_INT32(pRaw, dataPos, len, _OVER);
1,350,791✔
1360
  SDB_SET_BINARY(pRaw, dataPos, buf, len, _OVER);
1,350,791✔
1361

1362
  SDB_SET_INT64(pRaw, dataPos, pUser->ipWhiteListVer, _OVER);
1,350,791✔
1363
  SDB_SET_INT8(pRaw, dataPos, pUser->passEncryptAlgorithm, _OVER);
1,350,791✔
1364

1365
  SDB_SET_BINARY(pRaw, dataPos, pUser->totpsecret, sizeof(pUser->totpsecret), _OVER);
1,350,791✔
1366
  SDB_SET_INT8(pRaw, dataPos, pUser->changePass, _OVER);
1,350,791✔
1367
  SDB_SET_INT32(pRaw, dataPos, pUser->sessionPerUser, _OVER);
1,350,791✔
1368
  SDB_SET_INT32(pRaw, dataPos, pUser->connectTime, _OVER);
1,350,791✔
1369
  SDB_SET_INT32(pRaw, dataPos, pUser->connectIdleTime, _OVER);
1,350,791✔
1370
  SDB_SET_INT32(pRaw, dataPos, pUser->callPerSession, _OVER);
1,350,791✔
1371
  SDB_SET_INT32(pRaw, dataPos, pUser->vnodePerCall, _OVER);
1,350,791✔
1372
  SDB_SET_INT32(pRaw, dataPos, pUser->failedLoginAttempts, _OVER);
1,350,791✔
1373
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordLifeTime, _OVER);
1,350,791✔
1374
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordReuseTime, _OVER);
1,350,791✔
1375
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordReuseMax, _OVER);
1,350,791✔
1376
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordLockTime, _OVER);
1,350,791✔
1377
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordGraceTime, _OVER);
1,350,791✔
1378
  SDB_SET_INT32(pRaw, dataPos, pUser->inactiveAccountTime, _OVER);
1,350,791✔
1379
  SDB_SET_INT32(pRaw, dataPos, pUser->allowTokenNum, _OVER);
1,350,791✔
1380

1381
  SDB_SET_INT32(pRaw, dataPos, pUser->pTimeWhiteList->num, _OVER);
1,350,791✔
1382
  for (int32_t i = 0; i < pUser->pTimeWhiteList->num; i++) {
1,350,791✔
1383
    SDateTimeWhiteListItem *range = &pUser->pTimeWhiteList->ranges[i];
×
1384
    SDB_SET_BOOL(pRaw, dataPos, range->absolute, _OVER);
×
1385
    SDB_SET_BOOL(pRaw, dataPos, range->neg, _OVER);
×
1386
    SDB_SET_INT64(pRaw, dataPos, range->start, _OVER);
×
1387
    SDB_SET_INT32(pRaw, dataPos, range->duration, _OVER);
×
1388
  }
1389

1390
  SDB_SET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
1,350,791✔
1391
  SDB_SET_DATALEN(pRaw, dataPos, _OVER)
1,350,791✔
1392

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

1403
  mTrace("user:%s, encode user action to raw:%p, row:%p", pUser->user, pRaw, pUser);
1,350,791✔
1404
  return pRaw;
1,350,791✔
1405
}
1406

1407
static SSdbRow *mndUserActionDecode(SSdbRaw *pRaw) {
881,704✔
1408
  int32_t   code = 0;
881,704✔
1409
  int32_t   lino = 0;
881,704✔
1410
  SSdbRow  *pRow = NULL;
881,704✔
1411
  SUserObj *pUser = NULL;
881,704✔
1412
  char     *key = NULL;
881,704✔
1413
  char     *value = NULL;
881,704✔
1414

1415
  int8_t sver = 0;
881,704✔
1416
  if (sdbGetRawSoftVer(pRaw, &sver) != 0) {
881,704✔
1417
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_PTR, &lino, _OVER);
×
1418
  }
1419

1420
  if (sver < 1 || sver > USER_VER_NUMBER) {
881,704✔
1421
    TAOS_CHECK_GOTO(TSDB_CODE_SDB_INVALID_DATA_VER, &lino, _OVER);
×
1422
  }
1423

1424
  pRow = sdbAllocRow(sizeof(SUserObj));
881,704✔
1425
  if (pRow == NULL) {
881,704✔
1426
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1427
  }
1428

1429
  pUser = sdbGetRowObj(pRow);
881,704✔
1430
  if (pUser == NULL) {
881,704✔
1431
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1432
  }
1433

1434
  int32_t dataPos = 0;
881,704✔
1435
  SDB_GET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN, _OVER)
881,704✔
1436

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

1465
  SDB_GET_INT8(pRaw, dataPos, &pUser->superUser, _OVER)
881,704✔
1466
  SDB_GET_INT8(pRaw, dataPos, &pUser->sysInfo, _OVER)
881,704✔
1467
  SDB_GET_INT8(pRaw, dataPos, &pUser->enable, _OVER)
881,704✔
1468
  SDB_GET_UINT8(pRaw, dataPos, &pUser->flag, _OVER)
881,704✔
1469
  if (pUser->superUser) pUser->createdb = 1;
881,704✔
1470
  SDB_GET_INT32(pRaw, dataPos, &pUser->authVersion, _OVER)
881,704✔
1471
  if (sver >= 4) {
881,704✔
1472
    SDB_GET_INT32(pRaw, dataPos, &pUser->passVersion, _OVER)
881,704✔
1473
  }
1474

1475
  int32_t numOfReadDbs = 0;
881,704✔
1476
  int32_t numOfWriteDbs = 0;
881,704✔
1477
  int32_t numOfTopics = 0;
881,704✔
1478
  SDB_GET_INT32(pRaw, dataPos, &numOfReadDbs, _OVER)
881,704✔
1479
  SDB_GET_INT32(pRaw, dataPos, &numOfWriteDbs, _OVER)
881,704✔
1480
  if (sver >= 2) {
881,704✔
1481
    SDB_GET_INT32(pRaw, dataPos, &numOfTopics, _OVER)
881,704✔
1482
  }
1483

1484
  pUser->readDbs = taosHashInit(numOfReadDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
881,704✔
1485
  pUser->writeDbs =
881,704✔
1486
      taosHashInit(numOfWriteDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
881,704✔
1487
  pUser->topics = taosHashInit(numOfTopics, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
881,704✔
1488
  if (pUser->readDbs == NULL || pUser->writeDbs == NULL || pUser->topics == NULL) {
881,704✔
1489
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1490
    goto _OVER;
×
1491
  }
1492

1493
  for (int32_t i = 0; i < numOfReadDbs; ++i) {
1,074,511✔
1494
    char db[TSDB_DB_FNAME_LEN] = {0};
192,807✔
1495
    SDB_GET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER)
192,807✔
1496
    int32_t len = strlen(db) + 1;
192,807✔
1497
    TAOS_CHECK_GOTO(taosHashPut(pUser->readDbs, db, len, db, TSDB_DB_FNAME_LEN), &lino, _OVER);
192,807✔
1498
  }
1499

1500
  for (int32_t i = 0; i < numOfWriteDbs; ++i) {
1,073,804✔
1501
    char db[TSDB_DB_FNAME_LEN] = {0};
192,100✔
1502
    SDB_GET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER)
192,100✔
1503
    int32_t len = strlen(db) + 1;
192,100✔
1504
    TAOS_CHECK_GOTO(taosHashPut(pUser->writeDbs, db, len, db, TSDB_DB_FNAME_LEN), &lino, _OVER);
192,100✔
1505
  }
1506

1507
  if (sver >= 2) {
881,704✔
1508
    for (int32_t i = 0; i < numOfTopics; ++i) {
890,316✔
1509
      char topic[TSDB_TOPIC_FNAME_LEN] = {0};
8,612✔
1510
      SDB_GET_BINARY(pRaw, dataPos, topic, TSDB_TOPIC_FNAME_LEN, _OVER)
8,612✔
1511
      int32_t len = strlen(topic) + 1;
8,612✔
1512
      TAOS_CHECK_GOTO(taosHashPut(pUser->topics, topic, len, topic, TSDB_TOPIC_FNAME_LEN), &lino, _OVER);
8,612✔
1513
    }
1514
  }
1515

1516
  if (sver >= 3) {
881,704✔
1517
    int32_t numOfReadTbs = 0;
881,704✔
1518
    int32_t numOfWriteTbs = 0;
881,704✔
1519
    int32_t numOfAlterTbs = 0;
881,704✔
1520
    int32_t numOfReadViews = 0;
881,704✔
1521
    int32_t numOfWriteViews = 0;
881,704✔
1522
    int32_t numOfAlterViews = 0;
881,704✔
1523
    int32_t numOfUseDbs = 0;
881,704✔
1524
    SDB_GET_INT32(pRaw, dataPos, &numOfReadTbs, _OVER)
881,704✔
1525
    SDB_GET_INT32(pRaw, dataPos, &numOfWriteTbs, _OVER)
881,704✔
1526
    if (sver >= 6) {
881,704✔
1527
      SDB_GET_INT32(pRaw, dataPos, &numOfAlterTbs, _OVER)
881,704✔
1528
      SDB_GET_INT32(pRaw, dataPos, &numOfReadViews, _OVER)
881,704✔
1529
      SDB_GET_INT32(pRaw, dataPos, &numOfWriteViews, _OVER)
881,704✔
1530
      SDB_GET_INT32(pRaw, dataPos, &numOfAlterViews, _OVER)
881,704✔
1531
    }
1532
    SDB_GET_INT32(pRaw, dataPos, &numOfUseDbs, _OVER)
881,704✔
1533

1534
    pUser->readTbs =
881,704✔
1535
        taosHashInit(numOfReadTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
881,704✔
1536
    pUser->writeTbs =
881,704✔
1537
        taosHashInit(numOfWriteTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
881,704✔
1538
    pUser->alterTbs =
881,704✔
1539
        taosHashInit(numOfAlterTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
881,704✔
1540

1541
    pUser->readViews =
881,704✔
1542
        taosHashInit(numOfReadViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
881,704✔
1543
    pUser->writeViews =
881,704✔
1544
        taosHashInit(numOfWriteViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
881,704✔
1545
    pUser->alterViews =
881,704✔
1546
        taosHashInit(numOfAlterViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
881,704✔
1547

1548
    pUser->useDbs = taosHashInit(numOfUseDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
881,704✔
1549

1550
    if (pUser->readTbs == NULL || pUser->writeTbs == NULL || pUser->alterTbs == NULL || pUser->readViews == NULL ||
881,704✔
1551
        pUser->writeViews == NULL || pUser->alterViews == NULL || pUser->useDbs == NULL) {
881,704✔
1552
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1553
      goto _OVER;
×
1554
    }
1555

1556
    for (int32_t i = 0; i < numOfReadTbs; ++i) {
1,153,175✔
1557
      int32_t keyLen = 0;
271,471✔
1558
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
271,471✔
1559

1560
      TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
271,471✔
1561
      if (key == NULL) {
271,471✔
1562
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1563
      }
1564
      (void)memset(key, 0, keyLen);
271,471✔
1565
      SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
271,471✔
1566

1567
      int32_t valuelen = 0;
271,471✔
1568
      SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
271,471✔
1569
      TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
271,471✔
1570
      if (value == NULL) {
271,471✔
1571
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1572
      }
1573
      (void)memset(value, 0, valuelen);
271,471✔
1574
      SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
271,471✔
1575

1576
      TAOS_CHECK_GOTO(taosHashPut(pUser->readTbs, key, keyLen, value, valuelen), &lino, _OVER);
271,471✔
1577
    }
1578

1579
    for (int32_t i = 0; i < numOfWriteTbs; ++i) {
1,158,041✔
1580
      int32_t keyLen = 0;
276,337✔
1581
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
276,337✔
1582

1583
      TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
276,337✔
1584
      if (key == NULL) {
276,337✔
1585
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1586
      }
1587
      (void)memset(key, 0, keyLen);
276,337✔
1588
      SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
276,337✔
1589

1590
      int32_t valuelen = 0;
276,337✔
1591
      SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
276,337✔
1592
      TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
276,337✔
1593
      if (value == NULL) {
276,337✔
1594
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1595
      }
1596
      (void)memset(value, 0, valuelen);
276,337✔
1597
      SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
276,337✔
1598

1599
      TAOS_CHECK_GOTO(taosHashPut(pUser->writeTbs, key, keyLen, value, valuelen), &lino, _OVER);
276,337✔
1600
    }
1601

1602
    if (sver >= 6) {
881,704✔
1603
      for (int32_t i = 0; i < numOfAlterTbs; ++i) {
1,027,539✔
1604
        int32_t keyLen = 0;
145,835✔
1605
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
145,835✔
1606

1607
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
145,835✔
1608
        if (key == NULL) {
145,835✔
1609
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1610
        }
1611
        (void)memset(key, 0, keyLen);
145,835✔
1612
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
145,835✔
1613

1614
        int32_t valuelen = 0;
145,835✔
1615
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
145,835✔
1616
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
145,835✔
1617
        if (value == NULL) {
145,835✔
1618
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1619
        }
1620
        (void)memset(value, 0, valuelen);
145,835✔
1621
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
145,835✔
1622

1623
        TAOS_CHECK_GOTO(taosHashPut(pUser->alterTbs, key, keyLen, value, valuelen), &lino, _OVER);
145,835✔
1624
      }
1625

1626
      for (int32_t i = 0; i < numOfReadViews; ++i) {
906,308✔
1627
        int32_t keyLen = 0;
24,604✔
1628
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
24,604✔
1629

1630
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
24,604✔
1631
        if (key == NULL) {
24,604✔
1632
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1633
        }
1634
        (void)memset(key, 0, keyLen);
24,604✔
1635
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
24,604✔
1636

1637
        int32_t valuelen = 0;
24,604✔
1638
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
24,604✔
1639
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
24,604✔
1640
        if (value == NULL) {
24,604✔
1641
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1642
        }
1643
        (void)memset(value, 0, valuelen);
24,604✔
1644
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
24,604✔
1645

1646
        TAOS_CHECK_GOTO(taosHashPut(pUser->readViews, key, keyLen, value, valuelen), &lino, _OVER);
24,604✔
1647
      }
1648

1649
      for (int32_t i = 0; i < numOfWriteViews; ++i) {
900,377✔
1650
        int32_t keyLen = 0;
18,673✔
1651
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
18,673✔
1652

1653
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
18,673✔
1654
        if (key == NULL) {
18,673✔
1655
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1656
        }
1657
        (void)memset(key, 0, keyLen);
18,673✔
1658
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
18,673✔
1659

1660
        int32_t valuelen = 0;
18,673✔
1661
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
18,673✔
1662
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
18,673✔
1663
        if (value == NULL) {
18,673✔
1664
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1665
        }
1666
        (void)memset(value, 0, valuelen);
18,673✔
1667
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
18,673✔
1668

1669
        TAOS_CHECK_GOTO(taosHashPut(pUser->writeViews, key, keyLen, value, valuelen), &lino, _OVER);
18,673✔
1670
      }
1671

1672
      for (int32_t i = 0; i < numOfAlterViews; ++i) {
899,831✔
1673
        int32_t keyLen = 0;
18,127✔
1674
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
18,127✔
1675

1676
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
18,127✔
1677
        if (key == NULL) {
18,127✔
1678
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1679
        }
1680
        (void)memset(key, 0, keyLen);
18,127✔
1681
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
18,127✔
1682

1683
        int32_t valuelen = 0;
18,127✔
1684
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
18,127✔
1685
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
18,127✔
1686
        if (value == NULL) {
18,127✔
1687
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1688
        }
1689
        (void)memset(value, 0, valuelen);
18,127✔
1690
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
18,127✔
1691

1692
        TAOS_CHECK_GOTO(taosHashPut(pUser->alterViews, key, keyLen, value, valuelen), &lino, _OVER);
18,127✔
1693
      }
1694
    }
1695

1696
    for (int32_t i = 0; i < numOfUseDbs; ++i) {
1,211,305✔
1697
      int32_t keyLen = 0;
329,601✔
1698
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
329,601✔
1699

1700
      TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
329,601✔
1701
      if (key == NULL) {
329,601✔
1702
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1703
      }
1704
      (void)memset(key, 0, keyLen);
329,601✔
1705
      SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
329,601✔
1706

1707
      int32_t ref = 0;
329,601✔
1708
      SDB_GET_INT32(pRaw, dataPos, &ref, _OVER);
329,601✔
1709

1710
      TAOS_CHECK_GOTO(taosHashPut(pUser->useDbs, key, keyLen, &ref, sizeof(ref)), &lino, _OVER);
329,601✔
1711
    }
1712
  }
1713
  // decoder white list
1714
  if (sver >= USER_VER_SUPPORT_WHITELIST) {
881,704✔
1715
    if (sver < USER_VER_SUPPORT_WHITELIT_DUAL_STACK) {
881,704✔
1716
      int32_t len = 0;
×
1717
      SDB_GET_INT32(pRaw, dataPos, &len, _OVER);
×
1718

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

1725
      SIpWhiteList *pIpWhiteList = NULL;
×
1726
      TAOS_CHECK_GOTO(createIpWhiteListFromOldVer(key, len, &pIpWhiteList), &lino, _OVER);
×
1727

1728
      SDB_GET_INT64(pRaw, dataPos, &pUser->ipWhiteListVer, _OVER);
×
1729

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

1736
      taosMemoryFreeClear(pIpWhiteList);
×
1737

1738
    } else if (sver >= USER_VER_SUPPORT_WHITELIT_DUAL_STACK) {
881,704✔
1739
      int32_t len = 0;
881,704✔
1740
      SDB_GET_INT32(pRaw, dataPos, &len, _OVER);
881,704✔
1741

1742
      TAOS_MEMORY_REALLOC(key, len);
881,704✔
1743
      if (key == NULL) {
881,704✔
1744
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1745
      }
1746
      SDB_GET_BINARY(pRaw, dataPos, key, len, _OVER);
881,704✔
1747

1748
      TAOS_CHECK_GOTO(createIpWhiteList(key, len, &pUser->pIpWhiteListDual, sver >= USER_VER_SUPPORT_ADVANCED_SECURITY), &lino, _OVER);
881,704✔
1749
      SDB_GET_INT64(pRaw, dataPos, &pUser->ipWhiteListVer, _OVER);
881,704✔
1750
    }
1751
  }
1752

1753
  if (pUser->pIpWhiteListDual == NULL) {
881,704✔
1754
    TAOS_CHECK_GOTO(createDefaultIpWhiteList(&pUser->pIpWhiteListDual), &lino, _OVER);
×
1755
    pUser->ipWhiteListVer = taosGetTimestampMs();
×
1756
  }
1757

1758
  SDB_GET_INT8(pRaw, dataPos, &pUser->passEncryptAlgorithm, _OVER);
881,704✔
1759

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

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

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

1814
  SDB_GET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
881,704✔
1815
  taosInitRWLatch(&pUser->lock);
881,704✔
1816
  dropOldPasswords(pUser);
881,704✔
1817

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

1843
  mTrace("user:%s, decode from raw:%p, row:%p", pUser->user, pRaw, pUser);
881,704✔
1844
  return pRow;
881,704✔
1845
}
1846

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

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

1859
  return 0;
280,380✔
1860
}
1861

1862
int32_t mndDupTableHash(SHashObj *pOld, SHashObj **ppNew) {
22,496,486✔
1863
  int32_t code = 0;
22,496,486✔
1864
  *ppNew =
22,496,486✔
1865
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
22,496,486✔
1866
  if (*ppNew == NULL) {
22,496,486✔
1867
    TAOS_RETURN(terrno);
×
1868
  }
1869

1870
  char *tb = taosHashIterate(pOld, NULL);
22,496,486✔
1871
  while (tb != NULL) {
23,998,815✔
1872
    size_t keyLen = 0;
1,502,329✔
1873
    char  *key = taosHashGetKey(tb, &keyLen);
1,502,329✔
1874

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

1884
  TAOS_RETURN(code);
22,496,486✔
1885
}
1886

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

1895
  int32_t *db = taosHashIterate(pOld, NULL);
955,558✔
1896
  while (db != NULL) {
1,273,864✔
1897
    size_t keyLen = 0;
318,306✔
1898
    char  *key = taosHashGetKey(db, &keyLen);
318,306✔
1899

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

1908
  TAOS_RETURN(code);
955,558✔
1909
}
1910

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

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

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

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

1955
  pNew->pTimeWhiteList = cloneDateTimeWhiteList(pUser->pTimeWhiteList);
955,558✔
1956
  if (pNew->pTimeWhiteList == NULL) {
955,558✔
1957
    code = TSDB_CODE_OUT_OF_MEMORY;
×
1958
    goto _OVER;
×
1959
  }
1960

1961
_OVER:
955,558✔
1962
  taosRUnLockLatch(&pUser->lock);
955,558✔
1963
  TAOS_RETURN(code);
955,558✔
1964
}
1965

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

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

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

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

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

2038
  TSWAP(pOld->pIpWhiteListDual, pNew->pIpWhiteListDual);
572,547✔
2039
  pOld->ipWhiteListVer = pNew->ipWhiteListVer;
572,547✔
2040
  TSWAP(pOld->pTimeWhiteList, pNew->pTimeWhiteList);
572,547✔
2041
  pOld->timeWhiteListVer = pNew->timeWhiteListVer;
572,547✔
2042
  pOld->passEncryptAlgorithm = pNew->passEncryptAlgorithm;
572,547✔
2043

2044
  taosWUnLockLatch(&pOld->lock);
572,547✔
2045

2046
  return 0;
572,547✔
2047
}
2048

2049
int32_t mndAcquireUser(SMnode *pMnode, const char *userName, SUserObj **ppUser) {
44,430,452✔
2050
  int32_t code = 0;
44,430,452✔
2051
  SSdb   *pSdb = pMnode->pSdb;
44,430,452✔
2052

2053
  *ppUser = sdbAcquire(pSdb, SDB_USER, userName);
44,430,452✔
2054
  if (*ppUser == NULL) {
44,430,462✔
2055
    if (terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
59,276✔
2056
      code = TSDB_CODE_MND_USER_NOT_EXIST;
59,276✔
2057
    } else {
2058
      code = TSDB_CODE_MND_USER_NOT_AVAILABLE;
×
2059
    }
2060
  }
2061
  TAOS_RETURN(code);
44,430,600✔
2062
}
2063

2064
void mndReleaseUser(SMnode *pMnode, SUserObj *pUser) {
44,443,928✔
2065
  SSdb *pSdb = pMnode->pSdb;
44,443,928✔
2066
  sdbRelease(pSdb, pUser);
44,444,066✔
2067
}
44,444,361✔
2068

2069

2070

2071
int32_t mndEncryptPass(char *pass, const char* salt, int8_t *algo) {
54,318✔
2072
  int32_t code = 0;
54,318✔
2073
  if (tsiEncryptPassAlgorithm != DND_CA_SM4) {
54,318✔
2074
    return 0;
53,896✔
2075
  }
2076

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

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

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

2098
  memcpy(pass, packetData, newLen);
422✔
2099
  if (algo != NULL) {
422✔
2100
    *algo = DND_CA_SM4;
211✔
2101
  }
2102

2103
  return 0;
422✔
2104
}
2105

2106

2107

2108
static void generateSalt(char *salt, size_t len) {
49,856✔
2109
  const char* set = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
49,856✔
2110
  int32_t     setLen = 62;
49,856✔
2111
  for (int32_t i = 0; i < len - 1; ++i) {
1,595,392✔
2112
    salt[i] = set[taosSafeRand() % setLen];
1,545,536✔
2113
  }
2114
  salt[len - 1] = 0;
49,856✔
2115
}
49,856✔
2116

2117

2118

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

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

2128
  code = taosHashPut(pUniqueTab, &ipv4, sizeof(ipv4), &dummpy, sizeof(dummpy));
607✔
2129
  TSDB_CHECK_CODE(code, lino, _error);
607✔
2130

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

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

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

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

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

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

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

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

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

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

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

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

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

2242
    taosHashCleanup(pUniqueTab);
607✔
2243
    p->num = numOfRanges;
607✔
2244
    sortIpWhiteList(p);
607✔
2245
    userObj.pIpWhiteListDual = p;
607✔
2246
  }
2247

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

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

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

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

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

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

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

2302
  userObj.ipWhiteListVer = taosGetTimestampMs();
49,434✔
2303
  userObj.timeWhiteListVer = userObj.ipWhiteListVer;
49,434✔
2304

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

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

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

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

2331
  mndTransDrop(pTrans);
49,434✔
2332

2333
_OVER:
49,434✔
2334
  taosMemoryFree(userObj.passwords);
49,434✔
2335
  taosMemoryFree(userObj.pIpWhiteListDual);
49,434✔
2336
  taosMemoryFree(userObj.pTimeWhiteList);
49,434✔
2337
  TAOS_RETURN(code);
49,434✔
2338
}
2339

2340

2341
static int32_t mndCheckPasswordFmt(const char *pwd) {
54,493✔
2342
  if (strcmp(pwd, "taosdata") == 0) {
54,493✔
2343
    return 0;
12,828✔
2344
  }
2345

2346
  if (tsEnableStrongPassword == 0) {
41,665✔
2347
    for (char c = *pwd; c != 0; c = *(++pwd)) {
57,814✔
2348
      if (c == ' ' || c == '\'' || c == '\"' || c == '`' || c == '\\') {
57,181✔
2349
        return TSDB_CODE_MND_INVALID_PASS_FORMAT;
×
2350
      }
2351
    }
2352
    return 0;
633✔
2353
  }
2354

2355
  int32_t len = strlen(pwd);
41,032✔
2356
  if (len < TSDB_PASSWORD_MIN_LEN) {
41,032✔
2357
    return TSDB_CODE_PAR_PASSWD_TOO_SHORT_OR_EMPTY;
×
2358
  }
2359

2360
  if (len > TSDB_PASSWORD_MAX_LEN) {
41,032✔
2361
    return TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG;
×
2362
  }
2363

2364
  if (taosIsComplexString(pwd)) {
41,032✔
2365
    return 0;
41,032✔
2366
  }
2367

2368
  return TSDB_CODE_MND_INVALID_PASS_FORMAT;
×
2369
}
2370

2371

2372

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

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

2383
  return TSDB_CODE_PAR_INVALID_OPTION_VALUE;
×
2384
}
2385

2386

2387

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

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

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

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

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

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

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

2441

2442

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

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

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

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

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

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

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

2487

2488

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

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

2503
  TAOS_CHECK_GOTO(buildRetrieveDateTimeWhiteListRsp(&wlRsp), &lino, _OVER);
1,055✔
2504

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

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

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

2530
  tFreeSRetrieveDateTimeWhiteListRsp(&wlRsp);
1,055✔
2531
  TAOS_RETURN(code);
1,055✔
2532
}
2533

2534

2535

2536
static int32_t mndProcessCreateUserReq(SRpcMsg *pReq) {
49,820✔
2537
  SMnode        *pMnode = pReq->info.node;
49,820✔
2538
  int32_t        code = 0;
49,820✔
2539
  int32_t        lino = 0;
49,820✔
2540
  SUserObj      *pUser = NULL;
49,820✔
2541
  SUserObj      *pOperUser = NULL;
49,820✔
2542
  SCreateUserReq createReq = {0};
49,820✔
2543

2544
  if (tDeserializeSCreateUserReq(pReq->pCont, pReq->contLen, &createReq) != 0) {
49,820✔
2545
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
2546
  }
2547

2548
  mInfo("user:%s, start to create, createdb:%d, is_import:%d", createReq.user, createReq.createDb, createReq.isImport);
49,820✔
2549

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

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

2563
  if (createReq.user[0] == 0) {
49,820✔
2564
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
2565
  }
2566

2567
  if (createReq.isImport != 1) {
49,820✔
2568
    code = mndCheckPasswordFmt(createReq.pass);
49,820✔
2569
    TAOS_CHECK_GOTO(code, &lino, _OVER);
49,820✔
2570
  }
2571

2572
  if (createReq.totpseed[0] != 0) {
49,820✔
2573
    code = mndCheckTotpSeedFmt(createReq.totpseed);
×
2574
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2575
  }
2576

2577
  code = mndAcquireUser(pMnode, createReq.user, &pUser);
49,820✔
2578
  if (pUser != NULL) {
49,820✔
2579
    TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_ALREADY_EXIST, &lino, _OVER);
386✔
2580
  }
2581

2582
  code = mndAcquireUser(pMnode, pReq->info.conn.user, &pOperUser);
49,434✔
2583
  if (pOperUser == NULL) {
49,434✔
2584
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_USER_FROM_CONN, &lino, _OVER);
×
2585
  }
2586

2587
  TAOS_CHECK_GOTO(grantCheck(TSDB_GRANT_USER), &lino, _OVER);
49,434✔
2588

2589
  code = mndCreateUser(pMnode, pOperUser->acct, &createReq, pReq);
49,434✔
2590
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
49,434✔
2591

2592
  char detail[1000] = {0};
49,434✔
2593
  (void)tsnprintf(detail, sizeof(detail), "enable:%d, superUser:%d, sysInfo:%d, password:xxx", createReq.enable,
49,434✔
2594
                  createReq.superUser, createReq.sysInfo);
49,434✔
2595
  char operation[15] = {0};
49,434✔
2596
  if (createReq.isImport == 1) {
49,434✔
2597
    tstrncpy(operation, "importUser", sizeof(operation));
×
2598
  } else {
2599
    tstrncpy(operation, "createUser", sizeof(operation));
49,434✔
2600
  }
2601

2602
  auditRecord(pReq, pMnode->clusterId, operation, "", createReq.user, detail, strlen(detail));
49,434✔
2603

2604
_OVER:
49,820✔
2605
  if (code == TSDB_CODE_MND_USER_ALREADY_EXIST && createReq.ignoreExisting) {
49,820✔
2606
    code = 0;
×
2607
  } else if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
49,820✔
2608
    mError("user:%s, failed to create at line %d since %s", createReq.user, lino, tstrerror(code));
386✔
2609
  }
2610

2611
  mndReleaseUser(pMnode, pUser);
49,820✔
2612
  mndReleaseUser(pMnode, pOperUser);
49,820✔
2613
  tFreeSCreateUserReq(&createReq);
49,820✔
2614

2615
  TAOS_RETURN(code);
49,820✔
2616
}
2617

2618

2619

2620
static int32_t mndProcessGetUserIpWhiteListReq(SRpcMsg *pReq) {
76,590✔
2621
  SMnode              *pMnode = pReq->info.node;
76,590✔
2622
  int32_t              code = 0;
76,590✔
2623
  int32_t              lino = 0;
76,590✔
2624
  int32_t              contLen = 0;
76,590✔
2625
  void                *pRsp = NULL;
76,590✔
2626
  SUserObj            *pUser = NULL;
76,590✔
2627
  SGetUserWhiteListReq wlReq = {0};
76,590✔
2628
  SGetUserIpWhiteListRsp wlRsp = {0};
76,590✔
2629

2630
  int32_t (*serialFn)(void *, int32_t, SGetUserIpWhiteListRsp *) = NULL;
76,590✔
2631
  int32_t (*setRspFn)(SMnode * pMnode, SUserObj * pUser, SGetUserIpWhiteListRsp * pRsp) = NULL;
76,590✔
2632

2633
  if (pReq->msgType == TDMT_MND_GET_USER_IP_WHITELIST_DUAL) {
76,590✔
2634
    serialFn = tSerializeSGetUserIpWhiteListDualRsp;
76,590✔
2635
    setRspFn = mndSetUserIpWhiteListDualRsp;
76,590✔
2636
  } else {
2637
    serialFn = tSerializeSGetUserIpWhiteListRsp;
×
2638
    setRspFn = mndSetUserIpWhiteListRsp;
×
2639
  }
2640
  if (tDeserializeSGetUserWhiteListReq(pReq->pCont, pReq->contLen, &wlReq) != 0) {
76,590✔
2641
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
2642
  }
2643
  mTrace("user: %s, start to get ip whitelist", wlReq.user);
76,590✔
2644

2645
  code = mndAcquireUser(pMnode, wlReq.user, &pUser);
76,590✔
2646
  if (pUser == NULL) {
76,590✔
2647
    TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_NOT_EXIST, &lino, _OVER);
×
2648
  }
2649

2650
  TAOS_CHECK_GOTO(setRspFn(pMnode, pUser, &wlRsp), &lino, _OVER);
76,590✔
2651
  contLen = serialFn(NULL, 0, &wlRsp);
76,590✔
2652
  if (contLen < 0) {
76,590✔
2653
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2654
  }
2655
  pRsp = rpcMallocCont(contLen);
76,590✔
2656
  if (pRsp == NULL) {
76,590✔
2657
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2658
  }
2659

2660
  contLen = serialFn(pRsp, contLen, &wlRsp);
76,590✔
2661
  if (contLen < 0) {
76,590✔
2662
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2663
  }
2664

2665
_OVER:
76,590✔
2666
  mndReleaseUser(pMnode, pUser);
76,590✔
2667
  tFreeSGetUserIpWhiteListDualRsp(&wlRsp);
76,590✔
2668
  if (code < 0) {
76,590✔
2669
    mError("user:%s, failed to get whitelist at line %d since %s", wlReq.user, lino, tstrerror(code));
×
2670
    rpcFreeCont(pRsp);
×
2671
    pRsp = NULL;
×
2672
    contLen = 0;
×
2673
  }
2674
  pReq->code = code;
76,590✔
2675
  pReq->info.rsp = pRsp;
76,590✔
2676
  pReq->info.rspLen = contLen;
76,590✔
2677

2678
  TAOS_RETURN(code);
76,590✔
2679
}
2680

2681

2682

2683
static int32_t buildRetrieveIpWhiteListRsp(SUpdateIpWhite *pUpdate) {
1,055✔
2684
  (void)taosThreadRwlockWrlock(&userCache.rw);
1,055✔
2685

2686
  int32_t count = taosHashGetSize(userCache.users);
1,055✔
2687
  pUpdate->pUserIpWhite = taosMemoryCalloc(count, sizeof(SUpdateUserIpWhite));
1,055✔
2688
  if (pUpdate->pUserIpWhite == NULL) {
1,055✔
2689
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
2690
    TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
2691
  }
2692

2693
  count = 0;
1,055✔
2694
  void   *pIter = taosHashIterate(userCache.users, NULL);
1,055✔
2695
  while (pIter) {
2,110✔
2696
    SIpWhiteListDual   *wl = (*(SCachedUserInfo**)pIter)->wlIp;
1,055✔
2697
    if (wl == NULL || wl->num <= 0) {
1,055✔
2698
      pIter = taosHashIterate(userCache.users, pIter);
×
2699
      continue;
×
2700
    }
2701

2702
    SUpdateUserIpWhite *pUser = &pUpdate->pUserIpWhite[count];
1,055✔
2703
    pUser->ver = userCache.verIp;
1,055✔
2704

2705
    size_t klen;
1,055✔
2706
    char  *key = taosHashGetKey(pIter, &klen);
1,055✔
2707
    (void)memcpy(pUser->user, key, klen);
1,055✔
2708

2709
    pUser->numOfRange = wl->num;
1,055✔
2710
    pUser->pIpRanges = taosMemoryCalloc(wl->num, sizeof(SIpRange));
1,055✔
2711
    if (pUser->pIpRanges == NULL) {
1,055✔
2712
      (void)taosThreadRwlockUnlock(&userCache.rw);
×
2713
      TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
2714
    }
2715

2716
    (void)memcpy(pUser->pIpRanges, wl->pIpRanges, wl->num * sizeof(SIpRange));
1,055✔
2717
    count++;
1,055✔
2718
    pIter = taosHashIterate(userCache.users, pIter);
1,055✔
2719
  }
2720

2721
  pUpdate->numOfUser = count;
1,055✔
2722
  pUpdate->ver = userCache.verIp;
1,055✔
2723
  (void)taosThreadRwlockUnlock(&userCache.rw);
1,055✔
2724
  TAOS_RETURN(0);
1,055✔
2725
}
2726

2727

2728

2729
int32_t mndProcessRetrieveIpWhiteListReq(SRpcMsg *pReq) {
1,055✔
2730
  int32_t        code = 0;
1,055✔
2731
  int32_t        lino = 0;
1,055✔
2732
  int32_t        len = 0;
1,055✔
2733
  void          *pRsp = NULL;
1,055✔
2734
  SUpdateIpWhite ipWhite = {0};
1,055✔
2735

2736
  // impl later
2737
  SRetrieveWhiteListReq req = {0};
1,055✔
2738
  if (tDeserializeRetrieveWhiteListReq(pReq->pCont, pReq->contLen, &req) != 0) {
1,055✔
2739
    code = TSDB_CODE_INVALID_MSG;
×
2740
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2741
  }
2742

2743
  int32_t (*fn)(void *, int32_t, SUpdateIpWhite *) = NULL;
1,055✔
2744
  if (pReq->msgType == TDMT_MND_RETRIEVE_IP_WHITELIST) {
1,055✔
2745
    fn = tSerializeSUpdateIpWhite;
×
2746
  } else if (pReq->msgType == TDMT_MND_RETRIEVE_IP_WHITELIST_DUAL) {
1,055✔
2747
    fn = tSerializeSUpdateIpWhiteDual;
1,055✔
2748
  }
2749

2750
  TAOS_CHECK_GOTO(buildRetrieveIpWhiteListRsp(&ipWhite), &lino, _OVER);
1,055✔
2751

2752
  len = fn(NULL, 0, &ipWhite);
1,055✔
2753
  if (len < 0) {
1,055✔
2754
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
2755
  }
2756

2757
  pRsp = rpcMallocCont(len);
1,055✔
2758
  if (!pRsp) {
1,055✔
2759
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2760
  }
2761
  len = fn(pRsp, len, &ipWhite);
1,055✔
2762
  if (len < 0) {
1,055✔
2763
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
2764
  }
2765

2766
_OVER:
1,055✔
2767
  if (code < 0) {
1,055✔
2768
    mError("failed to process retrieve ip white request at line %d since %s", lino, tstrerror(code));
×
2769
    rpcFreeCont(pRsp);
×
2770
    pRsp = NULL;
×
2771
    len = 0;
×
2772
  }
2773
  pReq->code = code;
1,055✔
2774
  pReq->info.rsp = pRsp;
1,055✔
2775
  pReq->info.rspLen = len;
1,055✔
2776

2777
  tFreeSUpdateIpWhiteReq(&ipWhite);
1,055✔
2778
  TAOS_RETURN(code);
1,055✔
2779
}
2780

2781

2782

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

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

2804
  if (mndTransPrepare(pMnode, pTrans) != 0) {
×
2805
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
2806
    mndTransDrop(pTrans);
×
2807
    return;
×
2808
  }
2809

2810
  mndTransDrop(pTrans);
×
2811
}
2812

2813

2814

2815
static int32_t mndAlterUser(SMnode *pMnode, SUserObj *pOld, SUserObj *pNew, SRpcMsg *pReq) {
563,916✔
2816
  int32_t code = 0;
563,916✔
2817
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "alter-user");
563,916✔
2818
  if (pTrans == NULL) {
563,916✔
2819
    mError("user:%s, failed to alter since %s", pOld->user, terrstr());
×
2820
    TAOS_RETURN(terrno);
×
2821
  }
2822
  mInfo("trans:%d, used to alter user:%s", pTrans->id, pOld->user);
563,916✔
2823

2824
  SSdbRaw *pCommitRaw = mndUserActionEncode(pNew);
563,916✔
2825
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
563,916✔
2826
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
2827
    mndTransDrop(pTrans);
×
2828
    TAOS_RETURN(terrno);
×
2829
  }
2830
  code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
563,916✔
2831
  if (code < 0) {
563,916✔
2832
    mndTransDrop(pTrans);
×
2833
    TAOS_RETURN(code);
×
2834
  }
2835

2836
  if (mndTransPrepare(pMnode, pTrans) != 0) {
563,916✔
2837
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
2838
    mndTransDrop(pTrans);
×
2839
    TAOS_RETURN(terrno);
×
2840
  }
2841
  if ((code = userCacheUpdateWhiteList(pMnode, pNew)) != 0) {
563,916✔
2842
    mndTransDrop(pTrans);
×
2843
    TAOS_RETURN(code);
×
2844
  }
2845
  mndTransDrop(pTrans);
563,916✔
2846
  return 0;
563,916✔
2847
}
2848

2849
static int32_t mndDupObjHash(SHashObj *pOld, int32_t dataLen, SHashObj **ppNew) {
7,656,142✔
2850
  int32_t code = 0;
7,656,142✔
2851

2852
  *ppNew =
7,656,142✔
2853
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
7,656,142✔
2854
  if (*ppNew == NULL) {
7,656,142✔
2855
    code = terrno ? terrno : TSDB_CODE_OUT_OF_MEMORY;
×
2856
    TAOS_RETURN(code);
×
2857
  }
2858

2859
  char *db = taosHashIterate(pOld, NULL);
7,656,142✔
2860
  while (db != NULL) {
8,363,143✔
2861
    int32_t len = strlen(db) + 1;
707,001✔
2862
    if ((code = taosHashPut(*ppNew, db, len, db, dataLen)) != 0) {
707,001✔
2863
      taosHashCancelIterate(pOld, db);
×
2864
      taosHashCleanup(*ppNew);
×
2865
      TAOS_RETURN(code);
×
2866
    }
2867
    db = taosHashIterate(pOld, db);
707,001✔
2868
  }
2869

2870
  TAOS_RETURN(code);
7,656,142✔
2871
}
2872

2873
int32_t mndDupDbHash(SHashObj *pOld, SHashObj **ppNew) { return mndDupObjHash(pOld, TSDB_DB_FNAME_LEN, ppNew); }
6,700,584✔
2874

2875
int32_t mndDupTopicHash(SHashObj *pOld, SHashObj **ppNew) { return mndDupObjHash(pOld, TSDB_TOPIC_FNAME_LEN, ppNew); }
955,558✔
2876

2877
static int32_t mndTablePriviledge(SMnode *pMnode, SHashObj *hash, SHashObj *useDbHash, SAlterUserReq *alterReq,
285,520✔
2878
                                  SSdb *pSdb) {
2879
  void *pIter = NULL;
285,520✔
2880
  char  tbFName[TSDB_TABLE_FNAME_LEN] = {0};
285,520✔
2881

2882
  (void)snprintf(tbFName, sizeof(tbFName), "%s.%s", alterReq->objname, alterReq->tabName);
285,520✔
2883
  int32_t len = strlen(tbFName) + 1;
285,520✔
2884

2885
  if (alterReq->tagCond != NULL && alterReq->tagCondLen != 0) {
330,432✔
2886
    char *value = taosHashGet(hash, tbFName, len);
44,912✔
2887
    if (value != NULL) {
44,912✔
2888
      TAOS_RETURN(TSDB_CODE_MND_PRIVILEDGE_EXIST);
×
2889
    }
2890

2891
    int32_t condLen = alterReq->tagCondLen;
44,912✔
2892
    TAOS_CHECK_RETURN(taosHashPut(hash, tbFName, len, alterReq->tagCond, condLen));
44,912✔
2893
  } else {
2894
    TAOS_CHECK_RETURN(taosHashPut(hash, tbFName, len, alterReq->isView ? "v" : "t", 2));
240,608✔
2895
  }
2896

2897
  int32_t  dbKeyLen = strlen(alterReq->objname) + 1;
285,520✔
2898
  int32_t  ref = 1;
285,520✔
2899
  int32_t *currRef = taosHashGet(useDbHash, alterReq->objname, dbKeyLen);
285,520✔
2900
  if (NULL != currRef) {
285,520✔
2901
    ref = (*currRef) + 1;
169,334✔
2902
  }
2903
  TAOS_CHECK_RETURN(taosHashPut(useDbHash, alterReq->objname, dbKeyLen, &ref, sizeof(ref)));
285,520✔
2904

2905
  TAOS_RETURN(0);
285,520✔
2906
}
2907

2908
static int32_t mndRemoveTablePriviledge(SMnode *pMnode, SHashObj *hash, SHashObj *useDbHash, SAlterUserReq *alterReq,
266,647✔
2909
                                        SSdb *pSdb) {
2910
  void *pIter = NULL;
266,647✔
2911
  char  tbFName[TSDB_TABLE_FNAME_LEN] = {0};
266,647✔
2912
  (void)snprintf(tbFName, sizeof(tbFName), "%s.%s", alterReq->objname, alterReq->tabName);
266,647✔
2913
  int32_t len = strlen(tbFName) + 1;
266,647✔
2914

2915
  if (taosHashRemove(hash, tbFName, len) != 0) {
266,647✔
2916
    TAOS_RETURN(0);  // not found
663✔
2917
  }
2918

2919
  int32_t  dbKeyLen = strlen(alterReq->objname) + 1;
265,984✔
2920
  int32_t *currRef = taosHashGet(useDbHash, alterReq->objname, dbKeyLen);
265,984✔
2921
  if (NULL == currRef) {
265,984✔
2922
    return 0;
×
2923
  }
2924

2925
  if (1 == *currRef) {
265,984✔
2926
    if (taosHashRemove(useDbHash, alterReq->objname, dbKeyLen) != 0) {
109,661✔
2927
      TAOS_RETURN(0);  // not found
×
2928
    }
2929
    return 0;
109,661✔
2930
  }
2931
  int32_t ref = (*currRef) - 1;
156,323✔
2932
  TAOS_CHECK_RETURN(taosHashPut(useDbHash, alterReq->objname, dbKeyLen, &ref, sizeof(ref)));
156,323✔
2933

2934
  return 0;
156,323✔
2935
}
2936

2937
static char *mndUserAuditTypeStr(int32_t type) {
×
2938
  #if 0
2939
  if (type == TSDB_ALTER_USER_PASSWD) {
2940
    return "changePassword";
2941
  }
2942
  if (type == TSDB_ALTER_USER_SUPERUSER) {
2943
    return "changeSuperUser";
2944
  }
2945
  if (type == TSDB_ALTER_USER_ENABLE) {
2946
    return "enableUser";
2947
  }
2948
  if (type == TSDB_ALTER_USER_SYSINFO) {
2949
    return "userSysInfo";
2950
  }
2951
  if (type == TSDB_ALTER_USER_CREATEDB) {
2952
    return "userCreateDB";
2953
  }
2954
    #endif
2955
  return "error";
×
2956
}
2957

2958
static int32_t mndProcessAlterUserPrivilegesReq(SAlterUserReq *pAlterReq, SMnode *pMnode, SUserObj *pNewUser) {
553,214✔
2959
  SSdb   *pSdb = pMnode->pSdb;
553,214✔
2960
  void   *pIter = NULL;
553,214✔
2961
  int32_t code = 0;
553,214✔
2962
  int32_t lino = 0;
553,214✔
2963

2964
  if (ALTER_USER_ADD_READ_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
553,214✔
2965
      ALTER_USER_ADD_ALL_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
476,214✔
2966
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
77,000✔
2967
      int32_t len = strlen(pAlterReq->objname) + 1;
75,022✔
2968
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
75,022✔
2969
      if (pDb == NULL) {
75,022✔
2970
        mndReleaseDb(pMnode, pDb);
1,504✔
2971
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
1,504✔
2972
      }
2973
      if ((code = taosHashPut(pNewUser->readDbs, pAlterReq->objname, len, pAlterReq->objname, TSDB_DB_FNAME_LEN)) !=
73,518✔
2974
          0) {
2975
        mndReleaseDb(pMnode, pDb);
×
2976
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2977
      }
2978
      mndReleaseDb(pMnode, pDb);
73,518✔
2979
    } else {
2980
      while (1) {
3,232✔
2981
        SDbObj *pDb = NULL;
5,210✔
2982
        pIter = sdbFetch(pSdb, SDB_DB, pIter, (void **)&pDb);
5,210✔
2983
        if (pIter == NULL) break;
5,210✔
2984
        int32_t len = strlen(pDb->name) + 1;
3,232✔
2985
        if ((code = taosHashPut(pNewUser->readDbs, pDb->name, len, pDb->name, TSDB_DB_FNAME_LEN)) != 0) {
3,232✔
2986
          sdbRelease(pSdb, pDb);
×
2987
          sdbCancelFetch(pSdb, pIter);
×
2988
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2989
        }
2990
        sdbRelease(pSdb, pDb);
3,232✔
2991
      }
2992
    }
2993
  }
2994

2995
  if (ALTER_USER_ADD_WRITE_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
551,710✔
2996
      ALTER_USER_ADD_ALL_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
476,767✔
2997
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
74,943✔
2998
      int32_t len = strlen(pAlterReq->objname) + 1;
73,158✔
2999
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
73,158✔
3000
      if (pDb == NULL) {
73,158✔
3001
        mndReleaseDb(pMnode, pDb);
209✔
3002
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
209✔
3003
      }
3004
      if ((code = taosHashPut(pNewUser->writeDbs, pAlterReq->objname, len, pAlterReq->objname, TSDB_DB_FNAME_LEN)) !=
72,949✔
3005
          0) {
3006
        mndReleaseDb(pMnode, pDb);
×
3007
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3008
      }
3009
      mndReleaseDb(pMnode, pDb);
72,949✔
3010
    } else {
3011
      while (1) {
3,039✔
3012
        SDbObj *pDb = NULL;
4,824✔
3013
        pIter = sdbFetch(pSdb, SDB_DB, pIter, (void **)&pDb);
4,824✔
3014
        if (pIter == NULL) break;
4,824✔
3015
        int32_t len = strlen(pDb->name) + 1;
3,039✔
3016
        if ((code = taosHashPut(pNewUser->writeDbs, pDb->name, len, pDb->name, TSDB_DB_FNAME_LEN)) != 0) {
3,039✔
3017
          sdbRelease(pSdb, pDb);
×
3018
          sdbCancelFetch(pSdb, pIter);
×
3019
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3020
        }
3021
        sdbRelease(pSdb, pDb);
3,039✔
3022
      }
3023
    }
3024
  }
3025

3026
  if (ALTER_USER_DEL_READ_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
551,501✔
3027
      ALTER_USER_DEL_ALL_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
479,232✔
3028
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
72,269✔
3029
      int32_t len = strlen(pAlterReq->objname) + 1;
70,291✔
3030
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
70,291✔
3031
      if (pDb == NULL) {
70,291✔
3032
        mndReleaseDb(pMnode, pDb);
193✔
3033
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
193✔
3034
      }
3035
      code = taosHashRemove(pNewUser->readDbs, pAlterReq->objname, len);
70,098✔
3036
      if (code < 0) {
70,098✔
3037
        mError("read db:%s, failed to remove db:%s since %s", pNewUser->user, pAlterReq->objname, terrstr());
×
3038
      }
3039
      mndReleaseDb(pMnode, pDb);
70,098✔
3040
    } else {
3041
      taosHashClear(pNewUser->readDbs);
1,978✔
3042
    }
3043
  }
3044

3045
  if (ALTER_USER_DEL_WRITE_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
551,308✔
3046
      ALTER_USER_DEL_ALL_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
479,672✔
3047
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
71,636✔
3048
      int32_t len = strlen(pAlterReq->objname) + 1;
69,465✔
3049
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
69,465✔
3050
      if (pDb == NULL) {
69,465✔
3051
        mndReleaseDb(pMnode, pDb);
×
3052
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
×
3053
      }
3054
      code = taosHashRemove(pNewUser->writeDbs, pAlterReq->objname, len);
69,465✔
3055
      if (code < 0) {
69,465✔
3056
        mError("user:%s, failed to remove db:%s since %s", pNewUser->user, pAlterReq->objname, terrstr());
×
3057
      }
3058
      mndReleaseDb(pMnode, pDb);
69,465✔
3059
    } else {
3060
      taosHashClear(pNewUser->writeDbs);
2,171✔
3061
    }
3062
  }
3063

3064
  SHashObj *pReadTbs = pNewUser->readTbs;
551,308✔
3065
  SHashObj *pWriteTbs = pNewUser->writeTbs;
551,308✔
3066
  SHashObj *pAlterTbs = pNewUser->alterTbs;
551,308✔
3067

3068
#ifdef TD_ENTERPRISE
3069
  if (pAlterReq->isView) {
551,308✔
3070
    pReadTbs = pNewUser->readViews;
7,114✔
3071
    pWriteTbs = pNewUser->writeViews;
7,114✔
3072
    pAlterTbs = pNewUser->alterViews;
7,114✔
3073
  }
3074
#endif
3075

3076
  if (ALTER_USER_ADD_READ_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
551,308✔
3077
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
438,284✔
3078
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pReadTbs, pNewUser->useDbs, pAlterReq, pSdb), &lino, _OVER);
113,024✔
3079
  }
3080

3081
  if (ALTER_USER_ADD_WRITE_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
551,308✔
3082
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
439,278✔
3083
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pWriteTbs, pNewUser->useDbs, pAlterReq, pSdb), &lino, _OVER);
112,030✔
3084
  }
3085

3086
  if (ALTER_USER_ADD_ALTER_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
551,308✔
3087
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
490,842✔
3088
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pAlterTbs, pNewUser->useDbs, pAlterReq, pSdb), &lino, _OVER);
60,466✔
3089
  }
3090

3091
  if (ALTER_USER_DEL_READ_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
551,308✔
3092
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
445,055✔
3093
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pReadTbs, pNewUser->useDbs, pAlterReq, pSdb), &lino, _OVER);
106,253✔
3094
  }
3095

3096
  if (ALTER_USER_DEL_WRITE_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
551,308✔
3097
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
445,129✔
3098
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pWriteTbs, pNewUser->useDbs, pAlterReq, pSdb), &lino, _OVER);
106,179✔
3099
  }
3100

3101
  if (ALTER_USER_DEL_ALTER_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
551,308✔
3102
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
497,093✔
3103
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pAlterTbs, pNewUser->useDbs, pAlterReq, pSdb), &lino, _OVER);
54,215✔
3104
  }
3105

3106
#ifdef USE_TOPIC
3107
  if (ALTER_USER_ADD_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, pAlterReq->privileges)) {
551,308✔
3108
    int32_t      len = strlen(pAlterReq->objname) + 1;
3,387✔
3109
    SMqTopicObj *pTopic = NULL;
3,387✔
3110
    if ((code = mndAcquireTopic(pMnode, pAlterReq->objname, &pTopic)) != 0) {
3,387✔
3111
      mndReleaseTopic(pMnode, pTopic);
×
3112
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3113
    }
3114
    if ((code = taosHashPut(pNewUser->topics, pTopic->name, len, pTopic->name, TSDB_TOPIC_FNAME_LEN)) != 0) {
3,387✔
3115
      mndReleaseTopic(pMnode, pTopic);
×
3116
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3117
    }
3118
    mndReleaseTopic(pMnode, pTopic);
3,387✔
3119
  }
3120

3121
  if (ALTER_USER_DEL_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, pAlterReq->privileges)) {
551,308✔
3122
    int32_t      len = strlen(pAlterReq->objname) + 1;
2,196✔
3123
    SMqTopicObj *pTopic = NULL;
2,196✔
3124
    if ((code = mndAcquireTopic(pMnode, pAlterReq->objname, &pTopic)) != 0) {
2,196✔
3125
      mndReleaseTopic(pMnode, pTopic);
198✔
3126
      TAOS_CHECK_GOTO(code, &lino, _OVER);
198✔
3127
    }
3128
    code = taosHashRemove(pNewUser->topics, pAlterReq->objname, len);
1,998✔
3129
    if (code < 0) {
1,998✔
3130
      mError("user:%s, failed to remove topic:%s since %s", pNewUser->user, pAlterReq->objname, tstrerror(code));
×
3131
    }
3132
    mndReleaseTopic(pMnode, pTopic);
1,998✔
3133
  }
3134
#endif
3135
_OVER:
553,214✔
3136
  if (code < 0) {
553,214✔
3137
    mError("user:%s, failed to alter user privileges at line %d since %s", pAlterReq->user, lino, tstrerror(code));
2,104✔
3138
  }
3139
  TAOS_RETURN(code);
553,214✔
3140
}
3141

3142
static int32_t mndProcessAlterUserReq(SRpcMsg *pReq) {
581,430✔
3143
  SMnode       *pMnode = pReq->info.node;
581,430✔
3144
  SSdb         *pSdb = pMnode->pSdb;
581,430✔
3145
  void         *pIter = NULL;
581,430✔
3146
  int32_t       code = 0;
581,430✔
3147
  int32_t       lino = 0;
581,430✔
3148
  SUserObj     *pUser = NULL;
581,430✔
3149
  SUserObj     *pOperUser = NULL;
581,430✔
3150
  SUserObj      newUser = {0};
581,430✔
3151
  SAlterUserReq alterReq = {0};
581,430✔
3152
  TAOS_CHECK_GOTO(tDeserializeSAlterUserReq(pReq->pCont, pReq->contLen, &alterReq), &lino, _OVER);
581,430✔
3153

3154
  mInfo("user:%s, start to alter", alterReq.user);
581,430✔
3155

3156
  if (alterReq.user[0] == 0) {
581,430✔
3157
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
3158
  }
3159

3160
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, alterReq.user, &pUser), &lino, _OVER);
581,430✔
3161

3162
  (void)mndAcquireUser(pMnode, pReq->info.conn.user, &pOperUser);
576,674✔
3163
  if (pOperUser == NULL) {
576,674✔
3164
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_USER_FROM_CONN, &lino, _OVER);
×
3165
  }
3166

3167
  TAOS_CHECK_GOTO(mndCheckAlterUserPrivilege(pOperUser, pUser, &alterReq), &lino, _OVER);
576,674✔
3168
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
566,231✔
3169

3170
  if (alterReq.hasPassword) {
566,231✔
3171
    TAOS_CHECK_GOTO(mndCheckPasswordFmt(alterReq.pass), &lino, _OVER);
4,673✔
3172
    if (newUser.salt[0] == 0) {
4,673✔
3173
      generateSalt(newUser.salt, sizeof(newUser.salt));
422✔
3174
    }
3175
    char pass[TSDB_PASSWORD_LEN] = {0};
4,673✔
3176
    taosEncryptPass_c((uint8_t *)alterReq.pass, strlen(alterReq.pass), pass);
4,673✔
3177
    pass[sizeof(pass) - 1] = 0;
4,673✔
3178
    TAOS_CHECK_GOTO(mndEncryptPass(pass, newUser.salt, &newUser.passEncryptAlgorithm), &lino, _OVER);
4,673✔
3179

3180
    if (newUser.passwordReuseMax > 0 || newUser.passwordReuseTime > 0) {
6,783✔
3181
      for(int32_t i = 0; i < newUser.numOfPasswords; ++i) {
10,339✔
3182
        if (0 == strncmp(newUser.passwords[i].pass, pass, TSDB_PASSWORD_LEN)) {
8,229✔
3183
          TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_PASSWORD_REUSE, &lino, _OVER);
211✔
3184
        }
3185
      }
3186
      SUserPassword *passwords = taosMemoryCalloc(newUser.numOfPasswords + 1, sizeof(SUserPassword));
2,110✔
3187
      if (passwords == NULL) {
2,110✔
3188
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3189
      }
3190
      memcpy(passwords + 1, newUser.passwords, newUser.numOfPasswords * sizeof(SUserPassword));
2,110✔
3191
      memcpy(passwords[0].pass, pass, TSDB_PASSWORD_LEN);
2,110✔
3192
      passwords[0].setTime = taosGetTimestampSec();
2,110✔
3193
      taosMemoryFree(newUser.passwords);
2,110✔
3194
      newUser.passwords = passwords;
2,110✔
3195
      ++newUser.numOfPasswords;
2,110✔
3196
      ++newUser.passVersion;
2,110✔
3197
      if (strcmp(newUser.user, pOperUser->user) == 0) {
2,110✔
3198
        // if user change own password, set changePass to 2 so that user won't be
3199
        // forced to change password at next login
3200
        newUser.changePass = 2;
211✔
3201
      }
3202
    } else if (0 != strncmp(newUser.passwords[0].pass, pass, TSDB_PASSWORD_LEN)) {
2,352✔
3203
      memcpy(newUser.passwords[0].pass, pass, TSDB_PASSWORD_LEN);
1,579✔
3204
      newUser.passwords[0].setTime = taosGetTimestampSec();
1,579✔
3205
      ++newUser.passVersion;
1,579✔
3206
      if (strcmp(newUser.user, pOperUser->user) == 0) {
1,579✔
3207
        newUser.changePass = 2;
192✔
3208
      }
3209
    }
3210
  }
3211

3212
  if (alterReq.hasTotpseed) {
566,020✔
3213
    if (alterReq.totpseed[0] == 0) { // clear totp secret
×
3214
      memset(newUser.totpsecret, 0, sizeof(newUser.totpsecret));
×
3215
    } else if (taosGenerateTotpSecret(alterReq.totpseed, 0, newUser.totpsecret, sizeof(newUser.totpsecret)) < 0) {
×
3216
      TAOS_CHECK_GOTO(TSDB_CODE_PAR_INVALID_OPTION_VALUE, &lino, _OVER);
×
3217
    }
3218
  }
3219

3220
  if (alterReq.hasEnable) {
566,020✔
3221
    newUser.enable = alterReq.enable; // lock or unlock user manually
1,368✔
3222
    if (newUser.enable) {
1,368✔
3223
      // reset login info to allow login immediately
3224
      userCacheResetLoginInfo(newUser.user);
773✔
3225
    }
3226
  }
3227

3228
  if (alterReq.hasSysinfo) newUser.sysInfo = alterReq.sysinfo;
566,020✔
3229
  if (alterReq.hasCreatedb) newUser.createdb = alterReq.createdb;
566,020✔
3230
  if (alterReq.hasChangepass) newUser.changePass = alterReq.changepass;
566,020✔
3231
  if (alterReq.hasSessionPerUser) newUser.sessionPerUser = alterReq.sessionPerUser;
566,020✔
3232
  if (alterReq.hasConnectTime) newUser.connectTime = alterReq.connectTime;
566,020✔
3233
  if (alterReq.hasConnectIdleTime) newUser.connectIdleTime = alterReq.connectIdleTime;
566,020✔
3234
  if (alterReq.hasCallPerSession) newUser.callPerSession = alterReq.callPerSession;
566,020✔
3235
  if (alterReq.hasVnodePerCall) newUser.vnodePerCall = alterReq.vnodePerCall;
566,020✔
3236
  if (alterReq.hasFailedLoginAttempts) newUser.failedLoginAttempts = alterReq.failedLoginAttempts;
566,020✔
3237
  if (alterReq.hasPasswordLifeTime) newUser.passwordLifeTime = alterReq.passwordLifeTime;
566,020✔
3238
  if (alterReq.hasPasswordReuseTime) newUser.passwordReuseTime = alterReq.passwordReuseTime;
566,020✔
3239
  if (alterReq.hasPasswordReuseMax) newUser.passwordReuseMax = alterReq.passwordReuseMax;
566,020✔
3240
  if (alterReq.hasPasswordLockTime) newUser.passwordLockTime = alterReq.passwordLockTime;
566,020✔
3241
  if (alterReq.hasPasswordGraceTime) newUser.passwordGraceTime = alterReq.passwordGraceTime;
566,020✔
3242
  if (alterReq.hasInactiveAccountTime) newUser.inactiveAccountTime = alterReq.inactiveAccountTime;
566,020✔
3243
  if (alterReq.hasAllowTokenNum) newUser.allowTokenNum = alterReq.allowTokenNum;
566,020✔
3244

3245

3246
  if (alterReq.numDropIpRanges > 0 || alterReq.numIpRanges > 0) {
566,020✔
3247
    int32_t dummy = 0;
396✔
3248

3249
    // put previous ip whitelist into hash table
3250
    SHashObj *m = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
396✔
3251
    if (m == NULL) {
396✔
3252
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3253
    }
3254

3255
    for (int32_t i = 0; i < newUser.pIpWhiteListDual->num; i++) {
1,386✔
3256
      SIpRange range;
990✔
3257
      copyIpRange(&range, newUser.pIpWhiteListDual->pIpRanges + i);
990✔
3258
      code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
990✔
3259
      if (code != 0) {
990✔
3260
        taosHashCleanup(m);
×
3261
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3262
      }
3263
    }
3264

3265
    if (alterReq.numDropIpRanges > 0) {
396✔
3266
      for (int32_t i = 0; i < alterReq.numDropIpRanges; i++) {
396✔
3267
        if (taosHashGetSize(m) == 0) {
198✔
3268
          break;
×
3269
        }
3270

3271
        SIpRange range;
198✔
3272
        copyIpRange(&range, alterReq.pDropIpRanges + i);
198✔
3273

3274
        // for white list, drop default ip ranges is allowed, otherwise, we can never
3275
        // convert white list to black list.
3276

3277
        code = taosHashRemove(m, &range, sizeof(range));
198✔
3278
        if (code == TSDB_CODE_NOT_FOUND) {
198✔
3279
          // treat not exist as success
3280
          code = 0;
198✔
3281
        }
3282
        if (code != 0) {
198✔
3283
          taosHashCleanup(m);
×
3284
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3285
        }
3286
      }
3287
    }
3288

3289
    if (alterReq.numIpRanges > 0) {
396✔
3290
      for (int32_t i = 0; i < alterReq.numIpRanges; i++) {
396✔
3291
        SIpRange range;
198✔
3292
        copyIpRange(&range, alterReq.pIpRanges + i);
198✔
3293
        code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
198✔
3294
        if (code != 0) {
198✔
3295
          taosHashCleanup(m);
×
3296
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3297
        }
3298
      }
3299
    }
3300

3301
    int32_t numOfRanges = taosHashGetSize(m);
396✔
3302
    if (numOfRanges > MND_MAX_USER_IP_RANGE) {
396✔
3303
      taosHashCleanup(m);
×
3304
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_IP_RANGE, &lino, _OVER);
×
3305
    }
3306

3307
    SIpWhiteListDual *p = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + numOfRanges * sizeof(SIpRange));
396✔
3308
    if (p == NULL) {
396✔
3309
      taosHashCleanup(m);
×
3310
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3311
    }
3312

3313
    void *pIter = taosHashIterate(m, NULL);
396✔
3314
    int32_t i = 0;
396✔
3315
    while (pIter) {
1,584✔
3316
      size_t len = 0;
1,188✔
3317
      SIpRange *key = taosHashGetKey(pIter, &len);
1,188✔
3318
      memcpy(p->pIpRanges + i, key, sizeof(SIpRange));
1,188✔
3319
      pIter = taosHashIterate(m, pIter);
1,188✔
3320
      i++;
1,188✔
3321
    }
3322

3323
    taosHashCleanup(m);
396✔
3324
    p->num = numOfRanges;
396✔
3325
    taosMemoryFreeClear(newUser.pIpWhiteListDual);
396✔
3326
    sortIpWhiteList(p);
396✔
3327
    newUser.pIpWhiteListDual = p;
396✔
3328

3329
    newUser.ipWhiteListVer++;
396✔
3330
  }
3331

3332

3333
  if (alterReq.numTimeRanges > 0 || alterReq.numDropTimeRanges) {
566,020✔
3334
    int32_t dummy = 0;
×
3335

3336
    // put previous ip whitelist into hash table
3337
    SHashObj *m = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
×
3338
    if (m == NULL) {
×
3339
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3340
    }
3341

3342
    for (int32_t i = 0; i < newUser.pTimeWhiteList->num; i++) {
×
3343
      SDateTimeWhiteListItem *range = &newUser.pTimeWhiteList->ranges[i];
×
3344
      if (isDateTimeWhiteListItemExpired(range)) {
×
3345
        continue;
×
3346
      }
3347
      code = taosHashPut(m, range, sizeof(*range), &dummy, sizeof(dummy));
×
3348
      if (code != 0) {
×
3349
        taosHashCleanup(m);
×
3350
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3351
      }
3352
    }
3353

3354
    if (alterReq.numDropTimeRanges > 0) {
×
3355
      for (int32_t i = 0; i < alterReq.numDropTimeRanges; i++) {
×
3356
        if (taosHashGetSize(m) == 0) {
×
3357
          break;
×
3358
        }
3359
        SDateTimeWhiteListItem range = { 0 };
×
3360
        DateTimeRangeToWhiteListItem(&range, alterReq.pDropTimeRanges + i);
×
3361

3362
        code = taosHashRemove(m, &range, sizeof(range));
×
3363
        if (code == TSDB_CODE_NOT_FOUND) {
×
3364
          // treat not exist as success
3365
          code = 0;
×
3366
        }
3367
        if (code != 0) {
×
3368
          taosHashCleanup(m);
×
3369
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3370
        }
3371
      }
3372
    }
3373

3374
    if (alterReq.numTimeRanges > 0) {
×
3375
      for (int32_t i = 0; i < alterReq.numTimeRanges; i++) {
×
3376
        SDateTimeWhiteListItem range = { 0 };
×
3377
        DateTimeRangeToWhiteListItem(&range, alterReq.pTimeRanges + i);
×
3378
        if (isDateTimeWhiteListItemExpired(&range)) {
×
3379
          continue;
×
3380
        }
3381
        code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
×
3382
        if (code != 0) {
×
3383
          taosHashCleanup(m);
×
3384
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3385
        }
3386
      }
3387
    }
3388

3389
    int32_t numOfRanges = taosHashGetSize(m);
×
3390
    if (numOfRanges > MND_MAX_USER_TIME_RANGE) {
×
3391
      taosHashCleanup(m);
×
3392
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_TIME_RANGE, &lino, _OVER);
×
3393
    }
3394

3395
    SDateTimeWhiteList *p = taosMemoryCalloc(1, sizeof(SDateTimeWhiteList) + numOfRanges * sizeof(SDateTimeWhiteListItem));
×
3396
    if (p == NULL) {
×
3397
      taosHashCleanup(m);
×
3398
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3399
    }
3400

3401
    void *pIter = taosHashIterate(m, NULL);
×
3402
    int32_t i = 0;
×
3403
    while (pIter) {
×
3404
      size_t len = 0;
×
3405
      SDateTimeWhiteListItem *key = taosHashGetKey(pIter, &len);
×
3406
      memcpy(&p->ranges[i], key, sizeof(SDateTimeWhiteListItem));
×
3407
      pIter = taosHashIterate(m, pIter);
×
3408
      i++;
×
3409
    }
3410

3411
    taosHashCleanup(m);
×
3412
    p->num = numOfRanges;
×
3413
    taosMemoryFreeClear(newUser.pTimeWhiteList);
×
3414
    sortTimeWhiteList(p);
×
3415
    newUser.pTimeWhiteList = p;
×
3416
    newUser.timeWhiteListVer++;
×
3417
  }
3418

3419

3420
  if (ALTER_USER_ADD_PRIVS(alterReq.alterType) || ALTER_USER_DEL_PRIVS(alterReq.alterType)) {
566,020✔
3421
    TAOS_CHECK_GOTO(mndProcessAlterUserPrivilegesReq(&alterReq, pMnode, &newUser), &lino, _OVER);
553,214✔
3422
  }
3423

3424
  code = mndAlterUser(pMnode, pUser, &newUser, pReq);
563,916✔
3425
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
563,916✔
3426

3427
#if 0
3428
  if (alterReq.passIsMd5 == 0) {
3429
    if (TSDB_ALTER_USER_PASSWD == alterReq.alterType) {
3430
      code = mndCheckPasswordFmt(alterReq.pass, len);
3431
      TAOS_CHECK_GOTO(code, &lino, _OVER);
3432
    }
3433
  }
3434

3435
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, alterReq.user, &pUser), &lino, _OVER);
3436

3437
  (void)mndAcquireUser(pMnode, pReq->info.conn.user, &pOperUser);
3438
  if (pOperUser == NULL) {
3439
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_USER_FROM_CONN, &lino, _OVER);
3440
  }
3441

3442
  TAOS_CHECK_GOTO(mndCheckAlterUserPrivilege(pOperUser, pUser, &alterReq), &lino, _OVER);
3443

3444
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
3445

3446
  if (alterReq.alterType == TSDB_ALTER_USER_PASSWD) {
3447
    if (alterReq.passIsMd5 == 1) {
3448
      (void)memcpy(newUser.pass, alterReq.pass, TSDB_PASSWORD_LEN);
3449
    } else {
3450
      taosEncryptPass_c((uint8_t *)alterReq.pass, strlen(alterReq.pass), newUser.pass);
3451
    }
3452

3453
    TAOS_CHECK_GOTO(mndEncryptPass(newUser.pass, &newUser.passEncryptAlgorithm), &lino, _OVER);
3454

3455
    if (0 != strncmp(pUser->pass, newUser.pass, TSDB_PASSWORD_LEN)) {
3456
      ++newUser.passVersion;
3457
    }
3458
  }
3459

3460
  if (alterReq.alterType == TSDB_ALTER_USER_SUPERUSER) {
3461
    newUser.superUser = alterReq.superUser;
3462
  }
3463

3464
  if (alterReq.alterType == TSDB_ALTER_USER_ENABLE) {
3465
    newUser.enable = alterReq.enable;
3466
  }
3467

3468
  if (alterReq.alterType == TSDB_ALTER_USER_SYSINFO) {
3469
    newUser.sysInfo = alterReq.sysInfo;
3470
  }
3471

3472
  if (alterReq.alterType == TSDB_ALTER_USER_CREATEDB) {
3473
    newUser.createdb = alterReq.createdb;
3474
  }
3475

3476
  if (ALTER_USER_ADD_PRIVS(alterReq.alterType) || ALTER_USER_DEL_PRIVS(alterReq.alterType)) {
3477
    TAOS_CHECK_GOTO(mndProcessAlterUserPrivilegesReq(&alterReq, pMnode, &newUser), &lino, _OVER);
3478
  }
3479

3480
  if (alterReq.alterType == TSDB_ALTER_USER_ADD_ALLOWED_HOST) {
3481
    taosMemoryFreeClear(newUser.pIpWhiteListDual);
3482

3483
    int32_t           num = pUser->pIpWhiteListDual->num + alterReq.numIpRanges;
3484
    int32_t           idx = pUser->pIpWhiteListDual->num;
3485
    SIpWhiteListDual *pNew = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + sizeof(SIpRange) * num);
3486

3487
    if (pNew == NULL) {
3488
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
3489
    }
3490

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

3519
    if (pNew->num > MND_MAX_USER_IP_RANGE) {
3520
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_IP_RANGE, &lino, _OVER);
3521
    }
3522
  }
3523
  if (alterReq.alterType == TSDB_ALTER_USER_DROP_ALLOWED_HOST) {
3524
    taosMemoryFreeClear(newUser.pIpWhiteListDual);
3525

3526
    int32_t           num = pUser->pIpWhiteListDual->num;
3527
    bool              noexist = true;
3528
    bool              localHost = false;
3529
    SIpWhiteListDual *pNew = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + sizeof(SIpRange) * num);
3530

3531
    if (pNew == NULL) {
3532
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
3533
    }
3534

3535
    if (pUser->pIpWhiteListDual->num > 0) {
3536
      int idx = 0;
3537
      for (int i = 0; i < pUser->pIpWhiteListDual->num; i++) {
3538
        SIpRange *oldRange = &pUser->pIpWhiteListDual->pIpRanges[i];
3539

3540
        bool found = false;
3541
        for (int j = 0; j < alterReq.numIpRanges; j++) {
3542
          SIpRange range = {0};
3543
          if (alterReq.pIpDualRanges == NULL) {
3544
            SIpV4Range *trange = &alterReq.pIpRanges[j];
3545
            memcpy(&range.ipV4, trange, sizeof(SIpV4Range));
3546
          } else {
3547
            memcpy(&range, &alterReq.pIpDualRanges[j], sizeof(SIpRange));
3548
          }
3549

3550
          if (isDefaultRange(&range)) {
3551
            localHost = true;
3552
            break;
3553
          }
3554
          if (isIpRangeEqual(oldRange, &range)) {
3555
            found = true;
3556
            break;
3557
          }
3558
        }
3559
        if (localHost) break;
3560

3561
        if (found == false) {
3562
          (void)memcpy(&pNew->pIpRanges[idx], oldRange, sizeof(SIpRange));
3563
          idx++;
3564
        } else {
3565
          noexist = false;
3566
        }
3567
      }
3568
      pNew->num = idx;
3569
      newUser.pIpWhiteListDual = pNew;
3570
      newUser.ipWhiteListVer = pUser->ipWhiteListVer + 1;
3571

3572
    } else {
3573
      pNew->num = 0;
3574
      newUser.pIpWhiteListDual = pNew;
3575
      newUser.ipWhiteListVer = pUser->ipWhiteListVer + 1;
3576
    }
3577

3578
    if (localHost) {
3579
      TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_LOCAL_HOST_NOT_DROP, &lino, _OVER);
3580
    }
3581
    if (noexist) {
3582
      TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_HOST_NOT_EXIST, &lino, _OVER);
3583
    }
3584
  }
3585

3586
  code = mndAlterUser(pMnode, pUser, &newUser, pReq);
3587
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
3588

3589
  if (alterReq.alterType == TSDB_ALTER_USER_PASSWD) {
3590
    char detail[1000] = {0};
3591
    (void)tsnprintf(detail, sizeof(detail),
3592
                    "alterType:%s, enable:%d, superUser:%d, sysInfo:%d, createdb:%d, tabName:%s, password:xxx",
3593
                    mndUserAuditTypeStr(alterReq.alterType), alterReq.enable, alterReq.superUser, alterReq.sysInfo,
3594
                    alterReq.createdb ? 1 : 0, alterReq.tabName);
3595
    auditRecord(pReq, pMnode->clusterId, "alterUser", "", alterReq.user, detail, strlen(detail));
3596
  } else if (alterReq.alterType == TSDB_ALTER_USER_SUPERUSER || alterReq.alterType == TSDB_ALTER_USER_ENABLE ||
3597
             alterReq.alterType == TSDB_ALTER_USER_SYSINFO || alterReq.alterType == TSDB_ALTER_USER_CREATEDB) {
3598
    auditRecord(pReq, pMnode->clusterId, "alterUser", "", alterReq.user, alterReq.sql, alterReq.sqlLen);
3599
  } else if (ALTER_USER_ADD_READ_DB_PRIV(alterReq.alterType, alterReq.privileges, alterReq.tabName) ||
3600
             ALTER_USER_ADD_WRITE_DB_PRIV(alterReq.alterType, alterReq.privileges, alterReq.tabName) ||
3601
             ALTER_USER_ADD_ALL_DB_PRIV(alterReq.alterType, alterReq.privileges, alterReq.tabName) ||
3602
             ALTER_USER_ADD_READ_TB_PRIV(alterReq.alterType, alterReq.privileges, alterReq.tabName) ||
3603
             ALTER_USER_ADD_WRITE_TB_PRIV(alterReq.alterType, alterReq.privileges, alterReq.tabName) ||
3604
             ALTER_USER_ADD_ALL_TB_PRIV(alterReq.alterType, alterReq.privileges, alterReq.tabName)) {
3605
    if (strcmp(alterReq.objname, "1.*") != 0) {
3606
      SName name = {0};
3607
      TAOS_CHECK_GOTO(tNameFromString(&name, alterReq.objname, T_NAME_ACCT | T_NAME_DB), &lino, _OVER);
3608
      auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", name.dbname, alterReq.user, alterReq.sql,
3609
                  alterReq.sqlLen);
3610
    } else {
3611
      auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", "", alterReq.user, alterReq.sql, alterReq.sqlLen);
3612
    }
3613
  } else if (ALTER_USER_ADD_SUBSCRIBE_TOPIC_PRIV(alterReq.alterType, alterReq.privileges)) {
3614
    auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", alterReq.objname, alterReq.user, alterReq.sql,
3615
                alterReq.sqlLen);
3616
  } else if (ALTER_USER_DEL_SUBSCRIBE_TOPIC_PRIV(alterReq.alterType, alterReq.privileges)) {
3617
    auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", alterReq.objname, alterReq.user, alterReq.sql,
3618
                alterReq.sqlLen);
3619
  } else {
3620
    if (strcmp(alterReq.objname, "1.*") != 0) {
3621
      SName name = {0};
3622
      TAOS_CHECK_GOTO(tNameFromString(&name, alterReq.objname, T_NAME_ACCT | T_NAME_DB), &lino, _OVER);
3623
      auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", name.dbname, alterReq.user, alterReq.sql,
3624
                  alterReq.sqlLen);
3625
    } else {
3626
      auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", "", alterReq.user, alterReq.sql, alterReq.sqlLen);
3627
    }
3628
  }
3629

3630
#endif
3631

3632
_OVER:
581,430✔
3633
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
581,430✔
3634
    mError("user:%s, failed to alter at line %d since %s", alterReq.user, lino, tstrerror(code));
17,514✔
3635
  }
3636

3637
  tFreeSAlterUserReq(&alterReq);
581,430✔
3638
  mndReleaseUser(pMnode, pOperUser);
581,430✔
3639
  mndReleaseUser(pMnode, pUser);
581,430✔
3640
  mndUserFreeObj(&newUser);
581,430✔
3641
  TAOS_RETURN(code);
581,430✔
3642
}
3643

3644
static int32_t mndDropUser(SMnode *pMnode, SRpcMsg *pReq, SUserObj *pUser) {
28,777✔
3645
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "drop-user");
28,777✔
3646
  if (pTrans == NULL) {
28,777✔
3647
    mError("user:%s, failed to drop since %s", pUser->user, terrstr());
×
3648
    TAOS_RETURN(terrno);
×
3649
  }
3650
  mInfo("trans:%d, used to drop user:%s", pTrans->id, pUser->user);
28,777✔
3651

3652
  SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
28,777✔
3653
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
28,777✔
3654
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
3655
    mndTransDrop(pTrans);
×
3656
    TAOS_RETURN(terrno);
×
3657
  }
3658
  if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED) < 0) {
28,777✔
3659
    mndTransDrop(pTrans);
×
3660
    TAOS_RETURN(terrno);
×
3661
  }
3662

3663
  if (mndTransPrepare(pMnode, pTrans) != 0) {
28,777✔
3664
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
3665
    mndTransDrop(pTrans);
×
3666
    TAOS_RETURN(terrno);
×
3667
  }
3668

3669
  userCacheRemoveUser(pUser->user);
28,777✔
3670

3671
  mndTransDrop(pTrans);
28,777✔
3672
  TAOS_RETURN(0);
28,777✔
3673
}
3674

3675
static int32_t mndProcessDropUserReq(SRpcMsg *pReq) {
28,969✔
3676
  SMnode      *pMnode = pReq->info.node;
28,969✔
3677
  int32_t      code = 0;
28,969✔
3678
  int32_t      lino = 0;
28,969✔
3679
  SUserObj    *pUser = NULL;
28,969✔
3680
  SDropUserReq dropReq = {0};
28,969✔
3681

3682
  TAOS_CHECK_GOTO(tDeserializeSDropUserReq(pReq->pCont, pReq->contLen, &dropReq), &lino, _OVER);
28,969✔
3683

3684
  mInfo("user:%s, start to drop", dropReq.user);
28,969✔
3685
  TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_DROP_USER), &lino, _OVER);
28,969✔
3686

3687
  if (dropReq.user[0] == 0) {
28,969✔
3688
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
3689
  }
3690

3691
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, dropReq.user, &pUser), &lino, _OVER);
28,969✔
3692

3693
  TAOS_CHECK_GOTO(mndDropUser(pMnode, pReq, pUser), &lino, _OVER);
28,777✔
3694
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
28,777✔
3695

3696
  auditRecord(pReq, pMnode->clusterId, "dropUser", "", dropReq.user, dropReq.sql, dropReq.sqlLen);
28,777✔
3697

3698
_OVER:
28,969✔
3699
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
28,969✔
3700
    mError("user:%s, failed to drop at line %d since %s", dropReq.user, lino, tstrerror(code));
192✔
3701
  }
3702

3703
  mndReleaseUser(pMnode, pUser);
28,969✔
3704
  tFreeSDropUserReq(&dropReq);
28,969✔
3705
  TAOS_RETURN(code);
28,969✔
3706
}
3707

3708
static int32_t mndProcessGetUserAuthReq(SRpcMsg *pReq) {
2,047,779✔
3709
  SMnode         *pMnode = pReq->info.node;
2,047,779✔
3710
  int32_t         code = 0;
2,047,779✔
3711
  int32_t         lino = 0;
2,047,779✔
3712
  int32_t         contLen = 0;
2,047,779✔
3713
  void           *pRsp = NULL;
2,047,779✔
3714
  SUserObj       *pUser = NULL;
2,047,779✔
3715
  SGetUserAuthReq authReq = {0};
2,047,779✔
3716
  SGetUserAuthRsp authRsp = {0};
2,047,779✔
3717

3718
  TAOS_CHECK_EXIT(tDeserializeSGetUserAuthReq(pReq->pCont, pReq->contLen, &authReq));
2,047,779✔
3719
  mTrace("user:%s, start to get auth", authReq.user);
2,047,779✔
3720

3721
  TAOS_CHECK_EXIT(mndAcquireUser(pMnode, authReq.user, &pUser));
2,047,779✔
3722

3723
  TAOS_CHECK_EXIT(mndSetUserAuthRsp(pMnode, pUser, &authRsp));
2,047,095✔
3724

3725
  contLen = tSerializeSGetUserAuthRsp(NULL, 0, &authRsp);
2,047,095✔
3726
  if (contLen < 0) {
2,047,095✔
3727
    TAOS_CHECK_EXIT(contLen);
×
3728
  }
3729
  pRsp = rpcMallocCont(contLen);
2,047,095✔
3730
  if (pRsp == NULL) {
2,047,095✔
3731
    TAOS_CHECK_EXIT(terrno);
×
3732
  }
3733

3734
  contLen = tSerializeSGetUserAuthRsp(pRsp, contLen, &authRsp);
2,047,095✔
3735
  if (contLen < 0) {
2,047,095✔
3736
    TAOS_CHECK_EXIT(contLen);
×
3737
  }
3738

3739
_exit:
2,047,779✔
3740
  mndReleaseUser(pMnode, pUser);
2,047,779✔
3741
  tFreeSGetUserAuthRsp(&authRsp);
2,047,779✔
3742
  if (code < 0) {
2,047,659✔
3743
    mError("user:%s, failed to get auth at line %d since %s", authReq.user, lino, tstrerror(code));
684✔
3744
    rpcFreeCont(pRsp);
684✔
3745
    pRsp = NULL;
684✔
3746
    contLen = 0;
684✔
3747
  }
3748
  pReq->info.rsp = pRsp;
2,047,659✔
3749
  pReq->info.rspLen = contLen;
2,047,779✔
3750
  pReq->code = code;
2,047,779✔
3751

3752
  TAOS_RETURN(code);
2,047,779✔
3753
}
3754

3755

3756
bool mndIsTotpEnabledUser(SUserObj *pUser) {
1,361,977✔
3757
  for (int32_t i = 0; i < sizeof(pUser->totpsecret); i++) {
44,919,898✔
3758
    if (pUser->totpsecret[i] != 0) {
43,559,884✔
3759
      return true;
×
3760
    }
3761
  }
3762
  return false;
1,360,014✔
3763
}
3764

3765

3766
static int32_t mndRetrieveUsers(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
10,008✔
3767
  SMnode   *pMnode = pReq->info.node;
10,008✔
3768
  SSdb     *pSdb = pMnode->pSdb;
10,008✔
3769
  int32_t   code = 0;
10,008✔
3770
  int32_t   lino = 0;
10,008✔
3771
  int32_t   numOfRows = 0;
10,008✔
3772
  SUserObj *pUser = NULL;
10,008✔
3773
  int32_t   cols = 0;
10,008✔
3774
  int8_t    flag = 0;
10,008✔
3775
  char     *pWrite = NULL;
10,008✔
3776
  char     *buf = NULL;
10,008✔
3777
  char     *varstr = NULL;
10,008✔
3778

3779
  while (numOfRows < rows) {
35,921✔
3780
    pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
35,921✔
3781
    if (pShow->pIter == NULL) break;
35,921✔
3782

3783
    cols = 0;
25,913✔
3784
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
25,913✔
3785
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
25,913✔
3786
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
25,913✔
3787
    COL_DATA_SET_VAL_GOTO((const char *)name, false, pUser, pShow->pIter, _exit);
25,913✔
3788

3789
    cols++;
25,913✔
3790
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
25,913✔
3791
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->superUser, false, pUser, pShow->pIter, _exit);
25,913✔
3792

3793
    cols++;
25,913✔
3794
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
25,913✔
3795
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->enable, false, pUser, pShow->pIter, _exit);
25,913✔
3796

3797
    cols++;
25,913✔
3798
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
25,913✔
3799
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sysInfo, false, pUser, pShow->pIter, _exit);
25,913✔
3800

3801
    cols++;
25,913✔
3802
    flag = pUser->createdb ? 1 : 0;
25,913✔
3803
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
25,913✔
3804
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
25,913✔
3805

3806
    cols++;
25,913✔
3807
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
25,913✔
3808
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->createdTime, false, pUser, pShow->pIter, _exit);
25,913✔
3809

3810
    cols++;
25,913✔
3811
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
25,913✔
3812
    flag = mndIsTotpEnabledUser(pUser) ? 1 : 0;
25,913✔
3813
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
25,913✔
3814

3815
    cols++;
25,913✔
3816

3817
    int32_t tlen = convertIpWhiteListToStr(pUser, &buf);
25,913✔
3818
    if (tlen != 0) {
25,913✔
3819
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
25,913✔
3820
      if (varstr == NULL) {
25,913✔
3821
        sdbRelease(pSdb, pUser);
×
3822
        sdbCancelFetch(pSdb, pShow->pIter);
×
3823
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
3824
      }
3825
      varDataSetLen(varstr, tlen);
25,913✔
3826
      (void)memcpy(varDataVal(varstr), buf, tlen);
25,913✔
3827

3828
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
25,913✔
3829
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
25,913✔
3830

3831
      taosMemoryFreeClear(buf);
25,913✔
3832
    } else {
3833
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3834
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
3835
    }
3836

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

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

3852
      taosMemoryFreeClear(buf);
25,913✔
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
    numOfRows++;
25,913✔
3859
    sdbRelease(pSdb, pUser);
25,913✔
3860
  }
3861

3862
  pShow->numOfRows += numOfRows;
10,008✔
3863
_exit:
10,008✔
3864
  taosMemoryFreeClear(buf);
10,008✔
3865
  taosMemoryFreeClear(varstr);
10,008✔
3866
  if (code < 0) {
10,008✔
3867
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
3868
    TAOS_RETURN(code);
×
3869
  }
3870
  return numOfRows;
10,008✔
3871
}
3872

3873
static int32_t mndRetrieveUsersFull(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
×
3874
  int32_t numOfRows = 0;
×
3875
#ifdef TD_ENTERPRISE
3876
  SMnode   *pMnode = pReq->info.node;
×
3877
  SSdb     *pSdb = pMnode->pSdb;
×
3878
  SUserObj *pUser = NULL;
×
3879
  int32_t   code = 0;
×
3880
  int32_t   lino = 0;
×
3881
  int32_t   cols = 0;
×
3882
  int8_t    flag = 0;
×
3883
  char     *pWrite = NULL;
×
3884
  char     *buf = NULL;
×
3885
  char     *varstr = NULL;
×
3886

3887
  while (numOfRows < rows) {
×
3888
    pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
×
3889
    if (pShow->pIter == NULL) break;
×
3890

3891
    cols = 0;
×
3892
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3893
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
×
3894
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
×
3895
    COL_DATA_SET_VAL_GOTO((const char *)name, false, pUser, pShow->pIter, _exit);
×
3896

3897
    cols++;
×
3898
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3899
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->superUser, false, pUser, pShow->pIter, _exit);
×
3900

3901
    cols++;
×
3902
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3903
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->enable, false, pUser, pShow->pIter, _exit);
×
3904

3905
    cols++;
×
3906
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3907
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sysInfo, false, pUser, pShow->pIter, _exit);
×
3908

3909
    cols++;
×
3910
    flag = pUser->createdb ? 1 : 0;
×
3911
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3912
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
×
3913

3914
    cols++;
×
3915
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3916
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->createdTime, false, pUser, pShow->pIter, _exit);
×
3917

3918
    cols++;
×
3919
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3920
    flag = mndIsTotpEnabledUser(pUser) ? 1 : 0;
×
3921
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
×
3922

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

3927
    cols++;
×
3928
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3929
    char pass[TSDB_PASSWORD_LEN + VARSTR_HEADER_SIZE] = {0};
×
3930
    STR_WITH_MAXSIZE_TO_VARSTR(pass, pUser->passwords[0].pass, pShow->pMeta->pSchemas[cols].bytes);
×
3931
    COL_DATA_SET_VAL_GOTO((const char *)pass, false, pUser, pShow->pIter, _exit);
×
3932

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

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

3941
    cols++;
×
3942
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3943
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->connectIdleTime, false, pUser, pShow->pIter, _exit);
×
3944

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

3949
    /* not supported yet
3950
    cols++;
3951
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
3952
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->vnodePerSession, false, pUser, pShow->pIter, _exit);
3953
*/
3954

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

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

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

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

3971
    cols++;
×
3972
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3973
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordLockTime, false, pUser, pShow->pIter, _exit);
×
3974

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

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

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

3987
    cols++;
×
3988
    int32_t tlen = convertIpWhiteListToStr(pUser, &buf);
×
3989
    if (tlen != 0) {
×
3990
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
×
3991
      if (varstr == NULL) {
×
3992
        sdbRelease(pSdb, pUser);
×
3993
        sdbCancelFetch(pSdb, pShow->pIter);
×
3994
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
3995
      }
3996
      varDataSetLen(varstr, tlen);
×
3997
      (void)memcpy(varDataVal(varstr), buf, tlen);
×
3998

3999
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4000
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
×
4001

4002
      taosMemoryFreeClear(buf);
×
4003
    } else {
4004
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4005
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
4006
    }
4007

4008
    cols++;
×
4009
    tlen = convertTimeRangesToStr(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
    numOfRows++;
×
4030
    sdbRelease(pSdb, pUser);
×
4031
  }
4032

4033
  pShow->numOfRows += numOfRows;
×
4034
_exit:
×
4035
  taosMemoryFreeClear(buf);
×
4036
  taosMemoryFreeClear(varstr);
×
4037
  if (code < 0) {
×
4038
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4039
    TAOS_RETURN(code);
×
4040
  }
4041
#endif
4042
  return numOfRows;
×
4043
}
4044

4045
static void mndCancelGetNextUser(SMnode *pMnode, void *pIter) {
×
4046
  SSdb *pSdb = pMnode->pSdb;
×
4047
  sdbCancelFetchByType(pSdb, pIter, SDB_USER);
×
4048
}
×
4049

4050
static int32_t mndLoopHash(SHashObj *hash, char *priType, SSDataBlock *pBlock, int32_t *pNumOfRows, SSdb *pSdb,
272,544✔
4051
                           SUserObj *pUser, SShowObj *pShow, char **condition, char **sql) {
4052
  char   *value = taosHashIterate(hash, NULL);
272,544✔
4053
  char   *user = pUser->user;
272,544✔
4054
  int32_t code = 0;
272,544✔
4055
  int32_t lino = 0;
272,544✔
4056
  int32_t cols = 0;
272,544✔
4057
  int32_t numOfRows = *pNumOfRows;
272,544✔
4058

4059
  while (value != NULL) {
323,203✔
4060
    cols = 0;
50,659✔
4061
    char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
50,659✔
4062
    STR_WITH_MAXSIZE_TO_VARSTR(userName, user, pShow->pMeta->pSchemas[cols].bytes);
50,659✔
4063
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
50,659✔
4064
    COL_DATA_SET_VAL_GOTO((const char *)userName, false, NULL, NULL, _exit);
50,659✔
4065

4066
    char privilege[20] = {0};
50,659✔
4067
    STR_WITH_MAXSIZE_TO_VARSTR(privilege, priType, pShow->pMeta->pSchemas[cols].bytes);
50,659✔
4068
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
50,659✔
4069
    COL_DATA_SET_VAL_GOTO((const char *)privilege, false, NULL, NULL, _exit);
50,659✔
4070

4071
    size_t keyLen = 0;
50,659✔
4072
    void  *key = taosHashGetKey(value, &keyLen);
50,659✔
4073

4074
    char dbName[TSDB_DB_NAME_LEN] = {0};
50,659✔
4075
    (void)mndExtractShortDbNameFromStbFullName(key, dbName);
50,659✔
4076
    char dbNameContent[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
50,659✔
4077
    STR_WITH_MAXSIZE_TO_VARSTR(dbNameContent, dbName, pShow->pMeta->pSchemas[cols].bytes);
50,659✔
4078
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
50,659✔
4079
    COL_DATA_SET_VAL_GOTO((const char *)dbNameContent, false, NULL, NULL, _exit);
50,659✔
4080

4081
    char tableName[TSDB_TABLE_NAME_LEN] = {0};
50,659✔
4082
    mndExtractTbNameFromStbFullName(key, tableName, TSDB_TABLE_NAME_LEN);
50,659✔
4083
    char tableNameContent[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
50,659✔
4084
    STR_WITH_MAXSIZE_TO_VARSTR(tableNameContent, tableName, pShow->pMeta->pSchemas[cols].bytes);
50,659✔
4085
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
50,659✔
4086
    COL_DATA_SET_VAL_GOTO((const char *)tableNameContent, false, NULL, NULL, _exit);
50,659✔
4087

4088
    if (strcmp("t", value) != 0 && strcmp("v", value) != 0) {
87,917✔
4089
      SNode  *pAst = NULL;
37,258✔
4090
      int32_t sqlLen = 0;
37,258✔
4091
      size_t  bufSz = strlen(value) + 1;
37,258✔
4092
      if (bufSz < 6) bufSz = 6;
37,258✔
4093
      TAOS_MEMORY_REALLOC(*sql, bufSz);
37,258✔
4094
      if (*sql == NULL) {
37,258✔
4095
        code = terrno;
×
4096
        goto _exit;
×
4097
      }
4098
      TAOS_MEMORY_REALLOC(*condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
37,258✔
4099
      if ((*condition) == NULL) {
37,258✔
4100
        code = terrno;
×
4101
        goto _exit;
×
4102
      }
4103

4104
      if (nodesStringToNode(value, &pAst) == 0) {
37,258✔
4105
        if (nodesNodeToSQLFormat(pAst, *sql, bufSz, &sqlLen, true) != 0) {
37,258✔
4106
          sqlLen = tsnprintf(*sql, bufSz, "error");
×
4107
        }
4108
        nodesDestroyNode(pAst);
37,258✔
4109
      }
4110

4111
      if (sqlLen == 0) {
37,258✔
4112
        sqlLen = tsnprintf(*sql, bufSz, "error");
×
4113
      }
4114

4115
      STR_WITH_MAXSIZE_TO_VARSTR((*condition), (*sql), pShow->pMeta->pSchemas[cols].bytes);
37,258✔
4116

4117
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
37,258✔
4118
      COL_DATA_SET_VAL_GOTO((const char *)(*condition), false, NULL, NULL, _exit);
37,258✔
4119

4120
      char notes[2] = {0};
37,258✔
4121
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
37,258✔
4122
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
37,258✔
4123
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, NULL, NULL, _exit);
37,258✔
4124
    } else {
4125
      TAOS_MEMORY_REALLOC(*condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
13,401✔
4126
      if ((*condition) == NULL) {
13,401✔
4127
        code = terrno;
×
4128
        goto _exit;
×
4129
      }
4130
      STR_WITH_MAXSIZE_TO_VARSTR((*condition), "", pShow->pMeta->pSchemas[cols].bytes);
13,401✔
4131
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
13,401✔
4132
      COL_DATA_SET_VAL_GOTO((const char *)(*condition), false, NULL, NULL, _exit);
13,401✔
4133

4134
      char notes[64 + VARSTR_HEADER_SIZE] = {0};
13,401✔
4135
      STR_WITH_MAXSIZE_TO_VARSTR(notes, value[0] == 'v' ? "view" : "", sizeof(notes));
13,401✔
4136
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
13,401✔
4137
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, NULL, NULL, _exit);
13,401✔
4138
    }
4139

4140
    numOfRows++;
50,659✔
4141
    value = taosHashIterate(hash, value);
50,659✔
4142
  }
4143
  *pNumOfRows = numOfRows;
272,544✔
4144
_exit:
272,544✔
4145
  if (code < 0) {
272,544✔
4146
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4147
    sdbRelease(pSdb, pUser);
×
4148
    sdbCancelFetch(pSdb, pShow->pIter);
×
4149
  }
4150
  TAOS_RETURN(code);
272,544✔
4151
}
4152

4153
static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
7,541✔
4154
  int32_t   code = 0;
7,541✔
4155
  int32_t   lino = 0;
7,541✔
4156
  SMnode   *pMnode = pReq->info.node;
7,541✔
4157
  SSdb     *pSdb = pMnode->pSdb;
7,541✔
4158
  int32_t   numOfRows = 0;
7,541✔
4159
  SUserObj *pUser = NULL;
7,541✔
4160
  int32_t   cols = 0;
7,541✔
4161
  char     *pWrite = NULL;
7,541✔
4162
  char     *condition = NULL;
7,541✔
4163
  char     *sql = NULL;
7,541✔
4164

4165
  bool fetchNextUser = pShow->restore ? false : true;
7,541✔
4166
  pShow->restore = false;
7,541✔
4167

4168
  while (numOfRows < rows) {
52,965✔
4169
    if (fetchNextUser) {
52,965✔
4170
      pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
52,965✔
4171
      if (pShow->pIter == NULL) break;
52,965✔
4172
    } else {
4173
      fetchNextUser = true;
×
4174
      void *pKey = taosHashGetKey(pShow->pIter, NULL);
×
4175
      pUser = sdbAcquire(pSdb, SDB_USER, pKey);
×
4176
      if (!pUser) {
×
4177
        continue;
×
4178
      }
4179
    }
4180

4181
    int32_t numOfReadDbs = taosHashGetSize(pUser->readDbs);
45,424✔
4182
    int32_t numOfWriteDbs = taosHashGetSize(pUser->writeDbs);
45,424✔
4183
    int32_t numOfTopics = taosHashGetSize(pUser->topics);
45,424✔
4184
    int32_t numOfReadTbs = taosHashGetSize(pUser->readTbs);
45,424✔
4185
    int32_t numOfWriteTbs = taosHashGetSize(pUser->writeTbs);
45,424✔
4186
    int32_t numOfAlterTbs = taosHashGetSize(pUser->alterTbs);
45,424✔
4187
    int32_t numOfReadViews = taosHashGetSize(pUser->readViews);
45,424✔
4188
    int32_t numOfWriteViews = taosHashGetSize(pUser->writeViews);
45,424✔
4189
    int32_t numOfAlterViews = taosHashGetSize(pUser->alterViews);
45,424✔
4190
    if (numOfRows + numOfReadDbs + numOfWriteDbs + numOfTopics + numOfReadTbs + numOfWriteTbs + numOfAlterTbs +
45,424✔
4191
            numOfReadViews + numOfWriteViews + numOfAlterViews >=
45,424✔
4192
        rows) {
4193
      mInfo(
×
4194
          "will restore. current num of rows: %d, read dbs %d, write dbs %d, topics %d, read tables %d, write tables "
4195
          "%d, alter tables %d, read views %d, write views %d, alter views %d",
4196
          numOfRows, numOfReadDbs, numOfWriteDbs, numOfTopics, numOfReadTbs, numOfWriteTbs, numOfAlterTbs,
4197
          numOfReadViews, numOfWriteViews, numOfAlterViews);
4198
      pShow->restore = true;
×
4199
      sdbRelease(pSdb, pUser);
×
4200
      break;
×
4201
    }
4202

4203
    if (pUser->superUser) {
45,424✔
4204
      cols = 0;
7,541✔
4205
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
7,541✔
4206
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
7,541✔
4207
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
7,541✔
4208
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
7,541✔
4209

4210
      char privilege[20] = {0};
7,541✔
4211
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "all", pShow->pMeta->pSchemas[cols].bytes);
7,541✔
4212
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
7,541✔
4213
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
7,541✔
4214

4215
      char objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
7,541✔
4216
      STR_WITH_MAXSIZE_TO_VARSTR(objName, "all", pShow->pMeta->pSchemas[cols].bytes);
7,541✔
4217
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
7,541✔
4218
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
7,541✔
4219

4220
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
7,541✔
4221
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
7,541✔
4222
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
7,541✔
4223
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
7,541✔
4224

4225
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
7,541✔
4226
      if (condition == NULL) {
7,541✔
4227
        sdbRelease(pSdb, pUser);
×
4228
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
4229
      }
4230
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
7,541✔
4231
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
7,541✔
4232
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
7,541✔
4233

4234
      char notes[2] = {0};
7,541✔
4235
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
7,541✔
4236
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
7,541✔
4237
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
7,541✔
4238

4239
      numOfRows++;
7,541✔
4240
    }
4241

4242
    char *db = taosHashIterate(pUser->readDbs, NULL);
45,424✔
4243
    while (db != NULL) {
51,251✔
4244
      cols = 0;
5,827✔
4245
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
5,827✔
4246
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
5,827✔
4247
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5,827✔
4248
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
5,827✔
4249

4250
      char privilege[20] = {0};
5,827✔
4251
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "read", pShow->pMeta->pSchemas[cols].bytes);
5,827✔
4252
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5,827✔
4253
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
5,827✔
4254

4255
      SName name = {0};
5,827✔
4256
      char  objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
5,827✔
4257
      code = tNameFromString(&name, db, T_NAME_ACCT | T_NAME_DB);
5,827✔
4258
      if (code < 0) {
5,827✔
4259
        sdbRelease(pSdb, pUser);
×
4260
        sdbCancelFetch(pSdb, pShow->pIter);
×
4261
        TAOS_CHECK_GOTO(code, &lino, _exit);
×
4262
      }
4263
      (void)tNameGetDbName(&name, varDataVal(objName));
5,827✔
4264
      varDataSetLen(objName, strlen(varDataVal(objName)));
5,827✔
4265
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5,827✔
4266
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
5,827✔
4267

4268
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
5,827✔
4269
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
5,827✔
4270
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5,827✔
4271
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
5,827✔
4272

4273
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
5,827✔
4274
      if (condition == NULL) {
5,827✔
4275
        sdbRelease(pSdb, pUser);
×
4276
        sdbCancelFetch(pSdb, pShow->pIter);
×
4277
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
4278
      }
4279
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
5,827✔
4280
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5,827✔
4281
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
5,827✔
4282

4283
      char notes[2] = {0};
5,827✔
4284
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
5,827✔
4285
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5,827✔
4286
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
5,827✔
4287

4288
      numOfRows++;
5,827✔
4289
      db = taosHashIterate(pUser->readDbs, db);
5,827✔
4290
    }
4291

4292
    db = taosHashIterate(pUser->writeDbs, NULL);
45,424✔
4293
    while (db != NULL) {
51,902✔
4294
      cols = 0;
6,478✔
4295
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
6,478✔
4296
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
6,478✔
4297
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
6,478✔
4298
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
6,478✔
4299

4300
      char privilege[20] = {0};
6,478✔
4301
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "write", pShow->pMeta->pSchemas[cols].bytes);
6,478✔
4302
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
6,478✔
4303
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
6,478✔
4304

4305
      SName name = {0};
6,478✔
4306
      char  objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
6,478✔
4307
      code = tNameFromString(&name, db, T_NAME_ACCT | T_NAME_DB);
6,478✔
4308
      if (code < 0) {
6,478✔
4309
        sdbRelease(pSdb, pUser);
×
4310
        sdbCancelFetch(pSdb, pShow->pIter);
×
4311
        TAOS_CHECK_GOTO(code, &lino, _exit);
×
4312
      }
4313
      (void)tNameGetDbName(&name, varDataVal(objName));
6,478✔
4314
      varDataSetLen(objName, strlen(varDataVal(objName)));
6,478✔
4315
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
6,478✔
4316
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
6,478✔
4317

4318
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
6,478✔
4319
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
6,478✔
4320
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
6,478✔
4321
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
6,478✔
4322

4323
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
6,478✔
4324
      if (condition == NULL) {
6,478✔
4325
        sdbRelease(pSdb, pUser);
×
4326
        sdbCancelFetch(pSdb, pShow->pIter);
×
4327
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
4328
      }
4329
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
6,478✔
4330
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
6,478✔
4331
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
6,478✔
4332

4333
      char notes[2] = {0};
6,478✔
4334
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
6,478✔
4335
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
6,478✔
4336
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
6,478✔
4337

4338
      numOfRows++;
6,478✔
4339
      db = taosHashIterate(pUser->writeDbs, db);
6,478✔
4340
    }
4341

4342
    TAOS_CHECK_EXIT(mndLoopHash(pUser->readTbs, "read", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
45,424✔
4343

4344
    TAOS_CHECK_EXIT(mndLoopHash(pUser->writeTbs, "write", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
45,424✔
4345

4346
    TAOS_CHECK_EXIT(mndLoopHash(pUser->alterTbs, "alter", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
45,424✔
4347

4348
    TAOS_CHECK_EXIT(mndLoopHash(pUser->readViews, "read", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
45,424✔
4349

4350
    TAOS_CHECK_EXIT(mndLoopHash(pUser->writeViews, "write", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
45,424✔
4351

4352
    TAOS_CHECK_EXIT(mndLoopHash(pUser->alterViews, "alter", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
45,424✔
4353

4354
    char *topic = taosHashIterate(pUser->topics, NULL);
45,424✔
4355
    while (topic != NULL) {
47,235✔
4356
      cols = 0;
1,811✔
4357
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
1,811✔
4358
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
1,811✔
4359
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1,811✔
4360
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
1,811✔
4361

4362
      char privilege[20] = {0};
1,811✔
4363
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "subscribe", pShow->pMeta->pSchemas[cols].bytes);
1,811✔
4364
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1,811✔
4365
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
1,811✔
4366

4367
      char topicName[TSDB_TOPIC_NAME_LEN + VARSTR_HEADER_SIZE + 5] = {0};
1,811✔
4368
      tstrncpy(varDataVal(topicName), mndGetDbStr(topic), TSDB_TOPIC_NAME_LEN - 2);
1,811✔
4369
      varDataSetLen(topicName, strlen(varDataVal(topicName)));
1,811✔
4370
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1,811✔
4371
      COL_DATA_SET_VAL_GOTO((const char *)topicName, false, pUser, pShow->pIter, _exit);
1,811✔
4372

4373
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
1,811✔
4374
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
1,811✔
4375
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1,811✔
4376
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
1,811✔
4377

4378
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
1,811✔
4379
      if (condition == NULL) {
1,811✔
4380
        sdbRelease(pSdb, pUser);
×
4381
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
4382
      }
4383
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
1,811✔
4384
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1,811✔
4385
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
1,811✔
4386

4387
      char notes[2] = {0};
1,811✔
4388
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
1,811✔
4389
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1,811✔
4390
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
1,811✔
4391

4392
      numOfRows++;
1,811✔
4393
      topic = taosHashIterate(pUser->topics, topic);
1,811✔
4394
    }
4395

4396
    sdbRelease(pSdb, pUser);
45,424✔
4397
  }
4398

4399
  pShow->numOfRows += numOfRows;
7,541✔
4400
_exit:
7,541✔
4401
  taosMemoryFreeClear(condition);
7,541✔
4402
  taosMemoryFreeClear(sql);
7,541✔
4403
  if (code < 0) {
7,541✔
4404
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4405
    TAOS_RETURN(code);
×
4406
  }
4407
  return numOfRows;
7,541✔
4408
}
4409

4410
static void mndCancelGetNextPrivileges(SMnode *pMnode, void *pIter) {
×
4411
  SSdb *pSdb = pMnode->pSdb;
×
4412
  sdbCancelFetchByType(pSdb, pIter, SDB_USER);
×
4413
}
×
4414

4415
int32_t mndValidateUserAuthInfo(SMnode *pMnode, SUserAuthVersion *pUsers, int32_t numOfUses, void **ppRsp,
6,677,294✔
4416
                                int32_t *pRspLen, int64_t ipWhiteListVer) {
4417
  int32_t           code = 0;
6,677,294✔
4418
  int32_t           lino = 0;
6,677,294✔
4419
  int32_t           rspLen = 0;
6,677,294✔
4420
  void             *pRsp = NULL;
6,677,294✔
4421
  SUserAuthBatchRsp batchRsp = {0};
6,677,294✔
4422

4423
  batchRsp.pArray = taosArrayInit(numOfUses, sizeof(SGetUserAuthRsp));
6,677,294✔
4424
  if (batchRsp.pArray == NULL) {
6,677,294✔
4425
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
4426
  }
4427

4428
  for (int32_t i = 0; i < numOfUses; ++i) {
13,501,112✔
4429
    SUserObj *pUser = NULL;
6,823,818✔
4430
    code = mndAcquireUser(pMnode, pUsers[i].user, &pUser);
6,823,818✔
4431
    if (pUser == NULL) {
6,823,818✔
4432
      if (TSDB_CODE_MND_USER_NOT_EXIST == code) {
2,968✔
4433
        SGetUserAuthRsp rsp = {.dropped = 1};
2,968✔
4434
        (void)memcpy(rsp.user, pUsers[i].user, TSDB_USER_LEN);
2,968✔
4435
        TSDB_CHECK_NULL(taosArrayPush(batchRsp.pArray, &rsp), code, lino, _OVER, TSDB_CODE_OUT_OF_MEMORY);
5,936✔
4436
      }
4437
      mError("user:%s, failed to auth user since %s", pUsers[i].user, tstrerror(code));
2,968✔
4438
      code = 0;
2,968✔
4439
      continue;
3,307✔
4440
    }
4441

4442
    pUsers[i].version = ntohl(pUsers[i].version);
6,820,850✔
4443
    if (pUser->authVersion <= pUsers[i].version && ipWhiteListVer == pMnode->ipWhiteVer) {
6,820,850✔
4444
      mndReleaseUser(pMnode, pUser);
6,473,211✔
4445
      continue;
6,473,211✔
4446
    }
4447

4448
    SGetUserAuthRsp rsp = {0};
347,639✔
4449
    code = mndSetUserAuthRsp(pMnode, pUser, &rsp);
347,639✔
4450
    if (code) {
347,639✔
4451
      mndReleaseUser(pMnode, pUser);
×
4452
      tFreeSGetUserAuthRsp(&rsp);
×
4453
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
4454
    }
4455

4456
    if (!(taosArrayPush(batchRsp.pArray, &rsp))) {
695,278✔
4457
      code = terrno;
×
4458
      mndReleaseUser(pMnode, pUser);
×
4459
      tFreeSGetUserAuthRsp(&rsp);
×
4460
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
4461
    }
4462
    mndReleaseUser(pMnode, pUser);
347,639✔
4463
  }
4464

4465
  if (taosArrayGetSize(batchRsp.pArray) <= 0) {
6,677,294✔
4466
    *ppRsp = NULL;
6,331,924✔
4467
    *pRspLen = 0;
6,331,924✔
4468

4469
    tFreeSUserAuthBatchRsp(&batchRsp);
6,331,924✔
4470
    return 0;
6,331,924✔
4471
  }
4472

4473
  rspLen = tSerializeSUserAuthBatchRsp(NULL, 0, &batchRsp);
345,370✔
4474
  if (rspLen < 0) {
345,370✔
4475
    TAOS_CHECK_GOTO(rspLen, &lino, _OVER);
×
4476
  }
4477
  pRsp = taosMemoryMalloc(rspLen);
345,370✔
4478
  if (pRsp == NULL) {
345,370✔
4479
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
4480
  }
4481
  rspLen = tSerializeSUserAuthBatchRsp(pRsp, rspLen, &batchRsp);
345,370✔
4482
  if (rspLen < 0) {
345,370✔
4483
    TAOS_CHECK_GOTO(rspLen, &lino, _OVER);
×
4484
  }
4485
_OVER:
345,370✔
4486
  tFreeSUserAuthBatchRsp(&batchRsp);
345,370✔
4487
  if (code < 0) {
345,370✔
4488
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4489
    taosMemoryFreeClear(pRsp);
×
4490
    rspLen = 0;
×
4491
  }
4492
  *ppRsp = pRsp;
345,370✔
4493
  *pRspLen = rspLen;
345,370✔
4494

4495
  TAOS_RETURN(code);
345,370✔
4496
}
4497

4498
static int32_t mndRemoveDbPrivileges(SHashObj *pHash, const char *dbFName, int32_t dbFNameLen, int32_t *nRemoved) {
11,454✔
4499
  void *pVal = NULL;
11,454✔
4500
  while ((pVal = taosHashIterate(pHash, pVal))) {
22,219✔
4501
    size_t keyLen = 0;
10,765✔
4502
    char  *pKey = (char *)taosHashGetKey(pVal, &keyLen);
10,765✔
4503
    if (pKey == NULL || keyLen <= dbFNameLen) continue;
10,765✔
4504
    if ((*(pKey + dbFNameLen) == '.') && strncmp(pKey, dbFName, dbFNameLen) == 0) {
10,765✔
4505
      TAOS_CHECK_RETURN(taosHashRemove(pHash, pKey, keyLen));
6,369✔
4506
      if (nRemoved) ++(*nRemoved);
6,369✔
4507
    }
4508
  }
4509
  TAOS_RETURN(0);
11,454✔
4510
}
4511

4512
int32_t mndUserRemoveDb(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SSHashObj **ppUsers) {
425,885✔
4513
  int32_t    code = 0, lino = 0;
425,885✔
4514
  SSdb      *pSdb = pMnode->pSdb;
425,885✔
4515
  int32_t    dbLen = strlen(pDb->name);
425,885✔
4516
  void      *pIter = NULL;
425,885✔
4517
  SUserObj  *pUser = NULL;
425,885✔
4518
  SUserObj   newUser = {0};
425,885✔
4519
  SSHashObj *pUsers = ppUsers ? *ppUsers : NULL;
425,885✔
4520
  bool       output = (ppUsers != NULL);
425,885✔
4521

4522
  while (1) {
457,404✔
4523
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
883,289✔
4524
    if (pIter == NULL) break;
883,289✔
4525

4526
    bool update = false;
457,404✔
4527
    bool inReadDb = (taosHashGet(pUser->readDbs, pDb->name, dbLen + 1) != NULL);
457,404✔
4528
    bool inWriteDb = (taosHashGet(pUser->writeDbs, pDb->name, dbLen + 1) != NULL);
457,404✔
4529
    bool inUseDb = (taosHashGet(pUser->useDbs, pDb->name, dbLen + 1) != NULL);
457,404✔
4530
    bool inReadTbs = taosHashGetSize(pUser->readTbs) > 0;
457,404✔
4531
    bool inWriteTbs = taosHashGetSize(pUser->writeTbs) > 0;
457,404✔
4532
    bool inAlterTbs = taosHashGetSize(pUser->alterTbs) > 0;
457,404✔
4533
    bool inReadViews = taosHashGetSize(pUser->readViews) > 0;
457,404✔
4534
    bool inWriteViews = taosHashGetSize(pUser->writeViews) > 0;
457,404✔
4535
    bool inAlterViews = taosHashGetSize(pUser->alterViews) > 0;
457,404✔
4536
    // no need remove pUser->topics since topics must be dropped ahead of db
4537
    if (!inReadDb && !inWriteDb && !inReadTbs && !inWriteTbs && !inAlterTbs && !inReadViews && !inWriteViews &&
457,404✔
4538
        !inAlterViews) {
453,553✔
4539
      sdbRelease(pSdb, pUser);
453,553✔
4540
      continue;
453,553✔
4541
    }
4542
    SUserObj *pTargetUser = &newUser;
3,851✔
4543
    if (output) {
3,851✔
4544
      if (!pUsers) {
664✔
4545
        TSDB_CHECK_NULL(pUsers = tSimpleHashInit(32, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY)), code, lino,
332✔
4546
                        _exit, TSDB_CODE_OUT_OF_MEMORY);
4547
        *ppUsers = pUsers;
332✔
4548
      }
4549
      void   *pVal = NULL;
664✔
4550
      int32_t userLen = strlen(pUser->user) + 1;
664✔
4551
      if ((pVal = tSimpleHashGet(pUsers, pUser->user, userLen)) != NULL) {
664✔
4552
        pTargetUser = (SUserObj *)pVal;
332✔
4553
      } else {
4554
        TAOS_CHECK_EXIT(mndUserDupObj(pUser, &newUser));
332✔
4555
        TAOS_CHECK_EXIT(tSimpleHashPut(pUsers, pUser->user, userLen, &newUser, sizeof(SUserObj)));
332✔
4556
        TSDB_CHECK_NULL((pVal = tSimpleHashGet(pUsers, pUser->user, userLen)), code, lino, _exit,
332✔
4557
                        TSDB_CODE_OUT_OF_MEMORY);
4558
        pTargetUser = (SUserObj *)pVal;
332✔
4559
      }
4560
    } else {
4561
      TAOS_CHECK_EXIT(mndUserDupObj(pUser, &newUser));
3,187✔
4562
    }
4563
    if (inReadDb) {
3,851✔
4564
      TAOS_CHECK_EXIT(taosHashRemove(pTargetUser->readDbs, pDb->name, dbLen + 1));
1,115✔
4565
    }
4566
    if (inWriteDb) {
3,851✔
4567
      TAOS_CHECK_EXIT(taosHashRemove(pTargetUser->writeDbs, pDb->name, dbLen + 1));
906✔
4568
    }
4569
    if (inUseDb) {
3,851✔
4570
      TAOS_CHECK_EXIT(taosHashRemove(pTargetUser->useDbs, pDb->name, dbLen + 1));
873✔
4571
    }
4572
    update = inReadDb || inWriteDb || inUseDb;
3,851✔
4573

4574
    int32_t nRemovedReadTbs = 0;
3,851✔
4575
    int32_t nRemovedWriteTbs = 0;
3,851✔
4576
    int32_t nRemovedAlterTbs = 0;
3,851✔
4577
    if (inReadTbs || inWriteTbs || inAlterTbs) {
3,851✔
4578
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->readTbs, pDb->name, dbLen, &nRemovedReadTbs));
3,609✔
4579
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->writeTbs, pDb->name, dbLen, &nRemovedWriteTbs));
3,609✔
4580
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->alterTbs, pDb->name, dbLen, &nRemovedAlterTbs));
3,609✔
4581
      if (!update) update = nRemovedReadTbs > 0 || nRemovedWriteTbs > 0 || nRemovedAlterTbs > 0;
3,609✔
4582
    }
4583

4584
    int32_t nRemovedReadViews = 0;
3,851✔
4585
    int32_t nRemovedWriteViews = 0;
3,851✔
4586
    int32_t nRemovedAlterViews = 0;
3,851✔
4587
    if (inReadViews || inWriteViews || inAlterViews) {
3,851✔
4588
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->readViews, pDb->name, dbLen, &nRemovedReadViews));
209✔
4589
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->writeViews, pDb->name, dbLen, &nRemovedWriteViews));
209✔
4590
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->alterViews, pDb->name, dbLen, &nRemovedAlterViews));
209✔
4591
      if (!update) update = nRemovedReadViews > 0 || nRemovedWriteViews > 0 || nRemovedAlterViews > 0;
209✔
4592
    }
4593

4594
    if (!output) {
3,851✔
4595
      if (update) {
3,187✔
4596
        SSdbRaw *pCommitRaw = mndUserActionEncode(pTargetUser);
451✔
4597
        if (pCommitRaw == NULL) {
451✔
4598
          TAOS_CHECK_EXIT(terrno);
×
4599
        }
4600
        TAOS_CHECK_EXIT(mndTransAppendCommitlog(pTrans, pCommitRaw));
451✔
4601
        TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
451✔
4602
      }
4603
      mndUserFreeObj(&newUser);
3,187✔
4604
    }
4605
    sdbRelease(pSdb, pUser);
3,851✔
4606
  }
4607

4608
_exit:
425,885✔
4609
  if (code < 0) {
425,885✔
4610
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4611
    mndUserFreeObj(&newUser);
×
4612
  }
4613
  if (pUser != NULL) sdbRelease(pSdb, pUser);
425,885✔
4614
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
425,885✔
4615
  if (!output) mndUserFreeObj(&newUser);
425,885✔
4616
  TAOS_RETURN(code);
425,885✔
4617
}
4618

4619
int32_t mndUserRemoveStb(SMnode *pMnode, STrans *pTrans, char *stb) {
274,981✔
4620
  int32_t   code = 0;
274,981✔
4621
  SSdb     *pSdb = pMnode->pSdb;
274,981✔
4622
  int32_t   len = strlen(stb) + 1;
274,981✔
4623
  void     *pIter = NULL;
274,981✔
4624
  SUserObj *pUser = NULL;
274,981✔
4625
  SUserObj  newUser = {0};
274,981✔
4626

4627
  while (1) {
274,981✔
4628
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
549,962✔
4629
    if (pIter == NULL) break;
549,962✔
4630

4631
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
274,981✔
4632
      break;
×
4633
    }
4634

4635
    bool inRead = (taosHashGet(newUser.readTbs, stb, len) != NULL);
274,981✔
4636
    bool inWrite = (taosHashGet(newUser.writeTbs, stb, len) != NULL);
274,981✔
4637
    bool inAlter = (taosHashGet(newUser.alterTbs, stb, len) != NULL);
274,981✔
4638
    if (inRead || inWrite || inAlter) {
274,981✔
4639
      code = taosHashRemove(newUser.readTbs, stb, len);
×
4640
      if (code < 0) {
×
4641
        mError("failed to remove readTbs:%s from user:%s", stb, pUser->user);
×
4642
      }
4643
      code = taosHashRemove(newUser.writeTbs, stb, len);
×
4644
      if (code < 0) {
×
4645
        mError("failed to remove writeTbs:%s from user:%s", stb, pUser->user);
×
4646
      }
4647
      code = taosHashRemove(newUser.alterTbs, stb, len);
×
4648
      if (code < 0) {
×
4649
        mError("failed to remove alterTbs:%s from user:%s", stb, pUser->user);
×
4650
      }
4651

4652
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
×
4653
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
×
4654
        code = TSDB_CODE_OUT_OF_MEMORY;
×
4655
        break;
×
4656
      }
4657
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
×
4658
      if (code != 0) {
×
4659
        mndUserFreeObj(&newUser);
×
4660
        sdbRelease(pSdb, pUser);
×
4661
        TAOS_RETURN(code);
×
4662
      }
4663
    }
4664

4665
    mndUserFreeObj(&newUser);
274,981✔
4666
    sdbRelease(pSdb, pUser);
274,981✔
4667
  }
4668

4669
  if (pUser != NULL) sdbRelease(pSdb, pUser);
274,981✔
4670
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
274,981✔
4671
  mndUserFreeObj(&newUser);
274,981✔
4672
  TAOS_RETURN(code);
274,981✔
4673
}
4674

4675
int32_t mndUserRemoveView(SMnode *pMnode, STrans *pTrans, char *view) {
88,050✔
4676
  int32_t   code = 0;
88,050✔
4677
  SSdb     *pSdb = pMnode->pSdb;
88,050✔
4678
  int32_t   len = strlen(view) + 1;
88,050✔
4679
  void     *pIter = NULL;
88,050✔
4680
  SUserObj *pUser = NULL;
88,050✔
4681
  SUserObj  newUser = {0};
88,050✔
4682

4683
  while (1) {
91,649✔
4684
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
179,699✔
4685
    if (pIter == NULL) break;
179,699✔
4686

4687
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
91,649✔
4688
      break;
×
4689
    }
4690

4691
    bool inRead = (taosHashGet(newUser.readViews, view, len) != NULL);
91,649✔
4692
    bool inWrite = (taosHashGet(newUser.writeViews, view, len) != NULL);
91,649✔
4693
    bool inAlter = (taosHashGet(newUser.alterViews, view, len) != NULL);
91,649✔
4694
    if (inRead || inWrite || inAlter) {
91,649✔
4695
      code = taosHashRemove(newUser.readViews, view, len);
2,231✔
4696
      if (code < 0) {
2,231✔
4697
        mError("failed to remove readViews:%s from user:%s", view, pUser->user);
442✔
4698
      }
4699
      code = taosHashRemove(newUser.writeViews, view, len);
2,231✔
4700
      if (code < 0) {
2,231✔
4701
        mError("failed to remove writeViews:%s from user:%s", view, pUser->user);
1,126✔
4702
      }
4703
      code = taosHashRemove(newUser.alterViews, view, len);
2,231✔
4704
      if (code < 0) {
2,231✔
4705
        mError("failed to remove alterViews:%s from user:%s", view, pUser->user);
684✔
4706
      }
4707

4708
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
2,231✔
4709
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
2,231✔
4710
        code = TSDB_CODE_OUT_OF_MEMORY;
×
4711
        break;
×
4712
      }
4713
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
2,231✔
4714
      if (code < 0) {
2,231✔
4715
        mndUserFreeObj(&newUser);
×
4716
        sdbRelease(pSdb, pUser);
×
4717
        TAOS_RETURN(code);
×
4718
      }
4719
    }
4720

4721
    mndUserFreeObj(&newUser);
91,649✔
4722
    sdbRelease(pSdb, pUser);
91,649✔
4723
  }
4724

4725
  if (pUser != NULL) sdbRelease(pSdb, pUser);
88,050✔
4726
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
88,050✔
4727
  mndUserFreeObj(&newUser);
88,050✔
4728
  TAOS_RETURN(code);
88,050✔
4729
}
4730

4731
int32_t mndUserRemoveTopic(SMnode *pMnode, STrans *pTrans, char *topic) {
5,676✔
4732
  int32_t   code = 0;
5,676✔
4733
  SSdb     *pSdb = pMnode->pSdb;
5,676✔
4734
  int32_t   len = strlen(topic) + 1;
5,676✔
4735
  void     *pIter = NULL;
5,676✔
4736
  SUserObj *pUser = NULL;
5,676✔
4737
  SUserObj  newUser = {0};
5,676✔
4738

4739
  while (1) {
13,770✔
4740
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
19,446✔
4741
    if (pIter == NULL) {
19,446✔
4742
      break;
5,676✔
4743
    }
4744

4745
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
13,770✔
4746
      break;
×
4747
    }
4748

4749
    bool inTopic = (taosHashGet(newUser.topics, topic, len) != NULL);
13,770✔
4750
    if (inTopic) {
13,770✔
4751
      code = taosHashRemove(newUser.topics, topic, len);
209✔
4752
      if (code < 0) {
209✔
4753
        mError("failed to remove topic:%s from user:%s", topic, pUser->user);
×
4754
      }
4755
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
209✔
4756
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
209✔
4757
        code = TSDB_CODE_OUT_OF_MEMORY;
×
4758
        break;
×
4759
      }
4760
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
209✔
4761
      if (code < 0) {
209✔
4762
        mndUserFreeObj(&newUser);
×
4763
        sdbRelease(pSdb, pUser);
×
4764
        TAOS_RETURN(code);
×
4765
      }
4766
    }
4767

4768
    mndUserFreeObj(&newUser);
13,770✔
4769
    sdbRelease(pSdb, pUser);
13,770✔
4770
  }
4771

4772
  if (pUser != NULL) sdbRelease(pSdb, pUser);
5,676✔
4773
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
5,676✔
4774
  mndUserFreeObj(&newUser);
5,676✔
4775
  TAOS_RETURN(code);
5,676✔
4776
}
4777

4778
int64_t mndGetUserIpWhiteListVer(SMnode *pMnode, SUserObj *pUser) {
×
4779
  // ver = 0, disable ip white list
4780
  // ver > 0, enable ip white list
4781
  return tsEnableWhiteList ? pUser->ipWhiteListVer : 0;
×
4782
}
4783

4784
int64_t mndGetUserTimeWhiteListVer(SMnode *pMnode, SUserObj *pUser) {
×
4785
  // ver = 0, disable datetime white list
4786
  // ver > 0, enable datetime white list
4787
  return tsEnableWhiteList ? pUser->timeWhiteListVer : 0;
×
4788
}
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