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

taosdata / TDengine / #4897

25 Dec 2025 10:17AM UTC coverage: 65.717% (-0.2%) from 65.929%
#4897

push

travis-ci

web-flow
fix: [6622889291] Fix invalid rowSize. (#34043)

186011 of 283047 relevant lines covered (65.72%)

113853896.64 hits per line

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

72.76
/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 "mndToken.h"
31
#include "tbase64.h"
32
#include "totp.h"
33

34
// clang-format on
35

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

141

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

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

155
static SUserCache userCache;
156

157

158
static int32_t userCacheInit() {
514,590✔
159
  _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
514,590✔
160

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

166
  userCache.users = users;
514,590✔
167
  userCache.verIp = 0;
514,590✔
168
  userCache.verTime = 0;
514,590✔
169

170
  (void)taosThreadRwlockInit(&userCache.rw, NULL);
514,590✔
171
  TAOS_RETURN(0);
514,590✔
172
}
173

174

175

176
static void userCacheCleanup() {
514,469✔
177
  if (userCache.users == NULL) {
514,469✔
178
    return;
×
179
  }
180

181
  void *pIter = taosHashIterate(userCache.users, NULL);
514,469✔
182
  while (pIter) {
1,039,180✔
183
    SCachedUserInfo *pInfo = *(SCachedUserInfo **)pIter;
524,711✔
184
    if (pInfo != NULL) {
524,711✔
185
      taosMemoryFree(pInfo->wlIp);
524,711✔
186
      taosMemoryFree(pInfo->wlTime);
524,711✔
187
      taosMemoryFree(pInfo);
524,711✔
188
    }
189
    pIter = taosHashIterate(userCache.users, pIter);
524,711✔
190
  }
191
  taosHashCleanup(userCache.users);
514,469✔
192

193
  (void)taosThreadRwlockDestroy(&userCache.rw);
514,469✔
194
}
195

196

197

198
static void userCacheRemoveUser(const char *user) {
59,371✔
199
  size_t userLen = strlen(user);
59,371✔
200

201
  (void)taosThreadRwlockWrlock(&userCache.rw);
59,371✔
202

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

217
  (void)taosThreadRwlockUnlock(&userCache.rw);
59,371✔
218
}
59,371✔
219

220

221

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

225
  (void)taosThreadRwlockWrlock(&userCache.rw);
1,339✔
226

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

234
  (void)taosThreadRwlockUnlock(&userCache.rw);
1,339✔
235
}
1,339✔
236

237

238

239
static SCachedUserInfo* getCachedUserInfo(const char* user) {
4,123,701✔
240
  size_t userLen = strlen(user);
4,123,701✔
241
  SCachedUserInfo **ppInfo = taosHashGet(userCache.users, user, userLen);
4,123,701✔
242
  if (ppInfo != NULL) {
4,123,701✔
243
    return *ppInfo;
3,539,619✔
244
  }
245

246
  SCachedUserInfo  *pInfo = (SCachedUserInfo *)taosMemoryCalloc(1, sizeof(SCachedUserInfo));
584,082✔
247
  if (pInfo == NULL) {
584,082✔
248
    return NULL;
×
249
  }
250

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

256
  return pInfo;
584,082✔
257
}
258

259

260

261
void mndGetUserLoginInfo(const char *user, SLoginInfo *pLoginInfo) {
2,574,055✔
262
  size_t userLen = strlen(user);
2,574,055✔
263

264
  (void)taosThreadRwlockRdlock(&userCache.rw);
2,574,055✔
265

266
  SCachedUserInfo **ppInfo = taosHashGet(userCache.users, user, userLen);
2,574,470✔
267
  if (ppInfo != NULL && *ppInfo != NULL) {
2,574,026✔
268
    pLoginInfo->lastLoginTime = (*ppInfo)->loginInfo.lastLoginTime;
2,243,370✔
269
    pLoginInfo->failedLoginCount = (*ppInfo)->loginInfo.failedLoginCount;
2,242,935✔
270
    pLoginInfo->lastFailedLoginTime = (*ppInfo)->loginInfo.lastFailedLoginTime;
2,242,967✔
271
  } else {
272
    pLoginInfo->lastLoginTime = taosGetTimestampSec();
330,914✔
273
    pLoginInfo->failedLoginCount = 0;
330,656✔
274
    pLoginInfo->lastFailedLoginTime = 0;
330,656✔
275
  }
276

277
  (void)taosThreadRwlockUnlock(&userCache.rw);
2,573,672✔
278

279
  if (pLoginInfo->lastLoginTime == 0) {
2,574,470✔
280
    pLoginInfo->lastLoginTime = taosGetTimestampSec();
47,124✔
281
  }
282
}
2,573,805✔
283

284

285

286
void mndSetUserLoginInfo(const char *user, const SLoginInfo *pLoginInfo) {
2,574,313✔
287
  size_t userLen = strlen(user);
2,574,313✔
288

289
  (void)taosThreadRwlockWrlock(&userCache.rw);
2,574,313✔
290

291
  SCachedUserInfo  *pInfo = getCachedUserInfo(user);
2,574,470✔
292
  if (pInfo != NULL) {
2,574,470✔
293
    pInfo->loginInfo.lastLoginTime = pLoginInfo->lastLoginTime;
2,574,470✔
294
    pInfo->loginInfo.failedLoginCount = pLoginInfo->failedLoginCount;
2,574,470✔
295
    pInfo->loginInfo.lastFailedLoginTime = pLoginInfo->lastFailedLoginTime;
2,574,470✔
296
  }
297

298
  (void)taosThreadRwlockUnlock(&userCache.rw);
2,574,470✔
299
}
2,574,470✔
300

301

302

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

308
  if (a == NULL || b == NULL) {
1,033,482✔
309
    return false;
100,947✔
310
  }
311

312
  if (a->num != b->num) {
932,535✔
313
    return false;
×
314
  }
315

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

325
  return true;
932,535✔
326
}
327

328

329

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

333
  (void)taosThreadRwlockWrlock(&userCache.rw);
1,033,482✔
334

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

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

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

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

368

369

370
static int32_t userCacheRebuildIpWhiteList(SMnode *pMnode) {
622,094✔
371
  int32_t   code = 0, lino = 0;
622,094✔
372

373
  SSdb     *pSdb = pMnode->pSdb;
622,094✔
374
  void     *pIter = NULL;
622,094✔
375
  while (1) {
263,644✔
376
    SUserObj *pUser = NULL;
885,738✔
377
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
885,738✔
378
    if (pIter == NULL) {
885,738✔
379
      break;
622,094✔
380
    }
381

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

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

396
    taosMemoryFree(pInfo->wlIp);
263,644✔
397
    pInfo->wlIp = wl;
263,644✔
398

399
    sdbRelease(pSdb, pUser);
263,644✔
400
  }
401

402
  userCache.verIp++;
622,094✔
403

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

411

412

413
int64_t mndGetIpWhiteListVersion(SMnode *pMnode) {
41,351,087✔
414
  int64_t ver = 0;
41,351,087✔
415
  int32_t code = 0;
41,351,087✔
416

417
  if (mndEnableIpWhiteList(pMnode) != 0 && tsEnableWhiteList) {
41,351,087✔
418
    (void)taosThreadRwlockWrlock(&userCache.rw);
15,408✔
419

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

431
    (void)taosThreadRwlockUnlock(&userCache.rw);
15,408✔
432
  }
433

434
  mDebug("ip-white-list on mnode ver: %" PRId64, ver);
41,351,087✔
435
  return ver;
41,351,087✔
436
}
437

438

439

440
int32_t mndRefreshUserIpWhiteList(SMnode *pMnode) {
622,094✔
441
  int32_t code = 0;
622,094✔
442
  (void)taosThreadRwlockWrlock(&userCache.rw);
622,094✔
443

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

451
  TAOS_RETURN(code);
622,094✔
452
}
453

454

455

456
static int32_t userCacheRebuildTimeWhiteList(SMnode *pMnode) {
610,555✔
457
  int32_t   code = 0, lino = 0;
610,555✔
458

459
  SSdb     *pSdb = pMnode->pSdb;
610,555✔
460
  void     *pIter = NULL;
610,555✔
461
  while (1) {
252,105✔
462
    SUserObj *pUser = NULL;
862,660✔
463
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
862,660✔
464
    if (pIter == NULL) {
862,660✔
465
      break;
610,555✔
466
    }
467

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

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

482
    taosMemoryFree(pInfo->wlTime);
252,105✔
483
    pInfo->wlTime = wl;
252,105✔
484

485
    sdbRelease(pSdb, pUser);
252,105✔
486
  }
487

488
  userCache.verTime++;
610,555✔
489

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

497

498

499
int32_t mndRefreshUserDateTimeWhiteList(SMnode *pMnode) {
610,555✔
500
  int32_t code = 0;
610,555✔
501
  (void)taosThreadRwlockWrlock(&userCache.rw);
610,555✔
502

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

510
  TAOS_RETURN(code);
610,555✔
511
}
512

513

514

515
int64_t mndGetTimeWhiteListVersion(SMnode *pMnode) {
41,351,087✔
516
  int64_t ver = 0;
41,351,087✔
517
  int32_t code = 0;
41,351,087✔
518

519
  if (mndEnableTimeWhiteList(pMnode) != 0 && tsEnableWhiteList) {
41,351,087✔
520
    (void)taosThreadRwlockWrlock(&userCache.rw);
15,408✔
521

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

533
    (void)taosThreadRwlockUnlock(&userCache.rw);
15,408✔
534
  }
535

536
  mDebug("datetime-white-list on mnode ver: %" PRId64, ver);
41,351,087✔
537
  return ver;
41,351,087✔
538
}
539

540

541

542
int32_t mndInitUser(SMnode *pMnode) {
514,590✔
543
  TAOS_CHECK_RETURN(userCacheInit());
514,590✔
544

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

556
  mndSetMsgHandle(pMnode, TDMT_MND_CREATE_USER, mndProcessCreateUserReq);
514,590✔
557
  mndSetMsgHandle(pMnode, TDMT_MND_ALTER_USER, mndProcessAlterUserReq);
514,590✔
558
  mndSetMsgHandle(pMnode, TDMT_MND_DROP_USER, mndProcessDropUserReq);
514,590✔
559
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_AUTH, mndProcessGetUserAuthReq);
514,590✔
560

561
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_IP_WHITELIST, mndProcessGetUserIpWhiteListReq);
514,590✔
562
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_IP_WHITELIST_DUAL, mndProcessGetUserIpWhiteListReq);
514,590✔
563
  mndSetMsgHandle(pMnode, TDMT_MND_RETRIEVE_IP_WHITELIST, mndProcessRetrieveIpWhiteListReq);
514,590✔
564
  mndSetMsgHandle(pMnode, TDMT_MND_RETRIEVE_IP_WHITELIST_DUAL, mndProcessRetrieveIpWhiteListReq);
514,590✔
565
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_DATETIME_WHITELIST, mndProcessGetUserDateTimeWhiteListReq);
514,590✔
566
  mndSetMsgHandle(pMnode, TDMT_MND_RETRIEVE_DATETIME_WHITELIST, mndProcessRetrieveDateTimeWhiteListReq);
514,590✔
567

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

577

578

579
void mndCleanupUser(SMnode *pMnode) {
514,469✔
580
  userCacheCleanup();
514,469✔
581
}
514,469✔
582

583

584

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

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

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

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

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

605

606

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

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

623

624

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

630
  if (a->type == 0) {
1,864,350✔
631
    SIpV4Range *a4 = &a->ipV4;
932,535✔
632
    SIpV4Range *b4 = &b->ipV4;
932,535✔
633
    return (a4->ip == b4->ip && a4->mask == b4->mask);
932,535✔
634
  }
635
  
636
  SIpV6Range *a6 = &a->ipV6;
931,815✔
637
  SIpV6Range *b6 = &b->ipV6;
931,815✔
638
  return (a6->addr[0] == b6->addr[0] && a6->addr[1] == b6->addr[1] && a6->mask == b6->mask);
931,815✔
639
}
640

641

642

643
static bool isIpWhiteListEqual(SIpWhiteListDual *a, SIpWhiteListDual *b) {
1,033,482✔
644
  if (a == NULL && b == NULL) {
1,033,482✔
645
    return true;
×
646
  }
647
  
648
  if (a == NULL || b == NULL) {
1,033,482✔
649
    return false;
100,947✔
650
  }
651

652
  if (a->num != b->num) {
932,535✔
653
    return false;
360✔
654
  }
655
  for (int i = 0; i < a->num; i++) {
2,796,525✔
656
    if (!isIpRangeEqual(&a->pIpRanges[i], &b->pIpRanges[i])) {
1,864,350✔
657
      return false;
×
658
    }
659
  }
660
  return true;
932,175✔
661
}
662

663

664
static int32_t compareIpRange(const void *a, const void *b, const void* arg) {
3,960✔
665
  SIpRange *ra = (SIpRange *)a;
3,960✔
666
  SIpRange *rb = (SIpRange *)b;
3,960✔
667

668
  if (ra->neg != rb->neg) {
3,960✔
669
    return (ra->neg) ? -1 : 1;
×
670
  }
671

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

676
  if (ra->type == 0) {
3,960✔
677
    if (ra->ipV4.ip != rb->ipV4.ip) {
3,960✔
678
      return (ra->ipV4.ip < rb->ipV4.ip) ? -1 : 1;
3,240✔
679
    }
680
    return (ra->ipV4.mask < rb->ipV4.mask) ? -1 : 1;
720✔
681
  }
682

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

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

696

697

698
static int32_t convertIpWhiteListToStr(SUserObj *pUser, char **buf) {
53,045✔
699
  SIpWhiteListDual *pList = pUser->pIpWhiteListDual;
53,045✔
700

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

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

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

719

720

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

728
  TAOS_CHECK_GOTO(tStartEncode(&encoder), &lino, _OVER);
2,555,725✔
729
  TAOS_CHECK_GOTO(tEncodeI32(&encoder, pList->num), &lino, _OVER);
5,111,450✔
730

731
  for (int i = 0; i < pList->num; i++) {
7,668,249✔
732
    SIpRange *pRange = &(pList->pIpRanges[i]);
5,112,524✔
733
    TAOS_CHECK_GOTO(tSerializeIpRange(&encoder, pRange), &lino, _OVER);
5,112,524✔
734
  }
735

736
  tEndEncode(&encoder);
2,555,725✔
737

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

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

754
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
1,666,770✔
755
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &pList->num), &lino, _OVER);
3,333,540✔
756

757
  for (int i = 0; i < pList->num; i++) {
5,001,027✔
758
    SIpRange *pRange = &(pList->pIpRanges[i]);
3,334,257✔
759
    TAOS_CHECK_GOTO(tDeserializeIpRange(&decoder, pRange, supportNeg), &lino, _OVER);
3,334,257✔
760
  }
761

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

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

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

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

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

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

803
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
1,666,770✔
804
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &num), &lino, _OVER);
1,666,770✔
805

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

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

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

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

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

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

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

860
  SIpRange v4 = {0};
435,067✔
861
  SIpRange v6 = {0};
435,067✔
862

863
#ifndef TD_ASTRA
864
  code = createDefaultIp4Range(&v4);
435,067✔
865
  TSDB_CHECK_CODE(code, lino, _error);
435,067✔
866

867
  code = createDefaultIp6Range(&v6);
435,067✔
868
  TSDB_CHECK_CODE(code, lino, _error);
435,067✔
869

870
#endif
871

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

884

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

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

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

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

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

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

920
  return pos;
×
921
}
922

923

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

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

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

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

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

944
  return 0;
×
945
}
946

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

951

952

953

954
static void dropOldPasswords(SUserObj *pUser) {
4,222,495✔
955
  if (pUser->numOfPasswords <= pUser->passwordReuseMax) {
4,222,495✔
956
    return;
4,171,923✔
957
  }
958

959
  int32_t reuseMax = pUser->passwordReuseMax;
50,572✔
960
  if (reuseMax == 0) {
50,572✔
961
    reuseMax = 1; // keep at least one password
46,942✔
962
  }
963

964
  int32_t now = taosGetTimestampSec();
50,572✔
965
  int32_t index = reuseMax;
50,572✔
966
  while(index < pUser->numOfPasswords) {
60,736✔
967
    SUserPassword *pPass = &pUser->passwords[index];
10,164✔
968
    if (now - pPass->setTime >= pUser->passwordReuseTime) {
10,164✔
969
      break;
×
970
    }
971
    index++;
10,164✔
972
  }
973

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

982

983

984

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

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

1001
  userObj.passwords[0].setTime = taosGetTimestampSec();
335,566✔
1002
  userObj.numOfPasswords = 1;
335,566✔
1003

1004
  tstrncpy(userObj.user, user, TSDB_USER_LEN);
335,566✔
1005
  tstrncpy(userObj.acct, acct, TSDB_USER_LEN);
335,566✔
1006
  userObj.createdTime = taosGetTimestampMs();
335,566✔
1007
  userObj.updateTime = userObj.createdTime;
335,566✔
1008
  userObj.sysInfo = 1;
335,566✔
1009
  userObj.enable = 1;
335,566✔
1010
  userObj.changePass = 2;
335,566✔
1011
  userObj.ipWhiteListVer = taosGetTimestampMs();
335,566✔
1012
  userObj.connectTime = TSDB_USER_CONNECT_TIME_DEFAULT;
335,566✔
1013
  userObj.connectIdleTime = TSDB_USER_CONNECT_IDLE_TIME_DEFAULT;
335,566✔
1014
  userObj.callPerSession = TSDB_USER_CALL_PER_SESSION_DEFAULT;
335,566✔
1015
  userObj.vnodePerCall = TSDB_USER_VNODE_PER_CALL_DEFAULT;
335,566✔
1016
  userObj.passwordReuseTime = TSDB_USER_PASSWORD_REUSE_TIME_DEFAULT;
335,566✔
1017
  userObj.passwordReuseMax = TSDB_USER_PASSWORD_REUSE_MAX_DEFAULT;
335,566✔
1018
  userObj.passwordLockTime = TSDB_USER_PASSWORD_LOCK_TIME_DEFAULT;
335,566✔
1019
  // this is the root user, set some fields to -1 to allow the user login without restriction
1020
  userObj.sessionPerUser = -1;
335,566✔
1021
  userObj.failedLoginAttempts = -1;
335,566✔
1022
  userObj.passwordLifeTime = -1;
335,566✔
1023
  userObj.passwordGraceTime = -1;
335,566✔
1024
  userObj.inactiveAccountTime = -1;
335,566✔
1025
  userObj.allowTokenNum = TSDB_USER_ALLOW_TOKEN_NUM_DEFAULT;
335,566✔
1026
  userObj.tokenNum = 0;
335,566✔
1027

1028
  userObj.pTimeWhiteList = taosMemoryCalloc(1, sizeof(SDateTimeWhiteList));
335,566✔
1029
  if (userObj.pTimeWhiteList == NULL) {
335,566✔
1030
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _ERROR);
×
1031
  }
1032
  
1033
  TAOS_CHECK_GOTO(createDefaultIpWhiteList(&userObj.pIpWhiteListDual), &lino, _ERROR);
335,566✔
1034
  if (strcmp(user, TSDB_DEFAULT_USER) == 0) {
335,566✔
1035
    userObj.superUser = 1;
335,566✔
1036
    userObj.createdb = 1;
335,566✔
1037
    userObj.sessionPerUser = -1;
335,566✔
1038
    userObj.callPerSession = -1;
335,566✔
1039
    userObj.vnodePerCall = -1;
335,566✔
1040
    userObj.failedLoginAttempts = -1;
335,566✔
1041
    userObj.passwordLifeTime = -1;
335,566✔
1042
    userObj.passwordLockTime = 1;
335,566✔
1043
    userObj.inactiveAccountTime = -1;
335,566✔
1044
    userObj.allowTokenNum = -1;
335,566✔
1045
    userObj.tokenNum = 0;
335,566✔
1046
  }
1047

1048
  SSdbRaw *pRaw = mndUserActionEncode(&userObj);
335,566✔
1049
  if (pRaw == NULL) goto _ERROR;
335,566✔
1050
  TAOS_CHECK_GOTO(sdbSetRawStatus(pRaw, SDB_STATUS_READY), &lino, _ERROR);
335,566✔
1051

1052
  mInfo("user:%s, will be created when deploying, raw:%p", userObj.user, pRaw);
335,566✔
1053

1054
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, NULL, "create-user");
335,566✔
1055
  if (pTrans == NULL) {
335,566✔
1056
    sdbFreeRaw(pRaw);
×
1057
    mError("user:%s, failed to create since %s", userObj.user, terrstr());
×
1058
    goto _ERROR;
×
1059
  }
1060
  mInfo("trans:%d, used to create user:%s", pTrans->id, userObj.user);
335,566✔
1061

1062
  if (mndTransAppendCommitlog(pTrans, pRaw) != 0) {
335,566✔
1063
    mError("trans:%d, failed to commit redo log since %s", pTrans->id, terrstr());
×
1064
    mndTransDrop(pTrans);
×
1065
    goto _ERROR;
×
1066
  }
1067
  TAOS_CHECK_GOTO(sdbSetRawStatus(pRaw, SDB_STATUS_READY), &lino, _ERROR);
335,566✔
1068

1069
  if (mndTransPrepare(pMnode, pTrans) != 0) {
335,566✔
1070
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
1071
    mndTransDrop(pTrans);
×
1072
    goto _ERROR;
×
1073
  }
1074

1075
  mndTransDrop(pTrans);
335,566✔
1076
  taosMemoryFree(userObj.passwords);
335,566✔
1077
  taosMemoryFree(userObj.pIpWhiteListDual);
335,566✔
1078
  taosMemoryFree(userObj.pTimeWhiteList);
335,566✔
1079
  return 0;
335,566✔
1080

1081
_ERROR:
×
1082
  taosMemoryFree(userObj.passwords);
×
1083
  taosMemoryFree(userObj.pIpWhiteListDual);
×
1084
  taosMemoryFree(userObj.pTimeWhiteList);
×
1085
  TAOS_RETURN(terrno ? terrno : TSDB_CODE_APP_ERROR);
×
1086
}
1087

1088
static int32_t mndCreateDefaultUsers(SMnode *pMnode) {
335,566✔
1089
  return mndCreateDefaultUser(pMnode, TSDB_DEFAULT_USER, TSDB_DEFAULT_USER, TSDB_DEFAULT_PASS);
335,566✔
1090
}
1091

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

1113
  char *stb = taosHashIterate(pUser->readTbs, NULL);
2,555,725✔
1114
  while (stb != NULL) {
3,010,830✔
1115
    size_t keyLen = 0;
455,105✔
1116
    void  *key = taosHashGetKey(stb, &keyLen);
455,105✔
1117
    size += sizeof(int32_t);
455,105✔
1118
    size += keyLen;
455,105✔
1119

1120
    size_t valueLen = 0;
455,105✔
1121
    valueLen = strlen(stb) + 1;
455,105✔
1122
    size += sizeof(int32_t);
455,105✔
1123
    size += valueLen;
455,105✔
1124
    stb = taosHashIterate(pUser->readTbs, stb);
455,105✔
1125
  }
1126

1127
  stb = taosHashIterate(pUser->writeTbs, NULL);
2,555,725✔
1128
  while (stb != NULL) {
3,015,400✔
1129
    size_t keyLen = 0;
459,675✔
1130
    void  *key = taosHashGetKey(stb, &keyLen);
459,675✔
1131
    size += sizeof(int32_t);
459,675✔
1132
    size += keyLen;
459,675✔
1133

1134
    size_t valueLen = 0;
459,675✔
1135
    valueLen = strlen(stb) + 1;
459,675✔
1136
    size += sizeof(int32_t);
459,675✔
1137
    size += valueLen;
459,675✔
1138
    stb = taosHashIterate(pUser->writeTbs, stb);
459,675✔
1139
  }
1140

1141
  stb = taosHashIterate(pUser->alterTbs, NULL);
2,555,725✔
1142
  while (stb != NULL) {
2,793,250✔
1143
    size_t keyLen = 0;
237,525✔
1144
    void  *key = taosHashGetKey(stb, &keyLen);
237,525✔
1145
    size += sizeof(int32_t);
237,525✔
1146
    size += keyLen;
237,525✔
1147

1148
    size_t valueLen = 0;
237,525✔
1149
    valueLen = strlen(stb) + 1;
237,525✔
1150
    size += sizeof(int32_t);
237,525✔
1151
    size += valueLen;
237,525✔
1152
    stb = taosHashIterate(pUser->alterTbs, stb);
237,525✔
1153
  }
