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

taosdata / TDengine / #4923

09 Jan 2026 08:13AM UTC coverage: 65.373% (+0.2%) from 65.161%
#4923

push

travis-ci

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

33 of 56 new or added lines in 8 files covered. (58.93%)

3042 existing lines in 131 files now uncovered.

198273 of 303297 relevant lines covered (65.37%)

118980690.73 hits per line

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

59.56
/source/dnode/mnode/impl/src/mndUser.c
1
/*
2
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
3
 *
4
 * This program is free software: you can use, redistribute, and/or modify
5
 * it under the terms of the GNU Affero General Public License, version 3
6
 * or later ("AGPL"), as published by the Free Software Foundation.
7
 *
8
 * This program is distributed in the hope that it will be useful, but WITHOUT
9
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
 * FITNESS FOR A PARTICULAR PURPOSE.
11
 *
12
 * You should have received a copy of the GNU Affero General Public License
13
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14
 */
15

16
#define _DEFAULT_SOURCE
17
// clang-format off
18
#ifndef TD_ASTRA
19
#include <uv.h>
20
#endif
21
#include "crypt.h"
22
#include "mndRole.h"
23
#include "mndUser.h"
24
#include "audit.h"
25
#include "mndDb.h"
26
#include "mndPrivilege.h"
27
#include "mndShow.h"
28
#include "mndStb.h"
29
#include "mndTopic.h"
30
#include "mndTrans.h"
31
#include "mndToken.h"
32
#include "tbase64.h"
33
#include "totp.h"
34

35
// clang-format on
36

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

42
#define USER_RESERVE_SIZE                    63
43

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

48
#if 0
49
#define PRIVILEGE_TYPE_ALL       BIT_FLAG_MASK(0)
50
#define PRIVILEGE_TYPE_READ      BIT_FLAG_MASK(1)
51
#define PRIVILEGE_TYPE_WRITE     BIT_FLAG_MASK(2)
52
#define PRIVILEGE_TYPE_SUBSCRIBE BIT_FLAG_MASK(3)
53
#define PRIVILEGE_TYPE_ALTER     BIT_FLAG_MASK(4)
54
#endif
55

56
#define ALTER_USER_ADD_PRIVS(_type) ((_type) == TSDB_ALTER_USER_ADD_PRIVILEGES)
57
#define ALTER_USER_DEL_PRIVS(_type) ((_type) == TSDB_ALTER_USER_DEL_PRIVILEGES)
58

59
#if 0
60
#define ALTER_USER_ALL_PRIV(_priv)       (PRIV_HAS((_priv), PRIV_CM_ALL))
61
#define ALTER_USER_READ_PRIV(_priv)      (PRIV_HAS((_priv), PRIV_CM_READ) || PRIV_HAS((_priv), PRIV_CM_ALL))
62
#define ALTER_USER_WRITE_PRIV(_priv)     (PRIV_HAS((_priv), PRIV_CM_WRITE) || PRIV_HAS((_priv), PRIV_CM_ALL))
63
#define ALTER_USER_ALTER_PRIV(_priv)     (PRIV_HAS((_priv), PRIV_CM_ALTER) || PRIV_HAS((_priv), PRIV_CM_ALL))
64
#define ALTER_USER_SUBSCRIBE_PRIV(_priv) (PRIV_HAS((_priv), PRIV_TOPIC_SUBSCRIBE))
65

66
#define ALTER_USER_TARGET_DB(_tbname) (0 == (_tbname)[0])
67
#define ALTER_USER_TARGET_TB(_tbname) (0 != (_tbname)[0])
68

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

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

103
#define ALTER_USER_ADD_SUBSCRIBE_TOPIC_PRIV(_type, _priv) \
104
  (ALTER_USER_ADD_PRIVS(_type) && ALTER_USER_SUBSCRIBE_PRIV(_priv))
105
#define ALTER_USER_DEL_SUBSCRIBE_TOPIC_PRIV(_type, _priv) \
106
  (ALTER_USER_DEL_PRIVS(_type) && ALTER_USER_SUBSCRIBE_PRIV(_priv))
107
#endif
108
static void generateSalt(char *salt, size_t len);
109

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

113
static bool isIpWhiteListEqual(SIpWhiteListDual *a, SIpWhiteListDual *b);
114
static bool isIpRangeEqual(SIpRange *a, SIpRange *b);
115

116
#define MND_MAX_USER_IP_RANGE   (TSDB_PRIVILEDGE_HOST_LEN / 24)
117
#define MND_MAX_USER_TIME_RANGE 2048
118

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

135
static int32_t  mndProcessGetUserIpWhiteListReq(SRpcMsg *pReq);
136
static int32_t  mndProcessRetrieveIpWhiteListReq(SRpcMsg *pReq);
137
static int32_t  mndProcessGetUserDateTimeWhiteListReq(SRpcMsg *pReq);
138
static int32_t  mndProcessRetrieveDateTimeWhiteListReq(SRpcMsg *pReq);
139
static int32_t mndProcessCreateTotpSecretReq(SRpcMsg *pReq);
140
static int32_t mndProcessDropTotpSecretReq(SRpcMsg *pReq);
141

142
static int32_t createIpWhiteListFromOldVer(void *buf, int32_t len, SIpWhiteList **ppList);
143
static int32_t tDerializeIpWhileListFromOldVer(void *buf, int32_t len, SIpWhiteList *pList);
144

145

146
typedef struct {
147
  SIpWhiteListDual   *wlIp;
148
  SDateTimeWhiteList *wlTime;
149
  SLoginInfo          loginInfo;
150
} SCachedUserInfo;
151

152
typedef struct {
153
  SHashObj      *users;  // key: user, value: SCachedUserInfo*
154
  int64_t        verIp;
155
  int64_t        verTime;
156
  TdThreadRwlock rw;
157
} SUserCache;
158

159
static SUserCache userCache;
160

161

162
static int32_t userCacheInit() {
398,009✔
163
  _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
398,009✔
164

165
  SHashObj *users = taosHashInit(8, hashFn, 1, HASH_ENTRY_LOCK);
398,009✔
166
  if (users == NULL) {
398,009✔
167
    TAOS_RETURN(terrno);
×
168
  }
169

170
  userCache.users = users;
398,009✔
171
  userCache.verIp = 0;
398,009✔
172
  userCache.verTime = 0;
398,009✔
173

174
  (void)taosThreadRwlockInit(&userCache.rw, NULL);
398,009✔
175
  TAOS_RETURN(0);
398,009✔
176
}
177

178

179

180
static void userCacheCleanup() {
397,950✔
181
  if (userCache.users == NULL) {
397,950✔
182
    return;
×
183
  }
184

185
  void *pIter = taosHashIterate(userCache.users, NULL);
397,950✔
186
  while (pIter) {
802,356✔
187
    SCachedUserInfo *pInfo = *(SCachedUserInfo **)pIter;
404,406✔
188
    if (pInfo != NULL) {
404,406✔
189
      taosMemoryFree(pInfo->wlIp);
404,406✔
190
      taosMemoryFree(pInfo->wlTime);
404,406✔
191
      taosMemoryFree(pInfo);
404,406✔
192
    }
193
    pIter = taosHashIterate(userCache.users, pIter);
404,406✔
194
  }
195
  taosHashCleanup(userCache.users);
397,950✔
196

197
  (void)taosThreadRwlockDestroy(&userCache.rw);
397,950✔
198
}
199

200

201

202
static void userCacheRemoveUser(const char *user) {
19,754✔
203
  size_t userLen = strlen(user);
19,754✔
204

205
  (void)taosThreadRwlockWrlock(&userCache.rw);
19,754✔
206

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

221
  (void)taosThreadRwlockUnlock(&userCache.rw);
19,754✔
222
}
19,754✔
223

224

225

226
static void userCacheResetLoginInfo(const char *user) {
503✔
227
  size_t userLen = strlen(user);
503✔
228

229
  (void)taosThreadRwlockWrlock(&userCache.rw);
503✔
230

231
  SCachedUserInfo **ppInfo = taosHashGet(userCache.users, user, userLen);
503✔
232
  if (ppInfo != NULL && *ppInfo != NULL) {
503✔
233
    (*ppInfo)->loginInfo.lastLoginTime = taosGetTimestampSec();
503✔
234
    (*ppInfo)->loginInfo.failedLoginCount = 0;
503✔
235
    (*ppInfo)->loginInfo.lastFailedLoginTime = 0;
503✔
236
  }
237

238
  (void)taosThreadRwlockUnlock(&userCache.rw);
503✔
239
}
503✔
240

241

242

243
static SCachedUserInfo* getCachedUserInfo(const char* user) {
3,769,339✔
244
  size_t userLen = strlen(user);
3,769,339✔
245
  SCachedUserInfo **ppInfo = taosHashGet(userCache.users, user, userLen);
3,769,339✔
246
  if (ppInfo != NULL) {
3,769,339✔
247
    return *ppInfo;
3,345,179✔
248
  }
249

250
  SCachedUserInfo  *pInfo = (SCachedUserInfo *)taosMemoryCalloc(1, sizeof(SCachedUserInfo));
424,160✔
251
  if (pInfo == NULL) {
424,160✔
252
    return NULL;
×
253
  }
254

255
  if (taosHashPut(userCache.users, user, userLen, &pInfo, sizeof(pInfo)) != 0) {
424,160✔
256
    taosMemoryFree(pInfo);
×
257
    return NULL;
×
258
  }
259

260
  return pInfo;
424,160✔
261
}
262

263

264

265
void mndGetUserLoginInfo(const char *user, SLoginInfo *pLoginInfo) {
2,381,677✔
266
  size_t userLen = strlen(user);
2,381,677✔
267

268
  (void)taosThreadRwlockRdlock(&userCache.rw);
2,381,677✔
269

270
  SCachedUserInfo **ppInfo = taosHashGet(userCache.users, user, userLen);
2,382,686✔
271
  if (ppInfo != NULL && *ppInfo != NULL) {
2,382,627✔
272
    pLoginInfo->lastLoginTime = (*ppInfo)->loginInfo.lastLoginTime;
2,107,804✔
273
    pLoginInfo->failedLoginCount = (*ppInfo)->loginInfo.failedLoginCount;
2,107,411✔
274
    pLoginInfo->lastFailedLoginTime = (*ppInfo)->loginInfo.lastFailedLoginTime;
2,107,118✔
275
  } else {
276
    pLoginInfo->lastLoginTime = taosGetTimestampSec();
274,819✔
277
    pLoginInfo->failedLoginCount = 0;
274,782✔
278
    pLoginInfo->lastFailedLoginTime = 0;
274,782✔
279
  }
280

281
  (void)taosThreadRwlockUnlock(&userCache.rw);
2,381,877✔
282

283
  if (pLoginInfo->lastLoginTime == 0) {
2,382,193✔
284
    pLoginInfo->lastLoginTime = taosGetTimestampSec();
28,707✔
285
  }
286
}
2,382,748✔
287

288

289

290
void mndSetUserLoginInfo(const char *user, const SLoginInfo *pLoginInfo) {
2,382,182✔
291
  size_t userLen = strlen(user);
2,382,182✔
292

293
  (void)taosThreadRwlockWrlock(&userCache.rw);
2,382,182✔
294

295
  SCachedUserInfo  *pInfo = getCachedUserInfo(user);
2,382,778✔
296
  if (pInfo != NULL) {
2,382,778✔
297
    pInfo->loginInfo.lastLoginTime = pLoginInfo->lastLoginTime;
2,382,778✔
298
    pInfo->loginInfo.failedLoginCount = pLoginInfo->failedLoginCount;
2,382,778✔
299
    pInfo->loginInfo.lastFailedLoginTime = pLoginInfo->lastFailedLoginTime;
2,382,778✔
300
  }
301

302
  (void)taosThreadRwlockUnlock(&userCache.rw);
2,382,778✔
303
}
2,382,778✔
304

305

306

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

312
  if (a == NULL || b == NULL) {
1,012,939✔
313
    return false;
47,177✔
314
  }
315

316
  if (a->num != b->num) {
965,762✔
317
    return false;
×
318
  }
319

320
  for (int i = 0; i < a->num; i++) {
965,762✔
321
    if (a->ranges[i].start != b->ranges[i].start ||
×
322
        a->ranges[i].duration != b->ranges[i].duration ||
×
323
        a->ranges[i].neg != b->ranges[i].neg ||
×
324
        a->ranges[i].absolute != b->ranges[i].absolute) {
×
325
      return false;
×
326
    }
327
  }
328

329
  return true;
965,762✔
330
}
331

332

333

334
static int32_t userCacheUpdateWhiteList(SMnode* pMnode, SUserObj* pUser) {
1,012,939✔
335
  int32_t code = 0, lino = 0;
1,012,939✔
336

337
  (void)taosThreadRwlockWrlock(&userCache.rw);
1,012,939✔
338

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

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

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

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

372

373

374
static int32_t userCacheRebuildIpWhiteList(SMnode *pMnode) {
485,984✔
375
  int32_t   code = 0, lino = 0;
485,984✔
376

377
  SSdb     *pSdb = pMnode->pSdb;
485,984✔
378
  void     *pIter = NULL;
485,984✔
379
  while (1) {
190,986✔
380
    SUserObj *pUser = NULL;
676,970✔
381
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
676,970✔
382
    if (pIter == NULL) {
676,970✔
383
      break;
485,984✔
384
    }
385

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

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

400
    taosMemoryFree(pInfo->wlIp);
190,986✔
401
    pInfo->wlIp = wl;
190,986✔
402

403
    sdbRelease(pSdb, pUser);
190,986✔
404
  }
405

406
  userCache.verIp++;
485,984✔
407

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

415

416

417
int64_t mndGetIpWhiteListVersion(SMnode *pMnode) {
54,647,865✔
418
  int64_t ver = 0;
54,647,865✔
419
  int32_t code = 0;
54,647,865✔
420

421
  if (mndEnableIpWhiteList(pMnode) != 0 && tsEnableWhiteList) {
54,647,865✔
422
    (void)taosThreadRwlockWrlock(&userCache.rw);
4,773✔
423

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

435
    (void)taosThreadRwlockUnlock(&userCache.rw);
4,773✔
436
  }
437

438
  mDebug("ip-white-list on mnode ver: %" PRId64, ver);
54,647,865✔
439
  return ver;
54,647,865✔
440
}
441

442

443

444
int32_t mndRefreshUserIpWhiteList(SMnode *pMnode) {
485,984✔
445
  int32_t code = 0;
485,984✔
446
  (void)taosThreadRwlockWrlock(&userCache.rw);
485,984✔
447

448
  if ((code = userCacheRebuildIpWhiteList(pMnode)) != 0) {
485,984✔
449
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
450
    TAOS_RETURN(code);
×
451
  }
452
  userCache.verIp = taosGetTimestampMs();
485,984✔
453
  (void)taosThreadRwlockUnlock(&userCache.rw);
485,984✔
454

455
  TAOS_RETURN(code);
485,984✔
456
}
457

458

459

460
static int32_t userCacheRebuildTimeWhiteList(SMnode *pMnode) {
477,634✔
461
  int32_t   code = 0, lino = 0;
477,634✔
462

463
  SSdb     *pSdb = pMnode->pSdb;
477,634✔
464
  void     *pIter = NULL;
477,634✔
465
  while (1) {
182,636✔
466
    SUserObj *pUser = NULL;
660,270✔
467
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
660,270✔
468
    if (pIter == NULL) {
660,270✔
469
      break;
477,634✔
470
    }
471

472
    SCachedUserInfo *pInfo = getCachedUserInfo(pUser->user);
182,636✔
473
    if (pInfo == NULL) {
182,636✔
474
      sdbRelease(pSdb, pUser);
×
475
      sdbCancelFetch(pSdb, pIter);
×
476
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
477
    }
478

479
    SDateTimeWhiteList *wl = cloneDateTimeWhiteList(pUser->pTimeWhiteList);
182,636✔
480
    if (wl == NULL) {
182,636✔
481
      sdbRelease(pSdb, pUser);
×
482
      sdbCancelFetch(pSdb, pIter);
×
483
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
484
    }
485

486
    taosMemoryFree(pInfo->wlTime);
182,636✔
487
    pInfo->wlTime = wl;
182,636✔
488

489
    sdbRelease(pSdb, pUser);
182,636✔
490
  }
491

492
  userCache.verTime++;
477,634✔
493

494
_OVER:
477,634✔
495
  if (code < 0) {
477,634✔
496
    mError("failed to rebuild time white list at line %d since %s", lino, tstrerror(code));
×
497
  }
498
  TAOS_RETURN(code);
477,634✔
499
}
500

501

502

503
int32_t mndRefreshUserDateTimeWhiteList(SMnode *pMnode) {
477,634✔
504
  int32_t code = 0;
477,634✔
505
  (void)taosThreadRwlockWrlock(&userCache.rw);
477,634✔
506

507
  if ((code = userCacheRebuildTimeWhiteList(pMnode)) != 0) {
477,634✔
508
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
509
    TAOS_RETURN(code);
×
510
  }
511
  userCache.verTime = taosGetTimestampMs();
477,634✔
512
  (void)taosThreadRwlockUnlock(&userCache.rw);
477,634✔
513

514
  TAOS_RETURN(code);
477,634✔
515
}
516

517

518

519
int64_t mndGetTimeWhiteListVersion(SMnode *pMnode) {
54,647,865✔
520
  int64_t ver = 0;
54,647,865✔
521
  int32_t code = 0;
54,647,865✔
522

523
  if (mndEnableTimeWhiteList(pMnode) != 0 && tsEnableWhiteList) {
54,647,865✔
524
    (void)taosThreadRwlockWrlock(&userCache.rw);
4,773✔
525

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

537
    (void)taosThreadRwlockUnlock(&userCache.rw);
4,773✔
538
  }
539

540
  mDebug("datetime-white-list on mnode ver: %" PRId64, ver);
54,647,865✔
541
  return ver;
54,647,865✔
542
}
543

544

545

546
int32_t mndInitUser(SMnode *pMnode) {
398,009✔
547
  TAOS_CHECK_RETURN(userCacheInit());
398,009✔
548

549
  SSdbTable table = {
398,009✔
550
      .sdbType = SDB_USER,
551
      .keyType = SDB_KEY_BINARY,
552
      .deployFp = (SdbDeployFp)mndCreateDefaultUsers,
553
      // .redeployFp = (SdbDeployFp)mndCreateDefaultUsers, // TODO: upgrade user table(uid should be created)
554
      .encodeFp = (SdbEncodeFp)mndUserActionEncode,
555
      .decodeFp = (SdbDecodeFp)mndUserActionDecode,
556
      .insertFp = (SdbInsertFp)mndUserActionInsert,
557
      .updateFp = (SdbUpdateFp)mndUserActionUpdate,
558
      .deleteFp = (SdbDeleteFp)mndUserActionDelete,
559
  };
560

561
  mndSetMsgHandle(pMnode, TDMT_MND_CREATE_USER, mndProcessCreateUserReq);
398,009✔
562
  mndSetMsgHandle(pMnode, TDMT_MND_ALTER_USER, mndProcessAlterUserReq);
398,009✔
563
  mndSetMsgHandle(pMnode, TDMT_MND_DROP_USER, mndProcessDropUserReq);
398,009✔
564
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_AUTH, mndProcessGetUserAuthReq);
398,009✔
565

566
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_IP_WHITELIST, mndProcessGetUserIpWhiteListReq);
398,009✔
567
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_IP_WHITELIST_DUAL, mndProcessGetUserIpWhiteListReq);
398,009✔
568
  mndSetMsgHandle(pMnode, TDMT_MND_RETRIEVE_IP_WHITELIST, mndProcessRetrieveIpWhiteListReq);
398,009✔
569
  mndSetMsgHandle(pMnode, TDMT_MND_RETRIEVE_IP_WHITELIST_DUAL, mndProcessRetrieveIpWhiteListReq);
398,009✔
570
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_DATETIME_WHITELIST, mndProcessGetUserDateTimeWhiteListReq);
398,009✔
571
  mndSetMsgHandle(pMnode, TDMT_MND_RETRIEVE_DATETIME_WHITELIST, mndProcessRetrieveDateTimeWhiteListReq);
398,009✔
572

573
  mndSetMsgHandle(pMnode, TDMT_MND_CREATE_TOTP_SECRET, mndProcessCreateTotpSecretReq);
398,009✔
574
  mndSetMsgHandle(pMnode, TDMT_MND_DROP_TOTP_SECRET, mndProcessDropTotpSecretReq);
398,009✔
575

576
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_USER, mndRetrieveUsers);
398,009✔
577
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_USER, mndCancelGetNextUser);
398,009✔
578
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_USER_FULL, mndRetrieveUsersFull);
398,009✔
579
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_USER_FULL, mndCancelGetNextUser);
398,009✔
580
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_PRIVILEGES, mndRetrievePrivileges);
398,009✔
581
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_PRIVILEGES, mndCancelGetNextPrivileges);
398,009✔
582
  return sdbSetTable(pMnode->pSdb, table);
398,009✔
583
}
584

585

586

587
void mndCleanupUser(SMnode *pMnode) {
397,950✔
588
  userCacheCleanup();
397,950✔
589
}
397,950✔
590

591

592

593
static bool isDefaultRange(SIpRange *pRange) {
×
594
  int32_t code = 0;
×
595
  int32_t lino = 0;
×
596

597
  SIpRange range4 = {0};
×
598
  SIpRange range6 = {0};
×
599

600
  code = createDefaultIp4Range(&range4);
×
601
  TSDB_CHECK_CODE(code, lino, _error);
×
602

603
  code = createDefaultIp6Range(&range6);
×
604
  TSDB_CHECK_CODE(code, lino, _error);
×
605

606
  if (isIpRangeEqual(pRange, &range4) || (isIpRangeEqual(pRange, &range6))) {
×
607
    return true;
×
608
  }
609
_error:
×
610
  return false;
×
611
};
612

613

614

615
static int32_t ipRangeListToStr(SIpRange *range, int32_t num, char *buf, int64_t bufLen) {
18,978✔
616
  int32_t len = 0;
18,978✔
617
  for (int i = 0; i < num; i++) {
57,574✔
618
    SIpRange *pRange = &range[i];
38,596✔
619
    SIpAddr   addr = {0};
38,596✔
620
    int32_t code = tIpUintToStr(pRange, &addr);
38,596✔
621
    if (code != 0) {
38,596✔
622
      mError("%s failed to convert ip range to str, code: %d", __func__, code);
×
623
    }
624

625
    len += tsnprintf(buf + len, bufLen - len, "%c%s/%d, ", pRange->neg ? '-' : '+', IP_ADDR_STR(&addr), addr.mask);
38,596✔
626
  }
627
  if (len > 0) buf[len - 2] = 0;
18,978✔
628
  return len;
18,978✔
629
}
630

631

632

633
static bool isIpRangeEqual(SIpRange *a, SIpRange *b) {
1,931,204✔
634
  if (a->type != b->type || a->neg != b->neg) {
1,931,204✔
635
    return false;
×
636
  }
637

638
  if (a->type == 0) {
1,931,204✔
639
    SIpV4Range *a4 = &a->ipV4;
965,762✔
640
    SIpV4Range *b4 = &b->ipV4;
965,762✔
641
    return (a4->ip == b4->ip && a4->mask == b4->mask);
965,762✔
642
  }
643
  
644
  SIpV6Range *a6 = &a->ipV6;
965,442✔
645
  SIpV6Range *b6 = &b->ipV6;
965,442✔
646
  return (a6->addr[0] == b6->addr[0] && a6->addr[1] == b6->addr[1] && a6->mask == b6->mask);
965,442✔
647
}
648

649

650

651
static bool isIpWhiteListEqual(SIpWhiteListDual *a, SIpWhiteListDual *b) {
1,012,939✔
652
  if (a == NULL && b == NULL) {
1,012,939✔
653
    return true;
×
654
  }
655
  
656
  if (a == NULL || b == NULL) {
1,012,939✔
657
    return false;
47,177✔
658
  }
659

660
  if (a->num != b->num) {
965,762✔
661
    return false;
160✔
662
  }
663
  for (int i = 0; i < a->num; i++) {
2,896,806✔
664
    if (!isIpRangeEqual(&a->pIpRanges[i], &b->pIpRanges[i])) {
1,931,204✔
665
      return false;
×
666
    }
667
  }
668
  return true;
965,602✔
669
}
670

671

672
static int32_t compareIpRange(const void *a, const void *b, const void* arg) {
1,760✔
673
  SIpRange *ra = (SIpRange *)a;
1,760✔
674
  SIpRange *rb = (SIpRange *)b;
1,760✔
675

676
  if (ra->neg != rb->neg) {
1,760✔
677
    return (ra->neg) ? -1 : 1;
×
678
  }
679

680
  if (ra->type != rb->type) {
1,760✔
681
    return (ra->type == 0) ? -1 : 1;
×
682
  }
683

684
  if (ra->type == 0) {
1,760✔
685
    if (ra->ipV4.ip != rb->ipV4.ip) {
1,760✔
686
      return (ra->ipV4.ip < rb->ipV4.ip) ? -1 : 1;
1,440✔
687
    }
688
    return (ra->ipV4.mask < rb->ipV4.mask) ? -1 : 1;
320✔
689
  }
690

691
  if (ra->ipV6.addr[0] != rb->ipV6.addr[0]) {
×
692
    return (ra->ipV6.addr[0] < rb->ipV6.addr[0]) ? -1 : 1;
×
693
  }
694
  if (ra->ipV6.addr[1] != rb->ipV6.addr[1]) {
×
695
    return (ra->ipV6.addr[1] < rb->ipV6.addr[1]) ? -1 : 1;
×
696
  }
697
  return (ra->ipV6.mask < rb->ipV6.mask) ? -1 : 1;
×
698
}
699

700
static void sortIpWhiteList(SIpWhiteListDual *pList) {
800✔
701
  (void)taosqsort(pList->pIpRanges, pList->num, sizeof(SIpRange), NULL, compareIpRange);
800✔
702
}
800✔
703

704

705

706
static int32_t convertIpWhiteListToStr(SUserObj *pUser, char **buf) {
18,978✔
707
  SIpWhiteListDual *pList = pUser->pIpWhiteListDual;
18,978✔
708

709
  int64_t bufLen = pList->num * 128 + 8;
18,978✔
710
  *buf = taosMemoryCalloc(1, bufLen);
18,978✔
711
  if (*buf == NULL) {
18,978✔
712
    return 0;
×
713
  }
714

715
  if (pList->num == 0) {
18,978✔
716
    return tsnprintf(*buf, bufLen, "+ALL");
×
717
  }
718

719
  int32_t len = ipRangeListToStr(pList->pIpRanges, pList->num, *buf, bufLen - 2);
18,978✔
720
  if (len == 0) {
18,978✔
721
    taosMemoryFreeClear(*buf);
×
722
    return 0;
×
723
  }
724
  return len;
18,978✔
725
}
726

727

728

729
static int32_t tSerializeIpWhiteList(void *buf, int32_t len, SIpWhiteListDual *pList, uint32_t *pLen) {
2,168,552✔
730
  int32_t  code = 0;
2,168,552✔
731
  int32_t  lino = 0;
2,168,552✔
732
  int32_t  tlen = 0;
2,168,552✔
733
  SEncoder encoder = {0};
2,168,552✔
734
  tEncoderInit(&encoder, buf, len);
2,168,552✔
735

736
  TAOS_CHECK_GOTO(tStartEncode(&encoder), &lino, _OVER);
2,168,552✔
737
  TAOS_CHECK_GOTO(tEncodeI32(&encoder, pList->num), &lino, _OVER);
4,337,104✔
738

739
  for (int i = 0; i < pList->num; i++) {
6,506,136✔
740
    SIpRange *pRange = &(pList->pIpRanges[i]);
4,337,584✔
741
    TAOS_CHECK_GOTO(tSerializeIpRange(&encoder, pRange), &lino, _OVER);
4,337,584✔
742
  }
743

744
  tEndEncode(&encoder);
2,168,552✔
745

746
  tlen = encoder.pos;
2,168,552✔
747
_OVER:
2,168,552✔
748
  tEncoderClear(&encoder);
2,168,552✔
749
  if (code < 0) {
2,168,552✔
750
    mError("failed to serialize ip white list at line %d since %s", lino, tstrerror(code));
×
751
  }
752
  if (pLen) *pLen = tlen;
2,168,552✔
753
  TAOS_RETURN(code);
2,168,552✔
754
}
755

756
static int32_t tDerializeIpWhiteList(void *buf, int32_t len, SIpWhiteListDual *pList, bool supportNeg) {
1,442,122✔
757
  int32_t  code = 0;
1,442,122✔
758
  int32_t  lino = 0;
1,442,122✔
759
  SDecoder decoder = {0};
1,442,122✔
760
  tDecoderInit(&decoder, buf, len);
1,442,122✔
761

762
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
1,442,122✔
763
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &pList->num), &lino, _OVER);
2,884,244✔
764

765
  for (int i = 0; i < pList->num; i++) {
4,326,686✔
766
    SIpRange *pRange = &(pList->pIpRanges[i]);
2,884,564✔
767
    TAOS_CHECK_GOTO(tDeserializeIpRange(&decoder, pRange, supportNeg), &lino, _OVER);
2,884,564✔
768
  }
769

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

779
static int32_t tDerializeIpWhileListFromOldVer(void *buf, int32_t len, SIpWhiteList *pList) {
×
780
  int32_t  code = 0;
×
781
  int32_t  lino = 0;
×
782
  SDecoder decoder = {0};
×
783
  tDecoderInit(&decoder, buf, len);
×
784

785
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
×
786
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &pList->num), &lino, _OVER);
×
787

788
  for (int i = 0; i < pList->num; i++) {
×
789
    SIpV4Range *pIp4 = &(pList->pIpRange[i]);
×
790
    TAOS_CHECK_GOTO(tDecodeU32(&decoder, &pIp4->ip), &lino, _OVER);
×
791
    TAOS_CHECK_GOTO(tDecodeU32(&decoder, &pIp4->mask), &lino, _OVER);
×
792
  }
793

794
_OVER:
×
795
  tEndDecode(&decoder);
×
796
  tDecoderClear(&decoder);
×
797
  if (code < 0) {
×
798
    mError("failed to deserialize ip white list at line %d since %s", lino, tstrerror(code));
×
799
  }
800
  TAOS_RETURN(code);
×
801
}
802

803
static int32_t createIpWhiteList(void *buf, int32_t len, SIpWhiteListDual **ppList, bool supportNeg) {
1,442,122✔
804
  int32_t           code = 0;
1,442,122✔
805
  int32_t           lino = 0;
1,442,122✔
806
  int32_t           num = 0;
1,442,122✔
807
  SIpWhiteListDual *p = NULL;
1,442,122✔
808
  SDecoder          decoder = {0};
1,442,122✔
809
  tDecoderInit(&decoder, buf, len);
1,442,122✔
810

811
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
1,442,122✔
812
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &num), &lino, _OVER);
1,442,122✔
813

814
  p = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + num * sizeof(SIpRange));
1,442,122✔
815
  if (p == NULL) {
1,442,122✔
816
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
817
  }
818
  TAOS_CHECK_GOTO(tDerializeIpWhiteList(buf, len, p, supportNeg), &lino, _OVER);
1,442,122✔
819

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

831
static int32_t createIpWhiteListFromOldVer(void *buf, int32_t len, SIpWhiteList **ppList) {
×
832
  int32_t       code = 0;
×
833
  int32_t       lino = 0;
×
834
  int32_t       num = 0;
×
835
  SIpWhiteList *p = NULL;
×
836
  SDecoder      decoder = {0};
×
837
  tDecoderInit(&decoder, buf, len);
×
838

839
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
×
840
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &num), &lino, _OVER);
×
841

842
  p = taosMemoryCalloc(1, sizeof(SIpWhiteList) + num * sizeof(SIpV4Range));
×
843
  if (p == NULL) {
×
844
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
845
  }
846
  TAOS_CHECK_GOTO(tDerializeIpWhileListFromOldVer(buf, len, p), &lino, _OVER);
×
847

848
_OVER:
×
849
  tEndDecode(&decoder);
×
850
  tDecoderClear(&decoder);
×
851
  if (code < 0) {
×
852
    taosMemoryFreeClear(p);
×
853
    mError("failed to create ip white list at line %d since %s", lino, tstrerror(code));
×
854
  }
855
  *ppList = p;
×
856
  TAOS_RETURN(code);
×
857
}
858

859
static int32_t createDefaultIpWhiteList(SIpWhiteListDual **ppWhiteList) {
329,386✔
860
  int32_t code = 0;
329,386✔
861
  int32_t lino = 0;
329,386✔
862
  *ppWhiteList = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + sizeof(SIpRange) * 2);
329,386✔
863
  if (*ppWhiteList == NULL) {
329,386✔
864
    TAOS_RETURN(terrno);
×
865
  }
866
  (*ppWhiteList)->num = 2;
329,386✔
867

868
  SIpRange v4 = {0};
329,386✔
869
  SIpRange v6 = {0};
329,386✔
870

871
#ifndef TD_ASTRA
872
  code = createDefaultIp4Range(&v4);
329,386✔
873
  TSDB_CHECK_CODE(code, lino, _error);
329,386✔
874

875
  code = createDefaultIp6Range(&v6);
329,386✔
876
  TSDB_CHECK_CODE(code, lino, _error);
329,386✔
877

878
#endif
879

880
_error:
329,386✔
881
  if (code != 0) {
329,386✔
882
    taosMemoryFree(*ppWhiteList);
×
883
    *ppWhiteList = NULL;
×
884
    mError("failed to create default ip white list at line %d since %s", __LINE__, tstrerror(code));
×
885
  } else {
886
    memcpy(&(*ppWhiteList)->pIpRanges[0], &v4, sizeof(SIpRange));
329,386✔
887
    memcpy(&(*ppWhiteList)->pIpRanges[1], &v6, sizeof(SIpRange));
329,386✔
888
  }
889
  return 0;
329,386✔
890
}
891

892

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

895
static int32_t convertTimeRangesToStr(SUserObj *pUser, char **buf) {
18,978✔
896
  int32_t bufLen = pUser->pTimeWhiteList->num * 32 + 8;
18,978✔
897
  *buf = taosMemoryCalloc(1, bufLen);
18,978✔
898
  if (*buf == NULL) {
18,978✔
899
    return 0;
×
900
  }
901

902
  int32_t pos = 0;
18,978✔
903
  if (pUser->pTimeWhiteList->num == 0) {
18,978✔
904
    pos += tsnprintf(*buf + pos, bufLen - pos, "+ALL");
18,978✔
905
    return pos;
18,978✔
906
  }
907

908
  for (int32_t i = 0; i < pUser->pTimeWhiteList->num; i++) {
×
909
    SDateTimeWhiteListItem *range = &pUser->pTimeWhiteList->ranges[i];
×
910
    int duration = range->duration / 60;
×
911

912
    if (range->absolute) {
×
913
      struct STm tm;
×
914
      (void)taosTs2Tm(range->start, TSDB_TIME_PRECISION_SECONDS, &tm, NULL);
×
915
      pos += tsnprintf(*buf + pos, bufLen - pos, "%c%04d-%02d-%02d %02d:%02d %dm, ", range->neg ? '-' : '+', tm.tm.tm_year + 1900, tm.tm.tm_mon + 1, tm.tm.tm_mday, tm.tm.tm_hour, tm.tm.tm_min, duration);
×
916
    } else {
917
      int day = range->start / 86400;
×
918
      int hour = (range->start % 86400) / 3600;
×
919
      int minute = (range->start % 3600) / 60;
×
920
      pos += tsnprintf(*buf + pos, bufLen - pos, "%c%s %02d:%02d %dm, ", range->neg ? '-' : '+', weekdays[day], hour, minute, duration);
×
921
    }
922
  }
923

924
  if (pos > 0) {
×
925
    (*buf)[pos - 2] = 0; // remove last ", "
×
926
  }
927

928
  return pos;
×
929
}
930

