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

taosdata / TDengine / #5048

10 May 2026 03:11AM UTC coverage: 73.222% (+0.07%) from 73.152%
#5048

push

travis-ci

web-flow
merge: from main to 3.0 branch #35290

353 of 452 new or added lines in 9 files covered. (78.1%)

587 existing lines in 140 files now uncovered.

278189 of 379928 relevant lines covered (73.22%)

135206397.85 hits per line

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

66.06
/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 "mndCluster.h"
23
#include "mndSecurityPolicy.h"
24
#include "mndRole.h"
25
#include "mndUser.h"
26
#include "audit.h"
27
#include "mndDb.h"
28
#include "mndMnode.h"
29
#include "mndPrivilege.h"
30
#include "mndShow.h"
31
#include "mndStb.h"
32
#include "mndSync.h" 
33
#include "mndTopic.h"
34
#include "mndTrans.h"
35
#include "mndToken.h"
36
#include "tbase64.h"
37
#include "totp.h"
38
#include "mndDnode.h"
39
#include "mndVgroup.h"
40

41
// clang-format on
42

43
#define USER_VER_SUPPORT_WHITELIST           5
44
#define USER_VER_SUPPORT_WHITELIT_DUAL_STACK 7
45
#define USER_VER_SUPPORT_ADVANCED_SECURITY   8
46
#define USER_VER_NUMBER                      USER_VER_SUPPORT_ADVANCED_SECURITY
47

48
#define USER_RESERVE_SIZE 63
49

50
#define BIT_FLAG_MASK(n)              (1 << n)
51
#define BIT_FLAG_SET_MASK(val, mask)  ((val) |= (mask))
52
#define BIT_FLAG_TEST_MASK(val, mask) (((val) & (mask)) != 0)
53

54
#if 0
55
#define PRIVILEGE_TYPE_ALL       BIT_FLAG_MASK(0)
56
#define PRIVILEGE_TYPE_READ      BIT_FLAG_MASK(1)
57
#define PRIVILEGE_TYPE_WRITE     BIT_FLAG_MASK(2)
58
#define PRIVILEGE_TYPE_SUBSCRIBE BIT_FLAG_MASK(3)
59
#define PRIVILEGE_TYPE_ALTER     BIT_FLAG_MASK(4)
60
#endif
61

62
#define ALTER_USER_ADD_PRIVS(_type) ((_type) == TSDB_ALTER_USER_ADD_PRIVILEGES)
63
#define ALTER_USER_DEL_PRIVS(_type) ((_type) == TSDB_ALTER_USER_DEL_PRIVILEGES)
64

65
#if 0
66
#define ALTER_USER_ALL_PRIV(_priv)       (PRIV_HAS((_priv), PRIV_CM_ALL))
67
#define ALTER_USER_READ_PRIV(_priv)      (PRIV_HAS((_priv), PRIV_CM_READ) || PRIV_HAS((_priv), PRIV_CM_ALL))
68
#define ALTER_USER_WRITE_PRIV(_priv)     (PRIV_HAS((_priv), PRIV_CM_WRITE) || PRIV_HAS((_priv), PRIV_CM_ALL))
69
#define ALTER_USER_ALTER_PRIV(_priv)     (PRIV_HAS((_priv), PRIV_CM_ALTER) || PRIV_HAS((_priv), PRIV_CM_ALL))
70
#define ALTER_USER_SUBSCRIBE_PRIV(_priv) (PRIV_HAS((_priv), PRIV_TOPIC_SUBSCRIBE))
71

72
#define ALTER_USER_TARGET_DB(_tbname) (0 == (_tbname)[0])
73
#define ALTER_USER_TARGET_TB(_tbname) (0 != (_tbname)[0])
74

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

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

109
#define ALTER_USER_ADD_SUBSCRIBE_TOPIC_PRIV(_type, _priv) \
110
  (ALTER_USER_ADD_PRIVS(_type) && ALTER_USER_SUBSCRIBE_PRIV(_priv))
111
#define ALTER_USER_DEL_SUBSCRIBE_TOPIC_PRIV(_type, _priv) \
112
  (ALTER_USER_DEL_PRIVS(_type) && ALTER_USER_SUBSCRIBE_PRIV(_priv))
113
#endif
114

115
#ifdef TD_ENTERPRISE
116
extern int32_t mndAlterUserPrivInfo(SMnode *pMnode, SUserObj *pNew, SAlterRoleReq *pAlterReq);
117
extern int32_t mndAlterUserRoleInfo(SMnode *pMnode, SUserObj *pOperUser, const char *token, SUserObj *pOld,
118
                                    SUserObj *pNew, SAlterRoleReq *pAlterReq);
119
#endif
120

121
static void generateSalt(char *salt, size_t len);
122

123
static int32_t createDefaultIpWhiteList(SIpWhiteListDual **ppWhiteList);
124
static int32_t createIpWhiteList(void *buf, int32_t len, SIpWhiteListDual **ppWhiteList, bool supportNeg);
125

126
static bool isIpWhiteListEqual(SIpWhiteListDual *a, SIpWhiteListDual *b);
127
static bool isIpRangeEqual(SIpRange *a, SIpRange *b);
128

129
#define MND_MAX_USER_IP_RANGE   (TSDB_PRIVILEDGE_HOST_LEN / 24)
130
#define MND_MAX_USER_TIME_RANGE 2048
131

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

153
static int32_t mndProcessGetUserIpWhiteListReq(SRpcMsg *pReq);
154
static int32_t mndProcessRetrieveIpWhiteListReq(SRpcMsg *pReq);
155
static int32_t mndProcessGetUserDateTimeWhiteListReq(SRpcMsg *pReq);
156
static int32_t mndProcessRetrieveDateTimeWhiteListReq(SRpcMsg *pReq);
157
static int32_t mndProcessCreateTotpSecretReq(SRpcMsg *pReq);
158
static int32_t mndProcessDropTotpSecretReq(SRpcMsg *pReq);
159

160
static int32_t createIpWhiteListFromOldVer(void *buf, int32_t len, SIpWhiteList **ppList);
161
static int32_t tDerializeIpWhileListFromOldVer(void *buf, int32_t len, SIpWhiteList *pList);
162

163
typedef struct {
164
  SIpWhiteListDual   *wlIp;
165
  SDateTimeWhiteList *wlTime;
166
  SLoginInfo          loginInfo;
167
} SCachedUserInfo;
168

169
typedef struct {
170
  SHashObj      *users;  // key: user, value: SCachedUserInfo*
171
  int64_t        verIp;
172
  int64_t        verTime;
173
  char           auditLogUser[TSDB_USER_LEN];
174
  TdThreadRwlock rw;
175
} SUserCache;
176

177
static SUserCache userCache;
178
static int8_t     upgradeSecurity = 0;
179

180
static int32_t userCacheInit() {
514,757✔
181
  _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
514,757✔
182

183
  SHashObj *users = taosHashInit(8, hashFn, 1, HASH_ENTRY_LOCK);
514,757✔
184
  if (users == NULL) {
514,757✔
185
    TAOS_RETURN(terrno);
×
186
  }
187

188
  userCache.users = users;
514,757✔
189
  userCache.verIp = 0;
514,757✔
190
  userCache.verTime = 0;
514,757✔
191
  userCache.auditLogUser[0] = '\0';
514,757✔
192

193
  (void)taosThreadRwlockInit(&userCache.rw, NULL);
514,757✔
194
  TAOS_RETURN(0);
514,757✔
195
}
196

197
static void userCacheCleanup() {
514,689✔
198
  if (userCache.users == NULL) {
514,689✔
199
    return;
×
200
  }
201

202
  void *pIter = taosHashIterate(userCache.users, NULL);
514,689✔
203
  while (pIter) {
1,052,053✔
204
    SCachedUserInfo *pInfo = *(SCachedUserInfo **)pIter;
537,364✔
205
    if (pInfo != NULL) {
537,364✔
206
      taosMemoryFree(pInfo->wlIp);
537,364✔
207
      taosMemoryFree(pInfo->wlTime);
537,364✔
208
      taosMemoryFree(pInfo);
537,364✔
209
    }
210
    pIter = taosHashIterate(userCache.users, pIter);
537,364✔
211
  }
212
  taosHashCleanup(userCache.users);
514,689✔
213

214
  (void)taosThreadRwlockDestroy(&userCache.rw);
514,689✔
215
}
216

217
static void userCacheRemoveUser(const char *user) {
56,969✔
218
  size_t userLen = strlen(user);
56,969✔
219

220
  (void)taosThreadRwlockWrlock(&userCache.rw);
56,969✔
221

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

236
  (void)taosThreadRwlockUnlock(&userCache.rw);
56,969✔
237
}
56,969✔
238

239
static void userCacheResetLoginInfo(const char *user) {
1,331✔
240
  size_t userLen = strlen(user);
1,331✔
241

242
  (void)taosThreadRwlockWrlock(&userCache.rw);
1,331✔
243

244
  SCachedUserInfo **ppInfo = taosHashGet(userCache.users, user, userLen);
1,331✔
245
  if (ppInfo != NULL && *ppInfo != NULL) {
1,331✔
246
    (*ppInfo)->loginInfo.lastLoginTime = taosGetTimestampSec();
1,331✔
247
    (*ppInfo)->loginInfo.failedLoginCount = 0;
1,331✔
248
    (*ppInfo)->loginInfo.lastFailedLoginTime = 0;
1,331✔
249
  }
250

251
  (void)taosThreadRwlockUnlock(&userCache.rw);
1,331✔
252
}
1,331✔
253

254
static SCachedUserInfo *getCachedUserInfo(const char *user) {
5,278,391✔
255
  size_t            userLen = strlen(user);
5,278,391✔
256
  SCachedUserInfo **ppInfo = taosHashGet(userCache.users, user, userLen);
5,278,391✔
257
  if (ppInfo != NULL) {
5,278,391✔
258
    return *ppInfo;
4,684,058✔
259
  }
260

261
  SCachedUserInfo *pInfo = (SCachedUserInfo *)taosMemoryCalloc(1, sizeof(SCachedUserInfo));
594,333✔
262
  if (pInfo == NULL) {
594,333✔
263
    return NULL;
×
264
  }
265

266
  if (taosHashPut(userCache.users, user, userLen, &pInfo, sizeof(pInfo)) != 0) {
594,333✔
267
    taosMemoryFree(pInfo);
×
268
    return NULL;
×
269
  }
270

271
  return pInfo;
594,333✔
272
}
273

274
void mndGetUserLoginInfo(const char *user, SLoginInfo *pLoginInfo) {
3,160,638✔
275
  size_t userLen = strlen(user);
3,160,638✔
276

277
  (void)taosThreadRwlockRdlock(&userCache.rw);
3,160,638✔
278

279
  SCachedUserInfo **ppInfo = taosHashGet(userCache.users, user, userLen);
3,161,068✔
280
  if (ppInfo != NULL && *ppInfo != NULL) {
3,160,903✔
281
    pLoginInfo->lastLoginTime = (*ppInfo)->loginInfo.lastLoginTime;
2,799,388✔
282
    pLoginInfo->failedLoginCount = (*ppInfo)->loginInfo.failedLoginCount;
2,799,450✔
283
    pLoginInfo->lastFailedLoginTime = (*ppInfo)->loginInfo.lastFailedLoginTime;
2,799,478✔
284
  } else {
285
    pLoginInfo->lastLoginTime = taosGetTimestampSec();
361,558✔
286
    pLoginInfo->failedLoginCount = 0;
361,515✔
287
    pLoginInfo->lastFailedLoginTime = 0;
361,515✔
288
  }
289

290
  (void)taosThreadRwlockUnlock(&userCache.rw);
3,160,893✔
291

292
  if (pLoginInfo->lastLoginTime == 0) {
3,161,068✔
293
    pLoginInfo->lastLoginTime = taosGetTimestampSec();
72,413✔
294
  }
295
}
3,161,025✔
296

297
void mndSetUserLoginInfo(const char *user, const SLoginInfo *pLoginInfo) {
3,153,759✔
298
  size_t userLen = strlen(user);
3,153,759✔
299

300
  (void)taosThreadRwlockWrlock(&userCache.rw);
3,153,759✔
301

302
  SCachedUserInfo *pInfo = getCachedUserInfo(user);
3,153,802✔
303
  if (pInfo != NULL) {
3,153,802✔
304
    pInfo->loginInfo.lastLoginTime = pLoginInfo->lastLoginTime;
3,153,802✔
305
    pInfo->loginInfo.failedLoginCount = pLoginInfo->failedLoginCount;
3,153,802✔
306
    pInfo->loginInfo.lastFailedLoginTime = pLoginInfo->lastFailedLoginTime;
3,153,802✔
307
  }
308

309
  (void)taosThreadRwlockUnlock(&userCache.rw);
3,153,802✔
310
}
3,153,802✔
311

312
static bool isDateTimeWhiteListEqual(SDateTimeWhiteList *a, SDateTimeWhiteList *b) {
1,653,913✔
313
  if (a == NULL && b == NULL) {
1,653,913✔
314
    return true;
×
315
  }
316

317
  if (a == NULL || b == NULL) {
1,653,913✔
318
    return false;
104,278✔
319
  }
320

321
  if (a->num != b->num) {
1,549,635✔
322
    return false;
338✔
323
  }
324

325
  for (int i = 0; i < a->num; i++) {
1,549,804✔
326
    if (a->ranges[i].start != b->ranges[i].start || a->ranges[i].duration != b->ranges[i].duration ||
845✔
327
        a->ranges[i].neg != b->ranges[i].neg || a->ranges[i].absolute != b->ranges[i].absolute) {
507✔
328
      return false;
338✔
329
    }
330
  }
331

332
  return true;
1,548,959✔
333
}
334

335
static int32_t userCacheUpdateWhiteList(SMnode *pMnode, SUserObj *pUser) {
1,653,913✔
336
  int32_t code = 0, lino = 0;
1,653,913✔
337

338
  (void)taosThreadRwlockWrlock(&userCache.rw);
1,653,913✔
339

340
  SCachedUserInfo *pInfo = getCachedUserInfo(pUser->user);
1,653,913✔
341
  if (pInfo == NULL) {
1,653,913✔
342
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
343
  }
344

345
  if (!isIpWhiteListEqual(pInfo->wlIp, pUser->pIpWhiteListDual)) {
1,653,913✔
346
    SIpWhiteListDual *p = cloneIpWhiteList(pUser->pIpWhiteListDual);
105,127✔
347
    if (p == NULL) {
105,127✔
348
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
349
    }
350
    taosMemoryFree(pInfo->wlIp);
105,127✔
351
    pInfo->wlIp = p;
105,127✔
352
    userCache.verIp++;
105,127✔
353
  }
354

355
  if (!isDateTimeWhiteListEqual(pInfo->wlTime, pUser->pTimeWhiteList)) {
1,653,913✔
356
    SDateTimeWhiteList *p = cloneDateTimeWhiteList(pUser->pTimeWhiteList);
104,954✔
357
    if (p == NULL) {
104,954✔
358
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
359
    }
360
    taosMemoryFree(pInfo->wlTime);
104,954✔
361
    pInfo->wlTime = p;
104,954✔
362
    userCache.verTime++;
104,954✔
363
  }
364

365
_OVER:
1,653,913✔
366
  (void)taosThreadRwlockUnlock(&userCache.rw);
1,653,913✔
367
  if (code < 0) {
1,653,913✔
368
    mError("failed to update white list for user: %s at line %d since %s", pUser->user, lino, tstrerror(code));
×
369
  }
370
  TAOS_RETURN(code);
1,653,913✔
371
}
372

373
static int32_t userCacheRebuildIpWhiteList(SMnode *pMnode) {
623,453✔
374
  int32_t code = 0, lino = 0;
623,453✔
375

376
  SSdb *pSdb = pMnode->pSdb;
623,453✔
377
  void *pIter = NULL;
623,453✔
378
  while (1) {
240,650✔
379
    SUserObj *pUser = NULL;
864,103✔
380
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
864,103✔
381
    if (pIter == NULL) {
864,103✔
382
      break;
623,453✔
383
    }
384

385
    SCachedUserInfo *pInfo = getCachedUserInfo(pUser->user);
240,650✔
386
    if (pInfo == NULL) {
240,650✔
387
      sdbRelease(pSdb, pUser);
×
388
      sdbCancelFetch(pSdb, pIter);
×
389
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
390
    }
391

392
    SIpWhiteListDual *wl = cloneIpWhiteList(pUser->pIpWhiteListDual);
240,650✔
393
    if (wl == NULL) {
240,650✔
394
      sdbRelease(pSdb, pUser);
×
395
      sdbCancelFetch(pSdb, pIter);
×
396
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
397
    }
398

399
    taosMemoryFree(pInfo->wlIp);
240,650✔
400
    pInfo->wlIp = wl;
240,650✔
401

402
    sdbRelease(pSdb, pUser);
240,650✔
403
  }
404

405
  userCache.verIp++;
623,453✔
406

407
_OVER:
623,453✔
408
  if (code < 0) {
623,453✔
409
    mError("failed to rebuild ip white list at line %d since %s", lino, tstrerror(code));
×
410
  }
411
  TAOS_RETURN(code);
623,453✔
412
}
413

414
int64_t mndGetIpWhiteListVersion(SMnode *pMnode) {
56,672,265✔
415
  int64_t ver = 0;
56,672,265✔
416
  int32_t code = 0;
56,672,265✔
417

418
  if (mndEnableIpWhiteList(pMnode) != 0 && tsEnableWhiteList) {
56,672,265✔
419
    (void)taosThreadRwlockWrlock(&userCache.rw);
4,299✔
420

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

432
    (void)taosThreadRwlockUnlock(&userCache.rw);
4,299✔
433
  }
434

435
  mDebug("ip-white-list on mnode ver: %" PRId64, ver);
56,672,265✔
436
  return ver;
56,672,265✔
437
}
438

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

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

450
  TAOS_RETURN(code);
623,453✔
451
}
452

453
static int32_t userCacheRebuildTimeWhiteList(SMnode *pMnode) {
613,151✔
454
  int32_t code = 0, lino = 0;
613,151✔
455

456
  SSdb *pSdb = pMnode->pSdb;
613,151✔
457
  void *pIter = NULL;
613,151✔
458
  while (1) {
230,026✔
459
    SUserObj *pUser = NULL;
843,177✔
460
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
843,177✔
461
    if (pIter == NULL) {
843,177✔
462
      break;
613,151✔
463
    }
464

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

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

479
    taosMemoryFree(pInfo->wlTime);
230,026✔
480
    pInfo->wlTime = wl;
230,026✔
481

482
    sdbRelease(pSdb, pUser);
230,026✔
483
  }
484

485
  userCache.verTime++;
613,151✔
486

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

494
int32_t mndRefreshUserDateTimeWhiteList(SMnode *pMnode) {
613,151✔
495
  int32_t code = 0;
613,151✔
496
  (void)taosThreadRwlockWrlock(&userCache.rw);
613,151✔
497

498
  if ((code = userCacheRebuildTimeWhiteList(pMnode)) != 0) {
613,151✔
499
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
500
    TAOS_RETURN(code);
×
501
  }
502
  userCache.verTime = taosGetTimestampMs();
613,151✔
503
  (void)taosThreadRwlockUnlock(&userCache.rw);
613,151✔
504

505
  TAOS_RETURN(code);
613,151✔
506
}
507

508
int64_t mndGetTimeWhiteListVersion(SMnode *pMnode) {
56,672,265✔
509
  int64_t ver = 0;
56,672,265✔
510
  int32_t code = 0;
56,672,265✔
511

512
  if (mndEnableTimeWhiteList(pMnode) != 0 && tsEnableWhiteList) {
56,672,265✔
513
    (void)taosThreadRwlockWrlock(&userCache.rw);
4,299✔
514

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

526
    (void)taosThreadRwlockUnlock(&userCache.rw);
4,299✔
527
  }
528

529
  mDebug("datetime-white-list on mnode ver: %" PRId64, ver);
56,672,265✔
530
  return ver;
56,672,265✔
531
}
532

533
int32_t mndInitUser(SMnode *pMnode) {
514,757✔
534
  TAOS_CHECK_RETURN(userCacheInit());
514,757✔
535

536
  SSdbTable table = {
514,757✔
537
      .sdbType = SDB_USER,
538
      .keyType = SDB_KEY_BINARY,
539
      .deployFp = (SdbDeployFp)mndCreateDefaultUsers,
540
      .upgradeFp = (SdbUpgradeFp)mndUpgradeUsers,
541
      .encodeFp = (SdbEncodeFp)mndUserActionEncode,
542
      .decodeFp = (SdbDecodeFp)mndUserActionDecode,
543
      .insertFp = (SdbInsertFp)mndUserActionInsert,
544
      .updateFp = (SdbUpdateFp)mndUserActionUpdate,
545
      .deleteFp = (SdbDeleteFp)mndUserActionDelete,
546
  };
547

548
  mndSetMsgHandle(pMnode, TDMT_MND_CREATE_USER, mndProcessCreateUserReq);
514,757✔
549
  mndSetMsgHandle(pMnode, TDMT_MND_ALTER_USER, mndProcessAlterUserReq);
514,757✔
550
  mndSetMsgHandle(pMnode, TDMT_MND_DROP_USER, mndProcessDropUserReq);
514,757✔
551
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_AUTH, mndProcessGetUserAuthReq);
514,757✔
552
  mndSetMsgHandle(pMnode, TDMT_MND_UPGRADE_USER, mndProcessUpgradeUserReq);
514,757✔
553
  mndSetMsgHandle(pMnode, TDMT_MND_UPGRADE_USER_RSP, mndProcessUpgradeUserRsp);
514,757✔
554

555
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_IP_WHITELIST, mndProcessGetUserIpWhiteListReq);
514,757✔
556
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_IP_WHITELIST_DUAL, mndProcessGetUserIpWhiteListReq);
514,757✔
557
  mndSetMsgHandle(pMnode, TDMT_MND_RETRIEVE_IP_WHITELIST, mndProcessRetrieveIpWhiteListReq);
514,757✔
558
  mndSetMsgHandle(pMnode, TDMT_MND_RETRIEVE_IP_WHITELIST_DUAL, mndProcessRetrieveIpWhiteListReq);
514,757✔
559
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_DATETIME_WHITELIST, mndProcessGetUserDateTimeWhiteListReq);
514,757✔
560
  mndSetMsgHandle(pMnode, TDMT_MND_RETRIEVE_DATETIME_WHITELIST, mndProcessRetrieveDateTimeWhiteListReq);
514,757✔
561

562
  mndSetMsgHandle(pMnode, TDMT_MND_CREATE_TOTP_SECRET, mndProcessCreateTotpSecretReq);
514,757✔
563
  mndSetMsgHandle(pMnode, TDMT_MND_DROP_TOTP_SECRET, mndProcessDropTotpSecretReq);
514,757✔
564

565
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_USER, mndRetrieveUsers);
514,757✔
566
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_USER, mndCancelGetNextUser);
514,757✔
567
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_USER_FULL, mndRetrieveUsersFull);
514,757✔
568
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_USER_FULL, mndCancelGetNextUser);
514,757✔
569
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_PRIVILEGES, mndRetrievePrivileges);
514,757✔
570
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_PRIVILEGES, mndCancelGetNextPrivileges);
514,757✔
571
  return sdbSetTable(pMnode->pSdb, table);
514,757✔
572
}
573

574
void mndCleanupUser(SMnode *pMnode) { userCacheCleanup(); }
514,689✔
575

576
static bool isDefaultRange(SIpRange *pRange) {
×
577
  int32_t code = 0;
×
578
  int32_t lino = 0;
×
579

580
  SIpRange range4 = {0};
×
581
  SIpRange range6 = {0};
×
582

583
  code = createDefaultIp4Range(&range4);
×
584
  TSDB_CHECK_CODE(code, lino, _error);
×
585

586
  code = createDefaultIp6Range(&range6);
×
587
  TSDB_CHECK_CODE(code, lino, _error);
×
588

589
  if (isIpRangeEqual(pRange, &range4) || (isIpRangeEqual(pRange, &range6))) {
×
590
    return true;
×
591
  }
592
_error:
×
593
  return false;
×
594
};
595

596
static int32_t ipRangeListToStr(SIpRange *range, int32_t num, char *buf, int64_t bufLen) {
1,762,545✔
597
  int32_t len = 0;
1,762,545✔
598
  for (int i = 0; i < num; i++) {
5,330,266✔
599
    SIpRange *pRange = &range[i];
3,567,721✔
600
    SIpAddr   addr = {0};
3,567,721✔
601
    int32_t   code = tIpUintToStr(pRange, &addr);
3,567,721✔
602
    if (code != 0) {
3,567,721✔
603
      mError("%s failed to convert ip range to str, code: %d", __func__, code);
×
604
    }
605

606
    len += snprintf(buf + len, bufLen - len, "%c%s/%d, ", pRange->neg ? '-' : '+', IP_ADDR_STR(&addr), addr.mask);
3,567,721✔
607
  }
608
  if (len > 0) {
1,762,545✔
609
    len -= 2;
1,762,545✔
610
    buf[len] = 0; // remove last ", "
1,762,545✔
611
  }
612
  return len;
1,762,545✔
613
}
614

615
static bool isIpRangeEqual(SIpRange *a, SIpRange *b) {
3,098,445✔
616
  if (a->type != b->type || a->neg != b->neg) {
3,098,445✔
617
    return false;
×
618
  }
619

620
  if (a->type == 0) {
3,098,445✔
621
    SIpV4Range *a4 = &a->ipV4;
1,549,659✔
622
    SIpV4Range *b4 = &b->ipV4;
1,549,659✔
623
    return (a4->ip == b4->ip && a4->mask == b4->mask);
1,549,659✔
624
  }
625

626
  SIpV6Range *a6 = &a->ipV6;
1,548,786✔
627
  SIpV6Range *b6 = &b->ipV6;
1,548,786✔
628
  return (a6->addr[0] == b6->addr[0] && a6->addr[1] == b6->addr[1] && a6->mask == b6->mask);
1,548,786✔
629
}
630

631
static bool isIpWhiteListEqual(SIpWhiteListDual *a, SIpWhiteListDual *b) {
1,653,913✔
632
  if (a == NULL && b == NULL) {
1,653,913✔
633
    return true;
×
634
  }
635

636
  if (a == NULL || b == NULL) {
1,653,913✔
637
    return false;
104,278✔
638
  }
639

640
  if (a->num != b->num) {
1,549,635✔
641
    return false;
849✔
642
  }
643
  for (int i = 0; i < a->num; i++) {
4,647,231✔
644
    if (!isIpRangeEqual(&a->pIpRanges[i], &b->pIpRanges[i])) {
3,098,445✔
645
      return false;
×
646
    }
647
  }
648
  return true;
1,548,786✔
649
}
650

651
static int32_t compareIpRange(const void *a, const void *b, const void *arg) {
7,622✔
652
  SIpRange *ra = (SIpRange *)a;
7,622✔
653
  SIpRange *rb = (SIpRange *)b;
7,622✔
654

655
  if (ra->neg != rb->neg) {
7,622✔
656
    return (ra->neg) ? -1 : 1;
845✔
657
  }
658

659
  if (ra->type != rb->type) {
6,777✔
660
    return (ra->type == 0) ? -1 : 1;
2,473✔
661
  }
662

663
  if (ra->type == 0) {
4,304✔
664
    if (ra->ipV4.ip != rb->ipV4.ip) {
4,304✔
665
      return (ra->ipV4.ip < rb->ipV4.ip) ? -1 : 1;
3,910✔
666
    }
667
    return (ra->ipV4.mask < rb->ipV4.mask) ? -1 : 1;
394✔
668
  }
669

670
  if (ra->ipV6.addr[0] != rb->ipV6.addr[0]) {
×
671
    return (ra->ipV6.addr[0] < rb->ipV6.addr[0]) ? -1 : 1;
×
672
  }
673
  if (ra->ipV6.addr[1] != rb->ipV6.addr[1]) {
×
674
    return (ra->ipV6.addr[1] < rb->ipV6.addr[1]) ? -1 : 1;
×
675
  }
676
  return (ra->ipV6.mask < rb->ipV6.mask) ? -1 : 1;
×
677
}
678

679
static void sortIpWhiteList(SIpWhiteListDual *pList) {
2,980✔
680
  (void)taosqsort(pList->pIpRanges, pList->num, sizeof(SIpRange), NULL, compareIpRange);
2,980✔
681
}
2,980✔
682

683
static int32_t convertIpWhiteListToStr(SUserObj *pUser, char **buf) {
1,762,545✔
684
  SIpWhiteListDual *pList = pUser->pIpWhiteListDual;
1,762,545✔
685

686
  int64_t bufLen = pList->num * 128 + 8;
1,762,545✔
687
  *buf = taosMemoryCalloc(1, bufLen);
1,762,545✔
688
  if (*buf == NULL) {
1,762,545✔
689
    return 0;
×
690
  }
691

692
  if (pList->num == 0) {
1,762,545✔
693
    return snprintf(*buf, bufLen, "+ALL");
×
694
  }
695

696
  int32_t len = ipRangeListToStr(pList->pIpRanges, pList->num, *buf, bufLen - 2);
1,762,545✔
697
  if (len == 0) {
1,762,545✔
698
    taosMemoryFreeClear(*buf);
×
699
    return 0;
×
700
  }
701
  return len;
1,762,545✔
702
}
703

704
static int32_t tSerializeIpWhiteList(void *buf, int32_t len, SIpWhiteListDual *pList, uint32_t *pLen) {
4,780,164✔
705
  int32_t  code = 0;
4,780,164✔
706
  int32_t  lino = 0;
4,780,164✔
707
  int32_t  tlen = 0;
4,780,164✔
708
  SEncoder encoder = {0};
4,780,164✔
709
  tEncoderInit(&encoder, buf, len);
4,780,164✔
710

711
  TAOS_CHECK_GOTO(tStartEncode(&encoder), &lino, _OVER);
4,780,164✔
712
  TAOS_CHECK_GOTO(tEncodeI32(&encoder, pList->num), &lino, _OVER);
9,560,328✔
713

714
  for (int i = 0; i < pList->num; i++) {
14,346,486✔
715
    SIpRange *pRange = &(pList->pIpRanges[i]);
9,566,322✔
716
    TAOS_CHECK_GOTO(tSerializeIpRange(&encoder, pRange), &lino, _OVER);
9,566,322✔
717
  }
718

719
  tEndEncode(&encoder);
4,780,164✔
720

721
  tlen = encoder.pos;
4,780,164✔
722
_OVER:
4,780,164✔
723
  tEncoderClear(&encoder);
4,780,164✔
724
  if (code < 0) {
4,780,164✔
725
    mError("failed to serialize ip white list at line %d since %s", lino, tstrerror(code));
×
726
  }
727
  if (pLen) *pLen = tlen;
4,780,164✔
728
  TAOS_RETURN(code);
4,780,164✔
729
}
730

731
static int32_t tDerializeIpWhiteList(void *buf, int32_t len, SIpWhiteListDual *pList, bool supportNeg) {
3,882,339✔
732
  int32_t  code = 0;
3,882,339✔
733
  int32_t  lino = 0;
3,882,339✔
734
  SDecoder decoder = {0};
3,882,339✔
735
  tDecoderInit(&decoder, buf, len);
3,882,339✔
736

737
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
3,882,339✔
738
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &pList->num), &lino, _OVER);
7,764,678✔
739

740
  for (int i = 0; i < pList->num; i++) {
11,650,871✔
741
    SIpRange *pRange = &(pList->pIpRanges[i]);
7,768,532✔
742
    TAOS_CHECK_GOTO(tDeserializeIpRange(&decoder, pRange, supportNeg), &lino, _OVER);
7,768,532✔
743
  }
744

745
_OVER:
3,882,339✔
746
  tEndDecode(&decoder);
3,882,339✔
747
  tDecoderClear(&decoder);
3,882,339✔
748
  if (code < 0) {
3,882,339✔
749
    mError("failed to deserialize ip white list at line %d since %s", lino, tstrerror(code));
×
750
  }
751
  TAOS_RETURN(code);
3,882,339✔
752
}
753

754
static int32_t tDerializeIpWhileListFromOldVer(void *buf, int32_t len, SIpWhiteList *pList) {
×
755
  int32_t  code = 0;
×
756
  int32_t  lino = 0;
×
757
  SDecoder decoder = {0};
×
758
  tDecoderInit(&decoder, buf, len);
×
759

760
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
×
761
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &pList->num), &lino, _OVER);
×
762

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

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

778
static int32_t createIpWhiteList(void *buf, int32_t len, SIpWhiteListDual **ppList, bool supportNeg) {
3,882,339✔
779
  int32_t           code = 0;
3,882,339✔
780
  int32_t           lino = 0;
3,882,339✔
781
  int32_t           num = 0;
3,882,339✔
782
  SIpWhiteListDual *p = NULL;
3,882,339✔
783
  SDecoder          decoder = {0};
3,882,339✔
784
  tDecoderInit(&decoder, buf, len);
3,882,339✔
785

786
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
3,882,339✔
787
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &num), &lino, _OVER);
3,882,339✔
788

789
  p = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + num * sizeof(SIpRange));
3,882,339✔
790
  if (p == NULL) {
3,882,339✔
791
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
792
  }
793
  TAOS_CHECK_GOTO(tDerializeIpWhiteList(buf, len, p, supportNeg), &lino, _OVER);
3,882,339✔
794

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

806
static int32_t createIpWhiteListFromOldVer(void *buf, int32_t len, SIpWhiteList **ppList) {
×
807
  int32_t       code = 0;
×
808
  int32_t       lino = 0;
×
809
  int32_t       num = 0;
×
810
  SIpWhiteList *p = NULL;
×
811
  SDecoder      decoder = {0};
×
812
  tDecoderInit(&decoder, buf, len);
×
813

814
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
×
815
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &num), &lino, _OVER);
×
816

817
  p = taosMemoryCalloc(1, sizeof(SIpWhiteList) + num * sizeof(SIpV4Range));
×
818
  if (p == NULL) {
×
819
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
820
  }
821
  TAOS_CHECK_GOTO(tDerializeIpWhileListFromOldVer(buf, len, p), &lino, _OVER);
×
822

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

834
static int32_t createDefaultIpWhiteList(SIpWhiteListDual **ppWhiteList) {
473,798✔
835
  int32_t code = 0;
473,798✔
836
  int32_t lino = 0;
473,798✔
837
  *ppWhiteList = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + sizeof(SIpRange) * 2);
473,798✔
838
  if (*ppWhiteList == NULL) {
473,798✔
839
    TAOS_RETURN(terrno);
×
840
  }
841
  (*ppWhiteList)->num = 2;
473,798✔
842

843
  SIpRange v4 = {0};
473,798✔
844
  SIpRange v6 = {0};
473,798✔
845

846
#ifndef TD_ASTRA
847
  code = createDefaultIp4Range(&v4);
473,798✔
848
  TSDB_CHECK_CODE(code, lino, _error);
473,798✔
849

850
  code = createDefaultIp6Range(&v6);
473,798✔
851
  TSDB_CHECK_CODE(code, lino, _error);
473,798✔
852

853
#endif
854

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

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

869
static int32_t convertTimeRangesToStr(SUserObj *pUser, char **buf) {
1,762,545✔
870
  int32_t bufLen = pUser->pTimeWhiteList->num * 32 + 8;
1,762,545✔
871
  *buf = taosMemoryCalloc(1, bufLen);
1,762,545✔
872
  if (*buf == NULL) {
1,762,545✔
873
    return 0;
×
874
  }
875

876
  int32_t pos = 0;
1,762,545✔
877
  if (pUser->pTimeWhiteList->num == 0) {
1,762,545✔
878
    pos += snprintf(*buf + pos, bufLen - pos, "+ALL");
1,670,609✔
879
    return pos;
1,670,609✔
880
  }
881

882
  for (int32_t i = 0; i < pUser->pTimeWhiteList->num; i++) {
209,560✔
883
    SDateTimeWhiteListItem *range = &pUser->pTimeWhiteList->ranges[i];
117,624✔
884
    int                     duration = range->duration / 60;
117,624✔
885

886
    if (range->absolute) {
117,624✔
887
      struct STm tm;
69,459✔
888
      (void)taosTs2Tm(range->start, TSDB_TIME_PRECISION_SECONDS, &tm, NULL);
69,459✔
889
      pos += tsnprintf(*buf + pos, bufLen - pos, "%c%04d-%02d-%02d %02d:%02d %dm, ", range->neg ? '-' : '+',
69,459✔
890
                       tm.tm.tm_year + 1900, tm.tm.tm_mon + 1, tm.tm.tm_mday, tm.tm.tm_hour, tm.tm.tm_min, duration);
69,459✔
891
    } else {
892
      int day = range->start / 86400;
48,165✔
893
      int hour = (range->start % 86400) / 3600;
48,165✔
894
      int minute = (range->start % 3600) / 60;
48,165✔
895
      pos += tsnprintf(*buf + pos, bufLen - pos, "%c%s %02d:%02d %dm, ", range->neg ? '-' : '+', weekdays[day], hour,
48,165✔
896
                       minute, duration);
897
    }
898
  }
899

900
  if (pos > 0) {
91,936✔
901
    pos -= 2;
91,936✔
902
    (*buf)[pos] = 0; // remove last ", "
91,936✔
903
  }
904

905
  return pos;
91,936✔
906
}
907

908
static int32_t compareDateTimeInterval(const void *a, const void *b, const void *arg) {
1,014✔
909
  SDateTimeWhiteListItem *pA = (SDateTimeWhiteListItem *)a;
1,014✔
910
  SDateTimeWhiteListItem *pB = (SDateTimeWhiteListItem *)b;
1,014✔
911

912
  if (pA->neg != pB->neg) {
1,014✔
913
    return pA->neg ? -1 : 1;
676✔
914
  }
915

916
  if (pA->absolute != pB->absolute) {
338✔
917
    return pA->absolute ? 1 : -1;
338✔
918
  }
919

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

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

928
  return 0;
×
929
}
930

931
static void sortTimeWhiteList(SDateTimeWhiteList *pList) {
2,873✔
932
  (void)taosqsort(pList->ranges, pList->num, sizeof(SDateTimeWhiteListItem), NULL, compareDateTimeInterval);
2,873✔
933
}
2,873✔
934

935
static void dropOldPasswords(SUserObj *pUser) {
11,752,902✔
936
  if (pUser->numOfPasswords <= pUser->passwordReuseMax) {
11,752,902✔
937
    return;
611,109✔
938
  }
939

940
  int32_t reuseMax = pUser->passwordReuseMax;
11,141,793✔
941
  if (reuseMax == 0) {
11,141,793✔
942
    reuseMax = 1;  // keep at least one password
11,141,455✔
943
  }
944

945
  int32_t now = taosGetTimestampSec();
11,141,793✔
946
  int32_t index = reuseMax;
11,141,793✔
947
  while(index < pUser->numOfPasswords) {
11,141,793✔
948
    // the set time of the n-th password is the expire time of the n+1-th password
949
    int32_t expireTime = pUser->passwords[index - 1].setTime;
338✔
950
    if (now - expireTime >= pUser->passwordReuseTime) {
338✔
951
      break;
338✔
952
    }
953
    index++;
×
954
  }
955

956
  if (index == pUser->numOfPasswords) {
11,141,793✔
957
    return;
11,141,455✔
958
  }
959
  pUser->numOfPasswords = index;
338✔
960
  // this is a shrink operation, no need to check return value
961
  pUser->passwords = taosMemoryRealloc(pUser->passwords, sizeof(SUserPassword) * pUser->numOfPasswords);
338✔
962
}
963

964
static int32_t mndCreateDefaultUser(SMnode *pMnode, char *acct, char *user, char *pass) {
371,657✔
965
  int32_t  code = 0;
371,657✔
966
  int32_t  lino = 0;
371,657✔
967
  SUserObj userObj = {0};
371,657✔
968

969
  userObj.passwords = taosMemCalloc(1, sizeof(SUserPassword));
371,657✔
970
  if (userObj.passwords == NULL) {
371,657✔
971
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _ERROR);
×
972
  }
973
  taosEncryptPass_c((uint8_t *)pass, strlen(pass), userObj.passwords[0].pass);
371,657✔
974
  userObj.passwords[0].pass[sizeof(userObj.passwords[0].pass) - 1] = 0;
371,657✔
975
  if (strlen(tsDataKey) > 0) {
371,657✔
976
    generateSalt(userObj.salt, sizeof(userObj.salt));
2,328✔
977
    TAOS_CHECK_GOTO(mndEncryptPass(userObj.passwords[0].pass, userObj.salt, &userObj.passEncryptAlgorithm), &lino,
2,328✔
978
                    _ERROR);
979
  }
980

981
  userObj.passwords[0].setTime = taosGetTimestampSec();
371,657✔
982
  userObj.numOfPasswords = 1;
371,657✔
983

984
  tstrncpy(userObj.user, user, TSDB_USER_LEN);
371,657✔
985
  tstrncpy(userObj.acct, acct, TSDB_USER_LEN);
371,657✔
986
  userObj.createdTime = taosGetTimestampMs();
371,657✔
987
  userObj.updateTime = userObj.createdTime;
371,657✔
988
  userObj.uid = mndGenerateUid(userObj.user, strlen(userObj.user));
371,657✔
989
  userObj.sysInfo = 1;
371,657✔
990
  userObj.enable = 1;
371,657✔
991
  userObj.minSecLevel = TSDB_MIN_SECURITY_LEVEL;
371,657✔
992
  userObj.maxSecLevel = TSDB_MAX_SECURITY_LEVEL;
371,657✔
993

994
#ifdef TD_ENTERPRISE
995

996
  userObj.ipWhiteListVer = taosGetTimestampMs();
371,657✔
997
  userObj.timeWhiteListVer = userObj.ipWhiteListVer;
371,657✔
998

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

1029
  userObj.allowTokenNum = TSDB_USER_ALLOW_TOKEN_NUM_DEFAULT;
371,657✔
1030
  userObj.tokenNum = 0;
371,657✔
1031

1032
#else  // TD_ENTERPRISE
1033

1034
  userObj.ipWhiteListVer = 0;
1035
  userObj.timeWhiteListVer = 0;
1036
  userObj.changePass = 2;  // 2: allow but not force user to change password
1037
  userObj.connectTime = -1;
1038
  userObj.connectIdleTime = -1;
1039
  userObj.callPerSession = -1;
1040
  userObj.vnodePerCall = -1;
1041
  userObj.passwordReuseTime = 0;
1042
  userObj.passwordReuseMax = 0;
1043
  userObj.passwordLockTime = 1;
1044
  userObj.sessionPerUser = -1;
1045
  userObj.failedLoginAttempts = -1;
1046
  userObj.passwordLifeTime = -1;
1047
  userObj.passwordGraceTime = -1;
1048
  userObj.inactiveAccountTime = -1;
1049
  userObj.allowTokenNum = -1;
1050
  userObj.tokenNum = 0;
1051

1052
#endif  // TD_ENTERPRISE
1053

1054
  userObj.pTimeWhiteList = taosMemoryCalloc(1, sizeof(SDateTimeWhiteList));
371,657✔
1055
  if (userObj.pTimeWhiteList == NULL) {
371,657✔
1056
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _ERROR);
×
1057
  }
1058

1059
  TAOS_CHECK_GOTO(createDefaultIpWhiteList(&userObj.pIpWhiteListDual), &lino, _ERROR);
371,657✔
1060
  // if this is the root user, change the value of some fields to allow the user login without restriction
1061
  if (strcmp(user, TSDB_DEFAULT_USER) == 0) {
371,657✔
1062
    userObj.superUser = 1;
371,657✔
1063
    userObj.createdb = 1;
371,657✔
1064
    userObj.sessionPerUser = -1;
371,657✔
1065
    userObj.callPerSession = -1;
371,657✔
1066
    userObj.vnodePerCall = -1;
371,657✔
1067
    userObj.failedLoginAttempts = -1;
371,657✔
1068
    userObj.passwordGraceTime = -1;
371,657✔
1069
    userObj.inactiveAccountTime = -1;
371,657✔
1070
  }
1071

1072
  userObj.roles = taosHashInit(1, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
371,657✔
1073
  if (userObj.roles == NULL) {
371,657✔
1074
    TAOS_CHECK_GOTO(terrno, &lino, _ERROR);
×
1075
  }
1076

1077
  if ((code = taosHashPut(userObj.roles, TSDB_ROLE_SYSDBA, sizeof(TSDB_ROLE_SYSDBA), NULL, 0)) ||
743,314✔
1078
      (code = taosHashPut(userObj.roles, TSDB_ROLE_SYSSEC, sizeof(TSDB_ROLE_SYSSEC), NULL, 0)) ||
743,314✔
1079
      (code = taosHashPut(userObj.roles, TSDB_ROLE_SYSAUDIT, sizeof(TSDB_ROLE_SYSAUDIT), NULL, 0))) {
371,657✔
1080
    TAOS_CHECK_GOTO(code, &lino, _ERROR);
×
1081
  }
1082

1083
  SSdbRaw *pRaw = mndUserActionEncode(&userObj);
371,657✔
1084
  if (pRaw == NULL) goto _ERROR;
371,657✔
1085
  TAOS_CHECK_GOTO(sdbSetRawStatus(pRaw, SDB_STATUS_READY), &lino, _ERROR);
371,657✔
1086

1087
  mInfo("user:%s, will be created when deploying, raw:%p", userObj.user, pRaw);
371,657✔
1088

1089
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_ROLE, NULL, "create-user");
371,657✔
1090
  if (pTrans == NULL) {
371,657✔
1091
    sdbFreeRaw(pRaw);
×
1092
    mError("user:%s, failed to create since %s", userObj.user, terrstr());
×
1093
    goto _ERROR;
×
1094
  }
1095
  mInfo("trans:%d, used to create user:%s", pTrans->id, userObj.user);
371,657✔
1096

1097
  if (mndTransAppendCommitlog(pTrans, pRaw) != 0) {
371,657✔
1098
    mError("trans:%d, failed to commit redo log since %s", pTrans->id, terrstr());
×
1099
    mndTransDrop(pTrans);
×
1100
    goto _ERROR;
×
1101
  }
1102
  TAOS_CHECK_GOTO(sdbSetRawStatus(pRaw, SDB_STATUS_READY), &lino, _ERROR);
371,657✔
1103

1104
  if (mndTransPrepare(pMnode, pTrans) != 0) {
371,657✔
1105
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
1106
    mndTransDrop(pTrans);
×
1107
    goto _ERROR;
×
1108
  }
1109

1110
  mndTransDrop(pTrans);
371,657✔
1111
  mndUserFreeObj(&userObj);
371,657✔
1112
  return 0;
371,657✔
1113

1114
_ERROR:
×
1115
  mndUserFreeObj(&userObj);
×
1116
  if (code == 0) {
×
1117
    code = terrno ? terrno : TSDB_CODE_APP_ERROR;
×
1118
  }
1119
  mError("user:%s, failed to create default user since %s", user, tstrerror(code));
×
1120
  TAOS_RETURN(code);
×
1121
}
1122

1123
static int32_t mndCreateDefaultUsers(SMnode *pMnode) {
371,657✔
1124
  return mndCreateDefaultUser(pMnode, TSDB_DEFAULT_USER, TSDB_DEFAULT_USER, TSDB_DEFAULT_PASS);
371,657✔
1125
}
1126

1127
static int32_t mndUserPrivUpgradeDbOwners(SMnode *pMnode, SRpcMsg *pReq) {
×
1128
  int32_t code = 0, lino = 0;
×
1129
  SSdb   *pSdb = pMnode->pSdb;
×
1130
  SDbObj *pObj = NULL;
×
1131
  void   *pIter = NULL;
×
1132

1133
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "upgrade-db");
×
1134
  if (pTrans == NULL) {
×
1135
    TAOS_CHECK_EXIT(terrno);
×
1136
  }
1137

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

1174
  TAOS_CHECK_EXIT(mndTransPrepare(pMnode, pTrans));
×
1175

1176
_exit:
×
1177
  mndTransDrop(pTrans);
×
1178
  if (code < 0) {
×
1179
    mError("failed at line %d to upgrade db owner uid since %s", lino, tstrerror(code));
×
1180
  }
1181
  TAOS_RETURN(code);
×
1182
}
1183

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

1206
#ifdef TD_ENTERPRISE
1207
static int32_t mndUserPrivUpgradeTbViews(SMnode *pMnode, SUserObj *pUser, SHashObj **ppTblHash, SHashObj *pTbs, int32_t privType,
×
1208
                                         uint8_t objType) {
1209
  int32_t code = 0, lino = 0;
×
1210
  void   *pIter = NULL;
×
1211
  char   *key = NULL;
×
1212
  char   *value = NULL;
×
1213

1214
  SAlterRoleReq alterReq = {.alterType = TSDB_ALTER_ROLE_PRIVILEGES, .add = 1, .objType = objType, .objLevel = 1};
×
1215

1216
  while ((pIter = taosHashIterate(pTbs, pIter))) {
×
1217
    size_t keyLen = 0;
×
1218
    key = taosHashGetKey(pIter, &keyLen);
×
1219

1220
    SName name = {0};
×
1221
    TAOS_CHECK_EXIT(tNameFromString(&name, key, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE));
×
1222

1223
    snprintf(alterReq.objFName, TSDB_OBJ_FNAME_LEN, "%d.%s", name.acctId, name.dbname);
×
1224
    snprintf(alterReq.tblName, TSDB_TABLE_NAME_LEN, "%s", name.tname);
×
1225

1226
    privAddType(&alterReq.privileges.privSet, privType);
1227

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

1243
    TAOS_CHECK_EXIT(mndAlterUserPrivInfo(pMnode, pUser, &alterReq));
×
1244
    tFreeSAlterRoleReq(&alterReq);
×
1245
  }
1246
_exit:
×
1247
  tFreeSAlterRoleReq(&alterReq);
×
1248
  TAOS_RETURN(code);
×
1249
}
1250

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

1267
static int32_t mndUserPrivUpgradeUsedDbs(SMnode *pMnode, SUserObj *pUser, SHashObj *pDbs) {
×
1268
  int32_t code = 0, lino = 0;
×
1269
  void   *pIter = NULL;
×
1270
  char   *key = NULL;
×
1271
  char   *value = NULL;
×
1272

1273
  SAlterRoleReq alterReq = {.alterType = TSDB_ALTER_ROLE_PRIVILEGES, .add = 1, .objType = PRIV_OBJ_DB};
×
1274

1275
  while ((pIter = taosHashIterate(pDbs, pIter))) {
×
1276
    key = taosHashGetKey(pIter, NULL);
×
1277

1278
    SName name = {0};
×
1279
    TAOS_CHECK_EXIT(tNameFromString(&name, key, T_NAME_ACCT | T_NAME_DB));
×
1280

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

1283
    privAddType(&alterReq.privileges.privSet, PRIV_DB_USE);
1284

1285
    TAOS_CHECK_EXIT(mndAlterUserPrivInfo(pMnode, pUser, &alterReq));
×
1286
  }
1287
_exit:
×
1288
  tFreeSAlterRoleReq(&alterReq);
×
1289
  TAOS_RETURN(code);
×
1290
}
1291

1292
static int32_t mndUserPrivUpgradeTopics(SMnode *pMnode, SUserObj *pUser, SHashObj *pTopics) {
×
1293
  int32_t code = 0, lino = 0;
×
1294
  void   *pIter = NULL;
×
1295
  char   *key = NULL;
×
1296
  char   *value = NULL;
×
1297

1298
  SAlterRoleReq alterReq = {.alterType = TSDB_ALTER_ROLE_PRIVILEGES,
×
1299
                            .add = 1,
1300
                            .objType = PRIV_OBJ_TOPIC,
1301
                            .objLevel = 1,
1302
                            .ignoreNotExists = 1};
1303

1304
  while ((pIter = taosHashIterate(pTopics, pIter))) {
×
1305
    size_t keyLen = 0;
×
1306
    key = taosHashGetKey(pIter, &keyLen);
×
1307

1308
    SName name = {0};
×
1309
    if (tNameFromString(&name, key, T_NAME_ACCT | T_NAME_DB)) {  // 1.topicName
×
1310
      continue;
×
1311
    }
1312
    snprintf(alterReq.tblName, TSDB_TABLE_NAME_LEN, "%s", name.dbname);
×
1313

1314
    SMqTopicObj *pTopic = NULL;
×
1315
    if (mndAcquireTopic(pMnode, key, &pTopic)) {
×
1316
      continue;  // no topic exists
×
1317
    }
1318
    snprintf(alterReq.objFName, TSDB_OBJ_FNAME_LEN, "%s", pTopic->db);
×
1319
    mndReleaseTopic(pMnode, pTopic);
×
1320

1321
    privAddType(&alterReq.privileges.privSet, PRIV_CM_SUBSCRIBE);
1322

1323
    TAOS_CHECK_EXIT(mndAlterUserPrivInfo(pMnode, pUser, &alterReq));
×
1324
  }
1325
_exit:
×
1326
  tFreeSAlterRoleReq(&alterReq);
×
1327
  TAOS_RETURN(code);
×
1328
}
1329
#endif
1330

1331
/**
1332
 * @brief migrate from 3.3.x.y to 3.4.x.y
1333
 * @return int32_t
1334
 */
1335
static int32_t mndUserPrivUpgradeUser(SMnode *pMnode, SUserObj *pObj) {
×
1336
  int32_t          code = 0, lino = 0;
×
1337
  SPrivHashObjSet *pPrivSet = pObj->legacyPrivs;
×
1338

1339
  if (pObj->uid == 0) {
×
1340
    pObj->uid = mndGenerateUid(pObj->name, strlen(pObj->name));
×
1341
  }
1342

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

1348
  if (!pObj->roles &&
×
1349
      !(pObj->roles = taosHashInit(1, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK))) {
×
1350
    TAOS_CHECK_EXIT(terrno);
×
1351
  }
1352

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

1400
static int32_t mndUserPrivUpgradeUsers(SMnode *pMnode, SRpcMsg *pReq) {
×
1401
  int32_t   code = 0, lino = 0;
×
1402
  SSdb     *pSdb = pMnode->pSdb;
×
1403
  SUserObj *pObj = NULL;
×
1404
  void     *pIter = NULL;
×
1405
  SUserObj  newObj = {0};
×
1406
  SUserObj *pRoot = NULL;
×
1407
  bool      forceUpgrade = false;
×
1408

1409
  if (0 == mndAcquireUser(pMnode, TSDB_DEFAULT_USER, &pRoot)) {
×
1410
    if (taosHashGetSize(pRoot->roles) == 0) {
×
1411
      forceUpgrade = true;
×
1412
    }
1413
    mndReleaseUser(pMnode, pRoot);
×
1414
  }
1415

1416
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pObj))) {
×
1417
    if (pObj->uid != 0 && pObj->legacyPrivs == NULL && !forceUpgrade) {
×
1418
      sdbRelease(pSdb, pObj);
×
1419
      pObj = NULL;
×
1420
      continue;
×
1421
    }
1422
    if (pObj->uid == 0) {
×
1423
      // Assign uid firstly because the transactions in mndUserPrivUpgradeUsers may not finish when
1424
      // mndUserPrivUpgradeDbOwners is called
1425
      pObj->uid = mndGenerateUid(pObj->name, strlen(pObj->name));
×
1426
    }
1427
    memset(&newObj, 0, sizeof(SUserObj));
×
1428
    TAOS_CHECK_EXIT(mndUserDupObj(pObj, &newObj));
×
1429
    TAOS_CHECK_EXIT(mndUserPrivUpgradeUser(pMnode, &newObj));
×
1430
    TAOS_CHECK_EXIT(mndAlterUser(pMnode, &newObj, pReq));
×
1431
    mndUserFreeObj(&newObj);
×
1432
    sdbRelease(pSdb, pObj);
×
1433
    pObj = NULL;
×
1434
  }
1435
_exit:
×
1436
  sdbCancelFetch(pSdb, pIter);
×
1437
  sdbRelease(pSdb, pObj);
×
1438
  mndUserFreeObj(&newObj);
×
1439
  if (code < 0) {
×
1440
    mError("failed at line %d to upgrade db owner uid since %s", lino, tstrerror(code));
×
1441
  }
1442
  TAOS_RETURN(code);
×
1443
}
1444

1445
static int32_t mndProcessUpgradeUserReq(SRpcMsg *pReq) {
×
1446
  SMnode *pMnode = pReq->info.node;
×
1447
  int32_t code = 0, lino = 0;
×
1448

1449
  TAOS_CHECK_EXIT(mndUserPrivUpgradeUsers(pMnode, pReq));
×
1450
  TAOS_CHECK_EXIT(mndUserPrivUpgradeDbOwners(pMnode, pReq));
×
1451
_exit:
×
1452
  if (code < 0) {
×
1453
    mError("failed at line %d to upgrade users since %s", lino, tstrerror(code));
×
1454
  }
1455
  TAOS_RETURN(code);
×
1456
}
1457

1458
static int32_t mndProcessUpgradeUserRsp(SRpcMsg *pReq) { return 0;}
×
1459

1460
static int32_t mndUpgradeUsers(SMnode *pMnode, int32_t version) {
464,982✔
1461
  int32_t code = 0, lino = 0;
464,982✔
1462
  if (upgradeSecurity == 0) return code;
464,982✔
1463
  if (!mndIsLeader(pMnode)) return code;
×
1464

1465
  SRpcMsg rpcMsg = {.msgType = TDMT_MND_UPGRADE_USER, .info.ahandle = 0, .info.notFreeAhandle = 1};
×
1466
  SEpSet  epSet = {0};
×
1467
  mndGetMnodeEpSet(pMnode, &epSet);
×
1468
  TAOS_CHECK_EXIT(tmsgSendReq(&epSet, &rpcMsg));
×
1469
_exit:
×
1470
  if (code < 0) {
×
1471
    mError("failed at line %d to upgrade users since %s", lino, tstrerror(code));
×
1472
  }
1473
  TAOS_RETURN(code);
×
1474
}
1475

1476
static int32_t tSerializeUserObjExt(void *buf, int32_t bufLen, SUserObj *pObj) {
9,560,328✔
1477
  int32_t  code = 0, lino = 0;
9,560,328✔
1478
  int32_t  tlen = 0;
9,560,328✔
1479
  void    *pIter = NULL;
9,560,328✔
1480
  SEncoder encoder = {0};
9,560,328✔
1481
  tEncoderInit(&encoder, buf, bufLen);
9,560,328✔
1482

1483
  TAOS_CHECK_EXIT(tStartEncode(&encoder));
9,560,328✔
1484
  TAOS_CHECK_EXIT(tEncodeI64v(&encoder, pObj->uid));
19,120,656✔
1485

1486
  TAOS_CHECK_EXIT(tSerializePrivSysObjPolicies(&encoder, &pObj->sysPrivs, pObj->objPrivs));
9,560,328✔
1487

1488
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->selectTbs));
9,560,328✔
1489
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->insertTbs));
9,560,328✔
1490
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->updateTbs));
9,560,328✔
1491
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->deleteTbs));
9,560,328✔
1492

1493
  int32_t nRoles = taosHashGetSize(pObj->roles);
9,560,328✔
1494
  TAOS_CHECK_EXIT(tEncodeI32v(&encoder, nRoles));
9,560,328✔
1495

1496
  while ((pIter = taosHashIterate(pObj->roles, pIter))) {
30,405,796✔
1497
    size_t keyLen = 0;
20,845,468✔
1498
    char  *key = taosHashGetKey(pIter, &keyLen);  // key: role name
20,845,468✔
1499
    TAOS_CHECK_EXIT(tEncodeCStr(&encoder, key));
20,845,468✔
1500

1501
    uint8_t flag = *(uint8_t *)pIter;
20,845,468✔
1502
    TAOS_CHECK_EXIT(tEncodeU8(&encoder, flag));  // value: 0 reset, 1 set(default)
41,690,936✔
1503
  }
1504

1505
  int32_t nOwnedDbs = taosHashGetSize(pObj->ownedDbs);
9,560,328✔
1506
  TAOS_CHECK_EXIT(tEncodeI32v(&encoder, nOwnedDbs));
9,560,328✔
1507
  pIter = NULL;
9,560,328✔
1508
  while ((pIter = taosHashIterate(pObj->ownedDbs, pIter))) {
38,488,322✔
1509
    size_t keyLen = 0;
28,927,994✔
1510
    char  *key = taosHashGetKey(pIter, &keyLen);  // key: dbFName
28,927,994✔
1511
    TAOS_CHECK_EXIT(tEncodeCStr(&encoder, key));
28,927,994✔
1512
  }
1513

1514
  tEndEncode(&encoder);
9,560,328✔
1515
  tlen = encoder.pos;
9,560,328✔
1516
_exit:
9,560,328✔
1517
  tEncoderClear(&encoder);
9,560,328✔
1518
  if (code < 0) {
9,560,328✔
1519
    mError("user:%s, %s failed at line %d since %s", pObj->user, __func__, lino, tstrerror(code));
×
1520
    TAOS_RETURN(code);
×
1521
  }
1522

1523
  return tlen;
9,560,328✔
1524
}
1525

1526
static int32_t tDeserializeUserObjExt(void *buf, int32_t bufLen, SUserObj *pObj) {
3,882,339✔
1527
  int32_t  code = 0, lino = 0;
3,882,339✔
1528
  SDecoder decoder = {0};
3,882,339✔
1529
  tDecoderInit(&decoder, buf, bufLen);
3,882,339✔
1530

1531
  TAOS_CHECK_EXIT(tStartDecode(&decoder));
3,882,339✔
1532
  TAOS_CHECK_EXIT(tDecodeI64v(&decoder, &pObj->uid));
7,764,678✔
1533
  TAOS_CHECK_EXIT(tDeserializePrivSysObjPolicies(&decoder, &pObj->sysPrivs, &pObj->objPrivs));
3,882,339✔
1534
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->selectTbs));
3,882,339✔
1535
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->insertTbs));
3,882,339✔
1536
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->updateTbs));
3,882,339✔
1537
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->deleteTbs));
3,882,339✔
1538
  int32_t nRoles = 0;
3,882,339✔
1539
  TAOS_CHECK_EXIT(tDecodeI32v(&decoder, &nRoles));
3,882,339✔
1540
  if (nRoles > 0) {
3,882,339✔
1541
    if (!pObj->roles &&
3,827,841✔
1542
        !(pObj->roles = taosHashInit(nRoles, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), 1, HASH_ENTRY_LOCK))) {
3,827,841✔
1543
      TAOS_CHECK_EXIT(terrno);
×
1544
    }
1545
    for (int32_t i = 0; i < nRoles; i++) {
11,754,164✔
1546
      int32_t keyLen = 0;
7,926,323✔
1547
      char   *key = NULL;
7,926,323✔
1548
      TAOS_CHECK_EXIT(tDecodeCStrAndLen(&decoder, &key, &keyLen));
7,926,323✔
1549
      uint8_t flag = 0;
7,926,323✔
1550
      TAOS_CHECK_EXIT(tDecodeU8(&decoder, &flag));
7,926,323✔
1551
      TAOS_CHECK_EXIT(taosHashPut(pObj->roles, key, keyLen + 1, &flag, sizeof(flag)));
7,926,323✔
1552
    }
1553
  }
1554
  if (!tDecodeIsEnd(&decoder)) {
3,882,339✔
1555
    int32_t nOwnedDbs = 0;
3,882,339✔
1556
    TAOS_CHECK_EXIT(tDecodeI32v(&decoder, &nOwnedDbs));
3,882,339✔
1557
    if (nOwnedDbs > 0) {
3,882,339✔
1558
      if (!pObj->ownedDbs &&
1,642,217✔
1559
          !(pObj->ownedDbs =
1,642,217✔
1560
                taosHashInit(nOwnedDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), 1, HASH_ENTRY_LOCK))) {
1,642,217✔
1561
        TAOS_CHECK_EXIT(terrno);
×
1562
      }
1563
      for (int32_t i = 0; i < nOwnedDbs; ++i) {
14,749,451✔
1564
        int32_t keyLen = 0;
13,107,234✔
1565
        char   *key = NULL;
13,107,234✔
1566
        TAOS_CHECK_EXIT(tDecodeCStrAndLen(&decoder, &key, &keyLen));
13,107,234✔
1567
        TAOS_CHECK_EXIT(taosHashPut(pObj->ownedDbs, key, keyLen + 1, NULL, 0));
13,107,234✔
1568
      }
1569
    }
1570
  }
1571

1572
_exit:
3,878,186✔
1573
  tEndDecode(&decoder);
3,882,339✔
1574
  tDecoderClear(&decoder);
3,882,339✔
1575
  if (code < 0) {
3,882,339✔
1576
    mError("user, %s failed at line %d since %s, row:%p", __func__, lino, tstrerror(code), pObj);
×
1577
  }
1578
  TAOS_RETURN(code);
3,882,339✔
1579
}
1580

1581
SSdbRaw *mndUserActionEncode(SUserObj *pUser) {
4,780,164✔
1582
  int32_t code = 0;
4,780,164✔
1583
  int32_t lino = 0;
4,780,164✔
1584
  int32_t passReserve = (sizeof(SUserPassword) + 8) * pUser->numOfPasswords + 4;
4,780,164✔
1585
  int32_t ipWhiteReserve =
×
1586
      pUser->pIpWhiteListDual ? (sizeof(SIpRange) * pUser->pIpWhiteListDual->num + sizeof(SIpWhiteListDual) + 4) : 16;
4,780,164✔
1587
  int32_t timeWhiteReserve =
×
1588
      pUser->pTimeWhiteList
4,780,164✔
1589
          ? (sizeof(SDateTimeWhiteListItem) * pUser->pTimeWhiteList->num + sizeof(SDateTimeWhiteList) + 4)
4,780,164✔
1590
          : 16;
1591
  int32_t numOfReadDbs = 0;     // taosHashGetSize(pUser->readDbs);
4,780,164✔
1592
  int32_t numOfWriteDbs = 0;    // taosHashGetSize(pUser->writeDbs);
4,780,164✔
1593
  int32_t numOfReadTbs = 0;     // taosHashGetSize(pUser->readTbs);
4,780,164✔
1594
  int32_t numOfWriteTbs = 0;    // taosHashGetSize(pUser->writeTbs);
4,780,164✔
1595
  int32_t numOfAlterTbs = 0;    // taosHashGetSize(pUser->alterTbs);
4,780,164✔
1596
  int32_t numOfReadViews = 0;   // taosHashGetSize(pUser->readViews);
4,780,164✔
1597
  int32_t numOfWriteViews = 0;  // taosHashGetSize(pUser->writeViews);
4,780,164✔
1598
  int32_t numOfAlterViews = 0;  // taosHashGetSize(pUser->alterViews);
4,780,164✔
1599
  int32_t numOfTopics = 0;      // taosHashGetSize(pUser->topics);
4,780,164✔
1600
  int32_t numOfUseDbs = 0;      // taosHashGetSize(pUser->useDbs);
4,780,164✔
1601
  int32_t numOfRoles = taosHashGetSize(pUser->roles);
4,780,164✔
1602
  int32_t size = sizeof(SUserObj) + USER_RESERVE_SIZE + (numOfReadDbs + numOfWriteDbs) * TSDB_DB_FNAME_LEN +
4,780,164✔
1603
                 numOfTopics * TSDB_TOPIC_FNAME_LEN + ipWhiteReserve + timeWhiteReserve + passReserve;
4,780,164✔
1604
  char    *buf = NULL;
4,780,164✔
1605
  SSdbRaw *pRaw = NULL;
4,780,164✔
1606

1607
  char *stb = NULL;
4,780,164✔
1608
#if 0
1609
  stb = taosHashIterate(pUser->readTbs, NULL);
1610
  while (stb != NULL) {
1611
    size_t keyLen = 0;
1612
    void  *key = taosHashGetKey(stb, &keyLen);
1613
    size += sizeof(int32_t);
1614
    size += keyLen;
1615

1616
    size_t valueLen = 0;
1617
    valueLen = strlen(stb) + 1;
1618
    size += sizeof(int32_t);
1619
    size += valueLen;
1620
    stb = taosHashIterate(pUser->readTbs, stb);
1621
  }
1622

1623
  stb = taosHashIterate(pUser->writeTbs, NULL);
1624
  while (stb != NULL) {
1625
    size_t keyLen = 0;
1626
    void  *key = taosHashGetKey(stb, &keyLen);
1627
    size += sizeof(int32_t);
1628
    size += keyLen;
1629

1630
    size_t valueLen = 0;
1631
    valueLen = strlen(stb) + 1;
1632
    size += sizeof(int32_t);
1633
    size += valueLen;
1634
    stb = taosHashIterate(pUser->writeTbs, stb);
1635
  }
1636
  stb = taosHashIterate(pUser->alterTbs, NULL);
1637
  while (stb != NULL) {
1638
    size_t keyLen = 0;
1639
    void  *key = taosHashGetKey(stb, &keyLen);
1640
    size += sizeof(int32_t);
1641
    size += keyLen;
1642

1643
    size_t valueLen = 0;
1644
    valueLen = strlen(stb) + 1;
1645
    size += sizeof(int32_t);
1646
    size += valueLen;
1647
    stb = taosHashIterate(pUser->alterTbs, stb);
1648
  }
1649

1650
  stb = taosHashIterate(pUser->readViews, NULL);
1651
  while (stb != NULL) {
1652
    size_t keyLen = 0;
1653
    void  *key = taosHashGetKey(stb, &keyLen);
1654
    size += sizeof(int32_t);
1655
    size += keyLen;
1656

1657
    size_t valueLen = 0;
1658
    valueLen = strlen(stb) + 1;
1659
    size += sizeof(int32_t);
1660
    size += valueLen;
1661
    stb = taosHashIterate(pUser->readViews, stb);
1662
  }
1663

1664
  stb = taosHashIterate(pUser->writeViews, NULL);
1665
  while (stb != NULL) {
1666
    size_t keyLen = 0;
1667
    void  *key = taosHashGetKey(stb, &keyLen);
1668
    size += sizeof(int32_t);
1669
    size += keyLen;
1670

1671
    size_t valueLen = 0;
1672
    valueLen = strlen(stb) + 1;
1673
    size += sizeof(int32_t);
1674
    size += valueLen;
1675
    stb = taosHashIterate(pUser->writeViews, stb);
1676
  }
1677

1678
  stb = taosHashIterate(pUser->alterViews, NULL);
1679
  while (stb != NULL) {
1680
    size_t keyLen = 0;
1681
    void  *key = taosHashGetKey(stb, &keyLen);
1682
    size += sizeof(int32_t);
1683
    size += keyLen;
1684

1685
    size_t valueLen = 0;
1686
    valueLen = strlen(stb) + 1;
1687
    size += sizeof(int32_t);
1688
    size += valueLen;
1689
    stb = taosHashIterate(pUser->alterViews, stb);
1690
  }
1691

1692
  int32_t *useDb = taosHashIterate(pUser->useDbs, NULL);
1693
  while (useDb != NULL) {
1694
    size_t keyLen = 0;
1695
    void  *key = taosHashGetKey(useDb, &keyLen);
1696
    size += sizeof(int32_t);
1697
    size += keyLen;
1698
    size += sizeof(int32_t);
1699
    useDb = taosHashIterate(pUser->useDbs, useDb);
1700
  }
1701
#endif
1702
  int32_t sizeExt = tSerializeUserObjExt(NULL, 0, pUser);
4,780,164✔
1703
  if (sizeExt < 0) {
4,780,164✔
1704
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1705
  }
1706
  size += sizeExt;
4,780,164✔
1707

1708
  pRaw = sdbAllocRaw(SDB_USER, USER_VER_NUMBER, size);
4,780,164✔
1709
  if (pRaw == NULL) {
4,780,164✔
1710
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1711
  }
1712

1713
  int32_t dataPos = 0;
4,780,164✔
1714
  SDB_SET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN, _OVER)
4,780,164✔
1715

1716
  dropOldPasswords(pUser);
4,780,164✔
1717
  SDB_SET_INT32(pRaw, dataPos, pUser->numOfPasswords, _OVER)
4,780,164✔
1718
  for (int32_t i = 0; i < pUser->numOfPasswords; i++) {
10,492,025✔
1719
    SDB_SET_BINARY(pRaw, dataPos, pUser->passwords[i].pass, sizeof(pUser->passwords[i].pass), _OVER)
5,711,861✔
1720
    SDB_SET_INT32(pRaw, dataPos, pUser->passwords[i].setTime, _OVER)
5,711,861✔
1721
  }
1722
  SDB_SET_BINARY(pRaw, dataPos, pUser->salt, sizeof(pUser->salt), _OVER)
4,780,164✔
1723

1724
  SDB_SET_BINARY(pRaw, dataPos, pUser->acct, TSDB_USER_LEN, _OVER)
4,780,164✔
1725
  SDB_SET_INT64(pRaw, dataPos, pUser->createdTime, _OVER)
4,780,164✔
1726
  SDB_SET_INT64(pRaw, dataPos, pUser->updateTime, _OVER)
4,780,164✔
1727
  SDB_SET_INT8(pRaw, dataPos, pUser->superUser, _OVER)
4,780,164✔
1728
  SDB_SET_INT8(pRaw, dataPos, pUser->sysInfo, _OVER)
4,780,164✔
1729
  SDB_SET_INT8(pRaw, dataPos, pUser->enable, _OVER)
4,780,164✔
1730
  SDB_SET_UINT8(pRaw, dataPos, pUser->flag, _OVER)
4,780,164✔
1731
  SDB_SET_INT32(pRaw, dataPos, pUser->authVersion, _OVER)
4,780,164✔
1732
  SDB_SET_INT32(pRaw, dataPos, pUser->passVersion, _OVER)
4,780,164✔
1733
  SDB_SET_INT32(pRaw, dataPos, numOfReadDbs, _OVER)
4,780,164✔
1734
  SDB_SET_INT32(pRaw, dataPos, numOfWriteDbs, _OVER)
4,780,164✔
1735
  SDB_SET_INT32(pRaw, dataPos, numOfTopics, _OVER)
4,780,164✔
1736
#if 0
1737
  char *db = taosHashIterate(pUser->readDbs, NULL);
1738
  while (db != NULL) {
1739
    SDB_SET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER);
1740
    db = taosHashIterate(pUser->readDbs, db);
1741
  }
1742

1743
  db = taosHashIterate(pUser->writeDbs, NULL);
1744
  while (db != NULL) {
1745
    SDB_SET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER);
1746
    db = taosHashIterate(pUser->writeDbs, db);
1747
  }
1748
  char *topic = taosHashIterate(pUser->topics, NULL);
1749
  while (topic != NULL) {
1750
    SDB_SET_BINARY(pRaw, dataPos, topic, TSDB_TOPIC_FNAME_LEN, _OVER);
1751
    topic = taosHashIterate(pUser->topics, topic);
1752
  }
1753
#endif
1754
  SDB_SET_INT32(pRaw, dataPos, numOfReadTbs, _OVER)
4,780,164✔
1755
  SDB_SET_INT32(pRaw, dataPos, numOfWriteTbs, _OVER)
4,780,164✔
1756
  SDB_SET_INT32(pRaw, dataPos, numOfAlterTbs, _OVER)
4,780,164✔
1757
  SDB_SET_INT32(pRaw, dataPos, numOfReadViews, _OVER)
4,780,164✔
1758
  SDB_SET_INT32(pRaw, dataPos, numOfWriteViews, _OVER)
4,780,164✔
1759
  SDB_SET_INT32(pRaw, dataPos, numOfAlterViews, _OVER)
4,780,164✔
1760
  SDB_SET_INT32(pRaw, dataPos, numOfUseDbs, _OVER)
4,780,164✔
1761

1762
#if 0
1763
  stb = taosHashIterate(pUser->readTbs, NULL);
1764
  while (stb != NULL) {
1765
    size_t keyLen = 0;
1766
    void  *key = taosHashGetKey(stb, &keyLen);
1767
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1768
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1769

1770
    size_t valueLen = 0;
1771
    valueLen = strlen(stb) + 1;
1772
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
1773
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
1774
    stb = taosHashIterate(pUser->readTbs, stb);
1775
  }
1776

1777
  stb = taosHashIterate(pUser->writeTbs, NULL);
1778
  while (stb != NULL) {
1779
    size_t keyLen = 0;
1780
    void  *key = taosHashGetKey(stb, &keyLen);
1781
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1782
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1783

1784
    size_t valueLen = 0;
1785
    valueLen = strlen(stb) + 1;
1786
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
1787
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
1788
    stb = taosHashIterate(pUser->writeTbs, stb);
1789
  }
1790
  stb = taosHashIterate(pUser->alterTbs, NULL);
1791
  while (stb != NULL) {
1792
    size_t keyLen = 0;
1793
    void  *key = taosHashGetKey(stb, &keyLen);
1794
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1795
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1796

1797
    size_t valueLen = 0;
1798
    valueLen = strlen(stb) + 1;
1799
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
1800
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
1801
    stb = taosHashIterate(pUser->alterTbs, stb);
1802
  }
1803

1804
  stb = taosHashIterate(pUser->readViews, NULL);
1805
  while (stb != NULL) {
1806
    size_t keyLen = 0;
1807
    void  *key = taosHashGetKey(stb, &keyLen);
1808
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1809
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1810

1811
    size_t valueLen = 0;
1812
    valueLen = strlen(stb) + 1;
1813
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
1814
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
1815
    stb = taosHashIterate(pUser->readViews, stb);
1816
  }
1817

1818
  stb = taosHashIterate(pUser->writeViews, NULL);
1819
  while (stb != NULL) {
1820
    size_t keyLen = 0;
1821
    void  *key = taosHashGetKey(stb, &keyLen);
1822
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1823
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1824

1825
    size_t valueLen = 0;
1826
    valueLen = strlen(stb) + 1;
1827
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
1828
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
1829
    stb = taosHashIterate(pUser->writeViews, stb);
1830
  }
1831

1832
  stb = taosHashIterate(pUser->alterViews, NULL);
1833
  while (stb != NULL) {
1834
    size_t keyLen = 0;
1835
    void  *key = taosHashGetKey(stb, &keyLen);
1836
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1837
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1838

1839
    size_t valueLen = 0;
1840
    valueLen = strlen(stb) + 1;
1841
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
1842
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
1843
    stb = taosHashIterate(pUser->alterViews, stb);
1844
  }
1845

1846
  useDb = taosHashIterate(pUser->useDbs, NULL);
1847
  while (useDb != NULL) {
1848
    size_t keyLen = 0;
1849
    void  *key = taosHashGetKey(useDb, &keyLen);
1850
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1851
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1852

1853
    SDB_SET_INT32(pRaw, dataPos, *useDb, _OVER)
1854
    useDb = taosHashIterate(pUser->useDbs, useDb);
1855
  }
1856
#endif
1857
  // save white list
1858
  int32_t num = pUser->pIpWhiteListDual->num;
4,780,164✔
1859
  int32_t tlen = sizeof(SIpWhiteListDual) + num * sizeof(SIpRange) + 4;
4,780,164✔
1860
  int32_t maxBufLen = TMAX(tlen, sizeExt);
4,780,164✔
1861
  if ((buf = taosMemoryCalloc(1, maxBufLen)) == NULL) {
4,780,164✔
1862
    TAOS_CHECK_GOTO(terrno, NULL, _OVER);
×
1863
  }
1864
  int32_t len = 0;
4,780,164✔
1865
  TAOS_CHECK_GOTO(tSerializeIpWhiteList(buf, tlen, pUser->pIpWhiteListDual, &len), &lino, _OVER);
4,780,164✔
1866

1867
  SDB_SET_INT32(pRaw, dataPos, len, _OVER);
4,780,164✔
1868
  SDB_SET_BINARY(pRaw, dataPos, buf, len, _OVER);
4,780,164✔
1869

1870
  SDB_SET_INT64(pRaw, dataPos, pUser->ipWhiteListVer, _OVER);
4,780,164✔
1871
  SDB_SET_INT8(pRaw, dataPos, pUser->passEncryptAlgorithm, _OVER);
4,780,164✔
1872

1873
  SDB_SET_BINARY(pRaw, dataPos, pUser->totpsecret, sizeof(pUser->totpsecret), _OVER);
4,780,164✔
1874
  SDB_SET_INT8(pRaw, dataPos, pUser->changePass, _OVER);
4,780,164✔
1875
  SDB_SET_INT32(pRaw, dataPos, pUser->sessionPerUser, _OVER);
4,780,164✔
1876
  SDB_SET_INT32(pRaw, dataPos, pUser->connectTime, _OVER);
4,780,164✔
1877
  SDB_SET_INT32(pRaw, dataPos, pUser->connectIdleTime, _OVER);
4,780,164✔
1878
  SDB_SET_INT32(pRaw, dataPos, pUser->callPerSession, _OVER);
4,780,164✔
1879
  SDB_SET_INT32(pRaw, dataPos, pUser->vnodePerCall, _OVER);
4,780,164✔
1880
  SDB_SET_INT32(pRaw, dataPos, pUser->failedLoginAttempts, _OVER);
4,780,164✔
1881
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordLifeTime, _OVER);
4,780,164✔
1882
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordReuseTime, _OVER);
4,780,164✔
1883
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordReuseMax, _OVER);
4,780,164✔
1884
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordLockTime, _OVER);
4,780,164✔
1885
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordGraceTime, _OVER);
4,780,164✔
1886
  SDB_SET_INT32(pRaw, dataPos, pUser->inactiveAccountTime, _OVER);
4,780,164✔
1887
  SDB_SET_INT32(pRaw, dataPos, pUser->allowTokenNum, _OVER);
4,780,164✔
1888
  SDB_SET_INT32(pRaw, dataPos, pUser->tokenNum, _OVER);
4,780,164✔
1889

1890
  SDB_SET_INT32(pRaw, dataPos, pUser->pTimeWhiteList->num, _OVER);
4,780,164✔
1891
  for (int32_t i = 0; i < pUser->pTimeWhiteList->num; i++) {
4,788,614✔
1892
    SDateTimeWhiteListItem *range = &pUser->pTimeWhiteList->ranges[i];
8,450✔
1893
    SDB_SET_BOOL(pRaw, dataPos, range->absolute, _OVER);
8,450✔
1894
    SDB_SET_BOOL(pRaw, dataPos, range->neg, _OVER);
8,450✔
1895
    SDB_SET_INT64(pRaw, dataPos, range->start, _OVER);
8,450✔
1896
    SDB_SET_INT32(pRaw, dataPos, range->duration, _OVER);
8,450✔
1897
  }
1898

1899
  sizeExt = tSerializeUserObjExt(buf, sizeExt, pUser);
4,780,164✔
1900
  if (sizeExt < 0) {
4,780,164✔
1901
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1902
  }
1903
  SDB_SET_INT32(pRaw, dataPos, sizeExt, _OVER);
4,780,164✔
1904
  SDB_SET_BINARY(pRaw, dataPos, buf, sizeExt, _OVER);
4,780,164✔
1905

1906
  SDB_SET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
4,780,164✔
1907

1908
  SDB_SET_DATALEN(pRaw, dataPos, _OVER)
4,780,164✔
1909

1910
_OVER:
4,780,164✔
1911
  taosMemoryFree(buf);
4,780,164✔
1912
  if (code < 0) {
4,780,164✔
1913
    mError("user:%s, failed to encode user action to raw:%p at line %d since %s", pUser->user, pRaw, lino,
×
1914
           tstrerror(code));
1915
    sdbFreeRaw(pRaw);
×
1916
    pRaw = NULL;
×
1917
    terrno = code;
×
1918
  }
1919

1920
  mTrace("user:%s, encode user action to raw:%p, row:%p", pUser->user, pRaw, pUser);
4,780,164✔
1921
  return pRaw;
4,780,164✔
1922
}
1923

1924
static SSdbRow *mndUserActionDecode(SSdbRaw *pRaw) {
3,882,339✔
1925
  int32_t   code = 0;
3,882,339✔
1926
  int32_t   lino = 0;
3,882,339✔
1927
  SSdbRow  *pRow = NULL;
3,882,339✔
1928
  SUserObj *pUser = NULL;
3,882,339✔
1929
  char     *key = NULL;
3,882,339✔
1930
  char     *value = NULL;
3,882,339✔
1931

1932
  int8_t sver = 0;
3,882,339✔
1933
  if (sdbGetRawSoftVer(pRaw, &sver) != 0) {
3,882,339✔
1934
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_PTR, &lino, _OVER);
×
1935
  }
1936

1937
  if (sver < 1 || sver > USER_VER_NUMBER) {
3,882,339✔
1938
    TAOS_CHECK_GOTO(TSDB_CODE_SDB_INVALID_DATA_VER, &lino, _OVER);
×
1939
  }
1940

1941
  pRow = sdbAllocRow(sizeof(SUserObj));
3,882,339✔
1942
  if (pRow == NULL) {
3,882,339✔
1943
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1944
  }
1945

1946
  pUser = sdbGetRowObj(pRow);
3,882,339✔
1947
  if (pUser == NULL) {
3,882,339✔
1948
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1949
  }
1950

1951
  if (sver < USER_VER_SUPPORT_ADVANCED_SECURITY) {
3,882,339✔
1952
    upgradeSecurity = 1;
×
1953
    pUser->legacyPrivs = taosMemCalloc(1, sizeof(SPrivHashObjSet));
×
1954
    if (pUser->legacyPrivs == NULL) {
×
1955
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
1956
    }
1957
  }
1958

1959
  int32_t dataPos = 0;
3,882,339✔
1960
  SDB_GET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN, _OVER)
3,882,339✔
1961

1962
  if (sver < USER_VER_SUPPORT_ADVANCED_SECURITY) {
3,882,339✔
1963
    pUser->passwords = taosMemoryCalloc(1, sizeof(SUserPassword));
×
1964
    if (pUser->passwords == NULL) {
×
1965
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
1966
    }
1967
    SDB_GET_BINARY(pRaw, dataPos, pUser->passwords[0].pass, TSDB_PASSWORD_LEN, _OVER)
×
1968
    pUser->numOfPasswords = 1;
×
1969
    memset(pUser->salt, 0, sizeof(pUser->salt));
×
1970
  } else {
1971
    SDB_GET_INT32(pRaw, dataPos, &pUser->numOfPasswords, _OVER)
3,882,339✔
1972
    pUser->passwords = taosMemoryCalloc(pUser->numOfPasswords, sizeof(SUserPassword));
3,882,339✔
1973
    if (pUser->passwords == NULL) {
3,882,339✔
1974
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
1975
    }
1976
    for (int32_t i = 0; i < pUser->numOfPasswords; ++i) {
8,635,873✔
1977
      SDB_GET_BINARY(pRaw, dataPos, pUser->passwords[i].pass, sizeof(pUser->passwords[i].pass), _OVER);
4,753,534✔
1978
      SDB_GET_INT32(pRaw, dataPos, &pUser->passwords[i].setTime, _OVER);
4,753,534✔
1979
    }
1980
    SDB_GET_BINARY(pRaw, dataPos, pUser->salt, sizeof(pUser->salt), _OVER)
3,882,339✔
1981
  }
1982

1983
  SDB_GET_BINARY(pRaw, dataPos, pUser->acct, TSDB_USER_LEN, _OVER)
3,882,339✔
1984
  SDB_GET_INT64(pRaw, dataPos, &pUser->createdTime, _OVER)
3,882,339✔
1985
  SDB_GET_INT64(pRaw, dataPos, &pUser->updateTime, _OVER)
3,882,339✔
1986
  if (sver < USER_VER_SUPPORT_ADVANCED_SECURITY) {
3,882,339✔
1987
    pUser->passwords[0].setTime = (int32_t)(pUser->updateTime / 1000);
×
1988
  }
1989

1990
  SDB_GET_INT8(pRaw, dataPos, &pUser->superUser, _OVER)
3,882,339✔
1991
  SDB_GET_INT8(pRaw, dataPos, &pUser->sysInfo, _OVER)
3,882,339✔
1992
  SDB_GET_INT8(pRaw, dataPos, &pUser->enable, _OVER)
3,882,339✔
1993
  SDB_GET_UINT8(pRaw, dataPos, &pUser->flag, _OVER)
3,882,339✔
1994
  if (pUser->superUser) pUser->createdb = 1;
3,882,339✔
1995
  SDB_GET_INT32(pRaw, dataPos, &pUser->authVersion, _OVER)
3,882,339✔
1996
  if (sver >= 4) {
3,882,339✔
1997
    SDB_GET_INT32(pRaw, dataPos, &pUser->passVersion, _OVER)
3,882,339✔
1998
  }
1999

2000
  int32_t numOfReadDbs = 0;
3,882,339✔
2001
  int32_t numOfWriteDbs = 0;
3,882,339✔
2002
  int32_t numOfTopics = 0;
3,882,339✔
2003
  SDB_GET_INT32(pRaw, dataPos, &numOfReadDbs, _OVER)
3,882,339✔
2004
  SDB_GET_INT32(pRaw, dataPos, &numOfWriteDbs, _OVER)
3,882,339✔
2005
  if (sver >= 2) {
3,882,339✔
2006
    SDB_GET_INT32(pRaw, dataPos, &numOfTopics, _OVER)
3,882,339✔
2007
  }
2008

2009
  if (numOfReadDbs > 0) {
3,882,339✔
2010
    pUser->legacyPrivs->pReadDbs =
×
2011
        taosHashInit(numOfReadDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
2012
    if (pUser->legacyPrivs->pReadDbs == NULL) {
×
2013
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2014
    }
2015
  }
2016
  if (numOfWriteDbs > 0) {
3,882,339✔
2017
    pUser->legacyPrivs->pWriteDbs =
×
2018
        taosHashInit(numOfWriteDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
2019
    if (pUser->legacyPrivs->pWriteDbs == NULL) {
×
2020
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2021
    }
2022
  }
2023
  if (numOfTopics > 0) {
3,882,339✔
2024
    pUser->legacyPrivs->pTopics =
×
2025
        taosHashInit(numOfTopics, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
2026
    if (pUser->legacyPrivs->pTopics == NULL) {
×
2027
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2028
    }
2029
  }
2030
  for (int32_t i = 0; i < numOfReadDbs; ++i) {
3,882,339✔
2031
    char db[TSDB_DB_FNAME_LEN] = {0};
×
2032
    SDB_GET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER)
×
2033
    int32_t len = strlen(db) + 1;
×
2034
    TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pReadDbs, db, len, db, TSDB_DB_FNAME_LEN), &lino, _OVER);
×
2035
  }
2036

2037
  for (int32_t i = 0; i < numOfWriteDbs; ++i) {
3,882,339✔
2038
    char db[TSDB_DB_FNAME_LEN] = {0};
×
2039
    SDB_GET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER)
×
2040
    int32_t len = strlen(db) + 1;
×
2041
    TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pWriteDbs, db, len, db, TSDB_DB_FNAME_LEN), &lino, _OVER);
×
2042
  }
2043

2044
  if (sver >= 2) {
3,882,339✔
2045
    for (int32_t i = 0; i < numOfTopics; ++i) {
3,882,339✔
2046
      char topic[TSDB_TOPIC_FNAME_LEN] = {0};
×
2047
      SDB_GET_BINARY(pRaw, dataPos, topic, TSDB_TOPIC_FNAME_LEN, _OVER)
×
2048
      int32_t len = strlen(topic) + 1;
×
2049
      TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pTopics, topic, len, topic, TSDB_TOPIC_FNAME_LEN), &lino, _OVER);
×
2050
    }
2051
  }
2052

2053
  if (sver >= 3) {
3,882,339✔
2054
    int32_t numOfReadTbs = 0;
3,882,339✔
2055
    int32_t numOfWriteTbs = 0;
3,882,339✔
2056
    int32_t numOfAlterTbs = 0;
3,882,339✔
2057
    int32_t numOfReadViews = 0;
3,882,339✔
2058
    int32_t numOfWriteViews = 0;
3,882,339✔
2059
    int32_t numOfAlterViews = 0;
3,882,339✔
2060
    int32_t numOfUseDbs = 0;
3,882,339✔
2061
    SDB_GET_INT32(pRaw, dataPos, &numOfReadTbs, _OVER)
3,882,339✔
2062
    SDB_GET_INT32(pRaw, dataPos, &numOfWriteTbs, _OVER)
3,882,339✔
2063
    if (sver >= 6) {
3,882,339✔
2064
      SDB_GET_INT32(pRaw, dataPos, &numOfAlterTbs, _OVER)
3,882,339✔
2065
      SDB_GET_INT32(pRaw, dataPos, &numOfReadViews, _OVER)
3,882,339✔
2066
      SDB_GET_INT32(pRaw, dataPos, &numOfWriteViews, _OVER)
3,882,339✔
2067
      SDB_GET_INT32(pRaw, dataPos, &numOfAlterViews, _OVER)
3,882,339✔
2068
    }
2069
    SDB_GET_INT32(pRaw, dataPos, &numOfUseDbs, _OVER)
3,882,339✔
2070

2071
    if (numOfReadTbs > 0) {
3,882,339✔
2072
      pUser->legacyPrivs->pReadTbs =
×
2073
          taosHashInit(numOfReadTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
2074
      if (pUser->legacyPrivs->pReadTbs == NULL) {
×
2075
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2076
      }
2077
    }
2078
    if (numOfWriteTbs > 0) {
3,882,339✔
2079
      pUser->legacyPrivs->pWriteTbs =
×
2080
          taosHashInit(numOfWriteTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
2081
      if (pUser->legacyPrivs->pWriteTbs == NULL) {
×
2082
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2083
      }
2084
    }
2085
    if (numOfAlterTbs > 0) {
3,882,339✔
2086
      pUser->legacyPrivs->pAlterTbs =
×
2087
          taosHashInit(numOfAlterTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
2088
      if (pUser->legacyPrivs->pAlterTbs == NULL) {
×
2089
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2090
      }
2091
    }
2092
    if (numOfReadViews > 0) {
3,882,339✔
2093
      pUser->legacyPrivs->pReadViews =
×
2094
          taosHashInit(numOfReadViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
2095
      if (pUser->legacyPrivs->pReadViews == NULL) {
×
2096
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2097
      }
2098
    }
2099
    if (numOfWriteViews > 0) {
3,882,339✔
2100
      pUser->legacyPrivs->pWriteViews =
×
2101
          taosHashInit(numOfWriteViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
2102
      if (pUser->legacyPrivs->pWriteViews == NULL) {
×
2103
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2104
      }
2105
    }
2106
    if (numOfAlterViews > 0) {
3,882,339✔
2107
      pUser->legacyPrivs->pAlterViews =
×
2108
          taosHashInit(numOfAlterViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
2109
      if (pUser->legacyPrivs->pAlterViews == NULL) {
×
2110
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2111
      }
2112
    }
2113
    if (numOfUseDbs > 0) {
3,882,339✔
2114
      pUser->legacyPrivs->pUseDbs =
×
2115
          taosHashInit(numOfUseDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
2116
      if (pUser->legacyPrivs->pUseDbs == NULL) {
×
2117
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2118
      }
2119
    }
2120

2121
    for (int32_t i = 0; i < numOfReadTbs; ++i) {
3,882,339✔
2122
      int32_t keyLen = 0;
×
2123
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
2124

2125
      TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
2126
      if (key == NULL) {
×
2127
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2128
      }
2129
      (void)memset(key, 0, keyLen);
×
2130
      SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
2131

2132
      int32_t valuelen = 0;
×
2133
      SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
2134
      TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
2135
      if (value == NULL) {
×
2136
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2137
      }
2138
      (void)memset(value, 0, valuelen);
×
2139
      SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
2140

2141
      TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pReadTbs, key, keyLen, value, valuelen), &lino, _OVER);
×
2142
    }
2143

2144
    for (int32_t i = 0; i < numOfWriteTbs; ++i) {
3,882,339✔
2145
      int32_t keyLen = 0;
×
2146
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
2147

2148
      TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
2149
      if (key == NULL) {
×
2150
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2151
      }
2152
      (void)memset(key, 0, keyLen);
×
2153
      SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
2154

2155
      int32_t valuelen = 0;
×
2156
      SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
2157
      TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
2158
      if (value == NULL) {
×
2159
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2160
      }
2161
      (void)memset(value, 0, valuelen);
×
2162
      SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
2163

2164
      TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pWriteTbs, key, keyLen, value, valuelen), &lino, _OVER);
×
2165
    }
2166

2167
    if (sver >= 6) {
3,882,339✔
2168
      for (int32_t i = 0; i < numOfAlterTbs; ++i) {
3,882,339✔
2169
        int32_t keyLen = 0;
×
2170
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
2171

2172
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
2173
        if (key == NULL) {
×
2174
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2175
        }
2176
        (void)memset(key, 0, keyLen);
×
2177
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
2178

2179
        int32_t valuelen = 0;
×
2180
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
2181
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
2182
        if (value == NULL) {
×
2183
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2184
        }
2185
        (void)memset(value, 0, valuelen);
×
2186
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
2187

2188
        TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pAlterTbs, key, keyLen, value, valuelen), &lino, _OVER);
×
2189
      }
2190

2191
      for (int32_t i = 0; i < numOfReadViews; ++i) {
3,882,339✔
2192
        int32_t keyLen = 0;
×
2193
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
2194

2195
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
2196
        if (key == NULL) {
×
2197
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2198
        }
2199
        (void)memset(key, 0, keyLen);
×
2200
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
2201

2202
        int32_t valuelen = 0;
×
2203
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
2204
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
2205
        if (value == NULL) {
×
2206
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2207
        }
2208
        (void)memset(value, 0, valuelen);
×
2209
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
2210

2211
        TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pReadViews, key, keyLen, value, valuelen), &lino, _OVER);
×
2212
      }
2213

2214
      for (int32_t i = 0; i < numOfWriteViews; ++i) {
3,882,339✔
2215
        int32_t keyLen = 0;
×
2216
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
2217

2218
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
2219
        if (key == NULL) {
×
2220
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2221
        }
2222
        (void)memset(key, 0, keyLen);
×
2223
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
2224

2225
        int32_t valuelen = 0;
×
2226
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
2227
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
2228
        if (value == NULL) {
×
2229
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2230
        }
2231
        (void)memset(value, 0, valuelen);
×
2232
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
2233

2234
        TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pWriteViews, key, keyLen, value, valuelen), &lino, _OVER);
×
2235
      }
2236

2237
      for (int32_t i = 0; i < numOfAlterViews; ++i) {
3,882,339✔
2238
        int32_t keyLen = 0;
×
2239
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
2240

2241
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
2242
        if (key == NULL) {
×
2243
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2244
        }
2245
        (void)memset(key, 0, keyLen);
×
2246
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
2247

2248
        int32_t valuelen = 0;
×
2249
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
2250
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
2251
        if (value == NULL) {
×
2252
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2253
        }
2254
        (void)memset(value, 0, valuelen);
×
2255
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
2256

2257
        TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pAlterViews, key, keyLen, value, valuelen), &lino, _OVER);
×
2258
      }
2259
    }
2260

2261
    for (int32_t i = 0; i < numOfUseDbs; ++i) {
3,882,339✔
2262
      int32_t keyLen = 0;
×
2263
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
2264

2265
      TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
2266
      if (key == NULL) {
×
2267
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2268
      }
2269
      (void)memset(key, 0, keyLen);
×
2270
      SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
2271

2272
      int32_t ref = 0;
×
2273
      SDB_GET_INT32(pRaw, dataPos, &ref, _OVER);
×
2274

2275
      TAOS_CHECK_GOTO(taosHashPut(pUser->legacyPrivs->pUseDbs, key, keyLen, &ref, sizeof(ref)), &lino, _OVER);
×
2276
    }
2277
  }
2278
  // decoder white list
2279
  if (sver >= USER_VER_SUPPORT_WHITELIST) {
3,882,339✔
2280
    if (sver < USER_VER_SUPPORT_WHITELIT_DUAL_STACK) {
3,882,339✔
2281
      int32_t len = 0;
×
2282
      SDB_GET_INT32(pRaw, dataPos, &len, _OVER);
×
2283

2284
      TAOS_MEMORY_REALLOC(key, len);
×
2285
      if (key == NULL) {
×
2286
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2287
      }
2288
      SDB_GET_BINARY(pRaw, dataPos, key, len, _OVER);
×
2289

2290
      SIpWhiteList *pIpWhiteList = NULL;
×
2291
      TAOS_CHECK_GOTO(createIpWhiteListFromOldVer(key, len, &pIpWhiteList), &lino, _OVER);
×
2292

2293
      SDB_GET_INT64(pRaw, dataPos, &pUser->ipWhiteListVer, _OVER);
×
2294

2295
      code = cvtIpWhiteListToDual(pIpWhiteList, &pUser->pIpWhiteListDual);
×
2296
      if (code != 0) {
×
2297
        taosMemoryFreeClear(pIpWhiteList);
×
2298
      }
2299
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2300

2301
      taosMemoryFreeClear(pIpWhiteList);
×
2302

2303
    } else if (sver >= USER_VER_SUPPORT_WHITELIT_DUAL_STACK) {
3,882,339✔
2304
      int32_t len = 0;
3,882,339✔
2305
      SDB_GET_INT32(pRaw, dataPos, &len, _OVER);
3,882,339✔
2306

2307
      TAOS_MEMORY_REALLOC(key, len);
3,882,339✔
2308
      if (key == NULL) {
3,882,339✔
2309
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2310
      }
2311
      SDB_GET_BINARY(pRaw, dataPos, key, len, _OVER);
3,882,339✔
2312

2313
      TAOS_CHECK_GOTO(createIpWhiteList(key, len, &pUser->pIpWhiteListDual, sver >= USER_VER_SUPPORT_ADVANCED_SECURITY),
3,882,339✔
2314
                      &lino, _OVER);
2315
      SDB_GET_INT64(pRaw, dataPos, &pUser->ipWhiteListVer, _OVER);
3,882,339✔
2316
    }
2317
  }
2318

2319
  if (pUser->pIpWhiteListDual == NULL) {
3,882,339✔
2320
    TAOS_CHECK_GOTO(createDefaultIpWhiteList(&pUser->pIpWhiteListDual), &lino, _OVER);
×
2321
    pUser->ipWhiteListVer = taosGetTimestampMs();
×
2322
  }
2323

2324
  SDB_GET_INT8(pRaw, dataPos, &pUser->passEncryptAlgorithm, _OVER);
3,882,339✔
2325

2326
  if (sver < USER_VER_SUPPORT_ADVANCED_SECURITY) {
3,882,339✔
2327
    memset(pUser->totpsecret, 0, sizeof(pUser->totpsecret));
×
2328
    pUser->changePass = 2;
×
2329

2330
    if (tsEnableAdvancedSecurity) {
×
2331
      pUser->sessionPerUser = pUser->superUser ? -1 : TSDB_USER_SESSION_PER_USER_DEFAULT;
×
2332
      pUser->connectTime = TSDB_USER_CONNECT_TIME_DEFAULT;
×
2333
      pUser->connectIdleTime = TSDB_USER_CONNECT_IDLE_TIME_DEFAULT;
×
2334
      pUser->callPerSession = pUser->superUser ? -1 : TSDB_USER_CALL_PER_SESSION_DEFAULT;
×
2335
      pUser->vnodePerCall = pUser->superUser ? -1 : TSDB_USER_VNODE_PER_CALL_DEFAULT;
×
2336
      pUser->failedLoginAttempts = pUser->superUser ? -1 : TSDB_USER_FAILED_LOGIN_ATTEMPTS_DEFAULT;
×
2337
      pUser->passwordLifeTime = TSDB_USER_PASSWORD_LIFE_TIME_DEFAULT;
×
2338
      pUser->passwordReuseTime = TSDB_USER_PASSWORD_REUSE_TIME_DEFAULT;
×
2339
      pUser->passwordReuseMax = TSDB_USER_PASSWORD_REUSE_MAX_DEFAULT;
×
2340
      pUser->passwordLockTime = pUser->superUser ? 1 : TSDB_USER_PASSWORD_LOCK_TIME_DEFAULT;
×
2341
      pUser->passwordGraceTime = pUser->superUser ? -1 : TSDB_USER_PASSWORD_GRACE_TIME_DEFAULT;
×
2342
      pUser->inactiveAccountTime = pUser->superUser ? -1 : TSDB_USER_INACTIVE_ACCOUNT_TIME_DEFAULT;
×
2343
    } else {
2344
      pUser->sessionPerUser = -1;
×
2345
      pUser->connectTime = -1;
×
2346
      pUser->connectIdleTime = -1;
×
2347
      pUser->callPerSession = -1;
×
2348
      pUser->vnodePerCall = -1;
×
2349
      pUser->failedLoginAttempts = -1;
×
2350
      pUser->passwordLifeTime = -1;
×
2351
      pUser->passwordReuseTime = 0;
×
2352
      pUser->passwordReuseMax = 0;
×
2353
      pUser->passwordLockTime = 1;
×
2354
      pUser->passwordGraceTime = -1;
×
2355
      pUser->inactiveAccountTime =-1;
×
2356
    }
2357

2358
    pUser->allowTokenNum = TSDB_USER_ALLOW_TOKEN_NUM_DEFAULT;
×
2359
    pUser->tokenNum = 0;
×
2360
    pUser->pTimeWhiteList = taosMemCalloc(1, sizeof(SDateTimeWhiteList));
×
2361
    if (pUser->pTimeWhiteList == NULL) {
×
2362
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2363
    }
2364
  } else {
2365
    SDB_GET_BINARY(pRaw, dataPos, pUser->totpsecret, sizeof(pUser->totpsecret), _OVER);
3,882,339✔
2366
    SDB_GET_INT8(pRaw, dataPos, &pUser->changePass, _OVER);
3,882,339✔
2367
    SDB_GET_INT32(pRaw, dataPos, &pUser->sessionPerUser, _OVER);
3,882,339✔
2368
    SDB_GET_INT32(pRaw, dataPos, &pUser->connectTime, _OVER);
3,882,339✔
2369
    SDB_GET_INT32(pRaw, dataPos, &pUser->connectIdleTime, _OVER);
3,882,339✔
2370
    SDB_GET_INT32(pRaw, dataPos, &pUser->callPerSession, _OVER);
3,882,339✔
2371
    SDB_GET_INT32(pRaw, dataPos, &pUser->vnodePerCall, _OVER);
3,882,339✔
2372
    SDB_GET_INT32(pRaw, dataPos, &pUser->failedLoginAttempts, _OVER);
3,882,339✔
2373
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordLifeTime, _OVER);
3,882,339✔
2374
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordReuseTime, _OVER);
3,882,339✔
2375
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordReuseMax, _OVER);
3,882,339✔
2376
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordLockTime, _OVER);
3,882,339✔
2377
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordGraceTime, _OVER);
3,882,339✔
2378
    SDB_GET_INT32(pRaw, dataPos, &pUser->inactiveAccountTime, _OVER);
3,882,339✔
2379
    SDB_GET_INT32(pRaw, dataPos, &pUser->allowTokenNum, _OVER);
3,882,339✔
2380
    SDB_GET_INT32(pRaw, dataPos, &pUser->tokenNum, _OVER);
3,882,339✔
2381

2382
    int32_t num = 0;
3,882,339✔
2383
    SDB_GET_INT32(pRaw, dataPos, &num, _OVER);
3,882,339✔
2384
    pUser->pTimeWhiteList = taosMemCalloc(1, sizeof(SDateTimeWhiteList) + num * sizeof(SDateTimeWhiteListItem));
3,882,339✔
2385
    if (pUser->pTimeWhiteList == NULL) {
3,882,339✔
2386
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2387
    }
2388

2389
    pUser->pTimeWhiteList->num = num;
3,882,339✔
2390
    for (int32_t i = 0; i < num; i++) {
3,886,057✔
2391
      SDateTimeWhiteListItem *range = &pUser->pTimeWhiteList->ranges[i];
3,718✔
2392
      SDB_GET_BOOL(pRaw, dataPos, &range->absolute, _OVER);
3,718✔
2393
      SDB_GET_BOOL(pRaw, dataPos, &range->neg, _OVER);
3,718✔
2394
      SDB_GET_INT64(pRaw, dataPos, &range->start, _OVER);
3,718✔
2395
      SDB_GET_INT32(pRaw, dataPos, &range->duration, _OVER);
3,718✔
2396
    }
2397

2398
    int32_t extLen = 0;
3,882,339✔
2399
    SDB_GET_INT32(pRaw, dataPos, &extLen, _OVER);
3,882,339✔
2400
    TAOS_MEMORY_REALLOC(key, extLen);
3,882,339✔
2401
    if (key == NULL) {
3,882,339✔
2402
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2403
    }
2404
    SDB_GET_BINARY(pRaw, dataPos, key, extLen, _OVER);
3,882,339✔
2405
    TAOS_CHECK_GOTO(tDeserializeUserObjExt(key, extLen, pUser), &lino, _OVER);
3,882,339✔
2406
    if (pUser->superUser && taosHashGetSize(pUser->roles) == 0) {
3,882,339✔
2407
      upgradeSecurity = 1;
×
2408
    }
2409
  }
2410

2411
#ifndef TD_ENTERPRISE
2412
  // community users cannot modify these fields, and the default values may prevent
2413
  // the user from logging in, so we set them to different values here.
2414
  pUser->sessionPerUser = -1;
2415
  pUser->connectTime = -1;
2416
  pUser->connectIdleTime = -1;
2417
  pUser->callPerSession = -1;
2418
  pUser->vnodePerCall = -1;
2419
  pUser->failedLoginAttempts = -1;
2420
  pUser->passwordLifeTime = -1;
2421
  pUser->passwordReuseTime = 0;
2422
  pUser->passwordReuseMax = 0;
2423
  pUser->passwordLockTime = -1;
2424
  pUser->passwordGraceTime = -1;
2425
  pUser->inactiveAccountTime = -1;
2426
  pUser->allowTokenNum = -1;
2427
  pUser->tokenNum = 0;
2428
#endif  // TD_ENTERPRISE
2429

2430
  SDB_GET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
3,882,339✔
2431

2432
  taosInitRWLatch(&pUser->lock);
3,882,339✔
2433
  dropOldPasswords(pUser);
3,882,339✔
2434
_OVER:
3,882,339✔
2435
  taosMemoryFree(key);
3,882,339✔
2436
  taosMemoryFree(value);
3,882,339✔
2437
  if (code < 0) {
3,882,339✔
2438
    terrno = code;
×
2439
    mError("user:%s, failed to decode at line %d from raw:%p since %s", pUser == NULL ? "null" : pUser->user, lino,
×
2440
           pRaw, tstrerror(code));
2441
    if (pUser != NULL) {
×
2442
      mndUserFreeObj(pUser);
×
2443
    }
2444
    taosMemoryFreeClear(pRow);
×
2445
    return NULL;
×
2446
  }
2447

2448
  mTrace("user:%s, decode from raw:%p, row:%p", pUser->user, pRaw, pUser);
3,882,339✔
2449
  return pRow;
3,882,339✔
2450
}
2451

2452
static int32_t mndUserActionInsert(SSdb *pSdb, SUserObj *pUser) {
634,991✔
2453
  mTrace("user:%s, perform insert action, row:%p", pUser->user, pUser);
634,991✔
2454

2455
  SAcctObj *pAcct = sdbAcquire(pSdb, SDB_ACCT, pUser->acct);
634,991✔
2456
  if (pAcct == NULL) {
634,991✔
2457
    terrno = TSDB_CODE_MND_ACCT_NOT_EXIST;
×
2458
    mError("user:%s, failed to perform insert action since %s", pUser->user, terrstr());
×
2459
    TAOS_RETURN(terrno);
×
2460
  }
2461
  pUser->acctId = pAcct->acctId;
634,991✔
2462
  sdbRelease(pSdb, pAcct);
634,991✔
2463

2464
  return 0;
634,991✔
2465
}
2466

2467
int32_t mndDupTableHash(SHashObj *pOld, SHashObj **ppNew) {
×
2468
  int32_t code = 0;
×
2469
  *ppNew =
×
2470
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
2471
  if (*ppNew == NULL) {
×
2472
    TAOS_RETURN(terrno);
×
2473
  }
2474

2475
  char *tb = taosHashIterate(pOld, NULL);
×
2476
  while (tb != NULL) {
×
2477
    size_t keyLen = 0;
×
2478
    char  *key = taosHashGetKey(tb, &keyLen);
×
2479

2480
    int32_t valueLen = strlen(tb) + 1;
×
2481
    if ((code = taosHashPut(*ppNew, key, keyLen, tb, valueLen)) != 0) {
×
2482
      taosHashCancelIterate(pOld, tb);
×
2483
      taosHashCleanup(*ppNew);
×
2484
      TAOS_RETURN(code);
×
2485
    }
2486
    tb = taosHashIterate(pOld, tb);
×
2487
  }
2488

2489
  TAOS_RETURN(code);
×
2490
}
2491

2492
int32_t mndDupRoleHash(SHashObj *pOld, SHashObj **ppNew) {
3,104,243✔
2493
  if (!(*ppNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true,
3,104,243✔
2494
                              HASH_ENTRY_LOCK))) {
2495
    TAOS_RETURN(terrno);
×
2496
  }
2497

2498
  int32_t  code = 0;
3,104,243✔
2499
  uint8_t *flag = NULL;
3,104,243✔
2500
  while ((flag = taosHashIterate(pOld, flag))) {
9,119,238✔
2501
    size_t keyLen = 0;
6,014,995✔
2502
    char  *key = taosHashGetKey(flag, &keyLen);
6,014,995✔
2503

2504
    if ((code = taosHashPut(*ppNew, key, keyLen, flag, sizeof(*flag))) != 0) {
6,014,995✔
2505
      taosHashCancelIterate(pOld, flag);
×
2506
      taosHashCleanup(*ppNew);
×
2507
      TAOS_RETURN(code);
×
2508
    }
2509
  }
2510

2511
  TAOS_RETURN(code);
3,104,243✔
2512
}
2513

2514
int32_t mndMergePrivObjHash(SHashObj *pOld, SHashObj **ppNew) {
105,507,863✔
2515
  if (!(*ppNew)) return mndDupPrivObjHash(pOld, ppNew);
105,507,863✔
2516

2517
  int32_t           code = 0, lino = 0;
105,508,928✔
2518
  SHashObj         *pNew = *ppNew;
105,508,928✔
2519
  SPrivObjPolicies *policies = NULL;
105,510,366✔
2520
  while ((policies = taosHashIterate(pOld, policies))) {
1,091,560,842✔
2521
    size_t klen = 0;
986,073,141✔
2522
    char  *key = taosHashGetKey(policies, &klen);
986,073,141✔
2523
    size_t vlen = taosHashGetValueSize(policies);
986,069,164✔
2524

2525
    SPrivObjPolicies *pNewPolicies = taosHashGet(pNew, key, klen);
986,068,099✔
2526
    if (pNewPolicies) {
986,068,889✔
2527
      size_t newVlen = taosHashGetValueSize(pNewPolicies);
628,442,811✔
2528
      if (newVlen > 0 && vlen > 0) {
628,441,566✔
2529
        privAddSet(&pNewPolicies->policy, &policies->policy);
628,441,887✔
2530
      }
2531
      continue;
628,427,980✔
2532
    }
2533

2534
    if ((code = taosHashPut(pNew, key, klen, vlen ? policies : NULL, vlen)) != 0) {
357,626,078✔
2535
      taosHashCancelIterate(pOld, policies);
2,059✔
2536
      taosHashCleanup(pNew);
×
2537
      *ppNew = NULL;
×
2538
      TAOS_RETURN(code);
×
2539
    }
2540
  }
2541

2542
  TAOS_RETURN(code);
105,512,024✔
2543
}
2544

2545
/**
2546
 * 1. Prefer to use SPrivTblPolicies from user object(the updateUs of policy in user object is INT64_MAX)
2547
 * 2. If two or more roles have SPrivTblPolicies, the policy with latest update time take effect.
2548
 */
2549
int32_t mndMergePrivTblHash(SHashObj *pOld, SHashObj **ppNew, bool updateWithLatest) {
316,529,945✔
2550
  if (!(*ppNew)) return mndDupPrivTblHash(pOld, ppNew, false);
316,529,945✔
2551

2552
  int32_t           code = 0, lino = 0;
316,530,266✔
2553
  SHashObj         *pNew = *ppNew;
316,530,266✔
2554
  SPrivTblPolicies *policies = NULL;
316,533,599✔
2555
  while ((policies = taosHashIterate(pOld, policies))) {
316,534,565✔
2556
    size_t klen = 0;
966✔
2557
    char  *key = taosHashGetKey(policies, &klen);
966✔
2558
    size_t vlen = taosHashGetValueSize(policies);
966✔
2559

2560
    SPrivTblPolicies *pNewPolicies = taosHashGet(pNew, key, klen);
966✔
2561
    if (pNewPolicies) {
966✔
2562
      size_t newVlen = taosHashGetValueSize(pNewPolicies);
966✔
2563
      if (newVlen > 0 && vlen > 0) {
966✔
2564
        TAOS_CHECK_EXIT(privTblPoliciesMerge(pNewPolicies, policies, updateWithLatest));
966✔
2565
      }
2566
      continue;
966✔
2567
    }
2568

UNCOV
2569
    SPrivTblPolicies tmpPolicies = {0};
×
UNCOV
2570
    if (vlen > 0) {
×
UNCOV
2571
      if ((code = privTblPoliciesMerge(&tmpPolicies, policies, updateWithLatest))) {
×
2572
        privTblPoliciesFree(&tmpPolicies);
2573
        goto _exit;
×
2574
      }
2575
    }
UNCOV
2576
    if ((code = taosHashPut(pNew, key, klen, vlen ? &tmpPolicies : NULL, vlen)) != 0) {
×
2577
      privTblPoliciesFree(&tmpPolicies);
2578
      taosHashCancelIterate(pOld, policies);
×
2579
      taosHashCleanup(pNew);
×
2580
      *ppNew = NULL;
×
2581
      TAOS_RETURN(code);
×
2582
    }
2583
  }
2584

2585
_exit:
316,532,545✔
2586
  TAOS_RETURN(code);
316,532,545✔
2587
}
2588

2589
int32_t mndDupKVHash(SHashObj *pOld, SHashObj **ppNew) {
38,800,460✔
2590
  if (!(*ppNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true,
38,800,460✔
2591
                              HASH_ENTRY_LOCK))) {
2592
    TAOS_RETURN(terrno);
×
2593
  }
2594
  int32_t code = 0;
38,800,299✔
2595
  void   *val = NULL;
38,800,299✔
2596
  while ((val = taosHashIterate(pOld, val))) {
125,854,910✔
2597
    size_t klen = 0;
87,057,116✔
2598
    char  *key = taosHashGetKey(val, &klen);
87,057,116✔
2599
    size_t vlen = taosHashGetValueSize(val);
87,053,942✔
2600
    if ((code = taosHashPut(*ppNew, key, klen, vlen > 0 ? val : NULL, vlen)) != 0) {
87,056,103✔
2601
      taosHashCancelIterate(pOld, val);
×
2602
      taosHashCleanup(*ppNew);
×
2603
      TAOS_RETURN(code);
×
2604
    }
2605
  }
2606

2607
  TAOS_RETURN(code);
38,802,961✔
2608
}
2609

2610
int32_t mndDupPrivObjHash(SHashObj *pOld, SHashObj **ppNew) {
38,807,382✔
2611
  if (!(*ppNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true,
38,807,382✔
2612
                              HASH_ENTRY_LOCK))) {
2613
    TAOS_RETURN(terrno);
×
2614
  }
2615
  int32_t           code = 0;
38,807,172✔
2616
  SPrivObjPolicies *policies = NULL;
38,807,172✔
2617
  while ((policies = taosHashIterate(pOld, policies))) {
90,208,654✔
2618
    size_t klen = 0;
51,401,301✔
2619
    char  *key = taosHashGetKey(policies, &klen);
51,401,301✔
2620
    size_t vlen = taosHashGetValueSize(policies);
51,401,301✔
2621

2622
    if ((code = taosHashPut(*ppNew, key, klen, vlen > 0 ? policies : NULL, vlen)) != 0) {
51,400,942✔
2623
      taosHashCancelIterate(pOld, policies);
×
2624
      taosHashCleanup(*ppNew);
×
2625
      TAOS_RETURN(code);
×
2626
    }
2627
  }
2628

2629
  TAOS_RETURN(code);
38,807,402✔
2630
}
2631

2632
int32_t mndDupPrivTblHash(SHashObj *pOld, SHashObj **ppNew, bool setUpdateTimeMax) {
119,520,894✔
2633
  if (!(*ppNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true,
119,520,894✔
2634
                              HASH_ENTRY_LOCK))) {
2635
    TAOS_RETURN(terrno);
×
2636
  }
2637
  taosHashSetFreeFp(*ppNew, privTblPoliciesFree);
119,524,673✔
2638

2639
  int32_t           code = 0, lino = 0;
119,525,176✔
2640
  SPrivTblPolicies *policies = NULL, *pTmpPolicies = NULL;
119,525,176✔
2641
  SPrivTblPolicies  tmpPolicies = {0};
119,525,176✔
2642
  while ((policies = taosHashIterate(pOld, policies))) {
120,078,129✔
2643
    size_t klen = 0;
552,405✔
2644
    char  *key = taosHashGetKey(policies, &klen);
552,405✔
2645
    size_t vlen = taosHashGetValueSize(policies);
552,405✔
2646
    memset(&tmpPolicies, 0, sizeof(tmpPolicies));
552,405✔
2647
    pTmpPolicies = &tmpPolicies;
552,405✔
2648
    if (vlen > 0) {
552,405✔
2649
      TAOS_CHECK_EXIT(privTblPoliciesAdd(&tmpPolicies, policies, true, setUpdateTimeMax));
552,405✔
2650
    }
2651
    TAOS_CHECK_EXIT(taosHashPut(*ppNew, key, klen, vlen > 0 ? &tmpPolicies : NULL, vlen));
552,405✔
2652
    pTmpPolicies = NULL;
552,405✔
2653
  }
2654

2655
_exit:
119,525,046✔
2656
  if (code != 0) {
119,525,367✔
2657
    if (!pTmpPolicies) {
×
2658
      privTblPoliciesFree(pTmpPolicies);
2659
      pTmpPolicies = NULL;
×
2660
    }
2661
    if (policies) taosHashCancelIterate(pOld, policies);
×
2662
    taosHashCleanup(*ppNew);
×
2663
    *ppNew = NULL;
×
2664
  }
2665
  TAOS_RETURN(code);
119,525,367✔
2666
}
2667

2668
int32_t mndUserDupObj(SUserObj *pUser, SUserObj *pNew) {
3,090,399✔
2669
  int32_t code = 0;
3,090,399✔
2670
  (void)memcpy(pNew, pUser, sizeof(SUserObj));
3,090,399✔
2671
  pNew->authVersion++;
3,090,399✔
2672
  pNew->updateTime = taosGetTimestampMs();
3,090,399✔
2673
  taosInitRWLatch(&pNew->lock);
3,090,399✔
2674

2675
  pNew->passwords = NULL;
3,090,399✔
2676
  pNew->pIpWhiteListDual = NULL;
3,090,399✔
2677
  pNew->passwords = NULL;
3,090,399✔
2678
  pNew->objPrivs = NULL;
3,090,399✔
2679
  pNew->selectTbs = NULL;
3,090,399✔
2680
  pNew->insertTbs = NULL;
3,090,399✔
2681
  pNew->updateTbs = NULL;
3,090,399✔
2682
  pNew->deleteTbs = NULL;
3,090,399✔
2683
  pNew->ownedDbs = NULL;
3,090,399✔
2684
  pNew->pTimeWhiteList = NULL;
3,090,399✔
2685
  pNew->roles = NULL;
3,090,399✔
2686
  pNew->legacyPrivs = NULL;
3,090,399✔
2687

2688
  taosRLockLatch(&pUser->lock);
3,090,399✔
2689
  pNew->passwords = taosMemoryCalloc(pUser->numOfPasswords, sizeof(SUserPassword));
3,090,399✔
2690
  if (pNew->passwords == NULL) {
3,090,399✔
2691
    code = TSDB_CODE_OUT_OF_MEMORY;
×
2692
    goto _OVER;
×
2693
  }
2694
  (void)memcpy(pNew->passwords, pUser->passwords, pUser->numOfPasswords * sizeof(SUserPassword));
3,090,399✔
2695
  TAOS_CHECK_GOTO(mndDupKVHash(pUser->ownedDbs, &pNew->ownedDbs), NULL, _OVER);
3,090,399✔
2696
  TAOS_CHECK_GOTO(mndDupPrivObjHash(pUser->objPrivs, &pNew->objPrivs), NULL, _OVER);
3,090,399✔
2697
  TAOS_CHECK_GOTO(mndDupPrivTblHash(pUser->selectTbs, &pNew->selectTbs, false), NULL, _OVER);
3,090,399✔
2698
  TAOS_CHECK_GOTO(mndDupPrivTblHash(pUser->insertTbs, &pNew->insertTbs, false), NULL, _OVER);
3,090,399✔
2699
  TAOS_CHECK_GOTO(mndDupPrivTblHash(pUser->updateTbs, &pNew->updateTbs, false), NULL, _OVER);
3,090,399✔
2700
  TAOS_CHECK_GOTO(mndDupPrivTblHash(pUser->deleteTbs, &pNew->deleteTbs, false), NULL, _OVER);
3,090,399✔
2701
  TAOS_CHECK_GOTO(mndDupRoleHash(pUser->roles, &pNew->roles), NULL, _OVER);
3,090,399✔
2702
  if(pUser->legacyPrivs) {
3,090,399✔
2703
    pNew->legacyPrivs = taosMemCalloc(1, sizeof(SPrivHashObjSet));
×
2704
    if (pNew->legacyPrivs == NULL) {
×
2705
      code = TSDB_CODE_OUT_OF_MEMORY;
×
2706
      goto _OVER;
×
2707
    }
2708
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pReadDbs, &pNew->legacyPrivs->pReadDbs), NULL, _OVER);
×
2709
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pWriteDbs, &pNew->legacyPrivs->pWriteDbs), NULL, _OVER);
×
2710
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pReadTbs, &pNew->legacyPrivs->pReadTbs), NULL, _OVER);
×
2711
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pWriteTbs, &pNew->legacyPrivs->pWriteTbs), NULL, _OVER);
×
2712
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pTopics, &pNew->legacyPrivs->pTopics), NULL, _OVER);
×
2713
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pAlterTbs, &pNew->legacyPrivs->pAlterTbs), NULL, _OVER);
×
2714
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pReadViews, &pNew->legacyPrivs->pReadViews), NULL, _OVER);
×
2715
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pWriteViews, &pNew->legacyPrivs->pWriteViews), NULL, _OVER);
×
2716
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pAlterViews, &pNew->legacyPrivs->pAlterViews), NULL, _OVER);
×
2717
    TAOS_CHECK_GOTO(mndDupKVHash(pUser->legacyPrivs->pUseDbs, &pNew->legacyPrivs->pUseDbs), NULL, _OVER);
×
2718
  }
2719
  pNew->pIpWhiteListDual = cloneIpWhiteList(pUser->pIpWhiteListDual);
3,090,399✔
2720
  if (pNew->pIpWhiteListDual == NULL) {
3,090,399✔
2721
    code = TSDB_CODE_OUT_OF_MEMORY;
×
2722
    goto _OVER;
×
2723
  }
2724

2725
  pNew->pTimeWhiteList = cloneDateTimeWhiteList(pUser->pTimeWhiteList);
3,090,399✔
2726
  if (pNew->pTimeWhiteList == NULL) {
3,090,399✔
2727
    code = TSDB_CODE_OUT_OF_MEMORY;
×
2728
    goto _OVER;
×
2729
  }
2730

2731
_OVER:
3,090,399✔
2732
  taosRUnLockLatch(&pUser->lock);
3,090,399✔
2733
  if (code == 0) {
3,090,399✔
2734
    dropOldPasswords(pNew);
3,090,399✔
2735
  }
2736
  TAOS_RETURN(code);
3,090,399✔
2737
}
2738

2739
void mndUserFreeObj(SUserObj *pUser) {
7,671,426✔
2740
  taosHashCleanup(pUser->ownedDbs);
7,671,426✔
2741
  taosHashCleanup(pUser->objPrivs);
7,671,426✔
2742
  taosHashCleanup(pUser->selectTbs);
7,671,426✔
2743
  taosHashCleanup(pUser->insertTbs);
7,671,426✔
2744
  taosHashCleanup(pUser->updateTbs);
7,671,426✔
2745
  taosHashCleanup(pUser->deleteTbs);
7,671,426✔
2746
  taosHashCleanup(pUser->roles);
7,671,426✔
2747
  taosMemoryFreeClear(pUser->passwords);
7,671,426✔
2748
  taosMemoryFreeClear(pUser->pIpWhiteListDual);
7,671,426✔
2749
  taosMemoryFreeClear(pUser->pTimeWhiteList);
7,671,426✔
2750
  pUser->ownedDbs = NULL;
7,671,426✔
2751
  pUser->objPrivs = NULL;
7,671,426✔
2752
  pUser->selectTbs = NULL;
7,671,426✔
2753
  pUser->insertTbs = NULL;
7,671,426✔
2754
  pUser->updateTbs = NULL;
7,671,426✔
2755
  pUser->deleteTbs = NULL;
7,671,426✔
2756
  pUser->roles = NULL;
7,671,426✔
2757
  if (pUser->legacyPrivs) {
7,671,426✔
2758
    taosHashCleanup(pUser->legacyPrivs->pReadDbs);
×
2759
    taosHashCleanup(pUser->legacyPrivs->pWriteDbs);
×
2760
    taosHashCleanup(pUser->legacyPrivs->pReadTbs);
×
2761
    taosHashCleanup(pUser->legacyPrivs->pWriteTbs);
×
2762
    taosHashCleanup(pUser->legacyPrivs->pTopics);
×
2763
    taosHashCleanup(pUser->legacyPrivs->pAlterTbs);
×
2764
    taosHashCleanup(pUser->legacyPrivs->pReadViews);
×
2765
    taosHashCleanup(pUser->legacyPrivs->pWriteViews);
×
2766
    taosHashCleanup(pUser->legacyPrivs->pAlterViews);
×
2767
    taosHashCleanup(pUser->legacyPrivs->pUseDbs);
×
2768
    taosMemoryFreeClear(pUser->legacyPrivs);
×
2769
  }
2770
}
7,671,426✔
2771

2772
static int32_t mndUserActionDelete(SSdb *pSdb, SUserObj *pUser) {
3,882,287✔
2773
  mTrace("user:%s, perform delete action, row:%p", pUser->user, pUser);
3,882,287✔
2774
  mndUserFreeObj(pUser);
3,882,287✔
2775
  return 0;
3,882,287✔
2776
}
2777

2778
static int32_t mndUserActionUpdate(SSdb *pSdb, SUserObj *pOld, SUserObj *pNew) {
3,178,339✔
2779
  mTrace("user:%s, perform update action, old row:%p new row:%p", pOld->user, pOld, pNew);
3,178,339✔
2780
  taosWLockLatch(&pOld->lock);
3,178,339✔
2781
  pOld->updateTime = pNew->updateTime;
3,178,339✔
2782
  pOld->authVersion = pNew->authVersion;
3,178,339✔
2783
  pOld->passVersion = pNew->passVersion;
3,178,339✔
2784
  pOld->sysInfo = pNew->sysInfo;
3,178,339✔
2785
  pOld->enable = pNew->enable;
3,178,339✔
2786
  pOld->flag = pNew->flag;
3,178,339✔
2787
  pOld->changePass = pNew->changePass;
3,178,339✔
2788
  pOld->uid = pNew->uid;
3,178,339✔
2789

2790
  pOld->sessionPerUser = pNew->sessionPerUser;
3,178,339✔
2791
  pOld->connectTime = pNew->connectTime;
3,178,339✔
2792
  pOld->connectIdleTime = pNew->connectIdleTime;
3,178,339✔
2793
  pOld->callPerSession = pNew->callPerSession;
3,178,339✔
2794
  pOld->vnodePerCall = pNew->vnodePerCall;
3,178,339✔
2795
  pOld->failedLoginAttempts = pNew->failedLoginAttempts;
3,178,339✔
2796
  pOld->passwordLifeTime = pNew->passwordLifeTime;
3,178,339✔
2797
  pOld->passwordReuseTime = pNew->passwordReuseTime;
3,178,339✔
2798
  pOld->passwordReuseMax = pNew->passwordReuseMax;
3,178,339✔
2799
  pOld->passwordLockTime = pNew->passwordLockTime;
3,178,339✔
2800
  pOld->passwordGraceTime = pNew->passwordGraceTime;
3,178,339✔
2801
  pOld->inactiveAccountTime = pNew->inactiveAccountTime;
3,178,339✔
2802
  pOld->allowTokenNum = pNew->allowTokenNum;
3,178,339✔
2803
  pOld->tokenNum = pNew->tokenNum;
3,178,339✔
2804

2805
  pOld->numOfPasswords = pNew->numOfPasswords;
3,178,339✔
2806
  TSWAP(pOld->passwords, pNew->passwords);
3,178,339✔
2807
  (void)memcpy(pOld->salt, pNew->salt, sizeof(pOld->salt));
3,178,339✔
2808
  (void)memcpy(pOld->totpsecret, pNew->totpsecret, sizeof(pOld->totpsecret));
3,178,339✔
2809
  pOld->sysPrivs = pNew->sysPrivs;
3,178,339✔
2810
  TSWAP(pOld->ownedDbs, pNew->ownedDbs);
3,178,339✔
2811
  TSWAP(pOld->objPrivs, pNew->objPrivs);
3,178,339✔
2812
  TSWAP(pOld->selectTbs, pNew->selectTbs);
3,178,339✔
2813
  TSWAP(pOld->insertTbs, pNew->insertTbs);
3,178,339✔
2814
  TSWAP(pOld->updateTbs, pNew->updateTbs);
3,178,339✔
2815
  TSWAP(pOld->deleteTbs, pNew->deleteTbs);
3,178,339✔
2816
  TSWAP(pOld->roles, pNew->roles);
3,178,339✔
2817
  TSWAP(pOld->legacyPrivs, pNew->legacyPrivs);
3,178,339✔
2818

2819
  TSWAP(pOld->pIpWhiteListDual, pNew->pIpWhiteListDual);
3,178,339✔
2820
  pOld->ipWhiteListVer = pNew->ipWhiteListVer;
3,178,339✔
2821
  TSWAP(pOld->pTimeWhiteList, pNew->pTimeWhiteList);
3,178,339✔
2822
  pOld->timeWhiteListVer = pNew->timeWhiteListVer;
3,178,339✔
2823
  pOld->passEncryptAlgorithm = pNew->passEncryptAlgorithm;
3,178,339✔
2824

2825
  taosWUnLockLatch(&pOld->lock);
3,178,339✔
2826

2827
  return 0;
3,178,339✔
2828
}
2829

2830
int32_t mndAcquireUser(SMnode *pMnode, const char *userName, SUserObj **ppUser) {
122,720,760✔
2831
  int32_t code = 0;
122,720,760✔
2832
  SSdb   *pSdb = pMnode->pSdb;
122,720,760✔
2833

2834
  *ppUser = sdbAcquire(pSdb, SDB_USER, userName);
122,721,605✔
2835
  if (*ppUser == NULL) {
122,722,716✔
2836
    if (terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
129,418✔
2837
      code = TSDB_CODE_MND_USER_NOT_EXIST;
129,418✔
2838
    } else {
2839
      code = TSDB_CODE_MND_USER_NOT_AVAILABLE;
×
2840
    }
2841
  }
2842
  TAOS_RETURN(code);
122,722,716✔
2843
}
2844

2845
void mndReleaseUser(SMnode *pMnode, SUserObj *pUser) {
187,138,062✔
2846
  SSdb *pSdb = pMnode->pSdb;
187,138,062✔
2847
  sdbRelease(pSdb, pUser);
187,141,795✔
2848
}
187,143,479✔
2849

2850
int32_t mndAcquireUserById(SMnode *pMnode, int64_t userId, SUserObj **ppUser) {
×
2851
  void     *pIter = NULL;
×
2852
  SUserObj *pObj;
×
2853
  SSdb     *pSdb = pMnode->pSdb;
×
2854
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pObj))) {
×
2855
    if (pObj->uid == userId) {
×
2856
      return mndAcquireUser(pMnode, pObj->user, ppUser);
×
2857
    }
2858
  }
2859
  return 0;
×
2860
}
2861

2862
int32_t mndBuildUidNamesHash(SMnode *pMnode, SSHashObj **ppHash) {
612,983✔
2863
  int32_t    code = 0;
612,983✔
2864
  void      *pIter = NULL;
612,983✔
2865
  SUserObj  *pObj;
610,805✔
2866
  SSHashObj *pHash = NULL;
612,983✔
2867

2868
  int32_t nUser = sdbGetSize(pMnode->pSdb, SDB_USER);
612,983✔
2869

2870
  pHash = tSimpleHashInit(nUser, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT));
612,983✔
2871
  if (pHash == NULL) {
612,983✔
2872
    TAOS_RETURN(terrno);
×
2873
  }
2874

2875
  while ((pIter = sdbFetch(pMnode->pSdb, SDB_USER, pIter, (void **)&pObj))) {
1,474,886✔
2876
    code = tSimpleHashPut(pHash, &pObj->uid, sizeof(pObj->uid), pObj->name, strlen(pObj->name) + 1);
861,903✔
2877
    if (code != 0) {
861,903✔
2878
      sdbRelease(pMnode->pSdb, pObj);
×
2879
      sdbCancelFetch(pMnode->pSdb, pIter);
×
2880
      tSimpleHashCleanup(pHash);
×
2881
      TAOS_RETURN(code);
×
2882
    }
2883
    sdbRelease(pMnode->pSdb, pObj);
861,903✔
2884
  }
2885

2886
  *ppHash = pHash;
612,983✔
2887
  TAOS_RETURN(code);
612,983✔
2888
}
2889

2890
int32_t mndEncryptPass(char *pass, const char *salt, int8_t *algo) {
5,370✔
2891
  int32_t code = 0;
5,370✔
2892

2893
  if (salt[0] != 0) {
5,370✔
2894
    char passAndSalt[TSDB_PASSWORD_LEN - 1 + TSDB_PASSWORD_SALT_LEN];
5,332✔
2895
    (void)memcpy(passAndSalt, pass, TSDB_PASSWORD_LEN - 1);
5,370✔
2896
    (void)memcpy(passAndSalt + TSDB_PASSWORD_LEN - 1, salt, TSDB_PASSWORD_SALT_LEN);
5,370✔
2897
    taosEncryptPass_c((uint8_t *)passAndSalt, sizeof(passAndSalt), pass);
2898
  }
2899

2900
  unsigned char packetData[TSDB_PASSWORD_LEN] = {0};
5,370✔
2901
  SCryptOpts    opts = {0};
5,370✔
2902
  opts.len = TSDB_PASSWORD_LEN;
5,370✔
2903
  opts.source = pass;
5,370✔
2904
  opts.result = packetData;
5,370✔
2905
  opts.unitLen = TSDB_PASSWORD_LEN;
5,370✔
2906
  tstrncpy(opts.key, tsDataKey, ENCRYPT_KEY_LEN + 1);
5,370✔
2907
  int newLen = Builtin_CBC_Encrypt(&opts);
5,370✔
2908
  if (newLen <= 0) return terrno;
5,370✔
2909

2910
  memcpy(pass, packetData, newLen);
5,370✔
2911
  if (algo != NULL) {
5,370✔
2912
    *algo = DND_CA_SM4;
2,724✔
2913
  }
2914

2915
  return TSDB_CODE_SUCCESS;
5,370✔
2916
}
2917

2918
static void generateSalt(char *salt, size_t len) {
106,606✔
2919
  const char *set = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
106,606✔
2920
  int32_t     setLen = 62;
106,606✔
2921
  for (int32_t i = 0; i < len - 1; ++i) {
3,411,392✔
2922
    salt[i] = set[taosSafeRand() % setLen];
3,304,786✔
2923
  }
2924
  salt[len - 1] = 0;
106,606✔
2925
}
106,606✔
2926

2927
static int32_t addDefaultIpToTable(SHashObj *pUniqueTab) {
1,427✔
2928
  int32_t code = 0;
1,427✔
2929
  int32_t lino = 0;
1,427✔
2930
  int32_t dummy = 0;
1,427✔
2931

2932
  SIpRange ipv4 = {0}, ipv6 = {0};
1,427✔
2933
  code = createDefaultIp4Range(&ipv4);
1,427✔
2934
  TSDB_CHECK_CODE(code, lino, _error);
1,427✔
2935

2936
  code = taosHashPut(pUniqueTab, &ipv4, sizeof(ipv4), &dummy, sizeof(dummy));
1,427✔
2937
  TSDB_CHECK_CODE(code, lino, _error);
1,427✔
2938

2939
  code = createDefaultIp6Range(&ipv6);
1,427✔
2940
  TSDB_CHECK_CODE(code, lino, _error);
1,427✔
2941

2942
  code = taosHashPut(pUniqueTab, &ipv6, sizeof(ipv6), &dummy, sizeof(dummy));
1,427✔
2943
  TSDB_CHECK_CODE(code, lino, _error);
1,427✔
2944
    
2945
_error:
1,427✔
2946
  if (code != 0) {
1,427✔
2947
    mError("failed to add default ip range to table since %s", tstrerror(code));
×
2948
  }
2949
  return code;
1,427✔
2950
}
2951

2952
static int32_t mndCreateUser(SMnode *pMnode, char *acct, SCreateUserReq *pCreate, SRpcMsg *pReq) {
104,075✔
2953
  int32_t  code = 0;
104,075✔
2954
  int32_t  lino = 0;
104,075✔
2955
  SUserObj userObj = {0};
104,075✔
2956

2957
  userObj.passwords = taosMemoryCalloc(1, sizeof(SUserPassword));
104,075✔
2958
  if (userObj.passwords == NULL) {
104,075✔
2959
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2960
  }
2961
  userObj.numOfPasswords = 1;
104,075✔
2962

2963
  if (pCreate->isImport == 1) {
104,075✔
2964
    memset(userObj.salt, 0, sizeof(userObj.salt));
×
2965
    memcpy(userObj.passwords[0].pass, pCreate->pass, TSDB_PASSWORD_LEN);
×
2966
  } else {
2967
    generateSalt(userObj.salt, sizeof(userObj.salt));
104,075✔
2968
    taosEncryptPass_c((uint8_t *)pCreate->pass, strlen(pCreate->pass), userObj.passwords[0].pass);
104,075✔
2969
    userObj.passwords[0].pass[sizeof(userObj.passwords[0].pass) - 1] = 0;
104,075✔
2970
    if (strlen(tsDataKey) > 0) {
104,075✔
2971
      TAOS_CHECK_GOTO(mndEncryptPass(userObj.passwords[0].pass, userObj.salt, &userObj.passEncryptAlgorithm), &lino,
396✔
2972
                      _OVER);
2973
    }
2974
  }
2975
  userObj.passwords[0].setTime = taosGetTimestampSec();
104,075✔
2976

2977
  tstrncpy(userObj.user, pCreate->user, TSDB_USER_LEN);
104,075✔
2978
  tstrncpy(userObj.acct, acct, TSDB_USER_LEN);
104,075✔
2979
  if (pCreate->totpseed[0] != 0) {
104,075✔
2980
    int len = taosGenerateTotpSecret(pCreate->totpseed, 0, userObj.totpsecret, sizeof(userObj.totpsecret));
×
2981
    if (len < 0) {
×
2982
      TAOS_CHECK_GOTO(TSDB_CODE_PAR_INVALID_OPTION_VALUE, &lino, _OVER);
×
2983
    }
2984
  }
2985

2986
  userObj.createdTime = taosGetTimestampMs();
104,075✔
2987
  userObj.updateTime = userObj.createdTime;
104,075✔
2988
  userObj.superUser = 0;  // pCreate->superUser;
104,075✔
2989
  userObj.sysInfo = pCreate->sysInfo;
104,075✔
2990
  userObj.enable = pCreate->enable;
104,075✔
2991
  userObj.createdb = pCreate->createDb;
104,075✔
2992
  userObj.uid = mndGenerateUid(userObj.user, strlen(userObj.user));
104,075✔
2993
  userObj.minSecLevel = (uint8_t)pCreate->minSecLevel;
104,075✔
2994
  userObj.maxSecLevel = (uint8_t)pCreate->maxSecLevel;
104,075✔
2995

2996
  if (userObj.createdb == 1) {
104,075✔
2997
    privAddType(&userObj.sysPrivs, PRIV_DB_CREATE);
2998
  }
2999

3000
#ifdef TD_ENTERPRISE
3001

3002
  userObj.changePass = pCreate->changepass;
104,075✔
3003
  userObj.sessionPerUser = pCreate->sessionPerUser;
104,075✔
3004
  userObj.connectTime = pCreate->connectTime;
104,075✔
3005
  userObj.connectIdleTime = pCreate->connectIdleTime;
104,075✔
3006
  userObj.callPerSession = pCreate->callPerSession;
104,075✔
3007
  userObj.vnodePerCall = pCreate->vnodePerCall;
104,075✔
3008
  userObj.failedLoginAttempts = pCreate->failedLoginAttempts;
104,075✔
3009
  userObj.passwordLifeTime = pCreate->passwordLifeTime;
104,075✔
3010
  userObj.passwordReuseTime = pCreate->passwordReuseTime;
104,075✔
3011
  userObj.passwordReuseMax = pCreate->passwordReuseMax;
104,075✔
3012
  userObj.passwordLockTime = pCreate->passwordLockTime;
104,075✔
3013
  userObj.passwordGraceTime = pCreate->passwordGraceTime;
104,075✔
3014
  userObj.inactiveAccountTime = pCreate->inactiveAccountTime;
104,075✔
3015
  userObj.allowTokenNum = pCreate->allowTokenNum;
104,075✔
3016
  userObj.tokenNum = 0;
104,075✔
3017

3018
  if (pCreate->numIpRanges == 0) {
104,075✔
3019
    TAOS_CHECK_GOTO(createDefaultIpWhiteList(&userObj.pIpWhiteListDual), &lino, _OVER);
102,141✔
3020
  } else {
3021
    SHashObj *pUniqueTab = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
1,934✔
3022
    if (pUniqueTab == NULL) {
1,934✔
3023
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3024
    }
3025
    
3026
    bool hasPositive = false;
1,934✔
3027
    for (int i = 0; i < pCreate->numIpRanges; i++) {
4,769✔
3028
      SIpRange range = {0};
2,835✔
3029
      copyIpRange(&range, pCreate->pIpDualRanges + i);
2,835✔
3030
      hasPositive = hasPositive || !range.neg;
2,835✔
3031
      int32_t dummy = 0;
2,835✔
3032
      if ((code = taosHashPut(pUniqueTab, &range, sizeof(range), &dummy, sizeof(dummy))) != 0) {
2,835✔
3033
        taosHashCleanup(pUniqueTab);
×
3034
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3035
      }
3036
    }
3037

3038
    // add local ip if there is any positive range
3039
    if (hasPositive) {
1,934✔
3040
      code = addDefaultIpToTable(pUniqueTab);
1,427✔
3041
      if (code != 0) {
1,427✔
3042
        taosHashCleanup(pUniqueTab);
×
3043
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3044
      }
3045
    }
3046

3047
    if (taosHashGetSize(pUniqueTab) > MND_MAX_USER_IP_RANGE) {
1,934✔
3048
      taosHashCleanup(pUniqueTab);
×
3049
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_IP_RANGE, &lino, _OVER);
×
3050
    }
3051

3052
    int32_t           numOfRanges = taosHashGetSize(pUniqueTab);
1,934✔
3053
    SIpWhiteListDual *p = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + numOfRanges * sizeof(SIpRange));
1,934✔
3054
    if (p == NULL) {
1,934✔
3055
      taosHashCleanup(pUniqueTab);
×
3056
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3057
    }
3058

3059
    void *pIter = taosHashIterate(pUniqueTab, NULL);
1,934✔
3060
    for (int32_t i = 0; i < numOfRanges; i++) {
7,226✔
3061
      size_t    len = 0;
5,292✔
3062
      SIpRange *key = taosHashGetKey(pIter, &len);
5,292✔
3063
      memcpy(&p->pIpRanges[i], key, sizeof(SIpRange));
5,292✔
3064
      pIter = taosHashIterate(pUniqueTab, pIter);
5,292✔
3065
    }
3066

3067
    taosHashCleanup(pUniqueTab);
1,934✔
3068
    p->num = numOfRanges;
1,934✔
3069
    sortIpWhiteList(p);
1,934✔
3070
    userObj.pIpWhiteListDual = p;
1,934✔
3071
  }
3072

3073
  if (pCreate->numTimeRanges == 0) {
104,075✔
3074
    userObj.pTimeWhiteList = (SDateTimeWhiteList *)taosMemoryCalloc(1, sizeof(SDateTimeWhiteList));
101,878✔
3075
    if (userObj.pTimeWhiteList == NULL) {
101,878✔
3076
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3077
    }
3078
  } else {
3079
    SHashObj *pUniqueTab = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
2,197✔
3080
    if (pUniqueTab == NULL) {
2,197✔
3081
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3082
    }
3083

3084
    for (int i = 0; i < pCreate->numTimeRanges; i++) {
4,901✔
3085
      SDateTimeRange        *src = pCreate->pTimeRanges + i;
2,704✔
3086
      SDateTimeWhiteListItem range = {0};
2,704✔
3087
      DateTimeRangeToWhiteListItem(&range, src);
2,704✔
3088

3089
      // no need to add expired range
3090
      if (isDateTimeWhiteListItemExpired(&range)) {
2,704✔
3091
        continue;
338✔
3092
      }
3093

3094
      int32_t dummy = 0;
2,366✔
3095
      if ((code = taosHashPut(pUniqueTab, &range, sizeof(range), &dummy, sizeof(dummy))) != 0) {
2,366✔
3096
        taosHashCleanup(pUniqueTab);
×
3097
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3098
      }
3099
    }
3100

3101
    if (taosHashGetSize(pUniqueTab) > MND_MAX_USER_TIME_RANGE) {
2,197✔
3102
      taosHashCleanup(pUniqueTab);
×
3103
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_TIME_RANGE, &lino, _OVER);
×
3104
    }
3105

3106
    int32_t             numOfRanges = taosHashGetSize(pUniqueTab);
2,197✔
3107
    SDateTimeWhiteList *p =
4,394✔
3108
        taosMemoryCalloc(1, sizeof(SDateTimeWhiteList) + numOfRanges * sizeof(SDateTimeWhiteListItem));
2,197✔
3109
    if (p == NULL) {
2,197✔
3110
      taosHashCleanup(pUniqueTab);
×
3111
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3112
    }
3113

3114
    void *pIter = taosHashIterate(pUniqueTab, NULL);
2,197✔
3115
    for (int32_t i = 0; i < numOfRanges; i++) {
4,563✔
3116
      size_t                  len = 0;
2,366✔
3117
      SDateTimeWhiteListItem *key = taosHashGetKey(pIter, &len);
2,366✔
3118
      memcpy(p->ranges + i, key, sizeof(SDateTimeWhiteListItem));
2,366✔
3119
      pIter = taosHashIterate(pUniqueTab, pIter);
2,366✔
3120
    }
3121

3122
    taosHashCleanup(pUniqueTab);
2,197✔
3123
    p->num = numOfRanges;
2,197✔
3124
    sortTimeWhiteList(p);
2,197✔
3125
    userObj.pTimeWhiteList = p;
2,197✔
3126
  }
3127

3128
  userObj.ipWhiteListVer = taosGetTimestampMs();
104,075✔
3129
  userObj.timeWhiteListVer = userObj.ipWhiteListVer;
104,075✔
3130
  
3131

3132
#else  // TD_ENTERPRISE
3133

3134
  userObj.changePass = 1;
3135
  userObj.sessionPerUser = -1;
3136
  userObj.connectTime = -1;
3137
  userObj.connectIdleTime = -1;
3138
  userObj.callPerSession = -1;
3139
  userObj.vnodePerCall = -1;
3140
  userObj.failedLoginAttempts = -1;
3141
  userObj.passwordLifeTime = -1;
3142
  userObj.passwordReuseTime = 0;
3143
  userObj.passwordReuseMax = 0;
3144
  userObj.passwordLockTime = -1;
3145
  userObj.passwordGraceTime = -1;
3146
  userObj.inactiveAccountTime = -1;
3147
  userObj.allowTokenNum = -1;
3148
  userObj.tokenNum = 0;
3149

3150
  TAOS_CHECK_GOTO(createDefaultIpWhiteList(&userObj.pIpWhiteListDual), &lino, _OVER);
3151
  userObj.pTimeWhiteList = (SDateTimeWhiteList *)taosMemoryCalloc(1, sizeof(SDateTimeWhiteList));
3152
  if (userObj.pTimeWhiteList == NULL) {
3153
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
3154
  }
3155

3156
  userObj.ipWhiteListVer = 0;
3157
  userObj.timeWhiteListVer = 0;
3158

3159
#endif  // TD_ENTERPRISE
3160

3161
  userObj.roles = taosHashInit(1, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
104,075✔
3162
  if (userObj.roles == NULL) {
104,075✔
3163
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3164
  }
3165

3166
  uint8_t flag = 0x01;
104,075✔
3167
  if ((code = taosHashPut(userObj.roles, TSDB_ROLE_DEFAULT, sizeof(TSDB_ROLE_DEFAULT), &flag, sizeof(flag))) != 0) {
104,075✔
3168
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3169
  }
3170

3171
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "create-user");
104,075✔
3172
  if (pTrans == NULL) {
104,075✔
3173
    mError("user:%s, failed to create since %s", pCreate->user, terrstr());
×
3174
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3175
  }
3176
  mInfo("trans:%d, used to create user:%s", pTrans->id, pCreate->user);
104,075✔
3177

3178
  SSdbRaw *pCommitRaw = mndUserActionEncode(&userObj);
104,075✔
3179
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
104,075✔
3180
    mError("trans:%d, failed to commit redo log since %s", pTrans->id, terrstr());
×
3181
    mndTransDrop(pTrans);
×
3182
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3183
  }
3184
  TAOS_CHECK_GOTO(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY), &lino, _OVER);
104,075✔
3185

3186
  if (mndTransPrepare(pMnode, pTrans) != 0) {
104,075✔
3187
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
3188
    mndTransDrop(pTrans);
×
3189
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3190
  }
3191

3192
  if ((code = userCacheUpdateWhiteList(pMnode, &userObj)) != 0) {
104,075✔
3193
    mndTransDrop(pTrans);
×
3194
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3195
  }
3196

3197
  if (taosHashGet(userObj.roles, TSDB_ROLE_SYSAUDIT_LOG, sizeof(TSDB_ROLE_SYSAUDIT_LOG))) {
104,075✔
3198
    (void)mndResetAuditLogUser(pMnode, userObj.user, true);
×
3199
  }
3200

3201
  mndTransDrop(pTrans);
104,075✔
3202

3203
_OVER:
104,075✔
3204
  mndUserFreeObj(&userObj);
104,075✔
3205
  TAOS_RETURN(code);
104,075✔
3206
}
3207

3208
static int32_t mndCheckPasswordFmt(const char *pwd) {
154,573✔
3209
  if (tsEnableAdvancedSecurity == 0 && strcmp(pwd, "taosdata") == 0) {
154,573✔
3210
    return 0;
×
3211
  }
3212

3213
  if (tsEnableStrongPassword == 0) {
154,573✔
3214
    for (char c = *pwd; c != 0; c = *(++pwd)) {
124,030✔
3215
      if (c == ' ' || c == '\'' || c == '\"' || c == '`' || c == '\\') {
116,507✔
3216
        return TSDB_CODE_MND_INVALID_PASS_FORMAT;
×
3217
      }
3218
    }
3219
    return 0;
7,523✔
3220
  }
3221

3222
  int32_t len = strlen(pwd);
147,050✔
3223
  if (len < TSDB_PASSWORD_MIN_LEN) {
147,050✔
3224
    return TSDB_CODE_PAR_PASSWD_TOO_SHORT_OR_EMPTY;
×
3225
  }
3226

3227
  if (len > TSDB_PASSWORD_MAX_LEN) {
147,050✔
3228
    return TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG;
×
3229
  }
3230

3231
  if (taosIsComplexString(pwd)) {
147,050✔
3232
    return 0;
123,050✔
3233
  }
3234

3235
  return TSDB_CODE_MND_INVALID_PASS_FORMAT;
24,000✔
3236
}
3237

3238
static int32_t mndCheckTotpSeedFmt(const char *seed) {
×
3239
  int32_t len = strlen(seed);
×
3240
  if (len < TSDB_USER_TOTPSEED_MIN_LEN) {
×
3241
    return TSDB_CODE_PAR_OPTION_VALUE_TOO_SHORT;
×
3242
  }
3243

3244
  if (taosIsComplexString(seed)) {
×
3245
    return 0;
×
3246
  }
3247

3248
  return TSDB_CODE_PAR_INVALID_OPTION_VALUE;
×
3249
}
3250

3251
static int32_t mndProcessGetUserDateTimeWhiteListReq(SRpcMsg *pReq) {
×
3252
  SMnode                *pMnode = pReq->info.node;
×
3253
  int32_t                code = 0;
×
3254
  int32_t                lino = 0;
×
3255
  int32_t                contLen = 0;
×
3256
  void                  *pRsp = NULL;
×
3257
  SUserObj              *pUser = NULL;
×
3258
  SGetUserWhiteListReq   wlReq = {0};
×
3259
  SUserDateTimeWhiteList wlRsp = {0};
×
3260

3261
  if (tDeserializeSGetUserWhiteListReq(pReq->pCont, pReq->contLen, &wlReq) != 0) {
×
3262
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
3263
  }
3264
  mTrace("user: %s, start to get date time whitelist", wlReq.user);
×
3265

3266
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, wlReq.user, &pUser), &lino, _OVER);
×
3267
  TAOS_CHECK_GOTO(mndSetUserDateTimeWhiteListRsp(pMnode, pUser, &wlRsp), &lino, _OVER);
×
3268

3269
  contLen = tSerializeSUserDateTimeWhiteList(NULL, 0, &wlRsp);
×
3270
  if (contLen < 0) {
×
3271
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3272
  }
3273
  pRsp = rpcMallocCont(contLen);
×
3274
  if (pRsp == NULL) {
×
3275
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3276
  }
3277

3278
  contLen = tSerializeSUserDateTimeWhiteList(pRsp, contLen, &wlRsp);
×
3279
  if (contLen < 0) {
×
3280
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3281
  }
3282

3283
_OVER:
×
3284
  mndReleaseUser(pMnode, pUser);
×
3285
  tFreeSUserDateTimeWhiteList(&wlRsp);
×
3286
  if (code < 0) {
×
3287
    mError("user:%s, failed to get whitelist at line %d since %s", wlReq.user, lino, tstrerror(code));
×
3288
    rpcFreeCont(pRsp);
×
3289
    pRsp = NULL;
×
3290
    contLen = 0;
×
3291
  }
3292
  pReq->code = code;
×
3293
  pReq->info.rsp = pRsp;
×
3294
  pReq->info.rspLen = contLen;
×
3295

3296
  TAOS_RETURN(code);
×
3297
  return 0;
3298
}
3299

3300
static int32_t buildRetrieveDateTimeWhiteListRsp(SRetrieveDateTimeWhiteListRsp *pRsp) {
561✔
3301
  (void)taosThreadRwlockRdlock(&userCache.rw);
561✔
3302

3303
  int32_t count = taosHashGetSize(userCache.users);
561✔
3304
  pRsp->pUsers = taosMemoryCalloc(count, sizeof(SUserDateTimeWhiteList));
561✔
3305
  if (pRsp->pUsers == NULL) {
561✔
3306
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
3307
    TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
3308
  }
3309

3310
  count = 0;
561✔
3311
  void *pIter = taosHashIterate(userCache.users, NULL);
561✔
3312
  while (pIter) {
1,122✔
3313
    SDateTimeWhiteList *wl = (*(SCachedUserInfo **)pIter)->wlTime;
561✔
3314
    if (wl == NULL || wl->num <= 0) {
561✔
3315
      pIter = taosHashIterate(userCache.users, pIter);
561✔
3316
      continue;
561✔
3317
    }
3318

3319
    SUserDateTimeWhiteList *pUser = &pRsp->pUsers[count];
×
3320
    pUser->ver = userCache.verTime;
×
3321

3322
    size_t klen;
×
3323
    char  *key = taosHashGetKey(pIter, &klen);
×
3324
    (void)memcpy(pUser->user, key, klen);
×
3325

3326
    pUser->numWhiteLists = wl->num;
×
3327
    pUser->pWhiteLists = taosMemoryCalloc(wl->num, sizeof(SDateTimeWhiteListItem));
×
3328
    if (pUser->pWhiteLists == NULL) {
×
3329
      (void)taosThreadRwlockUnlock(&userCache.rw);
×
3330
      TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
3331
    }
3332

3333
    (void)memcpy(pUser->pWhiteLists, wl->ranges, wl->num * sizeof(SDateTimeWhiteListItem));
×
3334
    count++;
×
3335
    pIter = taosHashIterate(userCache.users, pIter);
×
3336
  }
3337

3338
  pRsp->numOfUser = count;
561✔
3339
  pRsp->ver = userCache.verTime;
561✔
3340
  (void)taosThreadRwlockUnlock(&userCache.rw);
561✔
3341
  TAOS_RETURN(0);
561✔
3342
}
3343

3344
static int32_t mndProcessRetrieveDateTimeWhiteListReq(SRpcMsg *pReq) {
561✔
3345
  int32_t                       code = 0;
561✔
3346
  int32_t                       lino = 0;
561✔
3347
  int32_t                       len = 0;
561✔
3348
  void                         *pRsp = NULL;
561✔
3349
  SRetrieveDateTimeWhiteListRsp wlRsp = {0};
561✔
3350

3351
  // impl later
3352
  SRetrieveWhiteListReq req = {0};
561✔
3353
  if (tDeserializeRetrieveWhiteListReq(pReq->pCont, pReq->contLen, &req) != 0) {
561✔
3354
    code = TSDB_CODE_INVALID_MSG;
×
3355
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3356
  }
3357

3358
  TAOS_CHECK_GOTO(buildRetrieveDateTimeWhiteListRsp(&wlRsp), &lino, _OVER);
561✔
3359

3360
  len = tSerializeSRetrieveDateTimeWhiteListRsp(NULL, 0, &wlRsp);
561✔
3361
  if (len < 0) {
561✔
3362
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
3363
  }
3364

3365
  pRsp = rpcMallocCont(len);
561✔
3366
  if (!pRsp) {
561✔
3367
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3368
  }
3369
  len = tSerializeSRetrieveDateTimeWhiteListRsp(pRsp, len, &wlRsp);
561✔
3370
  if (len < 0) {
561✔
3371
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
3372
  }
3373

3374
_OVER:
561✔
3375
  if (code < 0) {
561✔
3376
    mError("failed to process retrieve ip white request at line %d since %s", lino, tstrerror(code));
×
3377
    rpcFreeCont(pRsp);
×
3378
    pRsp = NULL;
×
3379
    len = 0;
×
3380
  }
3381
  pReq->code = code;
561✔
3382
  pReq->info.rsp = pRsp;
561✔
3383
  pReq->info.rspLen = len;
561✔
3384

3385
  tFreeSRetrieveDateTimeWhiteListRsp(&wlRsp);
561✔
3386
  TAOS_RETURN(code);
561✔
3387
}
3388

3389
static int32_t mndProcessCreateUserReq(SRpcMsg *pReq) {
116,848✔
3390
  SMnode        *pMnode = pReq->info.node;
116,848✔
3391
  int32_t        code = 0;
116,848✔
3392
  int32_t        lino = 0;
116,848✔
3393
  SRoleObj      *pRole = NULL;
116,848✔
3394
  SUserObj      *pUser = NULL;
116,848✔
3395
  SUserObj      *pOperUser = NULL;
116,848✔
3396
  SCreateUserReq createReq = {0};
116,848✔
3397
  int64_t        tss = taosGetTimestampMs();
116,848✔
3398

3399
  if (tDeserializeSCreateUserReq(pReq->pCont, pReq->contLen, &createReq) != 0) {
116,848✔
3400
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
3401
  }
3402

3403
  mInfo("user:%s, start to create, createdb:%d, is_import:%d", createReq.user, createReq.createDb, createReq.isImport);
116,848✔
3404

3405
#ifndef TD_ENTERPRISE
3406
  if (createReq.isImport == 1) {
3407
    TAOS_CHECK_GOTO(TSDB_CODE_OPS_NOT_SUPPORT, &lino, _OVER);  // enterprise feature
3408
  }
3409
#endif
3410
  code = mndAcquireUser(pMnode, RPC_MSG_USER(pReq), &pOperUser);
116,848✔
3411
  if (pOperUser == NULL) {
116,848✔
3412
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_USER_FROM_CONN, &lino, _OVER);
×
3413
  }
3414

3415
  if (createReq.isImport != 1) {
116,848✔
3416
    // TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, RPC_MSG_USER(pReq), MND_OPER_CREATE_USER), &lino, _OVER);
3417
    TAOS_CHECK_GOTO(mndCheckSysObjPrivilege(pMnode, pOperUser, RPC_MSG_TOKEN(pReq), PRIV_USER_CREATE, 0, 0, NULL, NULL),
116,848✔
3418
                    &lino, _OVER);
3419
  } else if (strcmp(RPC_MSG_USER(pReq), "root") != 0) {
×
3420
    mError("The operation is not permitted to create user:%s", RPC_MSG_USER(pReq));
×
3421
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_RIGHTS, &lino, _OVER);
×
3422
  }
3423

3424
  if (createReq.user[0] == 0) {
116,848✔
3425
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
3426
  }
3427

3428
  if (createReq.isImport != 1) {
116,848✔
3429
    code = mndCheckPasswordFmt(createReq.pass);
116,848✔
3430
    TAOS_CHECK_GOTO(code, &lino, _OVER);
116,848✔
3431
  }
3432

3433
  if (createReq.totpseed[0] != 0) {
104,651✔
3434
    code = mndCheckTotpSeedFmt(createReq.totpseed);
×
3435
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3436
  }
3437

3438
  code = mndAcquireUser(pMnode, createReq.user, &pUser);
104,651✔
3439
  if (pUser != NULL) {
104,651✔
3440
    TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_ALREADY_EXIST, &lino, _OVER);
398✔
3441
  }
3442

3443
  code = mndAcquireRole(pMnode, createReq.user, &pRole);
104,253✔
3444
  if (pRole != NULL) {
104,253✔
3445
    TAOS_CHECK_GOTO(TSDB_CODE_MND_ROLE_ALREADY_EXIST, &lino, _OVER);
×
3446
  }
3447

3448
  TAOS_CHECK_GOTO(grantCheck(TSDB_GRANT_USER), &lino, _OVER);
104,253✔
3449

3450
  if (sdbGetSize(pMnode->pSdb, SDB_USER) >= TSDB_MAX_USERS) {
104,253✔
3451
    mError("user:%s, failed to create since reach max user limit %d", createReq.user, TSDB_MAX_USERS);
×
3452
    TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USERS, &lino, _OVER);
×
3453
  }
3454

3455
  if (!createReq.hasSessionPerUser) createReq.sessionPerUser = (tsEnableAdvancedSecurity ? TSDB_USER_SESSION_PER_USER_DEFAULT : -1);
104,253✔
3456
  if (!createReq.hasConnectTime) createReq.connectTime = (tsEnableAdvancedSecurity ? TSDB_USER_CONNECT_TIME_DEFAULT : -1);
104,253✔
3457
  if (!createReq.hasConnectIdleTime) createReq.connectIdleTime = (tsEnableAdvancedSecurity ? TSDB_USER_CONNECT_IDLE_TIME_DEFAULT : -1);
104,253✔
3458
  if (!createReq.hasCallPerSession) createReq.callPerSession = (tsEnableAdvancedSecurity ? TSDB_USER_CALL_PER_SESSION_DEFAULT : -1);
104,253✔
3459
  if (!createReq.hasVnodePerCall) createReq.vnodePerCall = (tsEnableAdvancedSecurity ? TSDB_USER_VNODE_PER_CALL_DEFAULT : -1);
104,253✔
3460
  if (!createReq.hasFailedLoginAttempts) createReq.failedLoginAttempts = (tsEnableAdvancedSecurity ? TSDB_USER_FAILED_LOGIN_ATTEMPTS_DEFAULT : -1);
104,253✔
3461
  if (!createReq.hasPasswordLifeTime) createReq.passwordLifeTime = (tsEnableAdvancedSecurity ? TSDB_USER_PASSWORD_LIFE_TIME_DEFAULT : -1);
104,253✔
3462
  if (!createReq.hasPasswordReuseTime) createReq.passwordReuseTime = (tsEnableAdvancedSecurity ? TSDB_USER_PASSWORD_REUSE_TIME_DEFAULT : 0);
104,253✔
3463
  if (!createReq.hasPasswordReuseMax) createReq.passwordReuseMax = (tsEnableAdvancedSecurity ? TSDB_USER_PASSWORD_REUSE_MAX_DEFAULT : 0);
104,253✔
3464
  if (!createReq.hasPasswordLockTime) createReq.passwordLockTime = (tsEnableAdvancedSecurity ? TSDB_USER_PASSWORD_LOCK_TIME_DEFAULT : 1);
104,253✔
3465
  if (!createReq.hasPasswordGraceTime) createReq.passwordGraceTime = (tsEnableAdvancedSecurity ? TSDB_USER_PASSWORD_GRACE_TIME_DEFAULT : -1);
104,253✔
3466
  if (!createReq.hasInactiveAccountTime) createReq.inactiveAccountTime = (tsEnableAdvancedSecurity ? TSDB_USER_INACTIVE_ACCOUNT_TIME_DEFAULT : -1);
104,253✔
3467
  if (!createReq.hasAllowTokenNum) createReq.allowTokenNum = TSDB_USER_ALLOW_TOKEN_NUM_DEFAULT;
104,253✔
3468

3469
#ifdef TD_ENTERPRISE
3470
  // MAC: per FS §4.2.1.4, CREATE USER with security_level obeys:
3471
  //  - operator with PRIV_SECURITY_POLICY_ALTER  : may specify any [min,max] in [0,4]
3472
  //  - operator without PRIV_SECURITY_POLICY_ALTER: may only specify [0,0] (equivalent to default);
3473
  //                                                 specifying any value > 0 returns MND_NO_RIGHTS.
3474
  // No escalation check is applied on user level (bootstrap-dead-lock avoidance).
3475
  if (createReq.hasSecurityLevel) {
104,253✔
3476
    bool onlyZero = (createReq.minSecLevel == 0 && createReq.maxSecLevel == 0);
178✔
3477
    if (!onlyZero && !mndUserHasMacLabelPriv(pMnode, pOperUser)) {
178✔
3478
      mError("user:%s, failed to create with security_level[%d,%d], operator %s lacks PRIV_SECURITY_POLICY_ALTER",
178✔
3479
             createReq.user, createReq.minSecLevel, createReq.maxSecLevel, RPC_MSG_USER(pReq));
3480
      TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_RIGHTS, &lino, _OVER);
178✔
3481
    }
3482
  }
3483
#endif
3484

3485
  code = mndCreateUser(pMnode, pOperUser->acct, &createReq, pReq);
104,075✔
3486
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
104,075✔
3487

3488
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
104,075✔
3489
    char detail[1000] = {0};
104,075✔
3490
    (void)snprintf(detail, sizeof(detail), "enable:%d, superUser:%d, sysInfo:%d, password:xxx", createReq.enable,
104,075✔
3491
                   createReq.superUser, createReq.sysInfo);
104,075✔
3492
    char operation[15] = {0};
104,075✔
3493
    if (createReq.isImport == 1) {
104,075✔
3494
      tstrncpy(operation, "importUser", sizeof(operation));
×
3495
    } else {
3496
      tstrncpy(operation, "createUser", sizeof(operation));
104,075✔
3497
    }
3498

3499
    int64_t tse = taosGetTimestampMs();
104,075✔
3500
    double  duration = (double)(tse - tss);
104,075✔
3501
    duration = duration / 1000;
104,075✔
3502

3503
    auditRecord(pReq, pMnode->clusterId, operation, "", createReq.user, detail, strlen(detail), duration, 0);
104,075✔
3504
  }
3505

3506
_OVER:
116,848✔
3507
  if (code == TSDB_CODE_MND_USER_ALREADY_EXIST && createReq.ignoreExists) {
116,848✔
3508
    code = 0;
×
3509
  } else if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
116,848✔
3510
    mError("user:%s, failed to create at line %d since %s", createReq.user, lino, tstrerror(code));
12,773✔
3511
  }
3512

3513
  mndReleaseRole(pMnode, pRole);
116,848✔
3514
  mndReleaseUser(pMnode, pUser);
116,848✔
3515
  mndReleaseUser(pMnode, pOperUser);
116,848✔
3516
  tFreeSCreateUserReq(&createReq);
116,848✔
3517

3518
  TAOS_RETURN(code);
116,848✔
3519
}
3520

3521
static int32_t mndProcessGetUserIpWhiteListReq(SRpcMsg *pReq) {
11,624✔
3522
  SMnode                *pMnode = pReq->info.node;
11,624✔
3523
  int32_t                code = 0;
11,624✔
3524
  int32_t                lino = 0;
11,624✔
3525
  int32_t                contLen = 0;
11,624✔
3526
  void                  *pRsp = NULL;
11,624✔
3527
  SUserObj              *pUser = NULL;
11,624✔
3528
  SGetUserWhiteListReq   wlReq = {0};
11,624✔
3529
  SGetUserIpWhiteListRsp wlRsp = {0};
11,624✔
3530

3531
  int32_t (*serialFn)(void *, int32_t, SGetUserIpWhiteListRsp *) = NULL;
11,624✔
3532
  int32_t (*setRspFn)(SMnode *pMnode, SUserObj *pUser, SGetUserIpWhiteListRsp *pRsp) = NULL;
11,624✔
3533

3534
  if (pReq->msgType == TDMT_MND_GET_USER_IP_WHITELIST_DUAL) {
11,624✔
3535
    serialFn = tSerializeSGetUserIpWhiteListDualRsp;
11,624✔
3536
    setRspFn = mndSetUserIpWhiteListDualRsp;
11,624✔
3537
  } else {
3538
    serialFn = tSerializeSGetUserIpWhiteListRsp;
×
3539
    setRspFn = mndSetUserIpWhiteListRsp;
×
3540
  }
3541
  if (tDeserializeSGetUserWhiteListReq(pReq->pCont, pReq->contLen, &wlReq) != 0) {
11,624✔
3542
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
3543
  }
3544
  mTrace("user: %s, start to get ip whitelist", wlReq.user);
11,624✔
3545

3546
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, wlReq.user, &pUser), &lino, _OVER);
11,624✔
3547
  TAOS_CHECK_GOTO(setRspFn(pMnode, pUser, &wlRsp), &lino, _OVER);
11,624✔
3548

3549
  contLen = serialFn(NULL, 0, &wlRsp);
11,624✔
3550
  if (contLen < 0) {
11,624✔
3551
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3552
  }
3553
  pRsp = rpcMallocCont(contLen);
11,624✔
3554
  if (pRsp == NULL) {
11,624✔
3555
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3556
  }
3557

3558
  contLen = serialFn(pRsp, contLen, &wlRsp);
11,624✔
3559
  if (contLen < 0) {
11,624✔
3560
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3561
  }
3562

3563
_OVER:
11,624✔
3564
  mndReleaseUser(pMnode, pUser);
11,624✔
3565
  tFreeSGetUserIpWhiteListDualRsp(&wlRsp);
11,624✔
3566
  if (code < 0) {
11,624✔
3567
    mError("user:%s, failed to get whitelist at line %d since %s", wlReq.user, lino, tstrerror(code));
×
3568
    rpcFreeCont(pRsp);
×
3569
    pRsp = NULL;
×
3570
    contLen = 0;
×
3571
  }
3572
  pReq->code = code;
11,624✔
3573
  pReq->info.rsp = pRsp;
11,624✔
3574
  pReq->info.rspLen = contLen;
11,624✔
3575

3576
  TAOS_RETURN(code);
11,624✔
3577
}
3578

3579
static int32_t buildRetrieveIpWhiteListRsp(SUpdateIpWhite *pUpdate) {
561✔
3580
  (void)taosThreadRwlockRdlock(&userCache.rw);
561✔
3581

3582
  int32_t count = taosHashGetSize(userCache.users);
561✔
3583
  pUpdate->pUserIpWhite = taosMemoryCalloc(count, sizeof(SUpdateUserIpWhite));
561✔
3584
  if (pUpdate->pUserIpWhite == NULL) {
561✔
3585
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
3586
    TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
3587
  }
3588

3589
  count = 0;
561✔
3590
  void *pIter = taosHashIterate(userCache.users, NULL);
561✔
3591
  while (pIter) {
1,122✔
3592
    SIpWhiteListDual *wl = (*(SCachedUserInfo **)pIter)->wlIp;
561✔
3593
    if (wl == NULL || wl->num <= 0) {
561✔
3594
      pIter = taosHashIterate(userCache.users, pIter);
×
3595
      continue;
×
3596
    }
3597

3598
    SUpdateUserIpWhite *pUser = &pUpdate->pUserIpWhite[count];
561✔
3599
    pUser->ver = userCache.verIp;
561✔
3600

3601
    size_t klen;
561✔
3602
    char  *key = taosHashGetKey(pIter, &klen);
561✔
3603
    (void)memcpy(pUser->user, key, klen);
561✔
3604

3605
    pUser->numOfRange = wl->num;
561✔
3606
    pUser->pIpRanges = taosMemoryCalloc(wl->num, sizeof(SIpRange));
561✔
3607
    if (pUser->pIpRanges == NULL) {
561✔
3608
      (void)taosThreadRwlockUnlock(&userCache.rw);
×
3609
      TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
3610
    }
3611

3612
    (void)memcpy(pUser->pIpRanges, wl->pIpRanges, wl->num * sizeof(SIpRange));
561✔
3613
    count++;
561✔
3614
    pIter = taosHashIterate(userCache.users, pIter);
561✔
3615
  }
3616

3617
  pUpdate->numOfUser = count;
561✔
3618
  pUpdate->ver = userCache.verIp;
561✔
3619
  (void)taosThreadRwlockUnlock(&userCache.rw);
561✔
3620
  TAOS_RETURN(0);
561✔
3621
}
3622

3623
int32_t mndProcessRetrieveIpWhiteListReq(SRpcMsg *pReq) {
561✔
3624
  int32_t        code = 0;
561✔
3625
  int32_t        lino = 0;
561✔
3626
  int32_t        len = 0;
561✔
3627
  void          *pRsp = NULL;
561✔
3628
  SUpdateIpWhite ipWhite = {0};
561✔
3629

3630
  // impl later
3631
  SRetrieveWhiteListReq req = {0};
561✔
3632
  if (tDeserializeRetrieveWhiteListReq(pReq->pCont, pReq->contLen, &req) != 0) {
561✔
3633
    code = TSDB_CODE_INVALID_MSG;
×
3634
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3635
  }
3636

3637
  int32_t (*fn)(void *, int32_t, SUpdateIpWhite *) = NULL;
561✔
3638
  if (pReq->msgType == TDMT_MND_RETRIEVE_IP_WHITELIST) {
561✔
3639
    fn = tSerializeSUpdateIpWhite;
×
3640
  } else if (pReq->msgType == TDMT_MND_RETRIEVE_IP_WHITELIST_DUAL) {
561✔
3641
    fn = tSerializeSUpdateIpWhiteDual;
561✔
3642
  }
3643

3644
  TAOS_CHECK_GOTO(buildRetrieveIpWhiteListRsp(&ipWhite), &lino, _OVER);
561✔
3645

3646
  len = fn(NULL, 0, &ipWhite);
561✔
3647
  if (len < 0) {
561✔
3648
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
3649
  }
3650

3651
  pRsp = rpcMallocCont(len);
561✔
3652
  if (!pRsp) {
561✔
3653
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3654
  }
3655
  len = fn(pRsp, len, &ipWhite);
561✔
3656
  if (len < 0) {
561✔
3657
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
3658
  }
3659

3660
_OVER:
561✔
3661
  if (code < 0) {
561✔
3662
    mError("failed to process retrieve ip white request at line %d since %s", lino, tstrerror(code));
×
3663
    rpcFreeCont(pRsp);
×
3664
    pRsp = NULL;
×
3665
    len = 0;
×
3666
  }
3667
  pReq->code = code;
561✔
3668
  pReq->info.rsp = pRsp;
561✔
3669
  pReq->info.rspLen = len;
561✔
3670

3671
  tFreeSUpdateIpWhiteReq(&ipWhite);
561✔
3672
  TAOS_RETURN(code);
561✔
3673
}
3674

3675
static int32_t mndAlterUserEx(SMnode *pMnode, SUserObj *pNew, SRpcMsg *pReq, ETrnFunc stopFunc) {
1,549,838✔
3676
  int32_t code = 0, lino = 0;
1,549,838✔
3677
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "alter-user");
1,549,838✔
3678
  if (pTrans == NULL) {
1,549,838✔
3679
    mError("user:%s, failed to alter since %s", pNew->user, terrstr());
×
3680
    TAOS_RETURN(terrno);
×
3681
  }
3682
  mInfo("trans:%d, used to alter user:%s", pTrans->id, pNew->user);
1,549,838✔
3683

3684
  SSdbRaw *pCommitRaw = mndUserActionEncode(pNew);
1,549,838✔
3685
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
1,549,838✔
3686
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
3687
    mndTransDrop(pTrans);
×
3688
    TAOS_RETURN(terrno);
×
3689
  }
3690
  TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
1,549,838✔
3691

3692
  if (stopFunc > 0) {
1,549,838✔
3693
    mndTransSetCb(pTrans, 0, stopFunc, NULL, 0);
×
3694
  }
3695
  if (mndTransPrepare(pMnode, pTrans) != 0) {
1,549,838✔
3696
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
3697
    mndTransDrop(pTrans);
×
3698
    TAOS_RETURN(terrno);
×
3699
  }
3700
  if ((code = userCacheUpdateWhiteList(pMnode, pNew)) != 0) {
1,549,838✔
3701
    mndTransDrop(pTrans);
×
3702
    TAOS_RETURN(code);
×
3703
  }
3704
_exit:
1,549,838✔
3705
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
1,549,838✔
3706
    mError("user:%s, failed to alter at line %d since %s", pNew->user, lino, tstrerror(code));
×
3707
  }
3708
  mndTransDrop(pTrans);
1,549,838✔
3709
  TAOS_RETURN(code);
1,549,838✔
3710
}
3711

3712
static int32_t mndAlterUser(SMnode *pMnode, SUserObj *pNew, SRpcMsg *pReq) {
45,498✔
3713
  return mndAlterUserEx(pMnode, pNew, pReq, 0);
45,498✔
3714
}
3715

3716
static int32_t mndDupObjHash(SHashObj *pOld, int32_t dataLen, SHashObj **ppNew) {
×
3717
  int32_t code = 0;
×
3718

3719
  *ppNew =
×
3720
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
3721
  if (*ppNew == NULL) {
×
3722
    code = terrno ? terrno : TSDB_CODE_OUT_OF_MEMORY;
×
3723
    TAOS_RETURN(code);
×
3724
  }
3725

3726
  char *db = taosHashIterate(pOld, NULL);
×
3727
  while (db != NULL) {
×
3728
    int32_t len = strlen(db) + 1;
×
3729
    if ((code = taosHashPut(*ppNew, db, len, db, dataLen)) != 0) {
×
3730
      taosHashCancelIterate(pOld, db);
×
3731
      taosHashCleanup(*ppNew);
×
3732
      TAOS_RETURN(code);
×
3733
    }
3734
    db = taosHashIterate(pOld, db);
×
3735
  }
3736

3737
  TAOS_RETURN(code);
×
3738
}
3739

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

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

3744
static int32_t mndTablePriviledge(SMnode *pMnode, SHashObj *hash, SHashObj *useDbHash, SAlterUserReq *alterReq,
×
3745
                                  SSdb *pSdb) {
3746
  void *pIter = NULL;
×
3747
  char  tbFName[TSDB_TABLE_FNAME_LEN] = {0};
×
3748

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

3752
  if (alterReq->tagCond != NULL && alterReq->tagCondLen != 0) {
×
3753
    char *value = taosHashGet(hash, tbFName, len);
×
3754
    if (value != NULL) {
×
3755
      TAOS_RETURN(TSDB_CODE_MND_PRIVILEGE_EXIST);
×
3756
    }
3757

3758
    int32_t condLen = alterReq->tagCondLen;
×
3759
    TAOS_CHECK_RETURN(taosHashPut(hash, tbFName, len, alterReq->tagCond, condLen));
×
3760
  } else {
3761
    TAOS_CHECK_RETURN(taosHashPut(hash, tbFName, len, alterReq->isView ? "v" : "t", 2));
×
3762
  }
3763

3764
  int32_t  dbKeyLen = strlen(alterReq->objname) + 1;
×
3765
  int32_t  ref = 1;
×
3766
  int32_t *currRef = taosHashGet(useDbHash, alterReq->objname, dbKeyLen);
×
3767
  if (NULL != currRef) {
×
3768
    ref = (*currRef) + 1;
×
3769
  }
3770
  TAOS_CHECK_RETURN(taosHashPut(useDbHash, alterReq->objname, dbKeyLen, &ref, sizeof(ref)));
×
3771

3772
  TAOS_RETURN(0);
×
3773
}
3774

3775
static int32_t mndRemoveTablePriviledge(SMnode *pMnode, SHashObj *hash, SHashObj *useDbHash, SAlterUserReq *alterReq,
×
3776
                                        SSdb *pSdb) {
3777
  void *pIter = NULL;
×
3778
  char  tbFName[TSDB_TABLE_FNAME_LEN] = {0};
×
3779
  (void)snprintf(tbFName, sizeof(tbFName), "%s.%s", alterReq->objname, alterReq->tabName);
×
3780
  int32_t len = strlen(tbFName) + 1;
×
3781

3782
  if (taosHashRemove(hash, tbFName, len) != 0) {
×
3783
    TAOS_RETURN(0);  // not found
×
3784
  }
3785

3786
  int32_t  dbKeyLen = strlen(alterReq->objname) + 1;
×
3787
  int32_t *currRef = taosHashGet(useDbHash, alterReq->objname, dbKeyLen);
×
3788
  if (NULL == currRef) {
×
3789
    return 0;
×
3790
  }
3791

3792
  if (1 == *currRef) {
×
3793
    if (taosHashRemove(useDbHash, alterReq->objname, dbKeyLen) != 0) {
×
3794
      TAOS_RETURN(0);  // not found
×
3795
    }
3796
    return 0;
×
3797
  }
3798
  int32_t ref = (*currRef) - 1;
×
3799
  TAOS_CHECK_RETURN(taosHashPut(useDbHash, alterReq->objname, dbKeyLen, &ref, sizeof(ref)));
×
3800

3801
  return 0;
×
3802
}
3803

3804
#if 0
3805
static int32_t mndProcessAlterUserPrivilegesReq(SRpcMsg* pReq, SAlterUserReq *pAlterReq) {
3806
  SMnode   *pMnode = pReq->info.node;
3807
  SSdb     *pSdb = pMnode->pSdb;
3808
  int32_t   code = 0, lino = 0;
3809
  SUserObj *pUser = NULL;
3810
  SUserObj  newUser = {0};
3811
  int64_t   tss = taosGetTimestampMs();
3812

3813
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, pAlterReq->user, &pUser), &lino, _OVER);
3814
  TAOS_CHECK_GOTO(mndCheckAlterUserPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser, pAlterReq), &lino, _OVER);
3815
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
3816

3817
#if 0
3818
  if (ALTER_USER_ADD_READ_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName) ||
3819
      ALTER_USER_ADD_ALL_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName)) {
3820
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
3821
      int32_t len = strlen(pAlterReq->objname) + 1;
3822
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
3823
      if (pDb == NULL) {
3824
        mndReleaseDb(pMnode, pDb);
3825
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
3826
      }
3827
      if ((code = taosHashPut(newUser.readDbs, pAlterReq->objname, len, pAlterReq->objname, TSDB_DB_FNAME_LEN)) !=
3828
          0) {
3829
        mndReleaseDb(pMnode, pDb);
3830
        TAOS_CHECK_GOTO(code, &lino, _OVER);
3831
      }
3832
      mndReleaseDb(pMnode, pDb);
3833
    } else {
3834
      void   *pIter = NULL;
3835
      while (1) {
3836
        SDbObj *pDb = NULL;
3837
        pIter = sdbFetch(pSdb, SDB_DB, pIter, (void **)&pDb);
3838
        if (pIter == NULL) break;
3839
        int32_t len = strlen(pDb->name) + 1;
3840
        if ((code = taosHashPut(newUser.readDbs, pDb->name, len, pDb->name, TSDB_DB_FNAME_LEN)) != 0) {
3841
          sdbRelease(pSdb, pDb);
3842
          sdbCancelFetch(pSdb, pIter);
3843
          TAOS_CHECK_GOTO(code, &lino, _OVER);
3844
        }
3845
        sdbRelease(pSdb, pDb);
3846
      }
3847
    }
3848
  }
3849

3850
  if (ALTER_USER_ADD_WRITE_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName) ||
3851
      ALTER_USER_ADD_ALL_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName)) {
3852
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
3853
      int32_t len = strlen(pAlterReq->objname) + 1;
3854
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
3855
      if (pDb == NULL) {
3856
        mndReleaseDb(pMnode, pDb);
3857
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
3858
      }
3859
      if ((code = taosHashPut(newUser.writeDbs, pAlterReq->objname, len, pAlterReq->objname, TSDB_DB_FNAME_LEN)) !=
3860
          0) {
3861
        mndReleaseDb(pMnode, pDb);
3862
        TAOS_CHECK_GOTO(code, &lino, _OVER);
3863
      }
3864
      mndReleaseDb(pMnode, pDb);
3865
    } else {
3866
      void   *pIter = NULL;
3867
      while (1) {
3868
        SDbObj *pDb = NULL;
3869
        pIter = sdbFetch(pSdb, SDB_DB, pIter, (void **)&pDb);
3870
        if (pIter == NULL) break;
3871
        int32_t len = strlen(pDb->name) + 1;
3872
        if ((code = taosHashPut(newUser.writeDbs, pDb->name, len, pDb->name, TSDB_DB_FNAME_LEN)) != 0) {
3873
          sdbRelease(pSdb, pDb);
3874
          sdbCancelFetch(pSdb, pIter);
3875
          TAOS_CHECK_GOTO(code, &lino, _OVER);
3876
        }
3877
        sdbRelease(pSdb, pDb);
3878
      }
3879
    }
3880
  }
3881

3882
  if (ALTER_USER_DEL_READ_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName) ||
3883
      ALTER_USER_DEL_ALL_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName)) {
3884
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
3885
      int32_t len = strlen(pAlterReq->objname) + 1;
3886
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
3887
      if (pDb == NULL) {
3888
        mndReleaseDb(pMnode, pDb);
3889
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
3890
      }
3891
      code = taosHashRemove(newUser.readDbs, pAlterReq->objname, len);
3892
      if (code < 0) {
3893
        mError("read db:%s, failed to remove db:%s since %s", newUser.user, pAlterReq->objname, terrstr());
3894
      }
3895
      mndReleaseDb(pMnode, pDb);
3896
    } else {
3897
      taosHashClear(newUser.readDbs);
3898
    }
3899
  }
3900

3901
  if (ALTER_USER_DEL_WRITE_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName) ||
3902
      ALTER_USER_DEL_ALL_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName)) {
3903
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
3904
      int32_t len = strlen(pAlterReq->objname) + 1;
3905
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
3906
      if (pDb == NULL) {
3907
        mndReleaseDb(pMnode, pDb);
3908
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
3909
      }
3910
      code = taosHashRemove(newUser.writeDbs, pAlterReq->objname, len);
3911
      if (code < 0) {
3912
        mError("user:%s, failed to remove db:%s since %s", newUser.user, pAlterReq->objname, terrstr());
3913
      }
3914
      mndReleaseDb(pMnode, pDb);
3915
    } else {
3916
      taosHashClear(newUser.writeDbs);
3917
    }
3918
  }
3919

3920
  SHashObj *pReadTbs = newUser.readTbs;
3921
  SHashObj *pWriteTbs = newUser.writeTbs;
3922
  SHashObj *pAlterTbs = newUser.alterTbs;
3923

3924
#ifdef TD_ENTERPRISE
3925
  if (pAlterReq->isView) {
3926
    pReadTbs = newUser.readViews;
3927
    pWriteTbs = newUser.writeViews;
3928
    pAlterTbs = newUser.alterViews;
3929
  }
3930
#endif
3931

3932
  if (ALTER_USER_ADD_READ_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3933
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3934
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pReadTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3935
  }
3936

3937
  if (ALTER_USER_ADD_WRITE_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3938
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3939
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pWriteTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3940
  }
3941

3942
  if (ALTER_USER_ADD_ALTER_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3943
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3944
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pAlterTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3945
  }
3946

3947
  if (ALTER_USER_DEL_READ_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3948
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3949
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pReadTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3950
  }
3951

3952
  if (ALTER_USER_DEL_WRITE_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3953
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3954
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pWriteTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3955
  }
3956

3957
  if (ALTER_USER_DEL_ALTER_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3958
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3959
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pAlterTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3960
  }
3961
#endif
3962

3963
#if 0
3964
// #ifdef USE_TOPIC
3965
  if (ALTER_USER_ADD_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, &pAlterReq->privileges)) {
3966
    int32_t      len = strlen(pAlterReq->objname) + 1;
3967
    SMqTopicObj *pTopic = NULL;
3968
    if ((code = mndAcquireTopic(pMnode, pAlterReq->objname, &pTopic)) != 0) {
3969
      TAOS_CHECK_GOTO(code, &lino, _OVER);
3970
    }
3971
    taosRLockLatch(&pTopic->lock);
3972
    code = taosHashPut(newUser.topics, pTopic->name, len, pTopic->name, TSDB_TOPIC_FNAME_LEN);
3973
    taosRUnLockLatch(&pTopic->lock);
3974
    mndReleaseTopic(pMnode, pTopic);
3975
    TAOS_CHECK_GOTO(code, &lino, _OVER);
3976
  }
3977

3978
  if (ALTER_USER_DEL_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, &pAlterReq->privileges)) {
3979
    int32_t      len = strlen(pAlterReq->objname) + 1;
3980
    SMqTopicObj *pTopic = NULL;
3981
    if ((code = mndAcquireTopic(pMnode, pAlterReq->objname, &pTopic)) != 0) {
3982
      TAOS_CHECK_GOTO(code, &lino, _OVER);
3983
    }
3984
    taosRLockLatch(&pTopic->lock);
3985
    code = taosHashRemove(newUser.topics, pAlterReq->objname, len);
3986
    if (code < 0) {
3987
      mError("user:%s, failed to remove topic:%s since %s", newUser.user, pAlterReq->objname, tstrerror(code));
3988
    }
3989
    taosRUnLockLatch(&pTopic->lock);
3990
    mndReleaseTopic(pMnode, pTopic);
3991
  }
3992
#endif
3993

3994
  TAOS_CHECK_GOTO(mndAlterUser(pMnode, &newUser, pReq), &lino, _OVER);
3995
  code = TSDB_CODE_ACTION_IN_PROGRESS;
3996

3997
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
3998
    int64_t tse = taosGetTimestampMs();
3999
    double  duration = (double)(tse - tss);
4000
    duration = duration / 1000;
4001
    if (ALTER_USER_ADD_READ_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
4002
              ALTER_USER_ADD_WRITE_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
4003
              ALTER_USER_ADD_ALL_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
4004
              ALTER_USER_ADD_READ_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
4005
              ALTER_USER_ADD_WRITE_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
4006
              ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
4007
      if (strcmp(pAlterReq->objname, "1.*") != 0) {
4008
        SName name = {0};
4009
        TAOS_CHECK_GOTO(tNameFromString(&name, pAlterReq->objname, T_NAME_ACCT | T_NAME_DB), &lino, _OVER);
4010
        auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", name.dbname, pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
4011
      } else {
4012
        auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", "", pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
4013
      }
4014
    } else if (ALTER_USER_ADD_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, pAlterReq->privileges)) {
4015
      auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", pAlterReq->objname, pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
4016
    } else if (ALTER_USER_DEL_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, pAlterReq->privileges)) {
4017
      auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", pAlterReq->objname, pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
4018
    } else {
4019
      if (strcmp(pAlterReq->objname, "1.*") != 0) {
4020
        SName name = {0};
4021
        TAOS_CHECK_GOTO(tNameFromString(&name, pAlterReq->objname, T_NAME_ACCT | T_NAME_DB), &lino, _OVER);
4022
        auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", name.dbname, pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
4023
      } else {
4024
        auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", "", pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
4025
      }
4026
    }
4027
  }
4028
  
4029
_OVER:
4030
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
4031
    mError("user:%s, failed to alter user privileges at line %d since %s", pAlterReq->user, lino, tstrerror(code));
4032
  }
4033
  mndReleaseUser(pMnode, pUser);
4034
  mndUserFreeObj(&newUser);
4035
  TAOS_RETURN(code);
4036
}
4037
#endif
4038

4039
// Returns the minimum maxSecLevel a user must have to hold its current role set under MAC.
4040
// Floor mapping: SYSSEC/SYSAUDIT/SYSAUDIT_LOG=4, SYSDBA=3, SYSINFO_1=1, others=0.
4041
int8_t mndGetUserRoleFloorMaxLevel(SHashObj *roles) {
6,066✔
4042
  if (roles == NULL) return TSDB_MIN_SECURITY_LEVEL;
6,066✔
4043
  if (taosHashGet(roles, TSDB_ROLE_SYSSEC, sizeof(TSDB_ROLE_SYSSEC)) ||
10,086✔
4044
      taosHashGet(roles, TSDB_ROLE_SYSAUDIT, sizeof(TSDB_ROLE_SYSAUDIT)) ||
7,668✔
4045
      taosHashGet(roles, TSDB_ROLE_SYSAUDIT_LOG, sizeof(TSDB_ROLE_SYSAUDIT_LOG))) {
3,648✔
4046
    return TSDB_MAX_SECURITY_LEVEL;
2,418✔
4047
  }
4048
  if (taosHashGet(roles, TSDB_ROLE_SYSDBA, sizeof(TSDB_ROLE_SYSDBA))) {
3,648✔
4049
    return 3;
1,116✔
4050
  }
4051
  if (taosHashGet(roles, TSDB_ROLE_SYSINFO_1, sizeof(TSDB_ROLE_SYSINFO_1))) {
2,532✔
4052
    return 1;
2,532✔
4053
  }
4054
  return TSDB_MIN_SECURITY_LEVEL;
×
4055
}
4056

4057
// Returns the minSecLevel floor imposed by system roles:
4058
// SYSSEC/SYSAUDIT/SYSAUDIT_LOG require minSecLevel=4; SYSDBA requires minSecLevel=0 (no constraint).
4059
int8_t mndGetUserRoleFloorMinLevel(SHashObj *roles) {
6,066✔
4060
  if (roles == NULL) return TSDB_MIN_SECURITY_LEVEL;
6,066✔
4061
  if (taosHashGet(roles, TSDB_ROLE_SYSSEC, sizeof(TSDB_ROLE_SYSSEC)) ||
10,086✔
4062
      taosHashGet(roles, TSDB_ROLE_SYSAUDIT, sizeof(TSDB_ROLE_SYSAUDIT)) ||
7,668✔
4063
      taosHashGet(roles, TSDB_ROLE_SYSAUDIT_LOG, sizeof(TSDB_ROLE_SYSAUDIT_LOG))) {
3,648✔
4064
    return TSDB_MAX_SECURITY_LEVEL;
2,418✔
4065
  }
4066
  return TSDB_MIN_SECURITY_LEVEL;
3,648✔
4067
}
4068

4069
// Check if a user holds PRIV_SECURITY_POLICY_ALTER — directly or via any assigned role.
4070
// When MAC is mandatory, the holder must also have maxSecLevel == TSDB_MAX_SECURITY_LEVEL.
4071
// superUser always qualifies.
4072
bool mndUserHasMacLabelPriv(SMnode *pMnode, SUserObj *pUser) {
2,160,481✔
4073
#ifdef TD_ENTERPRISE
4074
  if (pUser->superUser) return true;
2,160,481✔
4075
  bool hasPriv = PRIV_HAS(&pUser->sysPrivs, PRIV_SECURITY_POLICY_ALTER);
16,126✔
4076
  if (!hasPriv && pUser->roles) {
16,126✔
4077
    void     *pIter = NULL;
16,126✔
4078
    SRoleObj *pRole = NULL;
16,126✔
4079
    while ((pIter = taosHashIterate(pUser->roles, pIter)) != NULL) {
35,090✔
4080
      char *roleName = taosHashGetKey(pIter, NULL);
28,178✔
4081
      if (!roleName) continue;
28,178✔
4082
      if (mndAcquireRole(pMnode, roleName, &pRole) != 0) continue;
28,178✔
4083
      if (pRole->enable && PRIV_HAS(&pRole->sysPrivs, PRIV_SECURITY_POLICY_ALTER)) {
28,178✔
4084
        mndReleaseRole(pMnode, pRole);
9,214✔
4085
        taosHashCancelIterate(pUser->roles, pIter);
9,214✔
4086
        hasPriv = true;
9,214✔
4087
        break;
9,214✔
4088
      }
4089
      mndReleaseRole(pMnode, pRole);
18,964✔
4090
    }
4091
  }
4092
  if (!hasPriv) return false;
16,126✔
4093
  // When MAC is mandatory, PRIV_SECURITY_POLICY_ALTER holder must have the highest security level
4094
  if (pMnode->macActive == MAC_MODE_MANDATORY && pUser->maxSecLevel < TSDB_MAX_SECURITY_LEVEL) {
9,214✔
4095
    return false;
×
4096
  }
4097
#endif
4098
  return true;
9,214✔
4099
}
4100

4101
int32_t mndAlterUserFromRole(SRpcMsg *pReq, SUserObj *pOperUser, SAlterRoleReq *pAlterReq) {
1,516,940✔
4102
  SMnode   *pMnode = pReq->info.node;
1,516,940✔
4103
  SSdb     *pSdb = pMnode->pSdb;
1,516,940✔
4104
  void     *pIter = NULL;
1,516,940✔
4105
  int32_t   code = 0, lino = 0;
1,516,940✔
4106
  SUserObj *pUser = NULL;
1,516,940✔
4107
  SUserObj  newUser = {0};
1,516,940✔
4108

4109
  if ((pAlterReq->alterType == TSDB_ALTER_ROLE_ROLE) && (pAlterReq->add == 0) &&
1,525,167✔
4110
      (mndGetSoDPhase(pMnode) == TSDB_SOD_PHASE_ENFORCE)) {
8,227✔
4111
    TAOS_RETURN(TSDB_CODE_MND_SOD_RESTRICTED);
×
4112
  }
4113

4114
  TAOS_CHECK_EXIT(mndAcquireUser(pMnode, pAlterReq->principal, &pUser));
1,516,940✔
4115

4116
  if (pUser->enable == 0) {
1,513,383✔
4117
    TAOS_CHECK_EXIT(TSDB_CODE_MND_USER_DISABLED);
×
4118
  }
4119
  if(pUser->superUser) {
1,513,383✔
4120
    TAOS_CHECK_EXIT(TSDB_CODE_MND_NO_RIGHTS);
2,686✔
4121
  }
4122

4123
  ETrnFunc stopFunc = 0;
1,510,697✔
4124
  if (pAlterReq->alterType == TSDB_ALTER_ROLE_PRIVILEGES) {
1,510,697✔
4125
#ifdef TD_ENTERPRISE
4126
    TAOS_CHECK_EXIT(mndUserDupObj(pUser, &newUser));
1,492,370✔
4127
    if ((code = mndAlterUserPrivInfo(pMnode, &newUser, pAlterReq)) == TSDB_CODE_QRY_DUPLICATED_OPERATION) {
1,492,370✔
4128
      code = 0;
×
4129
      goto _exit;
×
4130
    } else {
4131
      TAOS_CHECK_EXIT(code);
1,492,370✔
4132
    }
4133
  } else if (pAlterReq->alterType == TSDB_ALTER_ROLE_ROLE) {
18,327✔
4134
    bool isSysRole = IS_SYS_PREFIX(pAlterReq->roleName);
18,327✔
4135
    // SoD mandatory mode: check revoke of management roles
4136
    if ((pAlterReq->add == 0) && isSysRole && (mndGetClusterSoDMode(pMnode) == SOD_MODE_MANDATORY)) {
18,327✔
4137
      uint8_t roleType = 0;
1,302✔
4138
      if (strcmp(pAlterReq->roleName, TSDB_ROLE_SYSDBA) == 0) {
1,302✔
4139
        if (taosHashGet(pUser->roles, TSDB_ROLE_SYSDBA, sizeof(TSDB_ROLE_SYSDBA))) {
186✔
4140
          roleType = T_ROLE_SYSDBA;
186✔
4141
        }
4142
      } else if (strcmp(pAlterReq->roleName, TSDB_ROLE_SYSSEC) == 0) {
1,116✔
4143
        if (taosHashGet(pUser->roles, TSDB_ROLE_SYSSEC, sizeof(TSDB_ROLE_SYSSEC))) {
744✔
4144
          roleType = T_ROLE_SYSSEC;
744✔
4145
        }
4146
      } else if (strcmp(pAlterReq->roleName, TSDB_ROLE_SYSAUDIT) == 0) {
372✔
4147
        if (taosHashGet(pUser->roles, TSDB_ROLE_SYSAUDIT, sizeof(TSDB_ROLE_SYSAUDIT))) {
186✔
4148
          roleType = T_ROLE_SYSAUDIT;
186✔
4149
        }
4150
      }
4151
      if (roleType != 0) {
1,302✔
4152
        TAOS_CHECK_EXIT(mndCheckManagementRoleStatus(pMnode, pAlterReq->principal, 0));
1,116✔
4153
      }
4154
    }
4155

4156
    if ((code = mndAlterUserRoleInfo(pMnode, pOperUser, RPC_MSG_TOKEN(pReq), pUser, &newUser, pAlterReq)) ==
17,769✔
4157
        TSDB_CODE_QRY_DUPLICATED_OPERATION) {
4158
      code = 0;
342✔
4159
      goto _exit;
342✔
4160
    } else {
4161
      TAOS_CHECK_EXIT(code);
17,427✔
4162
    }
4163
    // MAC mandatory: if granting a role, user's security_level must satisfy the role's min and max floors
4164
    if ((pAlterReq->add == 1) && (pMnode->macActive == MAC_MODE_MANDATORY)) {
15,757✔
4165
      int8_t floorMaxLevel = mndGetUserRoleFloorMaxLevel(newUser.roles);
558✔
4166
      int8_t floorMinLevel = mndGetUserRoleFloorMinLevel(newUser.roles);
558✔
4167
      if (newUser.maxSecLevel < floorMaxLevel) {
558✔
4168
        mError("user:%s, GRANT role:%s rejected under MAC: maxSecLevel(%d) < role maxFloor(%d)", pAlterReq->principal,
186✔
4169
               pAlterReq->roleName, (int32_t)newUser.maxSecLevel, (int32_t)floorMaxLevel);
4170
        TAOS_CHECK_EXIT(TSDB_CODE_MAC_SEC_LEVEL_CONFLICTS_ROLE);
186✔
4171
      }
4172
      if (newUser.minSecLevel < floorMinLevel) {
372✔
4173
        mError("user:%s, GRANT role:%s rejected under MAC: minSecLevel(%d) < role minFloor(%d)", pAlterReq->principal,
186✔
4174
               pAlterReq->roleName, (int32_t)newUser.minSecLevel, (int32_t)floorMinLevel);
4175
        TAOS_CHECK_EXIT(TSDB_CODE_MAC_SEC_LEVEL_CONFLICTS_ROLE);
186✔
4176
      }
4177
    }
4178
    // REVOKE system role: security_level does not auto-change; write audit warning
4179
    if ((pAlterReq->add == 0) && isSysRole && (pMnode->macActive == MAC_MODE_MANDATORY)) {
15,385✔
4180
      mWarn("user:%s, REVOKE system role:%s — security_level [%d,%d] unchanged; manual ALTER USER may be required",
186✔
4181
            pAlterReq->principal, pAlterReq->roleName, (int32_t)pUser->minSecLevel,
4182
            (int32_t)pUser->maxSecLevel);
4183
    }
4184
    // Check if we need to set SoD role check callback
4185
    if ((pAlterReq->add == 1) && isSysRole &&
15,385✔
4186
        (strcmp(pAlterReq->roleName, TSDB_ROLE_SYSDBA) == 0 || strcmp(pAlterReq->roleName, TSDB_ROLE_SYSSEC) == 0 ||
6,383✔
4187
         strcmp(pAlterReq->roleName, TSDB_ROLE_SYSAUDIT) == 0) &&
7,374✔
4188
        (mndGetSoDPhase(pMnode) == TSDB_SOD_PHASE_INITIAL)) {
4,567✔
4189
      stopFunc = TRANS_STOP_FUNC_SOD_ROLE_CHECK;
×
4190
    }
4191
#endif
4192
  } else {
4193
    TAOS_CHECK_EXIT(TSDB_CODE_INVALID_MSG);
×
4194
  }
4195
  TAOS_CHECK_EXIT(mndAlterUserEx(pMnode, &newUser, pReq, stopFunc));
1,504,340✔
4196
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
1,504,340✔
4197

4198
_exit:
1,516,940✔
4199
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
1,516,940✔
4200
    mError("user:%s, failed to alter user at line %d since %s", pAlterReq->principal, lino, tstrerror(code));
12,258✔
4201
  }
4202
  mndReleaseUser(pMnode, pUser);
1,516,940✔
4203
  mndUserFreeObj(&newUser);
1,516,940✔
4204
  TAOS_RETURN(code);
1,516,940✔
4205
}
4206

4207
static int32_t mndProcessAlterUserBasicInfoReq(SRpcMsg *pReq, SAlterUserReq *pAlterReq) {
61,703✔
4208
  SMnode   *pMnode = pReq->info.node;
61,703✔
4209
  int32_t   code = 0, lino = 0;
61,703✔
4210
  SUserObj *pUser = NULL;
61,703✔
4211
  SUserObj  newUser = {0};
61,703✔
4212
  char      auditLog[1000] = {0};
61,703✔
4213
  int32_t   auditLen = 0;
61,703✔
4214
  int64_t   tss = taosGetTimestampMs();
61,703✔
4215

4216
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, pAlterReq->user, &pUser), &lino, _OVER);
61,703✔
4217
  TAOS_CHECK_GOTO(mndCheckAlterUserPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser, pAlterReq), &lino,
60,667✔
4218
                  _OVER);
4219
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
59,094✔
4220

4221
  if (pAlterReq->hasPassword) {
59,094✔
4222
    auditLen += snprintf(auditLog, sizeof(auditLog), "password,");
37,725✔
4223

4224
    TAOS_CHECK_GOTO(mndCheckPasswordFmt(pAlterReq->pass), &lino, _OVER);
37,725✔
4225
    if (newUser.salt[0] == 0) {
25,922✔
4226
      generateSalt(newUser.salt, sizeof(newUser.salt));
203✔
4227
    }
4228
    char pass[TSDB_PASSWORD_LEN] = {0};
25,922✔
4229
    taosEncryptPass_c((uint8_t *)pAlterReq->pass, strlen(pAlterReq->pass), pass);
25,922✔
4230
    pass[sizeof(pass) - 1] = 0;
25,922✔
4231
    if (strlen(tsDataKey) > 0) {
25,922✔
4232
      TAOS_CHECK_GOTO(mndEncryptPass(pass, newUser.salt, &newUser.passEncryptAlgorithm), &lino, _OVER);
×
4233
    }
4234

4235
    if (newUser.passwordReuseMax > 0 || newUser.passwordReuseTime > 0) {
25,922✔
4236
      for (int32_t i = 0; i < newUser.numOfPasswords; ++i) {
906,347✔
4237
        if (0 == strncmp(newUser.passwords[i].pass, pass, TSDB_PASSWORD_LEN)) {
888,602✔
4238
          TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_PASSWORD_REUSE, &lino, _OVER);
507✔
4239
        }
4240
      }
4241
      SUserPassword *passwords = taosMemoryCalloc(newUser.numOfPasswords + 1, sizeof(SUserPassword));
17,745✔
4242
      if (passwords == NULL) {
17,745✔
4243
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
4244
      }
4245
      memcpy(passwords + 1, newUser.passwords, newUser.numOfPasswords * sizeof(SUserPassword));
17,745✔
4246
      memcpy(passwords[0].pass, pass, TSDB_PASSWORD_LEN);
17,745✔
4247
      passwords[0].setTime = taosGetTimestampSec();
17,745✔
4248
      taosMemoryFree(newUser.passwords);
17,745✔
4249
      newUser.passwords = passwords;
17,745✔
4250
      ++newUser.numOfPasswords;
17,745✔
4251
      ++newUser.passVersion;
17,745✔
4252
      newUser.changePass = 2;
17,745✔
4253
    } else if (0 != strncmp(newUser.passwords[0].pass, pass, TSDB_PASSWORD_LEN)) {
7,670✔
4254
      memcpy(newUser.passwords[0].pass, pass, TSDB_PASSWORD_LEN);
7,433✔
4255
      newUser.passwords[0].setTime = taosGetTimestampSec();
7,433✔
4256
      ++newUser.passVersion;
7,433✔
4257
      newUser.changePass = 2;
7,433✔
4258
    }
4259
  }
4260

4261
  if (pAlterReq->hasTotpseed) {
46,784✔
4262
    auditLen += snprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "totpseed,");
×
4263

4264
    if (pAlterReq->totpseed[0] == 0) {  // clear totp secret
×
4265
      memset(newUser.totpsecret, 0, sizeof(newUser.totpsecret));
×
4266
    } else if (taosGenerateTotpSecret(pAlterReq->totpseed, 0, newUser.totpsecret, sizeof(newUser.totpsecret)) < 0) {
×
4267
      TAOS_CHECK_GOTO(TSDB_CODE_PAR_INVALID_OPTION_VALUE, &lino, _OVER);
×
4268
    }
4269
  }
4270

4271
  if (pAlterReq->hasEnable) {
46,784✔
4272
    auditLen += snprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "enable:%d,", pAlterReq->enable);
2,837✔
4273
#ifdef TD_ENTERPRISE
4274
    if (pAlterReq->enable == 0) {
2,837✔
4275
      if (mndGetSoDPhase(pMnode) == TSDB_SOD_PHASE_ENFORCE) {
1,506✔
4276
        TAOS_CHECK_GOTO(TSDB_CODE_MND_SOD_RESTRICTED, &lino, _OVER);
×
4277
      }
4278
      // SoD mandatory mode: ensure 3 management roles still satisfied after disable
4279
      if (mndGetClusterSoDMode(pMnode) == SOD_MODE_MANDATORY) {
1,506✔
4280
        TAOS_CHECK_GOTO(mndCheckManagementRoleStatus(pMnode, pUser->user, 0), &lino, _OVER);
744✔
4281
      }
4282
    } else {
4283
      if ((strncmp(pUser->name, TSDB_DEFAULT_USER, TSDB_USER_LEN) == 0) &&
1,331✔
4284
          (mndGetClusterSoDMode(pMnode) == SOD_MODE_MANDATORY)) {
×
4285
        TAOS_CHECK_GOTO(TSDB_CODE_MND_SOD_RESTRICTED, &lino, _OVER);
×
4286
      }
4287
    }
4288
#endif
4289

4290
    newUser.enable = pAlterReq->enable;  // lock or unlock user manually
2,279✔
4291
    if (newUser.enable) {
2,279✔
4292
      // reset login info to allow login immediately
4293
      userCacheResetLoginInfo(newUser.user);
1,331✔
4294
    }
4295
  }
4296

4297
  if (pAlterReq->hasSysinfo) {
46,226✔
4298
    auditLen += snprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "sysinfo:%d,", pAlterReq->sysinfo);
4,831✔
4299
    newUser.sysInfo = pAlterReq->sysinfo;
4,831✔
4300
  }
4301

4302
#ifdef TD_ENTERPRISE
4303
  if (pAlterReq->hasSecurityLevel) {
46,226✔
4304
    // MAC: per FS §4.2.1.4, ALTER USER security_level obeys:
4305
    //  - operator with PRIV_SECURITY_POLICY_ALTER  : allowed; no escalation check (bootstrap-dead-lock avoidance).
4306
    //  - operator without PRIV_SECURITY_POLICY_ALTER: rejected regardless of target value (including [0,0]).
4307
    SUserObj *pOperUser = NULL;
4,748✔
4308
    TAOS_CHECK_GOTO(mndAcquireUser(pMnode, RPC_MSG_USER(pReq), &pOperUser), &lino, _OVER);
4,748✔
4309
    if (!mndUserHasMacLabelPriv(pMnode, pOperUser)) {
4,748✔
4310
      mndReleaseUser(pMnode, pOperUser);
356✔
4311
      mError("user:%s, failed to alter security_level, operator %s lacks PRIV_SECURITY_POLICY_ALTER", pAlterReq->user, RPC_MSG_USER(pReq));
356✔
4312
      TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_RIGHTS, &lino, _OVER);
356✔
4313
    }
4314
    mndReleaseUser(pMnode, pOperUser);
4,392✔
4315
    // MAC mandatory: new security_level must satisfy role floors for both min and max,
4316
    // and direct PRIV_SECURITY_POLICY_ALTER holders must keep maxSecLevel=4.
4317
    if (pMnode->macActive == MAC_MODE_MANDATORY) {
4,392✔
4318
      int8_t floorMaxLevel = mndGetUserRoleFloorMaxLevel(pUser->roles);
3,276✔
4319
      int8_t floorMinLevel = mndGetUserRoleFloorMinLevel(pUser->roles);
3,276✔
4320
      if (pAlterReq->maxSecLevel < floorMaxLevel) {
3,276✔
4321
        mError("user:%s, ALTER security_level rejected under MAC: maxSecLevel(%d) < role maxFloor(%d)", pAlterReq->user,
372✔
4322
               (int32_t)pAlterReq->maxSecLevel, (int32_t)floorMaxLevel);
4323
        TAOS_CHECK_GOTO(TSDB_CODE_MAC_SEC_LEVEL_CONFLICTS_ROLE, &lino, _OVER);
372✔
4324
      }
4325
      if (pAlterReq->minSecLevel < floorMinLevel) {
2,904✔
4326
        mError("user:%s, ALTER security_level rejected under MAC: minSecLevel(%d) < role minFloor(%d)", pAlterReq->user,
186✔
4327
               (int32_t)pAlterReq->minSecLevel, (int32_t)floorMinLevel);
4328
        TAOS_CHECK_GOTO(TSDB_CODE_MAC_SEC_LEVEL_CONFLICTS_ROLE, &lino, _OVER);
186✔
4329
      }
4330
      // Direct PRIV_SECURITY_POLICY_ALTER holder must keep maxSecLevel = TSDB_MAX_SECURITY_LEVEL(4)
4331
      if (PRIV_HAS(&pUser->sysPrivs, PRIV_SECURITY_POLICY_ALTER) &&
2,718✔
4332
          pAlterReq->maxSecLevel < TSDB_MAX_SECURITY_LEVEL) {
186✔
4333
        mError("user:%s, ALTER security_level rejected under MAC: direct PRIV_SECURITY_POLICY_ALTER holder "
186✔
4334
               "must keep maxSecLevel=%d (got %d)",
4335
               pAlterReq->user, (int32_t)TSDB_MAX_SECURITY_LEVEL, (int32_t)pAlterReq->maxSecLevel);
4336
        TAOS_CHECK_GOTO(TSDB_CODE_MAC_SEC_LEVEL_CONFLICTS_ROLE, &lino, _OVER);
186✔
4337
      }
4338
    }
4339
    auditLen += snprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "securityLevels:[%d,%d],",
10,944✔
4340
                         pAlterReq->minSecLevel, pAlterReq->maxSecLevel);
3,648✔
4341
    newUser.minSecLevel = pAlterReq->minSecLevel;
3,648✔
4342
    newUser.maxSecLevel = pAlterReq->maxSecLevel;
3,648✔
4343
  }
4344
#endif
4345

4346
  if (pAlterReq->hasCreatedb) {
45,126✔
4347
    auditLen += snprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "createdb:%d,", pAlterReq->createdb);
6,048✔
4348
    newUser.createdb = pAlterReq->createdb;
6,048✔
4349
    if (newUser.createdb == 1) {
6,048✔
4350
      privAddType(&newUser.sysPrivs, PRIV_DB_CREATE);
4351
    } else {
4352
      privRemoveType(&newUser.sysPrivs, PRIV_DB_CREATE);
4353
    }
4354
  }
4355

4356
#ifdef TD_ENTERPRISE
4357
  if (pAlterReq->hasChangepass) {
45,126✔
4358
    auditLen += snprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "changepass:%d,", pAlterReq->changepass);
×
4359
    newUser.changePass = pAlterReq->changepass;
×
4360
  }
4361

4362
  if (pAlterReq->hasSessionPerUser) {
45,126✔
4363
    auditLen +=
338✔
4364
        tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "sessionPerUser:%d,", pAlterReq->sessionPerUser);
338✔
4365
    newUser.sessionPerUser = pAlterReq->sessionPerUser;
338✔
4366
  }
4367

4368
  if (pAlterReq->hasConnectTime) {
45,126✔
4369
    auditLen += snprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "connectTime:%d,", pAlterReq->connectTime);
169✔
4370
    newUser.connectTime = pAlterReq->connectTime;
169✔
4371
  }
4372

4373
  if (pAlterReq->hasConnectIdleTime) {
45,126✔
4374
    auditLen +=
169✔
4375
        tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "connectIdleTime:%d,", pAlterReq->connectIdleTime);
169✔
4376
    newUser.connectIdleTime = pAlterReq->connectIdleTime;
169✔
4377
  }
4378

4379
  if (pAlterReq->hasCallPerSession) {
45,126✔
4380
    auditLen +=
507✔
4381
        tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "callPerSession:%d,", pAlterReq->callPerSession);
507✔
4382
    newUser.callPerSession = pAlterReq->callPerSession;
507✔
4383
  }
4384

4385
  if (pAlterReq->hasVnodePerCall) {
45,126✔
4386
    auditLen +=
338✔
4387
        tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "vnodePerCall:%d,", pAlterReq->vnodePerCall);
338✔
4388
    newUser.vnodePerCall = pAlterReq->vnodePerCall;
338✔
4389
  }
4390

4391
  if (pAlterReq->hasFailedLoginAttempts) {
45,126✔
4392
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "failedLoginAttempts:%d,",
507✔
4393
                          pAlterReq->failedLoginAttempts);
4394
    newUser.failedLoginAttempts = pAlterReq->failedLoginAttempts;
507✔
4395
  }
4396

4397
  if (pAlterReq->hasPasswordLifeTime) {
45,126✔
4398
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordLifeTime:%d,",
169✔
4399
                          pAlterReq->passwordLifeTime);
4400
    newUser.passwordLifeTime = pAlterReq->passwordLifeTime;
169✔
4401
  }
4402

4403
  if (pAlterReq->hasPasswordReuseTime) {
45,126✔
4404
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordReuseTime:%d,",
507✔
4405
                          pAlterReq->passwordReuseTime);
4406
    newUser.passwordReuseTime = pAlterReq->passwordReuseTime;
507✔
4407
  }
4408

4409
  if (pAlterReq->hasPasswordReuseMax) {
45,126✔
4410
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordReuseMax:%d,",
507✔
4411
                          pAlterReq->passwordReuseMax);
4412
    newUser.passwordReuseMax = pAlterReq->passwordReuseMax;
507✔
4413
  }
4414

4415
  if (pAlterReq->hasPasswordLockTime) {
45,126✔
4416
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordLockTime:%d,",
169✔
4417
                          pAlterReq->passwordLockTime);
4418
    newUser.passwordLockTime = pAlterReq->passwordLockTime;
169✔
4419
  }
4420

4421
  if (pAlterReq->hasPasswordGraceTime) {
45,126✔
4422
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordGraceTime:%d,",
169✔
4423
                          pAlterReq->passwordGraceTime);
4424
    newUser.passwordGraceTime = pAlterReq->passwordGraceTime;
169✔
4425
  }
4426

4427
  if (pAlterReq->hasInactiveAccountTime) {
45,126✔
4428
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "inactiveAccountTime:%d,",
169✔
4429
                          pAlterReq->inactiveAccountTime);
4430
    newUser.inactiveAccountTime = pAlterReq->inactiveAccountTime;
169✔
4431
  }
4432

4433
  if (pAlterReq->hasAllowTokenNum) {
45,126✔
4434
    auditLen +=
338✔
4435
        tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "allowTokenNum:%d,", pAlterReq->allowTokenNum);
338✔
4436
    newUser.allowTokenNum = pAlterReq->allowTokenNum;
338✔
4437
  }
4438

4439
  if (pAlterReq->numDropIpRanges > 0 || pAlterReq->numIpRanges > 0) {
45,126✔
4440
    int32_t dummy = 0;
1,046✔
4441

4442
    // put previous ip whitelist into hash table
4443
    SHashObj *m = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
1,046✔
4444
    if (m == NULL) {
1,046✔
4445
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
4446
    }
4447

4448
    for (int32_t i = 0; i < newUser.pIpWhiteListDual->num; i++) {
4,538✔
4449
      SIpRange range;
3,492✔
4450
      copyIpRange(&range, newUser.pIpWhiteListDual->pIpRanges + i);
3,492✔
4451
      code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
3,492✔
4452
      if (code != 0) {
3,492✔
4453
        taosHashCleanup(m);
×
4454
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
4455
      }
4456
    }
4457

4458
    if (pAlterReq->numDropIpRanges > 0) {
1,046✔
4459
      auditLen +=
523✔
4460
          tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "dropIpRanges:%d,", pAlterReq->numDropIpRanges);
523✔
4461

4462
      for (int32_t i = 0; i < pAlterReq->numDropIpRanges; i++) {
1,215✔
4463
        if (taosHashGetSize(m) == 0) {
692✔
4464
          break;
×
4465
        }
4466

4467
        SIpRange range;
692✔
4468
        copyIpRange(&range, pAlterReq->pDropIpRanges + i);
692✔
4469

4470
        // for white list, drop default ip ranges is allowed, otherwise, we can never
4471
        // convert white list to black list.
4472

4473
        code = taosHashRemove(m, &range, sizeof(range));
692✔
4474
        if (code == TSDB_CODE_NOT_FOUND) {
692✔
4475
          // treat not exist as success
4476
          code = 0;
197✔
4477
        }
4478
        if (code != 0) {
692✔
4479
          taosHashCleanup(m);
×
4480
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
4481
        }
4482
      }
4483
    }
4484

4485
    if (pAlterReq->numIpRanges > 0) {
1,046✔
4486
      auditLen +=
523✔
4487
          tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "addIpRanges:%d,", pAlterReq->numIpRanges);
523✔
4488
      for (int32_t i = 0; i < pAlterReq->numIpRanges; i++) {
1,215✔
4489
        SIpRange range;
692✔
4490
        copyIpRange(&range, pAlterReq->pIpRanges + i);
692✔
4491
        code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
692✔
4492
        if (code != 0) {
692✔
4493
          taosHashCleanup(m);
×
4494
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
4495
        }
4496
      }
4497
    }
4498

4499
    int32_t numOfRanges = taosHashGetSize(m);
1,046✔
4500
    if (numOfRanges > MND_MAX_USER_IP_RANGE) {
1,046✔
4501
      taosHashCleanup(m);
×
4502
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_IP_RANGE, &lino, _OVER);
×
4503
    }
4504

4505
    SIpWhiteListDual *p = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + numOfRanges * sizeof(SIpRange));
1,046✔
4506
    if (p == NULL) {
1,046✔
4507
      taosHashCleanup(m);
×
4508
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
4509
    }
4510

4511
    void   *pIter = taosHashIterate(m, NULL);
1,046✔
4512
    int32_t i = 0;
1,046✔
4513
    while (pIter) {
4,735✔
4514
      size_t    len = 0;
3,689✔
4515
      SIpRange *key = taosHashGetKey(pIter, &len);
3,689✔
4516
      memcpy(p->pIpRanges + i, key, sizeof(SIpRange));
3,689✔
4517
      pIter = taosHashIterate(m, pIter);
3,689✔
4518
      i++;
3,689✔
4519
    }
4520

4521
    taosHashCleanup(m);
1,046✔
4522
    p->num = numOfRanges;
1,046✔
4523
    taosMemoryFreeClear(newUser.pIpWhiteListDual);
1,046✔
4524
    sortIpWhiteList(p);
1,046✔
4525
    newUser.pIpWhiteListDual = p;
1,046✔
4526

4527
    newUser.ipWhiteListVer++;
1,046✔
4528
  }
4529

4530
  if (pAlterReq->numTimeRanges > 0 || pAlterReq->numDropTimeRanges) {
45,126✔
4531
    int32_t dummy = 0;
676✔
4532

4533
    // put previous ip whitelist into hash table
4534
    SHashObj *m = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
676✔
4535
    if (m == NULL) {
676✔
4536
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
4537
    }
4538

4539
    for (int32_t i = 0; i < newUser.pTimeWhiteList->num; i++) {
1,690✔
4540
      SDateTimeWhiteListItem *range = &newUser.pTimeWhiteList->ranges[i];
1,014✔
4541
      if (isDateTimeWhiteListItemExpired(range)) {
1,014✔
4542
        continue;
×
4543
      }
4544
      code = taosHashPut(m, range, sizeof(*range), &dummy, sizeof(dummy));
1,014✔
4545
      if (code != 0) {
1,014✔
4546
        taosHashCleanup(m);
×
4547
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
4548
      }
4549
    }
4550

4551
    if (pAlterReq->numDropTimeRanges > 0) {
676✔
4552
      auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "dropTimeRanges:%d,",
507✔
4553
                            pAlterReq->numDropTimeRanges);
4554
      for (int32_t i = 0; i < pAlterReq->numDropTimeRanges; i++) {
1,183✔
4555
        if (taosHashGetSize(m) == 0) {
676✔
4556
          break;
×
4557
        }
4558
        SDateTimeWhiteListItem range = {0};
676✔
4559
        DateTimeRangeToWhiteListItem(&range, pAlterReq->pDropTimeRanges + i);
676✔
4560

4561
        code = taosHashRemove(m, &range, sizeof(range));
676✔
4562
        if (code == TSDB_CODE_NOT_FOUND) {
676✔
4563
          // treat not exist as success
4564
          code = 0;
×
4565
        }
4566
        if (code != 0) {
676✔
4567
          taosHashCleanup(m);
×
4568
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
4569
        }
4570
      }
4571
    }
4572

4573
    if (pAlterReq->numTimeRanges > 0) {
676✔
4574
      auditLen +=
507✔
4575
          tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "addTimeRanges:%d,", pAlterReq->numTimeRanges);
507✔
4576
      for (int32_t i = 0; i < pAlterReq->numTimeRanges; i++) {
1,183✔
4577
        SDateTimeWhiteListItem range = {0};
676✔
4578
        DateTimeRangeToWhiteListItem(&range, pAlterReq->pTimeRanges + i);
676✔
4579
        if (isDateTimeWhiteListItemExpired(&range)) {
676✔
4580
          continue;
×
4581
        }
4582
        code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
676✔
4583
        if (code != 0) {
676✔
4584
          taosHashCleanup(m);
×
4585
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
4586
        }
4587
      }
4588
    }
4589

4590
    int32_t numOfRanges = taosHashGetSize(m);
676✔
4591
    if (numOfRanges > MND_MAX_USER_TIME_RANGE) {
676✔
4592
      taosHashCleanup(m);
×
4593
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_TIME_RANGE, &lino, _OVER);
×
4594
    }
4595

4596
    SDateTimeWhiteList *p =
1,352✔
4597
        taosMemoryCalloc(1, sizeof(SDateTimeWhiteList) + numOfRanges * sizeof(SDateTimeWhiteListItem));
676✔
4598
    if (p == NULL) {
676✔
4599
      taosHashCleanup(m);
×
4600
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
4601
    }
4602

4603
    void   *pIter = taosHashIterate(m, NULL);
676✔
4604
    int32_t i = 0;
676✔
4605
    while (pIter) {
1,690✔
4606
      size_t                  len = 0;
1,014✔
4607
      SDateTimeWhiteListItem *key = taosHashGetKey(pIter, &len);
1,014✔
4608
      memcpy(&p->ranges[i], key, sizeof(SDateTimeWhiteListItem));
1,014✔
4609
      pIter = taosHashIterate(m, pIter);
1,014✔
4610
      i++;
1,014✔
4611
    }
4612

4613
    taosHashCleanup(m);
676✔
4614
    p->num = numOfRanges;
676✔
4615
    taosMemoryFreeClear(newUser.pTimeWhiteList);
676✔
4616
    sortTimeWhiteList(p);
676✔
4617
    newUser.pTimeWhiteList = p;
676✔
4618
    newUser.timeWhiteListVer++;
676✔
4619
  }
4620
#endif  // TD_ENTERPRISE
4621

4622
  TAOS_CHECK_GOTO(mndAlterUser(pMnode, &newUser, pReq), &lino, _OVER);
45,126✔
4623
  if (pAlterReq->hasEnable) {
45,126✔
4624
    if (newUser.enable) {
2,279✔
4625
      if (taosHashGet(newUser.roles, TSDB_ROLE_SYSAUDIT_LOG, sizeof(TSDB_ROLE_SYSAUDIT_LOG))) {
1,331✔
4626
        (void)mndResetAuditLogUser(pMnode, newUser.user, true);
×
4627
      }
4628
    } else {
4629
      (void)mndResetAuditLogUser(pMnode, newUser.user, false);
948✔
4630
    }
4631
  }
4632
  code = TSDB_CODE_ACTION_IN_PROGRESS;
45,126✔
4633

4634
  if (auditLen > 0) {
45,126✔
4635
    auditLog[--auditLen] = 0;  // remove last ','
45,126✔
4636
  }
4637
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
45,126✔
4638
    int64_t tse = taosGetTimestampMs();
45,126✔
4639
    double  duration = (double)(tse - tss);
45,126✔
4640
    duration = duration / 1000;
45,126✔
4641
    auditRecord(pReq, pMnode->clusterId, "alterUser", "", pAlterReq->user, auditLog, auditLen, duration, 0);
45,126✔
4642
  }
4643

4644
_OVER:
61,703✔
4645
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
61,703✔
4646
    mError("user:%s, failed to alter at line %d since %s", pAlterReq->user, lino, tstrerror(code));
16,577✔
4647
  }
4648

4649
  mndReleaseUser(pMnode, pUser);
61,703✔
4650
  mndUserFreeObj(&newUser);
61,703✔
4651
  return code;
61,703✔
4652
}
4653

4654
static int32_t mndProcessAlterUserReq(SRpcMsg *pReq) {
61,703✔
4655
  SAlterUserReq alterReq = {0};
61,703✔
4656

4657
  int32_t code = tDeserializeSAlterUserReq(pReq->pCont, pReq->contLen, &alterReq);
61,703✔
4658
  if (code != 0) {
61,703✔
4659
    mError("failed to deserialize alter user request at line %d since %s", __LINE__, tstrerror(code));
×
4660
    TAOS_RETURN(code);
×
4661
  }
4662

4663
  if (alterReq.user[0] == 0) {
61,703✔
4664
    tFreeSAlterUserReq(&alterReq);
×
4665
    mError("failed to alter user at line %d since invalid user format", __LINE__);
×
4666
    TAOS_RETURN(TSDB_CODE_MND_INVALID_USER_FORMAT);
×
4667
  }
4668

4669
  mInfo("user:%s, start to alter", alterReq.user);
61,703✔
4670
  if (alterReq.alterType == TSDB_ALTER_USER_BASIC_INFO) {
61,703✔
4671
    code = mndProcessAlterUserBasicInfoReq(pReq, &alterReq);
61,703✔
4672
  } else {
4673
    // code = mndProcessAlterUserPrivilegesReq(pReq, &alterReq); // obsolete
4674
  }
4675

4676
  tFreeSAlterUserReq(&alterReq);
61,703✔
4677
  TAOS_RETURN(code);
61,703✔
4678
}
4679

4680
int32_t mndResetAuditLogUser(SMnode *pMnode, const char *user, bool isAdd) {
56,724,292✔
4681
  if (user) {
56,724,292✔
4682
    (void)taosThreadRwlockRdlock(&userCache.rw);
57,998✔
4683
    if (isAdd) {
57,998✔
4684
      if (userCache.auditLogUser[0] != 0) {
81✔
4685
        (void)taosThreadRwlockUnlock(&userCache.rw);
×
4686
        return 0;
×
4687
      }
4688
      (void)taosThreadRwlockUnlock(&userCache.rw);
81✔
4689
      (void)taosThreadRwlockWrlock(&userCache.rw);
81✔
4690
      (void)tsnprintf(userCache.auditLogUser, TSDB_USER_LEN, "%s", user);
81✔
4691
      (void)taosThreadRwlockUnlock(&userCache.rw);
81✔
4692
      return 0;
81✔
4693
    } else if (strcmp(userCache.auditLogUser, user) != 0) {
57,917✔
4694
      (void)taosThreadRwlockUnlock(&userCache.rw);
57,917✔
4695
      return 0;
57,917✔
4696
    }
4697
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
4698
  }
4699

4700
  void     *pIter = NULL;
56,666,294✔
4701
  SSdb     *pSdb = pMnode->pSdb;
56,666,294✔
4702
  SUserObj *pUser = NULL;
56,666,294✔
4703
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser))) {
120,397,733✔
4704
    if (pUser->enable == 0) {
63,731,439✔
4705
      mndReleaseUser(pMnode, pUser);
32,911✔
4706
      continue;
32,911✔
4707
    }
4708
    if (taosHashGet(pUser->roles, TSDB_ROLE_SYSAUDIT_LOG, sizeof(TSDB_ROLE_SYSAUDIT_LOG)) != NULL) {
63,698,528✔
4709
      (void)taosThreadRwlockWrlock(&userCache.rw);
×
4710
      (void)tsnprintf(userCache.auditLogUser, TSDB_USER_LEN, "%s", pUser->name);
×
4711
      (void)taosThreadRwlockUnlock(&userCache.rw);
×
4712
      sdbCancelFetch(pSdb, pIter);
×
4713
      mndReleaseUser(pMnode, pUser);
×
4714
      return 0;
×
4715
    }
4716
    mndReleaseUser(pMnode, pUser);
63,698,528✔
4717
  }
4718
  (void)taosThreadRwlockWrlock(&userCache.rw);
56,666,294✔
4719
  userCache.auditLogUser[0] = 0;
56,666,294✔
4720
  (void)taosThreadRwlockUnlock(&userCache.rw);
56,666,294✔
4721
  return TSDB_CODE_MND_USER_NOT_AVAILABLE;
56,666,294✔
4722
}
4723

4724
int32_t mndGetAuditUser(SMnode *pMnode, char *user) {
56,667,347✔
4725
  (void)taosThreadRwlockRdlock(&userCache.rw);
56,667,347✔
4726
  if (userCache.auditLogUser[0] != 0) {
56,667,347✔
4727
    (void)tsnprintf(user, TSDB_USER_LEN, "%s", userCache.auditLogUser);
1,053✔
4728
    (void)taosThreadRwlockUnlock(&userCache.rw);
1,053✔
4729
    return 0;
1,053✔
4730
  }
4731
  (void)taosThreadRwlockUnlock(&userCache.rw);
56,666,294✔
4732

4733
  int32_t code = 0;
56,666,294✔
4734
  if ((code = mndResetAuditLogUser(pMnode, NULL, false)) != 0) {
56,666,294✔
4735
    return code;
56,666,294✔
4736
  }
4737

4738
  (void)taosThreadRwlockRdlock(&userCache.rw);
×
4739
  (void)tsnprintf(user, TSDB_USER_LEN, "%s", userCache.auditLogUser);
×
4740
  (void)taosThreadRwlockUnlock(&userCache.rw);
×
4741

4742
  return 0;
×
4743
}
4744

4745
static int32_t mndDropUser(SMnode *pMnode, SRpcMsg *pReq, SUserObj *pUser) {
56,969✔
4746
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "drop-user");
56,969✔
4747
  if (pTrans == NULL) {
56,969✔
4748
    mError("user:%s, failed to drop since %s", pUser->user, terrstr());
×
4749
    TAOS_RETURN(terrno);
×
4750
  }
4751
  mInfo("trans:%d, used to drop user:%s", pTrans->id, pUser->user);
56,969✔
4752

4753
  SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
56,969✔
4754
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
56,969✔
4755
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
4756
    mndTransDrop(pTrans);
×
4757
    TAOS_RETURN(terrno);
×
4758
  }
4759
  if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED) < 0) {
56,969✔
4760
    mndTransDrop(pTrans);
×
4761
    TAOS_RETURN(terrno);
×
4762
  }
4763

4764
  if (mndDropTokensByUser(pMnode, pTrans, pUser->user) != 0) {
56,969✔
4765
    mndTransDrop(pTrans);
×
4766
    TAOS_RETURN(terrno);
×
4767
  }
4768

4769
  if (mndTransPrepare(pMnode, pTrans) != 0) {
56,969✔
4770
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
4771
    mndTransDrop(pTrans);
×
4772
    TAOS_RETURN(terrno);
×
4773
  }
4774

4775
  userCacheRemoveUser(pUser->user);
56,969✔
4776
  mndDropCachedTokensByUser(pUser->user);
56,969✔
4777
  (void)mndResetAuditLogUser(pMnode, pUser->user, false);
56,969✔
4778

4779
  mndTransDrop(pTrans);
56,969✔
4780
  TAOS_RETURN(0);
56,969✔
4781
}
4782

4783
static int32_t mndProcessDropUserReq(SRpcMsg *pReq) {
62,004✔
4784
  SMnode      *pMnode = pReq->info.node;
62,004✔
4785
  int32_t      code = 0;
62,004✔
4786
  int32_t      lino = 0;
62,004✔
4787
  SUserObj    *pOperUser = NULL;
62,004✔
4788
  SUserObj    *pUser = NULL;
62,004✔
4789
  SDropUserReq dropReq = {0};
62,004✔
4790
  int64_t      tss = taosGetTimestampMs();
62,004✔
4791

4792
  TAOS_CHECK_GOTO(tDeserializeSDropUserReq(pReq->pCont, pReq->contLen, &dropReq), &lino, _OVER);
62,004✔
4793

4794
  mInfo("user:%s, start to drop", dropReq.user);
62,004✔
4795

4796
  if (dropReq.user[0] == 0) {
62,004✔
4797
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
4798
  }
4799

4800
  if (0 == strcmp(dropReq.user, TSDB_DEFAULT_USER)) {
62,004✔
4801
    return TSDB_CODE_MND_NO_RIGHTS;
×
4802
  }
4803

4804
#ifdef TD_ENTERPRISE
4805
  if (mndGetSoDPhase(pMnode) == TSDB_SOD_PHASE_ENFORCE) {
62,004✔
4806
    TAOS_CHECK_GOTO(TSDB_CODE_MND_SOD_RESTRICTED, &lino, _OVER);
×
4807
  }
4808
#endif
4809

4810
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, dropReq.user, &pUser), &lino, _OVER);
62,004✔
4811
#ifdef TD_ENTERPRISE
4812
  // SoD mandatory mode: ensure 3 management roles still satisfied after drop
4813
  if (mndGetClusterSoDMode(pMnode) == SOD_MODE_MANDATORY) {
58,085✔
4814
    TAOS_CHECK_GOTO(mndCheckManagementRoleStatus(pMnode, dropReq.user, 0), &lino, _OVER);
3,478✔
4815
  }
4816
#endif
4817

4818
  code = mndAcquireUser(pMnode, RPC_MSG_USER(pReq), &pOperUser);
56,969✔
4819
  if (pOperUser == NULL) {
56,969✔
4820
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_USER_FROM_CONN, &lino, _OVER);
×
4821
  }
4822

4823
  // TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, RPC_MSG_USER(pReq), MND_OPER_DROP_USER), &lino, _OVER);
4824
  TAOS_CHECK_GOTO(mndCheckSysObjPrivilege(pMnode, pOperUser, RPC_MSG_TOKEN(pReq), PRIV_USER_DROP, 0, 0, NULL, NULL),
56,969✔
4825
                  &lino, _OVER);
4826

4827
  TAOS_CHECK_GOTO(mndDropUser(pMnode, pReq, pUser), &lino, _OVER);
56,969✔
4828
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
56,969✔
4829

4830
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
56,969✔
4831
    int64_t tse = taosGetTimestampMs();
56,969✔
4832
    double  duration = (double)(tse - tss);
56,969✔
4833
    duration = duration / 1000;
56,969✔
4834
    auditRecord(pReq, pMnode->clusterId, "dropUser", "", dropReq.user, dropReq.sql, dropReq.sqlLen, duration, 0);
56,969✔
4835
  }
4836

4837
_OVER:
62,004✔
4838
  if (dropReq.ignoreNotExists && code == TSDB_CODE_MND_USER_NOT_EXIST) {
62,004✔
4839
    code = 0;
1,741✔
4840
  } else if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
60,263✔
4841
    mError("user:%s, failed to drop at line %d since %s", dropReq.user, lino, tstrerror(code));
3,294✔
4842
  }
4843

4844
  mndReleaseUser(pMnode, pUser);
62,004✔
4845
  mndReleaseUser(pMnode, pOperUser);
62,004✔
4846
  tFreeSDropUserReq(&dropReq);
62,004✔
4847
  TAOS_RETURN(code);
62,004✔
4848
}
4849

4850
static int32_t mndProcessGetUserAuthReq(SRpcMsg *pReq) {
6,797,085✔
4851
  SMnode         *pMnode = pReq->info.node;
6,797,085✔
4852
  int32_t         code = 0;
6,797,085✔
4853
  int32_t         lino = 0;
6,797,085✔
4854
  int32_t         contLen = 0;
6,797,085✔
4855
  void           *pRsp = NULL;
6,797,085✔
4856
  SUserObj       *pUser = NULL;
6,797,085✔
4857
  SGetUserAuthReq authReq = {0};
6,797,085✔
4858
  SGetUserAuthRsp authRsp = {0};
6,797,085✔
4859

4860
  TAOS_CHECK_EXIT(tDeserializeSGetUserAuthReq(pReq->pCont, pReq->contLen, &authReq));
6,797,085✔
4861
  mTrace("user:%s, start to get auth", authReq.user);
6,797,085✔
4862

4863
  TAOS_CHECK_EXIT(mndAcquireUser(pMnode, authReq.user, &pUser));
6,797,085✔
4864

4865
  TAOS_CHECK_EXIT(mndSetUserAuthRsp(pMnode, pUser, &authRsp));
6,795,820✔
4866

4867
  contLen = tSerializeSGetUserAuthRsp(NULL, 0, &authRsp);
6,794,173✔
4868
  if (contLen < 0) {
6,795,015✔
4869
    TAOS_CHECK_EXIT(contLen);
×
4870
  }
4871
  pRsp = rpcMallocCont(contLen);
6,795,015✔
4872
  if (pRsp == NULL) {
6,795,015✔
4873
    TAOS_CHECK_EXIT(terrno);
×
4874
  }
4875

4876
  contLen = tSerializeSGetUserAuthRsp(pRsp, contLen, &authRsp);
6,795,015✔
4877
  if (contLen < 0) {
6,795,015✔
4878
    TAOS_CHECK_EXIT(contLen);
×
4879
  }
4880

4881
_exit:
6,796,280✔
4882
  mndReleaseUser(pMnode, pUser);
6,797,085✔
4883
  tFreeSGetUserAuthRsp(&authRsp);
6,797,085✔
4884
  if (code < 0) {
6,797,085✔
4885
    mError("user:%s, failed to get auth at line %d since %s", authReq.user, lino, tstrerror(code));
1,265✔
4886
    rpcFreeCont(pRsp);
1,265✔
4887
    pRsp = NULL;
1,265✔
4888
    contLen = 0;
1,265✔
4889
  }
4890
  pReq->info.rsp = pRsp;
6,797,085✔
4891
  pReq->info.rspLen = contLen;
6,797,085✔
4892
  pReq->code = code;
6,796,280✔
4893

4894
  TAOS_RETURN(code);
6,797,085✔
4895
}
4896

4897
static void base32Encode(const uint8_t *in, int32_t inLen, char *out) {
20,319✔
4898
  int buffer = 0, bits = 0;
20,319✔
4899
  int outLen = 0;
20,319✔
4900

4901
  // process all input bytes
4902
  for (int i = 0; i < inLen; i++) {
670,527✔
4903
    buffer = (buffer << 8) | in[i];
650,208✔
4904
    bits += 8;
650,208✔
4905

4906
    while (bits >= 5) {
1,686,477✔
4907
      int v = (buffer >> (bits - 5)) & 0x1F;
1,036,269✔
4908
      out[outLen++] = (v >= 26) ? (v - 26 + '2') : (v + 'A');
1,036,269✔
4909
      bits -= 5;
1,036,269✔
4910
    }
4911
  }
4912

4913
  // process remaining bits
4914
  if (bits > 0) {
20,319✔
4915
    int v = (buffer << (5 - bits)) & 0x1F;
20,319✔
4916
    out[outLen++] = (v >= 26) ? (v - 26 + '2') : (v + 'A');
20,319✔
4917
  }
4918

4919
  out[outLen] = '\0';
20,319✔
4920
}
20,319✔
4921

4922
static int32_t mndCreateTotpSecret(SMnode *pMnode, SUserObj *pUser, SRpcMsg *pReq) {
20,319✔
4923
  SCreateTotpSecretRsp rsp = {0};
20,319✔
4924

4925
  base32Encode((uint8_t *)pUser->totpsecret, sizeof(pUser->totpsecret), rsp.totpSecret);
20,319✔
4926
  tstrncpy(rsp.user, pUser->user, sizeof(rsp.user));
20,319✔
4927

4928
  int32_t len = tSerializeSCreateTotpSecretRsp(NULL, 0, &rsp);
20,319✔
4929
  if (len < 0) {
20,319✔
4930
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
4931
  }
4932

4933
  void *pData = taosMemoryMalloc(len);
20,319✔
4934
  if (pData == NULL) {
20,319✔
4935
    TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
4936
  }
4937

4938
  if (tSerializeSCreateTotpSecretRsp(pData, len, &rsp) != len) {
20,319✔
4939
    taosMemoryFree(pData);
×
4940
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
4941
  }
4942

4943
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "create-totp-secret");
20,319✔
4944
  if (pTrans == NULL) {
20,319✔
4945
    mError("user:%s, failed to create totp secret since %s", pUser->user, terrstr());
×
4946
    taosMemoryFree(pData);
×
4947
    TAOS_RETURN(terrno);
×
4948
  }
4949
  mInfo("trans:%d, used to create totp secret for user:%s", pTrans->id, pUser->user);
20,319✔
4950

4951
  mndTransSetUserData(pTrans, pData, len);
20,319✔
4952

4953
  SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
20,319✔
4954
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
20,319✔
4955
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
4956
    mndTransDrop(pTrans);
×
4957
    TAOS_RETURN(terrno);
×
4958
  }
4959
  if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY) < 0) {
20,319✔
4960
    mndTransDrop(pTrans);
×
4961
    TAOS_RETURN(terrno);
×
4962
  }
4963

4964
  if (mndTransPrepare(pMnode, pTrans) != 0) {
20,319✔
4965
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
4966
    mndTransDrop(pTrans);
×
4967
    TAOS_RETURN(terrno);
×
4968
  }
4969

4970
  mndTransDrop(pTrans);
20,319✔
4971
  TAOS_RETURN(0);
20,319✔
4972
}
4973

4974
static int32_t mndProcessCreateTotpSecretReq(SRpcMsg *pReq) {
20,505✔
4975
  SMnode              *pMnode = pReq->info.node;
20,505✔
4976
  int32_t              code = 0;
20,505✔
4977
  int32_t              lino = 0;
20,505✔
4978
  SUserObj            *pUser = NULL;
20,505✔
4979
  SUserObj             newUser = {0};
20,505✔
4980
  SCreateTotpSecretReq req = {0};
20,505✔
4981
  int64_t              tss = taosGetTimestampMs();
20,505✔
4982

4983
  TAOS_CHECK_GOTO(tDeserializeSCreateTotpSecretReq(pReq->pCont, pReq->contLen, &req), &lino, _OVER);
20,505✔
4984
  mTrace("user:%s, start to create/update totp secret", req.user);
20,505✔
4985

4986
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, req.user, &pUser), &lino, _OVER);
20,505✔
4987
  TAOS_CHECK_GOTO(mndCheckTotpSecretPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser, PRIV_TOTP_CREATE),
20,319✔
4988
                  &lino, _OVER);
4989
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
20,319✔
4990
  taosSafeRandBytes((uint8_t *)newUser.totpsecret, sizeof(newUser.totpsecret));
20,319✔
4991
  TAOS_CHECK_GOTO(mndCreateTotpSecret(pMnode, &newUser, pReq), &lino, _OVER);
20,319✔
4992

4993
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
20,319✔
4994
    double duration = (double)(taosGetTimestampMs() - tss) / 1000.0;
20,319✔
4995
    auditRecord(pReq, pMnode->clusterId, "createTotpSecret", "", req.user, req.sql, req.sqlLen, duration, 0);
20,319✔
4996
  }
4997

4998
_OVER:
20,505✔
4999
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
20,505✔
5000
    mError("user:%s, failed to create totp secret at line %d since %s", req.user, lino, tstrerror(code));
186✔
5001
  }
5002
  mndReleaseUser(pMnode, pUser);
20,505✔
5003
  mndUserFreeObj(&newUser);
20,505✔
5004
  tFreeSCreateTotpSecretReq(&req);
20,505✔
5005
  TAOS_RETURN(code);
20,505✔
5006
}
5007

5008
int32_t mndBuildSMCreateTotpSecretResp(STrans *pTrans, void **ppResp, int32_t *pRespLen) {
20,319✔
5009
  // user data is the response
5010
  *ppResp = pTrans->userData;
20,319✔
5011
  *pRespLen = pTrans->userDataLen;
20,319✔
5012
  pTrans->userData = NULL;
20,319✔
5013
  pTrans->userDataLen = 0;
20,319✔
5014
  return 0;
20,319✔
5015
}
5016

5017
static int32_t mndProcessDropTotpSecretReq(SRpcMsg *pReq) {
7,812✔
5018
  SMnode            *pMnode = pReq->info.node;
7,812✔
5019
  int32_t            code = 0;
7,812✔
5020
  int32_t            lino = 0;
7,812✔
5021
  SUserObj          *pUser = NULL;
7,812✔
5022
  SUserObj           newUser = {0};
7,812✔
5023
  SDropTotpSecretReq req = {0};
7,812✔
5024
  int64_t            tss = taosGetTimestampMs();
7,812✔
5025

5026
  TAOS_CHECK_GOTO(tDeserializeSDropTotpSecretReq(pReq->pCont, pReq->contLen, &req), &lino, _OVER);
7,812✔
5027
  mTrace("user:%s, start to drop totp secret", req.user);
7,812✔
5028

5029
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, req.user, &pUser), &lino, _OVER);
7,812✔
5030
  TAOS_CHECK_GOTO(mndCheckTotpSecretPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser, PRIV_TOTP_DROP),
5,952✔
5031
                  &lino, _OVER);
5032

5033
  if (!mndIsTotpEnabledUser(pUser)) {
5,952✔
5034
    TAOS_CHECK_GOTO(TSDB_CODE_MND_TOTP_SECRET_NOT_EXIST, &lino, _OVER);
5,580✔
5035
  }
5036

5037
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
372✔
5038
  (void)memset(newUser.totpsecret, 0, sizeof(newUser.totpsecret));
372✔
5039
  TAOS_CHECK_GOTO(mndAlterUser(pMnode, &newUser, pReq), &lino, _OVER);
372✔
5040

5041
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
372✔
5042
    double duration = (double)(taosGetTimestampMs() - tss) / 1000.0;
372✔
5043
    auditRecord(pReq, pMnode->clusterId, "dropTotpSecret", "", req.user, req.sql, req.sqlLen, duration, 0);
372✔
5044
  }
5045

5046
_OVER:
7,812✔
5047
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
7,812✔
5048
    mError("user:%s, failed to drop totp secret at line %d since %s", req.user, lino, tstrerror(code));
7,440✔
5049
  }
5050
  mndReleaseUser(pMnode, pUser);
7,812✔
5051
  mndUserFreeObj(&newUser);
7,812✔
5052
  tFreeSDropTotpSecretReq(&req);
7,812✔
5053
  TAOS_RETURN(code);
7,812✔
5054
}
5055

5056
bool mndIsTotpEnabledUser(SUserObj *pUser) {
4,916,670✔
5057
  for (int32_t i = 0; i < sizeof(pUser->totpsecret); i++) {
160,080,807✔
5058
    if (pUser->totpsecret[i] != 0) {
155,231,319✔
5059
      return true;
65,190✔
5060
    }
5061
  }
5062
  return false;
4,849,488✔
5063
}
5064

5065
static int32_t mndRetrieveUsers(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
142,739✔
5066
  SMnode   *pMnode = pReq->info.node;
142,739✔
5067
  SSdb     *pSdb = pMnode->pSdb;
142,739✔
5068
  int32_t   code = 0;
142,739✔
5069
  int32_t   lino = 0;
142,739✔
5070
  int32_t   numOfRows = 0;
142,739✔
5071
  SUserObj *pUser = NULL;
142,739✔
5072
  int32_t   cols = 0;
142,739✔
5073
  int8_t    flag = 0;
142,739✔
5074
  char     *pWrite = NULL;
142,739✔
5075
  char     *buf = NULL;
142,739✔
5076
  char     *varstr = NULL;
142,739✔
5077
  char      tBuf[TSDB_MAX_SUBROLE * TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
142,739✔
5078
  int32_t   bufSize = sizeof(tBuf) - VARSTR_HEADER_SIZE;
142,739✔
5079

5080
  while (numOfRows < rows) {
1,240,160✔
5081
    pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
1,240,160✔
5082
    if (pShow->pIter == NULL) break;
1,240,160✔
5083

5084
    cols = 0;
1,097,421✔
5085
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
1,097,421✔
5086
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
1,097,421✔
5087
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
1,097,421✔
5088
    COL_DATA_SET_VAL_GOTO((const char *)name, false, pUser, pShow->pIter, _exit);
1,097,421✔
5089

5090
    cols++;
1,097,421✔
5091
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
1,097,421✔
5092
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->superUser, false, pUser, pShow->pIter, _exit);
1,097,421✔
5093

5094
    cols++;
1,097,421✔
5095
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
1,097,421✔
5096
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->enable, false, pUser, pShow->pIter, _exit);
1,097,421✔
5097

5098
    cols++;
1,097,421✔
5099
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
1,097,421✔
5100
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sysInfo, false, pUser, pShow->pIter, _exit);
1,097,421✔
5101

5102
    cols++;
1,097,421✔
5103
    flag = pUser->createdb ? 1 : 0;
1,097,421✔
5104
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
1,097,421✔
5105
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
1,097,421✔
5106

5107
    cols++;
1,097,421✔
5108
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
1,097,421✔
5109
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->createdTime, false, pUser, pShow->pIter, _exit);
1,097,421✔
5110

5111
    cols++;
1,097,421✔
5112
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
1,097,421✔
5113
    flag = mndIsTotpEnabledUser(pUser) ? 1 : 0;
1,097,421✔
5114
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
1,097,421✔
5115

5116
    cols++;
1,097,421✔
5117

5118
    int32_t tlen = convertIpWhiteListToStr(pUser, &buf);
1,097,421✔
5119
    if (tlen != 0) {
1,097,421✔
5120
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
1,097,421✔
5121
      if (varstr == NULL) {
1,097,421✔
5122
        sdbRelease(pSdb, pUser);
×
5123
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
5124
      }
5125
      varDataSetLen(varstr, tlen);
1,097,421✔
5126
      (void)memcpy(varDataVal(varstr), buf, tlen);
1,097,421✔
5127

5128
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
1,097,421✔
5129
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
1,097,421✔
5130

5131
      taosMemoryFreeClear(buf);
1,097,421✔
5132
    } else {
5133
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
5134
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
5135
    }
5136

5137
    cols++;
1,097,421✔
5138
    tlen = convertTimeRangesToStr(pUser, &buf);
1,097,421✔
5139
    if (tlen != 0) {
1,097,421✔
5140
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
1,097,421✔
5141
      if (varstr == NULL) {
1,097,421✔
5142
        sdbRelease(pSdb, pUser);
×
5143
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
5144
      }
5145
      varDataSetLen(varstr, tlen);
1,097,421✔
5146
      (void)memcpy(varDataVal(varstr), buf, tlen);
1,097,421✔
5147

5148
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
1,097,421✔
5149
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
1,097,421✔
5150

5151
      taosMemoryFreeClear(buf);
1,097,421✔
5152
    } else {
5153
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
5154
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
5155
    }
5156

5157
    if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
1,097,421✔
5158
      void  *pIter = NULL;
1,097,421✔
5159
      size_t klen = 0, tlen = 0;
1,097,421✔
5160
      char  *pBuf = POINTER_SHIFT(tBuf, VARSTR_HEADER_SIZE);
1,097,421✔
5161
      while ((pIter = taosHashIterate(pUser->roles, pIter))) {
2,487,283✔
5162
        char *roleName = taosHashGetKey(pIter, &klen);
1,389,862✔
5163
        tlen += snprintf(pBuf + tlen, bufSize - tlen, "%s,", roleName);
1,389,862✔
5164
      }
5165
      if (tlen > 0) {
1,097,421✔
5166
        pBuf[--tlen] = 0;  // remove last ','
1,097,260✔
5167
      } else {
5168
        pBuf[0] = 0;
161✔
5169
      }
5170
      varDataSetLen(tBuf, tlen);
1,097,421✔
5171
      COL_DATA_SET_VAL_GOTO((const char *)tBuf, false, pUser, pShow->pIter, _exit);
1,097,421✔
5172
    }
5173

5174
    if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
1,097,421✔
5175
      char  *pBuf = POINTER_SHIFT(tBuf, VARSTR_HEADER_SIZE);
1,097,421✔
5176
      size_t vlen = snprintf(pBuf, bufSize, "[%d,%d]", pUser->minSecLevel, pUser->maxSecLevel);
1,097,421✔
5177
      varDataSetLen(tBuf, vlen);
1,097,421✔
5178
      COL_DATA_SET_VAL_GOTO((const char *)tBuf, false, pUser, pShow->pIter, _exit);
1,097,421✔
5179
    }
5180

5181
    numOfRows++;
1,097,421✔
5182
    sdbRelease(pSdb, pUser);
1,097,421✔
5183
  }
5184

5185
  pShow->numOfRows += numOfRows;
142,739✔
5186
_exit:
142,739✔
5187
  taosMemoryFreeClear(buf);
142,739✔
5188
  taosMemoryFreeClear(varstr);
142,739✔
5189
  if (code < 0) {
142,739✔
5190
    mError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
5191
    TAOS_RETURN(code);
×
5192
  }
5193
  return numOfRows;
142,739✔
5194
}
5195

5196
static int32_t mndRetrieveUsersFull(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
15,757✔
5197
  int32_t numOfRows = 0;
15,757✔
5198
#ifdef TD_ENTERPRISE
5199
  SMnode   *pMnode = pReq->info.node;
15,757✔
5200
  SSdb     *pSdb = pMnode->pSdb;
15,757✔
5201
  SUserObj *pOperUser = NULL;
15,757✔
5202
  SUserObj *pUser = NULL;
15,757✔
5203
  int32_t   code = 0;
15,757✔
5204
  int32_t   lino = 0;
15,757✔
5205
  int32_t   cols = 0;
15,757✔
5206
  int8_t    flag = 0;
15,757✔
5207
  char     *pWrite = NULL;
15,757✔
5208
  char     *buf = NULL;
15,757✔
5209
  char     *varstr = NULL;
15,757✔
5210
  char     *pBuf = NULL;
15,757✔
5211
  char      tBuf[TSDB_MAX_SUBROLE * TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
15,757✔
5212
  int32_t   bufSize = sizeof(tBuf) - VARSTR_HEADER_SIZE;
15,757✔
5213
  bool      showSecurityInfo = false;
15,757✔
5214

5215
  code = mndAcquireUser(pMnode, RPC_MSG_USER(pReq), &pOperUser);
15,757✔
5216
  if (pOperUser == NULL) {
15,757✔
5217
    TAOS_CHECK_EXIT(TSDB_CODE_MND_NO_USER_FROM_CONN);
×
5218
  }
5219
  if (0 == mndCheckSysObjPrivilege(pMnode, pOperUser, RPC_MSG_TOKEN(pReq), PRIV_USER_SHOW_SECURITY, 0, 0, NULL, NULL)) {
15,757✔
5220
    showSecurityInfo = true;
15,757✔
5221
  }
5222

5223
  while (numOfRows < rows) {
680,881✔
5224
    pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
680,881✔
5225
    if (pShow->pIter == NULL) break;
680,881✔
5226

5227
    cols = 0;
665,124✔
5228
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
665,124✔
5229
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
665,124✔
5230
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
665,124✔
5231
    COL_DATA_SET_VAL_GOTO((const char *)name, false, pUser, pShow->pIter, _exit);
665,124✔
5232

5233
    cols++;
665,124✔
5234
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
665,124✔
5235
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->superUser, false, pUser, pShow->pIter, _exit);
665,124✔
5236

5237
    cols++;
665,124✔
5238
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
665,124✔
5239
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->enable, false, pUser, pShow->pIter, _exit);
665,124✔
5240

5241
    cols++;
665,124✔
5242
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
665,124✔
5243
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sysInfo, false, pUser, pShow->pIter, _exit);
665,124✔
5244

5245
    cols++;
665,124✔
5246
    flag = pUser->createdb ? 1 : 0;
665,124✔
5247
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
665,124✔
5248
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
665,124✔
5249

5250
    cols++;
665,124✔
5251
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
665,124✔
5252
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->createdTime, false, pUser, pShow->pIter, _exit);
665,124✔
5253

5254
    cols++;
665,124✔
5255
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
665,124✔
5256
    flag = mndIsTotpEnabledUser(pUser) ? 1 : 0;
665,124✔
5257
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
665,124✔
5258

5259
    cols++;
665,124✔
5260
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
665,124✔
5261
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->changePass, false, pUser, pShow->pIter, _exit);
665,124✔
5262

5263
    cols++;
665,124✔
5264
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
665,124✔
5265
    char pass[TSDB_PASSWORD_LEN + VARSTR_HEADER_SIZE] = {0};
665,124✔
5266
    STR_WITH_MAXSIZE_TO_VARSTR(pass, showSecurityInfo ? pUser->passwords[0].pass : "*",
665,124✔
5267
                               pShow->pMeta->pSchemas[cols].bytes);
5268
    COL_DATA_SET_VAL_GOTO((const char *)pass, false, pUser, pShow->pIter, _exit);
665,124✔
5269

5270
    cols++;
665,124✔
5271
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
665,124✔
5272
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sessionPerUser, false, pUser, pShow->pIter, _exit);
665,124✔
5273

5274
    cols++;
665,124✔
5275
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
665,124✔
5276
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->connectTime, false, pUser, pShow->pIter, _exit);
665,124✔
5277

5278
    cols++;
665,124✔
5279
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
665,124✔
5280
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->connectIdleTime, false, pUser, pShow->pIter, _exit);
665,124✔
5281

5282
    cols++;
665,124✔
5283
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
665,124✔
5284
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->callPerSession, false, pUser, pShow->pIter, _exit);
665,124✔
5285

5286
    cols++;
665,124✔
5287
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
665,124✔
5288
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->vnodePerCall, false, pUser, pShow->pIter, _exit);
665,124✔
5289

5290
    cols++;
665,124✔
5291
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
665,124✔
5292
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->failedLoginAttempts, false, pUser, pShow->pIter, _exit);
665,124✔
5293

5294
    cols++;
665,124✔
5295
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
665,124✔
5296
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordLifeTime, false, pUser, pShow->pIter, _exit);
665,124✔
5297

5298
    cols++;
665,124✔
5299
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
665,124✔
5300
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordReuseTime, false, pUser, pShow->pIter, _exit);
665,124✔
5301

5302
    cols++;
665,124✔
5303
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
665,124✔
5304
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordReuseMax, false, pUser, pShow->pIter, _exit);
665,124✔
5305

5306
    cols++;
665,124✔
5307
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
665,124✔
5308
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordLockTime, false, pUser, pShow->pIter, _exit);
665,124✔
5309

5310
    cols++;
665,124✔
5311
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
665,124✔
5312
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordGraceTime, false, pUser, pShow->pIter, _exit);
665,124✔
5313

5314
    cols++;
665,124✔
5315
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
665,124✔
5316
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->inactiveAccountTime, false, pUser, pShow->pIter, _exit);
665,124✔
5317

5318
    cols++;
665,124✔
5319
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
665,124✔
5320
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->allowTokenNum, false, pUser, pShow->pIter, _exit);
665,124✔
5321

5322
    cols++;
665,124✔
5323
    int32_t tlen = convertIpWhiteListToStr(pUser, &buf);
665,124✔
5324
    if (tlen != 0) {
665,124✔
5325
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
665,124✔
5326
      if (varstr == NULL) {
665,124✔
5327
        sdbRelease(pSdb, pUser);
×
5328
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
5329
      }
5330
      varDataSetLen(varstr, tlen);
665,124✔
5331
      (void)memcpy(varDataVal(varstr), buf, tlen);
665,124✔
5332

5333
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
665,124✔
5334
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
665,124✔
5335

5336
      taosMemoryFreeClear(buf);
665,124✔
5337
    } else {
5338
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
5339
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
5340
    }
5341

5342
    cols++;
665,124✔
5343
    tlen = convertTimeRangesToStr(pUser, &buf);
665,124✔
5344
    if (tlen != 0) {
665,124✔
5345
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
665,124✔
5346
      if (varstr == NULL) {
665,124✔
5347
        sdbRelease(pSdb, pUser);
×
5348
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
5349
      }
5350
      varDataSetLen(varstr, tlen);
665,124✔
5351
      (void)memcpy(varDataVal(varstr), buf, tlen);
665,124✔
5352

5353
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
665,124✔
5354
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
665,124✔
5355

5356
      taosMemoryFreeClear(buf);
665,124✔
5357
    } else {
5358
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
5359
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
5360
    }
5361

5362
    if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
665,124✔
5363
      void  *pIter = NULL;
665,124✔
5364
      size_t klen = 0, tlen = 0;
665,124✔
5365
      char  *pBuf = POINTER_SHIFT(tBuf, VARSTR_HEADER_SIZE);
665,124✔
5366
      while ((pIter = taosHashIterate(pUser->roles, pIter))) {
1,361,762✔
5367
        char *roleName = taosHashGetKey(pIter, &klen);
696,638✔
5368
        tlen += snprintf(pBuf + tlen, bufSize - tlen, "%s,", roleName);
696,638✔
5369
      }
5370
      if (tlen > 0) {
665,124✔
5371
        pBuf[--tlen] = 0;  // remove last ','
665,124✔
5372
      } else {
5373
        pBuf[0] = 0;
×
5374
      }
5375
      varDataSetLen(tBuf, tlen);
665,124✔
5376
      COL_DATA_SET_VAL_GOTO((const char *)tBuf, false, pUser, pShow->pIter, _exit);
665,124✔
5377
    }
5378

5379
    if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
665,124✔
5380
      char  *pBuf = POINTER_SHIFT(tBuf, VARSTR_HEADER_SIZE);
665,124✔
5381
      size_t vlen = snprintf(pBuf, bufSize, "[%d,%d]", pUser->minSecLevel, pUser->maxSecLevel);
665,124✔
5382
      varDataSetLen(tBuf, vlen);
665,124✔
5383
      COL_DATA_SET_VAL_GOTO((const char *)tBuf, false, pUser, pShow->pIter, _exit);
665,124✔
5384
    }
5385

5386
    numOfRows++;
665,124✔
5387
    sdbRelease(pSdb, pUser);
665,124✔
5388
  }
5389

5390
  pShow->numOfRows += numOfRows;
15,757✔
5391
_exit:
15,757✔
5392
  taosMemoryFreeClear(buf);
15,757✔
5393
  taosMemoryFreeClear(varstr);
15,757✔
5394
  mndReleaseUser(pMnode, pOperUser);
15,757✔
5395
  if (code < 0) {
15,757✔
5396
    mError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
5397
    TAOS_RETURN(code);
×
5398
  }
5399
#endif
5400
  return numOfRows;
15,757✔
5401
}
5402

5403
static void mndCancelGetNextUser(SMnode *pMnode, void *pIter) {
×
5404
  SSdb *pSdb = pMnode->pSdb;
×
5405
  sdbCancelFetchByType(pSdb, pIter, SDB_USER);
×
5406
}
×
5407

5408
static int32_t mndLoopHash(SHashObj *hash, char *priType, SSDataBlock *pBlock, int32_t *pNumOfRows, SSdb *pSdb,
×
5409
                           SUserObj *pUser, SShowObj *pShow, char **condition, char **sql) {
5410
  char   *value = taosHashIterate(hash, NULL);
×
5411
  char   *user = pUser->user;
×
5412
  int32_t code = 0;
×
5413
  int32_t lino = 0;
×
5414
  int32_t cols = 0;
×
5415
  int32_t numOfRows = *pNumOfRows;
×
5416

5417
  while (value != NULL) {
×
5418
    cols = 0;
×
5419
    char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
×
5420
    STR_WITH_MAXSIZE_TO_VARSTR(userName, user, pShow->pMeta->pSchemas[cols].bytes);
×
5421
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
5422
    COL_DATA_SET_VAL_GOTO((const char *)userName, false, NULL, NULL, _exit);
×
5423

5424
    char privilege[20] = {0};
×
5425
    STR_WITH_MAXSIZE_TO_VARSTR(privilege, priType, pShow->pMeta->pSchemas[cols].bytes);
×
5426
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
5427
    COL_DATA_SET_VAL_GOTO((const char *)privilege, false, NULL, NULL, _exit);
×
5428

5429
    size_t keyLen = 0;
×
5430
    void  *key = taosHashGetKey(value, &keyLen);
×
5431

5432
    char dbName[TSDB_DB_NAME_LEN] = {0};
×
5433
    (void)mndExtractShortDbNameFromStbFullName(key, dbName);
×
5434
    char dbNameContent[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
×
5435
    STR_WITH_MAXSIZE_TO_VARSTR(dbNameContent, dbName, pShow->pMeta->pSchemas[cols].bytes);
×
5436
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
5437
    COL_DATA_SET_VAL_GOTO((const char *)dbNameContent, false, NULL, NULL, _exit);
×
5438

5439
    char tableName[TSDB_TABLE_NAME_LEN] = {0};
×
5440
    mndExtractTbNameFromStbFullName(key, tableName, TSDB_TABLE_NAME_LEN);
×
5441
    char tableNameContent[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
×
5442
    STR_WITH_MAXSIZE_TO_VARSTR(tableNameContent, tableName, pShow->pMeta->pSchemas[cols].bytes);
×
5443
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
5444
    COL_DATA_SET_VAL_GOTO((const char *)tableNameContent, false, NULL, NULL, _exit);
×
5445

5446
    if (strcmp("t", value) != 0 && strcmp("v", value) != 0) {
×
5447
      SNode  *pAst = NULL;
×
5448
      int32_t sqlLen = 0;
×
5449
      size_t  bufSz = strlen(value) + 1;
×
5450
      if (bufSz < 6) bufSz = 6;
×
5451
      TAOS_MEMORY_REALLOC(*sql, bufSz);
×
5452
      if (*sql == NULL) {
×
5453
        code = terrno;
×
5454
        goto _exit;
×
5455
      }
5456
      TAOS_MEMORY_REALLOC(*condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
×
5457
      if ((*condition) == NULL) {
×
5458
        code = terrno;
×
5459
        goto _exit;
×
5460
      }
5461

5462
      if (nodesStringToNode(value, &pAst) == 0) {
×
5463
        if (nodesNodeToSQLFormat(pAst, *sql, bufSz, &sqlLen, true) != 0) {
×
5464
          sqlLen = snprintf(*sql, bufSz, "error");
×
5465
        }
5466
        nodesDestroyNode(pAst);
×
5467
      }
5468

5469
      if (sqlLen == 0) {
×
5470
        sqlLen = snprintf(*sql, bufSz, "error");
×
5471
      }
5472

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

5475
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
5476
      COL_DATA_SET_VAL_GOTO((const char *)(*condition), false, NULL, NULL, _exit);
×
5477

5478
      char notes[2] = {0};
×
5479
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
×
5480
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
5481
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, NULL, NULL, _exit);
×
5482
    } else {
5483
      TAOS_MEMORY_REALLOC(*condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
×
5484
      if ((*condition) == NULL) {
×
5485
        code = terrno;
×
5486
        goto _exit;
×
5487
      }
5488
      STR_WITH_MAXSIZE_TO_VARSTR((*condition), "", pShow->pMeta->pSchemas[cols].bytes);
×
5489
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
5490
      COL_DATA_SET_VAL_GOTO((const char *)(*condition), false, NULL, NULL, _exit);
×
5491

5492
      char notes[64 + VARSTR_HEADER_SIZE] = {0};
×
5493
      STR_WITH_MAXSIZE_TO_VARSTR(notes, value[0] == 'v' ? "view" : "", sizeof(notes));
×
5494
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
5495
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, NULL, NULL, _exit);
×
5496
    }
5497

5498
    numOfRows++;
×
5499
    value = taosHashIterate(hash, value);
×
5500
  }
5501
  *pNumOfRows = numOfRows;
×
5502
_exit:
×
5503
  if (code < 0) {
×
5504
    mError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
5505
    sdbRelease(pSdb, pUser);
×
5506
    sdbCancelFetch(pSdb, pShow->pIter);
×
5507
  }
5508
  TAOS_RETURN(code);
×
5509
}
5510

5511
#if 0
5512
static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
5513
  int32_t   code = 0;
5514
  int32_t   lino = 0;
5515
  SMnode   *pMnode = pReq->info.node;
5516
  SSdb     *pSdb = pMnode->pSdb;
5517
  int32_t   numOfRows = 0;
5518
  SUserObj *pUser = NULL;
5519
  int32_t   cols = 0;
5520
  char     *pWrite = NULL;
5521
  char     *condition = NULL;
5522
  char     *sql = NULL;
5523

5524
  bool fetchNextUser = pShow->restore ? false : true;
5525
  pShow->restore = false;
5526

5527
  while (numOfRows < rows) {
5528
    if (fetchNextUser) {
5529
      pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
5530
      if (pShow->pIter == NULL) break;
5531
    } else {
5532
      fetchNextUser = true;
5533
      void *pKey = taosHashGetKey(pShow->pIter, NULL);
5534
      pUser = sdbAcquire(pSdb, SDB_USER, pKey);
5535
      if (!pUser) {
5536
        continue;
5537
      }
5538
    }
5539

5540
    int32_t numOfReadDbs = 0; //taosHashGetSize(pUser->readDbs);
5541
    int32_t numOfWriteDbs = 0; //taosHashGetSize(pUser->writeDbs);
5542
    int32_t numOfTopics = taosHashGetSize(pUser->topics);
5543
    int32_t numOfReadTbs = taosHashGetSize(pUser->selectTbs);
5544
    int32_t numOfWriteTbs = taosHashGetSize(pUser->insertTbs);
5545
    int32_t numOfAlterTbs = taosHashGetSize(pUser->alterTbs);
5546
    int32_t numOfReadViews = taosHashGetSize(pUser->readViews);
5547
    int32_t numOfWriteViews = taosHashGetSize(pUser->writeViews);
5548
    int32_t numOfAlterViews = taosHashGetSize(pUser->alterViews);
5549
    if (numOfRows + numOfReadDbs + numOfWriteDbs + numOfTopics + numOfReadTbs + numOfWriteTbs + numOfAlterTbs +
5550
            numOfReadViews + numOfWriteViews + numOfAlterViews >=
5551
        rows) {
5552
      mInfo(
5553
          "will restore. current num of rows: %d, read dbs %d, write dbs %d, topics %d, read tables %d, write tables "
5554
          "%d, alter tables %d, select views %d, write views %d, alter views %d",
5555
          numOfRows, numOfReadDbs, numOfWriteDbs, numOfTopics, numOfReadTbs, numOfWriteTbs, numOfAlterTbs,
5556
          numOfReadViews, numOfWriteViews, numOfAlterViews);
5557
      pShow->restore = true;
5558
      sdbRelease(pSdb, pUser);
5559
      break;
5560
    }
5561

5562
    if (pUser->superUser) {
5563
      cols = 0;
5564
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
5565
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
5566
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5567
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
5568

5569
      char privilege[20] = {0};
5570
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "all", pShow->pMeta->pSchemas[cols].bytes);
5571
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5572
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
5573

5574
      char objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
5575
      STR_WITH_MAXSIZE_TO_VARSTR(objName, "all", pShow->pMeta->pSchemas[cols].bytes);
5576
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5577
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
5578

5579
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
5580
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
5581
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5582
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
5583

5584
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
5585
      if (condition == NULL) {
5586
        sdbRelease(pSdb, pUser);
5587
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
5588
      }
5589
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
5590
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5591
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
5592

5593
      char notes[2] = {0};
5594
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
5595
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5596
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
5597

5598
      numOfRows++;
5599
    }
5600
#if 0
5601
    char *db = taosHashIterate(pUser->readDbs, NULL);
5602
    while (db != NULL) {
5603
      cols = 0;
5604
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
5605
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
5606
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5607
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
5608

5609
      char privilege[20] = {0};
5610
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "read", pShow->pMeta->pSchemas[cols].bytes);
5611
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5612
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
5613

5614
      SName name = {0};
5615
      char  objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
5616
      code = tNameFromString(&name, db, T_NAME_ACCT | T_NAME_DB);
5617
      if (code < 0) {
5618
        sdbRelease(pSdb, pUser);
5619
        sdbCancelFetch(pSdb, pShow->pIter);
5620
        TAOS_CHECK_GOTO(code, &lino, _exit);
5621
      }
5622
      (void)tNameGetDbName(&name, varDataVal(objName));
5623
      varDataSetLen(objName, strlen(varDataVal(objName)));
5624
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5625
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
5626

5627
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
5628
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
5629
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5630
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
5631

5632
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
5633
      if (condition == NULL) {
5634
        sdbRelease(pSdb, pUser);
5635
        sdbCancelFetch(pSdb, pShow->pIter);
5636
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
5637
      }
5638
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
5639
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5640
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
5641

5642
      char notes[2] = {0};
5643
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
5644
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5645
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
5646

5647
      numOfRows++;
5648
      db = taosHashIterate(pUser->readDbs, db);
5649
    }
5650

5651
    db = taosHashIterate(pUser->writeDbs, NULL);
5652
    while (db != NULL) {
5653
      cols = 0;
5654
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
5655
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
5656
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5657
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
5658

5659
      char privilege[20] = {0};
5660
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "write", pShow->pMeta->pSchemas[cols].bytes);
5661
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5662
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
5663

5664
      SName name = {0};
5665
      char  objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
5666
      code = tNameFromString(&name, db, T_NAME_ACCT | T_NAME_DB);
5667
      if (code < 0) {
5668
        sdbRelease(pSdb, pUser);
5669
        sdbCancelFetch(pSdb, pShow->pIter);
5670
        TAOS_CHECK_GOTO(code, &lino, _exit);
5671
      }
5672
      (void)tNameGetDbName(&name, varDataVal(objName));
5673
      varDataSetLen(objName, strlen(varDataVal(objName)));
5674
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5675
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
5676

5677
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
5678
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
5679
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5680
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
5681

5682
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
5683
      if (condition == NULL) {
5684
        sdbRelease(pSdb, pUser);
5685
        sdbCancelFetch(pSdb, pShow->pIter);
5686
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
5687
      }
5688
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
5689
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5690
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
5691

5692
      char notes[2] = {0};
5693
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
5694
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5695
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
5696

5697
      numOfRows++;
5698
      db = taosHashIterate(pUser->writeDbs, db);
5699
    }
5700
#endif
5701
    TAOS_CHECK_EXIT(mndLoopHash(pUser->selectTbs, "select", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
5702

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

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

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

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

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

5713
    char *topic = taosHashIterate(pUser->topics, NULL);
5714
    while (topic != NULL) {
5715
      cols = 0;
5716
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
5717
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
5718
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5719
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
5720

5721
      char privilege[20] = {0};
5722
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "subscribe", pShow->pMeta->pSchemas[cols].bytes);
5723
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5724
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
5725

5726
      char topicName[TSDB_TOPIC_NAME_LEN + VARSTR_HEADER_SIZE + 5] = {0};
5727
      tstrncpy(varDataVal(topicName), mndGetDbStr(topic), TSDB_TOPIC_NAME_LEN - 2);
5728
      varDataSetLen(topicName, strlen(varDataVal(topicName)));
5729
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5730
      COL_DATA_SET_VAL_GOTO((const char *)topicName, false, pUser, pShow->pIter, _exit);
5731

5732
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
5733
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
5734
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5735
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
5736

5737
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
5738
      if (condition == NULL) {
5739
        sdbRelease(pSdb, pUser);
5740
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
5741
      }
5742
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
5743
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5744
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
5745

5746
      char notes[2] = {0};
5747
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
5748
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5749
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
5750

5751
      numOfRows++;
5752
      topic = taosHashIterate(pUser->topics, topic);
5753
    }
5754

5755
    sdbRelease(pSdb, pUser);
5756
  }
5757

5758
  pShow->numOfRows += numOfRows;
5759
_exit:
5760
  taosMemoryFreeClear(condition);
5761
  taosMemoryFreeClear(sql);
5762
  if (code < 0) {
5763
    mError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
5764
    TAOS_RETURN(code);
5765
  }
5766
  return numOfRows;
5767
}
5768
#endif
5769

5770
int32_t mndShowTablePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows, void *pObj,
461,196✔
5771
                               const char *principalName, SHashObj *privTbs, EPrivType privType, char *pBuf,
5772
                               int32_t bufSize, int32_t *pNumOfRows) {
5773
  int32_t     code = 0, lino = 0;
461,196✔
5774
  SMnode     *pMnode = pReq->info.node;
461,196✔
5775
  SSdb       *pSdb = pMnode->pSdb;
461,196✔
5776
  int32_t     cols = 0, qBufSize = bufSize - VARSTR_HEADER_SIZE;
461,196✔
5777
  int32_t     numOfRows = *pNumOfRows;
461,196✔
5778
  char       *qBuf = NULL;
461,196✔
5779
  char       *sql = NULL;
461,196✔
5780
  char        roleName[TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
461,196✔
5781
  const char *privName = privInfoGetName(privType);
461,196✔
5782

5783
  STR_WITH_MAXSIZE_TO_VARSTR(roleName, principalName, pShow->pMeta->pSchemas[cols].bytes);
461,196✔
5784

5785
  void *pIter = NULL;
461,196✔
5786
  while ((pIter = taosHashIterate(privTbs, pIter))) {
534,097✔
5787
    SPrivTblPolicies *pPolices = (SPrivTblPolicies *)pIter;
72,901✔
5788
    SArray           *tblPolicies = pPolices->policy;
72,901✔
5789

5790
    char   *key = taosHashGetKey(pPolices, NULL);
72,901✔
5791
    int32_t objType = PRIV_OBJ_UNKNOWN;
72,901✔
5792
    char    dbName[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
72,901✔
5793
    char    tblName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
72,901✔
5794
    if ((code = privObjKeyParse(key, &objType, dbName, sizeof(dbName), tblName, sizeof(tblName), false))) {
72,901✔
5795
      sdbRelease(pSdb, pObj);
×
5796
      sdbCancelFetch(pSdb, pShow->pIter);
×
5797
      TAOS_CHECK_EXIT(code);
×
5798
    }
5799

5800
    int32_t nTbPolicies = taosArrayGetSize(tblPolicies);
72,901✔
5801
    for (int32_t i = 0; i < nTbPolicies; ++i) {
145,802✔
5802
      SPrivTblPolicy *tbPolicy = (SPrivTblPolicy *)TARRAY_GET_ELEM(tblPolicies, i);
72,901✔
5803
      cols = 0;
72,901✔
5804
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
72,901✔
5805
      COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
72,901✔
5806

5807
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
72,901✔
5808
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privName, pShow->pMeta->pSchemas[cols].bytes);
72,901✔
5809
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
72,901✔
5810
      }
5811

5812
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
72,901✔
5813
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privObjGetName(objType), pShow->pMeta->pSchemas[cols].bytes);
72,901✔
5814
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
72,901✔
5815
      }
5816

5817
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
72,901✔
5818
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, dbName, pShow->pMeta->pSchemas[cols].bytes);
72,901✔
5819
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
72,901✔
5820
      }
5821

5822
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
72,901✔
5823
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, tblName, pShow->pMeta->pSchemas[cols].bytes);
72,901✔
5824
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
72,901✔
5825
      }
5826
      // condition
5827
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
72,901✔
5828
        SNode  *pAst = NULL;
72,901✔
5829
        int32_t sqlLen = 0;
72,901✔
5830
        qBuf = POINTER_SHIFT(pBuf, VARSTR_HEADER_SIZE);
72,901✔
5831
        if (tbPolicy->condLen > 0) {
72,901✔
5832
          if (nodesStringToNode(tbPolicy->cond, &pAst) == 0) {
72,901✔
5833
            if (nodesNodeToSQLFormat(pAst, qBuf, qBufSize, &sqlLen, true) != 0) {
72,901✔
5834
              sqlLen = tsnprintf(qBuf, qBufSize, "error");
×
5835
            }
5836
            nodesDestroyNode(pAst);
72,901✔
5837
          }
5838
          if (sqlLen == 0) {
72,901✔
5839
            sqlLen = tsnprintf(qBuf, qBufSize, "error");
×
5840
          }
5841
        } else {
5842
          sqlLen = tsnprintf(qBuf, qBufSize, "");
×
5843
        }
5844
        varDataSetLen(pBuf, sqlLen);
72,901✔
5845
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
72,901✔
5846
      }
5847
      // notes
5848
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
72,901✔
5849
        STR_WITH_MAXSIZE_TO_VARSTR((pBuf), "", 2);
72,901✔
5850
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
72,901✔
5851
      }
5852
      // columns
5853
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
72,901✔
5854
        SArray *pCols = tbPolicy->cols;
72,901✔
5855
        int32_t nCols = taosArrayGetSize(pCols);
72,901✔
5856
        int32_t totalLen = 0;
72,901✔
5857
        qBuf = POINTER_SHIFT(pBuf, VARSTR_HEADER_SIZE);
72,901✔
5858
        for (int32_t j = 0; j < nCols; ++j) {
106,748✔
5859
          SColNameFlag *pCol = (SColNameFlag *)TARRAY_GET_ELEM(pCols, j);
33,847✔
5860
          char          tmpBuf[TSDB_COL_NAME_LEN + 16] = {0};
33,847✔
5861
          int32_t       tmpLen = 0;
33,847✔
5862
          if (IS_MASK_ON(pCol)) {
33,847✔
5863
            tmpLen = snprintf(tmpBuf, sizeof(tmpBuf), "mask(%s)%s", pCol->colName, j == nCols - 1 ? "" : ",");
×
5864
          } else {
5865
            tmpLen = snprintf(tmpBuf, sizeof(tmpBuf), "%s%s", pCol->colName, j == nCols - 1 ? "" : ",");
33,847✔
5866
          }
5867
          if (totalLen + tmpLen > qBufSize) {
33,847✔
5868
            break;
×
5869
          }
5870
          (void)memcpy(POINTER_SHIFT(qBuf, totalLen), tmpBuf, tmpLen);
33,847✔
5871
          totalLen += tmpLen;
33,847✔
5872
        }
5873
        varDataSetLen(pBuf, totalLen);
72,901✔
5874
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
72,901✔
5875
      }
5876
      // update_time
5877
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
72,901✔
5878
        char updateTime[40] = {0};
72,901✔
5879
        (void)formatTimestampLocal(updateTime, sizeof(updateTime), tbPolicy->updateUs, TSDB_TIME_PRECISION_MICRO);
72,901✔
5880
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, updateTime, pShow->pMeta->pSchemas[cols].bytes);
72,901✔
5881
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
72,901✔
5882
      }
5883
      ++numOfRows;
72,901✔
5884
    }
5885
  }
5886
  *pNumOfRows = numOfRows;
461,196✔
5887
_exit:
461,196✔
5888
  TAOS_RETURN(code);
461,196✔
5889
}
5890

5891
static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
18,995✔
5892
  int32_t   code = 0, lino = 0;
18,995✔
5893
  SMnode   *pMnode = pReq->info.node;
18,995✔
5894
  SSdb     *pSdb = pMnode->pSdb;
18,995✔
5895
  int32_t   numOfRows = 0;
18,995✔
5896
  int32_t   cols = 0;
18,995✔
5897
  SUserObj *pObj = NULL;
18,995✔
5898
  char     *pBuf = NULL, *qBuf = NULL;
18,995✔
5899
  char     *sql = NULL;
18,995✔
5900
  char      roleName[TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
18,995✔
5901
  int32_t   bufSize = TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE;
18,995✔
5902

5903
  bool fetchNextInstance = pShow->restore ? false : true;
18,995✔
5904
  pShow->restore = false;
18,995✔
5905

5906
  while (numOfRows < rows) {
125,530✔
5907
    if (fetchNextInstance) {
125,530✔
5908
      pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pObj);
125,530✔
5909
      if (pShow->pIter == NULL) break;
125,530✔
5910
    } else {
5911
      fetchNextInstance = true;
×
5912
      void *pKey = taosHashGetKey(pShow->pIter, NULL);
×
5913
      if (!(pObj = sdbAcquire(pSdb, SDB_USER, pKey))) {
×
5914
        continue;
×
5915
      }
5916
    }
5917

5918
    // count total privileges for current user
5919
    int32_t nSysPrivileges = privPopCnt(&pObj->sysPrivs);
106,535✔
5920
    int32_t nObjPrivileges = 0;
106,535✔
5921
    void   *pIter = NULL;
106,535✔
5922
    while ((pIter = taosHashIterate(pObj->objPrivs, pIter))) {
1,347,733✔
5923
      SPrivObjPolicies *pPolices = (SPrivObjPolicies *)pIter;
1,241,198✔
5924
      nObjPrivileges += privPopCnt(&pPolices->policy);
2,482,396✔
5925
    }
5926
    int32_t nTblPrivileges = privTblPrivCnt(pObj->selectTbs);
106,535✔
5927
    nTblPrivileges += privTblPrivCnt(pObj->insertTbs);
106,535✔
5928
    nTblPrivileges += privTblPrivCnt(pObj->updateTbs);
106,535✔
5929
    nTblPrivileges += privTblPrivCnt(pObj->deleteTbs);
106,535✔
5930

5931
    int32_t totalPrivileges = nSysPrivileges + nObjPrivileges + nTblPrivileges;
106,535✔
5932

5933
    if (numOfRows + totalPrivileges >= rows) {
106,535✔
5934
      if (totalPrivileges >= SHOW_PRIVILEGES_STEP_SIZE) {
×
5935
        mError("user:%s, has too many privileges:%d to show", pObj->name, totalPrivileges);
×
5936
        sdbRelease(pSdb, pObj);
×
5937
        TAOS_CHECK_EXIT(TSDB_CODE_MND_TOO_MANY_PRIVS);
×
5938
      }
5939
      pShow->restore = true;
×
5940
      sdbRelease(pSdb, pObj);
×
5941
      break;
×
5942
    }
5943

5944
    if (!pBuf && !(pBuf = taosMemoryMalloc(bufSize))) {
106,535✔
5945
      sdbRelease(pSdb, pObj);
×
5946
      TAOS_CHECK_EXIT(terrno);
×
5947
    }
5948

5949
    cols = 0;
106,535✔
5950
    STR_WITH_MAXSIZE_TO_VARSTR(roleName, pObj->name, pShow->pMeta->pSchemas[cols].bytes);
106,535✔
5951

5952
    // system privileges
5953
    SPrivIter privIter = {0};
106,535✔
5954
    privIterInit(&privIter, &pObj->sysPrivs);
106,535✔
5955
    SPrivInfo *pPrivInfo = NULL;
106,535✔
5956
    while (privIterNext(&privIter, &pPrivInfo)) {
141,610✔
5957
      cols = 0;
35,075✔
5958
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
35,075✔
5959
      COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
35,075✔
5960

5961
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
35,075✔
5962
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, pPrivInfo->name, pShow->pMeta->pSchemas[cols].bytes);
35,075✔
5963
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
35,075✔
5964
      }
5965
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
35,075✔
5966
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privObjGetName(PRIV_OBJ_CLUSTER), pShow->pMeta->pSchemas[cols].bytes);
35,075✔
5967
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
35,075✔
5968
      }
5969
      // skip db, table, condition, notes, columns, update_time
5970
      COL_DATA_SET_EMPTY_VARCHAR(pBuf, 6);
245,525✔
5971
      numOfRows++;
35,075✔
5972
    }
5973

5974
    // object privileges
5975
    pIter = NULL;
106,535✔
5976
    while ((pIter = taosHashIterate(pObj->objPrivs, pIter))) {
1,347,733✔
5977
      SPrivObjPolicies *pPolices = (SPrivObjPolicies *)pIter;
1,241,198✔
5978

5979
      char   *key = taosHashGetKey(pPolices, NULL);
1,241,198✔
5980
      int32_t objType = PRIV_OBJ_UNKNOWN;
1,241,198✔
5981
      char    dbName[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
1,241,198✔
5982
      char    tblName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
1,241,198✔
5983
      if ((code = privObjKeyParse(key, &objType, dbName, sizeof(dbName), tblName, sizeof(tblName), false))) {
1,241,198✔
5984
        sdbRelease(pSdb, pObj);
×
5985
        TAOS_CHECK_EXIT(code);
×
5986
      }
5987

5988
      SPrivIter privIter = {0};
1,241,198✔
5989
      privIterInit(&privIter, &pPolices->policy);
1,241,198✔
5990
      SPrivInfo *pPrivInfo = NULL;
1,241,198✔
5991
      while (privIterNext(&privIter, &pPrivInfo)) {
3,795,827✔
5992
        cols = 0;
2,554,629✔
5993
        SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
2,554,629✔
5994
        COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
2,554,629✔
5995

5996
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
2,554,629✔
5997
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, pPrivInfo->name, pShow->pMeta->pSchemas[cols].bytes);
2,554,629✔
5998
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
2,554,629✔
5999
        }
6000

6001
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
2,554,629✔
6002
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privObjGetName(objType), pShow->pMeta->pSchemas[cols].bytes);
2,554,629✔
6003
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
2,554,629✔
6004
        }
6005

6006
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
2,554,629✔
6007
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, dbName, pShow->pMeta->pSchemas[cols].bytes);
2,554,629✔
6008
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
2,554,629✔
6009
        }
6010

6011
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
2,554,629✔
6012
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, tblName, pShow->pMeta->pSchemas[cols].bytes);
2,554,629✔
6013
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
2,554,629✔
6014
        }
6015

6016
        // skip condition, notes, columns, update_time
6017
        COL_DATA_SET_EMPTY_VARCHAR(pBuf, 4);
12,773,145✔
6018

6019
        numOfRows++;
2,554,629✔
6020
      }
6021
    }
6022

6023
    // table level privileges
6024
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->name, pObj->selectTbs,
106,535✔
6025
                                           PRIV_TBL_SELECT, pBuf, bufSize, &numOfRows));
6026
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->name, pObj->insertTbs,
106,535✔
6027
                                           PRIV_TBL_INSERT, pBuf, bufSize, &numOfRows));
6028
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->name, pObj->updateTbs,
106,535✔
6029
                                           PRIV_TBL_UPDATE, pBuf, bufSize, &numOfRows));
6030
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->name, pObj->deleteTbs,
106,535✔
6031
                                           PRIV_TBL_DELETE, pBuf, bufSize, &numOfRows));
6032
    sdbRelease(pSdb, pObj);
106,535✔
6033
  }
6034

6035
  pShow->numOfRows += numOfRows;
18,995✔
6036
_exit:
18,995✔
6037
  taosMemoryFreeClear(pBuf);
18,995✔
6038
  taosMemoryFreeClear(sql);
18,995✔
6039
  if (code < 0) {
18,995✔
6040
    mError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
6041
    TAOS_RETURN(code);
×
6042
  }
6043
  return numOfRows;
18,995✔
6044
}
6045

6046
static void mndCancelGetNextPrivileges(SMnode *pMnode, void *pIter) {
×
6047
  SSdb *pSdb = pMnode->pSdb;
×
6048
  sdbCancelFetchByType(pSdb, pIter, SDB_USER);
×
6049
}
×
6050

6051
int32_t mndValidateUserAuthInfo(SMnode *pMnode, SUserAuthVersion *pUsers, int32_t numOfUses, void **ppRsp,
28,376,300✔
6052
                                int32_t *pRspLen, int64_t ipWhiteListVer) {
6053
  int32_t           code = 0;
28,376,300✔
6054
  int32_t           lino = 0;
28,376,300✔
6055
  int32_t           rspLen = 0;
28,376,300✔
6056
  void             *pRsp = NULL;
28,376,300✔
6057
  SUserAuthBatchRsp batchRsp = {0};
28,376,300✔
6058

6059
  batchRsp.pArray = taosArrayInit(numOfUses, sizeof(SGetUserAuthRsp));
28,377,086✔
6060
  if (batchRsp.pArray == NULL) {
28,376,610✔
6061
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
6062
  }
6063
  int64_t now = taosGetTimestampMs();
28,376,771✔
6064
  for (int32_t i = 0; i < numOfUses; ++i) {
57,314,607✔
6065
    SUserObj *pUser = NULL;
28,937,836✔
6066
    code = mndAcquireUser(pMnode, pUsers[i].user, &pUser);
28,937,836✔
6067
    if (pUser == NULL) {
28,936,932✔
6068
      if (TSDB_CODE_MND_USER_NOT_EXIST == code) {
9,897✔
6069
        SGetUserAuthRsp rsp = {.dropped = 1};
9,897✔
6070
        (void)memcpy(rsp.user, pUsers[i].user, TSDB_USER_LEN);
9,897✔
6071
        TSDB_CHECK_NULL(taosArrayPush(batchRsp.pArray, &rsp), code, lino, _OVER, TSDB_CODE_OUT_OF_MEMORY);
19,794✔
6072
      }
6073
      mError("user:%s, failed to auth user since %s", pUsers[i].user, tstrerror(code));
9,897✔
6074
      code = 0;
9,897✔
6075
      continue;
9,897✔
6076
    }
6077

6078
    pUsers[i].version = ntohl(pUsers[i].version);
28,927,035✔
6079
    if ((pUser->authVersion <= pUsers[i].version) && (ipWhiteListVer == pMnode->ipWhiteVer) &&
28,927,350✔
6080
        !mndNeedRetrieveRole(pUser)) {
×
6081
      mndReleaseUser(pMnode, pUser);
×
6082
      continue;
×
6083
    }
6084

6085
    SGetUserAuthRsp rsp = {0};
28,927,072✔
6086
    code = mndSetUserAuthRsp(pMnode, pUser, &rsp);
28,926,249✔
6087
    if (code) {
28,925,899✔
6088
      mndReleaseUser(pMnode, pUser);
×
6089
      tFreeSGetUserAuthRsp(&rsp);
×
6090
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
6091
    }
6092

6093
    if (!(taosArrayPush(batchRsp.pArray, &rsp))) {
57,853,838✔
6094
      code = terrno;
×
6095
      mndReleaseUser(pMnode, pUser);
×
6096
      tFreeSGetUserAuthRsp(&rsp);
×
6097
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
6098
    }
6099
    pUser->lastRoleRetrieve = now;  // update user's last retrieve time
28,927,939✔
6100
    mndReleaseUser(pMnode, pUser);
28,927,029✔
6101
  }
6102

6103
  if (taosArrayGetSize(batchRsp.pArray) <= 0) {
28,376,771✔
6104
    *ppRsp = NULL;
×
6105
    *pRspLen = 0;
×
6106

6107
    tFreeSUserAuthBatchRsp(&batchRsp);
×
6108
    return 0;
×
6109
  }
6110

6111
  rspLen = tSerializeSUserAuthBatchRsp(NULL, 0, &batchRsp);
28,377,086✔
6112
  if (rspLen < 0) {
28,373,984✔
6113
    TAOS_CHECK_GOTO(rspLen, &lino, _OVER);
×
6114
  }
6115
  pRsp = taosMemoryMalloc(rspLen);
28,373,984✔
6116
  if (pRsp == NULL) {
28,373,881✔
6117
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
6118
  }
6119
  rspLen = tSerializeSUserAuthBatchRsp(pRsp, rspLen, &batchRsp);
28,373,881✔
6120
  if (rspLen < 0) {
28,376,179✔
6121
    TAOS_CHECK_GOTO(rspLen, &lino, _OVER);
×
6122
  }
6123
_OVER:
28,376,179✔
6124
  tFreeSUserAuthBatchRsp(&batchRsp);
28,375,858✔
6125
  if (code < 0) {
28,374,657✔
6126
    for (int32_t i = 0; i < numOfUses; ++i) {
×
6127
      SUserObj *pUser = NULL;
×
6128
      if (mndAcquireUser(pMnode, pUsers[i].user, &pUser) != 0) {
×
6129
        continue;
×
6130
      }
6131
      pUser->lastRoleRetrieve = 0;  // reset last retrieve time on error
×
6132
      mndReleaseUser(pMnode, pUser);
×
6133
    }
6134
    mError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
6135
    taosMemoryFreeClear(pRsp);
×
6136
    rspLen = 0;
×
6137
  }
6138
  *ppRsp = pRsp;
28,374,657✔
6139
  *pRspLen = rspLen;
28,373,791✔
6140

6141
  TAOS_RETURN(code);
28,374,577✔
6142
}
6143

6144
int32_t mndUserDropRole(SMnode *pMnode, STrans *pTrans, SRoleObj *pObj) {
1,610✔
6145
  int32_t   code = 0, lino = 0;
1,610✔
6146
  SSdb     *pSdb = pMnode->pSdb;
1,610✔
6147
  SUserObj *pUser = NULL;
1,610✔
6148
  void     *pIter = NULL;
1,610✔
6149

6150
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser))) {
5,474✔
6151
    SHashObj *pRole = taosHashGet(pUser->roles, pObj->name, strlen(pObj->name) + 1);
3,864✔
6152
    if (!pRole) {
3,864✔
6153
      sdbRelease(pSdb, pUser);
3,220✔
6154
      pUser = NULL;
3,220✔
6155
      continue;
3,220✔
6156
    }
6157

6158
    SUserObj newUser = {0};
644✔
6159
    TAOS_CHECK_EXIT(mndUserDupObj(pUser, &newUser));
644✔
6160
    code = taosHashRemove(newUser.roles, pObj->name, strlen(pObj->name) + 1);
644✔
6161
    if (code == TSDB_CODE_NOT_FOUND) {
644✔
6162
      sdbRelease(pSdb, pUser);
×
6163
      pUser = NULL;
×
6164
      mndUserFreeObj(&newUser);
×
6165
      continue;
×
6166
    }
6167
    if (code != 0) {
644✔
6168
      mndUserFreeObj(&newUser);
×
6169
      TAOS_CHECK_EXIT(code);
×
6170
    }
6171
    SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
644✔
6172
    if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
644✔
6173
      mndUserFreeObj(&newUser);
×
6174
      TAOS_CHECK_EXIT(TSDB_CODE_OUT_OF_MEMORY);
×
6175
    }
6176
    if ((code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY))) {
644✔
6177
      mndUserFreeObj(&newUser);
×
6178
      TAOS_CHECK_EXIT(code);
×
6179
    }
6180
    sdbRelease(pSdb, pUser);
644✔
6181
    pUser = NULL;
644✔
6182
    mndUserFreeObj(&newUser);
644✔
6183
  }
6184
_exit:
1,610✔
6185
  if (pIter) sdbCancelFetch(pSdb, pIter);
1,610✔
6186
  if (pUser) sdbRelease(pSdb, pUser);
1,610✔
6187
  if (code < 0) {
1,610✔
6188
    mError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
6189
  }
6190
  TAOS_RETURN(code);
1,610✔
6191
}
6192

6193
static int32_t mndUserPrivHashRemoveDb(SHashObj *pHash, const char *dbFName, int32_t dbFNameLen, bool *found) {
4,586,695✔
6194
  void *pVal = NULL;
4,586,695✔
6195
  while ((pVal = taosHashIterate(pHash, pVal))) {
4,834,438✔
6196
    size_t klen = 0;
247,743✔
6197
    char  *key = taosHashGetKey(pVal, &klen);
247,743✔
6198
    if (key && privDbKeyMatch(key, dbFName, dbFNameLen)) {
495,486✔
6199
      TAOS_CHECK_RETURN(taosHashRemove(pHash, key, klen));
31,772✔
6200
      if (found) *found = true;
31,772✔
6201
    }
6202
  }
6203
  TAOS_RETURN(0);
4,586,695✔
6204
}
6205

6206
static int32_t mndUserRemoveDbPrivsImpl(SUserObj *pUser, const char *key, int32_t keyLen, bool *pFound) {
917,339✔
6207
  bool found = false;
917,339✔
6208
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pUser->objPrivs, (char *)key, keyLen, found ? NULL : &found));
917,339✔
6209
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pUser->selectTbs, (char *)key, keyLen, found ? NULL : &found));
917,339✔
6210
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pUser->insertTbs, (char *)key, keyLen, found ? NULL : &found));
917,339✔
6211
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pUser->updateTbs, (char *)key, keyLen, found ? NULL : &found));
917,339✔
6212
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pUser->deleteTbs, (char *)key, keyLen, found ? NULL : &found));
917,339✔
6213
  if (taosHashGet(pUser->ownedDbs, key, keyLen)) {
917,339✔
6214
    TAOS_CHECK_RETURN(taosHashRemove(pUser->ownedDbs, (char *)key, keyLen));
×
6215
    if (!found) found = true;
×
6216
  }
6217
  if (pFound) *pFound = found;
917,339✔
6218
  TAOS_RETURN(0);
917,339✔
6219
}
6220

6221
static int32_t mndUserRemoveDbPrivs(SMnode *pMnode, STrans *pTrans, const char *key, int32_t keyLen,
804,371✔
6222
                                    SSHashObj **ppUsers) {
6223
  int32_t    code = 0, lino = 0;
804,371✔
6224
  SSdb      *pSdb = pMnode->pSdb;
804,371✔
6225
  void      *pIter = NULL;
804,371✔
6226
  SUserObj  *pUser = NULL;
804,371✔
6227
  SSHashObj *pUsers = ppUsers ? *ppUsers : NULL;
804,371✔
6228
  bool       output = (ppUsers != NULL);
804,371✔
6229
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser))) {
1,721,370✔
6230
    bool found = false;
916,999✔
6231
    TAOS_CHECK_EXIT(mndUserRemoveDbPrivsImpl(pUser, key, keyLen, &found));
916,999✔
6232
    if (!found) {
916,999✔
6233
      sdbRelease(pSdb, pUser);
898,601✔
6234
      pUser = NULL;
898,601✔
6235
      continue;
898,601✔
6236
    }
6237

6238
    if (output) {
18,398✔
6239
      if (!pUsers) {
680✔
6240
        TSDB_CHECK_NULL(pUsers = tSimpleHashInit(32, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY)), code, lino,
340✔
6241
                        _exit, TSDB_CODE_OUT_OF_MEMORY);
6242
        tSimpleHashSetFreeFp(pUsers, (_hash_free_fn_t)mndUserFreeObj);
340✔
6243
        *ppUsers = pUsers;
340✔
6244
      }
6245
      void   *pVal = NULL;
680✔
6246
      int32_t userLen = strlen(pUser->name) + 1;
680✔
6247
      if ((pVal = tSimpleHashGet(pUsers, pUser->name, userLen)) != NULL) {
680✔
6248
        TAOS_CHECK_EXIT(mndUserRemoveDbPrivsImpl((SUserObj *)pVal, key, keyLen, NULL));
340✔
6249
      } else {
6250
        SUserObj newUser = {0};
340✔
6251
        if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
340✔
6252
          mndUserFreeObj(&newUser);
×
6253
          TAOS_CHECK_EXIT(code);
×
6254
        }
6255
        if ((code = tSimpleHashPut(pUsers, pUser->name, userLen, &newUser, sizeof(SUserObj)))) {
340✔
6256
          mndUserFreeObj(&newUser);
×
6257
          TAOS_CHECK_EXIT(code);
×
6258
        }
6259
      }
6260
    } else {
6261
      int64_t now = taosGetTimestampMs();
17,718✔
6262
      taosWLockLatch(&pUser->lock);
17,718✔
6263
      pUser->updateTime = now;
17,718✔
6264
      ++pUser->authVersion;
17,718✔
6265
      taosWUnLockLatch(&pUser->lock);
17,718✔
6266

6267
      SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
17,718✔
6268
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
17,718✔
6269
        TAOS_CHECK_EXIT(TSDB_CODE_OUT_OF_MEMORY);
×
6270
      }
6271
      TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
17,718✔
6272
    }
6273

6274
    sdbRelease(pSdb, pUser);
18,398✔
6275
    pUser = NULL;
18,398✔
6276
  }
6277
_exit:
804,371✔
6278
  if (pUser != NULL) sdbRelease(pSdb, pUser);
804,371✔
6279
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
804,371✔
6280
  TAOS_RETURN(code);
804,371✔
6281
}
6282

6283
static int32_t mndRoleRemoveDbPrivsImpl(SRoleObj *pRole, const char *key, int32_t keyLen, bool *pFound) {
×
6284
  bool found = false;
×
6285
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pRole->objPrivs, (char *)key, keyLen, found ? NULL : &found));
×
6286
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pRole->selectTbs, (char *)key, keyLen, found ? NULL : &found));
×
6287
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pRole->insertTbs, (char *)key, keyLen, found ? NULL : &found));
×
6288
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pRole->updateTbs, (char *)key, keyLen, found ? NULL : &found));
×
6289
  TAOS_CHECK_RETURN(mndUserPrivHashRemoveDb(pRole->deleteTbs, (char *)key, keyLen, found ? NULL : &found));
×
6290
  if (pFound) *pFound = found;
×
6291
  TAOS_RETURN(0);
×
6292
}
6293

6294
static int32_t mndRoleRemoveDbPrivs(SMnode *pMnode, STrans *pTrans, const char *key, int32_t keyLen,
×
6295
                                    SSHashObj **ppRoles) {
6296
  int32_t    code = 0, lino = 0;
×
6297
  SSdb      *pSdb = pMnode->pSdb;
×
6298
  void      *pIter = NULL;
×
6299
  SRoleObj  *pRole = NULL;
×
6300
  SSHashObj *pRoles = ppRoles ? *ppRoles : NULL;
×
6301
  bool       output = (ppRoles != NULL);
×
6302
  while ((pIter = sdbFetch(pSdb, SDB_ROLE, pIter, (void **)&pRole))) {
×
6303
    bool found = false;
×
6304
    TAOS_CHECK_EXIT(mndRoleRemoveDbPrivsImpl(pRole, key, keyLen, &found));
×
6305
    if (!found) {
×
6306
      sdbRelease(pSdb, pRole);
×
6307
      pRole = NULL;
×
6308
      continue;
×
6309
    }
6310

6311
    if (output) {
×
6312
      if (!pRoles) {
×
6313
        TSDB_CHECK_NULL(pRoles = tSimpleHashInit(32, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY)), code, lino,
×
6314
                        _exit, TSDB_CODE_OUT_OF_MEMORY);
6315
        tSimpleHashSetFreeFp(pRoles, (_hash_free_fn_t)mndRoleFreeObj);
×
6316
        *ppRoles = pRoles;
×
6317
      }
6318
      void   *pVal = NULL;
×
6319
      int32_t roleLen = strlen(pRole->name) + 1;
×
6320
      if ((pVal = tSimpleHashGet(pRoles, pRole->name, roleLen)) != NULL) {
×
6321
        TAOS_CHECK_EXIT(mndRoleRemoveDbPrivsImpl((SRoleObj *)pVal, key, keyLen, NULL));
×
6322
      } else {
6323
        SRoleObj newRole = {0};
×
6324
        if ((code = mndRoleDupObj(pRole, &newRole)) != 0) {
×
6325
          mndRoleFreeObj(&newRole);
×
6326
          TAOS_CHECK_EXIT(code);
×
6327
        }
6328
        if ((code = tSimpleHashPut(pRoles, pRole->name, roleLen, &newRole, sizeof(SRoleObj)))) {
×
6329
          mndRoleFreeObj(&newRole);
×
6330
          TAOS_CHECK_EXIT(code);
×
6331
        }
6332
      }
6333
    } else {
6334
      int64_t now = taosGetTimestampMs();
×
6335
      taosWLockLatch(&pRole->lock);
×
6336
      pRole->updateTime = now;
×
6337
      ++pRole->version;
×
6338
      taosWUnLockLatch(&pRole->lock);
×
6339

6340
      SSdbRaw *pCommitRaw = mndRoleActionEncode(pRole);
×
6341
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
×
6342
        TAOS_CHECK_EXIT(TSDB_CODE_OUT_OF_MEMORY);
×
6343
      }
6344
      TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
×
6345
    }
6346

6347
    sdbRelease(pSdb, pRole);
×
6348
    pRole = NULL;
×
6349
  }
6350
_exit:
×
6351
  if (pRole != NULL) sdbRelease(pSdb, pRole);
×
6352
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
×
6353
  TAOS_RETURN(code);
×
6354
}
6355

6356
int32_t mndPrincipalRemoveDb(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SSHashObj **ppUsers, SSHashObj **ppRoles) {
804,371✔
6357
  TAOS_RETURN(mndUserRemoveDbPrivs(pMnode, pTrans, pDb->name, strlen(pDb->name), ppUsers));
804,371✔
6358
  return mndRoleRemoveDbPrivs(pMnode, pTrans, pDb->name, strlen(pDb->name), ppRoles);
6359
}
6360

6361
int32_t mndUserRemoveStb(SMnode *pMnode, STrans *pTrans, char *stb) {
514,214✔
6362
  return mndPrincipalRemoveObjPrivs(pMnode, pTrans, stb, PRIV_OBJ_TBL);
514,214✔
6363
}
6364

6365
static int32_t mndUserRemoveObjPrivs(SMnode *pMnode, STrans *pTrans, const char *key, int32_t keyLen,
795,052✔
6366
                                     EPrivObjType objType) {
6367
  int32_t   code = 0, lino = 0;
795,052✔
6368
  SSdb     *pSdb = pMnode->pSdb;
795,052✔
6369
  void     *pIter = NULL;
795,052✔
6370
  SUserObj *pUser = NULL;
795,052✔
6371
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser))) {
1,602,390✔
6372
    bool found = false;
807,338✔
6373
    if (taosHashGet(pUser->objPrivs, key, keyLen)) {
807,338✔
6374
      TAOS_CHECK_EXIT(taosHashRemove(pUser->objPrivs, key, keyLen));
3,177✔
6375
      found = true;
3,177✔
6376
    }
6377
    if (objType == PRIV_OBJ_TBL) {
807,338✔
6378
      SPrivTblPolicies *pTblPrivs = taosHashGet(pUser->selectTbs, key, keyLen);
515,059✔
6379
      if (pTblPrivs) {
515,059✔
6380
        TAOS_CHECK_EXIT(taosHashRemove(pUser->selectTbs, key, keyLen));
×
6381
        found = true;
×
6382
      }
6383
      pTblPrivs = taosHashGet(pUser->insertTbs, key, keyLen);
515,059✔
6384
      if (pTblPrivs) {
515,059✔
6385
        TAOS_CHECK_EXIT(taosHashRemove(pUser->insertTbs, key, keyLen));
×
6386
        found = true;
×
6387
      }
6388
      pTblPrivs = taosHashGet(pUser->updateTbs, key, keyLen);
515,059✔
6389
      if (pTblPrivs) {
515,059✔
6390
        TAOS_CHECK_EXIT(taosHashRemove(pUser->updateTbs, key, keyLen));
×
6391
        found = true;
×
6392
      }
6393
      pTblPrivs = taosHashGet(pUser->deleteTbs, key, keyLen);
515,059✔
6394
      if (pTblPrivs) {
515,059✔
6395
        TAOS_CHECK_EXIT(taosHashRemove(pUser->deleteTbs, key, keyLen));
×
6396
        found = true;
×
6397
      }
6398
    }
6399
    if (!found) {
807,338✔
6400
      sdbRelease(pSdb, pUser);
804,161✔
6401
      pUser = NULL;
804,161✔
6402
      continue;
804,161✔
6403
    }
6404

6405
    int64_t now = taosGetTimestampMs();
3,177✔
6406
    taosWLockLatch(&pUser->lock);
3,177✔
6407
    pUser->updateTime = now;
3,177✔
6408
    ++pUser->authVersion;
3,177✔
6409
    taosWUnLockLatch(&pUser->lock);
3,177✔
6410

6411
    SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
3,177✔
6412
    if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
3,177✔
6413
      TAOS_CHECK_EXIT(TSDB_CODE_OUT_OF_MEMORY);
×
6414
    }
6415
    TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
3,177✔
6416

6417
    sdbRelease(pSdb, pUser);
3,177✔
6418
    pUser = NULL;
3,177✔
6419
  }
6420
_exit:
795,052✔
6421
  if (pUser != NULL) sdbRelease(pSdb, pUser);
795,052✔
6422
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
795,052✔
6423
  TAOS_RETURN(code);
795,052✔
6424
}
6425

6426
static int32_t mndRoleRemoveObjPrivs(SMnode *pMnode, STrans *pTrans, const char *key, int32_t keyLen,
795,052✔
6427
                                     EPrivObjType objType) {
6428
  int32_t   code = 0, lino = 0;
795,052✔
6429
  SSdb     *pSdb = pMnode->pSdb;
795,052✔
6430
  void     *pIter = NULL;
795,052✔
6431
  SRoleObj *pRole = NULL;
795,052✔
6432
  while ((pIter = sdbFetch(pSdb, SDB_ROLE, pIter, (void **)&pRole))) {
5,565,364✔
6433
    // inherit system roles have no direct privileges
6434
    if (taosStrncasecmp(pRole->name, "sys", 3) == 0) {
4,770,312✔
6435
      sdbRelease(pSdb, pRole);
4,770,312✔
6436
      pRole = NULL;
4,770,312✔
6437
      continue;
4,770,312✔
6438
    }
6439
    bool found = false;
×
6440
    if (taosHashGet(pRole->objPrivs, key, keyLen)) {
×
6441
      TAOS_CHECK_EXIT(taosHashRemove(pRole->objPrivs, key, keyLen));
×
6442
      found = true;
×
6443
    }
6444

6445
    if (objType == PRIV_OBJ_TBL) {
×
6446
      SPrivTblPolicies *pTblPrivs = taosHashGet(pRole->selectTbs, key, keyLen);
×
6447
      if (pTblPrivs) {
×
6448
        TAOS_CHECK_EXIT(taosHashRemove(pRole->selectTbs, key, keyLen));
×
6449
        found = true;
×
6450
      }
6451
      pTblPrivs = taosHashGet(pRole->insertTbs, key, keyLen);
×
6452
      if (pTblPrivs) {
×
6453
        TAOS_CHECK_EXIT(taosHashRemove(pRole->insertTbs, key, keyLen));
×
6454
        found = true;
×
6455
      }
6456
      pTblPrivs = taosHashGet(pRole->updateTbs, key, keyLen);
×
6457
      if (pTblPrivs) {
×
6458
        TAOS_CHECK_EXIT(taosHashRemove(pRole->updateTbs, key, keyLen));
×
6459
        found = true;
×
6460
      }
6461
      pTblPrivs = taosHashGet(pRole->deleteTbs, key, keyLen);
×
6462
      if (pTblPrivs) {
×
6463
        TAOS_CHECK_EXIT(taosHashRemove(pRole->deleteTbs, key, keyLen));
×
6464
        found = true;
×
6465
      }
6466
    }
6467
    if (!found) {
×
6468
      sdbRelease(pSdb, pRole);
×
6469
      pRole = NULL;
×
6470
      continue;
×
6471
    }
6472
    int64_t now = taosGetTimestampMs();
×
6473
    taosWLockLatch(&pRole->lock);
×
6474
    pRole->updateTime = now;
×
6475
    ++pRole->version;
×
6476
    taosWUnLockLatch(&pRole->lock);
×
6477

6478
    SSdbRaw *pCommitRaw = mndRoleActionEncode(pRole);
×
6479
    if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
×
6480
      TAOS_CHECK_EXIT(TSDB_CODE_OUT_OF_MEMORY);
×
6481
    }
6482
    TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
×
6483

6484
    sdbRelease(pSdb, pRole);
×
6485
    pRole = NULL;
×
6486
  }
6487
_exit:
795,052✔
6488
  if (pRole != NULL) sdbRelease(pSdb, pRole);
795,052✔
6489
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
795,052✔
6490
  TAOS_RETURN(code);
795,052✔
6491
}
6492

6493
static int32_t mndPrincipalRemoveObjPrivs(SMnode *pMnode, STrans *pTrans, char *objFName, EPrivObjType objType) {
795,052✔
6494
  int32_t code = 0;
795,052✔
6495
  char    key[TSDB_PRIV_MAX_KEY_LEN] = {0};
795,052✔
6496
  int32_t keyLen = snprintf(key, sizeof(key), "%d.%s", objType, objFName) + 1;
795,052✔
6497
  TAOS_CHECK_RETURN(mndUserRemoveObjPrivs(pMnode, pTrans, key, keyLen, objType));
795,052✔
6498
  TAOS_CHECK_RETURN(mndRoleRemoveObjPrivs(pMnode, pTrans, key, keyLen, objType));
795,052✔
6499
  TAOS_RETURN(code);
795,052✔
6500
}
6501

6502
int32_t mndUserRemoveView(SMnode *pMnode, STrans *pTrans, char *view) {
163,877✔
6503
  return mndPrincipalRemoveObjPrivs(pMnode, pTrans, view, PRIV_OBJ_VIEW);
163,877✔
6504
}
6505

6506
int32_t mndUserRemoveTopic(SMnode *pMnode, STrans *pTrans, char *topic) {
116,961✔
6507
  return mndPrincipalRemoveObjPrivs(pMnode, pTrans, topic, PRIV_OBJ_TOPIC);
116,961✔
6508
}
6509

6510
int64_t mndGetUserIpWhiteListVer(SMnode *pMnode, SUserObj *pUser) {
×
6511
  // ver = 0, disable ip white list
6512
  // ver > 0, enable ip white list
6513
  return tsEnableWhiteList ? pUser->ipWhiteListVer : 0;
×
6514
}
6515

6516
int64_t mndGetUserTimeWhiteListVer(SMnode *pMnode, SUserObj *pUser) {
×
6517
  // ver = 0, disable datetime white list
6518
  // ver > 0, enable datetime white list
6519
  return tsEnableWhiteList ? pUser->timeWhiteListVer : 0;
×
6520
}
6521

6522
#ifdef TD_ENTERPRISE
6523
/**
6524
 * @brief Check if there is at least one valid user with SYSDBA, SYSSEC or SYSAUDIT role in the system, if not, return
6525
 * error code.
6526
 *
6527
 * @param pMnode
6528
 * @param skipUser
6529
 * @param skipRole  0 or T_ROLE_SYSDBA, T_ROLE_SYSSEC, T_ROLE_SYSAUDIT
6530
 * @return int32_t
6531
 */
6532
int32_t mndCheckManagementRoleStatus(SMnode *pMnode, const char *skipUser, uint8_t skipRole) {
6,082✔
6533
  SUserObj *pUser = NULL;
6,082✔
6534
  SSdb     *pSdb = pMnode->pSdb;
6,082✔
6535
  uint8_t   foundRoles = skipRole;  // 0x01: T_ROLE_SYSDBA, 0x02: T_ROLE_SYSSEC, 0x04: T_ROLE_SYSAUDIT
6,082✔
6536

6537
  void *pIter = NULL;
6,082✔
6538
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser))) {
34,932✔
6539
    if (pUser->enable == 0 || pUser->superUser == 1 || taosHashGetSize(pUser->roles) == 0 ||
32,142✔
6540
        (skipUser && strncmp(pUser->user, skipUser, TSDB_USER_LEN) == 0)) {
23,828✔
6541
      sdbRelease(pSdb, pUser);
11,420✔
6542
      continue;
11,420✔
6543
    }
6544

6545
    if ((foundRoles & T_ROLE_SYSDBA) == 0 && taosHashGet(pUser->roles, TSDB_ROLE_SYSDBA, sizeof(TSDB_ROLE_SYSDBA))) {
20,722✔
6546
      foundRoles |= T_ROLE_SYSDBA;
5,152✔
6547
    } else if ((foundRoles & T_ROLE_SYSSEC) == 0 &&
29,336✔
6548
               taosHashGet(pUser->roles, TSDB_ROLE_SYSSEC, sizeof(TSDB_ROLE_SYSSEC))) {
13,766✔
6549
      foundRoles |= T_ROLE_SYSSEC;
4,966✔
6550
    } else if ((foundRoles & T_ROLE_SYSAUDIT) == 0 &&
21,208✔
6551
               taosHashGet(pUser->roles, TSDB_ROLE_SYSAUDIT, sizeof(TSDB_ROLE_SYSAUDIT))) {
10,604✔
6552
      foundRoles |= T_ROLE_SYSAUDIT;
4,780✔
6553
    }
6554
    sdbRelease(pSdb, pUser);
20,722✔
6555
    if (foundRoles == (T_ROLE_SYSDBA | T_ROLE_SYSSEC | T_ROLE_SYSAUDIT)) {
20,722✔
6556
      sdbCancelFetch(pSdb, pIter);
3,292✔
6557
      return TSDB_CODE_SUCCESS;
3,292✔
6558
    }
6559
  }
6560

6561
  if ((foundRoles & T_ROLE_SYSDBA) == 0) {
2,790✔
6562
    return TSDB_CODE_MND_ROLE_NO_VALID_SYSDBA;
930✔
6563
  } else if ((foundRoles & T_ROLE_SYSSEC) == 0) {
1,860✔
6564
    return TSDB_CODE_MND_ROLE_NO_VALID_SYSSEC;
930✔
6565
  } else if ((foundRoles & T_ROLE_SYSAUDIT) == 0) {
930✔
6566
    return TSDB_CODE_MND_ROLE_NO_VALID_SYSAUDIT;
930✔
6567
  }
6568
  return TSDB_CODE_SUCCESS;
×
6569
}
6570

6571
#endif
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