1154

1155
  stb = taosHashIterate(pUser->readViews, NULL);
2,555,725✔
1156
  while (stb != NULL) {
2,604,022✔
1157
    size_t keyLen = 0;
48,297✔
1158
    void  *key = taosHashGetKey(stb, &keyLen);
48,297✔
1159
    size += sizeof(int32_t);
48,297✔
1160
    size += keyLen;
48,297✔
1161

1162
    size_t valueLen = 0;
48,297✔
1163
    valueLen = strlen(stb) + 1;
48,297✔
1164
    size += sizeof(int32_t);
48,297✔
1165
    size += valueLen;
48,297✔
1166
    stb = taosHashIterate(pUser->readViews, stb);
48,297✔
1167
  }
1168

1169
  stb = taosHashIterate(pUser->writeViews, NULL);
2,555,725✔
1170
  while (stb != NULL) {
2,592,646✔
1171
    size_t keyLen = 0;
36,921✔
1172
    void  *key = taosHashGetKey(stb, &keyLen);
36,921✔
1173
    size += sizeof(int32_t);
36,921✔
1174
    size += keyLen;
36,921✔
1175

1176
    size_t valueLen = 0;
36,921✔
1177
    valueLen = strlen(stb) + 1;
36,921✔
1178
    size += sizeof(int32_t);
36,921✔
1179
    size += valueLen;
36,921✔
1180
    stb = taosHashIterate(pUser->writeViews, stb);
36,921✔
1181
  }
1182

1183
  stb = taosHashIterate(pUser->alterViews, NULL);
2,555,725✔
1184
  while (stb != NULL) {
2,592,016✔
1185
    size_t keyLen = 0;
36,291✔
1186
    void  *key = taosHashGetKey(stb, &keyLen);
36,291✔
1187
    size += sizeof(int32_t);
36,291✔
1188
    size += keyLen;
36,291✔
1189

1190
    size_t valueLen = 0;
36,291✔
1191
    valueLen = strlen(stb) + 1;
36,291✔
1192
    size += sizeof(int32_t);
36,291✔
1193
    size += valueLen;
36,291✔
1194
    stb = taosHashIterate(pUser->alterViews, stb);
36,291✔
1195
  }
1196

1197
  int32_t *useDb = taosHashIterate(pUser->useDbs, NULL);
2,555,725✔
1198
  while (useDb != NULL) {
3,130,064✔
1199
    size_t keyLen = 0;
574,339✔
1200
    void  *key = taosHashGetKey(useDb, &keyLen);
574,339✔
1201
    size += sizeof(int32_t);
574,339✔
1202
    size += keyLen;
574,339✔
1203
    size += sizeof(int32_t);
574,339✔
1204
    useDb = taosHashIterate(pUser->useDbs, useDb);
574,339✔
1205
  }
1206

1207
  pRaw = sdbAllocRaw(SDB_USER, USER_VER_NUMBER, size);
2,555,725✔
1208
  if (pRaw == NULL) {
2,555,725✔
1209
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1210
  }
1211

1212
  int32_t dataPos = 0;
2,555,725✔
1213
  SDB_SET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN, _OVER)
2,555,725✔
1214

1215
  dropOldPasswords(pUser);
2,555,725✔
1216
  SDB_SET_INT32(pRaw, dataPos, pUser->numOfPasswords, _OVER)
2,555,725✔
1217
  for (int32_t i = 0; i < pUser->numOfPasswords; i++) {
5,142,279✔
1218
    SDB_SET_BINARY(pRaw, dataPos, pUser->passwords[i].pass, sizeof(pUser->passwords[i].pass), _OVER)
2,586,554✔
1219
    SDB_SET_INT32(pRaw, dataPos, pUser->passwords[i].setTime, _OVER)
2,586,554✔
1220
  }
1221
  SDB_SET_BINARY(pRaw, dataPos, pUser->salt, sizeof(pUser->salt), _OVER)
2,555,725✔
1222

1223
  SDB_SET_BINARY(pRaw, dataPos, pUser->acct, TSDB_USER_LEN, _OVER)
2,555,725✔
1224
  SDB_SET_INT64(pRaw, dataPos, pUser->createdTime, _OVER)
2,555,725✔
1225
  SDB_SET_INT64(pRaw, dataPos, pUser->updateTime, _OVER)
2,555,725✔
1226
  SDB_SET_INT8(pRaw, dataPos, pUser->superUser, _OVER)
2,555,725✔
1227
  SDB_SET_INT8(pRaw, dataPos, pUser->sysInfo, _OVER)
2,555,725✔
1228
  SDB_SET_INT8(pRaw, dataPos, pUser->enable, _OVER)
2,555,725✔
1229
  SDB_SET_UINT8(pRaw, dataPos, pUser->flag, _OVER)
2,555,725✔
1230
  SDB_SET_INT32(pRaw, dataPos, pUser->authVersion, _OVER)
2,555,725✔
1231
  SDB_SET_INT32(pRaw, dataPos, pUser->passVersion, _OVER)
2,555,725✔
1232
  SDB_SET_INT32(pRaw, dataPos, numOfReadDbs, _OVER)
2,555,725✔
1233
  SDB_SET_INT32(pRaw, dataPos, numOfWriteDbs, _OVER)
2,555,725✔
1234
  SDB_SET_INT32(pRaw, dataPos, numOfTopics, _OVER)
2,555,725✔
1235

1236
  char *db = taosHashIterate(pUser->readDbs, NULL);
2,555,725✔
1237
  while (db != NULL) {
2,893,386✔
1238
    SDB_SET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER);
337,661✔
1239
    db = taosHashIterate(pUser->readDbs, db);
337,661✔
1240
  }
1241

1242
  db = taosHashIterate(pUser->writeDbs, NULL);
2,555,725✔
1243
  while (db != NULL) {
2,886,903✔
1244
    SDB_SET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER);
331,178✔
1245
    db = taosHashIterate(pUser->writeDbs, db);
331,178✔
1246
  }
1247

1248
  char *topic = taosHashIterate(pUser->topics, NULL);
2,555,725✔
1249
  while (topic != NULL) {
2,572,759✔
1250
    SDB_SET_BINARY(pRaw, dataPos, topic, TSDB_TOPIC_FNAME_LEN, _OVER);
17,034✔
1251
    topic = taosHashIterate(pUser->topics, topic);
17,034✔
1252
  }
1253

1254
  SDB_SET_INT32(pRaw, dataPos, numOfReadTbs, _OVER)
2,555,725✔
1255
  SDB_SET_INT32(pRaw, dataPos, numOfWriteTbs, _OVER)
2,555,725✔
1256
  SDB_SET_INT32(pRaw, dataPos, numOfAlterTbs, _OVER)
2,555,725✔
1257
  SDB_SET_INT32(pRaw, dataPos, numOfReadViews, _OVER)
2,555,725✔
1258
  SDB_SET_INT32(pRaw, dataPos, numOfWriteViews, _OVER)
2,555,725✔
1259
  SDB_SET_INT32(pRaw, dataPos, numOfAlterViews, _OVER)
2,555,725✔
1260
  SDB_SET_INT32(pRaw, dataPos, numOfUseDbs, _OVER)
2,555,725✔
1261

1262
  stb = taosHashIterate(pUser->readTbs, NULL);
2,555,725✔
1263
  while (stb != NULL) {
3,010,830✔
1264
    size_t keyLen = 0;
455,105✔
1265
    void  *key = taosHashGetKey(stb, &keyLen);
455,105✔
1266
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
455,105✔
1267
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
455,105✔
1268

1269
    size_t valueLen = 0;
455,105✔
1270
    valueLen = strlen(stb) + 1;
455,105✔
1271
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
455,105✔
1272
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
455,105✔
1273
    stb = taosHashIterate(pUser->readTbs, stb);
455,105✔
1274
  }
1275

1276
  stb = taosHashIterate(pUser->writeTbs, NULL);
2,555,725✔
1277
  while (stb != NULL) {
3,015,400✔
1278
    size_t keyLen = 0;
459,675✔
1279
    void  *key = taosHashGetKey(stb, &keyLen);
459,675✔
1280
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
459,675✔
1281
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
459,675✔
1282

1283
    size_t valueLen = 0;
459,675✔
1284
    valueLen = strlen(stb) + 1;
459,675✔
1285
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
459,675✔
1286
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
459,675✔
1287
    stb = taosHashIterate(pUser->writeTbs, stb);
459,675✔
1288
  }
1289

1290
  stb = taosHashIterate(pUser->alterTbs, NULL);
2,555,725✔
1291
  while (stb != NULL) {
2,793,250✔
1292
    size_t keyLen = 0;
237,525✔
1293
    void  *key = taosHashGetKey(stb, &keyLen);
237,525✔
1294
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
237,525✔
1295
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
237,525✔
1296

1297
    size_t valueLen = 0;
237,525✔
1298
    valueLen = strlen(stb) + 1;
237,525✔
1299
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
237,525✔
1300
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
237,525✔
1301
    stb = taosHashIterate(pUser->alterTbs, stb);
237,525✔
1302
  }
1303

1304
  stb = taosHashIterate(pUser->readViews, NULL);
2,555,725✔
1305
  while (stb != NULL) {
2,604,022✔
1306
    size_t keyLen = 0;
48,297✔
1307
    void  *key = taosHashGetKey(stb, &keyLen);
48,297✔
1308
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
48,297✔
1309
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
48,297✔
1310

1311
    size_t valueLen = 0;
48,297✔
1312
    valueLen = strlen(stb) + 1;
48,297✔
1313
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
48,297✔
1314
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
48,297✔
1315
    stb = taosHashIterate(pUser->readViews, stb);
48,297✔
1316
  }
1317

1318
  stb = taosHashIterate(pUser->writeViews, NULL);
2,555,725✔
1319
  while (stb != NULL) {
2,592,646✔
1320
    size_t keyLen = 0;
36,921✔
1321
    void  *key = taosHashGetKey(stb, &keyLen);
36,921✔
1322
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
36,921✔
1323
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
36,921✔
1324

1325
    size_t valueLen = 0;
36,921✔
1326
    valueLen = strlen(stb) + 1;
36,921✔
1327
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
36,921✔
1328
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
36,921✔
1329
    stb = taosHashIterate(pUser->writeViews, stb);
36,921✔
1330
  }
1331

1332
  stb = taosHashIterate(pUser->alterViews, NULL);
2,555,725✔
1333
  while (stb != NULL) {
2,592,016✔
1334
    size_t keyLen = 0;
36,291✔
1335
    void  *key = taosHashGetKey(stb, &keyLen);
36,291✔
1336
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
36,291✔
1337
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
36,291✔
1338

1339
    size_t valueLen = 0;
36,291✔
1340
    valueLen = strlen(stb) + 1;
36,291✔
1341
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
36,291✔
1342
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
36,291✔
1343
    stb = taosHashIterate(pUser->alterViews, stb);
36,291✔
1344
  }
1345

1346
  useDb = taosHashIterate(pUser->useDbs, NULL);
2,555,725✔
1347
  while (useDb != NULL) {
3,130,064✔
1348
    size_t keyLen = 0;
574,339✔
1349
    void  *key = taosHashGetKey(useDb, &keyLen);
574,339✔
1350
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
574,339✔
1351
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
574,339✔
1352

1353
    SDB_SET_INT32(pRaw, dataPos, *useDb, _OVER)
574,339✔
1354
    useDb = taosHashIterate(pUser->useDbs, useDb);
574,339✔
1355
  }
1356

1357
  // save white list
1358
  int32_t num = pUser->pIpWhiteListDual->num;
2,555,725✔
1359
  int32_t tlen = sizeof(SIpWhiteListDual) + num * sizeof(SIpRange) + 4;
2,555,725✔
1360
  if ((buf = taosMemoryCalloc(1, tlen)) == NULL) {
2,555,725✔
1361
    TAOS_CHECK_GOTO(terrno, NULL, _OVER);
×
1362
  }
1363
  int32_t len = 0;
2,555,725✔
1364
  TAOS_CHECK_GOTO(tSerializeIpWhiteList(buf, tlen, pUser->pIpWhiteListDual, &len), &lino, _OVER);
2,555,725✔
1365

1366
  SDB_SET_INT32(pRaw, dataPos, len, _OVER);
2,555,725✔
1367
  SDB_SET_BINARY(pRaw, dataPos, buf, len, _OVER);
2,555,725✔
1368

1369
  SDB_SET_INT64(pRaw, dataPos, pUser->ipWhiteListVer, _OVER);
2,555,725✔
1370
  SDB_SET_INT8(pRaw, dataPos, pUser->passEncryptAlgorithm, _OVER);
2,555,725✔
1371

1372
  SDB_SET_BINARY(pRaw, dataPos, pUser->totpsecret, sizeof(pUser->totpsecret), _OVER);
2,555,725✔
1373
  SDB_SET_INT8(pRaw, dataPos, pUser->changePass, _OVER);
2,555,725✔
1374
  SDB_SET_INT32(pRaw, dataPos, pUser->sessionPerUser, _OVER);
2,555,725✔
1375
  SDB_SET_INT32(pRaw, dataPos, pUser->connectTime, _OVER);
2,555,725✔
1376
  SDB_SET_INT32(pRaw, dataPos, pUser->connectIdleTime, _OVER);
2,555,725✔
1377
  SDB_SET_INT32(pRaw, dataPos, pUser->callPerSession, _OVER);
2,555,725✔
1378
  SDB_SET_INT32(pRaw, dataPos, pUser->vnodePerCall, _OVER);
2,555,725✔
1379
  SDB_SET_INT32(pRaw, dataPos, pUser->failedLoginAttempts, _OVER);
2,555,725✔
1380
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordLifeTime, _OVER);
2,555,725✔
1381
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordReuseTime, _OVER);
2,555,725✔
1382
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordReuseMax, _OVER);
2,555,725✔
1383
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordLockTime, _OVER);
2,555,725✔
1384
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordGraceTime, _OVER);
2,555,725✔
1385
  SDB_SET_INT32(pRaw, dataPos, pUser->inactiveAccountTime, _OVER);
2,555,725✔
1386
  SDB_SET_INT32(pRaw, dataPos, pUser->allowTokenNum, _OVER);
2,555,725✔
1387
  SDB_SET_INT32(pRaw, dataPos, pUser->tokenNum, _OVER);
2,555,725✔
1388

1389
  SDB_SET_INT32(pRaw, dataPos, pUser->pTimeWhiteList->num, _OVER);
2,555,725✔
1390
  for (int32_t i = 0; i < pUser->pTimeWhiteList->num; i++) {
2,555,725✔
1391
    SDateTimeWhiteListItem *range = &pUser->pTimeWhiteList->ranges[i];
×
1392
    SDB_SET_BOOL(pRaw, dataPos, range->absolute, _OVER);
×
1393
    SDB_SET_BOOL(pRaw, dataPos, range->neg, _OVER);
×
1394
    SDB_SET_INT64(pRaw, dataPos, range->start, _OVER);
×
1395
    SDB_SET_INT32(pRaw, dataPos, range->duration, _OVER);
×
1396
  }
1397

1398
  SDB_SET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
2,555,725✔
1399
  SDB_SET_DATALEN(pRaw, dataPos, _OVER)
2,555,725✔
1400

1401
_OVER:
2,555,725✔
1402
  taosMemoryFree(buf);
2,555,725✔
1403
  if (code < 0) {
2,555,725✔
1404
    mError("user:%s, failed to encode user action to raw:%p at line %d since %s", pUser->user, pRaw, lino,
×
1405
           tstrerror(code));
1406
    sdbFreeRaw(pRaw);
×
1407
    pRaw = NULL;
×
1408
    terrno = code;
×
1409
  }
1410

1411
  mTrace("user:%s, encode user action to raw:%p, row:%p", pUser->user, pRaw, pUser);
2,555,725✔
1412
  return pRaw;
2,555,725✔
1413
}
1414

1415
static SSdbRow *mndUserActionDecode(SSdbRaw *pRaw) {
1,666,770✔
1416
  int32_t   code = 0;
1,666,770✔
1417
  int32_t   lino = 0;
1,666,770✔
1418
  SSdbRow  *pRow = NULL;
1,666,770✔
1419
  SUserObj *pUser = NULL;
1,666,770✔
1420
  char     *key = NULL;
1,666,770✔
1421
  char     *value = NULL;
1,666,770✔
1422

1423
  int8_t sver = 0;
1,666,770✔
1424
  if (sdbGetRawSoftVer(pRaw, &sver) != 0) {
1,666,770✔
1425
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_PTR, &lino, _OVER);
×
1426
  }
1427

1428
  if (sver < 1 || sver > USER_VER_NUMBER) {
1,666,770✔
1429
    TAOS_CHECK_GOTO(TSDB_CODE_SDB_INVALID_DATA_VER, &lino, _OVER);
×
1430
  }
1431

1432
  pRow = sdbAllocRow(sizeof(SUserObj));
1,666,770✔
1433
  if (pRow == NULL) {
1,666,770✔
1434
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1435
  }
1436

1437
  pUser = sdbGetRowObj(pRow);
1,666,770✔
1438
  if (pUser == NULL) {
1,666,770✔
1439
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1440
  }
1441

1442
  int32_t dataPos = 0;
1,666,770✔
1443
  SDB_GET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN, _OVER)
1,666,770✔
1444

1445
  if (sver < USER_VER_SUPPORT_ADVANCED_SECURITY) {
1,666,770✔
1446
    pUser->passwords = taosMemoryCalloc(1, sizeof(SUserPassword));
×
1447
    if (pUser->passwords == NULL) {
×
1448
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
1449
    }
1450
    SDB_GET_BINARY(pRaw, dataPos, pUser->passwords[0].pass, TSDB_PASSWORD_LEN, _OVER)
×
1451
    pUser->numOfPasswords = 1;
×
1452
    memset(pUser->salt, 0, sizeof(pUser->salt));
×
1453
  } else {
1454
    SDB_GET_INT32(pRaw, dataPos, &pUser->numOfPasswords, _OVER)
1,666,770✔
1455
    pUser->passwords = taosMemoryCalloc(pUser->numOfPasswords, sizeof(SUserPassword));
1,666,770✔
1456
    if (pUser->passwords == NULL) {
1,666,770✔
1457
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
1458
    }
1459
    for (int32_t i = 0; i < pUser->numOfPasswords; ++i) {
3,385,483✔
1460
      SDB_GET_BINARY(pRaw, dataPos, pUser->passwords[i].pass, sizeof(pUser->passwords[i].pass), _OVER);
1,718,713✔
1461
      SDB_GET_INT32(pRaw, dataPos, &pUser->passwords[i].setTime, _OVER);
1,718,713✔
1462
    }
1463
    SDB_GET_BINARY(pRaw, dataPos, pUser->salt, sizeof(pUser->salt), _OVER)
1,666,770✔
1464
  }
1465
  
1466
  SDB_GET_BINARY(pRaw, dataPos, pUser->acct, TSDB_USER_LEN, _OVER)
1,666,770✔
1467
  SDB_GET_INT64(pRaw, dataPos, &pUser->createdTime, _OVER)
1,666,770✔
1468
  SDB_GET_INT64(pRaw, dataPos, &pUser->updateTime, _OVER)
1,666,770✔
1469
  if (sver < USER_VER_SUPPORT_ADVANCED_SECURITY) {
1,666,770✔
1470
    pUser->passwords[0].setTime = (int32_t)(pUser->updateTime / 1000);
×
1471
  }
1472

1473
  SDB_GET_INT8(pRaw, dataPos, &pUser->superUser, _OVER)
1,666,770✔
1474
  SDB_GET_INT8(pRaw, dataPos, &pUser->sysInfo, _OVER)
1,666,770✔
1475
  SDB_GET_INT8(pRaw, dataPos, &pUser->enable, _OVER)
1,666,770✔
1476
  SDB_GET_UINT8(pRaw, dataPos, &pUser->flag, _OVER)
1,666,770✔
1477
  if (pUser->superUser) pUser->createdb = 1;
1,666,770✔
1478
  SDB_GET_INT32(pRaw, dataPos, &pUser->authVersion, _OVER)
1,666,770✔
1479
  if (sver >= 4) {
1,666,770✔
1480
    SDB_GET_INT32(pRaw, dataPos, &pUser->passVersion, _OVER)
1,666,770✔
1481
  }
1482

1483
  int32_t numOfReadDbs = 0;
1,666,770✔
1484
  int32_t numOfWriteDbs = 0;
1,666,770✔
1485
  int32_t numOfTopics = 0;
1,666,770✔
1486
  SDB_GET_INT32(pRaw, dataPos, &numOfReadDbs, _OVER)
1,666,770✔
1487
  SDB_GET_INT32(pRaw, dataPos, &numOfWriteDbs, _OVER)
1,666,770✔
1488
  if (sver >= 2) {
1,666,770✔
1489
    SDB_GET_INT32(pRaw, dataPos, &numOfTopics, _OVER)
1,666,770✔
1490
  }
1491