931

932
static int32_t compareDateTimeInterval(const void *a, const void *b, const void* arg) {
×
933
  SDateTimeWhiteListItem *pA = (SDateTimeWhiteListItem *)a;
×
934
  SDateTimeWhiteListItem *pB = (SDateTimeWhiteListItem *)b;
×
935

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

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

944
  if (pA->start != pB->start) {
×
945
    return (pA->start < pB->start) ? -1 : 1;
×
946
  }
947

948
  if (pA->duration != pB->duration) {
×
949
    return (pA->duration < pB->duration) ? -1 : 1;
×
950
  }
951

952
  return 0;
×
953
}
954

955
static void sortTimeWhiteList(SDateTimeWhiteList *pList) {
×
956
  (void)taosqsort(pList->ranges, pList->num, sizeof(SDateTimeWhiteListItem), NULL, compareDateTimeInterval);
×
957
}
×
958

959

960

961

962
static void dropOldPasswords(SUserObj *pUser) {
3,610,674✔
963
  if (pUser->numOfPasswords <= pUser->passwordReuseMax) {
3,610,674✔
964
    return;
3,605,804✔
965
  }
966

967
  int32_t reuseMax = pUser->passwordReuseMax;
4,870✔
968
  if (reuseMax == 0) {
4,870✔
969
    reuseMax = 1; // keep at least one password
3,270✔
970
  }
971

972
  int32_t now = taosGetTimestampSec();
4,870✔
973
  int32_t index = reuseMax;
4,870✔
974
  while(index < pUser->numOfPasswords) {
9,350✔
975
    SUserPassword *pPass = &pUser->passwords[index];
4,480✔
976
    if (now - pPass->setTime >= pUser->passwordReuseTime) {
4,480✔
977
      break;
×
978
    }
979
    index++;
4,480✔
980
  }
981

982
  if (index == pUser->numOfPasswords) {
4,870✔
983
    return;
4,870✔
984
  }
985
  pUser->numOfPasswords = index;
×
986
  // this is a shrink operation, no need to check return value
987
  pUser->passwords = taosMemoryRealloc(pUser->passwords, sizeof(SUserPassword) * pUser->numOfPasswords);
×
988
}
989

990

991

992
static int32_t mndCreateDefaultUser(SMnode *pMnode, char *acct, char *user, char *pass) {
282,849✔
993
  int32_t  code = 0;
282,849✔
994
  int32_t  lino = 0;
282,849✔
995
  SUserObj userObj = {0};
282,849✔
996

997
  userObj.passwords = taosMemCalloc(1, sizeof(SUserPassword));
282,849✔
998
  if (userObj.passwords == NULL) {
282,849✔
UNCOV
999
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _ERROR);
×
1000
  }
1001
  taosEncryptPass_c((uint8_t *)pass, strlen(pass), userObj.passwords[0].pass);
282,849✔
1002
  userObj.passwords[0].pass[sizeof(userObj.passwords[0].pass) - 1] = 0;
282,849✔
1003
  if (tsiEncryptPassAlgorithm == DND_CA_SM4 && strlen(tsDbKey) > 0) {
282,849✔
1004
    generateSalt(userObj.salt, sizeof(userObj.salt));
×
UNCOV
1005
    TAOS_CHECK_GOTO(mndEncryptPass(userObj.passwords[0].pass, userObj.salt, &userObj.passEncryptAlgorithm), &lino, _ERROR);
×
1006
  }
1007

1008
  userObj.passwords[0].setTime = taosGetTimestampSec();
282,849✔
1009
  userObj.numOfPasswords = 1;
282,849✔
1010

1011
  tstrncpy(userObj.user, user, TSDB_USER_LEN);
282,849✔
1012
  tstrncpy(userObj.acct, acct, TSDB_USER_LEN);
282,849✔
1013
  userObj.createdTime = taosGetTimestampMs();
282,849✔
1014
  userObj.updateTime = userObj.createdTime;
282,849✔
1015
  userObj.uid = mndGenerateUid(userObj.user, strlen(userObj.user));
282,849✔
1016
  userObj.sysInfo = 1;
282,849✔
1017
  userObj.enable = 1;
282,849✔
1018

1019
#ifdef TD_ENTERPRISE
1020

1021
  // 1: force user to change password
1022
  // 2: allow but not force user to change password
1023
  userObj.changePass = tsAllowDefaultPassword ? 2 : 1;
282,849✔
1024

1025
  userObj.ipWhiteListVer = taosGetTimestampMs();
282,849✔
1026
  userObj.timeWhiteListVer = userObj.ipWhiteListVer;
282,849✔
1027
  userObj.connectTime = TSDB_USER_CONNECT_TIME_DEFAULT;
282,849✔
1028
  userObj.connectIdleTime = TSDB_USER_CONNECT_IDLE_TIME_DEFAULT;
282,849✔
1029
  userObj.callPerSession = TSDB_USER_CALL_PER_SESSION_DEFAULT;
282,849✔
1030
  userObj.vnodePerCall = TSDB_USER_VNODE_PER_CALL_DEFAULT;
282,849✔
1031
  userObj.passwordReuseTime = TSDB_USER_PASSWORD_REUSE_TIME_DEFAULT;
282,849✔
1032
  userObj.passwordReuseMax = TSDB_USER_PASSWORD_REUSE_MAX_DEFAULT;
282,849✔
1033
  userObj.passwordLockTime = TSDB_USER_PASSWORD_LOCK_TIME_DEFAULT;
282,849✔
1034
  userObj.sessionPerUser = TSDB_USER_SESSION_PER_USER_DEFAULT;
282,849✔
1035
  userObj.failedLoginAttempts = TSDB_USER_FAILED_LOGIN_ATTEMPTS_DEFAULT;
282,849✔
1036
  userObj.passwordLifeTime = TSDB_USER_PASSWORD_LIFE_TIME_DEFAULT;
282,849✔
1037
  userObj.passwordGraceTime = TSDB_USER_PASSWORD_GRACE_TIME_DEFAULT;
282,849✔
1038
  userObj.inactiveAccountTime = TSDB_USER_INACTIVE_ACCOUNT_TIME_DEFAULT;
282,849✔
1039
  userObj.allowTokenNum = TSDB_USER_ALLOW_TOKEN_NUM_DEFAULT;
282,849✔
1040
  userObj.tokenNum = 0;
282,849✔
1041

1042
#else // TD_ENTERPRISE
1043

1044
  userObj.ipWhiteListVer = 0;
1045
  userObj.timeWhiteListVer = 0;
1046
  userObj.changePass = 2; // 2: allow but not force user to change password
1047
  userObj.connectTime = -1;
1048
  userObj.connectIdleTime = -1;
1049
  userObj.callPerSession = -1;
1050
  userObj.vnodePerCall = -1;
1051
  userObj.passwordReuseTime = 0;
1052
  userObj.passwordReuseMax = 0;
1053
  userObj.passwordLockTime = -1;
1054
  userObj.sessionPerUser = -1;
1055
  userObj.failedLoginAttempts = -1;
1056
  userObj.passwordLifeTime = -1;
1057
  userObj.passwordGraceTime = -1;
1058
  userObj.inactiveAccountTime = -1;
1059
  userObj.allowTokenNum = -1;
1060
  userObj.tokenNum = 0;
1061

1062
#endif // TD_ENTERPRISE
1063

1064
  userObj.pTimeWhiteList = taosMemoryCalloc(1, sizeof(SDateTimeWhiteList));
282,849✔
1065
  if (userObj.pTimeWhiteList == NULL) {
282,849✔
UNCOV
1066
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _ERROR);
×
1067
  }
1068
  
1069
  TAOS_CHECK_GOTO(createDefaultIpWhiteList(&userObj.pIpWhiteListDual), &lino, _ERROR);
282,849✔
1070
  // if this is the root user, change the value of some fields to allow the user login without restriction
1071
  if (strcmp(user, TSDB_DEFAULT_USER) == 0) {
282,849✔
1072
    userObj.superUser = 1;
282,849✔
1073
    userObj.createdb = 1;
282,849✔
1074
    userObj.sessionPerUser = -1;
282,849✔
1075
    userObj.callPerSession = -1;
282,849✔
1076
    userObj.vnodePerCall = -1;
282,849✔
1077
    userObj.failedLoginAttempts = -1;
282,849✔
1078
    userObj.passwordGraceTime = -1;
282,849✔
1079
    userObj.inactiveAccountTime = -1;
282,849✔
1080
    userObj.allowTokenNum = -1;
282,849✔
1081
  }
1082

1083
  userObj.roles = taosHashInit(1, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
282,849✔
1084
  if (userObj.roles == NULL) {
282,849✔
UNCOV
1085
    TAOS_CHECK_GOTO(terrno, &lino, _ERROR);
×
1086
  }
1087

1088
  if ((code = taosHashPut(userObj.roles, TSDB_ROLE_SYSDBA, strlen(TSDB_ROLE_SYSDBA) + 1, NULL, 0)) ||
565,698✔
1089
      (code = taosHashPut(userObj.roles, TSDB_ROLE_SYSSEC, strlen(TSDB_ROLE_SYSSEC) + 1, NULL, 0)) ||
565,698✔
1090
      (code = taosHashPut(userObj.roles, TSDB_ROLE_SYSAUDIT, strlen(TSDB_ROLE_SYSAUDIT) + 1, NULL, 0))) {
282,849✔
UNCOV
1091
    TAOS_CHECK_GOTO(code, &lino, _ERROR);
×
1092
  }
1093

1094
  SSdbRaw *pRaw = mndUserActionEncode(&userObj);
282,849✔
1095
  if (pRaw == NULL) goto _ERROR;
282,849✔
1096
  TAOS_CHECK_GOTO(sdbSetRawStatus(pRaw, SDB_STATUS_READY), &lino, _ERROR);
282,849✔
1097

1098
  mInfo("user:%s, will be created when deploying, raw:%p", userObj.user, pRaw);
282,849✔
1099

1100
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_ROLE, NULL, "create-user");
282,849✔
1101
  if (pTrans == NULL) {
282,849✔
UNCOV
1102
    sdbFreeRaw(pRaw);
×
UNCOV
1103
    mError("user:%s, failed to create since %s", userObj.user, terrstr());
×
UNCOV
1104
    goto _ERROR;
×
1105
  }
1106
  mInfo("trans:%d, used to create user:%s", pTrans->id, userObj.user);
282,849✔
1107

1108
  if (mndTransAppendCommitlog(pTrans, pRaw) != 0) {
282,849✔
UNCOV
1109
    mError("trans:%d, failed to commit redo log since %s", pTrans->id, terrstr());
×
UNCOV
1110
    mndTransDrop(pTrans);
×
1111
    goto _ERROR;
×
1112
  }
1113
  TAOS_CHECK_GOTO(sdbSetRawStatus(pRaw, SDB_STATUS_READY), &lino, _ERROR);
282,849✔
1114

1115
  if (mndTransPrepare(pMnode, pTrans) != 0) {
282,849✔
UNCOV
1116
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
1117
    mndTransDrop(pTrans);
×
UNCOV
1118
    goto _ERROR;
×
1119
  }
1120

1121
  mndTransDrop(pTrans);
282,849✔
1122
  mndUserFreeObj(&userObj);
282,849✔
1123
  return 0;
282,849✔
1124

UNCOV
1125
_ERROR:
×
UNCOV
1126
  mndUserFreeObj(&userObj);
×
UNCOV
1127
  if (code == 0) {
×
1128
    code = terrno ? terrno : TSDB_CODE_APP_ERROR;
×
1129
  }
1130
  mError("user:%s, failed to create default user since %s", user, tstrerror(code));
×
UNCOV
1131
  TAOS_RETURN(code);
×
1132
}
1133

1134
static int32_t mndCreateDefaultUsers(SMnode *pMnode) {
282,849✔
1135
  return mndCreateDefaultUser(pMnode, TSDB_DEFAULT_USER, TSDB_DEFAULT_USER, TSDB_DEFAULT_PASS);
282,849✔
1136
}
1137

1138
static int32_t tSerializeUserObjExt(void *buf, int32_t bufLen, SUserObj *pObj) {
4,337,104✔
1139
  int32_t  code = 0, lino = 0;
4,337,104✔
1140
  int32_t  tlen = 0;
4,337,104✔
1141
  void    *pIter = NULL;
4,337,104✔
1142
  SEncoder encoder = {0};
4,337,104✔
1143
  tEncoderInit(&encoder, buf, bufLen);
4,337,104✔
1144

1145
  TAOS_CHECK_EXIT(tStartEncode(&encoder));
4,337,104✔
1146
  TAOS_CHECK_EXIT(tEncodeI64v(&encoder, pObj->uid));
8,674,208✔
1147

1148
  TAOS_CHECK_EXIT(tSerializePrivSysObjPolicies(&encoder, &pObj->sysPrivs, pObj->objPrivs));
4,337,104✔
1149

1150
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->selectTbs));
4,337,104✔
1151
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->insertTbs));
4,337,104✔
1152
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->updateTbs));
4,337,104✔
1153
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->deleteTbs));
4,337,104✔
1154

1155
  int32_t nRoles = taosHashGetSize(pObj->roles);
4,337,104✔
1156
  TAOS_CHECK_EXIT(tEncodeI32v(&encoder, nRoles));
4,337,104✔
1157

1158
  while ((pIter = taosHashIterate(pObj->roles, pIter))) {
12,839,780✔
1159
    size_t keyLen = 0;
8,502,676✔
1160
    char  *key = taosHashGetKey(pIter, &keyLen);  // key: role name
8,502,676✔
1161
    TAOS_CHECK_EXIT(tEncodeCStr(&encoder, key));
8,502,676✔
1162

1163
    uint8_t flag = *(int8_t *)pIter;
8,502,676✔
1164
    TAOS_CHECK_EXIT(tEncodeU8(&encoder, flag));  // value: 0 reset, 1 set(default)
17,005,352✔
1165
  }
1166

1167
  tEndEncode(&encoder);
4,337,104✔
1168
  tlen = encoder.pos;
4,337,104✔
1169
_exit:
4,337,104✔
1170
  tEncoderClear(&encoder);
4,337,104✔
1171
  if (code < 0) {
4,337,104✔
UNCOV
1172
    mError("user:%s, %s failed at line %d since %s", pObj->user, __func__, lino, tstrerror(code));
×
UNCOV
1173
    TAOS_RETURN(code);
×
1174
  }
1175

1176
  return tlen;
4,337,104✔
1177
}
1178

1179
static int32_t tDeserializeUserObjExt(void *buf, int32_t bufLen, SUserObj *pObj) {
1,442,122✔
1180
  int32_t  code = 0, lino = 0;
1,442,122✔
1181
  SDecoder decoder = {0};
1,442,122✔
1182
  tDecoderInit(&decoder, buf, bufLen);
1,442,122✔
1183

1184
  TAOS_CHECK_EXIT(tStartDecode(&decoder));
1,442,122✔
1185
  TAOS_CHECK_EXIT(tDecodeI64v(&decoder, &pObj->uid));
2,884,244✔
1186
  TAOS_CHECK_EXIT(tDeserializePrivSysObjPolicies(&decoder, &pObj->sysPrivs, &pObj->objPrivs));
1,442,122✔
1187
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->selectTbs));
1,442,122✔
1188
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->insertTbs));
1,442,122✔
1189
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->updateTbs));
1,442,122✔
1190
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->deleteTbs));
1,442,122✔
1191
  int32_t nRoles = 0;
1,442,122✔
1192
  TAOS_CHECK_EXIT(tDecodeI32v(&decoder, &nRoles));
1,442,122✔
1193
  if (nRoles > 0) {
1,442,122✔
1194
    if (!pObj->roles &&
1,441,962✔
1195
        !(pObj->roles = taosHashInit(nRoles, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), 1, HASH_ENTRY_LOCK))) {
1,441,962✔
UNCOV
1196
      TAOS_CHECK_EXIT(terrno);
×
1197
    }
1198
    for (int32_t i = 0; i < nRoles; i++) {
3,681,832✔
1199
      int32_t keyLen = 0;
2,239,870✔
1200
      char   *key = NULL;
2,239,870✔
1201
      TAOS_CHECK_EXIT(tDecodeCStrAndLen(&decoder, &key, &keyLen));
2,239,870✔
1202
      uint8_t flag = 0;
2,239,870✔
1203
      TAOS_CHECK_EXIT(tDecodeU8(&decoder, &flag));
2,239,870✔
1204
      TAOS_CHECK_EXIT(taosHashPut(pObj->roles, key, keyLen + 1, &flag, sizeof(flag)));
2,239,870✔
1205
    }
1206
  }
1207

1208
_exit:
1,442,122✔
1209
  tEndDecode(&decoder);
1,442,122✔
1210
  tDecoderClear(&decoder);
1,442,122✔
1211
  if (code < 0) {
1,442,122✔
UNCOV
1212
    mError("user, %s failed at line %d since %s, row:%p", __func__, lino, tstrerror(code), pObj);
×
1213
  }
1214
  TAOS_RETURN(code);
1,442,122✔
1215
}
1216

1217
SSdbRaw *mndUserActionEncode(SUserObj *pUser) {
2,168,552✔
1218
  int32_t code = 0;
2,168,552✔
1219
  int32_t lino = 0;
2,168,552✔
1220
  int32_t passReserve = (sizeof(SUserPassword) + 8) * pUser->numOfPasswords + 4;
2,168,552✔
1221
  int32_t ipWhiteReserve = pUser->pIpWhiteListDual ? (sizeof(SIpRange) * pUser->pIpWhiteListDual->num + sizeof(SIpWhiteListDual) + 4) : 16;
2,168,552✔
1222
  int32_t timeWhiteReserve = pUser->pTimeWhiteList ? (sizeof(SDateTimeWhiteListItem) * pUser->pTimeWhiteList->num + sizeof(SDateTimeWhiteList) + 4) : 16;
2,168,552✔
1223
  int32_t numOfReadDbs = 0; //taosHashGetSize(pUser->readDbs);
2,168,552✔
1224
  int32_t numOfWriteDbs = 0; //taosHashGetSize(pUser->writeDbs);
2,168,552✔
1225
  int32_t numOfReadTbs = 0; //taosHashGetSize(pUser->readTbs);
2,168,552✔
1226
  int32_t numOfWriteTbs = 0; //taosHashGetSize(pUser->writeTbs);
2,168,552✔
1227
  int32_t numOfAlterTbs = 0; //taosHashGetSize(pUser->alterTbs);
2,168,552✔
1228
  int32_t numOfReadViews = 0; //taosHashGetSize(pUser->readViews);
2,168,552✔
1229
  int32_t numOfWriteViews = 0; //taosHashGetSize(pUser->writeViews);
2,168,552✔
1230
  int32_t numOfAlterViews = 0; //taosHashGetSize(pUser->alterViews);
2,168,552✔
1231
  int32_t numOfTopics = 0; // taosHashGetSize(pUser->topics);
2,168,552✔
1232
  int32_t numOfUseDbs = 0; // taosHashGetSize(pUser->useDbs);
2,168,552✔
1233
  int32_t numOfRoles = taosHashGetSize(pUser->roles);
2,168,552✔
1234
  int32_t size = sizeof(SUserObj) + USER_RESERVE_SIZE + (numOfReadDbs + numOfWriteDbs) * TSDB_DB_FNAME_LEN +
2,168,552✔
1235
                 numOfTopics * TSDB_TOPIC_FNAME_LEN + ipWhiteReserve + timeWhiteReserve + passReserve;
2,168,552✔
1236
  char    *buf = NULL;
2,168,552✔
1237
  SSdbRaw *pRaw = NULL;
2,168,552✔
1238

1239
  char *stb = NULL;
2,168,552✔
1240
#if 0
1241
  stb = taosHashIterate(pUser->readTbs, NULL);
1242
  while (stb != NULL) {
1243
    size_t keyLen = 0;
1244
    void  *key = taosHashGetKey(stb, &keyLen);
1245
    size += sizeof(int32_t);
1246
    size += keyLen;
1247

1248
    size_t valueLen = 0;
1249
    valueLen = strlen(stb) + 1;
1250
    size += sizeof(int32_t);
1251
    size += valueLen;
1252
    stb = taosHashIterate(pUser->readTbs, stb);
1253
  }
1254

1255
  stb = taosHashIterate(pUser->writeTbs, NULL);
1256
  while (stb != NULL) {
1257
    size_t keyLen = 0;
1258
    void  *key = taosHashGetKey(stb, &keyLen);
1259
    size += sizeof(int32_t);
1260
    size += keyLen;
1261

1262
    size_t valueLen = 0;
1263
    valueLen = strlen(stb) + 1;
1264
    size += sizeof(int32_t);
1265
    size += valueLen;
1266
    stb = taosHashIterate(pUser->writeTbs, stb);
1267
  }
1268
  stb = taosHashIterate(pUser->alterTbs, NULL);
1269
  while (stb != NULL) {
1270
    size_t keyLen = 0;
1271
    void  *key = taosHashGetKey(stb, &keyLen);
1272
    size += sizeof(int32_t);
1273
    size += keyLen;
1274

1275
    size_t valueLen = 0;
1276
    valueLen = strlen(stb) + 1;
1277
    size += sizeof(int32_t);
1278
    size += valueLen;
1279
    stb = taosHashIterate(pUser->alterTbs, stb);
1280
  }
1281

1282
  stb = taosHashIterate(pUser->readViews, NULL);
1283
  while (stb != NULL) {
1284
    size_t keyLen = 0;
1285
    void  *key = taosHashGetKey(stb, &keyLen);
1286
    size += sizeof(int32_t);
1287
    size += keyLen;
1288

1289
    size_t valueLen = 0;
1290
    valueLen = strlen(stb) + 1;
1291
    size += sizeof(int32_t);
1292
    size += valueLen;
1293
    stb = taosHashIterate(pUser->readViews, stb);
1294
  }
1295

1296
  stb = taosHashIterate(pUser->writeViews, NULL);
1297
  while (stb != NULL) {
1298
    size_t keyLen = 0;
1299
    void  *key = taosHashGetKey(stb, &keyLen);
1300
    size += sizeof(int32_t);
1301
    size += keyLen;
1302

1303
    size_t valueLen = 0;
1304
    valueLen = strlen(stb) + 1;
1305
    size += sizeof(int32_t);
1306
    size += valueLen;
1307
    stb = taosHashIterate(pUser->writeViews, stb);
1308
  }
1309

1310
  stb = taosHashIterate(pUser->alterViews, NULL);
1311
  while (stb != NULL) {
1312
    size_t keyLen = 0;
1313
    void  *key = taosHashGetKey(stb, &keyLen);
1314
    size += sizeof(int32_t);
1315
    size += keyLen;
1316

1317
    size_t valueLen = 0;
1318
    valueLen = strlen(stb) + 1;
1319
    size += sizeof(int32_t);
1320
    size += valueLen;
1321
    stb = taosHashIterate(pUser->alterViews, stb);
1322
  }
1323

1324
  int32_t *useDb = taosHashIterate(pUser->useDbs, NULL);
1325
  while (useDb != NULL) {
1326
    size_t keyLen = 0;
1327
    void  *key = taosHashGetKey(useDb, &keyLen);
1328
    size += sizeof(int32_t);
1329
    size += keyLen;
1330
    size += sizeof(int32_t);
1331
    useDb = taosHashIterate(pUser->useDbs, useDb);
1332
  }
1333
#endif
1334
  int32_t sizeExt = tSerializeUserObjExt(NULL, 0, pUser);
2,168,552✔
1335
  if (sizeExt < 0) {
2,168,552✔
UNCOV
1336
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1337
  }
1338
  size += sizeExt;
2,168,552✔
1339

1340
  pRaw = sdbAllocRaw(SDB_USER, USER_VER_NUMBER, size);
2,168,552✔
1341
  if (pRaw == NULL) {
2,168,552✔
UNCOV
1342
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1343
  }
1344

1345
  int32_t dataPos = 0;
2,168,552✔
1346
  SDB_SET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN, _OVER)
2,168,552✔
1347

1348
  dropOldPasswords(pUser);
2,168,552✔
1349
  SDB_SET_INT32(pRaw, dataPos, pUser->numOfPasswords, _OVER)
2,168,552✔
1350
  for (int32_t i = 0; i < pUser->numOfPasswords; i++) {
4,348,804✔
1351
    SDB_SET_BINARY(pRaw, dataPos, pUser->passwords[i].pass, sizeof(pUser->passwords[i].pass), _OVER)
2,180,252✔
1352
    SDB_SET_INT32(pRaw, dataPos, pUser->passwords[i].setTime, _OVER)
2,180,252✔
1353
  }
1354
  SDB_SET_BINARY(pRaw, dataPos, pUser->salt, sizeof(pUser->salt), _OVER)
2,168,552✔
1355

1356
  SDB_SET_BINARY(pRaw, dataPos, pUser->acct, TSDB_USER_LEN, _OVER)
2,168,552✔
1357
  SDB_SET_INT64(pRaw, dataPos, pUser->createdTime, _OVER)
2,168,552✔
1358
  SDB_SET_INT64(pRaw, dataPos, pUser->updateTime, _OVER)
2,168,552✔
1359
  SDB_SET_INT8(pRaw, dataPos, pUser->superUser, _OVER)
2,168,552✔
1360
  SDB_SET_INT8(pRaw, dataPos, pUser->sysInfo, _OVER)
2,168,552✔
1361
  SDB_SET_INT8(pRaw, dataPos, pUser->enable, _OVER)
2,168,552✔
1362
  SDB_SET_UINT8(pRaw, dataPos, pUser->flag, _OVER)
2,168,552✔
1363
  SDB_SET_INT32(pRaw, dataPos, pUser->authVersion, _OVER)
2,168,552✔
1364
  SDB_SET_INT32(pRaw, dataPos, pUser->passVersion, _OVER)
2,168,552✔
1365
  SDB_SET_INT32(pRaw, dataPos, numOfReadDbs, _OVER)
2,168,552✔
1366
  SDB_SET_INT32(pRaw, dataPos, numOfWriteDbs, _OVER)
2,168,552✔
1367
  SDB_SET_INT32(pRaw, dataPos, numOfTopics, _OVER)
2,168,552✔
1368
#if 0
1369
  char *db = taosHashIterate(pUser->readDbs, NULL);
1370
  while (db != NULL) {
1371
    SDB_SET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER);
1372
    db = taosHashIterate(pUser->readDbs, db);
1373
  }
1374

1375
  db = taosHashIterate(pUser->writeDbs, NULL);
1376
  while (db != NULL) {
1377
    SDB_SET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER);
1378
    db = taosHashIterate(pUser->writeDbs, db);
1379
  }
1380
  char *topic = taosHashIterate(pUser->topics, NULL);
1381
  while (topic != NULL) {
1382
    SDB_SET_BINARY(pRaw, dataPos, topic, TSDB_TOPIC_FNAME_LEN, _OVER);
1383
    topic = taosHashIterate(pUser->topics, topic);
1384
  }
1385
#endif
1386
  SDB_SET_INT32(pRaw, dataPos, numOfReadTbs, _OVER)
2,168,552✔
1387
  SDB_SET_INT32(pRaw, dataPos, numOfWriteTbs, _OVER)
2,168,552✔
1388
  SDB_SET_INT32(pRaw, dataPos, numOfAlterTbs, _OVER)
2,168,552✔
1389
  SDB_SET_INT32(pRaw, dataPos, numOfReadViews, _OVER)
2,168,552✔
1390
  SDB_SET_INT32(pRaw, dataPos, numOfWriteViews, _OVER)
2,168,552✔
1391
  SDB_SET_INT32(pRaw, dataPos, numOfAlterViews, _OVER)
2,168,552✔
1392
  SDB_SET_INT32(pRaw, dataPos, numOfUseDbs, _OVER)
2,168,552✔
1393

1394
#if 0
1395
  stb = taosHashIterate(pUser->readTbs, NULL);
1396
  while (stb != NULL) {
1397
    size_t keyLen = 0;
1398
    void  *key = taosHashGetKey(stb, &keyLen);
1399
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1400
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1401

1402
    size_t valueLen = 0;
1403
    valueLen = strlen(stb) + 1;
1404
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
1405
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
1406
    stb = taosHashIterate(pUser->readTbs, stb);
1407
  }
1408

1409
  stb = taosHashIterate(pUser->writeTbs, NULL);
1410
  while (stb != NULL) {
1411
    size_t keyLen = 0;
1412
    void  *key = taosHashGetKey(stb, &keyLen);
1413
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1414
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1415

1416
    size_t valueLen = 0;
1417
    valueLen = strlen(stb) + 1;
1418
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
1419
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
1420
    stb = taosHashIterate(pUser->writeTbs, stb);
1421
  }
1422
  stb = taosHashIterate(pUser->alterTbs, NULL);
1423
  while (stb != NULL) {
1424
    size_t keyLen = 0;
1425
    void  *key = taosHashGetKey(stb, &keyLen);
1426
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1427
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1428

1429
    size_t valueLen = 0;
1430
    valueLen = strlen(stb) + 1;
1431
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
1432
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
1433
    stb = taosHashIterate(pUser->alterTbs, stb);
1434
  }
1435

1436
  stb = taosHashIterate(pUser->readViews, NULL);
1437
  while (stb != NULL) {
1438
    size_t keyLen = 0;
1439
    void  *key = taosHashGetKey(stb, &keyLen);
1440
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1441
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1442

1443
    size_t valueLen = 0;
1444
    valueLen = strlen(stb) + 1;
1445
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
1446
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
1447
    stb = taosHashIterate(pUser->readViews, stb);
1448
  }
1449

1450
  stb = taosHashIterate(pUser->writeViews, NULL);
1451
  while (stb != NULL) {
1452
    size_t keyLen = 0;
1453
    void  *key = taosHashGetKey(stb, &keyLen);
1454
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1455
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1456

1457
    size_t valueLen = 0;
1458
    valueLen = strlen(stb) + 1;
1459
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
1460
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
1461
    stb = taosHashIterate(pUser->writeViews, stb);
1462
  }
1463

1464
  stb = taosHashIterate(pUser->alterViews, NULL);
1465
  while (stb != NULL) {
1466
    size_t keyLen = 0;
1467
    void  *key = taosHashGetKey(stb, &keyLen);
1468
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1469
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1470

1471
    size_t valueLen = 0;
1472
    valueLen = strlen(stb) + 1;
1473
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
1474
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
1475
    stb = taosHashIterate(pUser->alterViews, stb);
1476
  }
1477

1478
  useDb = taosHashIterate(pUser->useDbs, NULL);
1479
  while (useDb != NULL) {
1480
    size_t keyLen = 0;
1481
    void  *key = taosHashGetKey(useDb, &keyLen);
1482
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1483
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1484

1485
    SDB_SET_INT32(pRaw, dataPos, *useDb, _OVER)
1486
    useDb = taosHashIterate(pUser->useDbs, useDb);
1487
  }
1488
#endif
1489
  // save white list
1490
  int32_t num = pUser->pIpWhiteListDual->num;
2,168,552✔
1491
  int32_t tlen = sizeof(SIpWhiteListDual) + num * sizeof(SIpRange) + 4;
2,168,552✔
1492
  int32_t maxBufLen = TMAX(tlen, sizeExt);
2,168,552✔
1493
  if ((buf = taosMemoryCalloc(1, maxBufLen)) == NULL) {
2,168,552✔
UNCOV
1494
    TAOS_CHECK_GOTO(terrno, NULL, _OVER);
×
1495
  }
1496
  int32_t len = 0;
2,168,552✔
1497
  TAOS_CHECK_GOTO(tSerializeIpWhiteList(buf, tlen, pUser->pIpWhiteListDual, &len), &lino, _OVER);
2,168,552✔
1498

1499
  SDB_SET_INT32(pRaw, dataPos, len, _OVER);
2,168,552✔
1500
  SDB_SET_BINARY(pRaw, dataPos, buf, len, _OVER);
2,168,552✔
1501

1502
  SDB_SET_INT64(pRaw, dataPos, pUser->ipWhiteListVer, _OVER);
2,168,552✔
1503
  SDB_SET_INT8(pRaw, dataPos, pUser->passEncryptAlgorithm, _OVER);
2,168,552✔
1504

1505
  SDB_SET_BINARY(pRaw, dataPos, pUser->totpsecret, sizeof(pUser->totpsecret), _OVER);
2,168,552✔
1506
  SDB_SET_INT8(pRaw, dataPos, pUser->changePass, _OVER);
2,168,552✔
1507
  SDB_SET_INT32(pRaw, dataPos, pUser->sessionPerUser, _OVER);
2,168,552✔
1508
  SDB_SET_INT32(pRaw, dataPos, pUser->connectTime, _OVER);
2,168,552✔
1509
  SDB_SET_INT32(pRaw, dataPos, pUser->connectIdleTime, _OVER);
2,168,552✔
1510
  SDB_SET_INT32(pRaw, dataPos, pUser->callPerSession, _OVER);
2,168,552✔
1511
  SDB_SET_INT32(pRaw, dataPos, pUser->vnodePerCall, _OVER);
2,168,552✔
1512
  SDB_SET_INT32(pRaw, dataPos, pUser->failedLoginAttempts, _OVER);
2,168,552✔
1513
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordLifeTime, _OVER);
2,168,552✔
1514
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordReuseTime, _OVER);
2,168,552✔
1515
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordReuseMax, _OVER);
2,168,552✔
1516
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordLockTime, _OVER);
2,168,552✔
1517
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordGraceTime, _OVER);
2,168,552✔
1518
  SDB_SET_INT32(pRaw, dataPos, pUser->inactiveAccountTime, _OVER);
2,168,552✔
1519
  SDB_SET_INT32(pRaw, dataPos, pUser->allowTokenNum, _OVER);
2,168,552✔
1520
  SDB_SET_INT32(pRaw, dataPos, pUser->tokenNum, _OVER);
2,168,552✔
1521

1522
  SDB_SET_INT32(pRaw, dataPos, pUser->pTimeWhiteList->num, _OVER);
2,168,552✔
1523
  for (int32_t i = 0; i < pUser->pTimeWhiteList->num; i++) {
2,168,552✔
UNCOV
1524
    SDateTimeWhiteListItem *range = &pUser->pTimeWhiteList->ranges[i];
×
UNCOV
1525
    SDB_SET_BOOL(pRaw, dataPos, range->absolute, _OVER);
×
UNCOV
1526
    SDB_SET_BOOL(pRaw, dataPos, range->neg, _OVER);
×
UNCOV
1527
    SDB_SET_INT64(pRaw, dataPos, range->start, _OVER);
×
UNCOV
1528
    SDB_SET_INT32(pRaw, dataPos, range->duration, _OVER);
×
1529
  }
1530

1531
  sizeExt = tSerializeUserObjExt(buf, sizeExt, pUser);
2,168,552✔
1532
  if (sizeExt < 0) {
2,168,552✔
UNCOV
1533
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1534
  }
1535
  SDB_SET_INT32(pRaw, dataPos, sizeExt, _OVER);
2,168,552✔
1536
  SDB_SET_BINARY(pRaw, dataPos, buf, sizeExt, _OVER);
2,168,552✔
1537

1538
  SDB_SET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
2,168,552✔
1539

1540
  SDB_SET_DATALEN(pRaw, dataPos, _OVER)
2,168,552✔
1541

1542
_OVER:
2,168,552✔
1543
  taosMemoryFree(buf);