1492
  pUser->readDbs = taosHashInit(numOfReadDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,666,770✔
1493
  pUser->writeDbs =
1,666,770✔
1494
      taosHashInit(numOfWriteDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,666,770✔
1495
  pUser->topics = taosHashInit(numOfTopics, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,666,770✔
1496
  if (pUser->readDbs == NULL || pUser->writeDbs == NULL || pUser->topics == NULL) {
1,666,770✔
1497
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1498
    goto _OVER;
×
1499
  }
1500

1501
  for (int32_t i = 0; i < numOfReadDbs; ++i) {
1,995,033✔
1502
    char db[TSDB_DB_FNAME_LEN] = {0};
328,263✔
1503
    SDB_GET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER)
328,263✔
1504
    int32_t len = strlen(db) + 1;
328,263✔
1505
    TAOS_CHECK_GOTO(taosHashPut(pUser->readDbs, db, len, db, TSDB_DB_FNAME_LEN), &lino, _OVER);
328,263✔
1506
  }
1507

1508
  for (int32_t i = 0; i < numOfWriteDbs; ++i) {
1,988,212✔
1509
    char db[TSDB_DB_FNAME_LEN] = {0};
321,442✔
1510
    SDB_GET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER)
321,442✔
1511
    int32_t len = strlen(db) + 1;
321,442✔
1512
    TAOS_CHECK_GOTO(taosHashPut(pUser->writeDbs, db, len, db, TSDB_DB_FNAME_LEN), &lino, _OVER);
321,442✔
1513
  }
1514

1515
  if (sver >= 2) {
1,666,770✔
1516
    for (int32_t i = 0; i < numOfTopics; ++i) {
1,682,379✔
1517
      char topic[TSDB_TOPIC_FNAME_LEN] = {0};
15,609✔
1518
      SDB_GET_BINARY(pRaw, dataPos, topic, TSDB_TOPIC_FNAME_LEN, _OVER)
15,609✔
1519
      int32_t len = strlen(topic) + 1;
15,609✔
1520
      TAOS_CHECK_GOTO(taosHashPut(pUser->topics, topic, len, topic, TSDB_TOPIC_FNAME_LEN), &lino, _OVER);
15,609✔
1521
    }
1522
  }
1523

1524
  if (sver >= 3) {
1,666,770✔
1525
    int32_t numOfReadTbs = 0;
1,666,770✔
1526
    int32_t numOfWriteTbs = 0;
1,666,770✔
1527
    int32_t numOfAlterTbs = 0;
1,666,770✔
1528
    int32_t numOfReadViews = 0;
1,666,770✔
1529
    int32_t numOfWriteViews = 0;
1,666,770✔
1530
    int32_t numOfAlterViews = 0;
1,666,770✔
1531
    int32_t numOfUseDbs = 0;
1,666,770✔
1532
    SDB_GET_INT32(pRaw, dataPos, &numOfReadTbs, _OVER)
1,666,770✔
1533
    SDB_GET_INT32(pRaw, dataPos, &numOfWriteTbs, _OVER)
1,666,770✔
1534
    if (sver >= 6) {
1,666,770✔
1535
      SDB_GET_INT32(pRaw, dataPos, &numOfAlterTbs, _OVER)
1,666,770✔
1536
      SDB_GET_INT32(pRaw, dataPos, &numOfReadViews, _OVER)
1,666,770✔
1537
      SDB_GET_INT32(pRaw, dataPos, &numOfWriteViews, _OVER)
1,666,770✔
1538
      SDB_GET_INT32(pRaw, dataPos, &numOfAlterViews, _OVER)
1,666,770✔
1539
    }
1540
    SDB_GET_INT32(pRaw, dataPos, &numOfUseDbs, _OVER)
1,666,770✔
1541

1542
    pUser->readTbs =
1,666,770✔
1543
        taosHashInit(numOfReadTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,666,770✔
1544
    pUser->writeTbs =
1,666,770✔
1545
        taosHashInit(numOfWriteTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,666,770✔
1546
    pUser->alterTbs =
1,666,770✔
1547
        taosHashInit(numOfAlterTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,666,770✔
1548

1549
    pUser->readViews =
1,666,770✔
1550
        taosHashInit(numOfReadViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,666,770✔
1551
    pUser->writeViews =
1,666,770✔
1552
        taosHashInit(numOfWriteViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,666,770✔
1553
    pUser->alterViews =
1,666,770✔
1554
        taosHashInit(numOfAlterViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,666,770✔
1555

1556
    pUser->useDbs = taosHashInit(numOfUseDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,666,770✔
1557

1558
    if (pUser->readTbs == NULL || pUser->writeTbs == NULL || pUser->alterTbs == NULL || pUser->readViews == NULL ||
1,666,770✔
1559
        pUser->writeViews == NULL || pUser->alterViews == NULL || pUser->useDbs == NULL) {
1,666,770✔
1560
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1561
      goto _OVER;
×
1562
    }
1563

1564
    for (int32_t i = 0; i < numOfReadTbs; ++i) {
2,093,993✔
1565
      int32_t keyLen = 0;
427,223✔
1566
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
427,223✔
1567

1568
      TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
427,223✔
1569
      if (key == NULL) {
427,223✔
1570
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1571
      }
1572
      (void)memset(key, 0, keyLen);
427,223✔
1573
      SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
427,223✔
1574

1575
      int32_t valuelen = 0;
427,223✔
1576
      SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
427,223✔
1577
      TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
427,223✔
1578
      if (value == NULL) {
427,223✔
1579
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1580
      }
1581
      (void)memset(value, 0, valuelen);
427,223✔
1582
      SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
427,223✔
1583

1584
      TAOS_CHECK_GOTO(taosHashPut(pUser->readTbs, key, keyLen, value, valuelen), &lino, _OVER);
427,223✔
1585
    }
1586

1587
    for (int32_t i = 0; i < numOfWriteTbs; ++i) {
2,101,457✔
1588
      int32_t keyLen = 0;
434,687✔
1589
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
434,687✔
1590

1591
      TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
434,687✔
1592
      if (key == NULL) {
434,687✔
1593
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1594
      }
1595
      (void)memset(key, 0, keyLen);
434,687✔
1596
      SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
434,687✔
1597

1598
      int32_t valuelen = 0;
434,687✔
1599
      SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
434,687✔
1600
      TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
434,687✔
1601
      if (value == NULL) {
434,687✔
1602
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1603
      }
1604
      (void)memset(value, 0, valuelen);
434,687✔
1605
      SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
434,687✔
1606

1607
      TAOS_CHECK_GOTO(taosHashPut(pUser->writeTbs, key, keyLen, value, valuelen), &lino, _OVER);
434,687✔
1608
    }
1609

1610
    if (sver >= 6) {
1,666,770✔
1611
      for (int32_t i = 0; i < numOfAlterTbs; ++i) {
1,894,278✔
1612
        int32_t keyLen = 0;
227,508✔
1613
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
227,508✔
1614

1615
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
227,508✔
1616
        if (key == NULL) {
227,508✔
1617
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1618
        }
1619
        (void)memset(key, 0, keyLen);
227,508✔
1620
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
227,508✔
1621

1622
        int32_t valuelen = 0;
227,508✔
1623
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
227,508✔
1624
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
227,508✔
1625
        if (value == NULL) {
227,508✔
1626
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1627
        }
1628
        (void)memset(value, 0, valuelen);
227,508✔
1629
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
227,508✔
1630

1631
        TAOS_CHECK_GOTO(taosHashPut(pUser->alterTbs, key, keyLen, value, valuelen), &lino, _OVER);
227,508✔
1632
      }
1633

1634
      for (int32_t i = 0; i < numOfReadViews; ++i) {
1,715,067✔
1635
        int32_t keyLen = 0;
48,297✔
1636
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
48,297✔
1637

1638
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
48,297✔
1639
        if (key == NULL) {
48,297✔
1640
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1641
        }
1642
        (void)memset(key, 0, keyLen);
48,297✔
1643
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
48,297✔
1644

1645
        int32_t valuelen = 0;
48,297✔
1646
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
48,297✔
1647
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
48,297✔
1648
        if (value == NULL) {
48,297✔
1649
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1650
        }
1651
        (void)memset(value, 0, valuelen);
48,297✔
1652
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
48,297✔
1653

1654
        TAOS_CHECK_GOTO(taosHashPut(pUser->readViews, key, keyLen, value, valuelen), &lino, _OVER);
48,297✔
1655
      }
1656

1657
      for (int32_t i = 0; i < numOfWriteViews; ++i) {
1,703,691✔
1658
        int32_t keyLen = 0;
36,921✔
1659
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
36,921✔
1660

1661
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
36,921✔
1662
        if (key == NULL) {
36,921✔
1663
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1664
        }
1665
        (void)memset(key, 0, keyLen);
36,921✔
1666
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
36,921✔
1667

1668
        int32_t valuelen = 0;
36,921✔
1669
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
36,921✔
1670
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
36,921✔
1671
        if (value == NULL) {
36,921✔
1672
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1673
        }
1674
        (void)memset(value, 0, valuelen);
36,921✔
1675
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
36,921✔
1676

1677
        TAOS_CHECK_GOTO(taosHashPut(pUser->writeViews, key, keyLen, value, valuelen), &lino, _OVER);
36,921✔
1678
      }
1679

1680
      for (int32_t i = 0; i < numOfAlterViews; ++i) {
1,703,061✔
1681
        int32_t keyLen = 0;
36,291✔
1682
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
36,291✔
1683

1684
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
36,291✔
1685
        if (key == NULL) {
36,291✔
1686
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1687
        }
1688
        (void)memset(key, 0, keyLen);
36,291✔
1689
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
36,291✔
1690

1691
        int32_t valuelen = 0;
36,291✔
1692
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
36,291✔
1693
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
36,291✔
1694
        if (value == NULL) {
36,291✔
1695
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1696
        }
1697
        (void)memset(value, 0, valuelen);
36,291✔
1698
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
36,291✔
1699

1700
        TAOS_CHECK_GOTO(taosHashPut(pUser->alterViews, key, keyLen, value, valuelen), &lino, _OVER);
36,291✔
1701
      }
1702
    }
1703

1704
    for (int32_t i = 0; i < numOfUseDbs; ++i) {
2,199,643✔
1705
      int32_t keyLen = 0;
532,873✔
1706
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
532,873✔
1707

1708
      TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
532,873✔
1709
      if (key == NULL) {
532,873✔
1710
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1711
      }
1712
      (void)memset(key, 0, keyLen);
532,873✔
1713
      SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
532,873✔
1714

1715
      int32_t ref = 0;
532,873✔
1716
      SDB_GET_INT32(pRaw, dataPos, &ref, _OVER);
532,873✔
1717

1718
      TAOS_CHECK_GOTO(taosHashPut(pUser->useDbs, key, keyLen, &ref, sizeof(ref)), &lino, _OVER);
532,873✔
1719
    }
1720
  }
1721
  // decoder white list
1722
  if (sver >= USER_VER_SUPPORT_WHITELIST) {
1,666,770✔
1723
    if (sver < USER_VER_SUPPORT_WHITELIT_DUAL_STACK) {
1,666,770✔
1724
      int32_t len = 0;
×
1725
      SDB_GET_INT32(pRaw, dataPos, &len, _OVER);
×
1726

1727
      TAOS_MEMORY_REALLOC(key, len);
×
1728
      if (key == NULL) {
×
1729
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1730
      }
1731
      SDB_GET_BINARY(pRaw, dataPos, key, len, _OVER);
×
1732

1733
      SIpWhiteList *pIpWhiteList = NULL;
×
1734
      TAOS_CHECK_GOTO(createIpWhiteListFromOldVer(key, len, &pIpWhiteList), &lino, _OVER);
×
1735

1736
      SDB_GET_INT64(pRaw, dataPos, &pUser->ipWhiteListVer, _OVER);
×
1737

1738
      code = cvtIpWhiteListToDual(pIpWhiteList, &pUser->pIpWhiteListDual);
×
1739
      if (code != 0) {
×
1740
        taosMemoryFreeClear(pIpWhiteList);
×
1741
      }
1742
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
1743

1744
      taosMemoryFreeClear(pIpWhiteList);
×
1745

1746
    } else if (sver >= USER_VER_SUPPORT_WHITELIT_DUAL_STACK) {
1,666,770✔
1747
      int32_t len = 0;
1,666,770✔
1748
      SDB_GET_INT32(pRaw, dataPos, &len, _OVER);
1,666,770✔
1749

1750
      TAOS_MEMORY_REALLOC(key, len);
1,666,770✔
1751
      if (key == NULL) {
1,666,770✔
1752
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1753
      }
1754
      SDB_GET_BINARY(pRaw, dataPos, key, len, _OVER);
1,666,770✔
1755

1756
      TAOS_CHECK_GOTO(createIpWhiteList(key, len, &pUser->pIpWhiteListDual, sver >= USER_VER_SUPPORT_ADVANCED_SECURITY), &lino, _OVER);
1,666,770✔
1757
      SDB_GET_INT64(pRaw, dataPos, &pUser->ipWhiteListVer, _OVER);
1,666,770✔
1758
    }
1759
  }
1760

1761
  if (pUser->pIpWhiteListDual == NULL) {
1,666,770✔
1762
    TAOS_CHECK_GOTO(createDefaultIpWhiteList(&pUser->pIpWhiteListDual), &lino, _OVER);
×
1763
    pUser->ipWhiteListVer = taosGetTimestampMs();
×
1764
  }
1765

1766
  SDB_GET_INT8(pRaw, dataPos, &pUser->passEncryptAlgorithm, _OVER);
1,666,770✔
1767

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

1805
    int32_t num = 0;
1,666,770✔
1806
    SDB_GET_INT32(pRaw, dataPos, &num, _OVER);
1,666,770✔
1807
    pUser->pTimeWhiteList = taosMemCalloc(1, sizeof(SDateTimeWhiteList) + num * sizeof(SDateTimeWhiteListItem));
1,666,770✔
1808
    if (pUser->pTimeWhiteList == NULL) {
1,666,770✔
1809
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1810
    }
1811

1812
    pUser->pTimeWhiteList->num = num;
1,666,770✔
1813
    for (int32_t i = 0; i < num; i++) {
1,666,770✔
1814
      SDateTimeWhiteListItem *range = &pUser->pTimeWhiteList->ranges[i];
×
1815
      SDB_GET_BOOL(pRaw, dataPos, &range->absolute, _OVER);
×
1816
      SDB_GET_BOOL(pRaw, dataPos, &range->neg, _OVER);
×
1817
      SDB_GET_INT64(pRaw, dataPos, &range->start, _OVER);
×
1818
      SDB_GET_INT32(pRaw, dataPos, &range->duration, _OVER);
×
1819
    }
1820
  }
1821

1822
  SDB_GET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
1,666,770✔
1823
  taosInitRWLatch(&pUser->lock);
1,666,770✔
1824
  dropOldPasswords(pUser);
1,666,770✔
1825

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

1851
  mTrace("user:%s, decode from raw:%p, row:%p", pUser->user, pRaw, pUser);
1,666,770✔
1852
  return pRow;
1,666,770✔
1853
}
1854

1855
static int32_t mndUserActionInsert(SSdb *pSdb, SUserObj *pUser) {
633,088✔
1856
  mTrace("user:%s, perform insert action, row:%p", pUser->user, pUser);
633,088✔
1857

1858
  SAcctObj *pAcct = sdbAcquire(pSdb, SDB_ACCT, pUser->acct);
633,088✔
1859
  if (pAcct == NULL) {
633,088✔
1860
    terrno = TSDB_CODE_MND_ACCT_NOT_EXIST;
×
1861
    mError("user:%s, failed to perform insert action since %s", pUser->user, terrstr());
×
1862
    TAOS_RETURN(terrno);
×
1863
  }
1864
  pUser->acctId = pAcct->acctId;
633,088✔
1865
  sdbRelease(pSdb, pAcct);
633,088✔
1866

1867
  return 0;
633,088✔
1868
}
1869

1870
int32_t mndDupTableHash(SHashObj *pOld, SHashObj **ppNew) {
38,705,293✔
1871
  int32_t code = 0;
38,705,293✔
1872
  *ppNew =
38,705,293✔
1873
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
38,705,293✔
1874
  if (*ppNew == NULL) {
38,705,293✔
1875
    TAOS_RETURN(terrno);
×
1876
  }
1877

1878
  char *tb = taosHashIterate(pOld, NULL);
38,705,293✔
1879
  while (tb != NULL) {
41,125,721✔
1880
    size_t keyLen = 0;
2,420,428✔
1881
    char  *key = taosHashGetKey(tb, &keyLen);
2,420,428✔
1882

1883
    int32_t valueLen = strlen(tb) + 1;
2,420,428✔
1884
    if ((code = taosHashPut(*ppNew, key, keyLen, tb, valueLen)) != 0) {
2,420,428✔
1885
      taosHashCancelIterate(pOld, tb);
×
1886
      taosHashCleanup(*ppNew);
×
1887
      TAOS_RETURN(code);
×
1888
    }
1889
    tb = taosHashIterate(pOld, tb);
2,420,428✔
1890
  }
1891

1892
  TAOS_RETURN(code);
38,705,293✔
1893
}
1894

1895
int32_t mndDupUseDbHash(SHashObj *pOld, SHashObj **ppNew) {
1,703,656✔
1896
  int32_t code = 0;
1,703,656✔
1897
  *ppNew =
1,703,656✔
1898
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,703,656✔
1899
  if (*ppNew == NULL) {
1,703,656✔
1900
    TAOS_RETURN(terrno);
×
1901
  }
1902

1903
  int32_t *db = taosHashIterate(pOld, NULL);
1,703,656✔
1904
  while (db != NULL) {
2,215,756✔
1905
    size_t keyLen = 0;
512,100✔
1906
    char  *key = taosHashGetKey(db, &keyLen);
512,100✔
1907

1908
    if ((code = taosHashPut(*ppNew, key, keyLen, db, sizeof(*db))) != 0) {
512,100✔
1909
      taosHashCancelIterate(pOld, db);
×
1910
      taosHashCleanup(*ppNew);
×
1911
      TAOS_RETURN(code);
×
1912
    }
1913
    db = taosHashIterate(pOld, db);
512,100✔
1914
  }
1915

1916
  TAOS_RETURN(code);
1,703,656✔
1917
}
1918

1919
int32_t mndUserDupObj(SUserObj *pUser, SUserObj *pNew) {
1,703,656✔
1920
  int32_t code = 0;
1,703,656✔
1921
  (void)memcpy(pNew, pUser, sizeof(SUserObj));
1,703,656✔
1922
  pNew->authVersion++;
1,703,656✔
1923
  pNew->updateTime = taosGetTimestampMs();
1,703,656✔
1924
  taosInitRWLatch(&pNew->lock);
1,703,656✔
1925

1926
  pNew->passwords = NULL;
1,703,656✔
1927
  pNew->readDbs = NULL;
1,703,656✔
1928
  pNew->writeDbs = NULL;
1,703,656✔
1929
  pNew->readTbs = NULL;
1,703,656✔
1930
  pNew->writeTbs = NULL;
1,703,656✔
1931
  pNew->alterTbs = NULL;
1,703,656✔
1932
  pNew->readViews = NULL;
1,703,656✔
1933
  pNew->writeViews = NULL;
1,703,656✔
1934
  pNew->alterViews = NULL;
1,703,656✔
1935
  pNew->topics = NULL;
1,703,656✔
1936
  pNew->useDbs = NULL;
1,703,656✔
1937
  pNew->pIpWhiteListDual = NULL;
1,703,656✔
1938
  pNew->pTimeWhiteList = NULL;
1,703,656✔
1939

1940
  taosRLockLatch(&pUser->lock);
1,703,656✔
1941
  pNew->passwords = taosMemoryCalloc(pUser->numOfPasswords, sizeof(SUserPassword));
1,703,656✔
1942
  if (pNew->passwords == NULL) {
1,703,656✔
1943
    code = TSDB_CODE_OUT_OF_MEMORY;
×
1944
    goto _OVER;
×
1945
  }
1946
  (void)memcpy(pNew->passwords, pUser->passwords, pUser->numOfPasswords * sizeof(SUserPassword));
1,703,656✔
1947

1948
  TAOS_CHECK_GOTO(mndDupDbHash(pUser->readDbs, &pNew->readDbs), NULL, _OVER);
1,703,656✔
1949
  TAOS_CHECK_GOTO(mndDupDbHash(pUser->writeDbs, &pNew->writeDbs), NULL, _OVER);
1,703,656✔
1950
  TAOS_CHECK_GOTO(mndDupTableHash(pUser->readTbs, &pNew->readTbs), NULL, _OVER);
1,703,656✔
1951
  TAOS_CHECK_GOTO(mndDupTableHash(pUser->writeTbs, &pNew->writeTbs), NULL, _OVER);
1,703,656✔
1952
  TAOS_CHECK_GOTO(mndDupTableHash(pUser->alterTbs, &pNew->alterTbs), NULL, _OVER);
1,703,656✔
1953
  TAOS_CHECK_GOTO(mndDupTableHash(pUser->readViews, &pNew->readViews), NULL, _OVER);
1,703,656✔
1954
  TAOS_CHECK_GOTO(mndDupTableHash(pUser->writeViews, &pNew->writeViews), NULL, _OVER);
1,703,656✔
1955
  TAOS_CHECK_GOTO(mndDupTableHash(pUser->alterViews, &pNew->alterViews), NULL, _OVER);
1,703,656✔
1956
  TAOS_CHECK_GOTO(mndDupTopicHash(pUser->topics, &pNew->topics), NULL, _OVER);
1,703,656✔
1957
  TAOS_CHECK_GOTO(mndDupUseDbHash(pUser->useDbs, &pNew->useDbs), NULL, _OVER);
1,703,656✔
1958
  pNew->pIpWhiteListDual = cloneIpWhiteList(pUser->pIpWhiteListDual);
1,703,656✔
1959
  if (pNew->pIpWhiteListDual == NULL) {
1,703,656✔
1960
    code = TSDB_CODE_OUT_OF_MEMORY;
×
1961
    goto _OVER;
×
1962
  }
1963

1964
  pNew->pTimeWhiteList = cloneDateTimeWhiteList(pUser->pTimeWhiteList);
1,703,656✔
1965
  if (pNew->pTimeWhiteList == NULL) {
1,703,656✔
1966
    code = TSDB_CODE_OUT_OF_MEMORY;
×
1967
    goto _OVER;
×
1968
  }
1969

1970
_OVER:
1,703,656✔
1971
  taosRUnLockLatch(&pUser->lock);
1,703,656✔
1972
  TAOS_RETURN(code);
1,703,656✔
1973
}
1974

1975
void mndUserFreeObj(SUserObj *pUser) {
6,265,736✔
1976
  taosHashCleanup(pUser->readDbs);
6,265,736✔
1977
  taosHashCleanup(pUser->writeDbs);
6,265,736✔
1978
  taosHashCleanup(pUser->topics);
6,265,736✔
1979
  taosHashCleanup(pUser->readTbs);
6,265,736✔
1980
  taosHashCleanup(pUser->writeTbs);
6,265,736✔
1981
  taosHashCleanup(pUser->alterTbs);
6,265,736✔
1982
  taosHashCleanup(pUser->readViews);
6,265,736✔
1983
  taosHashCleanup(pUser->writeViews);
6,265,736✔
1984
  taosHashCleanup(pUser->alterViews);
6,265,736✔
1985
  taosHashCleanup(pUser->useDbs);
6,265,736✔
1986
  taosMemoryFreeClear(pUser->passwords);
6,265,736✔
1987
  taosMemoryFreeClear(pUser->pIpWhiteListDual);
6,265,736✔
1988
  taosMemoryFreeClear(pUser->pTimeWhiteList);
6,265,736✔
1989
  pUser->readDbs = NULL;
6,265,736✔
1990
  pUser->writeDbs = NULL;
6,265,736✔
1991
  pUser->topics = NULL;
6,265,736✔
1992
  pUser->readTbs = NULL;
6,265,736✔
1993
  pUser->writeTbs = NULL;
6,265,736✔
1994
  pUser->alterTbs = NULL;
6,265,736✔
1995
  pUser->readViews = NULL;
6,265,736✔
1996
  pUser->writeViews = NULL;
6,265,736✔
1997
  pUser->alterViews = NULL;
6,265,736✔
1998
  pUser->useDbs = NULL;
6,265,736✔
1999
}
6,265,736✔
2000

2001
static int32_t mndUserActionDelete(SSdb *pSdb, SUserObj *pUser) {
1,666,685✔
2002
  mTrace("user:%s, perform delete action, row:%p", pUser->user, pUser);
1,666,685✔
2003
  mndUserFreeObj(pUser);
1,666,685✔
2004
  return 0;
1,666,685✔
2005
}
2006

2007
static int32_t mndUserActionUpdate(SSdb *pSdb, SUserObj *pOld, SUserObj *pNew) {
962,701✔
2008
  mTrace("user:%s, perform update action, old row:%p new row:%p", pOld->user, pOld, pNew);
962,701✔
2009
  taosWLockLatch(&pOld->lock);
962,701✔
2010
  pOld->updateTime = pNew->updateTime;
962,701✔
2011
  pOld->authVersion = pNew->authVersion;
962,701✔
2012
  pOld->passVersion = pNew->passVersion;
962,701✔
2013
  pOld->sysInfo = pNew->sysInfo;
962,701✔
2014
  pOld->enable = pNew->enable;
962,701✔
2015
  pOld->flag = pNew->flag;
962,701✔
2016
  pOld->changePass = pNew->changePass;
962,701✔
2017

2018
  pOld->sessionPerUser = pNew->sessionPerUser;
962,701✔
2019
  pOld->connectTime = pNew->connectTime;
962,701✔
2020
  pOld->connectIdleTime = pNew->connectIdleTime;
962,701✔
2021
  pOld->callPerSession = pNew->callPerSession;
962,701✔
2022
  pOld->vnodePerCall = pNew->vnodePerCall;
962,701✔
2023
  pOld->failedLoginAttempts = pNew->failedLoginAttempts;
962,701✔
2024
  pOld->passwordLifeTime = pNew->passwordLifeTime;
962,701✔
2025
  pOld->passwordReuseTime = pNew->passwordReuseTime;
962,701✔
2026
  pOld->passwordReuseMax = pNew->passwordReuseMax;
962,701✔
2027
  pOld->passwordLockTime = pNew->passwordLockTime;
962,701✔
2028
  pOld->passwordGraceTime = pNew->passwordGraceTime;
962,701✔
2029
  pOld->inactiveAccountTime = pNew->inactiveAccountTime;
962,701✔
2030
  pOld->allowTokenNum = pNew->allowTokenNum;
962,701✔
2031
  pOld->tokenNum = pNew->tokenNum;
962,701✔
2032

2033
  pOld->numOfPasswords = pNew->numOfPasswords;
962,701✔
2034
  TSWAP(pOld->passwords, pNew->passwords);
962,701✔
2035
  (void)memcpy(pOld->salt, pNew->salt, sizeof(pOld->salt));
962,701✔
2036
  (void)memcpy(pOld->totpsecret, pNew->totpsecret, sizeof(pOld->totpsecret));
962,701✔
2037
  TSWAP(pOld->readDbs, pNew->readDbs);
962,701✔
2038
  TSWAP(pOld->writeDbs, pNew->writeDbs);
962,701✔
2039
  TSWAP(pOld->topics, pNew->topics);
962,701✔
2040
  TSWAP(pOld->readTbs, pNew->readTbs);
962,701✔
2041
  TSWAP(pOld->writeTbs, pNew->writeTbs);
962,701✔
2042
  TSWAP(pOld->alterTbs, pNew->alterTbs);
962,701✔
2043
  TSWAP(pOld->readViews, pNew->readViews);
962,701✔
2044
  TSWAP(pOld->writeViews, pNew->writeViews);
962,701✔
2045
  TSWAP(pOld->alterViews, pNew->alterViews);
962,701✔
2046
  TSWAP(pOld->useDbs, pNew->useDbs);
962,701✔
2047

2048
  TSWAP(pOld->pIpWhiteListDual, pNew->pIpWhiteListDual);
962,701✔
2049
  pOld->ipWhiteListVer = pNew->ipWhiteListVer;
962,701✔
2050
  TSWAP(pOld->pTimeWhiteList, pNew->pTimeWhiteList);
962,701✔
2051
  pOld->timeWhiteListVer = pNew->timeWhiteListVer;
962,701✔
2052
  pOld->passEncryptAlgorithm = pNew->passEncryptAlgorithm;
962,701✔
2053

2054
  taosWUnLockLatch(&pOld->lock);
962,701✔
2055

2056
  return 0;
962,701✔
2057
}
2058

2059
int32_t mndAcquireUser(SMnode *pMnode, const char *userName, SUserObj **ppUser) {
86,165,399✔
2060
  int32_t code = 0;
86,165,399✔
2061
  SSdb   *pSdb = pMnode->pSdb;
86,165,399✔
2062

2063
  *ppUser = sdbAcquire(pSdb, SDB_USER, userName);
86,165,814✔
2064
  if (*ppUser == NULL) {
86,165,640✔
2065
    if (terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
118,007✔
2066
      code = TSDB_CODE_MND_USER_NOT_EXIST;
118,007✔
2067
    } else {
2068
      code = TSDB_CODE_MND_USER_NOT_AVAILABLE;
×
2069
    }
2070
  }
2071
  TAOS_RETURN(code);
86,165,797✔
2072
}
2073

2074
void mndReleaseUser(SMnode *pMnode, SUserObj *pUser) {
86,227,888✔
2075
  SSdb *pSdb = pMnode->pSdb;
86,227,888✔
2076
  sdbRelease(pSdb, pUser);
86,228,146✔
2077
}
86,230,666✔
2078

2079

2080

2081
int32_t mndEncryptPass(char *pass, const char* salt, int8_t *algo) {
114,932✔
2082
  int32_t code = 0;
114,932✔
2083
  if (tsiEncryptPassAlgorithm != DND_CA_SM4) {
114,932✔
2084
    return 0;
114,206✔
2085
  }
2086

2087
  if (strlen(tsEncryptKey) == 0) {
726✔
2088
    return TSDB_CODE_DNODE_INVALID_ENCRYPTKEY;
×
2089
  }
2090

2091
  if (salt[0] != 0) {
726✔
2092
    char passAndSalt[TSDB_PASSWORD_LEN - 1 + TSDB_PASSWORD_SALT_LEN];
726✔
2093
    (void)memcpy(passAndSalt, pass, TSDB_PASSWORD_LEN - 1);
726✔
2094
    (void)memcpy(passAndSalt + TSDB_PASSWORD_LEN - 1, salt, TSDB_PASSWORD_SALT_LEN);
726✔
2095
    taosEncryptPass_c((uint8_t *)passAndSalt, sizeof(passAndSalt), pass);
2096
  }
2097

2098
  unsigned char packetData[TSDB_PASSWORD_LEN] = {0};
726✔
2099
  SCryptOpts opts = {0};
726✔
2100
  opts.len = TSDB_PASSWORD_LEN;
726✔
2101
  opts.source = pass;
726✔
2102
  opts.result = packetData;
726✔
2103
  opts.unitLen = TSDB_PASSWORD_LEN;
726✔
2104
  tstrncpy(opts.key, tsEncryptKey, ENCRYPT_KEY_LEN + 1);
726✔
2105
  int newLen = Builtin_CBC_Encrypt(&opts);
726✔
2106
  if (newLen <= 0) return terrno;
726✔
2107

2108
  memcpy(pass, packetData, newLen);
726✔
2109
  if (algo != NULL) {
726✔
2110
    *algo = DND_CA_SM4;
363✔
2111
  }
2112

2113
  return 0;
726✔
2114
}
2115

2116

2117

2118
static void generateSalt(char *salt, size_t len) {
101,310✔
2119
  const char* set = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
101,310✔
2120
  int32_t     setLen = 62;
101,310✔
2121
  for (int32_t i = 0; i < len - 1; ++i) {
3,241,920✔
2122
    salt[i] = set[taosSafeRand() % setLen];
3,140,610✔
2123
  }
2124
  salt[len - 1] = 0;
101,310✔
2125
}
101,310✔
2126

2127

2128

2129
static int32_t addDefaultIpToTable(int8_t enableIpv6, SHashObj *pUniqueTab) {
1,083✔
2130
  int32_t code = 0;
1,083✔
2131
  int32_t lino = 0;
1,083✔
2132
  int32_t dummpy = 0;
1,083✔
2133

2134
  SIpRange ipv4 = {0}, ipv6 = {0};
1,083✔
2135
  code = createDefaultIp4Range(&ipv4);
1,083✔
2136
  TSDB_CHECK_CODE(code, lino, _error);
1,083✔
2137

2138
  code = taosHashPut(pUniqueTab, &ipv4, sizeof(ipv4), &dummpy, sizeof(dummpy));
1,083✔
2139
  TSDB_CHECK_CODE(code, lino, _error);
1,083✔
2140

2141
  if (enableIpv6) {
1,083✔
2142
    code = createDefaultIp6Range(&ipv6);
×
2143
    TSDB_CHECK_CODE(code, lino, _error);
×
2144

2145
    code = taosHashPut(pUniqueTab, &ipv6, sizeof(ipv6), &dummpy, sizeof(dummpy));
×
2146
    TSDB_CHECK_CODE(code, lino, _error);
×
2147
  }
2148
_error:
1,083✔
2149
  if (code != 0) {
1,083✔
2150
    mError("failed to add default ip range to table since %s", tstrerror(code));
×
2151
  }
2152
  return code;
1,083✔
2153
}
2154

2155
static int32_t mndCreateUser(SMnode *pMnode, char *acct, SCreateUserReq *pCreate, SRpcMsg *pReq) {
100,584✔
2156
  int32_t  code = 0;
100,584✔
2157
  int32_t  lino = 0;
100,584✔
2158
  SUserObj userObj = {0};
100,584✔
2159

2160
  userObj.passwords = taosMemoryCalloc(1, sizeof(SUserPassword));
100,584✔
2161
  if (userObj.passwords == NULL) {
100,584✔
2162
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2163
  }
2164
  userObj.numOfPasswords = 1;
100,584✔
2165

2166
  if (pCreate->isImport == 1) {
100,584✔
2167
    memset(userObj.salt, 0, sizeof(userObj.salt));
×
2168
    memcpy(userObj.passwords[0].pass, pCreate->pass, TSDB_PASSWORD_LEN);
×
2169
  } else {
2170
    generateSalt(userObj.salt, sizeof(userObj.salt));
100,584✔
2171
    taosEncryptPass_c((uint8_t *)pCreate->pass, strlen(pCreate->pass), userObj.passwords[0].pass);
100,584✔
2172
    userObj.passwords[0].pass[sizeof(userObj.passwords[0].pass) - 1] = 0;
100,584✔
2173
    TAOS_CHECK_GOTO(mndEncryptPass(userObj.passwords[0].pass, userObj.salt, &userObj.passEncryptAlgorithm), &lino, _OVER);
100,584✔
2174
  }
2175
  userObj.passwords[0].setTime = taosGetTimestampSec();
100,584✔
2176

2177
  tstrncpy(userObj.user, pCreate->user, TSDB_USER_LEN);
100,584✔
2178
  tstrncpy(userObj.acct, acct, TSDB_USER_LEN);
100,584✔
2179
  if (pCreate->totpseed[0] != 0) {
100,584✔
2180
    int len = taosGenerateTotpSecret(pCreate->totpseed, 0, userObj.totpsecret, sizeof(userObj.totpsecret));
×
2181
    if (len < 0) {
×
2182
      TAOS_CHECK_GOTO(TSDB_CODE_PAR_INVALID_OPTION_VALUE, &lino, _OVER);
×
2183
    }
2184
  }
2185

2186
  userObj.createdTime = taosGetTimestampMs();
100,584✔
2187
  userObj.updateTime = userObj.createdTime;
100,584✔
2188
  userObj.superUser = 0;  // pCreate->superUser;
100,584✔
2189
  userObj.sysInfo = pCreate->sysInfo;
100,584✔
2190
  userObj.enable = pCreate->enable;
100,584✔
2191
  userObj.createdb = pCreate->createDb;
100,584✔
2192

2193
  userObj.changePass = pCreate->changepass;
100,584✔
2194
  userObj.sessionPerUser = pCreate->sessionPerUser;
100,584✔
2195
  userObj.connectTime = pCreate->connectTime;
100,584✔
2196
  userObj.connectIdleTime = pCreate->connectIdleTime;
100,584✔
2197
  userObj.callPerSession = pCreate->callPerSession;
100,584✔
2198
  userObj.vnodePerCall = pCreate->vnodePerCall;
100,584✔
2199
  userObj.failedLoginAttempts = pCreate->failedLoginAttempts;
100,584✔
2200
  userObj.passwordLifeTime = pCreate->passwordLifeTime;
100,584✔
2201
  userObj.passwordReuseTime = pCreate->passwordReuseTime;
100,584✔
2202
  userObj.passwordReuseMax = pCreate->passwordReuseMax;
100,584✔
2203
  userObj.passwordLockTime = pCreate->passwordLockTime;
100,584✔
2204
  userObj.passwordGraceTime = pCreate->passwordGraceTime;
100,584✔
2205
  userObj.inactiveAccountTime = pCreate->inactiveAccountTime;
100,584✔
2206
  userObj.allowTokenNum = pCreate->allowTokenNum;
100,584✔
2207
  userObj.tokenNum = 0;
100,584✔
2208

2209
  if (pCreate->numIpRanges == 0) {
100,584✔
2210
    TAOS_CHECK_GOTO(createDefaultIpWhiteList(&userObj.pIpWhiteListDual), &lino, _OVER);
99,501✔
2211
  } else {
2212
    SHashObj *pUniqueTab = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
1,083✔
2213
    if (pUniqueTab == NULL) {
1,083✔
2214
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2215
    }
2216
    int32_t dummpy = 0;
1,083✔
2217
    
2218
    for (int i = 0; i < pCreate->numIpRanges; i++) {
2,886✔
2219
      SIpRange range = {0};
1,803✔
2220
      copyIpRange(&range, pCreate->pIpDualRanges + i);
1,803✔
2221
      if ((code = taosHashPut(pUniqueTab, &range, sizeof(range), &dummpy, sizeof(dummpy))) != 0) {
1,803✔
2222
        taosHashCleanup(pUniqueTab);
×
2223
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2224
      }
2225
    }
2226

2227
    code = addDefaultIpToTable(tsEnableIpv6, pUniqueTab);
1,083✔
2228
    if (code != 0) {
1,083✔
2229
      taosHashCleanup(pUniqueTab);
×
2230
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2231
    }
2232

2233
    if (taosHashGetSize(pUniqueTab) > MND_MAX_USER_IP_RANGE) {
1,083✔
2234
      taosHashCleanup(pUniqueTab);
×
2235
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_IP_RANGE, &lino, _OVER);
×
2236
    }
2237

2238
    int32_t           numOfRanges = taosHashGetSize(pUniqueTab);
1,083✔
2239
    SIpWhiteListDual *p = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + numOfRanges * sizeof(SIpRange));
1,083✔
2240
    if (p == NULL) {
1,083✔
2241
      taosHashCleanup(pUniqueTab);
×
2242
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2243
    }
2244

2245
    void   *pIter = taosHashIterate(pUniqueTab, NULL);
1,083✔
2246
    for (int32_t i = 0; i < numOfRanges; i++) {
3,246✔
2247
      size_t    len = 0;
2,163✔
2248
      SIpRange *key = taosHashGetKey(pIter, &len);
2,163✔
2249
      memcpy(&p->pIpRanges[i], key, sizeof(SIpRange));
2,163✔
2250
      pIter = taosHashIterate(pUniqueTab, pIter);
2,163✔
2251
    }
2252

2253
    taosHashCleanup(pUniqueTab);
1,083✔
2254
    p->num = numOfRanges;
1,083✔
2255
    sortIpWhiteList(p);
1,083✔
2256
    userObj.pIpWhiteListDual = p;
1,083✔
2257
  }
2258

2259
  if (pCreate->numTimeRanges == 0) {
100,584✔
2260
    userObj.pTimeWhiteList = (SDateTimeWhiteList*)taosMemoryCalloc(1, sizeof(SDateTimeWhiteList));
100,584✔
2261
    if (userObj.pTimeWhiteList == NULL) {
100,584✔
2262
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2263
    }
2264
  } else {
2265
    SHashObj *pUniqueTab = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
×
2266
    if (pUniqueTab == NULL) {
×
2267
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2268
    }
2269
    int32_t dummpy = 0;
×
2270
    
2271
    for (int i = 0; i < pCreate->numIpRanges; i++) {
×
2272
      SDateTimeRange* src = pCreate->pTimeRanges + i;
×
2273
      SDateTimeWhiteListItem range = {0};
×
2274
      DateTimeRangeToWhiteListItem(&range, src);
×
2275

2276
      // no need to add expired range
2277
      if (isDateTimeWhiteListItemExpired(&range)) {
×
2278
        continue;
×
2279
      }
2280

2281
      if ((code = taosHashPut(pUniqueTab, &range, sizeof(range), &dummpy, sizeof(dummpy))) != 0) {
×
2282
        taosHashCleanup(pUniqueTab);
×
2283
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2284
      }
2285
    }
2286

2287
    if (taosHashGetSize(pUniqueTab) > MND_MAX_USER_TIME_RANGE) {
×
2288
      taosHashCleanup(pUniqueTab);
×
2289
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_TIME_RANGE, &lino, _OVER);
×
2290
    }
2291

2292
    int32_t           numOfRanges = taosHashGetSize(pUniqueTab);
×
2293
    SDateTimeWhiteList *p = taosMemoryCalloc(1, sizeof(SDateTimeWhiteList) + numOfRanges * sizeof(SDateTimeWhiteListItem));
×
2294
    if (p == NULL) {
×
2295
      taosHashCleanup(pUniqueTab);
×
2296
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2297
    }
2298

2299
    void   *pIter = taosHashIterate(pUniqueTab, NULL);
×
2300
    for (int32_t i = 0; i < numOfRanges; i++) {
×
2301
      size_t    len = 0;
×
2302
      SDateTimeWhiteListItem *key = taosHashGetKey(pIter, &len);
×
2303
      memcpy(p->ranges + i, key, sizeof(SDateTimeWhiteListItem));
×
2304
      pIter = taosHashIterate(pUniqueTab, pIter);
×
2305
    }
2306

2307
    taosHashCleanup(pUniqueTab);
×
2308
    p->num = numOfRanges;
×
2309
    sortTimeWhiteList(p);
×
2310
    userObj.pTimeWhiteList = p;
×
2311
  }
2312

2313
  userObj.ipWhiteListVer = taosGetTimestampMs();
100,584✔
2314
  userObj.timeWhiteListVer = userObj.ipWhiteListVer;
100,584✔
2315

2316
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "create-user");
100,584✔
2317
  if (pTrans == NULL) {
100,584✔
2318
    mError("user:%s, failed to create since %s", pCreate->user, terrstr());
×
2319
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2320
  }
2321
  mInfo("trans:%d, used to create user:%s", pTrans->id, pCreate->user);
100,584✔
2322

2323
  SSdbRaw *pCommitRaw = mndUserActionEncode(&userObj);
100,584✔
2324
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
100,584✔
2325
    mError("trans:%d, failed to commit redo log since %s", pTrans->id, terrstr());
×
2326
    mndTransDrop(pTrans);
×
2327
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2328
  }
2329
  TAOS_CHECK_GOTO(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY), &lino, _OVER);
100,584✔
2330

2331
  if (mndTransPrepare(pMnode, pTrans) != 0) {
100,584✔
2332
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
2333
    mndTransDrop(pTrans);
×
2334
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2335
  }
2336

2337
  if ((code = userCacheUpdateWhiteList(pMnode, &userObj)) != 0) {
100,584✔
2338
    mndTransDrop(pTrans);
×
2339
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2340
  }
2341

2342
  mndTransDrop(pTrans);
100,584✔
2343

2344
_OVER:
100,584✔
2345
  taosMemoryFree(userObj.passwords);
100,584✔
2346
  taosMemoryFree(userObj.pIpWhiteListDual);
100,584✔
2347
  taosMemoryFree(userObj.pTimeWhiteList);
100,584✔
2348
  TAOS_RETURN(code);
100,584✔
2349
}
2350

2351

2352
static int32_t mndCheckPasswordFmt(const char *pwd) {
115,265✔
2353
  if (strcmp(pwd, "taosdata") == 0) {
115,265✔
2354
    return 0;
27,943✔
2355
  }
2356

2357
  if (tsEnableStrongPassword == 0) {
87,322✔
2358
    for (char c = *pwd; c != 0; c = *(++pwd)) {
99,462✔
2359
      if (c == ' ' || c == '\'' || c == '\"' || c == '`' || c == '\\') {
98,373✔
2360
        return TSDB_CODE_MND_INVALID_PASS_FORMAT;
×
2361
      }
2362
    }
2363
    return 0;
1,089✔
2364
  }
2365

2366
  int32_t len = strlen(pwd);
86,233✔
2367
  if (len < TSDB_PASSWORD_MIN_LEN) {
86,233✔
2368
    return TSDB_CODE_PAR_PASSWD_TOO_SHORT_OR_EMPTY;
×
2369
  }
2370

2371
  if (len > TSDB_PASSWORD_MAX_LEN) {
86,233✔
2372
    return TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG;
×
2373
  }
2374

2375
  if (taosIsComplexString(pwd)) {
86,233✔
2376
    return 0;
86,233✔
2377
  }
2378

2379
  return TSDB_CODE_MND_INVALID_PASS_FORMAT;
×
2380
}
2381

2382

2383

2384
static int32_t mndCheckTotpSeedFmt(const char *seed) {
×
2385
  int32_t len = strlen(seed);
×
2386
  if (len < TSDB_USER_TOTPSEED_MIN_LEN) {
×
2387
    return TSDB_CODE_PAR_OPTION_VALUE_TOO_SHORT;
×
2388
  }
2389

2390
  if (taosIsComplexString(seed)) {
×
2391
    return 0;
×
2392
  }
2393

2394
  return TSDB_CODE_PAR_INVALID_OPTION_VALUE;
×
2395
}
2396

2397

2398

2399
static int32_t mndProcessGetUserDateTimeWhiteListReq(SRpcMsg *pReq) {
×
2400
  SMnode              *pMnode = pReq->info.node;
×
2401
  int32_t              code = 0;
×
2402
  int32_t              lino = 0;
×
2403
  int32_t              contLen = 0;
×
2404
  void                *pRsp = NULL;
×
2405
  SUserObj            *pUser = NULL;
×
2406
  SGetUserWhiteListReq wlReq = {0};
×
2407
  SUserDateTimeWhiteList wlRsp = {0};
×
2408

2409
  if (tDeserializeSGetUserWhiteListReq(pReq->pCont, pReq->contLen, &wlReq) != 0) {
×
2410
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
2411
  }
2412
  mTrace("user: %s, start to get date time whitelist", wlReq.user);
×
2413

2414
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, wlReq.user, &pUser), &lino, _OVER);
×
2415
  TAOS_CHECK_GOTO(mndSetUserDateTimeWhiteListRsp(pMnode, pUser, &wlRsp), &lino, _OVER);
×
2416

2417
  contLen = tSerializeSUserDateTimeWhiteList(NULL, 0, &wlRsp);
×
2418
  if (contLen < 0) {
×
2419
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2420
  }
2421
  pRsp = rpcMallocCont(contLen);
×
2422
  if (pRsp == NULL) {
×
2423
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2424
  }
2425
  
2426
  contLen = tSerializeSUserDateTimeWhiteList(pRsp, contLen, &wlRsp);
×
2427
  if (contLen < 0) {
×
2428
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2429
  }
2430

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

2444
  TAOS_RETURN(code);
×
2445
  return 0;
2446
}
2447

2448

2449

2450
static int32_t buildRetrieveDateTimeWhiteListRsp(SRetrieveDateTimeWhiteListRsp *pRsp) {
1,800✔
2451
  (void)taosThreadRwlockRdlock(&userCache.rw);
1,800✔
2452
  
2453
  int32_t count = taosHashGetSize(userCache.users);
1,800✔
2454
  pRsp->pUsers = taosMemoryCalloc(count, sizeof(SUserDateTimeWhiteList));
1,800✔
2455
  if (pRsp->pUsers == NULL) {
1,800✔
2456
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
2457
    TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
2458
  }
2459

2460
  count = 0;
1,800✔
2461
  void   *pIter = taosHashIterate(userCache.users, NULL);
1,800✔
2462
  while (pIter) {
3,600✔
2463
    SDateTimeWhiteList *wl = (*(SCachedUserInfo **)pIter)->wlTime;
1,800✔
2464
    if (wl == NULL || wl->num <= 0) {
1,800✔
2465
      pIter = taosHashIterate(userCache.users, pIter);
1,800✔
2466
      continue;
1,800✔
2467
    }
2468

2469
    SUserDateTimeWhiteList *pUser = &pRsp->pUsers[count];
×
2470
    pUser->ver = userCache.verTime;
×
2471

2472
    size_t klen;
×
2473
    char  *key = taosHashGetKey(pIter, &klen);
×
2474
    (void)memcpy(pUser->user, key, klen);
×
2475

2476
    pUser->numWhiteLists = wl->num;
×
2477
    pUser->pWhiteLists = taosMemoryCalloc(wl->num, sizeof(SDateTimeWhiteListItem));
×
2478
    if (pUser->pWhiteLists == NULL) {
×
2479
      (void)taosThreadRwlockUnlock(&userCache.rw);
×
2480
      TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
2481
    }
2482

2483
    (void)memcpy(pUser->pWhiteLists, wl->ranges, wl->num * sizeof(SDateTimeWhiteListItem));
×
2484
    count++;
×
2485
    pIter = taosHashIterate(userCache.users, pIter);
×
2486
  }
2487

2488
  pRsp->numOfUser = count;
1,800✔
2489
  pRsp->ver = userCache.verTime;
1,800✔
2490
  (void)taosThreadRwlockUnlock(&userCache.rw);
1,800✔
2491
  TAOS_RETURN(0);
1,800✔
2492
}
2493

2494

2495

2496
static int32_t mndProcessRetrieveDateTimeWhiteListReq(SRpcMsg *pReq) {
1,800✔
2497
  int32_t        code = 0;
1,800✔
2498
  int32_t        lino = 0;
1,800✔
2499
  int32_t        len = 0;
1,800✔
2500
  void          *pRsp = NULL;
1,800✔
2501
  SRetrieveDateTimeWhiteListRsp wlRsp = {0};
1,800✔
2502

2503
  // impl later
2504
  SRetrieveWhiteListReq req = {0};
1,800✔
2505
  if (tDeserializeRetrieveWhiteListReq(pReq->pCont, pReq->contLen, &req) != 0) {
1,800✔
2506
    code = TSDB_CODE_INVALID_MSG;
×
2507
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2508
  }
2509

2510
  TAOS_CHECK_GOTO(buildRetrieveDateTimeWhiteListRsp(&wlRsp), &lino, _OVER);
1,800✔
2511

2512
  len = tSerializeSRetrieveDateTimeWhiteListRsp(NULL, 0, &wlRsp);
1,800✔
2513
  if (len < 0) {
1,800✔
2514
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
2515
  }
2516

2517
  pRsp = rpcMallocCont(len);
1,800✔
2518
  if (!pRsp) {
1,800✔
2519
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2520
  }
2521
  len = tSerializeSRetrieveDateTimeWhiteListRsp(pRsp, len, &wlRsp);
1,800✔
2522
  if (len < 0) {
1,800✔
2523
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
2524
  }
2525

2526
_OVER:
1,800✔
2527
  if (code < 0) {
1,800✔
2528
    mError("failed to process retrieve ip white request at line %d since %s", lino, tstrerror(code));
×
2529
    rpcFreeCont(pRsp);
×
2530
    pRsp = NULL;
×
2531
    len = 0;
×
2532
  }
2533
  pReq->code = code;
1,800✔
2534
  pReq->info.rsp = pRsp;
1,800✔
2535
  pReq->info.rspLen = len;
1,800✔
2536

2537
  tFreeSRetrieveDateTimeWhiteListRsp(&wlRsp);
1,800✔
2538
  TAOS_RETURN(code);
1,800✔
2539
}
2540