2,168,552✔
1544
  if (code < 0) {
2,168,552✔
UNCOV
1545
    mError("user:%s, failed to encode user action to raw:%p at line %d since %s", pUser->user, pRaw, lino,
×
1546
           tstrerror(code));
UNCOV
1547
    sdbFreeRaw(pRaw);
×
UNCOV
1548
    pRaw = NULL;
×
UNCOV
1549
    terrno = code;
×
1550
  }
1551

1552
  mTrace("user:%s, encode user action to raw:%p, row:%p", pUser->user, pRaw, pUser);
2,168,552✔
1553
  return pRaw;
2,168,552✔
1554
}
1555

1556
static SSdbRow *mndUserActionDecode(SSdbRaw *pRaw) {
1,442,122✔
1557
  int32_t   code = 0;
1,442,122✔
1558
  int32_t   lino = 0;
1,442,122✔
1559
  SSdbRow  *pRow = NULL;
1,442,122✔
1560
  SUserObj *pUser = NULL;
1,442,122✔
1561
  char     *key = NULL;
1,442,122✔
1562
  char     *value = NULL;
1,442,122✔
1563

1564
  SHashObj *pReadDbs = NULL;
1,442,122✔
1565
  SHashObj *pWriteDbs = NULL;
1,442,122✔
1566
  SHashObj *pReadTbs = NULL;
1,442,122✔
1567
  SHashObj *pWriteTbs = NULL;
1,442,122✔
1568
  SHashObj *pTopics = NULL;
1,442,122✔
1569
  SHashObj *pAlterTbs = NULL;
1,442,122✔
1570
  SHashObj *pReadViews = NULL;
1,442,122✔
1571
  SHashObj *pWriteViews = NULL;
1,442,122✔
1572
  SHashObj *pAlterViews = NULL;
1,442,122✔
1573
  SHashObj *pUseDbs = NULL;
1,442,122✔
1574

1575
  int8_t sver = 0;
1,442,122✔
1576
  if (sdbGetRawSoftVer(pRaw, &sver) != 0) {
1,442,122✔
UNCOV
1577
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_PTR, &lino, _OVER);
×
1578
  }
1579

1580
  if (sver < 1 || sver > USER_VER_NUMBER) {
1,442,122✔
UNCOV
1581
    TAOS_CHECK_GOTO(TSDB_CODE_SDB_INVALID_DATA_VER, &lino, _OVER);
×
1582
  }
1583

1584
  pRow = sdbAllocRow(sizeof(SUserObj));
1,442,122✔
1585
  if (pRow == NULL) {
1,442,122✔
UNCOV
1586
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1587
  }
1588

1589
  pUser = sdbGetRowObj(pRow);
1,442,122✔
1590
  if (pUser == NULL) {
1,442,122✔
UNCOV
1591
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1592
  }
1593

1594
  int32_t dataPos = 0;
1,442,122✔
1595
  SDB_GET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN, _OVER)
1,442,122✔
1596

1597
  if (sver < USER_VER_SUPPORT_ADVANCED_SECURITY) {
1,442,122✔
UNCOV
1598
    pUser->passwords = taosMemoryCalloc(1, sizeof(SUserPassword));
×
UNCOV
1599
    if (pUser->passwords == NULL) {
×
UNCOV
1600
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
1601
    }
UNCOV
1602
    SDB_GET_BINARY(pRaw, dataPos, pUser->passwords[0].pass, TSDB_PASSWORD_LEN, _OVER)
×
1603
    pUser->numOfPasswords = 1;
×
UNCOV
1604
    memset(pUser->salt, 0, sizeof(pUser->salt));
×
1605
  } else {
1606
    SDB_GET_INT32(pRaw, dataPos, &pUser->numOfPasswords, _OVER)
1,442,122✔
1607
    pUser->passwords = taosMemoryCalloc(pUser->numOfPasswords, sizeof(SUserPassword));
1,442,122✔
1608
    if (pUser->passwords == NULL) {
1,442,122✔
UNCOV
1609
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
1610
    }
1611
    for (int32_t i = 0; i < pUser->numOfPasswords; ++i) {
2,901,364✔
1612
      SDB_GET_BINARY(pRaw, dataPos, pUser->passwords[i].pass, sizeof(pUser->passwords[i].pass), _OVER);
1,459,242✔
1613
      SDB_GET_INT32(pRaw, dataPos, &pUser->passwords[i].setTime, _OVER);
1,459,242✔
1614
    }
1615
    SDB_GET_BINARY(pRaw, dataPos, pUser->salt, sizeof(pUser->salt), _OVER)
1,442,122✔
1616
  }
1617
  
1618
  SDB_GET_BINARY(pRaw, dataPos, pUser->acct, TSDB_USER_LEN, _OVER)
1,442,122✔
1619
  SDB_GET_INT64(pRaw, dataPos, &pUser->createdTime, _OVER)
1,442,122✔
1620
  SDB_GET_INT64(pRaw, dataPos, &pUser->updateTime, _OVER)
1,442,122✔
1621
  if (sver < USER_VER_SUPPORT_ADVANCED_SECURITY) {
1,442,122✔
UNCOV
1622
    pUser->passwords[0].setTime = (int32_t)(pUser->updateTime / 1000);
×
1623
  }
1624

1625
  SDB_GET_INT8(pRaw, dataPos, &pUser->superUser, _OVER)
1,442,122✔
1626
  SDB_GET_INT8(pRaw, dataPos, &pUser->sysInfo, _OVER)
1,442,122✔
1627
  SDB_GET_INT8(pRaw, dataPos, &pUser->enable, _OVER)
1,442,122✔
1628
  SDB_GET_UINT8(pRaw, dataPos, &pUser->flag, _OVER)
1,442,122✔
1629
  if (pUser->superUser) pUser->createdb = 1;
1,442,122✔
1630
  SDB_GET_INT32(pRaw, dataPos, &pUser->authVersion, _OVER)
1,442,122✔
1631
  if (sver >= 4) {
1,442,122✔
1632
    SDB_GET_INT32(pRaw, dataPos, &pUser->passVersion, _OVER)
1,442,122✔
1633
  }
1634

1635
  int32_t numOfReadDbs = 0;
1,442,122✔
1636
  int32_t numOfWriteDbs = 0;
1,442,122✔
1637
  int32_t numOfTopics = 0;
1,442,122✔
1638
  SDB_GET_INT32(pRaw, dataPos, &numOfReadDbs, _OVER)
1,442,122✔
1639
  SDB_GET_INT32(pRaw, dataPos, &numOfWriteDbs, _OVER)
1,442,122✔
1640
  if (sver >= 2) {
1,442,122✔
1641
    SDB_GET_INT32(pRaw, dataPos, &numOfTopics, _OVER)
1,442,122✔
1642
  }
1643

1644
  if (numOfReadDbs > 0) {
1,442,122✔
UNCOV
1645
    pReadDbs = taosHashInit(numOfReadDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
UNCOV
1646
    if (pReadDbs == NULL) {
×
UNCOV
1647
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1648
    }
1649
  }
1650
  if (numOfWriteDbs > 0) {
1,442,122✔
UNCOV
1651
    pWriteDbs = taosHashInit(numOfWriteDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
UNCOV
1652
    if (pWriteDbs == NULL) {
×
UNCOV
1653
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1654
    }
1655
  }
1656
  if (numOfTopics > 0) {
1,442,122✔
UNCOV
1657
    pTopics = taosHashInit(numOfTopics, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
UNCOV
1658
    if (pTopics == NULL) {
×
UNCOV
1659
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1660
    }
1661
  }
1662
  for (int32_t i = 0; i < numOfReadDbs; ++i) {
1,442,122✔
UNCOV
1663
    char db[TSDB_DB_FNAME_LEN] = {0};
×
UNCOV
1664
    SDB_GET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER)
×
UNCOV
1665
    int32_t len = strlen(db) + 1;
×
UNCOV
1666
    TAOS_CHECK_GOTO(taosHashPut(pReadDbs, db, len, db, TSDB_DB_FNAME_LEN), &lino, _OVER);
×
1667
  }
1668

1669
  for (int32_t i = 0; i < numOfWriteDbs; ++i) {
1,442,122✔
UNCOV
1670
    char db[TSDB_DB_FNAME_LEN] = {0};
×
1671
    SDB_GET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER)
×
1672
    int32_t len = strlen(db) + 1;
×
1673
    TAOS_CHECK_GOTO(taosHashPut(pWriteDbs, db, len, db, TSDB_DB_FNAME_LEN), &lino, _OVER);
×
1674
  }
1675

1676
  if (sver >= 2) {
1,442,122✔
1677
    for (int32_t i = 0; i < numOfTopics; ++i) {
1,442,122✔
1678
      char topic[TSDB_TOPIC_FNAME_LEN] = {0};
×
1679
      SDB_GET_BINARY(pRaw, dataPos, topic, TSDB_TOPIC_FNAME_LEN, _OVER)
×
UNCOV
1680
      int32_t len = strlen(topic) + 1;
×
UNCOV
1681
      TAOS_CHECK_GOTO(taosHashPut(pTopics, topic, len, topic, TSDB_TOPIC_FNAME_LEN), &lino, _OVER);
×
1682
    }
1683
  }
1684

1685
  if (sver >= 3) {
1,442,122✔
1686
    int32_t numOfReadTbs = 0;
1,442,122✔
1687
    int32_t numOfWriteTbs = 0;
1,442,122✔
1688
    int32_t numOfAlterTbs = 0;
1,442,122✔
1689
    int32_t numOfReadViews = 0;
1,442,122✔
1690
    int32_t numOfWriteViews = 0;
1,442,122✔
1691
    int32_t numOfAlterViews = 0;
1,442,122✔
1692
    int32_t numOfUseDbs = 0;
1,442,122✔
1693
    SDB_GET_INT32(pRaw, dataPos, &numOfReadTbs, _OVER)
1,442,122✔
1694
    SDB_GET_INT32(pRaw, dataPos, &numOfWriteTbs, _OVER)
1,442,122✔
1695
    if (sver >= 6) {
1,442,122✔
1696
      SDB_GET_INT32(pRaw, dataPos, &numOfAlterTbs, _OVER)
1,442,122✔
1697
      SDB_GET_INT32(pRaw, dataPos, &numOfReadViews, _OVER)
1,442,122✔
1698
      SDB_GET_INT32(pRaw, dataPos, &numOfWriteViews, _OVER)
1,442,122✔
1699
      SDB_GET_INT32(pRaw, dataPos, &numOfAlterViews, _OVER)
1,442,122✔
1700
    }
1701
    SDB_GET_INT32(pRaw, dataPos, &numOfUseDbs, _OVER)
1,442,122✔
1702

1703
    if (numOfReadTbs > 0) {
1,442,122✔
1704
      pReadTbs = taosHashInit(numOfReadTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
1705
      if (pReadTbs == NULL) {
×
1706
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1707
      }
1708
    }
1709
    if (numOfWriteTbs > 0) {
1,442,122✔
UNCOV
1710
      pWriteTbs = taosHashInit(numOfWriteTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
UNCOV
1711
      if (pWriteTbs == NULL) {
×
UNCOV
1712
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1713
      }
1714
    }
1715
    pAlterTbs = taosHashInit(numOfAlterTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,442,122✔
1716
    pReadViews = taosHashInit(numOfReadViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,442,122✔
1717
    pWriteViews =
1718
        taosHashInit(numOfWriteViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,442,122✔
1719
    pAlterViews =
1720
        taosHashInit(numOfAlterViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,442,122✔
1721
    pUseDbs = taosHashInit(numOfUseDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,442,122✔
1722

1723
    if (pAlterTbs == NULL || pReadViews == NULL || pWriteViews == NULL || pAlterViews == NULL || pUseDbs == NULL) {
1,442,122✔
UNCOV
1724
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
UNCOV
1725
      goto _OVER;
×
1726
    }
1727

1728
    for (int32_t i = 0; i < numOfReadTbs; ++i) {
1,442,122✔
UNCOV
1729
      int32_t keyLen = 0;
×
1730
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
1731

1732
      TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
UNCOV
1733
      if (key == NULL) {
×
UNCOV
1734
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1735
      }
1736
      (void)memset(key, 0, keyLen);
×
1737
      SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
1738

UNCOV
1739
      int32_t valuelen = 0;
×
UNCOV
1740
      SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
UNCOV
1741
      TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
UNCOV
1742
      if (value == NULL) {
×
UNCOV
1743
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1744
      }
UNCOV
1745
      (void)memset(value, 0, valuelen);
×
UNCOV
1746
      SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
1747

UNCOV
1748
      TAOS_CHECK_GOTO(taosHashPut(pReadTbs, key, keyLen, value, valuelen), &lino, _OVER);
×
1749
    }
1750

1751
    for (int32_t i = 0; i < numOfWriteTbs; ++i) {
1,442,122✔
UNCOV
1752
      int32_t keyLen = 0;
×
UNCOV
1753
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
1754

1755
      TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
1756
      if (key == NULL) {
×
UNCOV
1757
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1758
      }
1759
      (void)memset(key, 0, keyLen);
×
1760
      SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
1761

1762
      int32_t valuelen = 0;
×
1763
      SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
UNCOV
1764
      TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
1765
      if (value == NULL) {
×
1766
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1767
      }
1768
      (void)memset(value, 0, valuelen);
×
1769
      SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
1770

1771
      TAOS_CHECK_GOTO(taosHashPut(pWriteTbs, key, keyLen, value, valuelen), &lino, _OVER);
×
1772
    }
1773

1774
    if (sver >= 6) {
1,442,122✔
1775
      for (int32_t i = 0; i < numOfAlterTbs; ++i) {
1,442,122✔
UNCOV
1776
        int32_t keyLen = 0;
×
UNCOV
1777
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
1778

1779
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
UNCOV
1780
        if (key == NULL) {
×
1781
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1782
        }
1783
        (void)memset(key, 0, keyLen);
×
UNCOV
1784
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
1785

1786
        int32_t valuelen = 0;
×
UNCOV
1787
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
1788
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
1789
        if (value == NULL) {
×
1790
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1791
        }
1792
        (void)memset(value, 0, valuelen);
×
UNCOV
1793
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
1794

1795
        TAOS_CHECK_GOTO(taosHashPut(pAlterTbs, key, keyLen, value, valuelen), &lino, _OVER);
×
1796
      }
1797

1798
      for (int32_t i = 0; i < numOfReadViews; ++i) {
1,442,122✔
UNCOV
1799
        int32_t keyLen = 0;
×
UNCOV
1800
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
1801

1802
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
1803
        if (key == NULL) {
×
UNCOV
1804
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1805
        }
1806
        (void)memset(key, 0, keyLen);
×
1807
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
1808

1809
        int32_t valuelen = 0;
×
1810
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
UNCOV
1811
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
1812
        if (value == NULL) {
×
1813
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1814
        }
1815
        (void)memset(value, 0, valuelen);
×
1816
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
1817

1818
        TAOS_CHECK_GOTO(taosHashPut(pReadViews, key, keyLen, value, valuelen), &lino, _OVER);
×
1819
      }
1820

1821
      for (int32_t i = 0; i < numOfWriteViews; ++i) {
1,442,122✔
UNCOV
1822
        int32_t keyLen = 0;
×
UNCOV
1823
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
1824

1825
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
1826
        if (key == NULL) {
×
UNCOV
1827
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1828
        }
1829
        (void)memset(key, 0, keyLen);
×
1830
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
1831

1832
        int32_t valuelen = 0;
×
1833
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
UNCOV
1834
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
1835
        if (value == NULL) {
×
1836
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1837
        }
1838
        (void)memset(value, 0, valuelen);
×
1839
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
1840

1841
        TAOS_CHECK_GOTO(taosHashPut(pWriteViews, key, keyLen, value, valuelen), &lino, _OVER);
×
1842
      }
1843

1844
      for (int32_t i = 0; i < numOfAlterViews; ++i) {
1,442,122✔
UNCOV
1845
        int32_t keyLen = 0;
×
UNCOV
1846
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
1847

1848
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
1849
        if (key == NULL) {
×
UNCOV
1850
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1851
        }
1852
        (void)memset(key, 0, keyLen);
×
1853
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
1854

1855
        int32_t valuelen = 0;
×
1856
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
UNCOV
1857
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
1858
        if (value == NULL) {
×
1859
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1860
        }
1861
        (void)memset(value, 0, valuelen);
×
1862
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
1863

1864
        TAOS_CHECK_GOTO(taosHashPut(pAlterViews, key, keyLen, value, valuelen), &lino, _OVER);
×
1865
      }
1866
    }
1867

1868
    for (int32_t i = 0; i < numOfUseDbs; ++i) {
1,442,122✔
UNCOV
1869
      int32_t keyLen = 0;
×
UNCOV
1870
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
1871

1872
      TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
UNCOV
1873
      if (key == NULL) {
×
1874
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1875
      }
1876
      (void)memset(key, 0, keyLen);
×
UNCOV
1877
      SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
1878

1879
      int32_t ref = 0;
×
UNCOV
1880
      SDB_GET_INT32(pRaw, dataPos, &ref, _OVER);
×
1881

1882
      TAOS_CHECK_GOTO(taosHashPut(pUseDbs, key, keyLen, &ref, sizeof(ref)), &lino, _OVER);
×
1883
    }
1884
  }
1885
  // decoder white list
1886
  if (sver >= USER_VER_SUPPORT_WHITELIST) {
1,442,122✔
1887
    if (sver < USER_VER_SUPPORT_WHITELIT_DUAL_STACK) {
1,442,122✔
1888
      int32_t len = 0;
×
UNCOV
1889
      SDB_GET_INT32(pRaw, dataPos, &len, _OVER);
×
1890

UNCOV
1891
      TAOS_MEMORY_REALLOC(key, len);
×
UNCOV
1892
      if (key == NULL) {
×
UNCOV
1893
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1894
      }
1895
      SDB_GET_BINARY(pRaw, dataPos, key, len, _OVER);
×
1896

UNCOV
1897
      SIpWhiteList *pIpWhiteList = NULL;
×
1898
      TAOS_CHECK_GOTO(createIpWhiteListFromOldVer(key, len, &pIpWhiteList), &lino, _OVER);
×
1899

1900
      SDB_GET_INT64(pRaw, dataPos, &pUser->ipWhiteListVer, _OVER);
×
1901

1902
      code = cvtIpWhiteListToDual(pIpWhiteList, &pUser->pIpWhiteListDual);
×
1903
      if (code != 0) {
×
UNCOV
1904
        taosMemoryFreeClear(pIpWhiteList);
×
1905
      }
1906
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
1907

1908
      taosMemoryFreeClear(pIpWhiteList);
×
1909

1910
    } else if (sver >= USER_VER_SUPPORT_WHITELIT_DUAL_STACK) {
1,442,122✔
1911
      int32_t len = 0;
1,442,122✔
1912
      SDB_GET_INT32(pRaw, dataPos, &len, _OVER);
1,442,122✔
1913

1914
      TAOS_MEMORY_REALLOC(key, len);
1,442,122✔
1915
      if (key == NULL) {
1,442,122✔
UNCOV
1916
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1917
      }
1918
      SDB_GET_BINARY(pRaw, dataPos, key, len, _OVER);
1,442,122✔
1919

1920
      TAOS_CHECK_GOTO(createIpWhiteList(key, len, &pUser->pIpWhiteListDual, sver >= USER_VER_SUPPORT_ADVANCED_SECURITY), &lino, _OVER);
1,442,122✔
1921
      SDB_GET_INT64(pRaw, dataPos, &pUser->ipWhiteListVer, _OVER);
1,442,122✔
1922
    }
1923
  }
1924

1925
  if (pUser->pIpWhiteListDual == NULL) {
1,442,122✔
1926
    TAOS_CHECK_GOTO(createDefaultIpWhiteList(&pUser->pIpWhiteListDual), &lino, _OVER);
×
UNCOV
1927
    pUser->ipWhiteListVer = taosGetTimestampMs();
×
1928
  }
1929

1930
  SDB_GET_INT8(pRaw, dataPos, &pUser->passEncryptAlgorithm, _OVER);
1,442,122✔
1931

1932
  if (sver < USER_VER_SUPPORT_ADVANCED_SECURITY) {
1,442,122✔
UNCOV
1933
    memset(pUser->totpsecret, 0, sizeof(pUser->totpsecret));
×
1934
    pUser->changePass = 2;
×
UNCOV
1935
    pUser->sessionPerUser = pUser->superUser ? -1 : TSDB_USER_SESSION_PER_USER_DEFAULT;
×
UNCOV
1936
    pUser->connectTime = TSDB_USER_CONNECT_TIME_DEFAULT;
×
UNCOV
1937
    pUser->connectIdleTime = TSDB_USER_CONNECT_IDLE_TIME_DEFAULT;
×
NEW
1938
    pUser->callPerSession = pUser->superUser ? -1 : TSDB_USER_CALL_PER_SESSION_DEFAULT;
×
NEW
1939
    pUser->vnodePerCall = pUser->superUser ? -1 : TSDB_USER_VNODE_PER_CALL_DEFAULT;
×
NEW
1940
    pUser->failedLoginAttempts = pUser->superUser ? -1 : TSDB_USER_FAILED_LOGIN_ATTEMPTS_DEFAULT;
×
1941
    pUser->passwordLifeTime = TSDB_USER_PASSWORD_LIFE_TIME_DEFAULT;
×
1942
    pUser->passwordReuseTime = TSDB_USER_PASSWORD_REUSE_TIME_DEFAULT;
×
NEW
1943
    pUser->passwordReuseMax = TSDB_USER_PASSWORD_REUSE_MAX_DEFAULT;
×
UNCOV
1944
    pUser->passwordLockTime = TSDB_USER_PASSWORD_LOCK_TIME_DEFAULT;
×
UNCOV
1945
    pUser->passwordGraceTime = pUser->superUser ? -1 : TSDB_USER_PASSWORD_GRACE_TIME_DEFAULT;
×
UNCOV
1946
    pUser->inactiveAccountTime = pUser->superUser ? -1 : TSDB_USER_INACTIVE_ACCOUNT_TIME_DEFAULT;
×
NEW
1947
    pUser->allowTokenNum = pUser->superUser ? -1 : TSDB_USER_ALLOW_TOKEN_NUM_DEFAULT;
×
UNCOV
1948
    pUser->tokenNum = 0;
×
UNCOV
1949
    pUser->pTimeWhiteList = taosMemCalloc(1, sizeof(SDateTimeWhiteList));
×
UNCOV
1950
    if (pUser->pTimeWhiteList == NULL) {
×
1951
    }
1952
  } else {
1953
    SDB_GET_BINARY(pRaw, dataPos, pUser->totpsecret, sizeof(pUser->totpsecret), _OVER);
1,442,122✔
1954
    SDB_GET_INT8(pRaw, dataPos, &pUser->changePass, _OVER);
1,442,122✔
1955
    SDB_GET_INT32(pRaw, dataPos, &pUser->sessionPerUser, _OVER);
1,442,122✔
1956
    SDB_GET_INT32(pRaw, dataPos, &pUser->connectTime, _OVER);
1,442,122✔
1957
    SDB_GET_INT32(pRaw, dataPos, &pUser->connectIdleTime, _OVER);
1,442,122✔
1958
    SDB_GET_INT32(pRaw, dataPos, &pUser->callPerSession, _OVER);
1,442,122✔
1959
    SDB_GET_INT32(pRaw, dataPos, &pUser->vnodePerCall, _OVER);
1,442,122✔
1960
    SDB_GET_INT32(pRaw, dataPos, &pUser->failedLoginAttempts, _OVER);
1,442,122✔
1961
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordLifeTime, _OVER);
1,442,122✔
1962
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordReuseTime, _OVER);
1,442,122✔
1963
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordReuseMax, _OVER);
1,442,122✔
1964
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordLockTime, _OVER);
1,442,122✔
1965
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordGraceTime, _OVER);
1,442,122✔
1966
    SDB_GET_INT32(pRaw, dataPos, &pUser->inactiveAccountTime, _OVER);
1,442,122✔
1967
    SDB_GET_INT32(pRaw, dataPos, &pUser->allowTokenNum, _OVER);
1,442,122✔
1968
    SDB_GET_INT32(pRaw, dataPos, &pUser->tokenNum, _OVER);
1,442,122✔
1969

1970
    int32_t num = 0;
1,442,122✔
1971
    SDB_GET_INT32(pRaw, dataPos, &num, _OVER);
1,442,122✔
1972
    pUser->pTimeWhiteList = taosMemCalloc(1, sizeof(SDateTimeWhiteList) + num * sizeof(SDateTimeWhiteListItem));
1,442,122✔
1973
    if (pUser->pTimeWhiteList == NULL) {
1,442,122✔
1974
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1975
    }
1976

1977
    pUser->pTimeWhiteList->num = num;
1,442,122✔
1978
    for (int32_t i = 0; i < num; i++) {
1,442,122✔
UNCOV
1979
      SDateTimeWhiteListItem *range = &pUser->pTimeWhiteList->ranges[i];
×
UNCOV
1980
      SDB_GET_BOOL(pRaw, dataPos, &range->absolute, _OVER);
×
UNCOV
1981
      SDB_GET_BOOL(pRaw, dataPos, &range->neg, _OVER);
×
UNCOV
1982
      SDB_GET_INT64(pRaw, dataPos, &range->start, _OVER);
×
UNCOV
1983
      SDB_GET_INT32(pRaw, dataPos, &range->duration, _OVER);
×
1984
    }
1985

1986
    int32_t extLen = 0;
1,442,122✔
1987
    SDB_GET_INT32(pRaw, dataPos, &extLen, _OVER);
1,442,122✔
1988
    TAOS_MEMORY_REALLOC(key, extLen);
1,442,122✔
1989
    if (key == NULL) {
1,442,122✔
UNCOV
1990
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1991
    }
1992
    SDB_GET_BINARY(pRaw, dataPos, key, extLen, _OVER);
1,442,122✔
1993
    TAOS_CHECK_GOTO(tDeserializeUserObjExt(key, extLen, pUser), &lino, _OVER);
1,442,122✔
1994
  }
1995

1996
#ifndef TD_ENTERPRISE
1997
  // community users cannot modify these fields, and the default values may prevent
1998
  // the user from logging in, so we set them to different values here.
1999
  pUser->sessionPerUser = -1;
2000
  pUser->connectTime = -1;
2001
  pUser->connectIdleTime = -1;
2002
  pUser->callPerSession = -1;
2003
  pUser->vnodePerCall = -1;
2004
  pUser->failedLoginAttempts = -1;
2005
  pUser->passwordLifeTime = -1;
2006
  pUser->passwordReuseTime = 0;
2007
  pUser->passwordReuseMax = 0;
2008
  pUser->passwordLockTime = -1;
2009
  pUser->passwordGraceTime = -1;
2010
  pUser->inactiveAccountTime = -1;
2011
  pUser->allowTokenNum = -1;
2012
  pUser->tokenNum = 0;
2013
#endif // TD_ENTERPRISE
2014

2015
  SDB_GET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
1,442,122✔
2016

2017
  taosInitRWLatch(&pUser->lock);
1,442,122✔
2018
  dropOldPasswords(pUser);
1,442,122✔
2019
  // TODO: migrate legacy privileges to new hash tables
2020
_OVER:
1,442,122✔
2021
  taosMemoryFree(key);
1,442,122✔
2022
  taosMemoryFree(value);
1,442,122✔
2023
  taosHashCleanup(pReadDbs);
1,442,122✔
2024
  taosHashCleanup(pWriteDbs);
1,442,122✔
2025
  taosHashCleanup(pTopics);
1,442,122✔
2026
  taosHashCleanup(pReadTbs);
1,442,122✔
2027
  taosHashCleanup(pWriteTbs);
1,442,122✔
2028
  taosHashCleanup(pAlterTbs);
1,442,122✔
2029
  taosHashCleanup(pReadViews);
1,442,122✔
2030
  taosHashCleanup(pWriteViews);
1,442,122✔
2031
  taosHashCleanup(pAlterViews);
1,442,122✔
2032
  taosHashCleanup(pUseDbs);
1,442,122✔
2033
  if (code < 0) {
1,442,122✔
UNCOV
2034
    terrno = code;
×
UNCOV
2035
    mError("user:%s, failed to decode at line %d from raw:%p since %s", pUser == NULL ? "null" : pUser->user, lino,
×
2036
           pRaw, tstrerror(code));
UNCOV
2037
    if (pUser != NULL) {
×
UNCOV
2038
      mndUserFreeObj(pUser);
×
2039
    }
UNCOV
2040
    taosMemoryFreeClear(pRow);
×
UNCOV
2041
    return NULL;
×
2042
  }
2043

2044
  mTrace("user:%s, decode from raw:%p, row:%p", pUser->user, pRaw, pUser);
1,442,122✔
2045
  return pRow;
1,442,122✔
2046
}
2047

2048
static int32_t mndUserActionInsert(SSdb *pSdb, SUserObj *pUser) {
449,919✔
2049
  mTrace("user:%s, perform insert action, row:%p", pUser->user, pUser);
449,919✔
2050

2051
  SAcctObj *pAcct = sdbAcquire(pSdb, SDB_ACCT, pUser->acct);
449,919✔
2052
  if (pAcct == NULL) {
449,919✔
UNCOV
2053
    terrno = TSDB_CODE_MND_ACCT_NOT_EXIST;
×
UNCOV
2054
    mError("user:%s, failed to perform insert action since %s", pUser->user, terrstr());
×
UNCOV
2055
    TAOS_RETURN(terrno);
×
2056
  }
2057
  pUser->acctId = pAcct->acctId;
449,919✔
2058
  sdbRelease(pSdb, pAcct);
449,919✔
2059

2060
  return 0;
449,919✔
2061
}
2062

UNCOV
2063
int32_t mndDupTableHash(SHashObj *pOld, SHashObj **ppNew) {
×
UNCOV
2064
  int32_t code = 0;
×
UNCOV
2065
  *ppNew =
×
UNCOV
2066
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
UNCOV
2067
  if (*ppNew == NULL) {
×
UNCOV
2068
    TAOS_RETURN(terrno);
×
2069
  }
2070

UNCOV
2071
  char *tb = taosHashIterate(pOld, NULL);
×
UNCOV
2072
  while (tb != NULL) {
×
UNCOV
2073
    size_t keyLen = 0;
×
UNCOV
2074
    char  *key = taosHashGetKey(tb, &keyLen);
×
2075

UNCOV
2076
    int32_t valueLen = strlen(tb) + 1;
×
UNCOV
2077
    if ((code = taosHashPut(*ppNew, key, keyLen, tb, valueLen)) != 0) {
×
UNCOV
2078
      taosHashCancelIterate(pOld, tb);
×
UNCOV
2079
      taosHashCleanup(*ppNew);
×
2080
      TAOS_RETURN(code);
×
2081
    }
UNCOV
2082
    tb = taosHashIterate(pOld, tb);
×
2083
  }
2084

UNCOV
2085
  TAOS_RETURN(code);
×
2086
}
2087

UNCOV
2088
int32_t mndDupUseDbHash(SHashObj *pOld, SHashObj **ppNew) {
×
UNCOV
2089
  int32_t code = 0;
×
UNCOV
2090
  *ppNew =
×
UNCOV
2091
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
UNCOV
2092
  if (*ppNew == NULL) {
×
UNCOV
2093
    TAOS_RETURN(terrno);
×
2094
  }
2095

UNCOV
2096
  int32_t *db = taosHashIterate(pOld, NULL);
×
UNCOV
2097
  while (db != NULL) {
×
UNCOV
2098
    size_t keyLen = 0;
×
2099
    char  *key = taosHashGetKey(db, &keyLen);
×
2100

2101
    if ((code = taosHashPut(*ppNew, key, keyLen, db, sizeof(*db))) != 0) {
×
UNCOV
2102
      taosHashCancelIterate(pOld, db);
×
UNCOV
2103
      taosHashCleanup(*ppNew);
×
UNCOV
2104
      TAOS_RETURN(code);
×
2105
    }
UNCOV
2106
    db = taosHashIterate(pOld, db);
×
2107
  }
2108

2109
  TAOS_RETURN(code);
×
2110
}
2111

2112
int32_t mndDupRoleHash(SHashObj *pOld, SHashObj **ppNew) {
967,349✔
2113
  if (!(*ppNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true,
967,349✔
2114
                              HASH_ENTRY_LOCK))) {
UNCOV
2115
    TAOS_RETURN(terrno);
×
2116
  }
2117

2118
  int32_t  code = 0;
967,349✔
2119
  uint8_t *flag = NULL;
967,349✔
2120
  while ((flag = taosHashIterate(pOld, flag))) {
1,934,858✔
2121
    size_t keyLen = 0;
967,509✔
2122
    char  *key = taosHashGetKey(flag, &keyLen);
967,509✔
2123

2124
    if ((code = taosHashPut(*ppNew, key, keyLen, flag, sizeof(*flag))) != 0) {
967,509✔
2125
      taosHashCancelIterate(pOld, flag);
×
2126
      taosHashCleanup(*ppNew);
×
UNCOV
2127
      TAOS_RETURN(code);
×
2128
    }
2129
  }
2130

2131
  TAOS_RETURN(code);
967,349✔
2132
}
2133

2134
int32_t mndMergePrivObjHash(SHashObj *pOld, SHashObj **ppNew) {
21,211,821✔
2135
  if (!(*ppNew)) return mndDupPrivObjHash(pOld, ppNew);
21,211,821✔
2136

2137
  int32_t           code = 0, lino = 0;
21,211,951✔
2138
  SHashObj         *pNew = *ppNew;
21,211,951✔
2139
  SPrivObjPolicies *policies = NULL;
21,211,691✔
2140
  while ((policies = taosHashIterate(pOld, policies))) {
197,908,715✔
2141
    size_t klen = 0;
176,699,000✔
2142
    char  *key = taosHashGetKey(policies, &klen);
176,699,000✔
2143
    size_t vlen = taosHashGetValueSize(policies);
176,698,289✔
2144

2145
    SPrivObjPolicies *pNewPolicies = taosHashGet(pNew, key, klen);
176,698,289✔
2146
    if (pNewPolicies) {
176,699,554✔
2147
      size_t newVlen = taosHashGetValueSize(pNewPolicies);
112,064,416✔
2148
      if (newVlen > 0 && vlen > 0) {
112,064,416✔
2149
        privAddSet(&pNewPolicies->policy, &policies->policy);
112,064,416✔
2150
      }
2151
      continue;
112,061,886✔
2152
    }
2153

2154
    if ((code = taosHashPut(pNew, key, klen, vlen ? policies : NULL, vlen)) != 0) {
64,635,138✔
2155
      taosHashCancelIterate(pOld, policies);
×
UNCOV
2156
      taosHashCleanup(pNew);
×
UNCOV
2157
      *ppNew = NULL;
×
UNCOV
2158
      TAOS_RETURN(code);
×
2159
    }
2160
  }
2161

2162
  TAOS_RETURN(code);
21,211,951✔
2163
}
2164

2165
/**
2166
 * 1. Prefer to use SPrivTblPolicies from user object(the updateUs of policy in user object is INT64_MAX)
2167
 * 2. If two or more roles have SPrivTblPolicies, the policy with latest update time take effect.
2168
 */
2169
int32_t mndMergePrivTblHash(SHashObj *pOld, SHashObj **ppNew, bool updateWithLatest) {
63,635,853✔
2170
  if (!(*ppNew)) return mndDupPrivTblHash(pOld, ppNew, false);
63,635,853✔
2171

2172
  int32_t           code = 0, lino = 0;
63,635,853✔
2173
  SHashObj         *pNew = *ppNew;
63,635,853✔
2174
  SPrivTblPolicies *policies = NULL;
63,635,793✔
2175
  while ((policies = taosHashIterate(pOld, policies))) {
63,635,793✔
UNCOV
2176
    size_t klen = 0;
×
UNCOV
2177
    char  *key = taosHashGetKey(policies, &klen);
×
UNCOV
2178
    size_t vlen = taosHashGetValueSize(policies);
×
2179

UNCOV
2180
    SPrivTblPolicies *pNewPolicies = taosHashGet(pNew, key, klen);
×
UNCOV
2181
    if (pNewPolicies) {
×
UNCOV
2182
      size_t newVlen = taosHashGetValueSize(pNewPolicies);
×
UNCOV
2183
      if (newVlen > 0 && vlen > 0) {
×
UNCOV
2184
        TAOS_CHECK_EXIT(privTblPoliciesMerge(pNewPolicies, policies, updateWithLatest));
×
2185
      }
UNCOV
2186
      continue;
×
2187
    }
2188

UNCOV
2189
    SPrivTblPolicies tmpPolicies = {0};
×
UNCOV
2190
    if (vlen > 0) {
×
UNCOV
2191
      if ((code = privTblPoliciesMerge(&tmpPolicies, policies, updateWithLatest))) {
×
2192
        privTblPoliciesFree(&tmpPolicies);
UNCOV
2193
        goto _exit;
×
2194
      }
2195
    }
UNCOV
2196
    if ((code = taosHashPut(pNew, key, klen, vlen ? &tmpPolicies : NULL, vlen)) != 0) {
×
2197
      privTblPoliciesFree(&tmpPolicies);
UNCOV
2198
      taosHashCancelIterate(pOld, policies);
×
UNCOV
2199
      taosHashCleanup(pNew);
×
UNCOV
2200
      *ppNew = NULL;
×
2201
      TAOS_RETURN(code);
×
2202
    }
2203
  }
2204

2205
_exit:
63,635,793✔
2206
  TAOS_RETURN(code);
63,635,793✔
2207
}
2208

2209
int32_t mndDupPrivObjHash(SHashObj *pOld, SHashObj **ppNew) {
8,170,348✔
2210
  if (!(*ppNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true,
8,170,348✔
2211
                             HASH_ENTRY_LOCK))) {
UNCOV
2212
    TAOS_RETURN(terrno);
×
2213
  }
2214
  int32_t           code = 0;
8,170,418✔
2215
  SPrivObjPolicies *policies = NULL;
8,170,418✔
2216
  while ((policies = taosHashIterate(pOld, policies))) {
10,880,149✔
2217
    size_t klen = 0;
2,709,731✔
2218
    char  *key = taosHashGetKey(policies, &klen);
2,709,731✔
2219
    size_t vlen = taosHashGetValueSize(policies);
2,709,731✔
2220

2221
    if ((code = taosHashPut(*ppNew, key, klen, vlen > 0 ? policies : NULL, vlen)) != 0) {
2,709,731✔
2222
      taosHashCancelIterate(pOld, policies);
×
2223
      taosHashCleanup(*ppNew);
×
2224
      TAOS_RETURN(code);
×
2225
    }
2226
  }
2227

2228
  TAOS_RETURN(code);
8,170,418✔
2229
}
2230