2541

2542

2543
static int32_t mndProcessCreateUserReq(SRpcMsg *pReq) {
101,280✔
2544
  SMnode        *pMnode = pReq->info.node;
101,280✔
2545
  int32_t        code = 0;
101,280✔
2546
  int32_t        lino = 0;
101,280✔
2547
  SUserObj      *pUser = NULL;
101,280✔
2548
  SUserObj      *pOperUser = NULL;
101,280✔
2549
  SCreateUserReq createReq = {0};
101,280✔
2550
  int64_t        tss = taosGetTimestampMs();
101,280✔
2551

2552
  if (tDeserializeSCreateUserReq(pReq->pCont, pReq->contLen, &createReq) != 0) {
101,280✔
2553
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
2554
  }
2555

2556
  mInfo("user:%s, start to create, createdb:%d, is_import:%d", createReq.user, createReq.createDb, createReq.isImport);
101,280✔
2557

2558
#ifndef TD_ENTERPRISE
2559
  if (createReq.isImport == 1) {
2560
    TAOS_CHECK_GOTO(TSDB_CODE_OPS_NOT_SUPPORT, &lino, _OVER);  // enterprise feature
2561
  }
2562
#endif
2563

2564
  if (createReq.isImport != 1) {
101,280✔
2565
    TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), MND_OPER_CREATE_USER), &lino, _OVER);
101,280✔
2566
  } else if (strcmp(RPC_MSG_USER(pReq), "root") != 0) {
×
2567
    mError("The operation is not permitted, user:%s", RPC_MSG_USER(pReq));
×
2568
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_RIGHTS, &lino, _OVER);
×
2569
  }
2570

2571
  if (createReq.user[0] == 0) {
101,280✔
2572
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
2573
  }
2574

2575
  if (createReq.isImport != 1) {
101,280✔
2576
    code = mndCheckPasswordFmt(createReq.pass);
101,280✔
2577
    TAOS_CHECK_GOTO(code, &lino, _OVER);
101,280✔
2578
  }
2579

2580
  if (createReq.totpseed[0] != 0) {
101,280✔
2581
    code = mndCheckTotpSeedFmt(createReq.totpseed);
×
2582
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2583
  }
2584

2585
  code = mndAcquireUser(pMnode, createReq.user, &pUser);
101,280✔
2586
  if (pUser != NULL) {
101,280✔
2587
    TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_ALREADY_EXIST, &lino, _OVER);
696✔
2588
  }
2589

2590
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, RPC_MSG_USER(pReq), &pOperUser), &lino, _OVER);
100,584✔
2591
  TAOS_CHECK_GOTO(grantCheck(TSDB_GRANT_USER), &lino, _OVER);
100,584✔
2592

2593
  code = mndCreateUser(pMnode, pOperUser->acct, &createReq, pReq);
100,584✔
2594
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
100,584✔
2595

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

2607
    int64_t tse = taosGetTimestampMs();
100,584✔
2608
    double  duration = (double)(tse - tss);
100,584✔
2609
    duration = duration / 1000;
100,584✔
2610
    auditRecord(pReq, pMnode->clusterId, operation, "", createReq.user, detail, strlen(detail), duration, 0);
100,584✔
2611
  }
2612

2613
_OVER:
101,280✔
2614
  if (code == TSDB_CODE_MND_USER_ALREADY_EXIST && createReq.ignoreExists) {
101,280✔
2615
    code = 0;
×
2616
  } else if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
101,280✔
2617
    mError("user:%s, failed to create at line %d since %s", createReq.user, lino, tstrerror(code));
696✔
2618
  }
2619

2620
  mndReleaseUser(pMnode, pUser);
101,280✔
2621
  mndReleaseUser(pMnode, pOperUser);
101,280✔
2622
  tFreeSCreateUserReq(&createReq);
101,280✔
2623

2624
  TAOS_RETURN(code);
101,280✔
2625
}
2626

2627

2628

2629
static int32_t mndProcessGetUserIpWhiteListReq(SRpcMsg *pReq) {
131,917✔
2630
  SMnode              *pMnode = pReq->info.node;
131,917✔
2631
  int32_t              code = 0;
131,917✔
2632
  int32_t              lino = 0;
131,917✔
2633
  int32_t              contLen = 0;
131,917✔
2634
  void                *pRsp = NULL;
131,917✔
2635
  SUserObj            *pUser = NULL;
131,917✔
2636
  SGetUserWhiteListReq wlReq = {0};
131,917✔
2637
  SGetUserIpWhiteListRsp wlRsp = {0};
131,917✔
2638

2639
  int32_t (*serialFn)(void *, int32_t, SGetUserIpWhiteListRsp *) = NULL;
131,917✔
2640
  int32_t (*setRspFn)(SMnode * pMnode, SUserObj * pUser, SGetUserIpWhiteListRsp * pRsp) = NULL;
131,917✔
2641

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

2654
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, wlReq.user, &pUser), &lino, _OVER);
131,917✔
2655
  TAOS_CHECK_GOTO(setRspFn(pMnode, pUser, &wlRsp), &lino, _OVER);
131,917✔
2656

2657
  contLen = serialFn(NULL, 0, &wlRsp);
131,917✔
2658
  if (contLen < 0) {
131,917✔
2659
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2660
  }
2661
  pRsp = rpcMallocCont(contLen);
131,917✔
2662
  if (pRsp == NULL) {
131,409✔
2663
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2664
  }
2665

2666
  contLen = serialFn(pRsp, contLen, &wlRsp);
131,409✔
2667
  if (contLen < 0) {
131,917✔
2668
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2669
  }
2670

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

2684
  TAOS_RETURN(code);
131,917✔
2685
}
2686

2687

2688

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

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

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

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

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

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

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

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

2733

2734

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

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

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

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

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

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

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

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

2787

2788

2789
static int32_t mndAlterUser(SMnode *pMnode, SUserObj *pNew, SRpcMsg *pReq) {
932,898✔
2790
  int32_t code = 0;
932,898✔
2791
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "alter-user");
932,898✔
2792
  if (pTrans == NULL) {
932,898✔
2793
    mError("user:%s, failed to alter since %s", pNew->user, terrstr());
×
2794
    TAOS_RETURN(terrno);
×
2795
  }
2796
  mInfo("trans:%d, used to alter user:%s", pTrans->id, pNew->user);
932,898✔
2797

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

2810
  if (mndTransPrepare(pMnode, pTrans) != 0) {
932,898✔
2811
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
2812
    mndTransDrop(pTrans);
×
2813
    TAOS_RETURN(terrno);
×
2814
  }
2815
  if ((code = userCacheUpdateWhiteList(pMnode, pNew)) != 0) {
932,898✔
2816
    mndTransDrop(pTrans);
×
2817
    TAOS_RETURN(code);
×
2818
  }
2819
  mndTransDrop(pTrans);
932,898✔
2820
  return 0;
932,898✔
2821
}
2822

2823
static int32_t mndDupObjHash(SHashObj *pOld, int32_t dataLen, SHashObj **ppNew) {
13,249,070✔
2824
  int32_t code = 0;
13,249,070✔
2825

2826
  *ppNew =
13,249,070✔
2827
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
13,249,070✔
2828
  if (*ppNew == NULL) {
13,249,070✔
2829
    code = terrno ? terrno : TSDB_CODE_OUT_OF_MEMORY;
×
2830
    TAOS_RETURN(code);
×
2831
  }
2832

2833
  char *db = taosHashIterate(pOld, NULL);
13,249,070✔
2834
  while (db != NULL) {
14,432,412✔
2835
    int32_t len = strlen(db) + 1;
1,183,342✔
2836
    if ((code = taosHashPut(*ppNew, db, len, db, dataLen)) != 0) {
1,183,342✔
2837
      taosHashCancelIterate(pOld, db);
×
2838
      taosHashCleanup(*ppNew);
×
2839
      TAOS_RETURN(code);
×
2840
    }
2841
    db = taosHashIterate(pOld, db);
1,183,342✔
2842
  }
2843

2844
  TAOS_RETURN(code);
13,249,070✔
2845
}
2846

2847
int32_t mndDupDbHash(SHashObj *pOld, SHashObj **ppNew) { return mndDupObjHash(pOld, TSDB_DB_FNAME_LEN, ppNew); }
11,545,414✔
2848

2849
int32_t mndDupTopicHash(SHashObj *pOld, SHashObj **ppNew) { return mndDupObjHash(pOld, TSDB_TOPIC_FNAME_LEN, ppNew); }
1,703,656✔
2850

2851
static int32_t mndTablePriviledge(SMnode *pMnode, SHashObj *hash, SHashObj *useDbHash, SAlterUserReq *alterReq,
450,571✔
2852
                                  SSdb *pSdb) {
2853
  void *pIter = NULL;
450,571✔
2854
  char  tbFName[TSDB_TABLE_FNAME_LEN] = {0};
450,571✔
2855

2856
  (void)snprintf(tbFName, sizeof(tbFName), "%s.%s", alterReq->objname, alterReq->tabName);
450,571✔
2857
  int32_t len = strlen(tbFName) + 1;
450,571✔
2858

2859
  if (alterReq->tagCond != NULL && alterReq->tagCondLen != 0) {
519,497✔
2860
    char *value = taosHashGet(hash, tbFName, len);
68,926✔
2861
    if (value != NULL) {
68,926✔
2862
      TAOS_RETURN(TSDB_CODE_MND_PRIVILEDGE_EXIST);
×
2863
    }
2864

2865
    int32_t condLen = alterReq->tagCondLen;
68,926✔
2866
    TAOS_CHECK_RETURN(taosHashPut(hash, tbFName, len, alterReq->tagCond, condLen));
68,926✔
2867
  } else {
2868
    TAOS_CHECK_RETURN(taosHashPut(hash, tbFName, len, alterReq->isView ? "v" : "t", 2));
381,645✔
2869
  }
2870

2871
  int32_t  dbKeyLen = strlen(alterReq->objname) + 1;
450,571✔
2872
  int32_t  ref = 1;
450,571✔
2873
  int32_t *currRef = taosHashGet(useDbHash, alterReq->objname, dbKeyLen);
450,571✔
2874
  if (NULL != currRef) {
450,571✔
2875
    ref = (*currRef) + 1;
261,444✔
2876
  }
2877
  TAOS_CHECK_RETURN(taosHashPut(useDbHash, alterReq->objname, dbKeyLen, &ref, sizeof(ref)));
450,571✔
2878

2879
  TAOS_RETURN(0);
450,571✔
2880
}
2881

2882
static int32_t mndRemoveTablePriviledge(SMnode *pMnode, SHashObj *hash, SHashObj *useDbHash, SAlterUserReq *alterReq,
413,580✔
2883
                                        SSdb *pSdb) {
2884
  void *pIter = NULL;
413,580✔
2885
  char  tbFName[TSDB_TABLE_FNAME_LEN] = {0};
413,580✔
2886
  (void)snprintf(tbFName, sizeof(tbFName), "%s.%s", alterReq->objname, alterReq->tabName);
413,580✔
2887
  int32_t len = strlen(tbFName) + 1;
413,580✔
2888

2889
  if (taosHashRemove(hash, tbFName, len) != 0) {
413,580✔
2890
    TAOS_RETURN(0);  // not found
1,350✔
2891
  }
2892

2893
  int32_t  dbKeyLen = strlen(alterReq->objname) + 1;
412,230✔
2894
  int32_t *currRef = taosHashGet(useDbHash, alterReq->objname, dbKeyLen);
412,230✔
2895
  if (NULL == currRef) {
412,230✔
2896
    return 0;
×
2897
  }
2898

2899
  if (1 == *currRef) {
412,230✔
2900
    if (taosHashRemove(useDbHash, alterReq->objname, dbKeyLen) != 0) {
175,890✔
2901
      TAOS_RETURN(0);  // not found
×
2902
    }
2903
    return 0;
175,890✔
2904
  }
2905
  int32_t ref = (*currRef) - 1;
236,340✔
2906
  TAOS_CHECK_RETURN(taosHashPut(useDbHash, alterReq->objname, dbKeyLen, &ref, sizeof(ref)));
236,340✔
2907

2908
  return 0;
236,340✔
2909
}
2910

2911

2912

2913
static int32_t mndProcessAlterUserPrivilegesReq(SRpcMsg* pReq, SAlterUserReq *pAlterReq) {
918,857✔
2914
  SMnode   *pMnode = pReq->info.node;
918,857✔
2915
  SSdb     *pSdb = pMnode->pSdb;
918,857✔
2916
  int32_t   code = 0, lino = 0;
918,857✔
2917
  SUserObj *pUser = NULL;
918,857✔
2918
  SUserObj  newUser = {0};
918,857✔
2919
  int64_t   tss = taosGetTimestampMs();
918,857✔
2920

2921
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, pAlterReq->user, &pUser), &lino, _OVER);
918,857✔
2922
  TAOS_CHECK_GOTO(mndCheckAlterUserPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser, pAlterReq), &lino, _OVER);
912,686✔
2923
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
898,151✔
2924

2925
  if (ALTER_USER_ADD_READ_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
898,151✔
2926
      ALTER_USER_ADD_ALL_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
768,735✔
2927
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
129,416✔
2928
      int32_t len = strlen(pAlterReq->objname) + 1;
125,891✔
2929
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
125,891✔
2930
      if (pDb == NULL) {
125,891✔
2931
        mndReleaseDb(pMnode, pDb);
2,811✔
2932
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
2,811✔
2933
      }
2934
      if ((code = taosHashPut(newUser.readDbs, pAlterReq->objname, len, pAlterReq->objname, TSDB_DB_FNAME_LEN)) !=
123,080✔
2935
          0) {
2936
        mndReleaseDb(pMnode, pDb);
×
2937
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2938
      }
2939
      mndReleaseDb(pMnode, pDb);
123,080✔
2940
    } else {
2941
      void   *pIter = NULL;
3,525✔
2942
      while (1) {
5,703✔
2943
        SDbObj *pDb = NULL;
9,228✔
2944
        pIter = sdbFetch(pSdb, SDB_DB, pIter, (void **)&pDb);
9,228✔
2945
        if (pIter == NULL) break;
9,228✔
2946
        int32_t len = strlen(pDb->name) + 1;
5,703✔
2947
        if ((code = taosHashPut(newUser.readDbs, pDb->name, len, pDb->name, TSDB_DB_FNAME_LEN)) != 0) {
5,703✔
2948
          sdbRelease(pSdb, pDb);
×
2949
          sdbCancelFetch(pSdb, pIter);
×
2950
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2951
        }
2952
        sdbRelease(pSdb, pDb);
5,703✔
2953
      }
2954
    }
2955
  }
2956

2957
  if (ALTER_USER_ADD_WRITE_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
895,340✔
2958
      ALTER_USER_ADD_ALL_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
770,216✔
2959
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
125,124✔
2960
      int32_t len = strlen(pAlterReq->objname) + 1;
121,947✔
2961
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
121,947✔
2962
      if (pDb == NULL) {
121,947✔
2963
        mndReleaseDb(pMnode, pDb);
363✔
2964
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
363✔
2965
      }
2966
      if ((code = taosHashPut(newUser.writeDbs, pAlterReq->objname, len, pAlterReq->objname, TSDB_DB_FNAME_LEN)) !=
121,584✔
2967
          0) {
2968
        mndReleaseDb(pMnode, pDb);
×
2969
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2970
      }
2971
      mndReleaseDb(pMnode, pDb);
121,584✔
2972
    } else {
2973
      void   *pIter = NULL;
3,177✔
2974
      while (1) {
5,355✔
2975
        SDbObj *pDb = NULL;
8,532✔
2976
        pIter = sdbFetch(pSdb, SDB_DB, pIter, (void **)&pDb);
8,532✔
2977
        if (pIter == NULL) break;
8,532✔
2978
        int32_t len = strlen(pDb->name) + 1;
5,355✔
2979
        if ((code = taosHashPut(newUser.writeDbs, pDb->name, len, pDb->name, TSDB_DB_FNAME_LEN)) != 0) {
5,355✔
2980
          sdbRelease(pSdb, pDb);
×
2981
          sdbCancelFetch(pSdb, pIter);
×
2982
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2983
        }
2984
        sdbRelease(pSdb, pDb);
5,355✔
2985
      }
2986
    }
2987
  }
2988

2989
  if (ALTER_USER_DEL_READ_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
894,977✔
2990
      ALTER_USER_DEL_ALL_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
779,184✔
2991
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
115,793✔
2992
      int32_t len = strlen(pAlterReq->objname) + 1;
112,268✔
2993
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
112,268✔
2994
      if (pDb == NULL) {
112,268✔
2995
        mndReleaseDb(pMnode, pDb);
348✔
2996
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
348✔
2997
      }
2998
      code = taosHashRemove(newUser.readDbs, pAlterReq->objname, len);
111,920✔
2999
      if (code < 0) {
111,920✔
3000
        mError("read db:%s, failed to remove db:%s since %s", newUser.user, pAlterReq->objname, terrstr());
×
3001
      }
3002
      mndReleaseDb(pMnode, pDb);
111,920✔
3003
    } else {
3004
      taosHashClear(newUser.readDbs);
3,525✔
3005
    }
3006
  }
3007

3008
  if (ALTER_USER_DEL_WRITE_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
894,629✔
3009
      ALTER_USER_DEL_ALL_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
779,165✔
3010
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
115,464✔
3011
      int32_t len = strlen(pAlterReq->objname) + 1;
111,591✔
3012
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
111,591✔
3013
      if (pDb == NULL) {
111,591✔
3014
        mndReleaseDb(pMnode, pDb);
×
3015
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
×
3016
      }
3017
      code = taosHashRemove(newUser.writeDbs, pAlterReq->objname, len);
111,591✔
3018
      if (code < 0) {
111,591✔
3019
        mError("user:%s, failed to remove db:%s since %s", newUser.user, pAlterReq->objname, terrstr());
×
3020
      }
3021
      mndReleaseDb(pMnode, pDb);
111,591✔
3022
    } else {
3023
      taosHashClear(newUser.writeDbs);
3,873✔
3024
    }
3025
  }
3026

3027
  SHashObj *pReadTbs = newUser.readTbs;
894,629✔
3028
  SHashObj *pWriteTbs = newUser.writeTbs;
894,629✔
3029
  SHashObj *pAlterTbs = newUser.alterTbs;
894,629✔
3030

3031
#ifdef TD_ENTERPRISE
3032
  if (pAlterReq->isView) {
894,629✔
3033
    pReadTbs = newUser.readViews;
13,935✔
3034
    pWriteTbs = newUser.writeViews;
13,935✔
3035
    pAlterTbs = newUser.alterViews;
13,935✔
3036
  }
3037
#endif
3038

3039
  if (ALTER_USER_ADD_READ_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
894,629✔
3040
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
714,201✔
3041
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pReadTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
180,428✔
3042
  }
3043

3044
  if (ALTER_USER_ADD_WRITE_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
894,629✔
3045
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
717,690✔
3046
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pWriteTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
176,939✔
3047
  }
3048

3049
  if (ALTER_USER_ADD_ALTER_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
894,629✔
3050
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
801,425✔
3051
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pAlterTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
93,204✔
3052
  }
3053

3054
  if (ALTER_USER_DEL_READ_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
894,629✔
3055
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
727,550✔
3056
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pReadTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
167,079✔
3057
  }
3058

3059
  if (ALTER_USER_DEL_WRITE_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
894,629✔
3060
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
729,155✔
3061
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pWriteTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
165,474✔
3062
  }
3063

3064
  if (ALTER_USER_DEL_ALTER_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
894,629✔
3065
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
813,602✔
3066
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pAlterTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
81,027✔
3067
  }
3068

3069
#ifdef USE_TOPIC
3070
  if (ALTER_USER_ADD_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, pAlterReq->privileges)) {
894,629✔
3071
    int32_t      len = strlen(pAlterReq->objname) + 1;
6,228✔
3072
    SMqTopicObj *pTopic = NULL;
6,228✔
3073
    if ((code = mndAcquireTopic(pMnode, pAlterReq->objname, &pTopic)) != 0) {
6,228✔
3074
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3075
    }
3076
    taosRLockLatch(&pTopic->lock);
6,228✔
3077
    code = taosHashPut(newUser.topics, pTopic->name, len, pTopic->name, TSDB_TOPIC_FNAME_LEN);
6,228✔
3078
    taosRUnLockLatch(&pTopic->lock);
6,228✔
3079
    mndReleaseTopic(pMnode, pTopic);
6,228✔
3080
    TAOS_CHECK_GOTO(code, &lino, _OVER);
6,228✔
3081
  }
3082

3083
  if (ALTER_USER_DEL_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, pAlterReq->privileges)) {
894,629✔
3084
    int32_t      len = strlen(pAlterReq->objname) + 1;
4,080✔
3085
    SMqTopicObj *pTopic = NULL;
4,080✔
3086
    if ((code = mndAcquireTopic(pMnode, pAlterReq->objname, &pTopic)) != 0) {
4,080✔
3087
      TAOS_CHECK_GOTO(code, &lino, _OVER);
360✔
3088
    }
3089
    taosRLockLatch(&pTopic->lock);
3,720✔
3090
    code = taosHashRemove(newUser.topics, pAlterReq->objname, len);
3,720✔
3091
    if (code < 0) {
3,720✔
3092
      mError("user:%s, failed to remove topic:%s since %s", newUser.user, pAlterReq->objname, tstrerror(code));
×
3093
    }
3094
    taosRUnLockLatch(&pTopic->lock);
3,720✔
3095
    mndReleaseTopic(pMnode, pTopic);
3,720✔
3096
  }
3097
#endif
3098

3099
  TAOS_CHECK_GOTO(mndAlterUser(pMnode, &newUser, pReq), &lino, _OVER);
894,269✔
3100
  code = TSDB_CODE_ACTION_IN_PROGRESS;
894,269✔
3101

3102
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
894,269✔
3103
    int64_t tse = taosGetTimestampMs();
894,269✔
3104
    double  duration = (double)(tse - tss);
894,269✔
3105
    duration = duration / 1000;
894,269✔
3106
    if (ALTER_USER_ADD_READ_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
894,269✔
3107
              ALTER_USER_ADD_WRITE_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
767,664✔
3108
              ALTER_USER_ADD_ALL_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
706,801✔
3109
              ALTER_USER_ADD_READ_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
706,801✔
3110
              ALTER_USER_ADD_WRITE_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
526,373✔
3111
              ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
437,616✔
3112
      if (strcmp(pAlterReq->objname, "1.*") != 0) {
456,653✔
3113
        SName name = {0};
451,721✔
3114
        TAOS_CHECK_GOTO(tNameFromString(&name, pAlterReq->objname, T_NAME_ACCT | T_NAME_DB), &lino, _OVER);
451,721✔
3115
        auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", name.dbname, pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
451,721✔
3116
      } else {
3117
        auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", "", pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
4,932✔
3118
      }
3119
    } else if (ALTER_USER_ADD_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, pAlterReq->privileges)) {
437,616✔
3120
      auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", pAlterReq->objname, pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
6,228✔
3121
    } else if (ALTER_USER_DEL_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, pAlterReq->privileges)) {
431,388✔
3122
      auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", pAlterReq->objname, pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
3,720✔
3123
    } else {
3124
      if (strcmp(pAlterReq->objname, "1.*") != 0) {
427,668✔
3125
        SName name = {0};
422,040✔
3126
        TAOS_CHECK_GOTO(tNameFromString(&name, pAlterReq->objname, T_NAME_ACCT | T_NAME_DB), &lino, _OVER);
422,040✔
3127
        auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", name.dbname, pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
422,040✔
3128
      } else {
3129
        auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", "", pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
5,628✔
3130
      }
3131
    }
3132
  }
3133
  
3134
_OVER:
918,857✔
3135
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
918,857✔
3136
    mError("user:%s, failed to alter user privileges at line %d since %s", pAlterReq->user, lino, tstrerror(code));
24,588✔
3137
  }
3138
  mndReleaseUser(pMnode, pUser);
918,857✔
3139
  mndUserFreeObj(&newUser);
918,857✔
3140
  TAOS_RETURN(code);
918,857✔
3141
}
3142

3143

3144

3145
static int32_t mndProcessAlterUserBasicInfoReq(SRpcMsg *pReq, SAlterUserReq *pAlterReq) {
45,366✔
3146
  SMnode       *pMnode = pReq->info.node;
45,366✔
3147
  int32_t       code = 0, lino = 0;
45,366✔
3148
  SUserObj     *pUser = NULL;
45,366✔
3149
  SUserObj      newUser = {0};
45,366✔
3150
  char          auditLog[1000] = {0};
45,366✔
3151
  int32_t       auditLen = 0;
45,366✔
3152
  int64_t       tss = taosGetTimestampMs();
45,366✔
3153

3154
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, pAlterReq->user, &pUser), &lino, _OVER);
45,366✔
3155
  TAOS_CHECK_GOTO(mndCheckAlterUserPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser, pAlterReq), &lino, _OVER);
43,316✔
3156
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
38,992✔
3157

3158
  if (pAlterReq->hasPassword) {
38,992✔
3159
    auditLen += tsnprintf(auditLog, sizeof(auditLog), "password,");
13,985✔
3160

3161
    TAOS_CHECK_GOTO(mndCheckPasswordFmt(pAlterReq->pass), &lino, _OVER);
13,985✔
3162
    if (newUser.salt[0] == 0) {
13,985✔
3163
      generateSalt(newUser.salt, sizeof(newUser.salt));
726✔
3164
    }
3165
    char pass[TSDB_PASSWORD_LEN] = {0};
13,985✔
3166
    taosEncryptPass_c((uint8_t *)pAlterReq->pass, strlen(pAlterReq->pass), pass);
13,985✔
3167
    pass[sizeof(pass) - 1] = 0;
13,985✔
3168
    TAOS_CHECK_GOTO(mndEncryptPass(pass, newUser.salt, &newUser.passEncryptAlgorithm), &lino, _OVER);
13,985✔
3169

3170
    if (newUser.passwordReuseMax > 0 || newUser.passwordReuseTime > 0) {
13,985✔
3171
      for(int32_t i = 0; i < newUser.numOfPasswords; ++i) {
29,467✔
3172
        if (0 == strncmp(newUser.passwords[i].pass, pass, TSDB_PASSWORD_LEN)) {
19,997✔
3173
          TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_PASSWORD_REUSE, &lino, _OVER);
363✔
3174
        }
3175
      }
3176
      SUserPassword *passwords = taosMemoryCalloc(newUser.numOfPasswords + 1, sizeof(SUserPassword));
9,470✔
3177
      if (passwords == NULL) {
9,470✔
3178
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3179
      }
3180
      memcpy(passwords + 1, newUser.passwords, newUser.numOfPasswords * sizeof(SUserPassword));
9,470✔
3181
      memcpy(passwords[0].pass, pass, TSDB_PASSWORD_LEN);
9,470✔
3182
      passwords[0].setTime = taosGetTimestampSec();
9,470✔
3183
      taosMemoryFree(newUser.passwords);
9,470✔
3184
      newUser.passwords = passwords;
9,470✔
3185
      ++newUser.numOfPasswords;
9,470✔
3186
      ++newUser.passVersion;
9,470✔
3187
      newUser.changePass = 2;
9,470✔
3188
    } else if (0 != strncmp(newUser.passwords[0].pass, pass, TSDB_PASSWORD_LEN)) {
4,152✔
3189
      memcpy(newUser.passwords[0].pass, pass, TSDB_PASSWORD_LEN);
2,813✔
3190
      newUser.passwords[0].setTime = taosGetTimestampSec();
2,813✔
3191
      ++newUser.passVersion;
2,813✔
3192
      newUser.changePass = 2;
2,813✔
3193
    }
3194
  }
3195

3196
  if (pAlterReq->hasTotpseed) {
38,629✔
3197
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "totpseed,");
×
3198

3199
    if (pAlterReq->totpseed[0] == 0) { // clear totp secret
×
3200
      memset(newUser.totpsecret, 0, sizeof(newUser.totpsecret));
×
3201
    } else if (taosGenerateTotpSecret(pAlterReq->totpseed, 0, newUser.totpsecret, sizeof(newUser.totpsecret)) < 0) {
×
3202
      TAOS_CHECK_GOTO(TSDB_CODE_PAR_INVALID_OPTION_VALUE, &lino, _OVER);
×
3203
    }
3204
  }
3205

3206
  if (pAlterReq->hasEnable) {
38,629✔
3207
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "enable:%d,", pAlterReq->enable);
2,396✔
3208

3209
    newUser.enable = pAlterReq->enable; // lock or unlock user manually
2,396✔
3210
    if (newUser.enable) {
2,396✔
3211
      // reset login info to allow login immediately
3212
      userCacheResetLoginInfo(newUser.user);
1,339✔
3213
    }
3214
  }
3215

3216
  if (pAlterReq->hasSysinfo) {
38,629✔
3217
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "sysinfo:%d,", pAlterReq->sysinfo);
10,798✔
3218
    newUser.sysInfo = pAlterReq->sysinfo;
10,798✔
3219
  }
3220

3221
  if (pAlterReq->hasCreatedb) {
38,629✔
3222
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "createdb:%d,", pAlterReq->createdb);
11,093✔
3223
    newUser.createdb = pAlterReq->createdb;
11,093✔
3224
  }
3225

3226
  if (pAlterReq->hasChangepass) {
38,629✔
3227
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "changepass:%d,", pAlterReq->changepass);
×
3228
    newUser.changePass = pAlterReq->changepass;
×
3229
  }
3230

3231
  if (pAlterReq->hasSessionPerUser) {
38,629✔
3232
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "sessionPerUser:%d,", pAlterReq->sessionPerUser);
×
3233
    newUser.sessionPerUser = pAlterReq->sessionPerUser;
×
3234
  }
3235

3236
  if (pAlterReq->hasConnectTime) {
38,629✔
3237
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "connectTime:%d,", pAlterReq->connectTime);
×
3238
    newUser.connectTime = pAlterReq->connectTime;
×
3239
  }
3240
  
3241
  if (pAlterReq->hasConnectIdleTime) {
38,629✔
3242
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "connectIdleTime:%d,", pAlterReq->connectIdleTime);
×
3243
    newUser.connectIdleTime = pAlterReq->connectIdleTime;
×
3244
  }
3245

3246
  if (pAlterReq->hasCallPerSession) {
38,629✔
3247
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "callPerSession:%d,", pAlterReq->callPerSession);
×
3248
    newUser.callPerSession = pAlterReq->callPerSession;
×
3249
  }
3250

3251
  if (pAlterReq->hasVnodePerCall) {
38,629✔
3252
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "vnodePerCall:%d,", pAlterReq->vnodePerCall);
×
3253
    newUser.vnodePerCall = pAlterReq->vnodePerCall;
×
3254
  }
3255

3256
  if (pAlterReq->hasFailedLoginAttempts) {
38,629✔
3257
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "failedLoginAttempts:%d,", pAlterReq->failedLoginAttempts);
×
3258
    newUser.failedLoginAttempts = pAlterReq->failedLoginAttempts;
×
3259
  }
3260

3261
  if (pAlterReq->hasPasswordLifeTime) {
38,629✔
3262
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordLifeTime:%d,", pAlterReq->passwordLifeTime);
×
3263
    newUser.passwordLifeTime = pAlterReq->passwordLifeTime;
×
3264
  }
3265

3266
  if (pAlterReq->hasPasswordReuseTime) {
38,629✔
3267
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordReuseTime:%d,", pAlterReq->passwordReuseTime);
×
3268
    newUser.passwordReuseTime = pAlterReq->passwordReuseTime;
×
3269
  }
3270

3271
  if (pAlterReq->hasPasswordReuseMax) {
38,629✔
3272
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordReuseMax:%d,", pAlterReq->passwordReuseMax);
×
3273
    newUser.passwordReuseMax = pAlterReq->passwordReuseMax;
×
3274
  }
3275

3276
  if (pAlterReq->hasPasswordLockTime) {
38,629✔
3277
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordLockTime:%d,", pAlterReq->passwordLockTime);
×
3278
    newUser.passwordLockTime = pAlterReq->passwordLockTime;
×
3279
  }
3280

3281
  if (pAlterReq->hasPasswordGraceTime) {
38,629✔
3282
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordGraceTime:%d,", pAlterReq->passwordGraceTime);
×
3283
    newUser.passwordGraceTime = pAlterReq->passwordGraceTime;
×
3284
  }
3285

3286
  if (pAlterReq->hasInactiveAccountTime) {
38,629✔
3287
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "inactiveAccountTime:%d,", pAlterReq->inactiveAccountTime);
×
3288
    newUser.inactiveAccountTime = pAlterReq->inactiveAccountTime;
×
3289
  }
3290

3291
  if (pAlterReq->hasAllowTokenNum) {
38,629✔
3292
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "allowTokenNum:%d,", pAlterReq->allowTokenNum);
×
3293
    newUser.allowTokenNum = pAlterReq->allowTokenNum;
×
3294
  }
3295

3296
  if (pAlterReq->numDropIpRanges > 0 || pAlterReq->numIpRanges > 0) {
38,629✔
3297
    int32_t dummy = 0;
720✔
3298

3299
    // put previous ip whitelist into hash table
3300
    SHashObj *m = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
720✔
3301
    if (m == NULL) {
720✔
3302
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3303
    }
3304

3305
    for (int32_t i = 0; i < newUser.pIpWhiteListDual->num; i++) {
2,520✔
3306
      SIpRange range;
1,800✔
3307
      copyIpRange(&range, newUser.pIpWhiteListDual->pIpRanges + i);
1,800✔
3308
      code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
1,800✔
3309
      if (code != 0) {
1,800✔
3310
        taosHashCleanup(m);
×
3311
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3312
      }
3313
    }
3314

3315
    if (pAlterReq->numDropIpRanges > 0) {
720✔
3316
      auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "dropIpRanges:%d,", pAlterReq->numDropIpRanges);
360✔
3317

3318
      for (int32_t i = 0; i < pAlterReq->numDropIpRanges; i++) {
720✔
3319
        if (taosHashGetSize(m) == 0) {
360✔
3320
          break;
×
3321
        }
3322

3323
        SIpRange range;
360✔
3324
        copyIpRange(&range, pAlterReq->pDropIpRanges + i);
360✔
3325

3326
        // for white list, drop default ip ranges is allowed, otherwise, we can never
3327
        // convert white list to black list.
3328

3329
        code = taosHashRemove(m, &range, sizeof(range));
360✔
3330
        if (code == TSDB_CODE_NOT_FOUND) {
360✔
3331
          // treat not exist as success
3332
          code = 0;
360✔
3333
        }
3334
        if (code != 0) {
360✔
3335
          taosHashCleanup(m);
×
3336
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3337
        }
3338
      }
3339
    }
3340

3341
    if (pAlterReq->numIpRanges > 0) {
720✔
3342
      auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "addIpRanges:%d,", pAlterReq->numIpRanges);
360✔
3343
      for (int32_t i = 0; i < pAlterReq->numIpRanges; i++) {
720✔
3344
        SIpRange range;
360✔
3345
        copyIpRange(&range, pAlterReq->pIpRanges + i);
360✔
3346
        code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
360✔
3347
        if (code != 0) {
360✔
3348
          taosHashCleanup(m);
×
3349
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3350
        }
3351
      }
3352
    }
3353

3354
    int32_t numOfRanges = taosHashGetSize(m);
720✔
3355
    if (numOfRanges > MND_MAX_USER_IP_RANGE) {
720✔
3356
      taosHashCleanup(m);
×
3357
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_IP_RANGE, &lino, _OVER);
×
3358
    }
3359

3360
    SIpWhiteListDual *p = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + numOfRanges * sizeof(SIpRange));
720✔
3361
    if (p == NULL) {
720✔
3362
      taosHashCleanup(m);
×
3363
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3364
    }
3365

3366
    void *pIter = taosHashIterate(m, NULL);
720✔
3367
    int32_t i = 0;
720✔
3368
    while (pIter) {
2,880✔
3369
      size_t len = 0;
2,160✔
3370
      SIpRange *key = taosHashGetKey(pIter, &len);
2,160✔
3371
      memcpy(p->pIpRanges + i, key, sizeof(SIpRange));
2,160✔
3372
      pIter = taosHashIterate(m, pIter);
2,160✔
3373
      i++;
2,160✔
3374
    }
3375

3376
    taosHashCleanup(m);
720✔
3377
    p->num = numOfRanges;
720✔
3378
    taosMemoryFreeClear(newUser.pIpWhiteListDual);
720✔
3379
    sortIpWhiteList(p);
720✔
3380
    newUser.pIpWhiteListDual = p;
720✔
3381

3382
    newUser.ipWhiteListVer++;
720✔
3383
  }
3384

3385

3386
  if (pAlterReq->numTimeRanges > 0 || pAlterReq->numDropTimeRanges) {
38,629✔
3387
    int32_t dummy = 0;
×
3388

3389
    // put previous ip whitelist into hash table
3390
    SHashObj *m = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
×
3391
    if (m == NULL) {
×
3392
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3393
    }
3394

3395
    for (int32_t i = 0; i < newUser.pTimeWhiteList->num; i++) {
×
3396
      SDateTimeWhiteListItem *range = &newUser.pTimeWhiteList->ranges[i];
×
3397
      if (isDateTimeWhiteListItemExpired(range)) {
×
3398
        continue;
×
3399
      }
3400
      code = taosHashPut(m, range, sizeof(*range), &dummy, sizeof(dummy));
×
3401
      if (code != 0) {
×
3402
        taosHashCleanup(m);
×
3403
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3404
      }
3405
    }
3406

3407
    if (pAlterReq->numDropTimeRanges > 0) {
×
3408
      auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "dropTimeRanges:%d,", pAlterReq->numDropTimeRanges);
×
3409
      for (int32_t i = 0; i < pAlterReq->numDropTimeRanges; i++) {
×
3410
        if (taosHashGetSize(m) == 0) {
×
3411
          break;
×
3412
        }
3413
        SDateTimeWhiteListItem range = { 0 };
×
3414
        DateTimeRangeToWhiteListItem(&range, pAlterReq->pDropTimeRanges + i);
×
3415

3416
        code = taosHashRemove(m, &range, sizeof(range));
×
3417
        if (code == TSDB_CODE_NOT_FOUND) {
×
3418
          // treat not exist as success
3419
          code = 0;
×
3420
        }
3421
        if (code != 0) {
×
3422
          taosHashCleanup(m);
×
3423
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3424
        }
3425
      }
3426
    }
3427

3428
    if (pAlterReq->numTimeRanges > 0) {
×
3429
      auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "addTimeRanges:%d,", pAlterReq->numTimeRanges);
×
3430
      for (int32_t i = 0; i < pAlterReq->numTimeRanges; i++) {
×
3431
        SDateTimeWhiteListItem range = { 0 };
×
3432
        DateTimeRangeToWhiteListItem(&range, pAlterReq->pTimeRanges + i);
×
3433
        if (isDateTimeWhiteListItemExpired(&range)) {
×
3434
          continue;
×
3435
        }
3436
        code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
×
3437
        if (code != 0) {
×
3438
          taosHashCleanup(m);
×
3439
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3440
        }
3441
      }
3442
    }
3443

3444
    int32_t numOfRanges = taosHashGetSize(m);
×
3445
    if (numOfRanges > MND_MAX_USER_TIME_RANGE) {
×
3446
      taosHashCleanup(m);
×
3447
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_TIME_RANGE, &lino, _OVER);
×
3448
    }
3449

3450
    SDateTimeWhiteList *p = taosMemoryCalloc(1, sizeof(SDateTimeWhiteList) + numOfRanges * sizeof(SDateTimeWhiteListItem));
×
3451
    if (p == NULL) {
×
3452
      taosHashCleanup(m);
×
3453
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3454
    }
3455

3456
    void *pIter = taosHashIterate(m, NULL);
×
3457
    int32_t i = 0;
×
3458
    while (pIter) {
×
3459
      size_t len = 0;
×
3460
      SDateTimeWhiteListItem *key = taosHashGetKey(pIter, &len);
×
3461
      memcpy(&p->ranges[i], key, sizeof(SDateTimeWhiteListItem));
×
3462
      pIter = taosHashIterate(m, pIter);
×
3463
      i++;
×
3464
    }
3465

3466
    taosHashCleanup(m);
×
3467
    p->num = numOfRanges;
×
3468
    taosMemoryFreeClear(newUser.pTimeWhiteList);
×
3469
    sortTimeWhiteList(p);
×
3470
    newUser.pTimeWhiteList = p;
×
3471
    newUser.timeWhiteListVer++;
×
3472
  }
3473

3474
  TAOS_CHECK_GOTO(mndAlterUser(pMnode, &newUser, pReq), &lino, _OVER);
38,629✔
3475
  code = TSDB_CODE_ACTION_IN_PROGRESS;
38,629✔
3476

3477
  if (auditLen > 0) {
38,629✔
3478
    auditLog[--auditLen] = 0; // remove last ','
38,629✔
3479
  }
3480
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
38,629✔
3481
    int64_t tse = taosGetTimestampMs();
38,629✔
3482
    double  duration = (double)(tse - tss);
38,629✔
3483
    duration = duration / 1000;
38,629✔
3484
    auditRecord(pReq, pMnode->clusterId, "alterUser", "", pAlterReq->user, auditLog, auditLen, duration, 0);
38,629✔
3485
  }
3486

3487
_OVER:
45,366✔
3488
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
45,366✔
3489
    mError("user:%s, failed to alter at line %d since %s", pAlterReq->user, lino, tstrerror(code));
6,737✔
3490
  }
3491

3492
  mndReleaseUser(pMnode, pUser);
45,366✔
3493
  mndUserFreeObj(&newUser);
45,366✔
3494
  return code;
45,366✔
3495
}
3496

3497

3498

3499
static int32_t mndProcessAlterUserReq(SRpcMsg *pReq) {
964,223✔
3500
  SAlterUserReq alterReq = {0};
964,223✔
3501

3502
  int32_t code = tDeserializeSAlterUserReq(pReq->pCont, pReq->contLen, &alterReq);
964,223✔
3503
  if (code != 0) {
964,223✔
3504
    mError("failed to deserialize alter user request at line %d since %s", __LINE__, tstrerror(code));
×
3505
    TAOS_RETURN(code);
×
3506
  }
3507

3508
  if (alterReq.user[0] == 0) {
964,223✔
3509
    tFreeSAlterUserReq(&alterReq);
×
3510
    mError("failed to alter user at line %d since invalid user format", __LINE__);
×
3511
    TAOS_RETURN(TSDB_CODE_MND_INVALID_USER_FORMAT);
×
3512
  }
3513

3514
  mInfo("user:%s, start to alter", alterReq.user);
964,223✔
3515
  if (alterReq.alterType == TSDB_ALTER_USER_BASIC_INFO) {
964,223✔
3516
    code = mndProcessAlterUserBasicInfoReq(pReq, &alterReq);
45,366✔
3517
  } else {
3518
    code = mndProcessAlterUserPrivilegesReq(pReq, &alterReq);
918,857✔
3519
  }
3520

3521
  tFreeSAlterUserReq(&alterReq);
964,223✔
3522
  TAOS_RETURN(code);
964,223✔
3523
}
3524

3525
int32_t mndGetAuditUser(SMnode *pMnode, char* user){
41,351,087✔
3526
  (void)tsnprintf(user, TSDB_USER_LEN, "audit");
41,351,087✔
3527
  return 0;
41,351,087✔
3528
}
3529

3530
static int32_t mndDropUser(SMnode *pMnode, SRpcMsg *pReq, SUserObj *pUser) {
59,371✔
3531
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "drop-user");
59,371✔
3532
  if (pTrans == NULL) {
59,371✔
3533
    mError("user:%s, failed to drop since %s", pUser->user, terrstr());
×
3534
    TAOS_RETURN(terrno);
×
3535
  }
3536
  mInfo("trans:%d, used to drop user:%s", pTrans->id, pUser->user);
59,371✔
3537

3538
  SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
59,371✔
3539
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
59,371✔
3540
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
3541
    mndTransDrop(pTrans);
×
3542
    TAOS_RETURN(terrno);
×
3543
  }
3544
  if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED) < 0) {
59,371✔
3545
    mndTransDrop(pTrans);
×
3546
    TAOS_RETURN(terrno);
×
3547
  }
3548

3549
  if (mndDropTokensByUser(pMnode, pTrans, pUser->user) != 0) {
59,371✔
3550
    mndTransDrop(pTrans);
×
3551
    TAOS_RETURN(terrno);
×
3552
  }
3553

3554
  if (mndTransPrepare(pMnode, pTrans) != 0) {
59,371✔
3555
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
3556
    mndTransDrop(pTrans);
×
3557
    TAOS_RETURN(terrno);
×
3558
  }
3559

3560
  userCacheRemoveUser(pUser->user);
59,371✔
3561
  mndDropCachedTokensByUser(pUser->user);
59,371✔
3562

3563
  mndTransDrop(pTrans);
59,371✔
3564
  TAOS_RETURN(0);
59,371✔
3565
}
3566

3567
static int32_t mndProcessDropUserReq(SRpcMsg *pReq) {
59,718✔
3568
  SMnode      *pMnode = pReq->info.node;
59,718✔
3569
  int32_t      code = 0;
59,718✔
3570
  int32_t      lino = 0;
59,718✔
3571
  SUserObj    *pUser = NULL;
59,718✔
3572
  SDropUserReq dropReq = {0};
59,718✔
3573
  int64_t      tss = taosGetTimestampMs();
59,718✔
3574

3575
  TAOS_CHECK_GOTO(tDeserializeSDropUserReq(pReq->pCont, pReq->contLen, &dropReq), &lino, _OVER);
59,718✔
3576

3577
  mInfo("user:%s, start to drop", dropReq.user);
59,718✔
3578
  TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), MND_OPER_DROP_USER), &lino, _OVER);
59,718✔
3579

3580
  if (dropReq.user[0] == 0) {
59,718✔
3581
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
3582
  }
3583

3584
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, dropReq.user, &pUser), &lino, _OVER);
59,718✔
3585

3586
  TAOS_CHECK_GOTO(mndDropUser(pMnode, pReq, pUser), &lino, _OVER);
59,371✔
3587
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
59,371✔
3588

3589
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
59,371✔
3590
    int64_t tse = taosGetTimestampMs();
59,371✔
3591
    double  duration = (double)(tse - tss);
59,371✔
3592
    duration = duration / 1000;
59,371✔
3593
    auditRecord(pReq, pMnode->clusterId, "dropUser", "", dropReq.user, dropReq.sql, dropReq.sqlLen, duration, 0);
59,371✔
3594
  }
3595

3596
_OVER:
59,718✔
3597
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
59,718✔
3598
    mError("user:%s, failed to drop at line %d since %s", dropReq.user, lino, tstrerror(code));
347✔
3599
  }
3600

3601
  mndReleaseUser(pMnode, pUser);
59,718✔
3602
  tFreeSDropUserReq(&dropReq);
59,718✔
3603
  TAOS_RETURN(code);
59,718✔
3604
}
3605