2231
int32_t mndDupPrivTblHash(SHashObj *pOld, SHashObj **ppNew, bool setUpdateTimeMax) {
25,478,273✔
2232
  if (!(*ppNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true,
25,478,273✔
2233
                              HASH_ENTRY_LOCK))) {
UNCOV
2234
    TAOS_RETURN(terrno);
×
2235
  }
2236
  taosHashSetFreeFp(*ppNew, privTblPoliciesFree);
25,478,533✔
2237

2238
  int32_t           code = 0, lino = 0;
25,478,533✔
2239
  SPrivTblPolicies *policies = NULL, *pTmpPolicies = NULL;
25,478,533✔
2240
  SPrivTblPolicies  tmpPolicies = {0};
25,478,533✔
2241
  while ((policies = taosHashIterate(pOld, policies))) {
25,541,617✔
2242
    size_t klen = 0;
63,084✔
2243
    char  *key = taosHashGetKey(policies, &klen);
63,084✔
2244
    size_t vlen = taosHashGetValueSize(policies);
63,084✔
2245
    memset(&tmpPolicies, 0, sizeof(tmpPolicies));
63,084✔
2246
    pTmpPolicies = &tmpPolicies;
63,084✔
2247
    if (vlen > 0) {
63,084✔
2248
      TAOS_CHECK_EXIT(privTblPoliciesAdd(&tmpPolicies, policies, true, setUpdateTimeMax));
63,084✔
2249
    }
2250
    TAOS_CHECK_EXIT(taosHashPut(*ppNew, key, klen, vlen > 0 ? &tmpPolicies : NULL, vlen));
63,084✔
2251
    pTmpPolicies = NULL;
63,084✔
2252
  }
2253

2254
_exit:
25,478,533✔
2255
  if (code != 0) {
25,478,533✔
UNCOV
2256
    if (!pTmpPolicies) {
×
2257
      privTblPoliciesFree(pTmpPolicies);
2258
      pTmpPolicies = NULL;
×
2259
    }
UNCOV
2260
    if (policies) taosHashCancelIterate(pOld, policies);
×
UNCOV
2261
    taosHashCleanup(*ppNew);
×
UNCOV
2262
    *ppNew = NULL;
×
2263
  }
2264
  TAOS_RETURN(code);
25,478,533✔
2265
}
2266

2267
int32_t mndUserDupObj(SUserObj *pUser, SUserObj *pNew) {
966,069✔
2268
  int32_t code = 0;
966,069✔
2269
  (void)memcpy(pNew, pUser, sizeof(SUserObj));
966,069✔
2270
  pNew->authVersion++;
966,069✔
2271
  pNew->updateTime = taosGetTimestampMs();
966,069✔
2272
  taosInitRWLatch(&pNew->lock);
966,069✔
2273

2274
  pNew->passwords = NULL;
966,069✔
2275
  pNew->pIpWhiteListDual = NULL;
966,069✔
2276
  pNew->passwords = NULL;
966,069✔
2277
  pNew->objPrivs = NULL;
966,069✔
2278
  pNew->selectTbs = NULL;
966,069✔
2279
  pNew->insertTbs = NULL;
966,069✔
2280
  pNew->updateTbs = NULL;
966,069✔
2281
  pNew->deleteTbs = NULL;
966,069✔
2282
  pNew->pTimeWhiteList = NULL;
966,069✔
2283
  pNew->roles = NULL;
966,069✔
2284

2285
  taosRLockLatch(&pUser->lock);
966,069✔
2286
  pNew->passwords = taosMemoryCalloc(pUser->numOfPasswords, sizeof(SUserPassword));
966,069✔
2287
  if (pNew->passwords == NULL) {
966,069✔
UNCOV
2288
    code = TSDB_CODE_OUT_OF_MEMORY;
×
UNCOV
2289
    goto _OVER;
×
2290
  }
2291
  (void)memcpy(pNew->passwords, pUser->passwords, pUser->numOfPasswords * sizeof(SUserPassword));
966,069✔
2292
  TAOS_CHECK_GOTO(mndDupPrivObjHash(pUser->objPrivs, &pNew->objPrivs), NULL, _OVER);
966,069✔
2293
  TAOS_CHECK_GOTO(mndDupPrivTblHash(pUser->selectTbs, &pNew->selectTbs, false), NULL, _OVER);
966,069✔
2294
  TAOS_CHECK_GOTO(mndDupPrivTblHash(pUser->insertTbs, &pNew->insertTbs, false), NULL, _OVER);
966,069✔
2295
  TAOS_CHECK_GOTO(mndDupPrivTblHash(pUser->updateTbs, &pNew->updateTbs, false), NULL, _OVER);
966,069✔
2296
  TAOS_CHECK_GOTO(mndDupPrivTblHash(pUser->deleteTbs, &pNew->deleteTbs, false), NULL, _OVER);
966,069✔
2297
  TAOS_CHECK_GOTO(mndDupRoleHash(pUser->roles, &pNew->roles), NULL, _OVER);
966,069✔
2298
  pNew->pIpWhiteListDual = cloneIpWhiteList(pUser->pIpWhiteListDual);
966,069✔
2299
  if (pNew->pIpWhiteListDual == NULL) {
966,069✔
UNCOV
2300
    code = TSDB_CODE_OUT_OF_MEMORY;
×
UNCOV
2301
    goto _OVER;
×
2302
  }
2303

2304
  pNew->pTimeWhiteList = cloneDateTimeWhiteList(pUser->pTimeWhiteList);
966,069✔
2305
  if (pNew->pTimeWhiteList == NULL) {
966,069✔
2306
    code = TSDB_CODE_OUT_OF_MEMORY;
×
2307
    goto _OVER;
×
2308
  }
2309

2310
_OVER:
966,069✔
2311
  taosRUnLockLatch(&pUser->lock);
966,069✔
2312
  TAOS_RETURN(code);
966,069✔
2313
}
2314

2315
void mndUserFreeObj(SUserObj *pUser) {
4,944,264✔
2316
  taosHashCleanup(pUser->objPrivs);
4,944,264✔
2317
  taosHashCleanup(pUser->selectTbs);
4,944,264✔
2318
  taosHashCleanup(pUser->insertTbs);
4,944,264✔
2319
  taosHashCleanup(pUser->updateTbs);
4,944,264✔
2320
  taosHashCleanup(pUser->deleteTbs);
4,944,264✔
2321
  taosHashCleanup(pUser->roles);
4,944,264✔
2322
  taosMemoryFreeClear(pUser->passwords);
4,944,264✔
2323
  taosMemoryFreeClear(pUser->pIpWhiteListDual);
4,944,264✔
2324
  taosMemoryFreeClear(pUser->pTimeWhiteList);
4,944,264✔
2325
  pUser->objPrivs = NULL;
4,944,264✔
2326
  pUser->selectTbs = NULL;
4,944,264✔
2327
  pUser->insertTbs = NULL;
4,944,264✔
2328
  pUser->updateTbs = NULL;
4,944,264✔
2329
  pUser->deleteTbs = NULL;
4,944,264✔
2330
  pUser->roles = NULL;
4,944,264✔
2331
}
4,944,264✔
2332

2333
static int32_t mndUserActionDelete(SSdb *pSdb, SUserObj *pUser) {
1,442,078✔
2334
  mTrace("user:%s, perform delete action, row:%p", pUser->user, pUser);
1,442,078✔
2335
  mndUserFreeObj(pUser);
1,442,078✔
2336
  return 0;
1,442,078✔
2337
}
2338

2339
static int32_t mndUserActionUpdate(SSdb *pSdb, SUserObj *pOld, SUserObj *pNew) {
969,259✔
2340
  mTrace("user:%s, perform update action, old row:%p new row:%p", pOld->user, pOld, pNew);
969,259✔
2341
  taosWLockLatch(&pOld->lock);
969,259✔
2342
  pOld->updateTime = pNew->updateTime;
969,259✔
2343
  pOld->authVersion = pNew->authVersion;
969,259✔
2344
  pOld->passVersion = pNew->passVersion;
969,259✔
2345
  pOld->sysInfo = pNew->sysInfo;
969,259✔
2346
  pOld->enable = pNew->enable;
969,259✔
2347
  pOld->flag = pNew->flag;
969,259✔
2348
  pOld->changePass = pNew->changePass;
969,259✔
2349
  pOld->uid = pNew->uid;
969,259✔
2350

2351
  pOld->sessionPerUser = pNew->sessionPerUser;
969,259✔
2352
  pOld->connectTime = pNew->connectTime;
969,259✔
2353
  pOld->connectIdleTime = pNew->connectIdleTime;
969,259✔
2354
  pOld->callPerSession = pNew->callPerSession;
969,259✔
2355
  pOld->vnodePerCall = pNew->vnodePerCall;
969,259✔
2356
  pOld->failedLoginAttempts = pNew->failedLoginAttempts;
969,259✔
2357
  pOld->passwordLifeTime = pNew->passwordLifeTime;
969,259✔
2358
  pOld->passwordReuseTime = pNew->passwordReuseTime;
969,259✔
2359
  pOld->passwordReuseMax = pNew->passwordReuseMax;
969,259✔
2360
  pOld->passwordLockTime = pNew->passwordLockTime;
969,259✔
2361
  pOld->passwordGraceTime = pNew->passwordGraceTime;
969,259✔
2362
  pOld->inactiveAccountTime = pNew->inactiveAccountTime;
969,259✔
2363
  pOld->allowTokenNum = pNew->allowTokenNum;
969,259✔
2364
  pOld->tokenNum = pNew->tokenNum;
969,259✔
2365

2366
  pOld->numOfPasswords = pNew->numOfPasswords;
969,259✔
2367
  TSWAP(pOld->passwords, pNew->passwords);
969,259✔
2368
  (void)memcpy(pOld->salt, pNew->salt, sizeof(pOld->salt));
969,259✔
2369
  (void)memcpy(pOld->totpsecret, pNew->totpsecret, sizeof(pOld->totpsecret));
969,259✔
2370
  pOld->sysPrivs = pNew->sysPrivs;
969,259✔
2371
  TSWAP(pOld->objPrivs, pNew->objPrivs);
969,259✔
2372
  TSWAP(pOld->selectTbs, pNew->selectTbs);
969,259✔
2373
  TSWAP(pOld->insertTbs, pNew->insertTbs);
969,259✔
2374
  TSWAP(pOld->updateTbs, pNew->updateTbs);
969,259✔
2375
  TSWAP(pOld->deleteTbs, pNew->deleteTbs);
969,259✔
2376
  TSWAP(pOld->roles, pNew->roles);
969,259✔
2377

2378
  TSWAP(pOld->pIpWhiteListDual, pNew->pIpWhiteListDual);
969,259✔
2379
  pOld->ipWhiteListVer = pNew->ipWhiteListVer;
969,259✔
2380
  TSWAP(pOld->pTimeWhiteList, pNew->pTimeWhiteList);
969,259✔
2381
  pOld->timeWhiteListVer = pNew->timeWhiteListVer;
969,259✔
2382
  pOld->passEncryptAlgorithm = pNew->passEncryptAlgorithm;
969,259✔
2383

2384
  taosWUnLockLatch(&pOld->lock);
969,259✔
2385

2386
  return 0;
969,259✔
2387
}
2388

2389
int32_t mndAcquireUser(SMnode *pMnode, const char *userName, SUserObj **ppUser) {
90,351,970✔
2390
  int32_t code = 0;
90,351,970✔
2391
  SSdb   *pSdb = pMnode->pSdb;
90,351,970✔
2392

2393
  *ppUser = sdbAcquire(pSdb, SDB_USER, userName);
90,352,917✔
2394
  if (*ppUser == NULL) {
90,352,974✔
2395
    if (terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
49,233✔
2396
      code = TSDB_CODE_MND_USER_NOT_EXIST;
49,233✔
2397
    } else {
UNCOV
2398
      code = TSDB_CODE_MND_USER_NOT_AVAILABLE;
×
2399
    }
2400
  }
2401
  TAOS_RETURN(code);
90,352,974✔
2402
}
2403

2404
void mndReleaseUser(SMnode *pMnode, SUserObj *pUser) {
97,265,342✔
2405
  SSdb *pSdb = pMnode->pSdb;
97,265,342✔
2406
  sdbRelease(pSdb, pUser);
97,266,062✔
2407
}
97,266,398✔
2408

UNCOV
2409
int32_t mndAcquireUserById(SMnode *pMnode, int64_t userId, SUserObj **ppUser) {
×
UNCOV
2410
  void     *pIter = NULL;
×
UNCOV
2411
  SUserObj *pObj;
×
UNCOV
2412
  SSdb     *pSdb = pMnode->pSdb;
×
UNCOV
2413
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pObj))) {
×
UNCOV
2414
    if (pObj->uid == userId) {
×
UNCOV
2415
      return mndAcquireUser(pMnode, pObj->user, ppUser);
×
2416
    }
2417
  }
UNCOV
2418
  return 0;
×
2419
}
2420

2421
int32_t mndBuildUidNamesHash(SMnode *pMnode, SSHashObj **ppHash) {
466,677✔
2422
  int32_t    code = 0;
466,677✔
2423
  void      *pIter = NULL;
466,677✔
2424
  SUserObj  *pObj;
466,677✔
2425
  SSHashObj *pHash = NULL;
466,677✔
2426

2427
  int32_t nUser = sdbGetSize(pMnode->pSdb, SDB_USER);
466,677✔
2428

2429
  pHash = tSimpleHashInit(nUser, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT));
466,677✔
2430
  if (pHash == NULL) {
466,677✔
UNCOV
2431
    TAOS_RETURN(terrno);
×
2432
  }
2433

2434
  while ((pIter = sdbFetch(pMnode->pSdb, SDB_USER, pIter, (void **)&pObj))) {
945,406✔
2435
    code = tSimpleHashPut(pHash, &pObj->uid, sizeof(pObj->uid), pObj->name, strlen(pObj->name) + 1);
478,729✔
2436
    if (code != 0) {
478,729✔
UNCOV
2437
      sdbRelease(pMnode->pSdb, pObj);
×
UNCOV
2438
      sdbCancelFetch(pMnode->pSdb, pIter);
×
UNCOV
2439
      tSimpleHashCleanup(pHash);
×
UNCOV
2440
      TAOS_RETURN(code);
×
2441
    }
2442
    sdbRelease(pMnode->pSdb, pObj);
478,729✔
2443
  }
2444

2445
  *ppHash = pHash;
466,677✔
2446
  TAOS_RETURN(code);
466,677✔
2447
}
2448

2449
int32_t mndEncryptPass(char *pass, const char* salt, int8_t *algo) {
51,050✔
2450
  int32_t code = 0;
51,050✔
2451
  if (tsMetaKey[0] == '\0') {
51,050✔
2452
    return 0;
50,987✔
2453
  }
2454

2455
  if (salt[0] != 0) {
63✔
2456
    char passAndSalt[TSDB_PASSWORD_LEN - 1 + TSDB_PASSWORD_SALT_LEN];
63✔
2457
    (void)memcpy(passAndSalt, pass, TSDB_PASSWORD_LEN - 1);
63✔
2458
    (void)memcpy(passAndSalt + TSDB_PASSWORD_LEN - 1, salt, TSDB_PASSWORD_SALT_LEN);
63✔
2459
    taosEncryptPass_c((uint8_t *)passAndSalt, sizeof(passAndSalt), pass);
2460
  }
2461

2462
  unsigned char packetData[TSDB_PASSWORD_LEN] = {0};
63✔
2463
  SCryptOpts opts = {0};
63✔
2464
  opts.len = TSDB_PASSWORD_LEN;
63✔
2465
  opts.source = pass;
63✔
2466
  opts.result = packetData;
63✔
2467
  opts.unitLen = TSDB_PASSWORD_LEN;
63✔
2468
  tstrncpy(opts.key, tsDbKey, ENCRYPT_KEY_LEN + 1);
63✔
2469
  int newLen = Builtin_CBC_Encrypt(&opts);
63✔
2470
  if (newLen <= 0) return terrno;
63✔
2471

2472
  memcpy(pass, packetData, newLen);
63✔
2473
  if (algo != NULL) {
63✔
2474
    *algo = DND_CA_SM4;
63✔
2475
  }
2476

2477
  return 0;
63✔
2478
}
2479

2480

2481

2482
static void generateSalt(char *salt, size_t len) {
47,177✔
2483
  const char* set = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
47,177✔
2484
  int32_t     setLen = 62;
47,177✔
2485
  for (int32_t i = 0; i < len - 1; ++i) {
1,509,664✔
2486
    salt[i] = set[taosSafeRand() % setLen];
1,462,487✔
2487
  }
2488
  salt[len - 1] = 0;
47,177✔
2489
}
47,177✔
2490

2491

2492

2493
static int32_t addDefaultIpToTable(int8_t enableIpv6, SHashObj *pUniqueTab) {
480✔
2494
  int32_t code = 0;
480✔
2495
  int32_t lino = 0;
480✔
2496
  int32_t dummpy = 0;
480✔
2497

2498
  SIpRange ipv4 = {0}, ipv6 = {0};
480✔
2499
  code = createDefaultIp4Range(&ipv4);
480✔
2500
  TSDB_CHECK_CODE(code, lino, _error);
480✔
2501

2502
  code = taosHashPut(pUniqueTab, &ipv4, sizeof(ipv4), &dummpy, sizeof(dummpy));
480✔
2503
  TSDB_CHECK_CODE(code, lino, _error);
480✔
2504

2505
  if (enableIpv6) {
480✔
UNCOV
2506
    code = createDefaultIp6Range(&ipv6);
×
UNCOV
2507
    TSDB_CHECK_CODE(code, lino, _error);
×
2508

UNCOV
2509
    code = taosHashPut(pUniqueTab, &ipv6, sizeof(ipv6), &dummpy, sizeof(dummpy));
×
UNCOV
2510
    TSDB_CHECK_CODE(code, lino, _error);
×
2511
  }
2512
_error:
480✔
2513
  if (code != 0) {
480✔
UNCOV
2514
    mError("failed to add default ip range to table since %s", tstrerror(code));
×
2515
  }
2516
  return code;
480✔
2517
}
2518

2519
static int32_t mndCreateUser(SMnode *pMnode, char *acct, SCreateUserReq *pCreate, SRpcMsg *pReq) {
47,017✔
2520
  int32_t  code = 0;
47,017✔
2521
  int32_t  lino = 0;
47,017✔
2522
  SUserObj userObj = {0};
47,017✔
2523

2524
  userObj.passwords = taosMemoryCalloc(1, sizeof(SUserPassword));
47,017✔
2525
  if (userObj.passwords == NULL) {
47,017✔
UNCOV
2526
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2527
  }
2528
  userObj.numOfPasswords = 1;
47,017✔
2529

2530
  if (pCreate->isImport == 1) {
47,017✔
UNCOV
2531
    memset(userObj.salt, 0, sizeof(userObj.salt));
×
UNCOV
2532
    memcpy(userObj.passwords[0].pass, pCreate->pass, TSDB_PASSWORD_LEN);
×
2533
  } else {
2534
    generateSalt(userObj.salt, sizeof(userObj.salt));
47,017✔
2535
    taosEncryptPass_c((uint8_t *)pCreate->pass, strlen(pCreate->pass), userObj.passwords[0].pass);
47,017✔
2536
    userObj.passwords[0].pass[sizeof(userObj.passwords[0].pass) - 1] = 0;
47,017✔
2537
    TAOS_CHECK_GOTO(mndEncryptPass(userObj.passwords[0].pass, userObj.salt, &userObj.passEncryptAlgorithm), &lino, _OVER);
47,017✔
2538
  }
2539
  userObj.passwords[0].setTime = taosGetTimestampSec();
47,017✔
2540

2541
  tstrncpy(userObj.user, pCreate->user, TSDB_USER_LEN);
47,017✔
2542
  tstrncpy(userObj.acct, acct, TSDB_USER_LEN);
47,017✔
2543
  if (pCreate->totpseed[0] != 0) {
47,017✔
UNCOV
2544
    int len = taosGenerateTotpSecret(pCreate->totpseed, 0, userObj.totpsecret, sizeof(userObj.totpsecret));
×
UNCOV
2545
    if (len < 0) {
×
UNCOV
2546
      TAOS_CHECK_GOTO(TSDB_CODE_PAR_INVALID_OPTION_VALUE, &lino, _OVER);
×
2547
    }
2548
  }
2549

2550
  userObj.createdTime = taosGetTimestampMs();
47,017✔
2551
  userObj.updateTime = userObj.createdTime;
47,017✔
2552
  userObj.superUser = 0;  // pCreate->superUser;
47,017✔
2553
  userObj.sysInfo = pCreate->sysInfo;
47,017✔
2554
  userObj.enable = pCreate->enable;
47,017✔
2555
  userObj.createdb = pCreate->createDb;
47,017✔
2556
  userObj.uid = mndGenerateUid(userObj.user, strlen(userObj.user));
47,017✔
2557

2558
#ifdef TD_ENTERPRISE
2559

2560
  userObj.changePass = pCreate->changepass;
47,017✔
2561
  userObj.sessionPerUser = pCreate->sessionPerUser;
47,017✔
2562
  userObj.connectTime = pCreate->connectTime;
47,017✔
2563
  userObj.connectIdleTime = pCreate->connectIdleTime;
47,017✔
2564
  userObj.callPerSession = pCreate->callPerSession;
47,017✔
2565
  userObj.vnodePerCall = pCreate->vnodePerCall;
47,017✔
2566
  userObj.failedLoginAttempts = pCreate->failedLoginAttempts;
47,017✔
2567
  userObj.passwordLifeTime = pCreate->passwordLifeTime;
47,017✔
2568
  userObj.passwordReuseTime = pCreate->passwordReuseTime;
47,017✔
2569
  userObj.passwordReuseMax = pCreate->passwordReuseMax;
47,017✔
2570
  userObj.passwordLockTime = pCreate->passwordLockTime;
47,017✔
2571
  userObj.passwordGraceTime = pCreate->passwordGraceTime;
47,017✔
2572
  userObj.inactiveAccountTime = pCreate->inactiveAccountTime;
47,017✔
2573
  userObj.allowTokenNum = pCreate->allowTokenNum;
47,017✔
2574
  userObj.tokenNum = 0;
47,017✔
2575

2576
  if (pCreate->numIpRanges == 0) {
47,017✔
2577
    TAOS_CHECK_GOTO(createDefaultIpWhiteList(&userObj.pIpWhiteListDual), &lino, _OVER);
46,537✔
2578
  } else {
2579
    SHashObj *pUniqueTab = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
480✔
2580
    if (pUniqueTab == NULL) {
480✔
UNCOV
2581
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2582
    }
2583
    int32_t dummpy = 0;
480✔
2584
    
2585
    for (int i = 0; i < pCreate->numIpRanges; i++) {
1,280✔
2586
      SIpRange range = {0};
800✔
2587
      copyIpRange(&range, pCreate->pIpDualRanges + i);
800✔
2588
      if ((code = taosHashPut(pUniqueTab, &range, sizeof(range), &dummpy, sizeof(dummpy))) != 0) {
800✔
UNCOV
2589
        taosHashCleanup(pUniqueTab);
×
UNCOV
2590
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2591
      }
2592
    }
2593

2594
    code = addDefaultIpToTable(tsEnableIpv6, pUniqueTab);
480✔
2595
    if (code != 0) {
480✔
UNCOV
2596
      taosHashCleanup(pUniqueTab);
×
UNCOV
2597
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2598
    }
2599

2600
    if (taosHashGetSize(pUniqueTab) > MND_MAX_USER_IP_RANGE) {
480✔
UNCOV
2601
      taosHashCleanup(pUniqueTab);
×
UNCOV
2602
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_IP_RANGE, &lino, _OVER);
×
2603
    }
2604

2605
    int32_t           numOfRanges = taosHashGetSize(pUniqueTab);
480✔
2606
    SIpWhiteListDual *p = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + numOfRanges * sizeof(SIpRange));
480✔
2607
    if (p == NULL) {
480✔
UNCOV
2608
      taosHashCleanup(pUniqueTab);
×
UNCOV
2609
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2610
    }
2611

2612
    void   *pIter = taosHashIterate(pUniqueTab, NULL);
480✔
2613
    for (int32_t i = 0; i < numOfRanges; i++) {
1,440✔
2614
      size_t    len = 0;
960✔
2615
      SIpRange *key = taosHashGetKey(pIter, &len);
960✔
2616
      memcpy(&p->pIpRanges[i], key, sizeof(SIpRange));
960✔
2617
      pIter = taosHashIterate(pUniqueTab, pIter);
960✔
2618
    }
2619

2620
    taosHashCleanup(pUniqueTab);
480✔
2621
    p->num = numOfRanges;
480✔
2622
    sortIpWhiteList(p);
480✔
2623
    userObj.pIpWhiteListDual = p;
480✔
2624
  }
2625

2626
  if (pCreate->numTimeRanges == 0) {
47,017✔
2627
    userObj.pTimeWhiteList = (SDateTimeWhiteList*)taosMemoryCalloc(1, sizeof(SDateTimeWhiteList));
47,017✔
2628
    if (userObj.pTimeWhiteList == NULL) {
47,017✔
2629
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2630
    }
2631
  } else {
UNCOV
2632
    SHashObj *pUniqueTab = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
×
UNCOV
2633
    if (pUniqueTab == NULL) {
×
UNCOV
2634
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2635
    }
UNCOV
2636
    int32_t dummpy = 0;
×
2637
    
NEW
2638
    for (int i = 0; i < pCreate->numTimeRanges; i++) {
×
UNCOV
2639
      SDateTimeRange* src = pCreate->pTimeRanges + i;
×
UNCOV
2640
      SDateTimeWhiteListItem range = {0};
×
UNCOV
2641
      DateTimeRangeToWhiteListItem(&range, src);
×
2642

2643
      // no need to add expired range
2644
      if (isDateTimeWhiteListItemExpired(&range)) {
×
2645
        continue;
×
2646
      }
2647

UNCOV
2648
      if ((code = taosHashPut(pUniqueTab, &range, sizeof(range), &dummpy, sizeof(dummpy))) != 0) {
×
2649
        taosHashCleanup(pUniqueTab);
×
2650
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2651
      }
2652
    }
2653

UNCOV
2654
    if (taosHashGetSize(pUniqueTab) > MND_MAX_USER_TIME_RANGE) {
×
UNCOV
2655
      taosHashCleanup(pUniqueTab);
×
2656
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_TIME_RANGE, &lino, _OVER);
×
2657
    }
2658

UNCOV
2659
    int32_t           numOfRanges = taosHashGetSize(pUniqueTab);
×
UNCOV
2660
    SDateTimeWhiteList *p = taosMemoryCalloc(1, sizeof(SDateTimeWhiteList) + numOfRanges * sizeof(SDateTimeWhiteListItem));
×
UNCOV
2661
    if (p == NULL) {
×
UNCOV
2662
      taosHashCleanup(pUniqueTab);
×
UNCOV
2663
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2664
    }
2665

UNCOV
2666
    void   *pIter = taosHashIterate(pUniqueTab, NULL);
×
UNCOV
2667
    for (int32_t i = 0; i < numOfRanges; i++) {
×
UNCOV
2668
      size_t    len = 0;
×
UNCOV
2669
      SDateTimeWhiteListItem *key = taosHashGetKey(pIter, &len);
×
UNCOV
2670
      memcpy(p->ranges + i, key, sizeof(SDateTimeWhiteListItem));
×
UNCOV
2671
      pIter = taosHashIterate(pUniqueTab, pIter);
×
2672
    }
2673

UNCOV
2674
    taosHashCleanup(pUniqueTab);
×
UNCOV
2675
    p->num = numOfRanges;
×
UNCOV
2676
    sortTimeWhiteList(p);
×
2677
    userObj.pTimeWhiteList = p;
×
2678
  }
2679

2680
  userObj.ipWhiteListVer = taosGetTimestampMs();
47,017✔
2681
  userObj.timeWhiteListVer = userObj.ipWhiteListVer;
47,017✔
2682

2683
#else // TD_ENTERPRISE
2684

2685
  userObj.changePass = 1;
2686
  userObj.sessionPerUser = -1;
2687
  userObj.connectTime = -1;
2688
  userObj.connectIdleTime = -1;
2689
  userObj.callPerSession = -1;
2690
  userObj.vnodePerCall = -1;
2691
  userObj.failedLoginAttempts = -1;
2692
  userObj.passwordLifeTime = -1;
2693
  userObj.passwordReuseTime = 0;
2694
  userObj.passwordReuseMax = 0;
2695
  userObj.passwordLockTime = -1;
2696
  userObj.passwordGraceTime = -1;
2697
  userObj.inactiveAccountTime = -1;
2698
  userObj.allowTokenNum = -1;
2699
  userObj.tokenNum = 0;
2700

2701
  TAOS_CHECK_GOTO(createDefaultIpWhiteList(&userObj.pIpWhiteListDual), &lino, _OVER);
2702
  userObj.pTimeWhiteList = (SDateTimeWhiteList*)taosMemoryCalloc(1, sizeof(SDateTimeWhiteList));
2703
  if (userObj.pTimeWhiteList == NULL) {
2704
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
2705
  }
2706

2707
  userObj.ipWhiteListVer = 0;
2708
  userObj.timeWhiteListVer = 0;
2709

2710
#endif // TD_ENTERPRISE
2711

2712
  userObj.roles = taosHashInit(1, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
47,017✔
2713
  if (userObj.roles == NULL) {
47,017✔
UNCOV
2714
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2715
  }
2716

2717
  if ((code = taosHashPut(userObj.roles, TSDB_ROLE_SYSINFO_1, strlen(TSDB_ROLE_SYSINFO_1) + 1, NULL, 0)) != 0) {
47,017✔
2718
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2719
  }
2720

2721
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "create-user");
47,017✔
2722
  if (pTrans == NULL) {
47,017✔
UNCOV
2723
    mError("user:%s, failed to create since %s", pCreate->user, terrstr());
×
UNCOV
2724
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2725
  }
2726
  mInfo("trans:%d, used to create user:%s", pTrans->id, pCreate->user);
47,017✔
2727

2728
  SSdbRaw *pCommitRaw = mndUserActionEncode(&userObj);
47,017✔
2729
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
47,017✔
UNCOV
2730
    mError("trans:%d, failed to commit redo log since %s", pTrans->id, terrstr());
×
2731
    mndTransDrop(pTrans);
×
2732
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2733
  }
2734
  TAOS_CHECK_GOTO(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY), &lino, _OVER);
47,017✔
2735

2736
  if (mndTransPrepare(pMnode, pTrans) != 0) {
47,017✔
2737
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
2738
    mndTransDrop(pTrans);
×
2739
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2740
  }
2741

2742
  if ((code = userCacheUpdateWhiteList(pMnode, &userObj)) != 0) {
47,017✔
2743
    mndTransDrop(pTrans);
×
2744
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2745
  }
2746

2747
  mndTransDrop(pTrans);
47,017✔
2748

2749
_OVER:
47,017✔
2750
  mndUserFreeObj(&userObj);
47,017✔
2751
  TAOS_RETURN(code);
47,017✔
2752
}
2753

2754

2755
static int32_t mndCheckPasswordFmt(const char *pwd) {
51,050✔
2756
  if (tsEnableStrongPassword == 0) {
51,050✔
2757
    for (char c = *pwd; c != 0; c = *(++pwd)) {
43,840✔
2758
      if (c == ' ' || c == '\'' || c == '\"' || c == '`' || c == '\\') {
43,360✔
UNCOV
2759
        return TSDB_CODE_MND_INVALID_PASS_FORMAT;
×
2760
      }
2761
    }
2762
    return 0;
480✔
2763
  }
2764

2765
  int32_t len = strlen(pwd);
50,570✔
2766
  if (len < TSDB_PASSWORD_MIN_LEN) {
50,570✔
UNCOV
2767
    return TSDB_CODE_PAR_PASSWD_TOO_SHORT_OR_EMPTY;
×
2768
  }
2769

2770
  if (len > TSDB_PASSWORD_MAX_LEN) {
50,570✔
UNCOV
2771
    return TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG;
×
2772
  }
2773

2774
  if (taosIsComplexString(pwd)) {
50,570✔
2775
    return 0;
50,570✔
2776
  }
2777

UNCOV
2778
  return TSDB_CODE_MND_INVALID_PASS_FORMAT;
×
2779
}
2780

2781

2782

UNCOV
2783
static int32_t mndCheckTotpSeedFmt(const char *seed) {
×
UNCOV
2784
  int32_t len = strlen(seed);
×
UNCOV
2785
  if (len < TSDB_USER_TOTPSEED_MIN_LEN) {
×
UNCOV
2786
    return TSDB_CODE_PAR_OPTION_VALUE_TOO_SHORT;
×
2787
  }
2788

UNCOV
2789
  if (taosIsComplexString(seed)) {
×
UNCOV
2790
    return 0;
×
2791
  }
2792

UNCOV
2793
  return TSDB_CODE_PAR_INVALID_OPTION_VALUE;
×
2794
}
2795

2796

2797

UNCOV
2798
static int32_t mndProcessGetUserDateTimeWhiteListReq(SRpcMsg *pReq) {
×
UNCOV
2799
  SMnode              *pMnode = pReq->info.node;
×
UNCOV
2800
  int32_t              code = 0;
×
UNCOV
2801
  int32_t              lino = 0;
×
UNCOV
2802
  int32_t              contLen = 0;
×
2803
  void                *pRsp = NULL;
×
2804
  SUserObj            *pUser = NULL;
×
2805
  SGetUserWhiteListReq wlReq = {0};
×
UNCOV
2806
  SUserDateTimeWhiteList wlRsp = {0};
×
2807

UNCOV
2808
  if (tDeserializeSGetUserWhiteListReq(pReq->pCont, pReq->contLen, &wlReq) != 0) {
×
UNCOV
2809
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
2810
  }
2811
  mTrace("user: %s, start to get date time whitelist", wlReq.user);
×
2812

UNCOV
2813
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, wlReq.user, &pUser), &lino, _OVER);
×
UNCOV
2814
  TAOS_CHECK_GOTO(mndSetUserDateTimeWhiteListRsp(pMnode, pUser, &wlRsp), &lino, _OVER);
×
2815

2816
  contLen = tSerializeSUserDateTimeWhiteList(NULL, 0, &wlRsp);
×
2817
  if (contLen < 0) {
×
UNCOV
2818
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2819
  }
UNCOV
2820
  pRsp = rpcMallocCont(contLen);
×
UNCOV
2821
  if (pRsp == NULL) {
×
UNCOV
2822
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2823
  }
2824
  
UNCOV
2825
  contLen = tSerializeSUserDateTimeWhiteList(pRsp, contLen, &wlRsp);
×
UNCOV
2826
  if (contLen < 0) {
×
UNCOV
2827
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2828
  }
2829

UNCOV
2830
_OVER:
×
UNCOV
2831
  mndReleaseUser(pMnode, pUser);
×
2832
  tFreeSUserDateTimeWhiteList(&wlRsp);
×
UNCOV
2833
  if (code < 0) {
×
UNCOV
2834
    mError("user:%s, failed to get whitelist at line %d since %s", wlReq.user, lino, tstrerror(code));
×
UNCOV
2835
    rpcFreeCont(pRsp);
×
UNCOV
2836
    pRsp = NULL;
×
UNCOV
2837
    contLen = 0;
×
2838
  }
UNCOV
2839
  pReq->code = code;
×
2840
  pReq->info.rsp = pRsp;
×
UNCOV
2841
  pReq->info.rspLen = contLen;
×
2842

UNCOV
2843
  TAOS_RETURN(code);
×
2844
  return 0;
2845
}
2846

2847

2848

2849
static int32_t buildRetrieveDateTimeWhiteListRsp(SRetrieveDateTimeWhiteListRsp *pRsp) {
462✔
2850
  (void)taosThreadRwlockRdlock(&userCache.rw);
462✔
2851
  
2852
  int32_t count = taosHashGetSize(userCache.users);
462✔
2853
  pRsp->pUsers = taosMemoryCalloc(count, sizeof(SUserDateTimeWhiteList));
462✔
2854
  if (pRsp->pUsers == NULL) {
462✔
UNCOV
2855
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
2856
    TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
2857
  }
2858

2859
  count = 0;
462✔
2860
  void   *pIter = taosHashIterate(userCache.users, NULL);
462✔
2861
  while (pIter) {
924✔
2862
    SDateTimeWhiteList *wl = (*(SCachedUserInfo **)pIter)->wlTime;
462✔
2863
    if (wl == NULL || wl->num <= 0) {
462✔
2864
      pIter = taosHashIterate(userCache.users, pIter);
462✔
2865
      continue;
462✔
2866
    }
2867

UNCOV
2868
    SUserDateTimeWhiteList *pUser = &pRsp->pUsers[count];
×
UNCOV
2869
    pUser->ver = userCache.verTime;
×
2870

2871
    size_t klen;
×
2872
    char  *key = taosHashGetKey(pIter, &klen);
×
2873
    (void)memcpy(pUser->user, key, klen);
×
2874

2875
    pUser->numWhiteLists = wl->num;
×
2876
    pUser->pWhiteLists = taosMemoryCalloc(wl->num, sizeof(SDateTimeWhiteListItem));
×
2877
    if (pUser->pWhiteLists == NULL) {
×
2878
      (void)taosThreadRwlockUnlock(&userCache.rw);
×
2879
      TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
2880
    }
2881

2882
    (void)memcpy(pUser->pWhiteLists, wl->ranges, wl->num * sizeof(SDateTimeWhiteListItem));
×
UNCOV
2883
    count++;
×
2884
    pIter = taosHashIterate(userCache.users, pIter);
×
2885
  }
2886

2887
  pRsp->numOfUser = count;
462✔
2888
  pRsp->ver = userCache.verTime;
462✔
2889
  (void)taosThreadRwlockUnlock(&userCache.rw);
462✔
2890
  TAOS_RETURN(0);
462✔
2891
}
2892

2893

2894

2895
static int32_t mndProcessRetrieveDateTimeWhiteListReq(SRpcMsg *pReq) {
462✔
2896
  int32_t        code = 0;
462✔
2897
  int32_t        lino = 0;
462✔
2898
  int32_t        len = 0;
462✔
2899
  void          *pRsp = NULL;
462✔
2900
  SRetrieveDateTimeWhiteListRsp wlRsp = {0};
462✔
2901

2902
  // impl later
2903
  SRetrieveWhiteListReq req = {0};
462✔
2904
  if (tDeserializeRetrieveWhiteListReq(pReq->pCont, pReq->contLen, &req) != 0) {
462✔
2905
    code = TSDB_CODE_INVALID_MSG;
×
2906
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2907
  }
2908

2909
  TAOS_CHECK_GOTO(buildRetrieveDateTimeWhiteListRsp(&wlRsp), &lino, _OVER);
462✔
2910

2911
  len = tSerializeSRetrieveDateTimeWhiteListRsp(NULL, 0, &wlRsp);
462✔
2912
  if (len < 0) {
462✔
2913
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
2914
  }
2915

2916
  pRsp = rpcMallocCont(len);
462✔
2917
  if (!pRsp) {
462✔
UNCOV
2918
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2919
  }
2920
  len = tSerializeSRetrieveDateTimeWhiteListRsp(pRsp, len, &wlRsp);
462✔
2921
  if (len < 0) {
462✔
UNCOV
2922
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
2923
  }
2924

2925
_OVER:
462✔
2926
  if (code < 0) {
462✔
UNCOV
2927
    mError("failed to process retrieve ip white request at line %d since %s", lino, tstrerror(code));
×
2928
    rpcFreeCont(pRsp);
×
2929
    pRsp = NULL;
×
UNCOV
2930
    len = 0;
×
2931
  }
2932
  pReq->code = code;
462✔
2933
  pReq->info.rsp = pRsp;
462✔
2934
  pReq->info.rspLen = len;
462✔
2935

2936
  tFreeSRetrieveDateTimeWhiteListRsp(&wlRsp);
462✔
2937
  TAOS_RETURN(code);
462✔
2938
}
2939

2940

2941

2942
static int32_t mndProcessCreateUserReq(SRpcMsg *pReq) {
47,017✔
2943
  SMnode        *pMnode = pReq->info.node;
47,017✔
2944
  int32_t        code = 0;
47,017✔
2945
  int32_t        lino = 0;
47,017✔
2946
  SRoleObj      *pRole = NULL;
47,017✔
2947
  SUserObj      *pUser = NULL;
47,017✔
2948
  SUserObj      *pOperUser = NULL;
47,017✔
2949
  SCreateUserReq createReq = {0};
47,017✔
2950
  int64_t        tss = taosGetTimestampMs();
47,017✔
2951

2952
  if (tDeserializeSCreateUserReq(pReq->pCont, pReq->contLen, &createReq) != 0) {
47,017✔
UNCOV
2953
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
2954
  }
2955

2956
  mInfo("user:%s, start to create, createdb:%d, is_import:%d", createReq.user, createReq.createDb, createReq.isImport);
47,017✔
2957

2958
#ifndef TD_ENTERPRISE
2959
  if (createReq.isImport == 1) {
2960
    TAOS_CHECK_GOTO(TSDB_CODE_OPS_NOT_SUPPORT, &lino, _OVER);  // enterprise feature
2961
  }
2962
#endif
2963
  code = mndAcquireUser(pMnode, RPC_MSG_USER(pReq), &pOperUser);
47,017✔
2964
  if (pOperUser == NULL) {
47,017✔
UNCOV
2965
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_USER_FROM_CONN, &lino, _OVER);
×
2966
  }
2967

2968
  if (createReq.isImport != 1) {
47,017✔
2969
    // TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, RPC_MSG_USER(pReq), MND_OPER_CREATE_USER), &lino, _OVER);
2970
    TAOS_CHECK_GOTO(mndCheckSysObjPrivilege(pMnode, pOperUser, PRIV_USER_CREATE, 0, 0, NULL, NULL), &lino, _OVER);
47,017✔
UNCOV
2971
  } else if (strcmp(RPC_MSG_USER(pReq), "root") != 0) {
×
UNCOV
2972
    mError("The operation is not permitted to create user:%s", RPC_MSG_USER(pReq));
×
UNCOV
2973
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_RIGHTS, &lino, _OVER);
×
2974
  }
2975

2976
  if (createReq.user[0] == 0) {
47,017✔
UNCOV
2977
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
2978
  }
2979

2980
  if (createReq.isImport != 1) {
47,017✔
2981
    code = mndCheckPasswordFmt(createReq.pass);
47,017✔
2982
    TAOS_CHECK_GOTO(code, &lino, _OVER);
47,017✔
2983
  }
2984

2985
  if (createReq.totpseed[0] != 0) {
47,017✔
2986
    code = mndCheckTotpSeedFmt(createReq.totpseed);
×
UNCOV
2987
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2988
  }
2989

2990
  code = mndAcquireUser(pMnode, createReq.user, &pUser);
47,017✔
2991
  if (pUser != NULL) {
47,017✔
UNCOV
2992
    TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_ALREADY_EXIST, &lino, _OVER);
×
2993
  }
2994

2995
  code = mndAcquireRole(pMnode, createReq.user, &pRole);
47,017✔
2996
  if (pRole != NULL) {
47,017✔
UNCOV
2997
    TAOS_CHECK_GOTO(TSDB_CODE_MND_ROLE_ALREADY_EXIST, &lino, _OVER);
×
2998
  }
2999

3000
  TAOS_CHECK_GOTO(grantCheck(TSDB_GRANT_USER), &lino, _OVER);
47,017✔
3001

3002
  code = mndCreateUser(pMnode, pOperUser->acct, &createReq, pReq);
47,017✔
3003
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
47,017✔
3004

3005
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
47,017✔
3006
    char detail[1000] = {0};
47,017✔
3007
    (void)tsnprintf(detail, sizeof(detail), "enable:%d, superUser:%d, sysInfo:%d, password:xxx", createReq.enable,
47,017✔
3008
                    createReq.superUser, createReq.sysInfo);
47,017✔
3009
    char operation[15] = {0};
47,017✔
3010
    if (createReq.isImport == 1) {
47,017✔
UNCOV
3011
      tstrncpy(operation, "importUser", sizeof(operation));
×
3012
    } else {
3013
      tstrncpy(operation, "createUser", sizeof(operation));
47,017✔
3014
    }
3015

3016
    int64_t tse = taosGetTimestampMs();
47,017✔
3017
    double  duration = (double)(tse - tss);
47,017✔
3018
    duration = duration / 1000;
47,017✔
3019
    auditRecord(pReq, pMnode->clusterId, operation, "", createReq.user, detail, strlen(detail), duration, 0);
47,017✔
3020
  }
3021

3022
_OVER:
47,017✔
3023
  if (code == TSDB_CODE_MND_USER_ALREADY_EXIST && createReq.ignoreExists) {
47,017✔
UNCOV
3024
    code = 0;
×
3025
  } else if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
47,017✔
3026
    mError("user:%s, failed to create at line %d since %s", createReq.user, lino, tstrerror(code));
×
3027
  }
3028

3029
  mndReleaseRole(pMnode, pRole);
47,017✔
3030
  mndReleaseUser(pMnode, pUser);
47,017✔
3031
  mndReleaseUser(pMnode, pOperUser);
47,017✔
3032
  tFreeSCreateUserReq(&createReq);
47,017✔
3033

3034
  TAOS_RETURN(code);
47,017✔
3035
}
3036

3037

3038

3039
static int32_t mndProcessGetUserIpWhiteListReq(SRpcMsg *pReq) {
14,673✔
3040
  SMnode              *pMnode = pReq->info.node;
14,673✔
3041
  int32_t              code = 0;
14,673✔
3042
  int32_t              lino = 0;
14,673✔
3043
  int32_t              contLen = 0;
14,673✔
3044
  void                *pRsp = NULL;
14,673✔
3045
  SUserObj            *pUser = NULL;
14,673✔
3046
  SGetUserWhiteListReq wlReq = {0};
14,673✔
3047
  SGetUserIpWhiteListRsp wlRsp = {0};
14,673✔
3048

3049
  int32_t (*serialFn)(void *, int32_t, SGetUserIpWhiteListRsp *) = NULL;
14,673✔
3050
  int32_t (*setRspFn)(SMnode * pMnode, SUserObj * pUser, SGetUserIpWhiteListRsp * pRsp) = NULL;
14,673✔
3051

3052
  if (pReq->msgType == TDMT_MND_GET_USER_IP_WHITELIST_DUAL) {
14,673✔
3053
    serialFn = tSerializeSGetUserIpWhiteListDualRsp;
14,673✔
3054
    setRspFn = mndSetUserIpWhiteListDualRsp;
14,673✔
3055
  } else {
UNCOV
3056
    serialFn = tSerializeSGetUserIpWhiteListRsp;
×
UNCOV
3057
    setRspFn = mndSetUserIpWhiteListRsp;
×
3058
  }
3059
  if (tDeserializeSGetUserWhiteListReq(pReq->pCont, pReq->contLen, &wlReq) != 0) {
14,673✔
3060
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
3061
  }
3062
  mTrace("user: %s, start to get ip whitelist", wlReq.user);
14,673✔
3063

3064
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, wlReq.user, &pUser), &lino, _OVER);
14,673✔
3065
  TAOS_CHECK_GOTO(setRspFn(pMnode, pUser, &wlRsp), &lino, _OVER);
14,673✔
3066

3067
  contLen = serialFn(NULL, 0, &wlRsp);
14,673✔
3068
  if (contLen < 0) {
14,673✔
UNCOV
3069
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3070
  }
3071
  pRsp = rpcMallocCont(contLen);
14,673✔
3072
  if (pRsp == NULL) {
14,636✔
UNCOV
3073
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3074
  }
3075

3076
  contLen = serialFn(pRsp, contLen, &wlRsp);
14,636✔
3077
  if (contLen < 0) {
14,636✔
UNCOV
3078
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3079
  }
3080

3081
_OVER:
14,636✔
3082
  mndReleaseUser(pMnode, pUser);
14,636✔
3083
  tFreeSGetUserIpWhiteListDualRsp(&wlRsp);
14,673✔
3084
  if (code < 0) {
14,673✔
UNCOV
3085
    mError("user:%s, failed to get whitelist at line %d since %s", wlReq.user, lino, tstrerror(code));
×
UNCOV
3086
    rpcFreeCont(pRsp);
×
UNCOV
3087
    pRsp = NULL;
×
UNCOV
3088
    contLen = 0;
×
3089
  }
3090
  pReq->code = code;
14,673✔
3091
  pReq->info.rsp = pRsp;
14,673✔
3092
  pReq->info.rspLen = contLen;
14,673✔
3093

3094
  TAOS_RETURN(code);
14,673✔
3095
}
3096

3097

3098

3099
static int32_t buildRetrieveIpWhiteListRsp(SUpdateIpWhite *pUpdate) {
462✔
3100
  (void)taosThreadRwlockRdlock(&userCache.rw);
462✔
3101

3102
  int32_t count = taosHashGetSize(userCache.users);
462✔
3103
  pUpdate->pUserIpWhite = taosMemoryCalloc(count, sizeof(SUpdateUserIpWhite));
462✔
3104
  if (pUpdate->pUserIpWhite == NULL) {
462✔
UNCOV
3105
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
UNCOV
3106
    TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
3107
  }
3108

3109
  count = 0;
462✔
3110
  void   *pIter = taosHashIterate(userCache.users, NULL);
462✔
3111
  while (pIter) {
924✔
3112
    SIpWhiteListDual   *wl = (*(SCachedUserInfo**)pIter)->wlIp;
462✔
3113
    if (wl == NULL || wl->num <= 0) {
462✔
UNCOV
3114
      pIter = taosHashIterate(userCache.users, pIter);
×
UNCOV
3115
      continue;
×
3116
    }
3117

3118
    SUpdateUserIpWhite *pUser = &pUpdate->pUserIpWhite[count];
462✔
3119
    pUser->ver = userCache.verIp;
462✔
3120

3121
    size_t klen;
462✔
3122
    char  *key = taosHashGetKey(pIter, &klen);
462✔
3123
    (void)memcpy(pUser->user, key, klen);
462✔
3124

3125
    pUser->numOfRange = wl->num;
462✔
3126
    pUser->pIpRanges = taosMemoryCalloc(wl->num, sizeof(SIpRange));
462✔
3127
    if (pUser->pIpRanges == NULL) {
462✔
UNCOV
3128
      (void)taosThreadRwlockUnlock(&userCache.rw);
×
3129
      TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
3130
    }
3131

3132
    (void)memcpy(pUser->pIpRanges, wl->pIpRanges, wl->num * sizeof(SIpRange));
462✔
3133
    count++;
462✔
3134
    pIter = taosHashIterate(userCache.users, pIter);
462✔
3135
  }
3136

3137
  pUpdate->numOfUser = count;
462✔
3138
  pUpdate->ver = userCache.verIp;
462✔
3139
  (void)taosThreadRwlockUnlock(&userCache.rw);
462✔
3140
  TAOS_RETURN(0);
462✔
3141
}
3142

3143

3144

3145
int32_t mndProcessRetrieveIpWhiteListReq(SRpcMsg *pReq) {
462✔
3146
  int32_t        code = 0;
462✔
3147
  int32_t        lino = 0;
462✔
3148
  int32_t        len = 0;
462✔
3149
  void          *pRsp = NULL;
462✔
3150
  SUpdateIpWhite ipWhite = {0};
462✔
3151

3152
  // impl later
3153
  SRetrieveWhiteListReq req = {0};
462✔
3154
  if (tDeserializeRetrieveWhiteListReq(pReq->pCont, pReq->contLen, &req) != 0) {
462✔
UNCOV
3155
    code = TSDB_CODE_INVALID_MSG;
×
UNCOV
3156
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3157
  }
3158

3159
  int32_t (*fn)(void *, int32_t, SUpdateIpWhite *) = NULL;
462✔
3160
  if (pReq->msgType == TDMT_MND_RETRIEVE_IP_WHITELIST) {
462✔
3161
    fn = tSerializeSUpdateIpWhite;
×
3162
  } else if (pReq->msgType == TDMT_MND_RETRIEVE_IP_WHITELIST_DUAL) {
462✔
3163
    fn = tSerializeSUpdateIpWhiteDual;
462✔
3164
  }
3165

3166
  TAOS_CHECK_GOTO(buildRetrieveIpWhiteListRsp(&ipWhite), &lino, _OVER);
462✔
3167

3168
  len = fn(NULL, 0, &ipWhite);
462✔
3169
  if (len < 0) {
462✔
UNCOV
3170
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
3171
  }
3172

3173
  pRsp = rpcMallocCont(len);
462✔
3174
  if (!pRsp) {
462✔
UNCOV
3175
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3176
  }
3177
  len = fn(pRsp, len, &ipWhite);
462✔
3178
  if (len < 0) {
462✔
3179
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
3180
  }
3181

3182
_OVER:
462✔
3183
  if (code < 0) {
462✔
UNCOV
3184
    mError("failed to process retrieve ip white request at line %d since %s", lino, tstrerror(code));
×
UNCOV
3185
    rpcFreeCont(pRsp);
×
UNCOV
3186
    pRsp = NULL;
×
3187
    len = 0;
×
3188
  }
3189
  pReq->code = code;
462✔
3190
  pReq->info.rsp = pRsp;
462✔
3191
  pReq->info.rspLen = len;
462✔
3192

3193
  tFreeSUpdateIpWhiteReq(&ipWhite);
462✔
3194
  TAOS_RETURN(code);
462✔
3195
}
3196

3197
static int32_t mndAlterUser(SMnode *pMnode, SUserObj *pNew, SRpcMsg *pReq) {
965,922✔
3198
  int32_t code = 0, lino = 0;
965,922✔
3199
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "alter-user");
965,922✔
3200
  if (pTrans == NULL) {
965,922✔
3201
    mError("user:%s, failed to alter since %s", pNew->user, terrstr());
×
3202
    TAOS_RETURN(terrno);
×
3203
  }
3204
  mInfo("trans:%d, used to alter user:%s", pTrans->id, pNew->user);
965,922✔
3205

3206
  SSdbRaw *pCommitRaw = mndUserActionEncode(pNew);
965,922✔
3207
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
965,922✔
UNCOV
3208
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
UNCOV
3209
    mndTransDrop(pTrans);
×
UNCOV
3210
    TAOS_RETURN(terrno);
×
3211
  }
3212
  TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
965,922✔
3213

3214
  if (mndTransPrepare(pMnode, pTrans) != 0) {
965,922✔
UNCOV
3215
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
UNCOV
3216
    mndTransDrop(pTrans);
×
UNCOV
3217
    TAOS_RETURN(terrno);
×
3218
  }
3219
  if ((code = userCacheUpdateWhiteList(pMnode, pNew)) != 0) {
965,922✔
UNCOV
3220
    mndTransDrop(pTrans);
×
UNCOV
3221
    TAOS_RETURN(code);
×
3222
  }
3223
_exit:
965,922✔
3224
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
965,922✔
UNCOV
3225
    mError("user:%s, failed to alter at line %d since %s", pNew->user, lino, tstrerror(code));
×
3226
  }
3227
  mndTransDrop(pTrans);
965,922✔
3228
  TAOS_RETURN(code);
965,922✔
3229
}
3230

UNCOV
3231
static int32_t mndDupObjHash(SHashObj *pOld, int32_t dataLen, SHashObj **ppNew) {
×
UNCOV
3232
  int32_t code = 0;
×
3233

3234
  *ppNew =
×
UNCOV
3235
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
UNCOV
3236
  if (*ppNew == NULL) {
×
UNCOV
3237
    code = terrno ? terrno : TSDB_CODE_OUT_OF_MEMORY;
×
UNCOV
3238
    TAOS_RETURN(code);
×
3239
  }
3240

UNCOV
3241
  char *db = taosHashIterate(pOld, NULL);
×
UNCOV
3242
  while (db != NULL) {
×
3243
    int32_t len = strlen(db) + 1;
×
UNCOV
3244
    if ((code = taosHashPut(*ppNew, db, len, db, dataLen)) != 0) {
×
UNCOV
3245
      taosHashCancelIterate(pOld, db);
×
UNCOV
3246
      taosHashCleanup(*ppNew);
×
UNCOV
3247
      TAOS_RETURN(code);
×
3248
    }
UNCOV
3249
    db = taosHashIterate(pOld, db);
×
3250
  }
3251

3252
  TAOS_RETURN(code);
×
3253
}
3254

UNCOV
3255
int32_t mndDupDbHash(SHashObj *pOld, SHashObj **ppNew) { return mndDupObjHash(pOld, TSDB_DB_FNAME_LEN, ppNew); }
×
3256

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

3259
static int32_t mndTablePriviledge(SMnode *pMnode, SHashObj *hash, SHashObj *useDbHash, SAlterUserReq *alterReq,
×
3260
                                  SSdb *pSdb) {
UNCOV
3261
  void *pIter = NULL;
×
UNCOV
3262
  char  tbFName[TSDB_TABLE_FNAME_LEN] = {0};
×
3263

UNCOV
3264
  (void)snprintf(tbFName, sizeof(tbFName), "%s.%s", alterReq->objname, alterReq->tabName);
×
UNCOV
3265
  int32_t len = strlen(tbFName) + 1;
×
3266

UNCOV
3267
  if (alterReq->tagCond != NULL && alterReq->tagCondLen != 0) {
×
UNCOV
3268
    char *value = taosHashGet(hash, tbFName, len);
×
UNCOV
3269
    if (value != NULL) {
×
UNCOV
3270
      TAOS_RETURN(TSDB_CODE_MND_PRIVILEGE_EXIST);
×
3271
    }
3272

UNCOV
3273
    int32_t condLen = alterReq->tagCondLen;
×
3274
    TAOS_CHECK_RETURN(taosHashPut(hash, tbFName, len, alterReq->tagCond, condLen));
×
3275
  } else {
UNCOV
3276
    TAOS_CHECK_RETURN(taosHashPut(hash, tbFName, len, alterReq->isView ? "v" : "t", 2));
×
3277
  }
3278

UNCOV
3279
  int32_t  dbKeyLen = strlen(alterReq->objname) + 1;
×
UNCOV
3280
  int32_t  ref = 1;
×
3281
  int32_t *currRef = taosHashGet(useDbHash, alterReq->objname, dbKeyLen);
×
3282
  if (NULL != currRef) {
×
3283
    ref = (*currRef) + 1;
×
3284
  }
UNCOV
3285
  TAOS_CHECK_RETURN(taosHashPut(useDbHash, alterReq->objname, dbKeyLen, &ref, sizeof(ref)));
×
3286

UNCOV
3287
  TAOS_RETURN(0);
×
3288
}
3289

3290
static int32_t mndRemoveTablePriviledge(SMnode *pMnode, SHashObj *hash, SHashObj *useDbHash, SAlterUserReq *alterReq,
×
3291
                                        SSdb *pSdb) {
UNCOV
3292
  void *pIter = NULL;
×
3293
  char  tbFName[TSDB_TABLE_FNAME_LEN] = {0};
×
3294
  (void)snprintf(tbFName, sizeof(tbFName), "%s.%s", alterReq->objname, alterReq->tabName);
×
UNCOV
3295
  int32_t len = strlen(tbFName) + 1;
×
3296

UNCOV
3297
  if (taosHashRemove(hash, tbFName, len) != 0) {
×
3298
    TAOS_RETURN(0);  // not found
×
3299
  }
3300

UNCOV
3301
  int32_t  dbKeyLen = strlen(alterReq->objname) + 1;
×
UNCOV
3302
  int32_t *currRef = taosHashGet(useDbHash, alterReq->objname, dbKeyLen);
×
UNCOV
3303
  if (NULL == currRef) {
×
3304
    return 0;
×
3305
  }
3306

3307
  if (1 == *currRef) {
×
3308
    if (taosHashRemove(useDbHash, alterReq->objname, dbKeyLen) != 0) {
×
3309
      TAOS_RETURN(0);  // not found
×
3310
    }
3311
    return 0;
×
3312
  }
UNCOV
3313
  int32_t ref = (*currRef) - 1;
×
3314
  TAOS_CHECK_RETURN(taosHashPut(useDbHash, alterReq->objname, dbKeyLen, &ref, sizeof(ref)));
×
3315

3316
  return 0;
×
3317
}
3318

3319

3320
#if 0
3321
static int32_t mndProcessAlterUserPrivilegesReq(SRpcMsg* pReq, SAlterUserReq *pAlterReq) {
3322
  SMnode   *pMnode = pReq->info.node;
3323
  SSdb     *pSdb = pMnode->pSdb;
3324
  int32_t   code = 0, lino = 0;
3325
  SUserObj *pUser = NULL;
3326
  SUserObj  newUser = {0};
3327
  int64_t   tss = taosGetTimestampMs();
3328

3329
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, pAlterReq->user, &pUser), &lino, _OVER);
3330
  TAOS_CHECK_GOTO(mndCheckAlterUserPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser, pAlterReq), &lino, _OVER);
3331
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
3332

3333
#if 0
3334
  if (ALTER_USER_ADD_READ_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName) ||
3335
      ALTER_USER_ADD_ALL_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName)) {
3336
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
3337
      int32_t len = strlen(pAlterReq->objname) + 1;
3338
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
3339
      if (pDb == NULL) {
3340
        mndReleaseDb(pMnode, pDb);
3341
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
3342
      }
3343
      if ((code = taosHashPut(newUser.readDbs, pAlterReq->objname, len, pAlterReq->objname, TSDB_DB_FNAME_LEN)) !=
3344
          0) {
3345
        mndReleaseDb(pMnode, pDb);
3346
        TAOS_CHECK_GOTO(code, &lino, _OVER);
3347
      }
3348
      mndReleaseDb(pMnode, pDb);
3349
    } else {
3350
      void   *pIter = NULL;
3351
      while (1) {
3352
        SDbObj *pDb = NULL;
3353
        pIter = sdbFetch(pSdb, SDB_DB, pIter, (void **)&pDb);
3354
        if (pIter == NULL) break;
3355
        int32_t len = strlen(pDb->name) + 1;
3356
        if ((code = taosHashPut(newUser.readDbs, pDb->name, len, pDb->name, TSDB_DB_FNAME_LEN)) != 0) {
3357
          sdbRelease(pSdb, pDb);
3358
          sdbCancelFetch(pSdb, pIter);
3359
          TAOS_CHECK_GOTO(code, &lino, _OVER);
3360
        }
3361
        sdbRelease(pSdb, pDb);
3362
      }
3363
    }
3364
  }
3365

3366
  if (ALTER_USER_ADD_WRITE_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName) ||
3367
      ALTER_USER_ADD_ALL_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName)) {
3368
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
3369
      int32_t len = strlen(pAlterReq->objname) + 1;
3370
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
3371
      if (pDb == NULL) {
3372
        mndReleaseDb(pMnode, pDb);
3373
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
3374
      }
3375
      if ((code = taosHashPut(newUser.writeDbs, pAlterReq->objname, len, pAlterReq->objname, TSDB_DB_FNAME_LEN)) !=
3376
          0) {
3377
        mndReleaseDb(pMnode, pDb);
3378
        TAOS_CHECK_GOTO(code, &lino, _OVER);
3379
      }
3380
      mndReleaseDb(pMnode, pDb);
3381
    } else {
3382
      void   *pIter = NULL;
3383
      while (1) {
3384
        SDbObj *pDb = NULL;
3385
        pIter = sdbFetch(pSdb, SDB_DB, pIter, (void **)&pDb);
3386
        if (pIter == NULL) break;
3387
        int32_t len = strlen(pDb->name) + 1;
3388
        if ((code = taosHashPut(newUser.writeDbs, pDb->name, len, pDb->name, TSDB_DB_FNAME_LEN)) != 0) {
3389
          sdbRelease(pSdb, pDb);
3390
          sdbCancelFetch(pSdb, pIter);
3391
          TAOS_CHECK_GOTO(code, &lino, _OVER);
3392
        }
3393
        sdbRelease(pSdb, pDb);
3394
      }
3395
    }
3396
  }
3397

3398
  if (ALTER_USER_DEL_READ_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName) ||
3399
      ALTER_USER_DEL_ALL_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName)) {
3400
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
3401
      int32_t len = strlen(pAlterReq->objname) + 1;
3402
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
3403
      if (pDb == NULL) {
3404
        mndReleaseDb(pMnode, pDb);
3405
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
3406
      }
3407
      code = taosHashRemove(newUser.readDbs, pAlterReq->objname, len);
3408
      if (code < 0) {
3409
        mError("read db:%s, failed to remove db:%s since %s", newUser.user, pAlterReq->objname, terrstr());
3410
      }
3411
      mndReleaseDb(pMnode, pDb);
3412
    } else {
3413
      taosHashClear(newUser.readDbs);
3414
    }
3415
  }
3416

3417
  if (ALTER_USER_DEL_WRITE_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName) ||
3418
      ALTER_USER_DEL_ALL_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName)) {
3419
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
3420
      int32_t len = strlen(pAlterReq->objname) + 1;
3421
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
3422
      if (pDb == NULL) {
3423
        mndReleaseDb(pMnode, pDb);
3424
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
3425
      }
3426
      code = taosHashRemove(newUser.writeDbs, pAlterReq->objname, len);
3427
      if (code < 0) {
3428
        mError("user:%s, failed to remove db:%s since %s", newUser.user, pAlterReq->objname, terrstr());
3429
      }
3430
      mndReleaseDb(pMnode, pDb);
3431
    } else {
3432
      taosHashClear(newUser.writeDbs);
3433
    }
3434
  }
3435

3436
  SHashObj *pReadTbs = newUser.readTbs;
3437
  SHashObj *pWriteTbs = newUser.writeTbs;
3438
  SHashObj *pAlterTbs = newUser.alterTbs;
3439

3440
#ifdef TD_ENTERPRISE
3441
  if (pAlterReq->isView) {
3442
    pReadTbs = newUser.readViews;
3443
    pWriteTbs = newUser.writeViews;
3444
    pAlterTbs = newUser.alterViews;
3445
  }
3446
#endif
3447

3448
  if (ALTER_USER_ADD_READ_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3449
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3450
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pReadTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3451
  }
3452

3453
  if (ALTER_USER_ADD_WRITE_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3454
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3455
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pWriteTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3456
  }
3457

3458
  if (ALTER_USER_ADD_ALTER_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3459
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3460
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pAlterTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3461
  }
3462

3463
  if (ALTER_USER_DEL_READ_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3464
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3465
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pReadTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3466
  }
3467

3468
  if (ALTER_USER_DEL_WRITE_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3469
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3470
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pWriteTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3471
  }
3472

3473
  if (ALTER_USER_DEL_ALTER_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3474
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3475
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pAlterTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3476
  }
3477
#endif
3478

3479
#if 0
3480
// #ifdef USE_TOPIC
3481
  if (ALTER_USER_ADD_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, &pAlterReq->privileges)) {
3482
    int32_t      len = strlen(pAlterReq->objname) + 1;
3483
    SMqTopicObj *pTopic = NULL;
3484
    if ((code = mndAcquireTopic(pMnode, pAlterReq->objname, &pTopic)) != 0) {
3485
      TAOS_CHECK_GOTO(code, &lino, _OVER);
3486
    }
3487
    taosRLockLatch(&pTopic->lock);
3488
    code = taosHashPut(newUser.topics, pTopic->name, len, pTopic->name, TSDB_TOPIC_FNAME_LEN);
3489
    taosRUnLockLatch(&pTopic->lock);
3490
    mndReleaseTopic(pMnode, pTopic);
3491
    TAOS_CHECK_GOTO(code, &lino, _OVER);
3492
  }
3493

3494
  if (ALTER_USER_DEL_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, &pAlterReq->privileges)) {
3495
    int32_t      len = strlen(pAlterReq->objname) + 1;
3496
    SMqTopicObj *pTopic = NULL;
3497
    if ((code = mndAcquireTopic(pMnode, pAlterReq->objname, &pTopic)) != 0) {
3498
      TAOS_CHECK_GOTO(code, &lino, _OVER);
3499
    }
3500
    taosRLockLatch(&pTopic->lock);
3501
    code = taosHashRemove(newUser.topics, pAlterReq->objname, len);
3502
    if (code < 0) {
3503
      mError("user:%s, failed to remove topic:%s since %s", newUser.user, pAlterReq->objname, tstrerror(code));
3504
    }
3505
    taosRUnLockLatch(&pTopic->lock);
3506
    mndReleaseTopic(pMnode, pTopic);
3507
  }