3606
static int32_t mndProcessGetUserAuthReq(SRpcMsg *pReq) {
3,376,333✔
3607
  SMnode         *pMnode = pReq->info.node;
3,376,333✔
3608
  int32_t         code = 0;
3,376,333✔
3609
  int32_t         lino = 0;
3,376,333✔
3610
  int32_t         contLen = 0;
3,376,333✔
3611
  void           *pRsp = NULL;
3,376,333✔
3612
  SUserObj       *pUser = NULL;
3,376,333✔
3613
  SGetUserAuthReq authReq = {0};
3,376,333✔
3614
  SGetUserAuthRsp authRsp = {0};
3,376,333✔
3615

3616
  TAOS_CHECK_EXIT(tDeserializeSGetUserAuthReq(pReq->pCont, pReq->contLen, &authReq));
3,376,333✔
3617
  mTrace("user:%s, start to get auth", authReq.user);
3,376,333✔
3618

3619
  TAOS_CHECK_EXIT(mndAcquireUser(pMnode, authReq.user, &pUser));
3,376,333✔
3620

3621
  TAOS_CHECK_EXIT(mndSetUserAuthRsp(pMnode, pUser, &authRsp));
3,374,959✔
3622

3623
  contLen = tSerializeSGetUserAuthRsp(NULL, 0, &authRsp);
3,374,959✔
3624
  if (contLen < 0) {
3,374,959✔
3625
    TAOS_CHECK_EXIT(contLen);
×
3626
  }
3627
  pRsp = rpcMallocCont(contLen);
3,374,959✔
3628
  if (pRsp == NULL) {
3,374,959✔
3629
    TAOS_CHECK_EXIT(terrno);
×
3630
  }
3631

3632
  contLen = tSerializeSGetUserAuthRsp(pRsp, contLen, &authRsp);
3,374,959✔
3633
  if (contLen < 0) {
3,374,191✔
3634
    TAOS_CHECK_EXIT(contLen);
×
3635
  }
3636

3637
_exit:
3,375,565✔
3638
  mndReleaseUser(pMnode, pUser);
3,375,565✔
3639
  tFreeSGetUserAuthRsp(&authRsp);
3,376,333✔
3640
  if (code < 0) {
3,376,333✔
3641
    mError("user:%s, failed to get auth at line %d since %s", authReq.user, lino, tstrerror(code));
1,374✔
3642
    rpcFreeCont(pRsp);
1,374✔
3643
    pRsp = NULL;
1,374✔
3644
    contLen = 0;
1,374✔
3645
  }
3646
  pReq->info.rsp = pRsp;
3,376,333✔
3647
  pReq->info.rspLen = contLen;
3,376,333✔
3648
  pReq->code = code;
3,375,565✔
3649

3650
  TAOS_RETURN(code);
3,376,333✔
3651
}
3652

3653

3654
bool mndIsTotpEnabledUser(SUserObj *pUser) {
2,626,717✔
3655
  for (int32_t i = 0; i < sizeof(pUser->totpsecret); i++) {
86,647,934✔
3656
    if (pUser->totpsecret[i] != 0) {
84,022,816✔
3657
      return true;
×
3658
    }
3659
  }
3660
  return false;
2,625,118✔
3661
}
3662

3663

3664
static int32_t mndRetrieveUsers(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
20,187✔
3665
  SMnode   *pMnode = pReq->info.node;
20,187✔
3666
  SSdb     *pSdb = pMnode->pSdb;
20,187✔
3667
  int32_t   code = 0;
20,187✔
3668
  int32_t   lino = 0;
20,187✔
3669
  int32_t   numOfRows = 0;
20,187✔
3670
  SUserObj *pUser = NULL;
20,187✔
3671
  int32_t   cols = 0;
20,187✔
3672
  int8_t    flag = 0;
20,187✔
3673
  char     *pWrite = NULL;
20,187✔
3674
  char     *buf = NULL;
20,187✔
3675
  char     *varstr = NULL;
20,187✔
3676

3677
  while (numOfRows < rows) {
73,232✔
3678
    pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
73,232✔
3679
    if (pShow->pIter == NULL) break;
73,232✔
3680

3681
    cols = 0;
53,045✔
3682
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
53,045✔
3683
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
53,045✔
3684
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
53,045✔
3685
    COL_DATA_SET_VAL_GOTO((const char *)name, false, pUser, pShow->pIter, _exit);
53,045✔
3686

3687
    cols++;
53,045✔
3688
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
53,045✔
3689
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->superUser, false, pUser, pShow->pIter, _exit);
53,045✔
3690

3691
    cols++;
53,045✔
3692
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
53,045✔
3693
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->enable, false, pUser, pShow->pIter, _exit);
53,045✔
3694

3695
    cols++;
53,045✔
3696
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
53,045✔
3697
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sysInfo, false, pUser, pShow->pIter, _exit);
53,045✔
3698

3699
    cols++;
53,045✔
3700
    flag = pUser->createdb ? 1 : 0;
53,045✔
3701
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
53,045✔
3702
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
53,045✔
3703

3704
    cols++;
53,045✔
3705
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
53,045✔
3706
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->createdTime, false, pUser, pShow->pIter, _exit);
53,045✔
3707

3708
    cols++;
53,045✔
3709
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
53,045✔
3710
    flag = mndIsTotpEnabledUser(pUser) ? 1 : 0;
53,045✔
3711
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
53,045✔
3712

3713
    cols++;
53,045✔
3714

3715
    int32_t tlen = convertIpWhiteListToStr(pUser, &buf);
53,045✔
3716
    if (tlen != 0) {
53,045✔
3717
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
53,045✔
3718
      if (varstr == NULL) {
53,045✔
3719
        sdbRelease(pSdb, pUser);
×
3720
        sdbCancelFetch(pSdb, pShow->pIter);
×
3721
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
3722
      }
3723
      varDataSetLen(varstr, tlen);
53,045✔
3724
      (void)memcpy(varDataVal(varstr), buf, tlen);
53,045✔
3725

3726
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
53,045✔
3727
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
53,045✔
3728

3729
      taosMemoryFreeClear(buf);
53,045✔
3730
    } else {
3731
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3732
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
3733
    }
3734

3735
    cols++;
53,045✔
3736
    tlen = convertTimeRangesToStr(pUser, &buf);
53,045✔
3737
    if (tlen != 0) {
53,045✔
3738
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
53,045✔
3739
      if (varstr == NULL) {
53,045✔
3740
        sdbRelease(pSdb, pUser);
×
3741
        sdbCancelFetch(pSdb, pShow->pIter);
×
3742
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
3743
      }
3744
      varDataSetLen(varstr, tlen);
53,045✔
3745
      (void)memcpy(varDataVal(varstr), buf, tlen);
53,045✔
3746

3747
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
53,045✔
3748
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
53,045✔
3749

3750
      taosMemoryFreeClear(buf);
53,045✔
3751
    } else {
3752
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3753
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
3754
    }
3755

3756
    numOfRows++;
53,045✔
3757
    sdbRelease(pSdb, pUser);
53,045✔
3758
  }
3759

3760
  pShow->numOfRows += numOfRows;
20,187✔
3761
_exit:
20,187✔
3762
  taosMemoryFreeClear(buf);
20,187✔
3763
  taosMemoryFreeClear(varstr);
20,187✔
3764
  if (code < 0) {
20,187✔
3765
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
3766
    TAOS_RETURN(code);
×
3767
  }
3768
  return numOfRows;
20,187✔
3769
}
3770

3771
static int32_t mndRetrieveUsersFull(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
×
3772
  int32_t numOfRows = 0;
×
3773
#ifdef TD_ENTERPRISE
3774
  SMnode   *pMnode = pReq->info.node;
×
3775
  SSdb     *pSdb = pMnode->pSdb;
×
3776
  SUserObj *pUser = NULL;
×
3777
  int32_t   code = 0;
×
3778
  int32_t   lino = 0;
×
3779
  int32_t   cols = 0;
×
3780
  int8_t    flag = 0;
×
3781
  char     *pWrite = NULL;
×
3782
  char     *buf = NULL;
×
3783
  char     *varstr = NULL;
×
3784

3785
  while (numOfRows < rows) {
×
3786
    pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
×
3787
    if (pShow->pIter == NULL) break;
×
3788

3789
    cols = 0;
×
3790
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3791
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
×
3792
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
×
3793
    COL_DATA_SET_VAL_GOTO((const char *)name, false, pUser, pShow->pIter, _exit);
×
3794

3795
    cols++;
×
3796
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3797
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->superUser, false, pUser, pShow->pIter, _exit);
×
3798

3799
    cols++;
×
3800
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3801
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->enable, false, pUser, pShow->pIter, _exit);
×
3802

3803
    cols++;
×
3804
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3805
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sysInfo, false, pUser, pShow->pIter, _exit);
×
3806

3807
    cols++;
×
3808
    flag = pUser->createdb ? 1 : 0;
×
3809
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3810
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
×
3811

3812
    cols++;
×
3813
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3814
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->createdTime, false, pUser, pShow->pIter, _exit);
×
3815

3816
    cols++;
×
3817
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3818
    flag = mndIsTotpEnabledUser(pUser) ? 1 : 0;
×
3819
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
×
3820

3821
    cols++;
×
3822
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3823
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->changePass, false, pUser, pShow->pIter, _exit);
×
3824

3825
    cols++;
×
3826
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3827
    char pass[TSDB_PASSWORD_LEN + VARSTR_HEADER_SIZE] = {0};
×
3828
    STR_WITH_MAXSIZE_TO_VARSTR(pass, pUser->passwords[0].pass, pShow->pMeta->pSchemas[cols].bytes);
×
3829
    COL_DATA_SET_VAL_GOTO((const char *)pass, false, pUser, pShow->pIter, _exit);
×
3830

3831
    cols++;
×
3832
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3833
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sessionPerUser, false, pUser, pShow->pIter, _exit);
×
3834

3835
    cols++;
×
3836
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3837
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->connectTime, false, pUser, pShow->pIter, _exit);
×
3838

3839
    cols++;
×
3840
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3841
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->connectIdleTime, false, pUser, pShow->pIter, _exit);
×
3842

3843
    cols++;
×
3844
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3845
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->callPerSession, false, pUser, pShow->pIter, _exit);
×
3846

3847
    /* not supported yet
3848
    cols++;
3849
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
3850
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->vnodePerSession, false, pUser, pShow->pIter, _exit);
3851
*/
3852

3853
    cols++;
×
3854
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3855
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->failedLoginAttempts, false, pUser, pShow->pIter, _exit);
×
3856

3857
    cols++;
×
3858
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3859
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordLifeTime, false, pUser, pShow->pIter, _exit);
×
3860

3861
    cols++;
×
3862
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3863
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordReuseTime, false, pUser, pShow->pIter, _exit);
×
3864

3865
    cols++;
×
3866
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3867
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordReuseMax, false, pUser, pShow->pIter, _exit);
×
3868

3869
    cols++;
×
3870
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3871
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordLockTime, false, pUser, pShow->pIter, _exit);
×
3872

3873
    cols++;
×
3874
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3875
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordGraceTime, false, pUser, pShow->pIter, _exit);
×
3876

3877
    cols++;
×
3878
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3879
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->inactiveAccountTime, false, pUser, pShow->pIter, _exit);
×
3880

3881
    cols++;
×
3882
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3883
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->allowTokenNum, false, pUser, pShow->pIter, _exit);
×
3884

3885
    cols++;
×
3886
    int32_t tlen = convertIpWhiteListToStr(pUser, &buf);
×
3887
    if (tlen != 0) {
×
3888
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
×
3889
      if (varstr == NULL) {
×
3890
        sdbRelease(pSdb, pUser);
×
3891
        sdbCancelFetch(pSdb, pShow->pIter);
×
3892
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
3893
      }
3894
      varDataSetLen(varstr, tlen);
×
3895
      (void)memcpy(varDataVal(varstr), buf, tlen);
×
3896

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

3900
      taosMemoryFreeClear(buf);
×
3901
    } else {
3902
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3903
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
3904
    }
3905

3906
    cols++;
×
3907
    tlen = convertTimeRangesToStr(pUser, &buf);
×
3908
    if (tlen != 0) {
×
3909
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
×
3910
      if (varstr == NULL) {
×
3911
        sdbRelease(pSdb, pUser);
×
3912
        sdbCancelFetch(pSdb, pShow->pIter);
×
3913
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
3914
      }
3915
      varDataSetLen(varstr, tlen);
×
3916
      (void)memcpy(varDataVal(varstr), buf, tlen);
×
3917

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

3921
      taosMemoryFreeClear(buf);
×
3922
    } else {
3923
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3924
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
3925
    }
3926

3927
    numOfRows++;
×
3928
    sdbRelease(pSdb, pUser);
×
3929
  }
3930

3931
  pShow->numOfRows += numOfRows;
×
3932
_exit:
×
3933
  taosMemoryFreeClear(buf);
×
3934
  taosMemoryFreeClear(varstr);
×
3935
  if (code < 0) {
×
3936
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
3937
    TAOS_RETURN(code);
×
3938
  }
3939
#endif
3940
  return numOfRows;
×
3941
}
3942

3943
static void mndCancelGetNextUser(SMnode *pMnode, void *pIter) {
×
3944
  SSdb *pSdb = pMnode->pSdb;
×
3945
  sdbCancelFetchByType(pSdb, pIter, SDB_USER);
×
3946
}
×
3947

3948
static int32_t mndLoopHash(SHashObj *hash, char *priType, SSDataBlock *pBlock, int32_t *pNumOfRows, SSdb *pSdb,
604,818✔
3949
                           SUserObj *pUser, SShowObj *pShow, char **condition, char **sql) {
3950
  char   *value = taosHashIterate(hash, NULL);
604,818✔
3951
  char   *user = pUser->user;
604,818✔
3952
  int32_t code = 0;
604,818✔
3953
  int32_t lino = 0;
604,818✔
3954
  int32_t cols = 0;
604,818✔
3955
  int32_t numOfRows = *pNumOfRows;
604,818✔
3956

3957
  while (value != NULL) {
687,156✔
3958
    cols = 0;
82,338✔
3959
    char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
82,338✔
3960
    STR_WITH_MAXSIZE_TO_VARSTR(userName, user, pShow->pMeta->pSchemas[cols].bytes);
82,338✔
3961
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
82,338✔
3962
    COL_DATA_SET_VAL_GOTO((const char *)userName, false, NULL, NULL, _exit);
82,338✔
3963

3964
    char privilege[20] = {0};
82,338✔
3965
    STR_WITH_MAXSIZE_TO_VARSTR(privilege, priType, pShow->pMeta->pSchemas[cols].bytes);
82,338✔
3966
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
82,338✔
3967
    COL_DATA_SET_VAL_GOTO((const char *)privilege, false, NULL, NULL, _exit);
82,338✔
3968

3969
    size_t keyLen = 0;
82,338✔
3970
    void  *key = taosHashGetKey(value, &keyLen);
82,338✔
3971

3972
    char dbName[TSDB_DB_NAME_LEN] = {0};
82,338✔
3973
    (void)mndExtractShortDbNameFromStbFullName(key, dbName);
82,338✔
3974
    char dbNameContent[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
82,338✔
3975
    STR_WITH_MAXSIZE_TO_VARSTR(dbNameContent, dbName, pShow->pMeta->pSchemas[cols].bytes);
82,338✔
3976
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
82,338✔
3977
    COL_DATA_SET_VAL_GOTO((const char *)dbNameContent, false, NULL, NULL, _exit);
82,338✔
3978

3979
    char tableName[TSDB_TABLE_NAME_LEN] = {0};
82,338✔
3980
    mndExtractTbNameFromStbFullName(key, tableName, TSDB_TABLE_NAME_LEN);
82,338✔
3981
    char tableNameContent[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
82,338✔
3982
    STR_WITH_MAXSIZE_TO_VARSTR(tableNameContent, tableName, pShow->pMeta->pSchemas[cols].bytes);
82,338✔
3983
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
82,338✔
3984
    COL_DATA_SET_VAL_GOTO((const char *)tableNameContent, false, NULL, NULL, _exit);
82,338✔
3985

3986
    if (strcmp("t", value) != 0 && strcmp("v", value) != 0) {
138,960✔
3987
      SNode  *pAst = NULL;
56,622✔
3988
      int32_t sqlLen = 0;
56,622✔
3989
      size_t  bufSz = strlen(value) + 1;
56,622✔
3990
      if (bufSz < 6) bufSz = 6;
56,622✔
3991
      TAOS_MEMORY_REALLOC(*sql, bufSz);
56,622✔
3992
      if (*sql == NULL) {
56,622✔
3993
        code = terrno;
×
3994
        goto _exit;
×
3995
      }
3996
      TAOS_MEMORY_REALLOC(*condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
56,622✔
3997
      if ((*condition) == NULL) {
56,622✔
3998
        code = terrno;
×
3999
        goto _exit;
×
4000
      }
4001

4002
      if (nodesStringToNode(value, &pAst) == 0) {
56,622✔
4003
        if (nodesNodeToSQLFormat(pAst, *sql, bufSz, &sqlLen, true) != 0) {
56,622✔
4004
          sqlLen = tsnprintf(*sql, bufSz, "error");
×
4005
        }
4006
        nodesDestroyNode(pAst);
56,622✔
4007
      }
4008

4009
      if (sqlLen == 0) {
56,622✔
4010
        sqlLen = tsnprintf(*sql, bufSz, "error");
×
4011
      }
4012

4013
      STR_WITH_MAXSIZE_TO_VARSTR((*condition), (*sql), pShow->pMeta->pSchemas[cols].bytes);
56,622✔
4014

4015
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
56,622✔
4016
      COL_DATA_SET_VAL_GOTO((const char *)(*condition), false, NULL, NULL, _exit);
56,622✔
4017

4018
      char notes[2] = {0};
56,622✔
4019
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
56,622✔
4020
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
56,622✔
4021
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, NULL, NULL, _exit);
56,622✔
4022
    } else {
4023
      TAOS_MEMORY_REALLOC(*condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
25,716✔
4024
      if ((*condition) == NULL) {
25,716✔
4025
        code = terrno;
×
4026
        goto _exit;
×
4027
      }
4028
      STR_WITH_MAXSIZE_TO_VARSTR((*condition), "", pShow->pMeta->pSchemas[cols].bytes);
25,716✔
4029
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
25,716✔
4030
      COL_DATA_SET_VAL_GOTO((const char *)(*condition), false, NULL, NULL, _exit);
25,716✔
4031

4032
      char notes[64 + VARSTR_HEADER_SIZE] = {0};
25,716✔
4033
      STR_WITH_MAXSIZE_TO_VARSTR(notes, value[0] == 'v' ? "view" : "", sizeof(notes));
25,716✔
4034
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
25,716✔
4035
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, NULL, NULL, _exit);
25,716✔
4036
    }
4037

4038
    numOfRows++;
82,338✔
4039
    value = taosHashIterate(hash, value);
82,338✔
4040
  }
4041
  *pNumOfRows = numOfRows;
604,818✔
4042
_exit:
604,818✔
4043
  if (code < 0) {
604,818✔
4044
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4045
    sdbRelease(pSdb, pUser);
×
4046
    sdbCancelFetch(pSdb, pShow->pIter);
×
4047
  }
4048
  TAOS_RETURN(code);
604,818✔
4049
}
4050

4051
static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
19,912✔
4052
  int32_t   code = 0;
19,912✔
4053
  int32_t   lino = 0;
19,912✔
4054
  SMnode   *pMnode = pReq->info.node;
19,912✔
4055
  SSdb     *pSdb = pMnode->pSdb;
19,912✔
4056
  int32_t   numOfRows = 0;
19,912✔
4057
  SUserObj *pUser = NULL;
19,912✔
4058
  int32_t   cols = 0;
19,912✔
4059
  char     *pWrite = NULL;
19,912✔
4060
  char     *condition = NULL;
19,912✔
4061
  char     *sql = NULL;
19,912✔
4062

4063
  bool fetchNextUser = pShow->restore ? false : true;
19,912✔
4064
  pShow->restore = false;
19,912✔
4065

4066
  while (numOfRows < rows) {
120,715✔
4067
    if (fetchNextUser) {
120,715✔
4068
      pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
120,715✔
4069
      if (pShow->pIter == NULL) break;
120,715✔
4070
    } else {
4071
      fetchNextUser = true;
×
4072
      void *pKey = taosHashGetKey(pShow->pIter, NULL);
×
4073
      pUser = sdbAcquire(pSdb, SDB_USER, pKey);
×
4074
      if (!pUser) {
×
4075
        continue;
×
4076
      }
4077
    }
4078

4079
    int32_t numOfReadDbs = taosHashGetSize(pUser->readDbs);
100,803✔
4080
    int32_t numOfWriteDbs = taosHashGetSize(pUser->writeDbs);
100,803✔
4081
    int32_t numOfTopics = taosHashGetSize(pUser->topics);
100,803✔
4082
    int32_t numOfReadTbs = taosHashGetSize(pUser->readTbs);
100,803✔
4083
    int32_t numOfWriteTbs = taosHashGetSize(pUser->writeTbs);
100,803✔
4084
    int32_t numOfAlterTbs = taosHashGetSize(pUser->alterTbs);
100,803✔
4085
    int32_t numOfReadViews = taosHashGetSize(pUser->readViews);
100,803✔
4086
    int32_t numOfWriteViews = taosHashGetSize(pUser->writeViews);
100,803✔
4087
    int32_t numOfAlterViews = taosHashGetSize(pUser->alterViews);
100,803✔
4088
    if (numOfRows + numOfReadDbs + numOfWriteDbs + numOfTopics + numOfReadTbs + numOfWriteTbs + numOfAlterTbs +
100,803✔
4089
            numOfReadViews + numOfWriteViews + numOfAlterViews >=
100,803✔
4090
        rows) {
4091
      mInfo(
×
4092
          "will restore. current num of rows: %d, read dbs %d, write dbs %d, topics %d, read tables %d, write tables "
4093
          "%d, alter tables %d, read views %d, write views %d, alter views %d",
4094
          numOfRows, numOfReadDbs, numOfWriteDbs, numOfTopics, numOfReadTbs, numOfWriteTbs, numOfAlterTbs,
4095
          numOfReadViews, numOfWriteViews, numOfAlterViews);
4096
      pShow->restore = true;
×
4097
      sdbRelease(pSdb, pUser);
×
4098
      break;
×
4099
    }
4100

4101
    if (pUser->superUser) {
100,803✔
4102
      cols = 0;
19,912✔
4103
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
19,912✔
4104
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
19,912✔
4105
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19,912✔
4106
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
19,912✔
4107

4108
      char privilege[20] = {0};
19,912✔
4109
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "all", pShow->pMeta->pSchemas[cols].bytes);
19,912✔
4110
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19,912✔
4111
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
19,912✔
4112

4113
      char objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
19,912✔
4114
      STR_WITH_MAXSIZE_TO_VARSTR(objName, "all", pShow->pMeta->pSchemas[cols].bytes);
19,912✔
4115
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19,912✔
4116
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
19,912✔
4117

4118
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
19,912✔
4119
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
19,912✔
4120
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19,912✔
4121
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
19,912✔
4122

4123
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
19,912✔
4124
      if (condition == NULL) {
19,912✔
4125
        sdbRelease(pSdb, pUser);
×
4126
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
4127
      }
4128
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
19,912✔
4129
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19,912✔
4130
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
19,912✔
4131

4132
      char notes[2] = {0};
19,912✔
4133
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
19,912✔
4134
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19,912✔
4135
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
19,912✔
4136

4137
      numOfRows++;
19,912✔
4138
    }
4139

4140
    char *db = taosHashIterate(pUser->readDbs, NULL);
100,803✔
4141
    while (db != NULL) {
120,035✔
4142
      cols = 0;
19,232✔
4143
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
19,232✔
4144
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
19,232✔
4145
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19,232✔
4146
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
19,232✔
4147

4148
      char privilege[20] = {0};
19,232✔
4149
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "read", pShow->pMeta->pSchemas[cols].bytes);
19,232✔
4150
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19,232✔
4151
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
19,232✔
4152

4153
      SName name = {0};
19,232✔
4154
      char  objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
19,232✔
4155
      code = tNameFromString(&name, db, T_NAME_ACCT | T_NAME_DB);
19,232✔
4156
      if (code < 0) {
19,232✔
4157
        sdbRelease(pSdb, pUser);
×
4158
        sdbCancelFetch(pSdb, pShow->pIter);
×
4159
        TAOS_CHECK_GOTO(code, &lino, _exit);
×
4160
      }
4161
      (void)tNameGetDbName(&name, varDataVal(objName));
19,232✔
4162
      varDataSetLen(objName, strlen(varDataVal(objName)));
19,232✔
4163
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19,232✔
4164
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
19,232✔
4165

4166
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
19,232✔
4167
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
19,232✔
4168
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19,232✔
4169
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
19,232✔
4170

4171
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
19,232✔
4172
      if (condition == NULL) {
19,232✔
4173
        sdbRelease(pSdb, pUser);
×
4174
        sdbCancelFetch(pSdb, pShow->pIter);
×
4175
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
4176
      }
4177
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
19,232✔
4178
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19,232✔
4179
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
19,232✔
4180

4181
      char notes[2] = {0};
19,232✔
4182
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
19,232✔
4183
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19,232✔
4184
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
19,232✔
4185

4186
      numOfRows++;
19,232✔
4187
      db = taosHashIterate(pUser->readDbs, db);
19,232✔
4188
    }
4189

4190
    db = taosHashIterate(pUser->writeDbs, NULL);
100,803✔
4191
    while (db != NULL) {
117,872✔
4192
      cols = 0;
17,069✔
4193
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
17,069✔
4194
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
17,069✔
4195
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
17,069✔
4196
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
17,069✔
4197

4198
      char privilege[20] = {0};
17,069✔
4199
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "write", pShow->pMeta->pSchemas[cols].bytes);
17,069✔
4200
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
17,069✔
4201
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
17,069✔
4202

4203
      SName name = {0};
17,069✔
4204
      char  objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
17,069✔
4205
      code = tNameFromString(&name, db, T_NAME_ACCT | T_NAME_DB);
17,069✔
4206
      if (code < 0) {
17,069✔
4207
        sdbRelease(pSdb, pUser);
×
4208
        sdbCancelFetch(pSdb, pShow->pIter);
×
4209
        TAOS_CHECK_GOTO(code, &lino, _exit);
×
4210
      }
4211
      (void)tNameGetDbName(&name, varDataVal(objName));
17,069✔
4212
      varDataSetLen(objName, strlen(varDataVal(objName)));
17,069✔
4213
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
17,069✔
4214
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
17,069✔
4215

4216
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
17,069✔
4217
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
17,069✔
4218
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
17,069✔
4219
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
17,069✔
4220

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

4231
      char notes[2] = {0};
17,069✔
4232
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
17,069✔
4233
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
17,069✔
4234
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
17,069✔
4235

4236
      numOfRows++;
17,069✔
4237
      db = taosHashIterate(pUser->writeDbs, db);
17,069✔
4238
    }