3508
#endif
3509

3510
  TAOS_CHECK_GOTO(mndAlterUser(pMnode, &newUser, pReq), &lino, _OVER);
3511
  code = TSDB_CODE_ACTION_IN_PROGRESS;
3512

3513
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
3514
    int64_t tse = taosGetTimestampMs();
3515
    double  duration = (double)(tse - tss);
3516
    duration = duration / 1000;
3517
    if (ALTER_USER_ADD_READ_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3518
              ALTER_USER_ADD_WRITE_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3519
              ALTER_USER_ADD_ALL_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3520
              ALTER_USER_ADD_READ_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3521
              ALTER_USER_ADD_WRITE_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3522
              ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3523
      if (strcmp(pAlterReq->objname, "1.*") != 0) {
3524
        SName name = {0};
3525
        TAOS_CHECK_GOTO(tNameFromString(&name, pAlterReq->objname, T_NAME_ACCT | T_NAME_DB), &lino, _OVER);
3526
        auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", name.dbname, pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
3527
      } else {
3528
        auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", "", pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
3529
      }
3530
    } else if (ALTER_USER_ADD_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, pAlterReq->privileges)) {
3531
      auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", pAlterReq->objname, pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
3532
    } else if (ALTER_USER_DEL_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, pAlterReq->privileges)) {
3533
      auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", pAlterReq->objname, pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
3534
    } else {
3535
      if (strcmp(pAlterReq->objname, "1.*") != 0) {
3536
        SName name = {0};
3537
        TAOS_CHECK_GOTO(tNameFromString(&name, pAlterReq->objname, T_NAME_ACCT | T_NAME_DB), &lino, _OVER);
3538
        auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", name.dbname, pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
3539
      } else {
3540
        auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", "", pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
3541
      }
3542
    }
3543
  }
3544
  
3545
_OVER:
3546
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
3547
    mError("user:%s, failed to alter user privileges at line %d since %s", pAlterReq->user, lino, tstrerror(code));
3548
  }
3549
  mndReleaseUser(pMnode, pUser);
3550
  mndUserFreeObj(&newUser);
3551
  TAOS_RETURN(code);
3552
}
3553
#endif
3554

3555
#ifdef TD_ENTERPRISE
3556
extern int32_t mndAlterUserPrivInfo(SMnode *pMnode, SUserObj *pOperUser, SUserObj *pOld, SUserObj *pNew, SAlterRoleReq *pAlterReq);
3557
extern int32_t mndAlterUserRoleInfo(SMnode *pMnode, SUserObj *pOperUser, SUserObj *pOld, SUserObj *pNew, SAlterRoleReq *pAlterReq);
3558
#endif
3559

3560
int32_t mndAlterUserFromRole(SRpcMsg *pReq, SUserObj *pOperUser, SAlterRoleReq *pAlterReq) {
957,373✔
3561
  SMnode   *pMnode = pReq->info.node;
957,373✔
3562
  SSdb     *pSdb = pMnode->pSdb;
957,373✔
3563
  void     *pIter = NULL;
957,373✔
3564
  int32_t   code = 0, lino = 0;
957,373✔
3565
  SUserObj *pUser = NULL;
957,373✔
3566
  SUserObj  newUser = {0};
957,373✔
3567

3568
  TAOS_CHECK_EXIT(mndAcquireUser(pMnode, pAlterReq->principal, &pUser));
957,373✔
3569

3570
  if (pUser->enable == 0) {
956,413✔
UNCOV
3571
    TAOS_CHECK_EXIT(TSDB_CODE_MND_USER_DISABLED);
×
3572
  }
3573

3574
  if (pAlterReq->alterType == TSDB_ALTER_ROLE_PRIVILEGES) {
956,413✔
3575
#ifdef TD_ENTERPRISE
3576
    TAOS_CHECK_EXIT(mndUserDupObj(pUser, &newUser));
952,893✔
3577
    if ((code = mndAlterUserPrivInfo(pMnode, pOperUser, pUser, &newUser, pAlterReq)) == TSDB_CODE_QRY_DUPLICATED_OPERATION) {
952,893✔
UNCOV
3578
      code = 0;
×
UNCOV
3579
      goto _exit;
×
3580
    } else {
3581
      TAOS_CHECK_EXIT(code);
952,893✔
3582
    }
3583
  } else if (pAlterReq->alterType == TSDB_ALTER_ROLE_ROLE) {
3,520✔
3584
    if ((code = mndAlterUserRoleInfo(pMnode, pOperUser, pUser, &newUser, pAlterReq)) == TSDB_CODE_QRY_DUPLICATED_OPERATION) {
3,520✔
3585
      code = 0;
160✔
3586
      goto _exit;
160✔
3587
    } else {
3588
      TAOS_CHECK_EXIT(code);
3,360✔
3589
    }
3590
#endif
3591
  } else {
UNCOV
3592
    TAOS_CHECK_EXIT(TSDB_CODE_INVALID_MSG);
×
3593
  }
3594
  code = mndAlterUser(pMnode, &newUser, pReq);
955,773✔
3595
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
955,773✔
3596

3597
_exit:
957,373✔
3598
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
957,373✔
3599
    mError("user:%s, failed to alter user at line %d since %s", pAlterReq->principal, lino, tstrerror(code));
1,440✔
3600
  }
3601
  mndReleaseUser(pMnode, pUser);
957,373✔
3602
  mndUserFreeObj(&newUser);
957,373✔
3603
  TAOS_RETURN(code);
957,373✔
3604
}
3605

3606

3607
static int32_t mndProcessAlterUserBasicInfoReq(SRpcMsg *pReq, SAlterUserReq *pAlterReq) {
12,412✔
3608
  SMnode       *pMnode = pReq->info.node;
12,412✔
3609
  int32_t       code = 0, lino = 0;
12,412✔
3610
  SUserObj     *pUser = NULL;
12,412✔
3611
  SUserObj      newUser = {0};
12,412✔
3612
  char          auditLog[1000] = {0};
12,412✔
3613
  int32_t       auditLen = 0;
12,412✔
3614
  int64_t       tss = taosGetTimestampMs();
12,412✔
3615

3616
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, pAlterReq->user, &pUser), &lino, _OVER);
12,412✔
3617
  TAOS_CHECK_GOTO(mndCheckAlterUserPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser, pAlterReq), &lino, _OVER);
11,749✔
3618
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
10,149✔
3619

3620
  if (pAlterReq->hasPassword) {
10,149✔
3621
    auditLen += tsnprintf(auditLog, sizeof(auditLog), "password,");
4,033✔
3622

3623
    TAOS_CHECK_GOTO(mndCheckPasswordFmt(pAlterReq->pass), &lino, _OVER);
4,033✔
3624
    if (newUser.salt[0] == 0) {
4,033✔
3625
      generateSalt(newUser.salt, sizeof(newUser.salt));
160✔
3626
    }
3627
    char pass[TSDB_PASSWORD_LEN] = {0};
4,033✔
3628
    taosEncryptPass_c((uint8_t *)pAlterReq->pass, strlen(pAlterReq->pass), pass);
4,033✔
3629
    pass[sizeof(pass) - 1] = 0;
4,033✔
3630
    TAOS_CHECK_GOTO(mndEncryptPass(pass, newUser.salt, &newUser.passEncryptAlgorithm), &lino, _OVER);
4,033✔
3631

3632
    if (newUser.passwordReuseMax > 0 || newUser.passwordReuseTime > 0) {
4,033✔
3633
      for(int32_t i = 0; i < newUser.numOfPasswords; ++i) {
10,900✔
3634
        if (0 == strncmp(newUser.passwords[i].pass, pass, TSDB_PASSWORD_LEN)) {
7,690✔
UNCOV
3635
          TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_PASSWORD_REUSE, &lino, _OVER);
×
3636
        }
3637
      }
3638
      SUserPassword *passwords = taosMemoryCalloc(newUser.numOfPasswords + 1, sizeof(SUserPassword));
3,210✔
3639
      if (passwords == NULL) {
3,210✔
UNCOV
3640
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3641
      }
3642
      memcpy(passwords + 1, newUser.passwords, newUser.numOfPasswords * sizeof(SUserPassword));
3,210✔
3643
      memcpy(passwords[0].pass, pass, TSDB_PASSWORD_LEN);
3,210✔
3644
      passwords[0].setTime = taosGetTimestampSec();
3,210✔
3645
      taosMemoryFree(newUser.passwords);
3,210✔
3646
      newUser.passwords = passwords;
3,210✔
3647
      ++newUser.numOfPasswords;
3,210✔
3648
      ++newUser.passVersion;
3,210✔
3649
      newUser.changePass = 2;
3,210✔
3650
    } else if (0 != strncmp(newUser.passwords[0].pass, pass, TSDB_PASSWORD_LEN)) {
823✔
3651
      memcpy(newUser.passwords[0].pass, pass, TSDB_PASSWORD_LEN);
640✔
3652
      newUser.passwords[0].setTime = taosGetTimestampSec();
640✔
3653
      ++newUser.passVersion;
640✔
3654
      newUser.changePass = 2;
640✔
3655
    }
3656
  }
3657

3658
  if (pAlterReq->hasTotpseed) {
10,149✔
UNCOV
3659
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "totpseed,");
×
3660

UNCOV
3661
    if (pAlterReq->totpseed[0] == 0) { // clear totp secret
×
UNCOV
3662
      memset(newUser.totpsecret, 0, sizeof(newUser.totpsecret));
×
UNCOV
3663
    } else if (taosGenerateTotpSecret(pAlterReq->totpseed, 0, newUser.totpsecret, sizeof(newUser.totpsecret)) < 0) {
×
UNCOV
3664
      TAOS_CHECK_GOTO(TSDB_CODE_PAR_INVALID_OPTION_VALUE, &lino, _OVER);
×
3665
    }
3666
  }
3667

3668
  if (pAlterReq->hasEnable) {
10,149✔
3669
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "enable:%d,", pAlterReq->enable);
663✔
3670

3671
    newUser.enable = pAlterReq->enable; // lock or unlock user manually
663✔
3672
    if (newUser.enable) {
663✔
3673
      // reset login info to allow login immediately
3674
      userCacheResetLoginInfo(newUser.user);
503✔
3675
    }
3676
  }
3677

3678
  if (pAlterReq->hasSysinfo) {
10,149✔
3679
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "sysinfo:%d,", pAlterReq->sysinfo);
3,537✔
3680
    newUser.sysInfo = pAlterReq->sysinfo;
3,537✔
3681
  }
3682

3683
  if (pAlterReq->hasCreatedb) {
10,149✔
3684
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "createdb:%d,", pAlterReq->createdb);
1,596✔
3685
    newUser.createdb = pAlterReq->createdb;
1,596✔
3686
  }
3687

3688
#ifdef TD_ENTERPRISE
3689
  if (pAlterReq->hasChangepass) {
10,149✔
UNCOV
3690
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "changepass:%d,", pAlterReq->changepass);
×
UNCOV
3691
    newUser.changePass = pAlterReq->changepass;
×
3692
  }
3693

3694
  if (pAlterReq->hasSessionPerUser) {
10,149✔
UNCOV
3695
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "sessionPerUser:%d,", pAlterReq->sessionPerUser);
×
UNCOV
3696
    newUser.sessionPerUser = pAlterReq->sessionPerUser;
×
3697
  }
3698

3699
  if (pAlterReq->hasConnectTime) {
10,149✔
UNCOV
3700
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "connectTime:%d,", pAlterReq->connectTime);
×
UNCOV
3701
    newUser.connectTime = pAlterReq->connectTime;
×
3702
  }
3703
  
3704
  if (pAlterReq->hasConnectIdleTime) {
10,149✔
UNCOV
3705
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "connectIdleTime:%d,", pAlterReq->connectIdleTime);
×
UNCOV
3706
    newUser.connectIdleTime = pAlterReq->connectIdleTime;
×
3707
  }
3708

3709
  if (pAlterReq->hasCallPerSession) {
10,149✔
UNCOV
3710
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "callPerSession:%d,", pAlterReq->callPerSession);
×
UNCOV
3711
    newUser.callPerSession = pAlterReq->callPerSession;
×
3712
  }
3713

3714
  if (pAlterReq->hasVnodePerCall) {
10,149✔
UNCOV
3715
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "vnodePerCall:%d,", pAlterReq->vnodePerCall);
×
UNCOV
3716
    newUser.vnodePerCall = pAlterReq->vnodePerCall;
×
3717
  }
3718

3719
  if (pAlterReq->hasFailedLoginAttempts) {
10,149✔
UNCOV
3720
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "failedLoginAttempts:%d,", pAlterReq->failedLoginAttempts);
×
UNCOV
3721
    newUser.failedLoginAttempts = pAlterReq->failedLoginAttempts;
×
3722
  }
3723

3724
  if (pAlterReq->hasPasswordLifeTime) {
10,149✔
UNCOV
3725
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordLifeTime:%d,", pAlterReq->passwordLifeTime);
×
UNCOV
3726
    newUser.passwordLifeTime = pAlterReq->passwordLifeTime;
×
3727
  }
3728

3729
  if (pAlterReq->hasPasswordReuseTime) {
10,149✔
UNCOV
3730
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordReuseTime:%d,", pAlterReq->passwordReuseTime);
×
UNCOV
3731
    newUser.passwordReuseTime = pAlterReq->passwordReuseTime;
×
3732
  }
3733

3734
  if (pAlterReq->hasPasswordReuseMax) {
10,149✔
3735
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordReuseMax:%d,", pAlterReq->passwordReuseMax);
×
3736
    newUser.passwordReuseMax = pAlterReq->passwordReuseMax;
×
3737
  }
3738

3739
  if (pAlterReq->hasPasswordLockTime) {
10,149✔
UNCOV
3740
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordLockTime:%d,", pAlterReq->passwordLockTime);
×
UNCOV
3741
    newUser.passwordLockTime = pAlterReq->passwordLockTime;
×
3742
  }
3743

3744
  if (pAlterReq->hasPasswordGraceTime) {
10,149✔
UNCOV
3745
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordGraceTime:%d,", pAlterReq->passwordGraceTime);
×
UNCOV
3746
    newUser.passwordGraceTime = pAlterReq->passwordGraceTime;
×
3747
  }
3748

3749
  if (pAlterReq->hasInactiveAccountTime) {
10,149✔
UNCOV
3750
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "inactiveAccountTime:%d,", pAlterReq->inactiveAccountTime);
×
UNCOV
3751
    newUser.inactiveAccountTime = pAlterReq->inactiveAccountTime;
×
3752
  }
3753

3754
  if (pAlterReq->hasAllowTokenNum) {
10,149✔
UNCOV
3755
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "allowTokenNum:%d,", pAlterReq->allowTokenNum);
×
UNCOV
3756
    newUser.allowTokenNum = pAlterReq->allowTokenNum;
×
3757
  }
3758

3759
  if (pAlterReq->numDropIpRanges > 0 || pAlterReq->numIpRanges > 0) {
10,149✔
3760
    int32_t dummy = 0;
320✔
3761

3762
    // put previous ip whitelist into hash table
3763
    SHashObj *m = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
320✔
3764
    if (m == NULL) {
320✔
3765
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3766
    }
3767

3768
    for (int32_t i = 0; i < newUser.pIpWhiteListDual->num; i++) {
1,120✔
3769
      SIpRange range;
800✔
3770
      copyIpRange(&range, newUser.pIpWhiteListDual->pIpRanges + i);
800✔
3771
      code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
800✔
3772
      if (code != 0) {
800✔
UNCOV
3773
        taosHashCleanup(m);
×
3774
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3775
      }
3776
    }
3777

3778
    if (pAlterReq->numDropIpRanges > 0) {
320✔
3779
      auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "dropIpRanges:%d,", pAlterReq->numDropIpRanges);
160✔
3780

3781
      for (int32_t i = 0; i < pAlterReq->numDropIpRanges; i++) {
320✔
3782
        if (taosHashGetSize(m) == 0) {
160✔
UNCOV
3783
          break;
×
3784
        }
3785

3786
        SIpRange range;
160✔
3787
        copyIpRange(&range, pAlterReq->pDropIpRanges + i);
160✔
3788

3789
        // for white list, drop default ip ranges is allowed, otherwise, we can never
3790
        // convert white list to black list.
3791

3792
        code = taosHashRemove(m, &range, sizeof(range));
160✔
3793
        if (code == TSDB_CODE_NOT_FOUND) {
160✔
3794
          // treat not exist as success
3795
          code = 0;
160✔
3796
        }
3797
        if (code != 0) {
160✔
UNCOV
3798
          taosHashCleanup(m);
×
3799
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3800
        }
3801
      }
3802
    }
3803

3804
    if (pAlterReq->numIpRanges > 0) {
320✔
3805
      auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "addIpRanges:%d,", pAlterReq->numIpRanges);
160✔
3806
      for (int32_t i = 0; i < pAlterReq->numIpRanges; i++) {
320✔
3807
        SIpRange range;
160✔
3808
        copyIpRange(&range, pAlterReq->pIpRanges + i);
160✔
3809
        code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
160✔
3810
        if (code != 0) {
160✔
UNCOV
3811
          taosHashCleanup(m);
×
UNCOV
3812
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3813
        }
3814
      }
3815
    }
3816

3817
    int32_t numOfRanges = taosHashGetSize(m);
320✔
3818
    if (numOfRanges > MND_MAX_USER_IP_RANGE) {
320✔
3819
      taosHashCleanup(m);
×
3820
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_IP_RANGE, &lino, _OVER);
×
3821
    }
3822

3823
    SIpWhiteListDual *p = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + numOfRanges * sizeof(SIpRange));
320✔
3824
    if (p == NULL) {
320✔
3825
      taosHashCleanup(m);
×
UNCOV
3826
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3827
    }
3828

3829
    void *pIter = taosHashIterate(m, NULL);
320✔
3830
    int32_t i = 0;
320✔
3831
    while (pIter) {
1,280✔
3832
      size_t len = 0;
960✔
3833
      SIpRange *key = taosHashGetKey(pIter, &len);
960✔
3834
      memcpy(p->pIpRanges + i, key, sizeof(SIpRange));
960✔
3835
      pIter = taosHashIterate(m, pIter);
960✔
3836
      i++;
960✔
3837
    }
3838

3839
    taosHashCleanup(m);
320✔
3840
    p->num = numOfRanges;
320✔
3841
    taosMemoryFreeClear(newUser.pIpWhiteListDual);
320✔
3842
    sortIpWhiteList(p);
320✔
3843
    newUser.pIpWhiteListDual = p;
320✔
3844

3845
    newUser.ipWhiteListVer++;
320✔
3846
  }
3847

3848

3849
  if (pAlterReq->numTimeRanges > 0 || pAlterReq->numDropTimeRanges) {
10,149✔
UNCOV
3850
    int32_t dummy = 0;
×
3851

3852
    // put previous ip whitelist into hash table
UNCOV
3853
    SHashObj *m = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
×
UNCOV
3854
    if (m == NULL) {
×
UNCOV
3855
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3856
    }
3857

UNCOV
3858
    for (int32_t i = 0; i < newUser.pTimeWhiteList->num; i++) {
×
UNCOV
3859
      SDateTimeWhiteListItem *range = &newUser.pTimeWhiteList->ranges[i];
×
UNCOV
3860
      if (isDateTimeWhiteListItemExpired(range)) {
×
UNCOV
3861
        continue;
×
3862
      }
UNCOV
3863
      code = taosHashPut(m, range, sizeof(*range), &dummy, sizeof(dummy));
×
UNCOV
3864
      if (code != 0) {
×
UNCOV
3865
        taosHashCleanup(m);
×
UNCOV
3866
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3867
      }
3868
    }
3869

UNCOV
3870
    if (pAlterReq->numDropTimeRanges > 0) {
×
UNCOV
3871
      auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "dropTimeRanges:%d,", pAlterReq->numDropTimeRanges);
×
3872
      for (int32_t i = 0; i < pAlterReq->numDropTimeRanges; i++) {
×
3873
        if (taosHashGetSize(m) == 0) {
×
UNCOV
3874
          break;
×
3875
        }
UNCOV
3876
        SDateTimeWhiteListItem range = { 0 };
×
UNCOV
3877
        DateTimeRangeToWhiteListItem(&range, pAlterReq->pDropTimeRanges + i);
×
3878

UNCOV
3879
        code = taosHashRemove(m, &range, sizeof(range));
×
UNCOV
3880
        if (code == TSDB_CODE_NOT_FOUND) {
×
3881
          // treat not exist as success
UNCOV
3882
          code = 0;
×
3883
        }
UNCOV
3884
        if (code != 0) {
×
3885
          taosHashCleanup(m);
×
3886
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3887
        }
3888
      }
3889
    }
3890

UNCOV
3891
    if (pAlterReq->numTimeRanges > 0) {
×
UNCOV
3892
      auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "addTimeRanges:%d,", pAlterReq->numTimeRanges);
×
3893
      for (int32_t i = 0; i < pAlterReq->numTimeRanges; i++) {
×
3894
        SDateTimeWhiteListItem range = { 0 };
×
UNCOV
3895
        DateTimeRangeToWhiteListItem(&range, pAlterReq->pTimeRanges + i);
×
UNCOV
3896
        if (isDateTimeWhiteListItemExpired(&range)) {
×
UNCOV
3897
          continue;
×
3898
        }
3899
        code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
×
3900
        if (code != 0) {
×
UNCOV
3901
          taosHashCleanup(m);
×
UNCOV
3902
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3903
        }
3904
      }
3905
    }
3906

UNCOV
3907
    int32_t numOfRanges = taosHashGetSize(m);
×
UNCOV
3908
    if (numOfRanges > MND_MAX_USER_TIME_RANGE) {
×
UNCOV
3909
      taosHashCleanup(m);
×
UNCOV
3910
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_TIME_RANGE, &lino, _OVER);
×
3911
    }
3912

UNCOV
3913
    SDateTimeWhiteList *p = taosMemoryCalloc(1, sizeof(SDateTimeWhiteList) + numOfRanges * sizeof(SDateTimeWhiteListItem));
×
UNCOV
3914
    if (p == NULL) {
×
UNCOV
3915
      taosHashCleanup(m);
×
UNCOV
3916
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3917
    }
3918

UNCOV
3919
    void *pIter = taosHashIterate(m, NULL);
×
UNCOV
3920
    int32_t i = 0;
×
UNCOV
3921
    while (pIter) {
×
UNCOV
3922
      size_t len = 0;
×
UNCOV
3923
      SDateTimeWhiteListItem *key = taosHashGetKey(pIter, &len);
×
3924
      memcpy(&p->ranges[i], key, sizeof(SDateTimeWhiteListItem));
×
UNCOV
3925
      pIter = taosHashIterate(m, pIter);
×
UNCOV
3926
      i++;
×
3927
    }
3928

3929
    taosHashCleanup(m);
×
UNCOV
3930
    p->num = numOfRanges;
×
UNCOV
3931
    taosMemoryFreeClear(newUser.pTimeWhiteList);
×
3932
    sortTimeWhiteList(p);
×
3933
    newUser.pTimeWhiteList = p;
×
3934
    newUser.timeWhiteListVer++;
×
3935
  }
3936
#endif // TD_ENTERPRISE
3937

3938
  TAOS_CHECK_GOTO(mndAlterUser(pMnode, &newUser, pReq), &lino, _OVER);
10,149✔
3939
  code = TSDB_CODE_ACTION_IN_PROGRESS;
10,149✔
3940

3941
  if (auditLen > 0) {
10,149✔
3942
    auditLog[--auditLen] = 0; // remove last ','
10,149✔
3943
  }
3944
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
10,149✔
3945
    int64_t tse = taosGetTimestampMs();
10,149✔
3946
    double  duration = (double)(tse - tss);
10,149✔
3947
    duration = duration / 1000;
10,149✔
3948
    auditRecord(pReq, pMnode->clusterId, "alterUser", "", pAlterReq->user, auditLog, auditLen, duration, 0);
10,149✔
3949
  }
3950

3951
_OVER:
12,412✔
3952
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
12,412✔
3953
    mError("user:%s, failed to alter at line %d since %s", pAlterReq->user, lino, tstrerror(code));
2,263✔
3954
  }
3955

3956
  mndReleaseUser(pMnode, pUser);
12,412✔
3957
  mndUserFreeObj(&newUser);
12,412✔
3958
  return code;
12,412✔
3959
}
3960

3961

3962

3963
static int32_t mndProcessAlterUserReq(SRpcMsg *pReq) {
12,412✔
3964
  SAlterUserReq alterReq = {0};
12,412✔
3965

3966
  int32_t code = tDeserializeSAlterUserReq(pReq->pCont, pReq->contLen, &alterReq);
12,412✔
3967
  if (code != 0) {
12,412✔
3968
    mError("failed to deserialize alter user request at line %d since %s", __LINE__, tstrerror(code));
×
3969
    TAOS_RETURN(code);
×
3970
  }
3971

3972
  if (alterReq.user[0] == 0) {
12,412✔
UNCOV
3973
    tFreeSAlterUserReq(&alterReq);
×
3974
    mError("failed to alter user at line %d since invalid user format", __LINE__);
×
3975
    TAOS_RETURN(TSDB_CODE_MND_INVALID_USER_FORMAT);
×
3976
  }
3977

3978
  mInfo("user:%s, start to alter", alterReq.user);
12,412✔
3979
  if (alterReq.alterType == TSDB_ALTER_USER_BASIC_INFO) {
12,412✔
3980
    code = mndProcessAlterUserBasicInfoReq(pReq, &alterReq);
12,412✔
3981
  } else {
3982
    // code = mndProcessAlterUserPrivilegesReq(pReq, &alterReq); // obsolete
3983
  }
3984

3985
  tFreeSAlterUserReq(&alterReq);
12,412✔
3986
  TAOS_RETURN(code);
12,412✔
3987
}
3988

3989
int32_t mndGetAuditUser(SMnode *pMnode, char* user){
54,647,865✔
3990
  (void)tsnprintf(user, TSDB_USER_LEN, "audit");
54,647,865✔
3991
  return 0;
54,647,865✔
3992
}
3993

3994
static int32_t mndDropUser(SMnode *pMnode, SRpcMsg *pReq, SUserObj *pUser) {
19,754✔
3995
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "drop-user");
19,754✔
3996
  if (pTrans == NULL) {
19,754✔
3997
    mError("user:%s, failed to drop since %s", pUser->user, terrstr());
×
3998
    TAOS_RETURN(terrno);
×
3999
  }
4000
  mInfo("trans:%d, used to drop user:%s", pTrans->id, pUser->user);
19,754✔
4001

4002
  SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
19,754✔
4003
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
19,754✔
4004
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
4005
    mndTransDrop(pTrans);
×
4006
    TAOS_RETURN(terrno);
×
4007
  }
4008
  if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED) < 0) {
19,754✔
4009
    mndTransDrop(pTrans);
×
UNCOV
4010
    TAOS_RETURN(terrno);
×
4011
  }
4012

4013
  if (mndDropTokensByUser(pMnode, pTrans, pUser->user) != 0) {
19,754✔
UNCOV
4014
    mndTransDrop(pTrans);
×
UNCOV
4015
    TAOS_RETURN(terrno);
×
4016
  }
4017

4018
  if (mndTransPrepare(pMnode, pTrans) != 0) {
19,754✔
UNCOV
4019
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
UNCOV
4020
    mndTransDrop(pTrans);
×
UNCOV
4021
    TAOS_RETURN(terrno);
×
4022
  }
4023

4024
  userCacheRemoveUser(pUser->user);
19,754✔
4025
  mndDropCachedTokensByUser(pUser->user);
19,754✔
4026

4027
  mndTransDrop(pTrans);
19,754✔
4028
  TAOS_RETURN(0);
19,754✔
4029
}
4030

4031
static int32_t mndProcessDropUserReq(SRpcMsg *pReq) {
19,754✔
4032
  SMnode      *pMnode = pReq->info.node;
19,754✔
4033
  int32_t      code = 0;
19,754✔
4034
  int32_t      lino = 0;
19,754✔
4035
  SUserObj    *pOperUser = NULL;
19,754✔
4036
  SUserObj    *pUser = NULL;
19,754✔
4037
  SDropUserReq dropReq = {0};
19,754✔
4038
  int64_t      tss = taosGetTimestampMs();
19,754✔
4039

4040
  TAOS_CHECK_GOTO(tDeserializeSDropUserReq(pReq->pCont, pReq->contLen, &dropReq), &lino, _OVER);
19,754✔
4041

4042
  mInfo("user:%s, start to drop", dropReq.user);
19,754✔
4043

4044
  if (dropReq.user[0] == 0) {
19,754✔
UNCOV
4045
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
4046
  }
4047

4048
  if (0 == strcmp(dropReq.user, TSDB_DEFAULT_USER)) {
19,754✔
4049
    return TSDB_CODE_MND_NO_RIGHTS;
×
4050
  }
4051

4052
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, dropReq.user, &pUser), &lino, _OVER);
19,754✔
4053

4054
  code = mndAcquireUser(pMnode, RPC_MSG_USER(pReq), &pOperUser);
19,754✔
4055
  if (pOperUser == NULL) {
19,754✔
UNCOV
4056
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_USER_FROM_CONN, &lino, _OVER);
×
4057
  }
4058

4059
  // TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, RPC_MSG_USER(pReq), MND_OPER_DROP_USER), &lino, _OVER);
4060
  TAOS_CHECK_GOTO(mndCheckSysObjPrivilege(pMnode, pOperUser, PRIV_USER_DROP, 0, 0, NULL, NULL), &lino, _OVER);
19,754✔
4061

4062
  TAOS_CHECK_GOTO(mndDropUser(pMnode, pReq, pUser), &lino, _OVER);
19,754✔
4063
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
19,754✔
4064

4065
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
19,754✔
4066
    int64_t tse = taosGetTimestampMs();
19,754✔
4067
    double  duration = (double)(tse - tss);
19,754✔
4068
    duration = duration / 1000;
19,754✔
4069
    auditRecord(pReq, pMnode->clusterId, "dropUser", "", dropReq.user, dropReq.sql, dropReq.sqlLen, duration, 0);
19,754✔
4070
  }
4071

4072
_OVER:
19,754✔
4073
  if (dropReq.ignoreNotExists && code == TSDB_CODE_MND_USER_NOT_EXIST) {
19,754✔
UNCOV
4074
    code = 0;
×
4075
  } else if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
19,754✔
UNCOV
4076
    mError("user:%s, failed to drop at line %d since %s", dropReq.user, lino, tstrerror(code));
×
4077
  }
4078

4079
  mndReleaseUser(pMnode, pUser);
19,754✔
4080
  mndReleaseUser(pMnode, pOperUser);
19,754✔
4081
  tFreeSDropUserReq(&dropReq);
19,754✔
4082
  TAOS_RETURN(code);
19,754✔
4083
}
4084

4085
static int32_t mndProcessGetUserAuthReq(SRpcMsg *pReq) {
6,275,268✔
4086
  SMnode         *pMnode = pReq->info.node;
6,275,268✔
4087
  int32_t         code = 0;
6,275,268✔
4088
  int32_t         lino = 0;
6,275,268✔
4089
  int32_t         contLen = 0;
6,275,268✔
4090
  void           *pRsp = NULL;
6,275,268✔
4091
  SUserObj       *pUser = NULL;
6,275,268✔
4092
  SGetUserAuthReq authReq = {0};
6,275,268✔
4093
  SGetUserAuthRsp authRsp = {0};
6,275,268✔
4094

4095
  TAOS_CHECK_EXIT(tDeserializeSGetUserAuthReq(pReq->pCont, pReq->contLen, &authReq));
6,275,268✔
4096
  mTrace("user:%s, start to get auth", authReq.user);
6,275,268✔
4097

4098
  TAOS_CHECK_EXIT(mndAcquireUser(pMnode, authReq.user, &pUser));
6,275,268✔
4099

4100
  TAOS_CHECK_EXIT(mndSetUserAuthRsp(pMnode, pUser, &authRsp));
6,275,268✔
4101

4102
  contLen = tSerializeSGetUserAuthRsp(NULL, 0, &authRsp);
6,275,268✔
4103
  if (contLen < 0) {
6,275,268✔
UNCOV
4104
    TAOS_CHECK_EXIT(contLen);
×
4105
  }
4106
  pRsp = rpcMallocCont(contLen);
6,275,268✔
4107
  if (pRsp == NULL) {
6,275,268✔
UNCOV
4108
    TAOS_CHECK_EXIT(terrno);
×
4109
  }
4110

4111
  contLen = tSerializeSGetUserAuthRsp(pRsp, contLen, &authRsp);
6,275,268✔
4112
  if (contLen < 0) {
6,275,268✔
UNCOV
4113
    TAOS_CHECK_EXIT(contLen);
×
4114
  }
4115

4116
_exit:
6,275,268✔
4117
  mndReleaseUser(pMnode, pUser);
6,275,268✔
4118
  tFreeSGetUserAuthRsp(&authRsp);
6,275,268✔
4119
  if (code < 0) {
6,274,752✔
4120
    mError("user:%s, failed to get auth at line %d since %s", authReq.user, lino, tstrerror(code));
×
UNCOV
4121
    rpcFreeCont(pRsp);
×
UNCOV
4122
    pRsp = NULL;
×
UNCOV
4123
    contLen = 0;
×
4124
  }
4125
  pReq->info.rsp = pRsp;
6,274,752✔
4126
  pReq->info.rspLen = contLen;
6,275,268✔
4127
  pReq->code = code;
6,275,268✔
4128

4129
  TAOS_RETURN(code);
6,274,752✔
4130
}
4131

4132

4133

4134
static void base32Encode(const uint8_t *in, int32_t inLen, char *out) {
42✔
4135
  int buffer = 0, bits = 0;
42✔
4136
  int outLen = 0;
42✔
4137

4138
  // process all input bytes
4139
  for (int i = 0; i < inLen; i++) {
1,386✔
4140
    buffer = (buffer << 8) | in[i];
1,344✔
4141
    bits += 8;
1,344✔
4142

4143
    while (bits >= 5) {
3,486✔
4144
      int v = (buffer >> (bits - 5)) & 0x1F;
2,142✔
4145
      out[outLen++] = (v >= 26) ? (v - 26 + '2') : (v + 'A');
2,142✔
4146
      bits -= 5;
2,142✔
4147
    }
4148
  }
4149

4150
  // process remaining bits
4151
  if (bits > 0) {
42✔
4152
    int v = (buffer << (5 - bits)) & 0x1F;
42✔
4153
    out[outLen++] = (v >= 26) ? (v - 26 + '2') : (v + 'A');
42✔
4154
  }
4155

4156
  out[outLen] = '\0';
42✔
4157
}
42✔
4158

4159

4160
static int32_t mndCreateTotpSecret(SMnode *pMnode, SUserObj *pUser, SRpcMsg *pReq) {
42✔
4161
  SCreateTotpSecretRsp rsp = {0};
42✔
4162

4163
  base32Encode((uint8_t *)pUser->totpsecret, sizeof(pUser->totpsecret), rsp.totpSecret);
42✔
4164
  tstrncpy(rsp.user, pUser->user, sizeof(rsp.user));
42✔
4165

4166
  int32_t len = tSerializeSCreateTotpSecretRsp(NULL, 0, &rsp);
42✔
4167
  if (len < 0) {
42✔
UNCOV
4168
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
4169
  }
4170

4171
  void *pData = taosMemoryMalloc(len);
42✔
4172
  if (pData == NULL) {
42✔
UNCOV
4173
    TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
4174
  }
4175

4176
  if (tSerializeSCreateTotpSecretRsp(pData, len, &rsp) != len) {
42✔
UNCOV
4177
    taosMemoryFree(pData);
×
UNCOV
4178
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
4179
  }
4180

4181
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "create-totp-secret");
42✔
4182
  if (pTrans == NULL) {
42✔
4183
    mError("user:%s, failed to create totp secret since %s", pUser->user, terrstr());
×
UNCOV
4184
    taosMemoryFree(pData);
×
UNCOV
4185
    TAOS_RETURN(terrno);
×
4186
  }
4187
  mInfo("trans:%d, used to create totp secret for user:%s", pTrans->id, pUser->user);
42✔
4188

4189
  mndTransSetUserData(pTrans, pData, len);
42✔
4190

4191
  SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
42✔
4192
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
42✔
UNCOV
4193
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
UNCOV
4194
    mndTransDrop(pTrans);
×
4195
    TAOS_RETURN(terrno);
×
4196
  }
4197
  if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY) < 0) {
42✔
4198
    mndTransDrop(pTrans);
×
UNCOV
4199
    TAOS_RETURN(terrno);
×
4200
  }
4201

4202
  if (mndTransPrepare(pMnode, pTrans) != 0) {
42✔
UNCOV
4203
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
UNCOV
4204
    mndTransDrop(pTrans);
×
UNCOV
4205
    TAOS_RETURN(terrno);
×
4206
  }
4207

4208
  mndTransDrop(pTrans);
42✔
4209
  TAOS_RETURN(0);
42✔
4210
}
4211

4212

4213
static int32_t mndProcessCreateTotpSecretReq(SRpcMsg *pReq) {
42✔
4214
  SMnode              *pMnode = pReq->info.node;
42✔
4215
  int32_t              code = 0;
42✔
4216
  int32_t              lino = 0;
42✔
4217
  SUserObj            *pUser = NULL;
42✔
4218
  SUserObj             newUser = {0};
42✔
4219
  SCreateTotpSecretReq req = {0};
42✔
4220
  int64_t              tss = taosGetTimestampMs();
42✔
4221

4222
  TAOS_CHECK_GOTO(tDeserializeSCreateTotpSecretReq(pReq->pCont, pReq->contLen, &req), &lino, _OVER);
42✔
4223
  mTrace("user:%s, start to create/update totp secret", req.user);
42✔
4224

4225
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, req.user, &pUser), &lino, _OVER);
42✔
4226
  TAOS_CHECK_GOTO(mndCheckTotpSecretPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser), &lino, _OVER);
42✔
4227
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
42✔
4228
  taosSafeRandBytes((uint8_t *)newUser.totpsecret, sizeof(newUser.totpsecret));
42✔
4229
  TAOS_CHECK_GOTO(mndCreateTotpSecret(pMnode, &newUser, pReq), &lino, _OVER); 
42✔
4230

4231
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
42✔
4232
    double  duration = (double)(taosGetTimestampMs()- tss) / 1000.0;
42✔
4233
    auditRecord(pReq, pMnode->clusterId, "createTotpSecret", "", req.user, req.sql, req.sqlLen, duration, 0);
42✔
4234
  }
4235

4236
_OVER:
42✔
4237
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
42✔
UNCOV
4238
    mError("user:%s, failed to create totp secret at line %d since %s", req.user, lino, tstrerror(code));
×
4239
  }
4240
  mndReleaseUser(pMnode, pUser);
42✔
4241
  mndUserFreeObj(&newUser);
42✔
4242
  tFreeSCreateTotpSecretReq(&req);
42✔
4243
  TAOS_RETURN(code);
42✔
4244
}
4245

4246

4247

4248
int32_t mndBuildSMCreateTotpSecretResp(STrans *pTrans, void **ppResp, int32_t *pRespLen) {
42✔
4249
  // user data is the response
4250
  *ppResp = pTrans->userData;
42✔
4251
  *pRespLen = pTrans->userDataLen;
42✔
4252
  pTrans->userData = NULL;
42✔
4253
  pTrans->userDataLen = 0;
42✔
4254
  return 0;
42✔
4255
}
4256

4257

4258

4259
static int32_t mndProcessDropTotpSecretReq(SRpcMsg *pReq) {
×
4260
  SMnode            *pMnode = pReq->info.node;
×
UNCOV
4261
  int32_t            code = 0;
×
UNCOV
4262
  int32_t            lino = 0;
×
UNCOV
4263
  SUserObj          *pUser = NULL;
×
UNCOV
4264
  SDropTotpSecretReq req = {0};
×
UNCOV
4265
  int64_t            tss = taosGetTimestampMs();
×
4266

UNCOV
4267
  TAOS_CHECK_GOTO(tDeserializeSDropTotpSecretReq(pReq->pCont, pReq->contLen, &req), &lino, _OVER);
×
4268
  mTrace("user:%s, start to drop totp secret", req.user);
×
4269

4270
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, req.user, &pUser), &lino, _OVER);
×
UNCOV
4271
  TAOS_CHECK_GOTO(mndCheckTotpSecretPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser), &lino, _OVER);
×
4272

4273
  SUserObj newUser = {0};
×
4274
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
×
UNCOV
4275
  (void)memset(newUser.totpsecret, 0, sizeof(newUser.totpsecret));
×
UNCOV
4276
  TAOS_CHECK_GOTO(mndAlterUser(pMnode, &newUser, pReq), &lino, _OVER); 
×
4277

4278
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
×
4279
    double  duration = (double)(taosGetTimestampMs()- tss) / 1000.0;
×
4280
    auditRecord(pReq, pMnode->clusterId, "dropTotpSecret", "", req.user, req.sql, req.sqlLen, duration, 0);
×
4281
  }
4282

UNCOV
4283
_OVER:
×
UNCOV
4284
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
×
UNCOV
4285
    mError("user:%s, failed to drop totp secret at line %d since %s", req.user, lino, tstrerror(code));
×
4286
  }
UNCOV
4287
  mndReleaseUser(pMnode, pUser);
×
UNCOV
4288
  mndUserFreeObj(&newUser);
×
UNCOV
4289
  tFreeSDropTotpSecretReq(&req);
×
UNCOV
4290
  TAOS_RETURN(code);
×
4291
}
4292

4293

4294

4295
bool mndIsTotpEnabledUser(SUserObj *pUser) {
2,400,571✔
4296
  for (int32_t i = 0; i < sizeof(pUser->totpsecret); i++) {
79,211,909✔
4297
    if (pUser->totpsecret[i] != 0) {
76,807,238✔
4298
      return true;
84✔
4299
    }
4300
  }
4301
  return false;
2,404,671✔
4302
}
4303

4304

4305
static int32_t mndRetrieveUsers(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
7,473✔
4306
  SMnode   *pMnode = pReq->info.node;
7,473✔
4307
  SSdb     *pSdb = pMnode->pSdb;
7,473✔
4308
  int32_t   code = 0;
7,473✔
4309
  int32_t   lino = 0;
7,473✔
4310
  int32_t   numOfRows = 0;
7,473✔
4311
  SUserObj *pUser = NULL;
7,473✔
4312
  int32_t   cols = 0;
7,473✔
4313
  int8_t    flag = 0;
7,473✔
4314
  char     *pWrite = NULL;
7,473✔
4315
  char     *buf = NULL;
7,473✔
4316
  char     *varstr = NULL;
7,473✔
4317
  char      tBuf[TSDB_MAX_SUBROLE * TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
7,473✔
4318
  int32_t   bufSize = sizeof(tBuf) - VARSTR_HEADER_SIZE;
7,473✔
4319

4320
  while (numOfRows < rows) {
26,451✔
4321
    pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
26,451✔
4322
    if (pShow->pIter == NULL) break;
26,451✔
4323

4324
    cols = 0;
18,978✔
4325
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
18,978✔
4326
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
18,978✔
4327
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
18,978✔
4328
    COL_DATA_SET_VAL_GOTO((const char *)name, false, pUser, pShow->pIter, _exit);
18,978✔
4329

4330
    cols++;
18,978✔
4331
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
18,978✔
4332
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->superUser, false, pUser, pShow->pIter, _exit);
18,978✔
4333

4334
    cols++;
18,978✔
4335
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
18,978✔
4336
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->enable, false, pUser, pShow->pIter, _exit);
18,978✔
4337

4338
    cols++;
18,978✔
4339
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
18,978✔
4340
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sysInfo, false, pUser, pShow->pIter, _exit);
18,978✔
4341

4342
    cols++;
18,978✔
4343
    flag = pUser->createdb ? 1 : 0;
18,978✔
4344
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
18,978✔
4345
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
18,978✔
4346

4347
    cols++;
18,978✔
4348
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
18,978✔
4349
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->createdTime, false, pUser, pShow->pIter, _exit);
18,978✔
4350

4351
    cols++;
18,978✔
4352
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
18,978✔
4353
    flag = mndIsTotpEnabledUser(pUser) ? 1 : 0;
18,978✔
4354
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
18,978✔
4355

4356
    cols++;
18,978✔
4357

4358
    int32_t tlen = convertIpWhiteListToStr(pUser, &buf);
18,978✔
4359
    if (tlen != 0) {
18,978✔
4360
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
18,978✔
4361
      if (varstr == NULL) {
18,978✔
4362
        sdbRelease(pSdb, pUser);
×
4363
        sdbCancelFetch(pSdb, pShow->pIter);
×
4364
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
4365
      }
4366
      varDataSetLen(varstr, tlen);
18,978✔
4367
      (void)memcpy(varDataVal(varstr), buf, tlen);
18,978✔
4368

4369
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
18,978✔
4370
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
18,978✔
4371

4372
      taosMemoryFreeClear(buf);
18,978✔
4373
    } else {
UNCOV
4374
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4375
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
4376
    }
4377

4378
    cols++;
18,978✔
4379
    tlen = convertTimeRangesToStr(pUser, &buf);
18,978✔
4380
    if (tlen != 0) {
18,978✔
4381
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
18,978✔
4382
      if (varstr == NULL) {
18,978✔
UNCOV
4383
        sdbRelease(pSdb, pUser);
×
UNCOV
4384
        sdbCancelFetch(pSdb, pShow->pIter);
×
UNCOV
4385
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
4386
      }
4387
      varDataSetLen(varstr, tlen);
18,978✔
4388
      (void)memcpy(varDataVal(varstr), buf, tlen);
18,978✔
4389

4390
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
18,978✔
4391
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
18,978✔
4392

4393
      taosMemoryFreeClear(buf);
18,978✔
4394
    } else {
UNCOV
4395
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4396
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
4397
    }
4398

4399
    if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
18,978✔
4400
      void  *pIter = NULL;
18,978✔
4401
      size_t klen = 0, tlen = 0;
18,978✔
4402
      char  *pBuf = POINTER_SHIFT(tBuf, VARSTR_HEADER_SIZE);
18,978✔
4403
      while ((pIter = taosHashIterate(pUser->roles, pIter))) {
53,222✔
4404
        char *roleName = taosHashGetKey(pIter, &klen);
34,244✔
4405
        tlen += snprintf(pBuf + tlen, bufSize - tlen, "%s,", roleName);
34,244✔
4406
      }
4407
      if (tlen > 0) {
18,978✔
4408
        pBuf[tlen - 1] = 0;  // remove last ','
18,978✔
4409
      } else {
UNCOV
4410
        pBuf[0] = 0;
×
4411
      }
4412
      varDataSetLen(tBuf, tlen);
18,978✔
4413
      COL_DATA_SET_VAL_GOTO((const char *)tBuf, false, pUser, pShow->pIter, _exit);
18,978✔
4414
    }
4415

4416
    numOfRows++;
18,978✔
4417
    sdbRelease(pSdb, pUser);
18,978✔
4418
  }
4419

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

UNCOV
4431
static int32_t mndRetrieveUsersFull(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
×
UNCOV
4432
  int32_t numOfRows = 0;
×
4433
#ifdef TD_ENTERPRISE
UNCOV
4434
  SMnode   *pMnode = pReq->info.node;
×
UNCOV
4435
  SSdb     *pSdb = pMnode->pSdb;
×
UNCOV
4436
  SUserObj *pUser = NULL;
×
4437
  int32_t   code = 0;
×
4438
  int32_t   lino = 0;
×
4439
  int32_t   cols = 0;
×
UNCOV
4440
  int8_t    flag = 0;
×
UNCOV
4441
  char     *pWrite = NULL;
×
UNCOV
4442
  char     *buf = NULL;
×
UNCOV
4443
  char     *varstr = NULL;
×
UNCOV
4444
  char     *pBuf = NULL;
×
UNCOV
4445
  char      tBuf[TSDB_MAX_SUBROLE * TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
×
UNCOV
4446
  int32_t   bufSize = sizeof(tBuf) - VARSTR_HEADER_SIZE;
×
4447

UNCOV
4448
  while (numOfRows < rows) {
×
4449
    pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
×
4450
    if (pShow->pIter == NULL) break;
×
4451

UNCOV
4452
    cols = 0;
×
UNCOV
4453
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4454
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
×
UNCOV
4455
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
×
UNCOV
4456
    COL_DATA_SET_VAL_GOTO((const char *)name, false, pUser, pShow->pIter, _exit);
×
4457

4458
    cols++;
×
4459
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4460
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->superUser, false, pUser, pShow->pIter, _exit);
×
4461

UNCOV
4462
    cols++;
×
UNCOV
4463
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4464
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->enable, false, pUser, pShow->pIter, _exit);
×
4465

UNCOV
4466
    cols++;
×
UNCOV
4467
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4468
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sysInfo, false, pUser, pShow->pIter, _exit);
×
4469

4470
    cols++;
×
4471
    flag = pUser->createdb ? 1 : 0;
×
UNCOV
4472
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4473
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
×
4474

UNCOV
4475
    cols++;
×
UNCOV
4476
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4477
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->createdTime, false, pUser, pShow->pIter, _exit);
×
4478

UNCOV
4479
    cols++;
×
UNCOV
4480
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4481
    flag = mndIsTotpEnabledUser(pUser) ? 1 : 0;
×
UNCOV
4482
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
×
4483

UNCOV
4484
    cols++;
×
4485
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4486
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->changePass, false, pUser, pShow->pIter, _exit);
×
4487

UNCOV
4488
    cols++;
×
UNCOV
4489
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4490
    char pass[TSDB_PASSWORD_LEN + VARSTR_HEADER_SIZE] = {0};
×
UNCOV
4491
    STR_WITH_MAXSIZE_TO_VARSTR(pass, pUser->passwords[0].pass, pShow->pMeta->pSchemas[cols].bytes);
×
UNCOV
4492
    COL_DATA_SET_VAL_GOTO((const char *)pass, false, pUser, pShow->pIter, _exit);
×
4493

UNCOV
4494
    cols++;
×
UNCOV
4495
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4496
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sessionPerUser, false, pUser, pShow->pIter, _exit);
×
4497

UNCOV
4498
    cols++;
×
UNCOV
4499
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4500
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->connectTime, false, pUser, pShow->pIter, _exit);
×
4501

UNCOV
4502
    cols++;
×
UNCOV
4503
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4504
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->connectIdleTime, false, pUser, pShow->pIter, _exit);
×
4505

4506
    cols++;
×
4507
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4508
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->callPerSession, false, pUser, pShow->pIter, _exit);
×
4509

4510
    cols++;
×
4511
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4512
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->vnodePerCall, false, pUser, pShow->pIter, _exit);
×
4513

4514
    cols++;
×
4515
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4516
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->failedLoginAttempts, false, pUser, pShow->pIter, _exit);
×
4517

4518
    cols++;
×
4519
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4520
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordLifeTime, false, pUser, pShow->pIter, _exit);
×
4521

UNCOV
4522
    cols++;
×
4523
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4524
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordReuseTime, false, pUser, pShow->pIter, _exit);
×
4525

UNCOV
4526
    cols++;
×
4527
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4528
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordReuseMax, false, pUser, pShow->pIter, _exit);
×
4529

4530
    cols++;
×
4531
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4532
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordLockTime, false, pUser, pShow->pIter, _exit);
×
4533

4534
    cols++;
×
4535
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4536
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordGraceTime, false, pUser, pShow->pIter, _exit);
×
4537

4538
    cols++;
×
4539
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4540
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->inactiveAccountTime, false, pUser, pShow->pIter, _exit);
×
4541

4542
    cols++;
×
4543
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4544
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->allowTokenNum, false, pUser, pShow->pIter, _exit);
×
4545

4546
    cols++;
×
4547
    int32_t tlen = convertIpWhiteListToStr(pUser, &buf);
×
4548
    if (tlen != 0) {
×
UNCOV
4549
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
×
4550
      if (varstr == NULL) {
×
4551
        sdbRelease(pSdb, pUser);
×
4552
        sdbCancelFetch(pSdb, pShow->pIter);
×
UNCOV
4553
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
4554
      }
4555
      varDataSetLen(varstr, tlen);
×
4556
      (void)memcpy(varDataVal(varstr), buf, tlen);
×
4557

UNCOV
4558
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4559
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
×
4560

4561
      taosMemoryFreeClear(buf);
×
4562
    } else {
4563
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4564
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
4565
    }
4566

4567
    cols++;
×
UNCOV
4568
    tlen = convertTimeRangesToStr(pUser, &buf);
×
4569
    if (tlen != 0) {
×
4570
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
×
4571
      if (varstr == NULL) {
×
UNCOV
4572
        sdbRelease(pSdb, pUser);
×
4573
        sdbCancelFetch(pSdb, pShow->pIter);
×
4574
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
4575
      }
UNCOV
4576
      varDataSetLen(varstr, tlen);
×
4577
      (void)memcpy(varDataVal(varstr), buf, tlen);
×
4578

4579
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4580
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
×
4581

4582
      taosMemoryFreeClear(buf);
×
4583
    } else {
UNCOV
4584
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4585
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
4586
    }
4587

UNCOV
4588
    if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
×
4589
      void  *pIter = NULL;
×
4590
      size_t klen = 0, tlen = 0;
×
4591
      char  *pBuf = POINTER_SHIFT(tBuf, VARSTR_HEADER_SIZE);
×
UNCOV
4592
      while ((pIter = taosHashIterate(pUser->roles, pIter))) {
×
4593
        char *roleName = taosHashGetKey(pIter, &klen);
×
4594
        tlen += snprintf(pBuf + tlen, bufSize - tlen, "%s,", roleName);
×
4595
      }
UNCOV
4596
      if (tlen > 0) {
×
4597
        pBuf[tlen - 1] = 0;  // remove last ','
×
4598
      } else {
4599
        pBuf[0] = 0;
×
4600
      }
4601
      varDataSetLen(tBuf, tlen);
×
4602
      COL_DATA_SET_VAL_GOTO((const char *)tBuf, false, pUser, pShow->pIter, _exit);
×
4603
    }
4604

4605
    numOfRows++;
×
4606
    sdbRelease(pSdb, pUser);
×
4607
  }
4608

4609
  pShow->numOfRows += numOfRows;
×
4610
_exit:
×
4611
  taosMemoryFreeClear(buf);
×
UNCOV
4612
  taosMemoryFreeClear(varstr);
×
4613
  if (code < 0) {
×
4614
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4615
    TAOS_RETURN(code);
×
4616
  }
4617
#endif
4618
  return numOfRows;
×
4619
}
4620

4621
static void mndCancelGetNextUser(SMnode *pMnode, void *pIter) {
×
4622
  SSdb *pSdb = pMnode->pSdb;
×
4623
  sdbCancelFetchByType(pSdb, pIter, SDB_USER);
×
4624
}
×
4625

4626
static int32_t mndLoopHash(SHashObj *hash, char *priType, SSDataBlock *pBlock, int32_t *pNumOfRows, SSdb *pSdb,
×
4627
                           SUserObj *pUser, SShowObj *pShow, char **condition, char **sql) {
4628
  char   *value = taosHashIterate(hash, NULL);
×
UNCOV
4629
  char   *user = pUser->user;
×
4630
  int32_t code = 0;
×
4631
  int32_t lino = 0;
×
UNCOV
4632
  int32_t cols = 0;
×
4633
  int32_t numOfRows = *pNumOfRows;
×
4634

UNCOV
4635
  while (value != NULL) {
×
4636
    cols = 0;
×
UNCOV
4637
    char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
×
4638
    STR_WITH_MAXSIZE_TO_VARSTR(userName, user, pShow->pMeta->pSchemas[cols].bytes);
×
4639
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
UNCOV
4640
    COL_DATA_SET_VAL_GOTO((const char *)userName, false, NULL, NULL, _exit);
×
4641

4642
    char privilege[20] = {0};
×
4643
    STR_WITH_MAXSIZE_TO_VARSTR(privilege, priType, pShow->pMeta->pSchemas[cols].bytes);
×
4644
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4645
    COL_DATA_SET_VAL_GOTO((const char *)privilege, false, NULL, NULL, _exit);
×
4646

4647
    size_t keyLen = 0;
×
4648
    void  *key = taosHashGetKey(value, &keyLen);
×
4649

UNCOV
4650
    char dbName[TSDB_DB_NAME_LEN] = {0};
×
4651
    (void)mndExtractShortDbNameFromStbFullName(key, dbName);
×
4652
    char dbNameContent[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
×
UNCOV
4653
    STR_WITH_MAXSIZE_TO_VARSTR(dbNameContent, dbName, pShow->pMeta->pSchemas[cols].bytes);
×
4654
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4655
    COL_DATA_SET_VAL_GOTO((const char *)dbNameContent, false, NULL, NULL, _exit);
×
4656

4657
    char tableName[TSDB_TABLE_NAME_LEN] = {0};
×
UNCOV
4658
    mndExtractTbNameFromStbFullName(key, tableName, TSDB_TABLE_NAME_LEN);
×
4659
    char tableNameContent[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
×
4660
    STR_WITH_MAXSIZE_TO_VARSTR(tableNameContent, tableName, pShow->pMeta->pSchemas[cols].bytes);
×
UNCOV
4661
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
UNCOV
4662
    COL_DATA_SET_VAL_GOTO((const char *)tableNameContent, false, NULL, NULL, _exit);
×
4663

4664
    if (strcmp("t", value) != 0 && strcmp("v", value) != 0) {
×
4665
      SNode  *pAst = NULL;
×
4666
      int32_t sqlLen = 0;
×
4667
      size_t  bufSz = strlen(value) + 1;
×
4668
      if (bufSz < 6) bufSz = 6;
×
4669
      TAOS_MEMORY_REALLOC(*sql, bufSz);
×
UNCOV
4670
      if (*sql == NULL) {
×
4671
        code = terrno;
×
4672
        goto _exit;
×
4673
      }
4674
      TAOS_MEMORY_REALLOC(*condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
×
UNCOV
4675
      if ((*condition) == NULL) {
×
4676
        code = terrno;
×
4677
        goto _exit;
×
4678
      }
4679

4680
      if (nodesStringToNode(value, &pAst) == 0) {
×
4681
        if (nodesNodeToSQLFormat(pAst, *sql, bufSz, &sqlLen, true) != 0) {
×
UNCOV
4682
          sqlLen = tsnprintf(*sql, bufSz, "error");
×
4683
        }
4684
        nodesDestroyNode(pAst);
×
4685
      }
4686

4687
      if (sqlLen == 0) {
×
4688
        sqlLen = tsnprintf(*sql, bufSz, "error");
×
4689
      }
4690

UNCOV
4691
      STR_WITH_MAXSIZE_TO_VARSTR((*condition), (*sql), pShow->pMeta->pSchemas[cols].bytes);
×
4692

4693
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
UNCOV
4694
      COL_DATA_SET_VAL_GOTO((const char *)(*condition), false, NULL, NULL, _exit);
×
4695

4696
      char notes[2] = {0};
×
4697
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
×
4698
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4699
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, NULL, NULL, _exit);
×
4700
    } else {
4701
      TAOS_MEMORY_REALLOC(*condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
×
UNCOV
4702
      if ((*condition) == NULL) {
×
4703
        code = terrno;
×
4704
        goto _exit;
×
4705
      }
4706
      STR_WITH_MAXSIZE_TO_VARSTR((*condition), "", pShow->pMeta->pSchemas[cols].bytes);
×
4707
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4708
      COL_DATA_SET_VAL_GOTO((const char *)(*condition), false, NULL, NULL, _exit);
×
4709

4710
      char notes[64 + VARSTR_HEADER_SIZE] = {0};
×
4711
      STR_WITH_MAXSIZE_TO_VARSTR(notes, value[0] == 'v' ? "view" : "", sizeof(notes));
×
4712
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4713
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, NULL, NULL, _exit);
×
4714
    }
4715

UNCOV
4716
    numOfRows++;
×
4717
    value = taosHashIterate(hash, value);
×
4718
  }
4719
  *pNumOfRows = numOfRows;
×
4720
_exit:
×
UNCOV
4721
  if (code < 0) {
×
4722
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4723
    sdbRelease(pSdb, pUser);
×
UNCOV
4724
    sdbCancelFetch(pSdb, pShow->pIter);
×
4725
  }
4726
  TAOS_RETURN(code);
×
4727
}
4728

4729
#if 0
4730
static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
4731
  int32_t   code = 0;
4732
  int32_t   lino = 0;
4733
  SMnode   *pMnode = pReq->info.node;
4734
  SSdb     *pSdb = pMnode->pSdb;
4735
  int32_t   numOfRows = 0;
4736
  SUserObj *pUser = NULL;
4737
  int32_t   cols = 0;
4738
  char     *pWrite = NULL;
4739
  char     *condition = NULL;
4740
  char     *sql = NULL;
4741

4742
  bool fetchNextUser = pShow->restore ? false : true;
4743
  pShow->restore = false;
4744

4745
  while (numOfRows < rows) {
4746
    if (fetchNextUser) {
4747
      pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
4748
      if (pShow->pIter == NULL) break;
4749
    } else {
4750
      fetchNextUser = true;
4751
      void *pKey = taosHashGetKey(pShow->pIter, NULL);
4752
      pUser = sdbAcquire(pSdb, SDB_USER, pKey);
4753
      if (!pUser) {
4754
        continue;
4755
      }
4756
    }
4757

4758
    int32_t numOfReadDbs = 0; //taosHashGetSize(pUser->readDbs);
4759
    int32_t numOfWriteDbs = 0; //taosHashGetSize(pUser->writeDbs);
4760
    int32_t numOfTopics = taosHashGetSize(pUser->topics);
4761
    int32_t numOfReadTbs = taosHashGetSize(pUser->selectTbs);
4762
    int32_t numOfWriteTbs = taosHashGetSize(pUser->insertTbs);
4763
    int32_t numOfAlterTbs = taosHashGetSize(pUser->alterTbs);
4764
    int32_t numOfReadViews = taosHashGetSize(pUser->readViews);
4765
    int32_t numOfWriteViews = taosHashGetSize(pUser->writeViews);
4766
    int32_t numOfAlterViews = taosHashGetSize(pUser->alterViews);
4767
    if (numOfRows + numOfReadDbs + numOfWriteDbs + numOfTopics + numOfReadTbs + numOfWriteTbs + numOfAlterTbs +
4768
            numOfReadViews + numOfWriteViews + numOfAlterViews >=
4769
        rows) {
4770
      mInfo(
4771
          "will restore. current num of rows: %d, read dbs %d, write dbs %d, topics %d, read tables %d, write tables "
4772
          "%d, alter tables %d, select views %d, write views %d, alter views %d",
4773
          numOfRows, numOfReadDbs, numOfWriteDbs, numOfTopics, numOfReadTbs, numOfWriteTbs, numOfAlterTbs,
4774
          numOfReadViews, numOfWriteViews, numOfAlterViews);
4775
      pShow->restore = true;
4776
      sdbRelease(pSdb, pUser);
4777
      break;
4778
    }
4779

4780
    if (pUser->superUser) {
4781
      cols = 0;
4782
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
4783
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
4784
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4785
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
4786

4787
      char privilege[20] = {0};
4788
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "all", pShow->pMeta->pSchemas[cols].bytes);
4789
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4790
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
4791

4792
      char objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4793
      STR_WITH_MAXSIZE_TO_VARSTR(objName, "all", pShow->pMeta->pSchemas[cols].bytes);
4794
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4795
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
4796

4797
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4798
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
4799
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4800
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
4801

4802
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
4803
      if (condition == NULL) {
4804
        sdbRelease(pSdb, pUser);
4805
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
4806
      }
4807
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
4808
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4809
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
4810

4811
      char notes[2] = {0};
4812
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
4813
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4814
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
4815

4816
      numOfRows++;
4817
    }
4818
#if 0
4819
    char *db = taosHashIterate(pUser->readDbs, NULL);
4820
    while (db != NULL) {
4821
      cols = 0;
4822
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
4823
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
4824
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4825
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
4826

4827
      char privilege[20] = {0};
4828
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "read", pShow->pMeta->pSchemas[cols].bytes);
4829
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4830
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
4831

4832
      SName name = {0};
4833
      char  objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4834
      code = tNameFromString(&name, db, T_NAME_ACCT | T_NAME_DB);
4835
      if (code < 0) {
4836
        sdbRelease(pSdb, pUser);
4837
        sdbCancelFetch(pSdb, pShow->pIter);
4838
        TAOS_CHECK_GOTO(code, &lino, _exit);
4839
      }
4840
      (void)tNameGetDbName(&name, varDataVal(objName));
4841
      varDataSetLen(objName, strlen(varDataVal(objName)));
4842
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4843
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
4844

4845
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4846
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
4847
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4848
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
4849

4850
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
4851
      if (condition == NULL) {
4852
        sdbRelease(pSdb, pUser);
4853
        sdbCancelFetch(pSdb, pShow->pIter);
4854
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
4855
      }
4856
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
4857
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4858
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
4859

4860
      char notes[2] = {0};
4861
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
4862
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4863
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
4864

4865
      numOfRows++;
4866
      db = taosHashIterate(pUser->readDbs, db);
4867
    }
4868

4869
    db = taosHashIterate(pUser->writeDbs, NULL);
4870
    while (db != NULL) {
4871
      cols = 0;
4872
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
4873
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
4874
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4875
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
4876

4877
      char privilege[20] = {0};
4878
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "write", pShow->pMeta->pSchemas[cols].bytes);
4879
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4880
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
4881

4882
      SName name = {0};
4883
      char  objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4884
      code = tNameFromString(&name, db, T_NAME_ACCT | T_NAME_DB);
4885
      if (code < 0) {
4886
        sdbRelease(pSdb, pUser);
4887
        sdbCancelFetch(pSdb, pShow->pIter);
4888
        TAOS_CHECK_GOTO(code, &lino, _exit);
4889
      }
4890
      (void)tNameGetDbName(&name, varDataVal(objName));
4891
      varDataSetLen(objName, strlen(varDataVal(objName)));
4892
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4893
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
4894

4895
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4896
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
4897
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4898
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
4899

4900
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
4901
      if (condition == NULL) {
4902
        sdbRelease(pSdb, pUser);
4903
        sdbCancelFetch(pSdb, pShow->pIter);
4904
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
4905
      }
4906
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
4907
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4908
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
4909

4910
      char notes[2] = {0};
4911
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
4912
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4913
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
4914

4915
      numOfRows++;
4916
      db = taosHashIterate(pUser->writeDbs, db);
4917
    }
4918
#endif
4919
    TAOS_CHECK_EXIT(mndLoopHash(pUser->selectTbs, "select", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
4920

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

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

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

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

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

4931
    char *topic = taosHashIterate(pUser->topics, NULL);
4932
    while (topic != NULL) {
4933
      cols = 0;
4934
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
4935
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
4936
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4937
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
4938

4939
      char privilege[20] = {0};
4940
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "subscribe", pShow->pMeta->pSchemas[cols].bytes);
4941
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4942
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
4943

4944
      char topicName[TSDB_TOPIC_NAME_LEN + VARSTR_HEADER_SIZE + 5] = {0};
4945
      tstrncpy(varDataVal(topicName), mndGetDbStr(topic), TSDB_TOPIC_NAME_LEN - 2);
4946
      varDataSetLen(topicName, strlen(varDataVal(topicName)));
4947
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4948
      COL_DATA_SET_VAL_GOTO((const char *)topicName, false, pUser, pShow->pIter, _exit);
4949

4950
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4951
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
4952
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4953
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
4954

4955
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
4956
      if (condition == NULL) {
4957
        sdbRelease(pSdb, pUser);
4958
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
4959
      }
4960
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
4961
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4962
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
4963

4964
      char notes[2] = {0};
4965
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
4966
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4967
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
4968

4969
      numOfRows++;
4970
      topic = taosHashIterate(pUser->topics, topic);
4971
    }
4972

4973
    sdbRelease(pSdb, pUser);
4974
  }
4975

4976
  pShow->numOfRows += numOfRows;
4977
_exit:
4978
  taosMemoryFreeClear(condition);
4979
  taosMemoryFreeClear(sql);
4980
  if (code < 0) {
4981
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
4982
    TAOS_RETURN(code);
4983
  }
4984
  return numOfRows;
4985
}
4986
#endif
4987

4988
static int32_t mndShowTablePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows, SUserObj *pObj,
136,056✔
4989
                                      SHashObj *privTbs, EPrivType privType, char *pBuf, int32_t bufSize, int32_t *pNumOfRows) {
4990
  int32_t     code = 0, lino = 0;
136,056✔
4991
  SMnode     *pMnode = pReq->info.node;
136,056✔
4992
  SSdb       *pSdb = pMnode->pSdb;
136,056✔
4993
  int32_t     cols = 0, qBufSize = bufSize - VARSTR_HEADER_SIZE;
136,056✔
4994
  int32_t     numOfRows = *pNumOfRows;
136,056✔
4995
  char       *qBuf = NULL;
136,056✔
4996
  char       *sql = NULL;
136,056✔
4997
  char        roleName[TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
136,056✔
4998
  const char *privName = privInfoGetName(privType);
136,056✔
4999

5000
  STR_WITH_MAXSIZE_TO_VARSTR(roleName, pObj->name, pShow->pMeta->pSchemas[cols].bytes);
136,056✔
5001

5002
  void *pIter = NULL;
136,056✔
5003
  while ((pIter = taosHashIterate(privTbs, pIter))) {
171,736✔
5004
    SPrivTblPolicies *pPolices = (SPrivTblPolicies *)pIter;
35,680✔
5005
    SArray           *tblPolicies = pPolices->policy;
35,680✔
5006

5007
    char   *key = taosHashGetKey(pPolices, NULL);
35,680✔
5008
    int32_t objType = PRIV_OBJ_UNKNOWN;
35,680✔
5009
    char    dbName[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
35,680✔
5010
    char    tblName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
35,680✔
5011
    if ((code = privObjKeyParse(key, &objType, dbName, sizeof(dbName), tblName, sizeof(tblName), false))) {
35,680✔
UNCOV
5012
      sdbRelease(pSdb, pObj);
×
UNCOV
5013
      sdbCancelFetch(pSdb, pShow->pIter);
×
UNCOV
5014
      TAOS_CHECK_EXIT(code);
×
5015
    }
5016

5017
    int32_t nTbPolicies = taosArrayGetSize(tblPolicies);
35,680✔
5018
    for (int32_t i = 0; i < nTbPolicies; ++i) {
71,360✔
5019
      SPrivTblPolicy *tbPolicy = (SPrivTblPolicy *)TARRAY_GET_ELEM(tblPolicies, i);
35,680✔
5020
      cols = 0;
35,680✔
5021
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
35,680✔
5022
      COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
35,680✔
5023

5024
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
35,680✔
5025
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privName, pShow->pMeta->pSchemas[cols].bytes);
35,680✔
5026
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
35,680✔
5027
      }
5028

5029
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
35,680✔
5030
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privObjGetName(objType), pShow->pMeta->pSchemas[cols].bytes);
35,680✔
5031
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
35,680✔
5032
      }
5033

5034
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
35,680✔
5035
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, dbName, pShow->pMeta->pSchemas[cols].bytes);
35,680✔
5036
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
35,680✔
5037
      }