4239

4240
    TAOS_CHECK_EXIT(mndLoopHash(pUser->readTbs, "read", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
100,803✔
4241

4242
    TAOS_CHECK_EXIT(mndLoopHash(pUser->writeTbs, "write", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
100,803✔
4243

4244
    TAOS_CHECK_EXIT(mndLoopHash(pUser->alterTbs, "alter", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
100,803✔
4245

4246
    TAOS_CHECK_EXIT(mndLoopHash(pUser->readViews, "read", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
100,803✔
4247

4248
    TAOS_CHECK_EXIT(mndLoopHash(pUser->writeViews, "write", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
100,803✔
4249

4250
    TAOS_CHECK_EXIT(mndLoopHash(pUser->alterViews, "alter", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
100,803✔
4251

4252
    char *topic = taosHashIterate(pUser->topics, NULL);
100,803✔
4253
    while (topic != NULL) {
104,166✔
4254
      cols = 0;
3,363✔
4255
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
3,363✔
4256
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
3,363✔
4257
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
3,363✔
4258
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
3,363✔
4259

4260
      char privilege[20] = {0};
3,363✔
4261
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "subscribe", pShow->pMeta->pSchemas[cols].bytes);
3,363✔
4262
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
3,363✔
4263
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
3,363✔
4264

4265
      char topicName[TSDB_TOPIC_NAME_LEN + VARSTR_HEADER_SIZE + 5] = {0};
3,363✔
4266
      tstrncpy(varDataVal(topicName), mndGetDbStr(topic), TSDB_TOPIC_NAME_LEN - 2);
3,363✔
4267
      varDataSetLen(topicName, strlen(varDataVal(topicName)));
3,363✔
4268
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
3,363✔
4269
      COL_DATA_SET_VAL_GOTO((const char *)topicName, false, pUser, pShow->pIter, _exit);
3,363✔
4270

4271
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
3,363✔
4272
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
3,363✔
4273
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
3,363✔
4274
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
3,363✔
4275

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

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

4290
      numOfRows++;
3,363✔
4291
      topic = taosHashIterate(pUser->topics, topic);
3,363✔
4292
    }
4293

4294
    sdbRelease(pSdb, pUser);
100,803✔
4295
  }
4296

4297
  pShow->numOfRows += numOfRows;
19,912✔
4298
_exit:
19,912✔
4299
  taosMemoryFreeClear(condition);
19,912✔
4300
  taosMemoryFreeClear(sql);
19,912✔
4301
  if (code < 0) {
19,912✔
4302
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4303
    TAOS_RETURN(code);
×
4304
  }
4305
  return numOfRows;
19,912✔
4306
}
4307

4308
static void mndCancelGetNextPrivileges(SMnode *pMnode, void *pIter) {
×
4309
  SSdb *pSdb = pMnode->pSdb;
×
4310
  sdbCancelFetchByType(pSdb, pIter, SDB_USER);
×
4311
}
×
4312

4313
int32_t mndValidateUserAuthInfo(SMnode *pMnode, SUserAuthVersion *pUsers, int32_t numOfUses, void **ppRsp,
17,183,102✔
4314
                                int32_t *pRspLen, int64_t ipWhiteListVer) {
4315
  int32_t           code = 0;
17,183,102✔
4316
  int32_t           lino = 0;
17,183,102✔
4317
  int32_t           rspLen = 0;
17,183,102✔
4318
  void             *pRsp = NULL;
17,183,102✔
4319
  SUserAuthBatchRsp batchRsp = {0};
17,183,102✔
4320

4321
  batchRsp.pArray = taosArrayInit(numOfUses, sizeof(SGetUserAuthRsp));
17,183,102✔
4322
  if (batchRsp.pArray == NULL) {
17,183,102✔
4323
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
4324
  }
4325

4326
  for (int32_t i = 0; i < numOfUses; ++i) {
34,698,577✔
4327
    SUserObj *pUser = NULL;
17,515,475✔
4328
    code = mndAcquireUser(pMnode, pUsers[i].user, &pUser);
17,514,702✔
4329
    if (pUser == NULL) {
17,515,475✔
4330
      if (TSDB_CODE_MND_USER_NOT_EXIST == code) {
5,808✔
4331
        SGetUserAuthRsp rsp = {.dropped = 1};
5,808✔
4332
        (void)memcpy(rsp.user, pUsers[i].user, TSDB_USER_LEN);
5,808✔
4333
        TSDB_CHECK_NULL(taosArrayPush(batchRsp.pArray, &rsp), code, lino, _OVER, TSDB_CODE_OUT_OF_MEMORY);
11,616✔
4334
      }
4335
      mError("user:%s, failed to auth user since %s", pUsers[i].user, tstrerror(code));
5,808✔
4336
      code = 0;
5,808✔
4337
      continue;
8,276✔
4338
    }
4339

4340
    pUsers[i].version = ntohl(pUsers[i].version);
17,509,667✔
4341
    if (pUser->authVersion <= pUsers[i].version && ipWhiteListVer == pMnode->ipWhiteVer) {
17,509,667✔
4342
      mndReleaseUser(pMnode, pUser);
16,815,245✔
4343
      continue;
16,815,575✔
4344
    }
4345

4346
    SGetUserAuthRsp rsp = {0};
694,422✔
4347
    code = mndSetUserAuthRsp(pMnode, pUser, &rsp);
694,092✔
4348
    if (code) {
694,092✔
4349
      mndReleaseUser(pMnode, pUser);
×
4350
      tFreeSGetUserAuthRsp(&rsp);
×
4351
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
4352
    }
4353

4354
    if (!(taosArrayPush(batchRsp.pArray, &rsp))) {
1,388,184✔
4355
      code = terrno;
×
4356
      mndReleaseUser(pMnode, pUser);
×
4357
      tFreeSGetUserAuthRsp(&rsp);
×
4358
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
4359
    }
4360
    mndReleaseUser(pMnode, pUser);
694,092✔
4361
  }
4362

4363
  if (taosArrayGetSize(batchRsp.pArray) <= 0) {
17,183,102✔
4364
    *ppRsp = NULL;
16,500,134✔
4365
    *pRspLen = 0;
16,500,134✔
4366

4367
    tFreeSUserAuthBatchRsp(&batchRsp);
16,500,134✔
4368
    return 0;
16,500,134✔
4369
  }
4370

4371
  rspLen = tSerializeSUserAuthBatchRsp(NULL, 0, &batchRsp);
682,968✔
4372
  if (rspLen < 0) {
682,932✔
4373
    TAOS_CHECK_GOTO(rspLen, &lino, _OVER);
×
4374
  }
4375
  pRsp = taosMemoryMalloc(rspLen);
682,932✔
4376
  if (pRsp == NULL) {
682,932✔
4377
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
4378
  }
4379
  rspLen = tSerializeSUserAuthBatchRsp(pRsp, rspLen, &batchRsp);
682,932✔
4380
  if (rspLen < 0) {
682,968✔
4381
    TAOS_CHECK_GOTO(rspLen, &lino, _OVER);
×
4382
  }
4383
_OVER:
682,968✔
4384
  tFreeSUserAuthBatchRsp(&batchRsp);
682,968✔
4385
  if (code < 0) {
682,968✔
4386
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4387
    taosMemoryFreeClear(pRsp);
×
4388
    rspLen = 0;
×
4389
  }
4390
  *ppRsp = pRsp;
682,968✔
4391
  *pRspLen = rspLen;
682,968✔
4392

4393
  TAOS_RETURN(code);
682,968✔
4394
}
4395

4396
static int32_t mndRemoveDbPrivileges(SHashObj *pHash, const char *dbFName, int32_t dbFNameLen, int32_t *nRemoved) {
29,160✔
4397
  void *pVal = NULL;
29,160✔
4398
  while ((pVal = taosHashIterate(pHash, pVal))) {
51,903✔
4399
    size_t keyLen = 0;
22,743✔
4400
    char  *pKey = (char *)taosHashGetKey(pVal, &keyLen);
22,743✔
4401
    if (pKey == NULL || keyLen <= dbFNameLen) continue;
22,743✔
4402
    if ((*(pKey + dbFNameLen) == '.') && strncmp(pKey, dbFName, dbFNameLen) == 0) {
22,743✔
4403
      TAOS_CHECK_RETURN(taosHashRemove(pHash, pKey, keyLen));
11,814✔
4404
      if (nRemoved) ++(*nRemoved);
11,814✔
4405
    }
4406
  }
4407
  TAOS_RETURN(0);
29,160✔
4408
}
4409

4410
int32_t mndUserRemoveDb(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SSHashObj **ppUsers) {
718,224✔
4411
  int32_t    code = 0, lino = 0;
718,224✔
4412
  SSdb      *pSdb = pMnode->pSdb;
718,224✔
4413
  int32_t    dbLen = strlen(pDb->name);
718,224✔
4414
  void      *pIter = NULL;
718,224✔
4415
  SUserObj  *pUser = NULL;
718,224✔
4416
  SUserObj   newUser = {0};
718,224✔
4417
  SSHashObj *pUsers = ppUsers ? *ppUsers : NULL;
718,224✔
4418
  bool       output = (ppUsers != NULL);
718,224✔
4419

4420
  while (1) {
779,590✔
4421
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
1,497,814✔
4422
    if (pIter == NULL) break;
1,497,814✔
4423

4424
    bool update = false;
779,590✔
4425
    bool inReadDb = (taosHashGet(pUser->readDbs, pDb->name, dbLen + 1) != NULL);
779,590✔
4426
    bool inWriteDb = (taosHashGet(pUser->writeDbs, pDb->name, dbLen + 1) != NULL);
779,590✔
4427
    bool inUseDb = (taosHashGet(pUser->useDbs, pDb->name, dbLen + 1) != NULL);
779,590✔
4428
    bool inReadTbs = taosHashGetSize(pUser->readTbs) > 0;
779,590✔
4429
    bool inWriteTbs = taosHashGetSize(pUser->writeTbs) > 0;
779,590✔
4430
    bool inAlterTbs = taosHashGetSize(pUser->alterTbs) > 0;
779,590✔
4431
    bool inReadViews = taosHashGetSize(pUser->readViews) > 0;
779,590✔
4432
    bool inWriteViews = taosHashGetSize(pUser->writeViews) > 0;
779,590✔
4433
    bool inAlterViews = taosHashGetSize(pUser->alterViews) > 0;
779,590✔
4434
    // no need remove pUser->topics since topics must be dropped ahead of db
4435
    if (!inReadDb && !inWriteDb && !inReadTbs && !inWriteTbs && !inAlterTbs && !inReadViews && !inWriteViews &&
779,590✔
4436
        !inAlterViews) {
769,298✔
4437
      sdbRelease(pSdb, pUser);
769,298✔
4438
      continue;
769,298✔
4439
    }
4440
    SUserObj *pTargetUser = &newUser;
10,292✔
4441
    if (output) {
10,292✔
4442
      if (!pUsers) {
1,290✔
4443
        TSDB_CHECK_NULL(pUsers = tSimpleHashInit(32, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY)), code, lino,
645✔
4444
                        _exit, TSDB_CODE_OUT_OF_MEMORY);
4445
        *ppUsers = pUsers;
645✔
4446
      }
4447
      void   *pVal = NULL;
1,290✔
4448
      int32_t userLen = strlen(pUser->user) + 1;
1,290✔
4449
      if ((pVal = tSimpleHashGet(pUsers, pUser->user, userLen)) != NULL) {
1,290✔
4450
        pTargetUser = (SUserObj *)pVal;
645✔
4451
      } else {
4452
        TAOS_CHECK_EXIT(mndUserDupObj(pUser, &newUser));
645✔
4453
        TAOS_CHECK_EXIT(tSimpleHashPut(pUsers, pUser->user, userLen, &newUser, sizeof(SUserObj)));
645✔
4454
        TSDB_CHECK_NULL((pVal = tSimpleHashGet(pUsers, pUser->user, userLen)), code, lino, _exit,
645✔
4455
                        TSDB_CODE_OUT_OF_MEMORY);
4456
        pTargetUser = (SUserObj *)pVal;
645✔
4457
      }
4458
    } else {
4459
      TAOS_CHECK_EXIT(mndUserDupObj(pUser, &newUser));
9,002✔
4460
    }
4461
    if (inReadDb) {
10,292✔
4462
      TAOS_CHECK_EXIT(taosHashRemove(pTargetUser->readDbs, pDb->name, dbLen + 1));
2,588✔
4463
    }
4464
    if (inWriteDb) {
10,292✔
4465
      TAOS_CHECK_EXIT(taosHashRemove(pTargetUser->writeDbs, pDb->name, dbLen + 1));
2,225✔
4466
    }
4467
    if (inUseDb) {
10,292✔
4468
      TAOS_CHECK_EXIT(taosHashRemove(pTargetUser->useDbs, pDb->name, dbLen + 1));
1,653✔
4469
    }
4470
    update = inReadDb || inWriteDb || inUseDb;
10,292✔
4471

4472
    int32_t nRemovedReadTbs = 0;
10,292✔
4473
    int32_t nRemovedWriteTbs = 0;
10,292✔
4474
    int32_t nRemovedAlterTbs = 0;
10,292✔
4475
    if (inReadTbs || inWriteTbs || inAlterTbs) {
10,292✔
4476
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->readTbs, pDb->name, dbLen, &nRemovedReadTbs));
9,357✔
4477
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->writeTbs, pDb->name, dbLen, &nRemovedWriteTbs));
9,357✔
4478
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->alterTbs, pDb->name, dbLen, &nRemovedAlterTbs));
9,357✔
4479
      if (!update) update = nRemovedReadTbs > 0 || nRemovedWriteTbs > 0 || nRemovedAlterTbs > 0;
9,357✔
4480
    }
4481

4482
    int32_t nRemovedReadViews = 0;
10,292✔
4483
    int32_t nRemovedWriteViews = 0;
10,292✔
4484
    int32_t nRemovedAlterViews = 0;
10,292✔
4485
    if (inReadViews || inWriteViews || inAlterViews) {
10,292✔
4486
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->readViews, pDb->name, dbLen, &nRemovedReadViews));
363✔
4487
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->writeViews, pDb->name, dbLen, &nRemovedWriteViews));
363✔
4488
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->alterViews, pDb->name, dbLen, &nRemovedAlterViews));
363✔
4489
      if (!update) update = nRemovedReadViews > 0 || nRemovedWriteViews > 0 || nRemovedAlterViews > 0;
363✔
4490
    }
4491

4492
    if (!output) {
10,292✔
4493
      if (update) {
9,002✔
4494
        SSdbRaw *pCommitRaw = mndUserActionEncode(pTargetUser);
1,298✔
4495
        if (pCommitRaw == NULL) {
1,298✔
4496
          TAOS_CHECK_EXIT(terrno);
×
4497
        }
4498
        TAOS_CHECK_EXIT(mndTransAppendCommitlog(pTrans, pCommitRaw));
1,298✔
4499
        TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
1,298✔
4500
      }
4501
      mndUserFreeObj(&newUser);
9,002✔
4502
    }
4503
    sdbRelease(pSdb, pUser);
10,292✔
4504
  }
4505

4506
_exit:
718,224✔
4507
  if (code < 0) {
718,224✔
4508
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4509
    mndUserFreeObj(&newUser);
×
4510
  }
4511
  if (pUser != NULL) sdbRelease(pSdb, pUser);
718,224✔
4512
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
718,224✔
4513
  if (!output) mndUserFreeObj(&newUser);
718,224✔
4514
  TAOS_RETURN(code);
718,224✔
4515
}
4516

4517
int32_t mndUserRemoveStb(SMnode *pMnode, STrans *pTrans, char *stb) {
513,724✔
4518
  int32_t   code = 0;
513,724✔
4519
  SSdb     *pSdb = pMnode->pSdb;
513,724✔
4520
  int32_t   len = strlen(stb) + 1;
513,724✔
4521
  void     *pIter = NULL;
513,724✔
4522
  SUserObj *pUser = NULL;
513,724✔
4523
  SUserObj  newUser = {0};
513,724✔
4524

4525
  while (1) {
513,724✔
4526
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
1,027,448✔
4527
    if (pIter == NULL) break;
1,027,448✔
4528

4529
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
513,724✔
4530
      break;
×
4531
    }
4532

4533
    bool inRead = (taosHashGet(newUser.readTbs, stb, len) != NULL);
513,724✔
4534
    bool inWrite = (taosHashGet(newUser.writeTbs, stb, len) != NULL);
513,724✔
4535
    bool inAlter = (taosHashGet(newUser.alterTbs, stb, len) != NULL);
513,724✔
4536
    if (inRead || inWrite || inAlter) {
513,724✔
4537
      code = taosHashRemove(newUser.readTbs, stb, len);
×
4538
      if (code < 0) {
×
4539
        mError("failed to remove readTbs:%s from user:%s", stb, pUser->user);
×
4540
      }
4541
      code = taosHashRemove(newUser.writeTbs, stb, len);
×
4542
      if (code < 0) {
×
4543
        mError("failed to remove writeTbs:%s from user:%s", stb, pUser->user);
×
4544
      }
4545
      code = taosHashRemove(newUser.alterTbs, stb, len);
×
4546
      if (code < 0) {
×
4547
        mError("failed to remove alterTbs:%s from user:%s", stb, pUser->user);
×
4548
      }
4549

4550
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
×
4551
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
×
4552
        code = TSDB_CODE_OUT_OF_MEMORY;
×
4553
        break;
×
4554
      }
4555
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
×
4556
      if (code != 0) {
×
4557
        mndUserFreeObj(&newUser);
×
4558
        sdbRelease(pSdb, pUser);
×
4559
        TAOS_RETURN(code);
×
4560
      }
4561
    }
4562

4563
    mndUserFreeObj(&newUser);
513,724✔
4564
    sdbRelease(pSdb, pUser);
513,724✔
4565
  }
4566

4567
  if (pUser != NULL) sdbRelease(pSdb, pUser);
513,724✔
4568
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
513,724✔
4569
  mndUserFreeObj(&newUser);
513,724✔
4570
  TAOS_RETURN(code);
513,724✔
4571
}
4572

4573
int32_t mndUserRemoveView(SMnode *pMnode, STrans *pTrans, char *view) {
178,218✔
4574
  int32_t   code = 0;
178,218✔
4575
  SSdb     *pSdb = pMnode->pSdb;
178,218✔
4576
  int32_t   len = strlen(view) + 1;
178,218✔
4577
  void     *pIter = NULL;
178,218✔
4578
  SUserObj *pUser = NULL;
178,218✔
4579
  SUserObj  newUser = {0};
178,218✔
4580

4581
  while (1) {
185,490✔
4582
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
363,708✔
4583
    if (pIter == NULL) break;
363,708✔
4584

4585
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
185,490✔
4586
      break;
×
4587
    }
4588

4589
    bool inRead = (taosHashGet(newUser.readViews, view, len) != NULL);
185,490✔
4590
    bool inWrite = (taosHashGet(newUser.writeViews, view, len) != NULL);
185,490✔
4591
    bool inAlter = (taosHashGet(newUser.alterViews, view, len) != NULL);
185,490✔
4592
    if (inRead || inWrite || inAlter) {
185,490✔
4593
      code = taosHashRemove(newUser.readViews, view, len);
4,524✔
4594
      if (code < 0) {
4,524✔
4595
        mError("failed to remove readViews:%s from user:%s", view, pUser->user);
900✔
4596
      }
4597
      code = taosHashRemove(newUser.writeViews, view, len);
4,524✔
4598
      if (code < 0) {
4,524✔
4599
        mError("failed to remove writeViews:%s from user:%s", view, pUser->user);
2,274✔
4600
      }
4601
      code = taosHashRemove(newUser.alterViews, view, len);
4,524✔
4602
      if (code < 0) {
4,524✔
4603
        mError("failed to remove alterViews:%s from user:%s", view, pUser->user);
1,374✔
4604
      }
4605

4606
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
4,524✔
4607
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
4,524✔
4608
        code = TSDB_CODE_OUT_OF_MEMORY;
×
4609
        break;
×
4610
      }
4611
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
4,524✔
4612
      if (code < 0) {
4,524✔
4613
        mndUserFreeObj(&newUser);
×
4614
        sdbRelease(pSdb, pUser);
×
4615
        TAOS_RETURN(code);
×
4616
      }
4617
    }
4618

4619
    mndUserFreeObj(&newUser);
185,490✔
4620
    sdbRelease(pSdb, pUser);
185,490✔
4621
  }
4622

4623
  if (pUser != NULL) sdbRelease(pSdb, pUser);
178,218✔
4624
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
178,218✔
4625
  mndUserFreeObj(&newUser);
178,218✔
4626
  TAOS_RETURN(code);
178,218✔
4627
}
4628

4629
int32_t mndUserRemoveTopic(SMnode *pMnode, STrans *pTrans, char *topic) {
31,691✔
4630
  int32_t   code = 0;
31,691✔
4631
  SSdb     *pSdb = pMnode->pSdb;
31,691✔
4632
  int32_t   len = strlen(topic) + 1;
31,691✔
4633
  void     *pIter = NULL;
31,691✔
4634
  SUserObj *pUser = NULL;
31,691✔
4635
  SUserObj  newUser = {0};
31,691✔
4636

4637
  while (1) {
46,289✔
4638
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
77,980✔
4639
    if (pIter == NULL) {
77,980✔
4640
      break;
31,691✔
4641
    }
4642

4643
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
46,289✔
4644
      break;
×
4645
    }
4646

4647
    bool inTopic = (taosHashGet(newUser.topics, topic, len) != NULL);
46,289✔
4648
    if (inTopic) {
46,289✔
4649
      code = taosHashRemove(newUser.topics, topic, len);
363✔
4650
      if (code < 0) {
363✔
4651
        mError("failed to remove topic:%s from user:%s", topic, pUser->user);
×
4652
      }
4653
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
363✔
4654
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
363✔
4655
        code = TSDB_CODE_OUT_OF_MEMORY;
×
4656
        break;
×
4657
      }
4658
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
363✔
4659
      if (code < 0) {
363✔
4660
        mndUserFreeObj(&newUser);
×
4661
        sdbRelease(pSdb, pUser);
×
4662
        TAOS_RETURN(code);
×
4663
      }
4664
    }
4665

4666
    mndUserFreeObj(&newUser);
46,289✔
4667
    sdbRelease(pSdb, pUser);
46,289✔
4668
  }
4669

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

4676
int64_t mndGetUserIpWhiteListVer(SMnode *pMnode, SUserObj *pUser) {
×
4677
  // ver = 0, disable ip white list
4678
  // ver > 0, enable ip white list
4679
  return tsEnableWhiteList ? pUser->ipWhiteListVer : 0;
×
4680
}
4681

4682
int64_t mndGetUserTimeWhiteListVer(SMnode *pMnode, SUserObj *pUser) {
×
4683
  // ver = 0, disable datetime white list
4684
  // ver > 0, enable datetime white list
4685
  return tsEnableWhiteList ? pUser->timeWhiteListVer : 0;
×
4686
}
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