5038

5039
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
35,680✔
5040
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, tblName, pShow->pMeta->pSchemas[cols].bytes);
35,680✔
5041
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
35,680✔
5042
      }
5043
      // condition
5044
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
35,680✔
5045
        SNode  *pAst = NULL;
35,680✔
5046
        int32_t sqlLen = 0;
35,680✔
5047
        qBuf = POINTER_SHIFT(pBuf, VARSTR_HEADER_SIZE);
35,680✔
5048
        if (tbPolicy->condLen > 0) {
35,680✔
5049
          if (nodesStringToNode(tbPolicy->cond, &pAst) == 0) {
35,680✔
5050
            if (nodesNodeToSQLFormat(pAst, qBuf, qBufSize, &sqlLen, true) != 0) {
35,680✔
UNCOV
5051
              sqlLen = tsnprintf(qBuf, qBufSize, "error");
×
5052
            }
5053
            nodesDestroyNode(pAst);
35,680✔
5054
          }
5055
          if (sqlLen == 0) {
35,680✔
UNCOV
5056
            sqlLen = tsnprintf(qBuf, qBufSize, "error");
×
5057
          }
5058
        } else {
UNCOV
5059
          sqlLen = tsnprintf(qBuf, qBufSize, "");
×
5060
        }
5061
        varDataSetLen(pBuf, sqlLen);
35,680✔
5062
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
35,680✔
5063
      }
5064
      // notes
5065
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
35,680✔
5066
        STR_WITH_MAXSIZE_TO_VARSTR((pBuf), "", 2);
35,680✔
5067
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
35,680✔
5068
      }
5069
      // columns
5070
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
35,680✔
5071
        SArray *pCols = tbPolicy->cols;
35,680✔
5072
        int32_t nCols = taosArrayGetSize(pCols);
35,680✔
5073
        int32_t totalLen = 0;
35,680✔
5074
        qBuf = POINTER_SHIFT(pBuf, VARSTR_HEADER_SIZE);
35,680✔
5075
        for (int32_t j = 0; j < nCols; ++j) {
35,680✔
UNCOV
5076
          SColNameFlag *pCol = (SColNameFlag *)TARRAY_GET_ELEM(pCols, j);
×
UNCOV
5077
          char          tmpBuf[TSDB_COL_NAME_LEN + 16] = {0};
×
UNCOV
5078
          int32_t       tmpLen = 0;
×
UNCOV
5079
          if (IS_MASK_ON(pCol)) {
×
UNCOV
5080
            tmpLen = snprintf(tmpBuf, sizeof(tmpBuf), "mask(%s)%s", pCol->colName, j == nCols - 1 ? "" : ",");
×
5081
          } else {
UNCOV
5082
            tmpLen = snprintf(tmpBuf, sizeof(tmpBuf), "%s%s", pCol->colName, j == nCols - 1 ? "" : ",");
×
5083
          }
UNCOV
5084
          if(totalLen + tmpLen > qBufSize) {
×
UNCOV
5085
            break;
×
5086
          }
5087
          (void)memcpy(POINTER_SHIFT(qBuf, totalLen), tmpBuf, tmpLen);
×
5088
          totalLen += tmpLen;
×
5089
        }
5090
        varDataSetLen(pBuf, totalLen);
35,680✔
5091
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
35,680✔
5092
      }
5093
      // update_time
5094
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
35,680✔
5095
        char updateTime[40] = {0};
35,680✔
5096
        (void)formatTimestampLocal(updateTime, tbPolicy->updateUs, TSDB_TIME_PRECISION_MICRO);
35,680✔
5097
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, updateTime, pShow->pMeta->pSchemas[cols].bytes);
35,680✔
5098
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
35,680✔
5099
      }
5100
      ++numOfRows;
35,680✔
5101
    }
5102
  }
5103
  *pNumOfRows = numOfRows;
136,056✔
5104
_exit:
136,056✔
5105
  TAOS_RETURN(code);
136,056✔
5106
}
5107

5108
static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
5,248✔
5109
  int32_t   code = 0, lino = 0;
5,248✔
5110
  SMnode   *pMnode = pReq->info.node;
5,248✔
5111
  SSdb     *pSdb = pMnode->pSdb;
5,248✔
5112
  int32_t   numOfRows = 0;
5,248✔
5113
  int32_t   cols = 0;
5,248✔
5114
  SUserObj *pObj = NULL;
5,248✔
5115
  char     *pBuf = NULL, *qBuf = NULL;
5,248✔
5116
  char     *sql = NULL;
5,248✔
5117
  char      roleName[TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
5,248✔
5118
  int32_t   bufSize = TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE;
5,248✔
5119

5120
  bool fetchNextInstance = pShow->restore ? false : true;
5,248✔
5121
  pShow->restore = false;
5,248✔
5122

5123
  while (numOfRows < rows) {
39,262✔
5124
    if (fetchNextInstance) {
39,262✔
5125
      pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pObj);
39,262✔
5126
      if (pShow->pIter == NULL) break;
39,262✔
5127
    } else {
UNCOV
5128
      fetchNextInstance = true;
×
UNCOV
5129
      void *pKey = taosHashGetKey(pShow->pIter, NULL);
×
UNCOV
5130
      if (!(pObj = sdbAcquire(pSdb, SDB_USER, pKey))) {
×
5131
        continue;
×
5132
      }
5133
    }
5134

5135
    int32_t nSysPrivileges = 0, nObjPrivileges = 0;
34,014✔
5136
    if (nSysPrivileges + nObjPrivileges >= rows) {
34,014✔
UNCOV
5137
      pShow->restore = true;
×
UNCOV
5138
      sdbRelease(pSdb, pObj);
×
UNCOV
5139
      break;
×
5140
    }
5141

5142
    if (!pBuf && !(pBuf = taosMemoryMalloc(bufSize))) {
34,014✔
UNCOV
5143
      sdbCancelFetch(pSdb, pShow->pIter);
×
UNCOV
5144
      sdbRelease(pSdb, pObj);
×
UNCOV
5145
      TAOS_CHECK_EXIT(terrno);
×
5146
    }
5147

5148
    cols = 0;
34,014✔
5149
    STR_WITH_MAXSIZE_TO_VARSTR(roleName, pObj->name, pShow->pMeta->pSchemas[cols].bytes);
34,014✔
5150

5151
    // system privileges
5152
    SPrivIter privIter = {0};
34,014✔
5153
    privIterInit(&privIter, &pObj->sysPrivs);
34,014✔
5154
    SPrivInfo *pPrivInfo = NULL;
34,014✔
5155
    while (privIterNext(&privIter, &pPrivInfo)) {
35,934✔
5156
      cols = 0;
1,920✔
5157
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
1,920✔
5158
      COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
1,920✔
5159

5160
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
1,920✔
5161
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, pPrivInfo->name, pShow->pMeta->pSchemas[cols].bytes);
1,920✔
5162
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
1,920✔
5163
      }
5164
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
1,920✔
5165
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privObjGetName(PRIV_OBJ_CLUSTER), pShow->pMeta->pSchemas[cols].bytes);
1,920✔
5166
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
1,920✔
5167
      }
5168
      // skip db, table, condition, notes, columns, update_time
5169
      COL_DATA_SET_EMPTY_VARCHAR(pBuf, 6);
13,440✔
5170
      numOfRows++;
1,920✔
5171
    }
5172

5173
    // object privileges
5174
    void *pIter = NULL;
34,014✔
5175
    while ((pIter = taosHashIterate(pObj->objPrivs, pIter))) {
54,500✔
5176
      SPrivObjPolicies *pPolices = (SPrivObjPolicies *)pIter;
20,486✔
5177

5178
      char   *key = taosHashGetKey(pPolices, NULL);
20,486✔
5179
      int32_t objType = PRIV_OBJ_UNKNOWN;
20,486✔
5180
      char    dbName[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
20,486✔
5181
      char    tblName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
20,486✔
5182
      if ((code = privObjKeyParse(key, &objType, dbName, sizeof(dbName), tblName, sizeof(tblName), false))) {
20,486✔
UNCOV
5183
        sdbRelease(pSdb, pObj);
×
UNCOV
5184
        sdbCancelFetch(pSdb, pShow->pIter);
×
UNCOV
5185
        TAOS_CHECK_EXIT(code);
×
5186
      }
5187

5188
      SPrivIter privIter = {0};
20,486✔
5189
      privIterInit(&privIter, &pPolices->policy);
20,486✔
5190
      SPrivInfo *pPrivInfo = NULL;
20,486✔
5191
      while (privIterNext(&privIter, &pPrivInfo)) {
114,500✔
5192
        cols = 0;
94,014✔
5193
        SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
94,014✔
5194
        COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
94,014✔
5195

5196
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
94,014✔
5197
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, pPrivInfo->name, pShow->pMeta->pSchemas[cols].bytes);
94,014✔
5198
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
94,014✔
5199
        }
5200

5201
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
94,014✔
5202
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privObjGetName(objType), pShow->pMeta->pSchemas[cols].bytes);
94,014✔
5203
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
94,014✔
5204
        }
5205

5206
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
94,014✔
5207
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, dbName, pShow->pMeta->pSchemas[cols].bytes);
94,014✔
5208
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
94,014✔
5209
        }
5210

5211
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
94,014✔
5212
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, tblName, pShow->pMeta->pSchemas[cols].bytes);
94,014✔
5213
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
94,014✔
5214
        }
5215

5216
        // skip condition, notes, columns, update_time
5217
        COL_DATA_SET_EMPTY_VARCHAR(pBuf, 4);
470,070✔
5218

5219
        numOfRows++;
94,014✔
5220
      }
5221
    }
5222

5223
    // table level privileges
5224
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->selectTbs,
34,014✔
5225
                                           PRIV_TBL_SELECT, pBuf, bufSize, &numOfRows));
5226
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->insertTbs,
34,014✔
5227
                                           PRIV_TBL_INSERT, pBuf, bufSize, &numOfRows));
5228
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->updateTbs,
34,014✔
5229
                                           PRIV_TBL_UPDATE, pBuf, bufSize, &numOfRows));
5230
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->deleteTbs,
34,014✔
5231
                                           PRIV_TBL_DELETE, pBuf, bufSize, &numOfRows));
5232
#if 0
5233
    while ((pIter = taosHashIterate(pObj->selectTbs, pIter))) {
5234
      SPrivTblPolicies *pPolices = (SPrivTblPolicies *)pIter;
5235
      SArray           *tblPolicies = pPolices->policy;
5236

5237
      char   *key = taosHashGetKey(pPolices, NULL);
5238
      int32_t objType = PRIV_OBJ_UNKNOWN;
5239
      char    dbName[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
5240
      char    tblName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
5241
      if ((code = privObjKeyParse(key, &objType, dbName, sizeof(dbName), tblName, sizeof(tblName), false))) {
5242
        sdbRelease(pSdb, pObj);
5243
        sdbCancelFetch(pSdb, pShow->pIter);
5244
        TAOS_CHECK_EXIT(code);
5245
      }
5246

5247
      int32_t nTbPolicies = taosArrayGetSize(tblPolicies);
5248
      for (int32_t i = 0; i < nTbPolicies; ++i) {
5249
        SPrivTblPolicy *tbPolicy = (SPrivTblPolicy *)TARRAY_GET_ELEM(tblPolicies, i);
5250
        cols = 0;
5251
        SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
5252
        COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
5253

5254
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
5255
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privInfoGetName(PRIV_TBL_SELECT), pShow->pMeta->pSchemas[cols].bytes);
5256
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
5257
        }
5258

5259
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
5260
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, dbName, pShow->pMeta->pSchemas[cols].bytes);
5261
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
5262
        }
5263

5264
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
5265
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, tblName, pShow->pMeta->pSchemas[cols].bytes);
5266
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
5267
        }
5268

5269
        // skip condition, notes, columns, update_time
5270
        COL_DATA_SET_EMPTY_VARCHAR(pBuf, 4);
5271

5272
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
5273
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privObjGetName(objType), pShow->pMeta->pSchemas[cols].bytes);
5274
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
5275
        }
5276
        numOfRows++;
5277
      }
5278
    }
5279
#endif
5280
    sdbRelease(pSdb, pObj);
34,014✔
5281
  }
5282

5283
  pShow->numOfRows += numOfRows;
5,248✔
5284
_exit:
5,248✔
5285
  taosMemoryFreeClear(pBuf);
5,248✔
5286
  taosMemoryFreeClear(sql);
5,248✔
5287
  if (code < 0) {
5,248✔
UNCOV
5288
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
UNCOV
5289
    TAOS_RETURN(code);
×
5290
  }
5291
  return numOfRows;
5,248✔
5292
}
5293

UNCOV
5294
static void mndCancelGetNextPrivileges(SMnode *pMnode, void *pIter) {
×
UNCOV
5295
  SSdb *pSdb = pMnode->pSdb;
×
UNCOV
5296
  sdbCancelFetchByType(pSdb, pIter, SDB_USER);
×
UNCOV
5297
}
×
5298

5299
int32_t mndValidateUserAuthInfo(SMnode *pMnode, SUserAuthVersion *pUsers, int32_t numOfUses, void **ppRsp,
27,239,719✔
5300
                                int32_t *pRspLen, int64_t ipWhiteListVer) {
5301
  int32_t           code = 0;
27,239,719✔
5302
  int32_t           lino = 0;
27,239,719✔
5303
  int32_t           rspLen = 0;
27,239,418✔
5304
  void             *pRsp = NULL;
27,239,418✔
5305
  SUserAuthBatchRsp batchRsp = {0};
27,239,418✔
5306

5307
  batchRsp.pArray = taosArrayInit(numOfUses, sizeof(SGetUserAuthRsp));
27,239,418✔
5308
  if (batchRsp.pArray == NULL) {
27,240,408✔
UNCOV
5309
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
5310
  }
5311
  int64_t now = taosGetTimestampMs();
27,239,719✔
5312
  for (int32_t i = 0; i < numOfUses; ++i) {
54,551,738✔
5313
    SUserObj *pUser = NULL;
27,311,330✔
5314
    code = mndAcquireUser(pMnode, pUsers[i].user, &pUser);
27,311,330✔
5315
    if (pUser == NULL) {
27,311,330✔
5316
      if (TSDB_CODE_MND_USER_NOT_EXIST == code) {
322✔
5317
        SGetUserAuthRsp rsp = {.dropped = 1};
322✔
5318
        (void)memcpy(rsp.user, pUsers[i].user, TSDB_USER_LEN);
322✔
5319
        TSDB_CHECK_NULL(taosArrayPush(batchRsp.pArray, &rsp), code, lino, _OVER, TSDB_CODE_OUT_OF_MEMORY);
644✔
5320
      }
5321
      mError("user:%s, failed to auth user since %s", pUsers[i].user, tstrerror(code));
322✔
5322
      code = 0;
322✔
5323
      continue;
2,192✔
5324
    }
5325

5326
    pUsers[i].version = ntohl(pUsers[i].version);
27,311,008✔
5327
    if ((pUser->authVersion <= pUsers[i].version) && (ipWhiteListVer == pMnode->ipWhiteVer) &&
27,311,697✔
5328
        !mndNeedRetrieveRole(pUser)) {
26,477,701✔
5329
      mndReleaseUser(pMnode, pUser);
26,383,066✔
5330
      continue;
26,383,066✔
5331
    }
5332

5333
    SGetUserAuthRsp rsp = {0};
928,631✔
5334
    code = mndSetUserAuthRsp(pMnode, pUser, &rsp);
928,631✔
5335
    if (code) {
928,631✔
UNCOV
5336
      mndReleaseUser(pMnode, pUser);
×
UNCOV
5337
      tFreeSGetUserAuthRsp(&rsp);
×
UNCOV
5338
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
5339
    }
5340

5341
    if (!(taosArrayPush(batchRsp.pArray, &rsp))) {
1,857,262✔
UNCOV
5342
      code = terrno;
×
UNCOV
5343
      mndReleaseUser(pMnode, pUser);
×
UNCOV
5344
      tFreeSGetUserAuthRsp(&rsp);
×
UNCOV
5345
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
5346
    }
5347
    pUser->lastRoleRetrieve = now;  // update user's last retrieve time
928,631✔
5348
    mndReleaseUser(pMnode, pUser);
928,631✔
5349
  }
5350

5351
  if (taosArrayGetSize(batchRsp.pArray) <= 0) {
27,240,408✔
5352
    *ppRsp = NULL;
26,355,795✔
5353
    *pRspLen = 0;
26,355,795✔
5354

5355
    tFreeSUserAuthBatchRsp(&batchRsp);
26,355,795✔
5356
    return 0;
26,355,106✔
5357
  }
5358

5359
  rspLen = tSerializeSUserAuthBatchRsp(NULL, 0, &batchRsp);
884,613✔
5360
  if (rspLen < 0) {
884,613✔
UNCOV
5361
    TAOS_CHECK_GOTO(rspLen, &lino, _OVER);
×
5362
  }
5363
  pRsp = taosMemoryMalloc(rspLen);
884,613✔
5364
  if (pRsp == NULL) {
884,613✔
UNCOV
5365
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
5366
  }
5367
  rspLen = tSerializeSUserAuthBatchRsp(pRsp, rspLen, &batchRsp);
884,613✔
5368
  if (rspLen < 0) {
884,613✔
5369
    TAOS_CHECK_GOTO(rspLen, &lino, _OVER);
×
5370
  }
5371
_OVER:
884,613✔
5372
  tFreeSUserAuthBatchRsp(&batchRsp);
884,059✔
5373
  if (code < 0) {
884,613✔
UNCOV
5374
    for (int32_t i = 0; i < numOfUses; ++i) {
×
UNCOV
5375
      SUserObj *pUser = NULL;
×
UNCOV
5376
      if (mndAcquireUser(pMnode, pUsers[i].user, &pUser) != 0) {
×
UNCOV
5377
        continue;
×
5378
      }
UNCOV
5379
      pUser->lastRoleRetrieve = 0;  // reset last retrieve time on error
×
UNCOV
5380
      mndReleaseUser(pMnode, pUser);
×
5381
    }
UNCOV
5382
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
UNCOV
5383
    taosMemoryFreeClear(pRsp);
×
5384
    rspLen = 0;
×
5385
  }
5386
  *ppRsp = pRsp;
884,613✔
5387
  *pRspLen = rspLen;
883,999✔
5388

5389
  TAOS_RETURN(code);
883,999✔
5390
}
5391

UNCOV
5392
static int32_t mndRemoveDbPrivileges(SHashObj *pHash, const char *dbFName, int32_t dbFNameLen, int32_t *nRemoved) {
×
UNCOV
5393
  void *pVal = NULL;
×
UNCOV
5394
  while ((pVal = taosHashIterate(pHash, pVal))) {
×
UNCOV
5395
    size_t keyLen = 0;
×
UNCOV
5396
    char  *pKey = (char *)taosHashGetKey(pVal, &keyLen);
×
UNCOV
5397
    if (pKey == NULL || keyLen <= dbFNameLen) continue;
×
UNCOV
5398
    if ((*(pKey + dbFNameLen) == '.') && strncmp(pKey, dbFName, dbFNameLen) == 0) {
×
UNCOV
5399
      TAOS_CHECK_RETURN(taosHashRemove(pHash, pKey, keyLen));
×
UNCOV
5400
      if (nRemoved) ++(*nRemoved);
×
5401
    }
5402
  }
UNCOV
5403
  TAOS_RETURN(0);
×
5404
}
5405

UNCOV
5406
int32_t mndUserDropRole(SMnode *pMnode, STrans *pTrans, SRoleObj *pObj) {
×
UNCOV
5407
  int32_t   code = 0, lino = 0;
×
UNCOV
5408
  SSdb     *pSdb = pMnode->pSdb;
×
UNCOV
5409
  SUserObj *pUser = NULL;
×
UNCOV
5410
  void     *pIter = NULL;
×
5411

5412
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser))) {
×
5413
    SHashObj *pRole = taosHashGet(pUser->roles, pObj->name, strlen(pObj->name) + 1);
×
UNCOV
5414
    if (!pRole) {
×
UNCOV
5415
      sdbRelease(pSdb, pUser);
×
UNCOV
5416
      pUser = NULL;
×
5417
      continue;
×
5418
    }
5419

5420
    SUserObj newUser = {0};
×
UNCOV
5421
    TAOS_CHECK_EXIT(mndUserDupObj(pUser, &newUser));
×
UNCOV
5422
    code = taosHashRemove(newUser.roles, pObj->name, strlen(pObj->name) + 1);
×
UNCOV
5423
    if (code == TSDB_CODE_NOT_FOUND) {
×
UNCOV
5424
      sdbRelease(pSdb, pUser);
×
UNCOV
5425
      pUser = NULL;
×
UNCOV
5426
      mndUserFreeObj(&newUser);
×
UNCOV
5427
      continue;
×
5428
    }
UNCOV
5429
    if (code != 0) {
×
UNCOV
5430
      mndUserFreeObj(&newUser);
×
UNCOV
5431
      TAOS_CHECK_EXIT(code);
×
5432
    }
UNCOV
5433
    SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
×
UNCOV
5434
    if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
×
UNCOV
5435
      mndUserFreeObj(&newUser);
×
5436
      TAOS_CHECK_EXIT(TSDB_CODE_OUT_OF_MEMORY);
×
5437
    }
UNCOV
5438
    if ((code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY))) {
×
UNCOV
5439
      mndUserFreeObj(&newUser);
×
5440
      TAOS_CHECK_EXIT(code);
×
5441
    }
UNCOV
5442
    sdbRelease(pSdb, pUser);
×
UNCOV
5443
    pUser = NULL;
×
5444
    mndUserFreeObj(&newUser);
×
5445
  }
UNCOV
5446
_exit:
×
UNCOV
5447
  if (pIter) sdbCancelFetch(pSdb, pIter);
×
UNCOV
5448
  if (pUser) sdbRelease(pSdb, pUser);
×
5449
  if (code < 0) {
×
5450
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
5451
  }
5452
  TAOS_RETURN(code);
×
5453
}
5454

5455
int32_t mndUserRemoveDb(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SSHashObj **ppUsers) {
598,810✔
5456
  int32_t    code = 0, lino = 0;
598,810✔
5457
  SSdb      *pSdb = pMnode->pSdb;
598,810✔
5458
  int32_t    dbLen = strlen(pDb->name);
598,810✔
5459
  void      *pIter = NULL;
598,810✔
5460
  SUserObj  *pUser = NULL;
598,810✔
5461
  SUserObj   newUser = {0};
598,810✔
5462
  SSHashObj *pUsers = ppUsers ? *ppUsers : NULL;
598,810✔
5463
  bool       output = (ppUsers != NULL);
598,810✔
5464
#ifdef PRIV_TODO
5465
  while (1) {
5466
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
5467
    if (pIter == NULL) break;
5468

5469
    bool update = false;
5470
    bool inReadDb = false; //(taosHashGet(pUser->readDbs, pDb->name, dbLen + 1) != NULL);
5471
    bool inWriteDb = false; //(taosHashGet(pUser->writeDbs, pDb->name, dbLen + 1) != NULL);
5472
    bool inUseDb = (taosHashGet(pUser->useDbs, pDb->name, dbLen + 1) != NULL);
5473
    bool inReadTbs = taosHashGetSize(pUser->selectTbs) > 0;
5474
    bool inWriteTbs = taosHashGetSize(pUser->insertTbs) > 0;
5475
    bool inAlterTbs = taosHashGetSize(pUser->alterTbs) > 0;
5476
    bool inReadViews = taosHashGetSize(pUser->readViews) > 0;
5477
    bool inWriteViews = taosHashGetSize(pUser->writeViews) > 0;
5478
    bool inAlterViews = taosHashGetSize(pUser->alterViews) > 0;
5479
    // no need remove pUser->topics since topics must be dropped ahead of db
5480
    if (!inReadDb && !inWriteDb && !inReadTbs && !inWriteTbs && !inAlterTbs && !inReadViews && !inWriteViews &&
5481
        !inAlterViews) {
5482
      sdbRelease(pSdb, pUser);
5483
      continue;
5484
    }
5485
    SUserObj *pTargetUser = &newUser;
5486
    if (output) {
5487
      if (!pUsers) {
5488
        TSDB_CHECK_NULL(pUsers = tSimpleHashInit(32, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY)), code, lino,
5489
                        _exit, TSDB_CODE_OUT_OF_MEMORY);
5490
        *ppUsers = pUsers;
5491
      }
5492
      void   *pVal = NULL;
5493
      int32_t userLen = strlen(pUser->user) + 1;
5494
      if ((pVal = tSimpleHashGet(pUsers, pUser->user, userLen)) != NULL) {
5495
        pTargetUser = (SUserObj *)pVal;
5496
      } else {
5497
        TAOS_CHECK_EXIT(mndUserDupObj(pUser, &newUser));
5498
        TAOS_CHECK_EXIT(tSimpleHashPut(pUsers, pUser->user, userLen, &newUser, sizeof(SUserObj)));
5499
        TSDB_CHECK_NULL((pVal = tSimpleHashGet(pUsers, pUser->user, userLen)), code, lino, _exit,
5500
                        TSDB_CODE_OUT_OF_MEMORY);
5501
        pTargetUser = (SUserObj *)pVal;
5502
      }
5503
    } else {
5504
      TAOS_CHECK_EXIT(mndUserDupObj(pUser, &newUser));
5505
    }
5506
    if (inReadDb) {
5507
      // TAOS_CHECK_EXIT(taosHashRemove(pTargetUser->readDbs, pDb->name, dbLen + 1));
5508
    }
5509
    if (inWriteDb) {
5510
      // TAOS_CHECK_EXIT(taosHashRemove(pTargetUser->writeDbs, pDb->name, dbLen + 1));
5511
    }
5512
    if (inUseDb) {
5513
      TAOS_CHECK_EXIT(taosHashRemove(pTargetUser->useDbs, pDb->name, dbLen + 1));
5514
    }
5515
    update = inReadDb || inWriteDb || inUseDb;
5516

5517
    int32_t nRemovedReadTbs = 0;
5518
    int32_t nRemovedWriteTbs = 0;
5519
    int32_t nRemovedAlterTbs = 0;
5520
    if (inReadTbs || inWriteTbs || inAlterTbs) {
5521
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->selectTbs, pDb->name, dbLen, &nRemovedReadTbs));
5522
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->insertTbs, pDb->name, dbLen, &nRemovedWriteTbs));
5523
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->alterTbs, pDb->name, dbLen, &nRemovedAlterTbs));
5524
      if (!update) update = nRemovedReadTbs > 0 || nRemovedWriteTbs > 0 || nRemovedAlterTbs > 0;
5525
    }
5526

5527
    int32_t nRemovedReadViews = 0;
5528
    int32_t nRemovedWriteViews = 0;
5529
    int32_t nRemovedAlterViews = 0;
5530
    if (inReadViews || inWriteViews || inAlterViews) {
5531
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->readViews, pDb->name, dbLen, &nRemovedReadViews));
5532
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->writeViews, pDb->name, dbLen, &nRemovedWriteViews));
5533
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->alterViews, pDb->name, dbLen, &nRemovedAlterViews));
5534
      if (!update) update = nRemovedReadViews > 0 || nRemovedWriteViews > 0 || nRemovedAlterViews > 0;
5535
    }
5536

5537
    if (!output) {
5538
      if (update) {
5539
        SSdbRaw *pCommitRaw = mndUserActionEncode(pTargetUser);
5540
        if (pCommitRaw == NULL) {
5541
          TAOS_CHECK_EXIT(terrno);
5542
        }
5543
        TAOS_CHECK_EXIT(mndTransAppendCommitlog(pTrans, pCommitRaw));
5544
        TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
5545
      }
5546
      mndUserFreeObj(&newUser);
5547
    }
5548
    sdbRelease(pSdb, pUser);
5549
  }
5550
#endif
5551
_exit:
598,810✔
5552
  if (code < 0) {
598,810✔
UNCOV
5553
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
UNCOV
5554
    mndUserFreeObj(&newUser);
×
5555
  }
5556
  if (pUser != NULL) sdbRelease(pSdb, pUser);
598,810✔
5557
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
598,810✔
5558
  if (!output) mndUserFreeObj(&newUser);
598,810✔
5559
  TAOS_RETURN(code);
598,810✔
5560
}
5561

5562
int32_t mndUserRemoveStb(SMnode *pMnode, STrans *pTrans, char *stb) {
430,648✔
5563
  int32_t   code = 0;
430,648✔
5564
  SSdb     *pSdb = pMnode->pSdb;
430,648✔
5565
  int32_t   len = strlen(stb) + 1;
430,648✔
5566
  void     *pIter = NULL;
430,648✔
5567
  SUserObj *pUser = NULL;
430,648✔
5568
  SUserObj  newUser = {0};
430,648✔
5569
#ifdef PRIV_TODO
5570
  while (1) {
5571
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
5572
    if (pIter == NULL) break;
5573

5574
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
5575
      break;
5576
    }
5577

5578
    bool inRead = (taosHashGet(newUser.selectTbs, stb, len) != NULL);
5579
    bool inWrite = (taosHashGet(newUser.insertTbs, stb, len) != NULL);
5580
    bool inAlter = (taosHashGet(newUser.alterTbs, stb, len) != NULL);
5581
    if (inRead || inWrite || inAlter) {
5582
      code = taosHashRemove(newUser.selectTbs, stb, len);
5583
      if (code < 0) {
5584
        mError("failed to remove selectTbs:%s from user:%s", stb, pUser->user);
5585
      }
5586
      code = taosHashRemove(newUser.insertTbs, stb, len);
5587
      if (code < 0) {
5588
        mError("failed to remove insertTbs:%s from user:%s", stb, pUser->user);
5589
      }
5590
      code = taosHashRemove(newUser.alterTbs, stb, len);
5591
      if (code < 0) {
5592
        mError("failed to remove alterTbs:%s from user:%s", stb, pUser->user);
5593
      }
5594

5595
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
5596
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
5597
        code = TSDB_CODE_OUT_OF_MEMORY;
5598
        break;
5599
      }
5600
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
5601
      if (code != 0) {
5602
        mndUserFreeObj(&newUser);
5603
        sdbRelease(pSdb, pUser);
5604
        TAOS_RETURN(code);
5605
      }
5606
    }
5607

5608
    mndUserFreeObj(&newUser);
5609
    sdbRelease(pSdb, pUser);
5610
  }
5611
#endif
5612
  if (pUser != NULL) sdbRelease(pSdb, pUser);
430,648✔
5613
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
430,648✔
5614
  mndUserFreeObj(&newUser);
430,648✔
5615
  TAOS_RETURN(code);
430,648✔
5616
}
5617

UNCOV
5618
int32_t mndUserRemoveView(SMnode *pMnode, STrans *pTrans, char *view) {
×
UNCOV
5619
  int32_t   code = 0;
×
UNCOV
5620
  SSdb     *pSdb = pMnode->pSdb;
×
UNCOV
5621
  int32_t   len = strlen(view) + 1;
×
UNCOV
5622
  void     *pIter = NULL;
×
UNCOV
5623
  SUserObj *pUser = NULL;
×
UNCOV
5624
  SUserObj  newUser = {0};
×
5625
#ifdef PRIV_TODO
5626
  while (1) {
5627
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
5628
    if (pIter == NULL) break;
5629

5630
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
5631
      break;
5632
    }
5633

5634
    bool inRead = (taosHashGet(newUser.readViews, view, len) != NULL);
5635
    bool inWrite = (taosHashGet(newUser.writeViews, view, len) != NULL);
5636
    bool inAlter = (taosHashGet(newUser.alterViews, view, len) != NULL);
5637
    if (inRead || inWrite || inAlter) {
5638
      code = taosHashRemove(newUser.readViews, view, len);
5639
      if (code < 0) {
5640
        mError("failed to remove readViews:%s from user:%s", view, pUser->user);
5641
      }
5642
      code = taosHashRemove(newUser.writeViews, view, len);
5643
      if (code < 0) {
5644
        mError("failed to remove writeViews:%s from user:%s", view, pUser->user);
5645
      }
5646
      code = taosHashRemove(newUser.alterViews, view, len);
5647
      if (code < 0) {
5648
        mError("failed to remove alterViews:%s from user:%s", view, pUser->user);
5649
      }
5650

5651
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
5652
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
5653
        code = TSDB_CODE_OUT_OF_MEMORY;
5654
        break;
5655
      }
5656
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
5657
      if (code < 0) {
5658
        mndUserFreeObj(&newUser);
5659
        sdbRelease(pSdb, pUser);
5660
        TAOS_RETURN(code);
5661
      }
5662
    }
5663

5664
    mndUserFreeObj(&newUser);
5665
    sdbRelease(pSdb, pUser);
5666
  }
5667
#endif
UNCOV
5668
  if (pUser != NULL) sdbRelease(pSdb, pUser);
×
UNCOV
5669
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
×
UNCOV
5670
  mndUserFreeObj(&newUser);
×
UNCOV
5671
  TAOS_RETURN(code);
×
5672
}
5673

5674
int32_t mndUserRemoveTopic(SMnode *pMnode, STrans *pTrans, char *topic) {
91,918✔
5675
  int32_t   code = 0;
91,918✔
5676
  SSdb     *pSdb = pMnode->pSdb;
91,918✔
5677
  int32_t   len = strlen(topic) + 1;
91,918✔
5678
  void     *pIter = NULL;
91,918✔
5679
  SUserObj *pUser = NULL;
91,918✔
5680
  SUserObj  newUser = {0};
91,918✔
5681
#ifdef PRIV_TODO
5682
  while (1) {
5683
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
5684
    if (pIter == NULL) {
5685
      break;
5686
    }
5687

5688
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
5689
      break;
5690
    }
5691

5692
    bool inTopic = (taosHashGet(newUser.topics, topic, len) != NULL);
5693
    if (inTopic) {
5694
      code = taosHashRemove(newUser.topics, topic, len);
5695
      if (code < 0) {
5696
        mError("failed to remove topic:%s from user:%s", topic, pUser->user);
5697
      }
5698
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
5699
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
5700
        code = TSDB_CODE_OUT_OF_MEMORY;
5701
        break;
5702
      }
5703
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
5704
      if (code < 0) {
5705
        mndUserFreeObj(&newUser);
5706
        sdbRelease(pSdb, pUser);
5707
        TAOS_RETURN(code);
5708
      }
5709
    }
5710

5711
    mndUserFreeObj(&newUser);
5712
    sdbRelease(pSdb, pUser);
5713
  }
5714
#endif
5715
  if (pUser != NULL) sdbRelease(pSdb, pUser);
91,918✔
5716
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
91,918✔
5717
  mndUserFreeObj(&newUser);
91,918✔
5718
  TAOS_RETURN(code);
91,918✔
5719
}
5720

UNCOV
5721
int64_t mndGetUserIpWhiteListVer(SMnode *pMnode, SUserObj *pUser) {
×
5722
  // ver = 0, disable ip white list
5723
  // ver > 0, enable ip white list
UNCOV
5724
  return tsEnableWhiteList ? pUser->ipWhiteListVer : 0;
×
5725
}
5726

UNCOV
5727
int64_t mndGetUserTimeWhiteListVer(SMnode *pMnode, SUserObj *pUser) {
×
5728
  // ver = 0, disable datetime white list
5729
  // ver > 0, enable datetime white list
UNCOV
5730
  return tsEnableWhiteList ? pUser->timeWhiteListVer : 0;
×
5731
}
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