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

taosdata / TDengine / #4905

29 Dec 2025 02:08PM UTC coverage: 65.423% (-0.3%) from 65.734%
#4905

push

travis-ci

web-flow
enh: sign connect request (#34067)

23 of 29 new or added lines in 4 files covered. (79.31%)

11614 existing lines in 186 files now uncovered.

193476 of 295730 relevant lines covered (65.42%)

115752566.53 hits per line

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

59.34
/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

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

143

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

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

157
static SUserCache userCache;
158

159

160
static int32_t userCacheInit() {
384,157✔
161
  _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
384,157✔
162

163
  SHashObj *users = taosHashInit(8, hashFn, 1, HASH_ENTRY_LOCK);
384,157✔
164
  if (users == NULL) {
384,157✔
UNCOV
165
    TAOS_RETURN(terrno);
×
166
  }
167

168
  userCache.users = users;
384,157✔
169
  userCache.verIp = 0;
384,157✔
170
  userCache.verTime = 0;
384,157✔
171

172
  (void)taosThreadRwlockInit(&userCache.rw, NULL);
384,157✔
173
  TAOS_RETURN(0);
384,157✔
174
}
175

176

177

178
static void userCacheCleanup() {
384,094✔
179
  if (userCache.users == NULL) {
384,094✔
UNCOV
180
    return;
×
181
  }
182

183
  void *pIter = taosHashIterate(userCache.users, NULL);
384,094✔
184
  while (pIter) {
775,318✔
185
    SCachedUserInfo *pInfo = *(SCachedUserInfo **)pIter;
391,224✔
186
    if (pInfo != NULL) {
391,224✔
187
      taosMemoryFree(pInfo->wlIp);
391,224✔
188
      taosMemoryFree(pInfo->wlTime);
391,224✔
189
      taosMemoryFree(pInfo);
391,224✔
190
    }
191
    pIter = taosHashIterate(userCache.users, pIter);
391,224✔
192
  }
193
  taosHashCleanup(userCache.users);
384,094✔
194

195
  (void)taosThreadRwlockDestroy(&userCache.rw);
384,094✔
196
}
197

198

199

200
static void userCacheRemoveUser(const char *user) {
19,418✔
201
  size_t userLen = strlen(user);
19,418✔
202

203
  (void)taosThreadRwlockWrlock(&userCache.rw);
19,418✔
204

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

219
  (void)taosThreadRwlockUnlock(&userCache.rw);
19,418✔
220
}
19,418✔
221

222

223

224
static void userCacheResetLoginInfo(const char *user) {
499✔
225
  size_t userLen = strlen(user);
499✔
226

227
  (void)taosThreadRwlockWrlock(&userCache.rw);
499✔
228

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

236
  (void)taosThreadRwlockUnlock(&userCache.rw);
499✔
237
}
499✔
238

239

240

241
static SCachedUserInfo* getCachedUserInfo(const char* user) {
3,250,838✔
242
  size_t userLen = strlen(user);
3,250,838✔
243
  SCachedUserInfo **ppInfo = taosHashGet(userCache.users, user, userLen);
3,250,838✔
244
  if (ppInfo != NULL) {
3,250,838✔
245
    return *ppInfo;
2,840,196✔
246
  }
247

248
  SCachedUserInfo  *pInfo = (SCachedUserInfo *)taosMemoryCalloc(1, sizeof(SCachedUserInfo));
410,642✔
249
  if (pInfo == NULL) {
410,642✔
UNCOV
250
    return NULL;
×
251
  }
252

253
  if (taosHashPut(userCache.users, user, userLen, &pInfo, sizeof(pInfo)) != 0) {
410,642✔
UNCOV
254
    taosMemoryFree(pInfo);
×
UNCOV
255
    return NULL;
×
256
  }
257

258
  return pInfo;
410,642✔
259
}
260

261

262

263
void mndGetUserLoginInfo(const char *user, SLoginInfo *pLoginInfo) {
1,906,058✔
264
  size_t userLen = strlen(user);
1,906,058✔
265

266
  (void)taosThreadRwlockRdlock(&userCache.rw);
1,906,058✔
267

268
  SCachedUserInfo **ppInfo = taosHashGet(userCache.users, user, userLen);
1,906,399✔
269
  if (ppInfo != NULL && *ppInfo != NULL) {
1,906,440✔
270
    pLoginInfo->lastLoginTime = (*ppInfo)->loginInfo.lastLoginTime;
1,638,248✔
271
    pLoginInfo->failedLoginCount = (*ppInfo)->loginInfo.failedLoginCount;
1,637,750✔
272
    pLoginInfo->lastFailedLoginTime = (*ppInfo)->loginInfo.lastFailedLoginTime;
1,637,987✔
273
  } else {
274
    pLoginInfo->lastLoginTime = taosGetTimestampSec();
268,192✔
275
    pLoginInfo->failedLoginCount = 0;
268,192✔
276
    pLoginInfo->lastFailedLoginTime = 0;
268,192✔
277
  }
278

279
  (void)taosThreadRwlockUnlock(&userCache.rw);
1,906,440✔
280

281
  if (pLoginInfo->lastLoginTime == 0) {
1,906,058✔
282
    pLoginInfo->lastLoginTime = taosGetTimestampSec();
26,117✔
283
  }
284
}
1,906,058✔
285

286

287

288
void mndSetUserLoginInfo(const char *user, const SLoginInfo *pLoginInfo) {
1,906,440✔
289
  size_t userLen = strlen(user);
1,906,440✔
290

291
  (void)taosThreadRwlockWrlock(&userCache.rw);
1,906,440✔
292

293
  SCachedUserInfo  *pInfo = getCachedUserInfo(user);
1,906,440✔
294
  if (pInfo != NULL) {
1,906,440✔
295
    pInfo->loginInfo.lastLoginTime = pLoginInfo->lastLoginTime;
1,906,440✔
296
    pInfo->loginInfo.failedLoginCount = pLoginInfo->failedLoginCount;
1,906,440✔
297
    pInfo->loginInfo.lastFailedLoginTime = pLoginInfo->lastFailedLoginTime;
1,906,440✔
298
  }
299

300
  (void)taosThreadRwlockUnlock(&userCache.rw);
1,906,440✔
301
}
1,906,440✔
302

303

304

305
static bool isDateTimeWhiteListEqual(SDateTimeWhiteList *a, SDateTimeWhiteList *b) {
996,744✔
306
  if (a == NULL && b == NULL) {
996,744✔
UNCOV
307
    return true;
×
308
  }
309

310
  if (a == NULL || b == NULL) {
996,744✔
311
    return false;
45,986✔
312
  }
313

314
  if (a->num != b->num) {
950,758✔
UNCOV
315
    return false;
×
316
  }
317

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

327
  return true;
950,758✔
328
}
329

330

331

332
static int32_t userCacheUpdateWhiteList(SMnode* pMnode, SUserObj* pUser) {
996,744✔
333
  int32_t code = 0, lino = 0;
996,744✔
334

335
  (void)taosThreadRwlockWrlock(&userCache.rw);
996,744✔
336

337
  SCachedUserInfo *pInfo = getCachedUserInfo(pUser->user);
996,744✔
338
  if (pInfo == NULL) {
996,744✔
UNCOV
339
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
340
  }
341

342
  if (!isIpWhiteListEqual(pInfo->wlIp, pUser->pIpWhiteListDual)) {
996,744✔
343
    SIpWhiteListDual *p = cloneIpWhiteList(pUser->pIpWhiteListDual);
46,141✔
344
    if (p == NULL) {
46,141✔
UNCOV
345
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
346
    }
347
    taosMemoryFree(pInfo->wlIp);
46,141✔
348
    pInfo->wlIp = p;
46,141✔
349
    userCache.verIp++;
46,141✔
350
  }
351

352
  if (!isDateTimeWhiteListEqual(pInfo->wlTime, pUser->pTimeWhiteList)) {
996,744✔
353
    SDateTimeWhiteList *p = cloneDateTimeWhiteList(pUser->pTimeWhiteList);
45,986✔
354
    if (p == NULL) {
45,986✔
UNCOV
355
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
356
    }
357
    taosMemoryFree(pInfo->wlTime);
45,986✔
358
    pInfo->wlTime = p;
45,986✔
359
    userCache.verTime++;
45,986✔
360
  }
361

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

370

371

372
static int32_t userCacheRebuildIpWhiteList(SMnode *pMnode) {
464,850✔
373
  int32_t   code = 0, lino = 0;
464,850✔
374

375
  SSdb     *pSdb = pMnode->pSdb;
464,850✔
376
  void     *pIter = NULL;
464,850✔
377
  while (1) {
177,919✔
378
    SUserObj *pUser = NULL;
642,769✔
379
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
642,769✔
380
    if (pIter == NULL) {
642,769✔
381
      break;
464,850✔
382
    }
383

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

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

398
    taosMemoryFree(pInfo->wlIp);
177,919✔
399
    pInfo->wlIp = wl;
177,919✔
400

401
    sdbRelease(pSdb, pUser);
177,919✔
402
  }
403

404
  userCache.verIp++;
464,850✔
405

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

413

414

415
int64_t mndGetIpWhiteListVersion(SMnode *pMnode) {
38,043,597✔
416
  int64_t ver = 0;
38,043,597✔
417
  int32_t code = 0;
38,043,597✔
418

419
  if (mndEnableIpWhiteList(pMnode) != 0 && tsEnableWhiteList) {
38,043,597✔
420
    (void)taosThreadRwlockWrlock(&userCache.rw);
3,871✔
421

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

433
    (void)taosThreadRwlockUnlock(&userCache.rw);
3,871✔
434
  }
435

436
  mDebug("ip-white-list on mnode ver: %" PRId64, ver);
38,043,597✔
437
  return ver;
38,043,597✔
438
}
439

440

441

442
int32_t mndRefreshUserIpWhiteList(SMnode *pMnode) {
464,850✔
443
  int32_t code = 0;
464,850✔
444
  (void)taosThreadRwlockWrlock(&userCache.rw);
464,850✔
445

446
  if ((code = userCacheRebuildIpWhiteList(pMnode)) != 0) {
464,850✔
UNCOV
447
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
UNCOV
448
    TAOS_RETURN(code);
×
449
  }
450
  userCache.verIp = taosGetTimestampMs();
464,850✔
451
  (void)taosThreadRwlockUnlock(&userCache.rw);
464,850✔
452

453
  TAOS_RETURN(code);
464,850✔
454
}
455

456

457

458
static int32_t userCacheRebuildTimeWhiteList(SMnode *pMnode) {
456,666✔
459
  int32_t   code = 0, lino = 0;
456,666✔
460

461
  SSdb     *pSdb = pMnode->pSdb;
456,666✔
462
  void     *pIter = NULL;
456,666✔
463
  while (1) {
169,735✔
464
    SUserObj *pUser = NULL;
626,401✔
465
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
626,401✔
466
    if (pIter == NULL) {
626,401✔
467
      break;
456,666✔
468
    }
469

470
    SCachedUserInfo *pInfo = getCachedUserInfo(pUser->user);
169,735✔
471
    if (pInfo == NULL) {
169,735✔
472
      sdbRelease(pSdb, pUser);
×
UNCOV
473
      sdbCancelFetch(pSdb, pIter);
×
UNCOV
474
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
475
    }
476

477
    SDateTimeWhiteList *wl = cloneDateTimeWhiteList(pUser->pTimeWhiteList);
169,735✔
478
    if (wl == NULL) {
169,735✔
479
      sdbRelease(pSdb, pUser);
×
UNCOV
480
      sdbCancelFetch(pSdb, pIter);
×
UNCOV
481
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
482
    }
483

484
    taosMemoryFree(pInfo->wlTime);
169,735✔
485
    pInfo->wlTime = wl;
169,735✔
486

487
    sdbRelease(pSdb, pUser);
169,735✔
488
  }
489

490
  userCache.verTime++;
456,666✔
491

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

499

500

501
int32_t mndRefreshUserDateTimeWhiteList(SMnode *pMnode) {
456,666✔
502
  int32_t code = 0;
456,666✔
503
  (void)taosThreadRwlockWrlock(&userCache.rw);
456,666✔
504

505
  if ((code = userCacheRebuildTimeWhiteList(pMnode)) != 0) {
456,666✔
UNCOV
506
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
UNCOV
507
    TAOS_RETURN(code);
×
508
  }
509
  userCache.verTime = taosGetTimestampMs();
456,666✔
510
  (void)taosThreadRwlockUnlock(&userCache.rw);
456,666✔
511

512
  TAOS_RETURN(code);
456,666✔
513
}
514

515

516

517
int64_t mndGetTimeWhiteListVersion(SMnode *pMnode) {
38,043,597✔
518
  int64_t ver = 0;
38,043,597✔
519
  int32_t code = 0;
38,043,597✔
520

521
  if (mndEnableTimeWhiteList(pMnode) != 0 && tsEnableWhiteList) {
38,043,597✔
522
    (void)taosThreadRwlockWrlock(&userCache.rw);
3,871✔
523

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

535
    (void)taosThreadRwlockUnlock(&userCache.rw);
3,871✔
536
  }
537

538
  mDebug("datetime-white-list on mnode ver: %" PRId64, ver);
38,043,597✔
539
  return ver;
38,043,597✔
540
}
541

542

543

544
int32_t mndInitUser(SMnode *pMnode) {
384,157✔
545
  TAOS_CHECK_RETURN(userCacheInit());
384,157✔
546

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

559
  mndSetMsgHandle(pMnode, TDMT_MND_CREATE_USER, mndProcessCreateUserReq);
384,157✔
560
  mndSetMsgHandle(pMnode, TDMT_MND_ALTER_USER, mndProcessAlterUserReq);
384,157✔
561
  mndSetMsgHandle(pMnode, TDMT_MND_DROP_USER, mndProcessDropUserReq);
384,157✔
562
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_AUTH, mndProcessGetUserAuthReq);
384,157✔
563

564
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_IP_WHITELIST, mndProcessGetUserIpWhiteListReq);
384,157✔
565
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_IP_WHITELIST_DUAL, mndProcessGetUserIpWhiteListReq);
384,157✔
566
  mndSetMsgHandle(pMnode, TDMT_MND_RETRIEVE_IP_WHITELIST, mndProcessRetrieveIpWhiteListReq);
384,157✔
567
  mndSetMsgHandle(pMnode, TDMT_MND_RETRIEVE_IP_WHITELIST_DUAL, mndProcessRetrieveIpWhiteListReq);
384,157✔
568
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_DATETIME_WHITELIST, mndProcessGetUserDateTimeWhiteListReq);
384,157✔
569
  mndSetMsgHandle(pMnode, TDMT_MND_RETRIEVE_DATETIME_WHITELIST, mndProcessRetrieveDateTimeWhiteListReq);
384,157✔
570

571
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_USER, mndRetrieveUsers);
384,157✔
572
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_USER, mndCancelGetNextUser);
384,157✔
573
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_USER_FULL, mndRetrieveUsersFull);
384,157✔
574
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_USER_FULL, mndCancelGetNextUser);
384,157✔
575
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_PRIVILEGES, mndRetrievePrivileges);
384,157✔
576
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_PRIVILEGES, mndCancelGetNextPrivileges);
384,157✔
577
  return sdbSetTable(pMnode->pSdb, table);
384,157✔
578
}
579

580

581

582
void mndCleanupUser(SMnode *pMnode) {
384,094✔
583
  userCacheCleanup();
384,094✔
584
}
384,094✔
585

586

587

UNCOV
588
static bool isDefaultRange(SIpRange *pRange) {
×
589
  int32_t code = 0;
×
590
  int32_t lino = 0;
×
591

592
  SIpRange range4 = {0};
×
593
  SIpRange range6 = {0};
×
594

595
  code = createDefaultIp4Range(&range4);
×
596
  TSDB_CHECK_CODE(code, lino, _error);
×
597

598
  code = createDefaultIp6Range(&range6);
×
599
  TSDB_CHECK_CODE(code, lino, _error);
×
600

601
  if (isIpRangeEqual(pRange, &range4) || (isIpRangeEqual(pRange, &range6))) {
×
602
    return true;
×
603
  }
UNCOV
604
_error:
×
UNCOV
605
  return false;
×
606
};
607

608

609

610
static int32_t ipRangeListToStr(SIpRange *range, int32_t num, char *buf, int64_t bufLen) {
18,415✔
611
  int32_t len = 0;
18,415✔
612
  for (int i = 0; i < num; i++) {
55,865✔
613
    SIpRange *pRange = &range[i];
37,450✔
614
    SIpAddr   addr = {0};
37,450✔
615
    int32_t code = tIpUintToStr(pRange, &addr);
37,450✔
616
    if (code != 0) {
37,450✔
UNCOV
617
      mError("%s failed to convert ip range to str, code: %d", __func__, code);
×
618
    }
619

620
    len += tsnprintf(buf + len, bufLen - len, "%c%s/%d, ", pRange->neg ? '-' : '+', IP_ADDR_STR(&addr), addr.mask);
37,450✔
621
  }
622
  if (len > 0) buf[len - 2] = 0;
18,415✔
623
  return len;
18,415✔
624
}
625

626

627

628
static bool isIpRangeEqual(SIpRange *a, SIpRange *b) {
1,901,206✔
629
  if (a->type != b->type || a->neg != b->neg) {
1,901,206✔
UNCOV
630
    return false;
×
631
  }
632

633
  if (a->type == 0) {
1,901,206✔
634
    SIpV4Range *a4 = &a->ipV4;
950,758✔
635
    SIpV4Range *b4 = &b->ipV4;
950,758✔
636
    return (a4->ip == b4->ip && a4->mask == b4->mask);
950,758✔
637
  }
638
  
639
  SIpV6Range *a6 = &a->ipV6;
950,448✔
640
  SIpV6Range *b6 = &b->ipV6;
950,448✔
641
  return (a6->addr[0] == b6->addr[0] && a6->addr[1] == b6->addr[1] && a6->mask == b6->mask);
950,448✔
642
}
643

644

645

646
static bool isIpWhiteListEqual(SIpWhiteListDual *a, SIpWhiteListDual *b) {
996,744✔
647
  if (a == NULL && b == NULL) {
996,744✔
UNCOV
648
    return true;
×
649
  }
650
  
651
  if (a == NULL || b == NULL) {
996,744✔
652
    return false;
45,986✔
653
  }
654

655
  if (a->num != b->num) {
950,758✔
656
    return false;
155✔
657
  }
658
  for (int i = 0; i < a->num; i++) {
2,851,809✔
659
    if (!isIpRangeEqual(&a->pIpRanges[i], &b->pIpRanges[i])) {
1,901,206✔
UNCOV
660
      return false;
×
661
    }
662
  }
663
  return true;
950,603✔
664
}
665

666

667
static int32_t compareIpRange(const void *a, const void *b, const void* arg) {
1,705✔
668
  SIpRange *ra = (SIpRange *)a;
1,705✔
669
  SIpRange *rb = (SIpRange *)b;
1,705✔
670

671
  if (ra->neg != rb->neg) {
1,705✔
UNCOV
672
    return (ra->neg) ? -1 : 1;
×
673
  }
674

675
  if (ra->type != rb->type) {
1,705✔
UNCOV
676
    return (ra->type == 0) ? -1 : 1;
×
677
  }
678

679
  if (ra->type == 0) {
1,705✔
680
    if (ra->ipV4.ip != rb->ipV4.ip) {
1,705✔
681
      return (ra->ipV4.ip < rb->ipV4.ip) ? -1 : 1;
1,395✔
682
    }
683
    return (ra->ipV4.mask < rb->ipV4.mask) ? -1 : 1;
310✔
684
  }
685

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

695
static void sortIpWhiteList(SIpWhiteListDual *pList) {
777✔
696
  (void)taosqsort(pList->pIpRanges, pList->num, sizeof(SIpRange), NULL, compareIpRange);
777✔
697
}
777✔
698

699

700

701
static int32_t convertIpWhiteListToStr(SUserObj *pUser, char **buf) {
18,415✔
702
  SIpWhiteListDual *pList = pUser->pIpWhiteListDual;
18,415✔
703

704
  int64_t bufLen = pList->num * 128 + 8;
18,415✔
705
  *buf = taosMemoryCalloc(1, bufLen);
18,415✔
706
  if (*buf == NULL) {
18,415✔
UNCOV
707
    return 0;
×
708
  }
709

710
  if (pList->num == 0) {
18,415✔
UNCOV
711
    return tsnprintf(*buf, bufLen, "+ALL");
×
712
  }
713

714
  int32_t len = ipRangeListToStr(pList->pIpRanges, pList->num, *buf, bufLen - 2);
18,415✔
715
  if (len == 0) {
18,415✔
UNCOV
716
    taosMemoryFreeClear(*buf);
×
UNCOV
717
    return 0;
×
718
  }
719
  return len;
18,415✔
720
}
721

722

723

724
static int32_t tSerializeIpWhiteList(void *buf, int32_t len, SIpWhiteListDual *pList, uint32_t *pLen) {
2,117,672✔
725
  int32_t  code = 0;
2,117,672✔
726
  int32_t  lino = 0;
2,117,672✔
727
  int32_t  tlen = 0;
2,117,672✔
728
  SEncoder encoder = {0};
2,117,672✔
729
  tEncoderInit(&encoder, buf, len);
2,117,672✔
730

731
  TAOS_CHECK_GOTO(tStartEncode(&encoder), &lino, _OVER);
2,117,672✔
732
  TAOS_CHECK_GOTO(tEncodeI32(&encoder, pList->num), &lino, _OVER);
4,235,344✔
733

734
  for (int i = 0; i < pList->num; i++) {
6,353,477✔
735
    SIpRange *pRange = &(pList->pIpRanges[i]);
4,235,805✔
736
    TAOS_CHECK_GOTO(tSerializeIpRange(&encoder, pRange), &lino, _OVER);
4,235,805✔
737
  }
738

739
  tEndEncode(&encoder);
2,117,672✔
740

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

751
static int32_t tDerializeIpWhiteList(void *buf, int32_t len, SIpWhiteListDual *pList, bool supportNeg) {
1,411,543✔
752
  int32_t  code = 0;
1,411,543✔
753
  int32_t  lino = 0;
1,411,543✔
754
  SDecoder decoder = {0};
1,411,543✔
755
  tDecoderInit(&decoder, buf, len);
1,411,543✔
756

757
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
1,411,543✔
758
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &pList->num), &lino, _OVER);
2,823,086✔
759

760
  for (int i = 0; i < pList->num; i++) {
4,234,937✔
761
    SIpRange *pRange = &(pList->pIpRanges[i]);
2,823,394✔
762
    TAOS_CHECK_GOTO(tDeserializeIpRange(&decoder, pRange, supportNeg), &lino, _OVER);
2,823,394✔
763
  }
764

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

774
static int32_t tDerializeIpWhileListFromOldVer(void *buf, int32_t len, SIpWhiteList *pList) {
×
775
  int32_t  code = 0;
×
UNCOV
776
  int32_t  lino = 0;
×
777
  SDecoder decoder = {0};
×
778
  tDecoderInit(&decoder, buf, len);
×
779

780
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
×
781
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &pList->num), &lino, _OVER);
×
782

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

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

798
static int32_t createIpWhiteList(void *buf, int32_t len, SIpWhiteListDual **ppList, bool supportNeg) {
1,411,543✔
799
  int32_t           code = 0;
1,411,543✔
800
  int32_t           lino = 0;
1,411,543✔
801
  int32_t           num = 0;
1,411,543✔
802
  SIpWhiteListDual *p = NULL;
1,411,543✔
803
  SDecoder          decoder = {0};
1,411,543✔
804
  tDecoderInit(&decoder, buf, len);
1,411,543✔
805

806
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
1,411,543✔
807
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &num), &lino, _OVER);
1,411,543✔
808

809
  p = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + num * sizeof(SIpRange));
1,411,543✔
810
  if (p == NULL) {
1,411,543✔
UNCOV
811
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
812
  }
813
  TAOS_CHECK_GOTO(tDerializeIpWhiteList(buf, len, p, supportNeg), &lino, _OVER);
1,411,543✔
814

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

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

834
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
×
835
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &num), &lino, _OVER);
×
836

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

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

854
static int32_t createDefaultIpWhiteList(SIpWhiteListDual **ppWhiteList) {
321,814✔
855
  int32_t code = 0;
321,814✔
856
  int32_t lino = 0;
321,814✔
857
  *ppWhiteList = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + sizeof(SIpRange) * 2);
321,814✔
858
  if (*ppWhiteList == NULL) {
321,814✔
UNCOV
859
    TAOS_RETURN(terrno);
×
860
  }
861
  (*ppWhiteList)->num = 2;
321,814✔
862

863
  SIpRange v4 = {0};
321,814✔
864
  SIpRange v6 = {0};
321,814✔
865

866
#ifndef TD_ASTRA
867
  code = createDefaultIp4Range(&v4);
321,814✔
868
  TSDB_CHECK_CODE(code, lino, _error);
321,814✔
869

870
  code = createDefaultIp6Range(&v6);
321,814✔
871
  TSDB_CHECK_CODE(code, lino, _error);
321,814✔
872

873
#endif
874

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

887

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

890
static int32_t convertTimeRangesToStr(SUserObj *pUser, char **buf) {
18,415✔
891
  int32_t bufLen = pUser->pTimeWhiteList->num * 32 + 8;
18,415✔
892
  *buf = taosMemoryCalloc(1, bufLen);
18,415✔
893
  if (*buf == NULL) {
18,415✔
UNCOV
894
    return 0;
×
895
  }
896

897
  int32_t pos = 0;
18,415✔
898
  if (pUser->pTimeWhiteList->num == 0) {
18,415✔
899
    pos += tsnprintf(*buf + pos, bufLen - pos, "+ALL");
18,415✔
900
    return pos;
18,415✔
901
  }
902

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

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

UNCOV
919
  if (pos > 0) {
×
920
    (*buf)[pos - 2] = 0; // remove last ", "
×
921
  }
922

UNCOV
923
  return pos;
×
924
}
925

926

UNCOV
927
static int32_t compareDateTimeInterval(const void *a, const void *b, const void* arg) {
×
928
  SDateTimeWhiteListItem *pA = (SDateTimeWhiteListItem *)a;
×
929
  SDateTimeWhiteListItem *pB = (SDateTimeWhiteListItem *)b;
×
930

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

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

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

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

947
  return 0;
×
948
}
949

UNCOV
950
static void sortTimeWhiteList(SDateTimeWhiteList *pList) {
×
UNCOV
951
  (void)taosqsort(pList->ranges, pList->num, sizeof(SDateTimeWhiteListItem), NULL, compareDateTimeInterval);
×
UNCOV
952
}
×
953

954

955

956

957
static void dropOldPasswords(SUserObj *pUser) {
3,529,215✔
958
  if (pUser->numOfPasswords <= pUser->passwordReuseMax) {
3,529,215✔
959
    return;
3,524,382✔
960
  }
961

962
  int32_t reuseMax = pUser->passwordReuseMax;
4,833✔
963
  if (reuseMax == 0) {
4,833✔
964
    reuseMax = 1; // keep at least one password
3,263✔
965
  }
966

967
  int32_t now = taosGetTimestampSec();
4,833✔
968
  int32_t index = reuseMax;
4,833✔
969
  while(index < pUser->numOfPasswords) {
9,229✔
970
    SUserPassword *pPass = &pUser->passwords[index];
4,396✔
971
    if (now - pPass->setTime >= pUser->passwordReuseTime) {
4,396✔
UNCOV
972
      break;
×
973
    }
974
    index++;
4,396✔
975
  }
976

977
  if (index == pUser->numOfPasswords) {
4,833✔
978
    return;
4,833✔
979
  }
UNCOV
980
  pUser->numOfPasswords = index;
×
981
  // this is a shrink operation, no need to check return value
UNCOV
982
  pUser->passwords = taosMemoryRealloc(pUser->passwords, sizeof(SUserPassword) * pUser->numOfPasswords);
×
983
}
984

985

986

987

988
static int32_t mndCreateDefaultUser(SMnode *pMnode, char *acct, char *user, char *pass) {
276,452✔
989
  int32_t  code = 0;
276,452✔
990
  int32_t  lino = 0;
276,452✔
991
  SUserObj userObj = {0};
276,452✔
992

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

1004
  userObj.passwords[0].setTime = taosGetTimestampSec();
276,452✔
1005
  userObj.numOfPasswords = 1;
276,452✔
1006

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

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

1052
  userObj.roles = taosHashInit(1, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
276,452✔
1053
  if (userObj.roles == NULL) {
276,452✔
UNCOV
1054
    TAOS_CHECK_GOTO(terrno, &lino, _ERROR);
×
1055
  }
1056

1057
  if ((code = taosHashPut(userObj.roles, TSDB_ROLE_SYSDBA, strlen(TSDB_ROLE_SYSDBA) + 1, NULL, 0)) ||
552,904✔
1058
      (code = taosHashPut(userObj.roles, TSDB_ROLE_SYSSEC, strlen(TSDB_ROLE_SYSSEC) + 1, NULL, 0)) ||
552,904✔
1059
      (code = taosHashPut(userObj.roles, TSDB_ROLE_SYSAUDIT, strlen(TSDB_ROLE_SYSAUDIT) + 1, NULL, 0))) {
276,452✔
UNCOV
1060
    TAOS_CHECK_GOTO(code, &lino, _ERROR);
×
1061
  }
1062

1063
  SSdbRaw *pRaw = mndUserActionEncode(&userObj);
276,452✔
1064
  if (pRaw == NULL) goto _ERROR;
276,452✔
1065
  TAOS_CHECK_GOTO(sdbSetRawStatus(pRaw, SDB_STATUS_READY), &lino, _ERROR);
276,452✔
1066

1067
  mInfo("user:%s, will be created when deploying, raw:%p", userObj.user, pRaw);
276,452✔
1068

1069
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_ROLE, NULL, "create-user");
276,452✔
1070
  if (pTrans == NULL) {
276,452✔
1071
    sdbFreeRaw(pRaw);
×
1072
    mError("user:%s, failed to create since %s", userObj.user, terrstr());
×
UNCOV
1073
    goto _ERROR;
×
1074
  }
1075
  mInfo("trans:%d, used to create user:%s", pTrans->id, userObj.user);
276,452✔
1076

1077
  if (mndTransAppendCommitlog(pTrans, pRaw) != 0) {
276,452✔
UNCOV
1078
    mError("trans:%d, failed to commit redo log since %s", pTrans->id, terrstr());
×
UNCOV
1079
    mndTransDrop(pTrans);
×
UNCOV
1080
    goto _ERROR;
×
1081
  }
1082
  TAOS_CHECK_GOTO(sdbSetRawStatus(pRaw, SDB_STATUS_READY), &lino, _ERROR);
276,452✔
1083

1084
  if (mndTransPrepare(pMnode, pTrans) != 0) {
276,452✔
1085
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
UNCOV
1086
    mndTransDrop(pTrans);
×
UNCOV
1087
    goto _ERROR;
×
1088
  }
1089

1090
  mndTransDrop(pTrans);
276,452✔
1091
  mndUserFreeObj(&userObj);
276,452✔
1092
  return 0;
276,452✔
1093

UNCOV
1094
_ERROR:
×
UNCOV
1095
  mndUserFreeObj(&userObj);
×
UNCOV
1096
  if (code == 0) {
×
UNCOV
1097
    code = terrno ? terrno : TSDB_CODE_APP_ERROR;
×
1098
  }
UNCOV
1099
  mError("user:%s, failed to create default user since %s", user, tstrerror(code));
×
UNCOV
1100
  TAOS_RETURN(code);
×
1101
}
1102

1103
static int32_t mndCreateDefaultUsers(SMnode *pMnode) {
276,452✔
1104
  return mndCreateDefaultUser(pMnode, TSDB_DEFAULT_USER, TSDB_DEFAULT_USER, TSDB_DEFAULT_PASS);
276,452✔
1105
}
1106

1107
static int32_t tSerializeUserObjExt(void *buf, int32_t bufLen, SUserObj *pObj) {
4,235,344✔
1108
  int32_t  code = 0, lino = 0;
4,235,344✔
1109
  int32_t  tlen = 0;
4,235,344✔
1110
  void    *pIter = NULL;
4,235,344✔
1111
  SEncoder encoder = {0};
4,235,344✔
1112
  tEncoderInit(&encoder, buf, bufLen);
4,235,344✔
1113

1114
  TAOS_CHECK_EXIT(tStartEncode(&encoder));
4,235,344✔
1115
  TAOS_CHECK_EXIT(tEncodeI64v(&encoder, pObj->uid));
8,470,688✔
1116

1117
  TAOS_CHECK_EXIT(tSerializePrivSysObjPolicies(&encoder, &pObj->sysPrivs, pObj->objPrivs));
4,235,344✔
1118

1119
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->selectTbs));
4,235,344✔
1120
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->insertTbs));
4,235,344✔
1121
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->updateTbs));
4,235,344✔
1122
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->deleteTbs));
4,235,344✔
1123

1124
  int32_t nRoles = taosHashGetSize(pObj->roles);
4,235,344✔
1125
  TAOS_CHECK_EXIT(tEncodeI32v(&encoder, nRoles));
4,235,344✔
1126

1127
  while ((pIter = taosHashIterate(pObj->roles, pIter))) {
12,508,690✔
1128
    size_t keyLen = 0;
8,273,346✔
1129
    char  *key = taosHashGetKey(pIter, &keyLen);  // key: role name
8,273,346✔
1130
    TAOS_CHECK_EXIT(tEncodeCStr(&encoder, key));
8,273,346✔
1131

1132
    uint8_t flag = *(int8_t *)pIter;
8,273,346✔
1133
    TAOS_CHECK_EXIT(tEncodeU8(&encoder, flag));  // value: 0 reset, 1 set(default)
16,546,692✔
1134
  }
1135

1136
  tEndEncode(&encoder);
4,235,344✔
1137
  tlen = encoder.pos;
4,235,344✔
1138
_exit:
4,235,344✔
1139
  tEncoderClear(&encoder);
4,235,344✔
1140
  if (code < 0) {
4,235,344✔
UNCOV
1141
    mError("user:%s, %s failed at line %d since %s", pObj->user, __func__, lino, tstrerror(code));
×
UNCOV
1142
    TAOS_RETURN(code);
×
1143
  }
1144

1145
  return tlen;
4,235,344✔
1146
}
1147

1148
static int32_t tDeserializeUserObjExt(void *buf, int32_t bufLen, SUserObj *pObj) {
1,411,543✔
1149
  int32_t  code = 0, lino = 0;
1,411,543✔
1150
  SDecoder decoder = {0};
1,411,543✔
1151
  tDecoderInit(&decoder, buf, bufLen);
1,411,543✔
1152

1153
  TAOS_CHECK_EXIT(tStartDecode(&decoder));
1,411,543✔
1154
  TAOS_CHECK_EXIT(tDecodeI64v(&decoder, &pObj->uid));
2,823,086✔
1155
  TAOS_CHECK_EXIT(tDeserializePrivSysObjPolicies(&decoder, &pObj->sysPrivs, &pObj->objPrivs));
1,411,543✔
1156
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->selectTbs));
1,411,543✔
1157
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->insertTbs));
1,411,543✔
1158
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->updateTbs));
1,411,543✔
1159
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->deleteTbs));
1,411,543✔
1160
  int32_t nRoles = 0;
1,411,543✔
1161
  TAOS_CHECK_EXIT(tDecodeI32v(&decoder, &nRoles));
1,411,543✔
1162
  if (nRoles > 0) {
1,411,543✔
1163
    if (!pObj->roles &&
1,411,388✔
1164
        !(pObj->roles = taosHashInit(nRoles, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), 1, HASH_ENTRY_LOCK))) {
1,411,388✔
UNCOV
1165
      TAOS_CHECK_EXIT(terrno);
×
1166
    }
1167
    for (int32_t i = 0; i < nRoles; i++) {
3,592,902✔
1168
      int32_t keyLen = 0;
2,181,514✔
1169
      char   *key = NULL;
2,181,514✔
1170
      TAOS_CHECK_EXIT(tDecodeCStrAndLen(&decoder, &key, &keyLen));
2,181,514✔
1171
      uint8_t flag = 0;
2,181,514✔
1172
      TAOS_CHECK_EXIT(tDecodeU8(&decoder, &flag));
2,181,514✔
1173
      TAOS_CHECK_EXIT(taosHashPut(pObj->roles, key, keyLen + 1, &flag, sizeof(flag)));
2,181,514✔
1174
    }
1175
  }
1176

1177
_exit:
1,411,543✔
1178
  tEndDecode(&decoder);
1,411,543✔
1179
  tDecoderClear(&decoder);
1,411,543✔
1180
  if (code < 0) {
1,411,543✔
UNCOV
1181
    mError("user, %s failed at line %d since %s, row:%p", __func__, lino, tstrerror(code), pObj);
×
1182
  }
1183
  TAOS_RETURN(code);
1,411,543✔
1184
}
1185

1186
SSdbRaw *mndUserActionEncode(SUserObj *pUser) {
2,117,672✔
1187
  int32_t code = 0;
2,117,672✔
1188
  int32_t lino = 0;
2,117,672✔
1189
  int32_t passReserve = (sizeof(SUserPassword) + 8) * pUser->numOfPasswords + 4;
2,117,672✔
1190
  int32_t ipWhiteReserve = pUser->pIpWhiteListDual ? (sizeof(SIpRange) * pUser->pIpWhiteListDual->num + sizeof(SIpWhiteListDual) + 4) : 16;
2,117,672✔
1191
  int32_t timeWhiteReserve = pUser->pTimeWhiteList ? (sizeof(SDateTimeWhiteListItem) * pUser->pTimeWhiteList->num + sizeof(SDateTimeWhiteList) + 4) : 16;
2,117,672✔
1192
  int32_t numOfReadDbs = 0; //taosHashGetSize(pUser->readDbs);
2,117,672✔
1193
  int32_t numOfWriteDbs = 0; //taosHashGetSize(pUser->writeDbs);
2,117,672✔
1194
  int32_t numOfReadTbs = 0; //taosHashGetSize(pUser->readTbs);
2,117,672✔
1195
  int32_t numOfWriteTbs = 0; //taosHashGetSize(pUser->writeTbs);
2,117,672✔
1196
  int32_t numOfAlterTbs = 0; //taosHashGetSize(pUser->alterTbs);
2,117,672✔
1197
  int32_t numOfReadViews = 0; //taosHashGetSize(pUser->readViews);
2,117,672✔
1198
  int32_t numOfWriteViews = 0; //taosHashGetSize(pUser->writeViews);
2,117,672✔
1199
  int32_t numOfAlterViews = 0; //taosHashGetSize(pUser->alterViews);
2,117,672✔
1200
  int32_t numOfTopics = 0; // taosHashGetSize(pUser->topics);
2,117,672✔
1201
  int32_t numOfUseDbs = 0; // taosHashGetSize(pUser->useDbs);
2,117,672✔
1202
  int32_t numOfRoles = taosHashGetSize(pUser->roles);
2,117,672✔
1203
  int32_t size = sizeof(SUserObj) + USER_RESERVE_SIZE + (numOfReadDbs + numOfWriteDbs) * TSDB_DB_FNAME_LEN +
2,117,672✔
1204
                 numOfTopics * TSDB_TOPIC_FNAME_LEN + ipWhiteReserve + timeWhiteReserve + passReserve;
2,117,672✔
1205
  char    *buf = NULL;
2,117,672✔
1206
  SSdbRaw *pRaw = NULL;
2,117,672✔
1207

1208
  char *stb = NULL;
2,117,672✔
1209
#if 0
1210
  stb = taosHashIterate(pUser->readTbs, NULL);
1211
  while (stb != NULL) {
1212
    size_t keyLen = 0;
1213
    void  *key = taosHashGetKey(stb, &keyLen);
1214
    size += sizeof(int32_t);
1215
    size += keyLen;
1216

1217
    size_t valueLen = 0;
1218
    valueLen = strlen(stb) + 1;
1219
    size += sizeof(int32_t);
1220
    size += valueLen;
1221
    stb = taosHashIterate(pUser->readTbs, stb);
1222
  }
1223

1224
  stb = taosHashIterate(pUser->writeTbs, NULL);
1225
  while (stb != NULL) {
1226
    size_t keyLen = 0;
1227
    void  *key = taosHashGetKey(stb, &keyLen);
1228
    size += sizeof(int32_t);
1229
    size += keyLen;
1230

1231
    size_t valueLen = 0;
1232
    valueLen = strlen(stb) + 1;
1233
    size += sizeof(int32_t);
1234
    size += valueLen;
1235
    stb = taosHashIterate(pUser->writeTbs, stb);
1236
  }
1237
  stb = taosHashIterate(pUser->alterTbs, NULL);
1238
  while (stb != NULL) {
1239
    size_t keyLen = 0;
1240
    void  *key = taosHashGetKey(stb, &keyLen);
1241
    size += sizeof(int32_t);
1242
    size += keyLen;
1243

1244
    size_t valueLen = 0;
1245
    valueLen = strlen(stb) + 1;
1246
    size += sizeof(int32_t);
1247
    size += valueLen;
1248
    stb = taosHashIterate(pUser->alterTbs, stb);
1249
  }
1250

1251
  stb = taosHashIterate(pUser->readViews, NULL);
1252
  while (stb != NULL) {
1253
    size_t keyLen = 0;
1254
    void  *key = taosHashGetKey(stb, &keyLen);
1255
    size += sizeof(int32_t);
1256
    size += keyLen;
1257

1258
    size_t valueLen = 0;
1259
    valueLen = strlen(stb) + 1;
1260
    size += sizeof(int32_t);
1261
    size += valueLen;
1262
    stb = taosHashIterate(pUser->readViews, stb);
1263
  }
1264

1265
  stb = taosHashIterate(pUser->writeViews, NULL);
1266
  while (stb != NULL) {
1267
    size_t keyLen = 0;
1268
    void  *key = taosHashGetKey(stb, &keyLen);
1269
    size += sizeof(int32_t);
1270
    size += keyLen;
1271

1272
    size_t valueLen = 0;
1273
    valueLen = strlen(stb) + 1;
1274
    size += sizeof(int32_t);
1275
    size += valueLen;
1276
    stb = taosHashIterate(pUser->writeViews, stb);
1277
  }
1278

1279
  stb = taosHashIterate(pUser->alterViews, NULL);
1280
  while (stb != NULL) {
1281
    size_t keyLen = 0;
1282
    void  *key = taosHashGetKey(stb, &keyLen);
1283
    size += sizeof(int32_t);
1284
    size += keyLen;
1285

1286
    size_t valueLen = 0;
1287
    valueLen = strlen(stb) + 1;
1288
    size += sizeof(int32_t);
1289
    size += valueLen;
1290
    stb = taosHashIterate(pUser->alterViews, stb);
1291
  }
1292

1293
  int32_t *useDb = taosHashIterate(pUser->useDbs, NULL);
1294
  while (useDb != NULL) {
1295
    size_t keyLen = 0;
1296
    void  *key = taosHashGetKey(useDb, &keyLen);
1297
    size += sizeof(int32_t);
1298
    size += keyLen;
1299
    size += sizeof(int32_t);
1300
    useDb = taosHashIterate(pUser->useDbs, useDb);
1301
  }
1302
#endif
1303
  int32_t sizeExt = tSerializeUserObjExt(NULL, 0, pUser);
2,117,672✔
1304
  if (sizeExt < 0) {
2,117,672✔
UNCOV
1305
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1306
  }
1307
  size += sizeExt;
2,117,672✔
1308

1309
  pRaw = sdbAllocRaw(SDB_USER, USER_VER_NUMBER, size);
2,117,672✔
1310
  if (pRaw == NULL) {
2,117,672✔
UNCOV
1311
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1312
  }
1313

1314
  int32_t dataPos = 0;
2,117,672✔
1315
  SDB_SET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN, _OVER)
2,117,672✔
1316

1317
  dropOldPasswords(pUser);
2,117,672✔
1318
  SDB_SET_INT32(pRaw, dataPos, pUser->numOfPasswords, _OVER)
2,117,672✔
1319
  for (int32_t i = 0; i < pUser->numOfPasswords; i++) {
4,246,905✔
1320
    SDB_SET_BINARY(pRaw, dataPos, pUser->passwords[i].pass, sizeof(pUser->passwords[i].pass), _OVER)
2,129,233✔
1321
    SDB_SET_INT32(pRaw, dataPos, pUser->passwords[i].setTime, _OVER)
2,129,233✔
1322
  }
1323
  SDB_SET_BINARY(pRaw, dataPos, pUser->salt, sizeof(pUser->salt), _OVER)
2,117,672✔
1324

1325
  SDB_SET_BINARY(pRaw, dataPos, pUser->acct, TSDB_USER_LEN, _OVER)
2,117,672✔
1326
  SDB_SET_INT64(pRaw, dataPos, pUser->createdTime, _OVER)
2,117,672✔
1327
  SDB_SET_INT64(pRaw, dataPos, pUser->updateTime, _OVER)
2,117,672✔
1328
  SDB_SET_INT8(pRaw, dataPos, pUser->superUser, _OVER)
2,117,672✔
1329
  SDB_SET_INT8(pRaw, dataPos, pUser->sysInfo, _OVER)
2,117,672✔
1330
  SDB_SET_INT8(pRaw, dataPos, pUser->enable, _OVER)
2,117,672✔
1331
  SDB_SET_UINT8(pRaw, dataPos, pUser->flag, _OVER)
2,117,672✔
1332
  SDB_SET_INT32(pRaw, dataPos, pUser->authVersion, _OVER)
2,117,672✔
1333
  SDB_SET_INT32(pRaw, dataPos, pUser->passVersion, _OVER)
2,117,672✔
1334
  SDB_SET_INT32(pRaw, dataPos, numOfReadDbs, _OVER)
2,117,672✔
1335
  SDB_SET_INT32(pRaw, dataPos, numOfWriteDbs, _OVER)
2,117,672✔
1336
  SDB_SET_INT32(pRaw, dataPos, numOfTopics, _OVER)
2,117,672✔
1337
#if 0
1338
  char *db = taosHashIterate(pUser->readDbs, NULL);
1339
  while (db != NULL) {
1340
    SDB_SET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER);
1341
    db = taosHashIterate(pUser->readDbs, db);
1342
  }
1343

1344
  db = taosHashIterate(pUser->writeDbs, NULL);
1345
  while (db != NULL) {
1346
    SDB_SET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER);
1347
    db = taosHashIterate(pUser->writeDbs, db);
1348
  }
1349
  char *topic = taosHashIterate(pUser->topics, NULL);
1350
  while (topic != NULL) {
1351
    SDB_SET_BINARY(pRaw, dataPos, topic, TSDB_TOPIC_FNAME_LEN, _OVER);
1352
    topic = taosHashIterate(pUser->topics, topic);
1353
  }
1354
#endif
1355
  SDB_SET_INT32(pRaw, dataPos, numOfReadTbs, _OVER)
2,117,672✔
1356
  SDB_SET_INT32(pRaw, dataPos, numOfWriteTbs, _OVER)
2,117,672✔
1357
  SDB_SET_INT32(pRaw, dataPos, numOfAlterTbs, _OVER)
2,117,672✔
1358
  SDB_SET_INT32(pRaw, dataPos, numOfReadViews, _OVER)
2,117,672✔
1359
  SDB_SET_INT32(pRaw, dataPos, numOfWriteViews, _OVER)
2,117,672✔
1360
  SDB_SET_INT32(pRaw, dataPos, numOfAlterViews, _OVER)
2,117,672✔
1361
  SDB_SET_INT32(pRaw, dataPos, numOfUseDbs, _OVER)
2,117,672✔
1362

1363
#if 0
1364
  stb = taosHashIterate(pUser->readTbs, NULL);
1365
  while (stb != NULL) {
1366
    size_t keyLen = 0;
1367
    void  *key = taosHashGetKey(stb, &keyLen);
1368
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1369
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1370

1371
    size_t valueLen = 0;
1372
    valueLen = strlen(stb) + 1;
1373
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
1374
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
1375
    stb = taosHashIterate(pUser->readTbs, stb);
1376
  }
1377

1378
  stb = taosHashIterate(pUser->writeTbs, NULL);
1379
  while (stb != NULL) {
1380
    size_t keyLen = 0;
1381
    void  *key = taosHashGetKey(stb, &keyLen);
1382
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1383
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1384

1385
    size_t valueLen = 0;
1386
    valueLen = strlen(stb) + 1;
1387
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
1388
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
1389
    stb = taosHashIterate(pUser->writeTbs, stb);
1390
  }
1391
  stb = taosHashIterate(pUser->alterTbs, NULL);
1392
  while (stb != NULL) {
1393
    size_t keyLen = 0;
1394
    void  *key = taosHashGetKey(stb, &keyLen);
1395
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1396
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1397

1398
    size_t valueLen = 0;
1399
    valueLen = strlen(stb) + 1;
1400
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
1401
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
1402
    stb = taosHashIterate(pUser->alterTbs, stb);
1403
  }
1404

1405
  stb = taosHashIterate(pUser->readViews, NULL);
1406
  while (stb != NULL) {
1407
    size_t keyLen = 0;
1408
    void  *key = taosHashGetKey(stb, &keyLen);
1409
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1410
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1411

1412
    size_t valueLen = 0;
1413
    valueLen = strlen(stb) + 1;
1414
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
1415
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
1416
    stb = taosHashIterate(pUser->readViews, stb);
1417
  }
1418

1419
  stb = taosHashIterate(pUser->writeViews, NULL);
1420
  while (stb != NULL) {
1421
    size_t keyLen = 0;
1422
    void  *key = taosHashGetKey(stb, &keyLen);
1423
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1424
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1425

1426
    size_t valueLen = 0;
1427
    valueLen = strlen(stb) + 1;
1428
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
1429
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
1430
    stb = taosHashIterate(pUser->writeViews, stb);
1431
  }
1432

1433
  stb = taosHashIterate(pUser->alterViews, NULL);
1434
  while (stb != NULL) {
1435
    size_t keyLen = 0;
1436
    void  *key = taosHashGetKey(stb, &keyLen);
1437
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1438
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1439

1440
    size_t valueLen = 0;
1441
    valueLen = strlen(stb) + 1;
1442
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
1443
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
1444
    stb = taosHashIterate(pUser->alterViews, stb);
1445
  }
1446

1447
  useDb = taosHashIterate(pUser->useDbs, NULL);
1448
  while (useDb != NULL) {
1449
    size_t keyLen = 0;
1450
    void  *key = taosHashGetKey(useDb, &keyLen);
1451
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1452
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1453

1454
    SDB_SET_INT32(pRaw, dataPos, *useDb, _OVER)
1455
    useDb = taosHashIterate(pUser->useDbs, useDb);
1456
  }
1457
#endif
1458
  // save white list
1459
  int32_t num = pUser->pIpWhiteListDual->num;
2,117,672✔
1460
  int32_t tlen = sizeof(SIpWhiteListDual) + num * sizeof(SIpRange) + 4;
2,117,672✔
1461
  int32_t maxBufLen = TMAX(tlen, sizeExt);
2,117,672✔
1462
  if ((buf = taosMemoryCalloc(1, maxBufLen)) == NULL) {
2,117,672✔
UNCOV
1463
    TAOS_CHECK_GOTO(terrno, NULL, _OVER);
×
1464
  }
1465
  int32_t len = 0;
2,117,672✔
1466
  TAOS_CHECK_GOTO(tSerializeIpWhiteList(buf, tlen, pUser->pIpWhiteListDual, &len), &lino, _OVER);
2,117,672✔
1467

1468
  SDB_SET_INT32(pRaw, dataPos, len, _OVER);
2,117,672✔
1469
  SDB_SET_BINARY(pRaw, dataPos, buf, len, _OVER);
2,117,672✔
1470

1471
  SDB_SET_INT64(pRaw, dataPos, pUser->ipWhiteListVer, _OVER);
2,117,672✔
1472
  SDB_SET_INT8(pRaw, dataPos, pUser->passEncryptAlgorithm, _OVER);
2,117,672✔
1473

1474
  SDB_SET_BINARY(pRaw, dataPos, pUser->totpsecret, sizeof(pUser->totpsecret), _OVER);
2,117,672✔
1475
  SDB_SET_INT8(pRaw, dataPos, pUser->changePass, _OVER);
2,117,672✔
1476
  SDB_SET_INT32(pRaw, dataPos, pUser->sessionPerUser, _OVER);
2,117,672✔
1477
  SDB_SET_INT32(pRaw, dataPos, pUser->connectTime, _OVER);
2,117,672✔
1478
  SDB_SET_INT32(pRaw, dataPos, pUser->connectIdleTime, _OVER);
2,117,672✔
1479
  SDB_SET_INT32(pRaw, dataPos, pUser->callPerSession, _OVER);
2,117,672✔
1480
  SDB_SET_INT32(pRaw, dataPos, pUser->vnodePerCall, _OVER);
2,117,672✔
1481
  SDB_SET_INT32(pRaw, dataPos, pUser->failedLoginAttempts, _OVER);
2,117,672✔
1482
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordLifeTime, _OVER);
2,117,672✔
1483
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordReuseTime, _OVER);
2,117,672✔
1484
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordReuseMax, _OVER);
2,117,672✔
1485
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordLockTime, _OVER);
2,117,672✔
1486
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordGraceTime, _OVER);
2,117,672✔
1487
  SDB_SET_INT32(pRaw, dataPos, pUser->inactiveAccountTime, _OVER);
2,117,672✔
1488
  SDB_SET_INT32(pRaw, dataPos, pUser->allowTokenNum, _OVER);
2,117,672✔
1489
  SDB_SET_INT32(pRaw, dataPos, pUser->tokenNum, _OVER);
2,117,672✔
1490

1491
  SDB_SET_INT32(pRaw, dataPos, pUser->pTimeWhiteList->num, _OVER);
2,117,672✔
1492
  for (int32_t i = 0; i < pUser->pTimeWhiteList->num; i++) {
2,117,672✔
UNCOV
1493
    SDateTimeWhiteListItem *range = &pUser->pTimeWhiteList->ranges[i];
×
UNCOV
1494
    SDB_SET_BOOL(pRaw, dataPos, range->absolute, _OVER);
×
UNCOV
1495
    SDB_SET_BOOL(pRaw, dataPos, range->neg, _OVER);
×
UNCOV
1496
    SDB_SET_INT64(pRaw, dataPos, range->start, _OVER);
×
1497
    SDB_SET_INT32(pRaw, dataPos, range->duration, _OVER);
×
1498
  }
1499

1500
  sizeExt = tSerializeUserObjExt(buf, sizeExt, pUser);
2,117,672✔
1501
  if (sizeExt < 0) {
2,117,672✔
UNCOV
1502
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1503
  }
1504
  SDB_SET_INT32(pRaw, dataPos, sizeExt, _OVER);
2,117,672✔
1505
  SDB_SET_BINARY(pRaw, dataPos, buf, sizeExt, _OVER);
2,117,672✔
1506

1507
  SDB_SET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
2,117,672✔
1508

1509
  SDB_SET_DATALEN(pRaw, dataPos, _OVER)
2,117,672✔
1510

1511
_OVER:
2,117,672✔
1512
  taosMemoryFree(buf);
2,117,672✔
1513
  if (code < 0) {
2,117,672✔
UNCOV
1514
    mError("user:%s, failed to encode user action to raw:%p at line %d since %s", pUser->user, pRaw, lino,
×
1515
           tstrerror(code));
UNCOV
1516
    sdbFreeRaw(pRaw);
×
UNCOV
1517
    pRaw = NULL;
×
UNCOV
1518
    terrno = code;
×
1519
  }
1520

1521
  mTrace("user:%s, encode user action to raw:%p, row:%p", pUser->user, pRaw, pUser);
2,117,672✔
1522
  return pRaw;
2,117,672✔
1523
}
1524

1525
static SSdbRow *mndUserActionDecode(SSdbRaw *pRaw) {
1,411,543✔
1526
  int32_t   code = 0;
1,411,543✔
1527
  int32_t   lino = 0;
1,411,543✔
1528
  SSdbRow  *pRow = NULL;
1,411,543✔
1529
  SUserObj *pUser = NULL;
1,411,543✔
1530
  char     *key = NULL;
1,411,543✔
1531
  char     *value = NULL;
1,411,543✔
1532

1533
  SHashObj *pReadDbs = NULL;
1,411,543✔
1534
  SHashObj *pWriteDbs = NULL;
1,411,543✔
1535
  SHashObj *pReadTbs = NULL;
1,411,543✔
1536
  SHashObj *pWriteTbs = NULL;
1,411,543✔
1537
  SHashObj *pTopics = NULL;
1,411,543✔
1538
  SHashObj *pAlterTbs = NULL;
1,411,543✔
1539
  SHashObj *pReadViews = NULL;
1,411,543✔
1540
  SHashObj *pWriteViews = NULL;
1,411,543✔
1541
  SHashObj *pAlterViews = NULL;
1,411,543✔
1542
  SHashObj *pUseDbs = NULL;
1,411,543✔
1543

1544
  int8_t sver = 0;
1,411,543✔
1545
  if (sdbGetRawSoftVer(pRaw, &sver) != 0) {
1,411,543✔
UNCOV
1546
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_PTR, &lino, _OVER);
×
1547
  }
1548

1549
  if (sver < 1 || sver > USER_VER_NUMBER) {
1,411,543✔
UNCOV
1550
    TAOS_CHECK_GOTO(TSDB_CODE_SDB_INVALID_DATA_VER, &lino, _OVER);
×
1551
  }
1552

1553
  pRow = sdbAllocRow(sizeof(SUserObj));
1,411,543✔
1554
  if (pRow == NULL) {
1,411,543✔
UNCOV
1555
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1556
  }
1557

1558
  pUser = sdbGetRowObj(pRow);
1,411,543✔
1559
  if (pUser == NULL) {
1,411,543✔
1560
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1561
  }
1562

1563
  int32_t dataPos = 0;
1,411,543✔
1564
  SDB_GET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN, _OVER)
1,411,543✔
1565

1566
  if (sver < USER_VER_SUPPORT_ADVANCED_SECURITY) {
1,411,543✔
UNCOV
1567
    pUser->passwords = taosMemoryCalloc(1, sizeof(SUserPassword));
×
UNCOV
1568
    if (pUser->passwords == NULL) {
×
UNCOV
1569
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
1570
    }
UNCOV
1571
    SDB_GET_BINARY(pRaw, dataPos, pUser->passwords[0].pass, TSDB_PASSWORD_LEN, _OVER)
×
UNCOV
1572
    pUser->numOfPasswords = 1;
×
UNCOV
1573
    memset(pUser->salt, 0, sizeof(pUser->salt));
×
1574
  } else {
1575
    SDB_GET_INT32(pRaw, dataPos, &pUser->numOfPasswords, _OVER)
1,411,543✔
1576
    pUser->passwords = taosMemoryCalloc(pUser->numOfPasswords, sizeof(SUserPassword));
1,411,543✔
1577
    if (pUser->passwords == NULL) {
1,411,543✔
UNCOV
1578
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
1579
    }
1580
    for (int32_t i = 0; i < pUser->numOfPasswords; ++i) {
2,840,125✔
1581
      SDB_GET_BINARY(pRaw, dataPos, pUser->passwords[i].pass, sizeof(pUser->passwords[i].pass), _OVER);
1,428,582✔
1582
      SDB_GET_INT32(pRaw, dataPos, &pUser->passwords[i].setTime, _OVER);
1,428,582✔
1583
    }
1584
    SDB_GET_BINARY(pRaw, dataPos, pUser->salt, sizeof(pUser->salt), _OVER)
1,411,543✔
1585
  }
1586
  
1587
  SDB_GET_BINARY(pRaw, dataPos, pUser->acct, TSDB_USER_LEN, _OVER)
1,411,543✔
1588
  SDB_GET_INT64(pRaw, dataPos, &pUser->createdTime, _OVER)
1,411,543✔
1589
  SDB_GET_INT64(pRaw, dataPos, &pUser->updateTime, _OVER)
1,411,543✔
1590
  if (sver < USER_VER_SUPPORT_ADVANCED_SECURITY) {
1,411,543✔
UNCOV
1591
    pUser->passwords[0].setTime = (int32_t)(pUser->updateTime / 1000);
×
1592
  }
1593

1594
  SDB_GET_INT8(pRaw, dataPos, &pUser->superUser, _OVER)
1,411,543✔
1595
  SDB_GET_INT8(pRaw, dataPos, &pUser->sysInfo, _OVER)
1,411,543✔
1596
  SDB_GET_INT8(pRaw, dataPos, &pUser->enable, _OVER)
1,411,543✔
1597
  SDB_GET_UINT8(pRaw, dataPos, &pUser->flag, _OVER)
1,411,543✔
1598
  if (pUser->superUser) pUser->createdb = 1;
1,411,543✔
1599
  SDB_GET_INT32(pRaw, dataPos, &pUser->authVersion, _OVER)
1,411,543✔
1600
  if (sver >= 4) {
1,411,543✔
1601
    SDB_GET_INT32(pRaw, dataPos, &pUser->passVersion, _OVER)
1,411,543✔
1602
  }
1603

1604
  int32_t numOfReadDbs = 0;
1,411,543✔
1605
  int32_t numOfWriteDbs = 0;
1,411,543✔
1606
  int32_t numOfTopics = 0;
1,411,543✔
1607
  SDB_GET_INT32(pRaw, dataPos, &numOfReadDbs, _OVER)
1,411,543✔
1608
  SDB_GET_INT32(pRaw, dataPos, &numOfWriteDbs, _OVER)
1,411,543✔
1609
  if (sver >= 2) {
1,411,543✔
1610
    SDB_GET_INT32(pRaw, dataPos, &numOfTopics, _OVER)
1,411,543✔
1611
  }
1612

1613
  if (numOfReadDbs > 0) {
1,411,543✔
UNCOV
1614
    pReadDbs = taosHashInit(numOfReadDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
UNCOV
1615
    if (pReadDbs == NULL) {
×
UNCOV
1616
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1617
    }
1618
  }
1619
  if (numOfWriteDbs > 0) {
1,411,543✔
UNCOV
1620
    pWriteDbs = taosHashInit(numOfWriteDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
UNCOV
1621
    if (pWriteDbs == NULL) {
×
UNCOV
1622
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1623
    }
1624
  }
1625
  if (numOfTopics > 0) {
1,411,543✔
1626
    pTopics = taosHashInit(numOfTopics, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
UNCOV
1627
    if (pTopics == NULL) {
×
UNCOV
1628
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1629
    }
1630
  }
1631
  for (int32_t i = 0; i < numOfReadDbs; ++i) {
1,411,543✔
UNCOV
1632
    char db[TSDB_DB_FNAME_LEN] = {0};
×
UNCOV
1633
    SDB_GET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER)
×
UNCOV
1634
    int32_t len = strlen(db) + 1;
×
UNCOV
1635
    TAOS_CHECK_GOTO(taosHashPut(pReadDbs, db, len, db, TSDB_DB_FNAME_LEN), &lino, _OVER);
×
1636
  }
1637

1638
  for (int32_t i = 0; i < numOfWriteDbs; ++i) {
1,411,543✔
UNCOV
1639
    char db[TSDB_DB_FNAME_LEN] = {0};
×
1640
    SDB_GET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER)
×
UNCOV
1641
    int32_t len = strlen(db) + 1;
×
UNCOV
1642
    TAOS_CHECK_GOTO(taosHashPut(pWriteDbs, db, len, db, TSDB_DB_FNAME_LEN), &lino, _OVER);
×
1643
  }
1644

1645
  if (sver >= 2) {
1,411,543✔
1646
    for (int32_t i = 0; i < numOfTopics; ++i) {
1,411,543✔
UNCOV
1647
      char topic[TSDB_TOPIC_FNAME_LEN] = {0};
×
UNCOV
1648
      SDB_GET_BINARY(pRaw, dataPos, topic, TSDB_TOPIC_FNAME_LEN, _OVER)
×
1649
      int32_t len = strlen(topic) + 1;
×
UNCOV
1650
      TAOS_CHECK_GOTO(taosHashPut(pTopics, topic, len, topic, TSDB_TOPIC_FNAME_LEN), &lino, _OVER);
×
1651
    }
1652
  }
1653

1654
  if (sver >= 3) {
1,411,543✔
1655
    int32_t numOfReadTbs = 0;
1,411,543✔
1656
    int32_t numOfWriteTbs = 0;
1,411,543✔
1657
    int32_t numOfAlterTbs = 0;
1,411,543✔
1658
    int32_t numOfReadViews = 0;
1,411,543✔
1659
    int32_t numOfWriteViews = 0;
1,411,543✔
1660
    int32_t numOfAlterViews = 0;
1,411,543✔
1661
    int32_t numOfUseDbs = 0;
1,411,543✔
1662
    SDB_GET_INT32(pRaw, dataPos, &numOfReadTbs, _OVER)
1,411,543✔
1663
    SDB_GET_INT32(pRaw, dataPos, &numOfWriteTbs, _OVER)
1,411,543✔
1664
    if (sver >= 6) {
1,411,543✔
1665
      SDB_GET_INT32(pRaw, dataPos, &numOfAlterTbs, _OVER)
1,411,543✔
1666
      SDB_GET_INT32(pRaw, dataPos, &numOfReadViews, _OVER)
1,411,543✔
1667
      SDB_GET_INT32(pRaw, dataPos, &numOfWriteViews, _OVER)
1,411,543✔
1668
      SDB_GET_INT32(pRaw, dataPos, &numOfAlterViews, _OVER)
1,411,543✔
1669
    }
1670
    SDB_GET_INT32(pRaw, dataPos, &numOfUseDbs, _OVER)
1,411,543✔
1671

1672
    if (numOfReadTbs > 0) {
1,411,543✔
UNCOV
1673
      pReadTbs = taosHashInit(numOfReadTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
UNCOV
1674
      if (pReadTbs == NULL) {
×
UNCOV
1675
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1676
      }
1677
    }
1678
    if (numOfWriteTbs > 0) {
1,411,543✔
UNCOV
1679
      pWriteTbs = taosHashInit(numOfWriteTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
UNCOV
1680
      if (pWriteTbs == NULL) {
×
UNCOV
1681
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1682
      }
1683
    }
1684
    pAlterTbs = taosHashInit(numOfAlterTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,411,543✔
1685
    pReadViews = taosHashInit(numOfReadViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,411,543✔
1686
    pWriteViews =
1687
        taosHashInit(numOfWriteViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,411,543✔
1688
    pAlterViews =
1689
        taosHashInit(numOfAlterViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,411,543✔
1690
    pUseDbs = taosHashInit(numOfUseDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,411,543✔
1691

1692
    if (pAlterTbs == NULL || pReadViews == NULL || pWriteViews == NULL || pAlterViews == NULL || pUseDbs == NULL) {
1,411,543✔
UNCOV
1693
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
UNCOV
1694
      goto _OVER;
×
1695
    }
1696

1697
    for (int32_t i = 0; i < numOfReadTbs; ++i) {
1,411,543✔
UNCOV
1698
      int32_t keyLen = 0;
×
UNCOV
1699
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
1700

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

UNCOV
1708
      int32_t valuelen = 0;
×
UNCOV
1709
      SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
1710
      TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
UNCOV
1711
      if (value == NULL) {
×
UNCOV
1712
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1713
      }
UNCOV
1714
      (void)memset(value, 0, valuelen);
×
UNCOV
1715
      SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
1716

UNCOV
1717
      TAOS_CHECK_GOTO(taosHashPut(pReadTbs, key, keyLen, value, valuelen), &lino, _OVER);
×
1718
    }
1719

1720
    for (int32_t i = 0; i < numOfWriteTbs; ++i) {
1,411,543✔
UNCOV
1721
      int32_t keyLen = 0;
×
UNCOV
1722
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
1723

1724
      TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
1725
      if (key == NULL) {
×
UNCOV
1726
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1727
      }
1728
      (void)memset(key, 0, keyLen);
×
1729
      SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
1730

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

1740
      TAOS_CHECK_GOTO(taosHashPut(pWriteTbs, key, keyLen, value, valuelen), &lino, _OVER);
×
1741
    }
1742

1743
    if (sver >= 6) {
1,411,543✔
1744
      for (int32_t i = 0; i < numOfAlterTbs; ++i) {
1,411,543✔
UNCOV
1745
        int32_t keyLen = 0;
×
UNCOV
1746
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
1747

UNCOV
1748
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
UNCOV
1749
        if (key == NULL) {
×
UNCOV
1750
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1751
        }
1752
        (void)memset(key, 0, keyLen);
×
UNCOV
1753
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
1754

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

UNCOV
1764
        TAOS_CHECK_GOTO(taosHashPut(pAlterTbs, key, keyLen, value, valuelen), &lino, _OVER);
×
1765
      }
1766

1767
      for (int32_t i = 0; i < numOfReadViews; ++i) {
1,411,543✔
UNCOV
1768
        int32_t keyLen = 0;
×
1769
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
1770

1771
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
1772
        if (key == NULL) {
×
1773
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1774
        }
1775
        (void)memset(key, 0, keyLen);
×
1776
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
1777

1778
        int32_t valuelen = 0;
×
1779
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
1780
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
1781
        if (value == NULL) {
×
1782
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1783
        }
1784
        (void)memset(value, 0, valuelen);
×
1785
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
1786

UNCOV
1787
        TAOS_CHECK_GOTO(taosHashPut(pReadViews, key, keyLen, value, valuelen), &lino, _OVER);
×
1788
      }
1789

1790
      for (int32_t i = 0; i < numOfWriteViews; ++i) {
1,411,543✔
UNCOV
1791
        int32_t keyLen = 0;
×
UNCOV
1792
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
1793

UNCOV
1794
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
UNCOV
1795
        if (key == NULL) {
×
UNCOV
1796
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1797
        }
UNCOV
1798
        (void)memset(key, 0, keyLen);
×
UNCOV
1799
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
1800

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

UNCOV
1810
        TAOS_CHECK_GOTO(taosHashPut(pWriteViews, key, keyLen, value, valuelen), &lino, _OVER);
×
1811
      }
1812

1813
      for (int32_t i = 0; i < numOfAlterViews; ++i) {
1,411,543✔
1814
        int32_t keyLen = 0;
×
1815
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
1816

1817
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
1818
        if (key == NULL) {
×
UNCOV
1819
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1820
        }
UNCOV
1821
        (void)memset(key, 0, keyLen);
×
UNCOV
1822
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
1823

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

1833
        TAOS_CHECK_GOTO(taosHashPut(pAlterViews, key, keyLen, value, valuelen), &lino, _OVER);
×
1834
      }
1835
    }
1836

1837
    for (int32_t i = 0; i < numOfUseDbs; ++i) {
1,411,543✔
1838
      int32_t keyLen = 0;
×
1839
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
1840

1841
      TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
×
1842
      if (key == NULL) {
×
1843
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1844
      }
1845
      (void)memset(key, 0, keyLen);
×
UNCOV
1846
      SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
×
1847

1848
      int32_t ref = 0;
×
UNCOV
1849
      SDB_GET_INT32(pRaw, dataPos, &ref, _OVER);
×
1850

UNCOV
1851
      TAOS_CHECK_GOTO(taosHashPut(pUseDbs, key, keyLen, &ref, sizeof(ref)), &lino, _OVER);
×
1852
    }
1853
  }
1854
  // decoder white list
1855
  if (sver >= USER_VER_SUPPORT_WHITELIST) {
1,411,543✔
1856
    if (sver < USER_VER_SUPPORT_WHITELIT_DUAL_STACK) {
1,411,543✔
UNCOV
1857
      int32_t len = 0;
×
UNCOV
1858
      SDB_GET_INT32(pRaw, dataPos, &len, _OVER);
×
1859

1860
      TAOS_MEMORY_REALLOC(key, len);
×
1861
      if (key == NULL) {
×
1862
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1863
      }
UNCOV
1864
      SDB_GET_BINARY(pRaw, dataPos, key, len, _OVER);
×
1865

UNCOV
1866
      SIpWhiteList *pIpWhiteList = NULL;
×
UNCOV
1867
      TAOS_CHECK_GOTO(createIpWhiteListFromOldVer(key, len, &pIpWhiteList), &lino, _OVER);
×
1868

UNCOV
1869
      SDB_GET_INT64(pRaw, dataPos, &pUser->ipWhiteListVer, _OVER);
×
1870

UNCOV
1871
      code = cvtIpWhiteListToDual(pIpWhiteList, &pUser->pIpWhiteListDual);
×
UNCOV
1872
      if (code != 0) {
×
UNCOV
1873
        taosMemoryFreeClear(pIpWhiteList);
×
1874
      }
1875
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
1876

UNCOV
1877
      taosMemoryFreeClear(pIpWhiteList);
×
1878

1879
    } else if (sver >= USER_VER_SUPPORT_WHITELIT_DUAL_STACK) {
1,411,543✔
1880
      int32_t len = 0;
1,411,543✔
1881
      SDB_GET_INT32(pRaw, dataPos, &len, _OVER);
1,411,543✔
1882

1883
      TAOS_MEMORY_REALLOC(key, len);
1,411,543✔
1884
      if (key == NULL) {
1,411,543✔
1885
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1886
      }
1887
      SDB_GET_BINARY(pRaw, dataPos, key, len, _OVER);
1,411,543✔
1888

1889
      TAOS_CHECK_GOTO(createIpWhiteList(key, len, &pUser->pIpWhiteListDual, sver >= USER_VER_SUPPORT_ADVANCED_SECURITY), &lino, _OVER);
1,411,543✔
1890
      SDB_GET_INT64(pRaw, dataPos, &pUser->ipWhiteListVer, _OVER);
1,411,543✔
1891
    }
1892
  }
1893

1894
  if (pUser->pIpWhiteListDual == NULL) {
1,411,543✔
UNCOV
1895
    TAOS_CHECK_GOTO(createDefaultIpWhiteList(&pUser->pIpWhiteListDual), &lino, _OVER);
×
UNCOV
1896
    pUser->ipWhiteListVer = taosGetTimestampMs();
×
1897
  }
1898

1899
  SDB_GET_INT8(pRaw, dataPos, &pUser->passEncryptAlgorithm, _OVER);
1,411,543✔
1900

1901
  if (sver < USER_VER_SUPPORT_ADVANCED_SECURITY) {
1,411,543✔
UNCOV
1902
    memset(pUser->totpsecret, 0, sizeof(pUser->totpsecret));
×
UNCOV
1903
    pUser->changePass = 2;
×
UNCOV
1904
    pUser->sessionPerUser = pUser->superUser ? -1 : TSDB_USER_SESSION_PER_USER_DEFAULT;
×
UNCOV
1905
    pUser->connectTime = TSDB_USER_CONNECT_TIME_DEFAULT;
×
UNCOV
1906
    pUser->connectIdleTime = TSDB_USER_CONNECT_IDLE_TIME_DEFAULT;
×
UNCOV
1907
    pUser->callPerSession = TSDB_USER_CALL_PER_SESSION_DEFAULT;
×
UNCOV
1908
    pUser->vnodePerCall = TSDB_USER_VNODE_PER_CALL_DEFAULT;
×
1909
    pUser->failedLoginAttempts = TSDB_USER_FAILED_LOGIN_ATTEMPTS_DEFAULT;
×
1910
    pUser->passwordLifeTime = TSDB_USER_PASSWORD_LIFE_TIME_DEFAULT;
×
1911
    pUser->passwordReuseTime = TSDB_USER_PASSWORD_REUSE_TIME_DEFAULT;
×
UNCOV
1912
    pUser->passwordLockTime = TSDB_USER_PASSWORD_LOCK_TIME_DEFAULT;
×
UNCOV
1913
    pUser->passwordGraceTime = pUser->superUser ? -1 : TSDB_USER_PASSWORD_GRACE_TIME_DEFAULT;
×
UNCOV
1914
    pUser->inactiveAccountTime = pUser->superUser ? -1 : TSDB_USER_INACTIVE_ACCOUNT_TIME_DEFAULT;
×
UNCOV
1915
    pUser->allowTokenNum = TSDB_USER_ALLOW_TOKEN_NUM_DEFAULT;
×
UNCOV
1916
    pUser->tokenNum = 0;
×
UNCOV
1917
    pUser->pTimeWhiteList = taosMemCalloc(1, sizeof(SDateTimeWhiteList));
×
UNCOV
1918
    if (pUser->pTimeWhiteList == NULL) {
×
1919
    }
1920
  } else {
1921
    SDB_GET_BINARY(pRaw, dataPos, pUser->totpsecret, sizeof(pUser->totpsecret), _OVER);
1,411,543✔
1922
    SDB_GET_INT8(pRaw, dataPos, &pUser->changePass, _OVER);
1,411,543✔
1923
    SDB_GET_INT32(pRaw, dataPos, &pUser->sessionPerUser, _OVER);
1,411,543✔
1924
    SDB_GET_INT32(pRaw, dataPos, &pUser->connectTime, _OVER);
1,411,543✔
1925
    SDB_GET_INT32(pRaw, dataPos, &pUser->connectIdleTime, _OVER);
1,411,543✔
1926
    SDB_GET_INT32(pRaw, dataPos, &pUser->callPerSession, _OVER);
1,411,543✔
1927
    SDB_GET_INT32(pRaw, dataPos, &pUser->vnodePerCall, _OVER);
1,411,543✔
1928
    SDB_GET_INT32(pRaw, dataPos, &pUser->failedLoginAttempts, _OVER);
1,411,543✔
1929
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordLifeTime, _OVER);
1,411,543✔
1930
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordReuseTime, _OVER);
1,411,543✔
1931
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordReuseMax, _OVER);
1,411,543✔
1932
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordLockTime, _OVER);
1,411,543✔
1933
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordGraceTime, _OVER);
1,411,543✔
1934
    SDB_GET_INT32(pRaw, dataPos, &pUser->inactiveAccountTime, _OVER);
1,411,543✔
1935
    SDB_GET_INT32(pRaw, dataPos, &pUser->allowTokenNum, _OVER);
1,411,543✔
1936
    SDB_GET_INT32(pRaw, dataPos, &pUser->tokenNum, _OVER);
1,411,543✔
1937

1938
    int32_t num = 0;
1,411,543✔
1939
    SDB_GET_INT32(pRaw, dataPos, &num, _OVER);
1,411,543✔
1940
    pUser->pTimeWhiteList = taosMemCalloc(1, sizeof(SDateTimeWhiteList) + num * sizeof(SDateTimeWhiteListItem));
1,411,543✔
1941
    if (pUser->pTimeWhiteList == NULL) {
1,411,543✔
UNCOV
1942
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1943
    }
1944

1945
    pUser->pTimeWhiteList->num = num;
1,411,543✔
1946
    for (int32_t i = 0; i < num; i++) {
1,411,543✔
UNCOV
1947
      SDateTimeWhiteListItem *range = &pUser->pTimeWhiteList->ranges[i];
×
UNCOV
1948
      SDB_GET_BOOL(pRaw, dataPos, &range->absolute, _OVER);
×
UNCOV
1949
      SDB_GET_BOOL(pRaw, dataPos, &range->neg, _OVER);
×
UNCOV
1950
      SDB_GET_INT64(pRaw, dataPos, &range->start, _OVER);
×
UNCOV
1951
      SDB_GET_INT32(pRaw, dataPos, &range->duration, _OVER);
×
1952
    }
1953

1954
    int32_t extLen = 0;
1,411,543✔
1955
    SDB_GET_INT32(pRaw, dataPos, &extLen, _OVER);
1,411,543✔
1956
    TAOS_MEMORY_REALLOC(key, extLen);
1,411,543✔
1957
    if (key == NULL) {
1,411,543✔
UNCOV
1958
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1959
    }
1960
    SDB_GET_BINARY(pRaw, dataPos, key, extLen, _OVER);
1,411,543✔
1961
    TAOS_CHECK_GOTO(tDeserializeUserObjExt(key, extLen, pUser), &lino, _OVER);
1,411,543✔
1962
  }
1963

1964
  SDB_GET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
1,411,543✔
1965

1966
  taosInitRWLatch(&pUser->lock);
1,411,543✔
1967
  dropOldPasswords(pUser);
1,411,543✔
1968
  // TODO: migrate legacy privileges to new hash tables
1969
_OVER:
1,411,543✔
1970
  taosMemoryFree(key);
1,411,543✔
1971
  taosMemoryFree(value);
1,411,543✔
1972
  taosHashCleanup(pReadDbs);
1,411,543✔
1973
  taosHashCleanup(pWriteDbs);
1,411,543✔
1974
  taosHashCleanup(pTopics);
1,411,543✔
1975
  taosHashCleanup(pReadTbs);
1,411,543✔
1976
  taosHashCleanup(pWriteTbs);
1,411,543✔
1977
  taosHashCleanup(pAlterTbs);
1,411,543✔
1978
  taosHashCleanup(pReadViews);
1,411,543✔
1979
  taosHashCleanup(pWriteViews);
1,411,543✔
1980
  taosHashCleanup(pAlterViews);
1,411,543✔
1981
  taosHashCleanup(pUseDbs);
1,411,543✔
1982
  if (code < 0) {
1,411,543✔
UNCOV
1983
    terrno = code;
×
UNCOV
1984
    mError("user:%s, failed to decode at line %d from raw:%p since %s", pUser == NULL ? "null" : pUser->user, lino,
×
1985
           pRaw, tstrerror(code));
UNCOV
1986
    if (pUser != NULL) {
×
UNCOV
1987
      mndUserFreeObj(pUser);
×
1988
    }
UNCOV
1989
    taosMemoryFreeClear(pRow);
×
UNCOV
1990
    return NULL;
×
1991
  }
1992

1993
  mTrace("user:%s, decode from raw:%p, row:%p", pUser->user, pRaw, pUser);
1,411,543✔
1994
  return pRow;
1,411,543✔
1995
}
1996

1997
static int32_t mndUserActionInsert(SSdb *pSdb, SUserObj *pUser) {
434,790✔
1998
  mTrace("user:%s, perform insert action, row:%p", pUser->user, pUser);
434,790✔
1999

2000
  SAcctObj *pAcct = sdbAcquire(pSdb, SDB_ACCT, pUser->acct);
434,790✔
2001
  if (pAcct == NULL) {
434,790✔
UNCOV
2002
    terrno = TSDB_CODE_MND_ACCT_NOT_EXIST;
×
UNCOV
2003
    mError("user:%s, failed to perform insert action since %s", pUser->user, terrstr());
×
UNCOV
2004
    TAOS_RETURN(terrno);
×
2005
  }
2006
  pUser->acctId = pAcct->acctId;
434,790✔
2007
  sdbRelease(pSdb, pAcct);
434,790✔
2008

2009
  return 0;
434,790✔
2010
}
2011

UNCOV
2012
int32_t mndDupTableHash(SHashObj *pOld, SHashObj **ppNew) {
×
UNCOV
2013
  int32_t code = 0;
×
UNCOV
2014
  *ppNew =
×
UNCOV
2015
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
UNCOV
2016
  if (*ppNew == NULL) {
×
UNCOV
2017
    TAOS_RETURN(terrno);
×
2018
  }
2019

UNCOV
2020
  char *tb = taosHashIterate(pOld, NULL);
×
UNCOV
2021
  while (tb != NULL) {
×
UNCOV
2022
    size_t keyLen = 0;
×
UNCOV
2023
    char  *key = taosHashGetKey(tb, &keyLen);
×
2024

UNCOV
2025
    int32_t valueLen = strlen(tb) + 1;
×
UNCOV
2026
    if ((code = taosHashPut(*ppNew, key, keyLen, tb, valueLen)) != 0) {
×
UNCOV
2027
      taosHashCancelIterate(pOld, tb);
×
UNCOV
2028
      taosHashCleanup(*ppNew);
×
UNCOV
2029
      TAOS_RETURN(code);
×
2030
    }
UNCOV
2031
    tb = taosHashIterate(pOld, tb);
×
2032
  }
2033

UNCOV
2034
  TAOS_RETURN(code);
×
2035
}
2036

UNCOV
2037
int32_t mndDupUseDbHash(SHashObj *pOld, SHashObj **ppNew) {
×
UNCOV
2038
  int32_t code = 0;
×
UNCOV
2039
  *ppNew =
×
UNCOV
2040
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
UNCOV
2041
  if (*ppNew == NULL) {
×
UNCOV
2042
    TAOS_RETURN(terrno);
×
2043
  }
2044

UNCOV
2045
  int32_t *db = taosHashIterate(pOld, NULL);
×
UNCOV
2046
  while (db != NULL) {
×
UNCOV
2047
    size_t keyLen = 0;
×
UNCOV
2048
    char  *key = taosHashGetKey(db, &keyLen);
×
2049

UNCOV
2050
    if ((code = taosHashPut(*ppNew, key, keyLen, db, sizeof(*db))) != 0) {
×
UNCOV
2051
      taosHashCancelIterate(pOld, db);
×
UNCOV
2052
      taosHashCleanup(*ppNew);
×
UNCOV
2053
      TAOS_RETURN(code);
×
2054
    }
UNCOV
2055
    db = taosHashIterate(pOld, db);
×
2056
  }
2057

UNCOV
2058
  TAOS_RETURN(code);
×
2059
}
2060

2061
int32_t mndDupRoleHash(SHashObj *pOld, SHashObj **ppNew) {
952,272✔
2062
  if (!(*ppNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true,
952,272✔
2063
                              HASH_ENTRY_LOCK))) {
UNCOV
2064
    TAOS_RETURN(terrno);
×
2065
  }
2066

2067
  int32_t  code = 0;
952,272✔
2068
  uint8_t *flag = NULL;
952,272✔
2069
  while ((flag = taosHashIterate(pOld, flag))) {
1,905,047✔
2070
    size_t keyLen = 0;
952,775✔
2071
    char  *key = taosHashGetKey(flag, &keyLen);
952,775✔
2072

2073
    if ((code = taosHashPut(*ppNew, key, keyLen, flag, sizeof(*flag))) != 0) {
952,775✔
UNCOV
2074
      taosHashCancelIterate(pOld, flag);
×
UNCOV
2075
      taosHashCleanup(*ppNew);
×
UNCOV
2076
      TAOS_RETURN(code);
×
2077
    }
2078
  }
2079

2080
  TAOS_RETURN(code);
952,272✔
2081
}
2082

2083
int32_t mndMergePrivObjHash(SHashObj *pOld, SHashObj **ppNew) {
17,874,848✔
2084
  if (!(*ppNew)) return mndDupPrivObjHash(pOld, ppNew);
17,874,848✔
2085

2086
  int32_t           code = 0, lino = 0;
17,875,044✔
2087
  SHashObj         *pNew = *ppNew;
17,875,044✔
2088
  SPrivObjPolicies *policies = NULL;
17,874,946✔
2089
  while ((policies = taosHashIterate(pOld, policies))) {
166,769,945✔
2090
    size_t klen = 0;
148,897,653✔
2091
    char  *key = taosHashGetKey(policies, &klen);
148,897,653✔
2092
    size_t vlen = taosHashGetValueSize(policies);
148,897,653✔
2093

2094
    SPrivObjPolicies *pNewPolicies = taosHashGet(pNew, key, klen);
148,897,653✔
2095
    if (pNewPolicies) {
148,896,771✔
2096
      size_t newVlen = taosHashGetValueSize(pNewPolicies);
94,356,228✔
2097
      if (newVlen > 0 && vlen > 0) {
94,356,228✔
2098
        privAddSet(&pNewPolicies->policy, &policies->policy);
94,356,130✔
2099
      }
2100
      continue;
94,354,554✔
2101
    }
2102

2103
    if ((code = taosHashPut(pNew, key, klen, vlen ? policies : NULL, vlen)) != 0) {
54,540,543✔
2104
      taosHashCancelIterate(pOld, policies);
×
2105
      taosHashCleanup(pNew);
×
2106
      *ppNew = NULL;
×
UNCOV
2107
      TAOS_RETURN(code);
×
2108
    }
2109
  }
2110

2111
  TAOS_RETURN(code);
17,875,044✔
2112
}
2113

2114
/**
2115
 * 1. Prefer to use SPrivTblPolicies from user object(the updateUs of policy in user object is INT64_MAX)
2116
 * 2. If two or more roles have SPrivTblPolicies, the policy with latest update time take effect.
2117
 */
2118
int32_t mndMergePrivTblHash(SHashObj *pOld, SHashObj **ppNew, bool updateWithLatest) {
53,624,936✔
2119
  if (!(*ppNew)) return mndDupPrivTblHash(pOld, ppNew, false);
53,624,936✔
2120

2121
  int32_t           code = 0, lino = 0;
53,625,034✔
2122
  SHashObj         *pNew = *ppNew;
53,625,034✔
2123
  SPrivTblPolicies *policies = NULL;
53,625,034✔
2124
  while ((policies = taosHashIterate(pOld, policies))) {
53,625,034✔
UNCOV
2125
    size_t klen = 0;
×
UNCOV
2126
    char  *key = taosHashGetKey(policies, &klen);
×
UNCOV
2127
    size_t vlen = taosHashGetValueSize(policies);
×
2128

UNCOV
2129
    SPrivTblPolicies *pNewPolicies = taosHashGet(pNew, key, klen);
×
UNCOV
2130
    if (pNewPolicies) {
×
UNCOV
2131
      size_t newVlen = taosHashGetValueSize(pNewPolicies);
×
UNCOV
2132
      if (newVlen > 0 && vlen > 0) {
×
UNCOV
2133
        TAOS_CHECK_EXIT(privTblPoliciesMerge(pNewPolicies, policies, updateWithLatest));
×
2134
      }
UNCOV
2135
      continue;
×
2136
    }
2137

2138
    SPrivTblPolicies tmpPolicies = {0};
×
2139
    if (vlen > 0) {
×
UNCOV
2140
      if ((code = privTblPoliciesMerge(&tmpPolicies, policies, updateWithLatest))) {
×
2141
        privTblPoliciesFree(&tmpPolicies);
2142
        goto _exit;
×
2143
      }
2144
    }
UNCOV
2145
    if ((code = taosHashPut(pNew, key, klen, vlen ? &tmpPolicies : NULL, vlen)) != 0) {
×
2146
      privTblPoliciesFree(&tmpPolicies);
UNCOV
2147
      taosHashCancelIterate(pOld, policies);
×
UNCOV
2148
      taosHashCleanup(pNew);
×
UNCOV
2149
      *ppNew = NULL;
×
UNCOV
2150
      TAOS_RETURN(code);
×
2151
    }
2152
  }
2153

2154
_exit:
53,624,936✔
2155
  TAOS_RETURN(code);
53,624,936✔
2156
}
2157

2158
int32_t mndDupPrivObjHash(SHashObj *pOld, SHashObj **ppNew) {
7,032,114✔
2159
  if (!(*ppNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true,
7,032,114✔
2160
                             HASH_ENTRY_LOCK))) {
UNCOV
2161
    TAOS_RETURN(terrno);
×
2162
  }
2163
  int32_t           code = 0;
7,032,114✔
2164
  SPrivObjPolicies *policies = NULL;
7,032,114✔
2165
  while ((policies = taosHashIterate(pOld, policies))) {
9,670,398✔
2166
    size_t klen = 0;
2,638,284✔
2167
    char  *key = taosHashGetKey(policies, &klen);
2,638,284✔
2168
    size_t vlen = taosHashGetValueSize(policies);
2,638,284✔
2169

2170
    if ((code = taosHashPut(*ppNew, key, klen, vlen > 0 ? policies : NULL, vlen)) != 0) {
2,638,284✔
UNCOV
2171
      taosHashCancelIterate(pOld, policies);
×
UNCOV
2172
      taosHashCleanup(*ppNew);
×
UNCOV
2173
      TAOS_RETURN(code);
×
2174
    }
2175
  }
2176

2177
  TAOS_RETURN(code);
7,032,114✔
2178
}
2179

2180
int32_t mndDupPrivTblHash(SHashObj *pOld, SHashObj **ppNew, bool setUpdateTimeMax) {
22,047,818✔
2181
  if (!(*ppNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true,
22,047,818✔
2182
                              HASH_ENTRY_LOCK))) {
UNCOV
2183
    TAOS_RETURN(terrno);
×
2184
  }
2185
  taosHashSetFreeFp(*ppNew, privTblPoliciesFree);
22,048,014✔
2186

2187
  int32_t           code = 0, lino = 0;
22,048,014✔
2188
  SPrivTblPolicies *policies = NULL, *pTmpPolicies = NULL;
22,048,014✔
2189
  SPrivTblPolicies  tmpPolicies = {0};
22,048,014✔
2190
  while ((policies = taosHashIterate(pOld, policies))) {
22,108,410✔
2191
    size_t klen = 0;
60,396✔
2192
    char  *key = taosHashGetKey(policies, &klen);
60,396✔
2193
    size_t vlen = taosHashGetValueSize(policies);
60,396✔
2194
    memset(&tmpPolicies, 0, sizeof(tmpPolicies));
60,396✔
2195
    pTmpPolicies = &tmpPolicies;
60,396✔
2196
    if (vlen > 0) {
60,396✔
2197
      TAOS_CHECK_EXIT(privTblPoliciesAdd(&tmpPolicies, policies, true, setUpdateTimeMax));
60,396✔
2198
    }
2199
    TAOS_CHECK_EXIT(taosHashPut(*ppNew, key, klen, vlen > 0 ? &tmpPolicies : NULL, vlen));
60,396✔
2200
    pTmpPolicies = NULL;
60,396✔
2201
  }
2202

2203
_exit:
22,047,916✔
2204
  if (code != 0) {
22,047,916✔
UNCOV
2205
    if (!pTmpPolicies) {
×
2206
      privTblPoliciesFree(pTmpPolicies);
UNCOV
2207
      pTmpPolicies = NULL;
×
2208
    }
UNCOV
2209
    if (policies) taosHashCancelIterate(pOld, policies);
×
2210
    taosHashCleanup(*ppNew);
×
UNCOV
2211
    *ppNew = NULL;
×
2212
  }
2213
  TAOS_RETURN(code);
22,047,916✔
2214
}
2215

2216
int32_t mndUserDupObj(SUserObj *pUser, SUserObj *pNew) {
951,072✔
2217
  int32_t code = 0;
951,072✔
2218
  (void)memcpy(pNew, pUser, sizeof(SUserObj));
951,072✔
2219
  pNew->authVersion++;
951,072✔
2220
  pNew->updateTime = taosGetTimestampMs();
951,072✔
2221
  taosInitRWLatch(&pNew->lock);
951,072✔
2222

2223
  pNew->passwords = NULL;
951,072✔
2224
  pNew->pIpWhiteListDual = NULL;
951,072✔
2225
  pNew->passwords = NULL;
951,072✔
2226
  pNew->objPrivs = NULL;
951,072✔
2227
  pNew->selectTbs = NULL;
951,072✔
2228
  pNew->insertTbs = NULL;
951,072✔
2229
  pNew->updateTbs = NULL;
951,072✔
2230
  pNew->deleteTbs = NULL;
951,072✔
2231
  pNew->pTimeWhiteList = NULL;
951,072✔
2232
  pNew->roles = NULL;
951,072✔
2233

2234
  taosRLockLatch(&pUser->lock);
951,072✔
2235
  pNew->passwords = taosMemoryCalloc(pUser->numOfPasswords, sizeof(SUserPassword));
951,072✔
2236
  if (pNew->passwords == NULL) {
951,072✔
2237
    code = TSDB_CODE_OUT_OF_MEMORY;
×
2238
    goto _OVER;
×
2239
  }
2240
  (void)memcpy(pNew->passwords, pUser->passwords, pUser->numOfPasswords * sizeof(SUserPassword));
951,072✔
2241
  TAOS_CHECK_GOTO(mndDupPrivObjHash(pUser->objPrivs, &pNew->objPrivs), NULL, _OVER);
951,072✔
2242
  TAOS_CHECK_GOTO(mndDupPrivTblHash(pUser->selectTbs, &pNew->selectTbs, false), NULL, _OVER);
951,072✔
2243
  TAOS_CHECK_GOTO(mndDupPrivTblHash(pUser->insertTbs, &pNew->insertTbs, false), NULL, _OVER);
951,072✔
2244
  TAOS_CHECK_GOTO(mndDupPrivTblHash(pUser->updateTbs, &pNew->updateTbs, false), NULL, _OVER);
951,072✔
2245
  TAOS_CHECK_GOTO(mndDupPrivTblHash(pUser->deleteTbs, &pNew->deleteTbs, false), NULL, _OVER);
951,072✔
2246
  TAOS_CHECK_GOTO(mndDupRoleHash(pUser->roles, &pNew->roles), NULL, _OVER);
951,072✔
2247
  pNew->pIpWhiteListDual = cloneIpWhiteList(pUser->pIpWhiteListDual);
951,072✔
2248
  if (pNew->pIpWhiteListDual == NULL) {
951,072✔
UNCOV
2249
    code = TSDB_CODE_OUT_OF_MEMORY;
×
UNCOV
2250
    goto _OVER;
×
2251
  }
2252

2253
  pNew->pTimeWhiteList = cloneDateTimeWhiteList(pUser->pTimeWhiteList);
951,072✔
2254
  if (pNew->pTimeWhiteList == NULL) {
951,072✔
UNCOV
2255
    code = TSDB_CODE_OUT_OF_MEMORY;
×
UNCOV
2256
    goto _OVER;
×
2257
  }
2258

2259
_OVER:
951,072✔
2260
  taosRUnLockLatch(&pUser->lock);
951,072✔
2261
  TAOS_RETURN(code);
951,072✔
2262
}
2263

2264
void mndUserFreeObj(SUserObj *pUser) {
4,830,750✔
2265
  taosHashCleanup(pUser->objPrivs);
4,830,750✔
2266
  taosHashCleanup(pUser->selectTbs);
4,830,750✔
2267
  taosHashCleanup(pUser->insertTbs);
4,830,750✔
2268
  taosHashCleanup(pUser->updateTbs);
4,830,750✔
2269
  taosHashCleanup(pUser->deleteTbs);
4,830,750✔
2270
  taosHashCleanup(pUser->roles);
4,830,750✔
2271
  taosMemoryFreeClear(pUser->passwords);
4,830,750✔
2272
  taosMemoryFreeClear(pUser->pIpWhiteListDual);
4,830,750✔
2273
  taosMemoryFreeClear(pUser->pTimeWhiteList);
4,830,750✔
2274
  pUser->objPrivs = NULL;
4,830,750✔
2275
  pUser->selectTbs = NULL;
4,830,750✔
2276
  pUser->insertTbs = NULL;
4,830,750✔
2277
  pUser->updateTbs = NULL;
4,830,750✔
2278
  pUser->deleteTbs = NULL;
4,830,750✔
2279
  pUser->roles = NULL;
4,830,750✔
2280
}
4,830,750✔
2281

2282
static int32_t mndUserActionDelete(SSdb *pSdb, SUserObj *pUser) {
1,411,496✔
2283
  mTrace("user:%s, perform delete action, row:%p", pUser->user, pUser);
1,411,496✔
2284
  mndUserFreeObj(pUser);
1,411,496✔
2285
  return 0;
1,411,496✔
2286
}
2287

2288
static int32_t mndUserActionUpdate(SSdb *pSdb, SUserObj *pOld, SUserObj *pNew) {
954,125✔
2289
  mTrace("user:%s, perform update action, old row:%p new row:%p", pOld->user, pOld, pNew);
954,125✔
2290
  taosWLockLatch(&pOld->lock);
954,125✔
2291
  pOld->updateTime = pNew->updateTime;
954,125✔
2292
  pOld->authVersion = pNew->authVersion;
954,125✔
2293
  pOld->passVersion = pNew->passVersion;
954,125✔
2294
  pOld->sysInfo = pNew->sysInfo;
954,125✔
2295
  pOld->enable = pNew->enable;
954,125✔
2296
  pOld->flag = pNew->flag;
954,125✔
2297
  pOld->changePass = pNew->changePass;
954,125✔
2298
  pOld->uid = pNew->uid;
954,125✔
2299

2300
  pOld->sessionPerUser = pNew->sessionPerUser;
954,125✔
2301
  pOld->connectTime = pNew->connectTime;
954,125✔
2302
  pOld->connectIdleTime = pNew->connectIdleTime;
954,125✔
2303
  pOld->callPerSession = pNew->callPerSession;
954,125✔
2304
  pOld->vnodePerCall = pNew->vnodePerCall;
954,125✔
2305
  pOld->failedLoginAttempts = pNew->failedLoginAttempts;
954,125✔
2306
  pOld->passwordLifeTime = pNew->passwordLifeTime;
954,125✔
2307
  pOld->passwordReuseTime = pNew->passwordReuseTime;
954,125✔
2308
  pOld->passwordReuseMax = pNew->passwordReuseMax;
954,125✔
2309
  pOld->passwordLockTime = pNew->passwordLockTime;
954,125✔
2310
  pOld->passwordGraceTime = pNew->passwordGraceTime;
954,125✔
2311
  pOld->inactiveAccountTime = pNew->inactiveAccountTime;
954,125✔
2312
  pOld->allowTokenNum = pNew->allowTokenNum;
954,125✔
2313
  pOld->tokenNum = pNew->tokenNum;
954,125✔
2314

2315
  pOld->numOfPasswords = pNew->numOfPasswords;
954,125✔
2316
  TSWAP(pOld->passwords, pNew->passwords);
954,125✔
2317
  (void)memcpy(pOld->salt, pNew->salt, sizeof(pOld->salt));
954,125✔
2318
  (void)memcpy(pOld->totpsecret, pNew->totpsecret, sizeof(pOld->totpsecret));
954,125✔
2319
  pOld->sysPrivs = pNew->sysPrivs;
954,125✔
2320
  TSWAP(pOld->objPrivs, pNew->objPrivs);
954,125✔
2321
  TSWAP(pOld->selectTbs, pNew->selectTbs);
954,125✔
2322
  TSWAP(pOld->insertTbs, pNew->insertTbs);
954,125✔
2323
  TSWAP(pOld->updateTbs, pNew->updateTbs);
954,125✔
2324
  TSWAP(pOld->deleteTbs, pNew->deleteTbs);
954,125✔
2325
  TSWAP(pOld->roles, pNew->roles);
954,125✔
2326

2327
  TSWAP(pOld->pIpWhiteListDual, pNew->pIpWhiteListDual);
954,125✔
2328
  pOld->ipWhiteListVer = pNew->ipWhiteListVer;
954,125✔
2329
  TSWAP(pOld->pTimeWhiteList, pNew->pTimeWhiteList);
954,125✔
2330
  pOld->timeWhiteListVer = pNew->timeWhiteListVer;
954,125✔
2331
  pOld->passEncryptAlgorithm = pNew->passEncryptAlgorithm;
954,125✔
2332

2333
  taosWUnLockLatch(&pOld->lock);
954,125✔
2334

2335
  return 0;
954,125✔
2336
}
2337

2338
int32_t mndAcquireUser(SMnode *pMnode, const char *userName, SUserObj **ppUser) {
75,041,020✔
2339
  int32_t code = 0;
75,041,020✔
2340
  SSdb   *pSdb = pMnode->pSdb;
75,041,020✔
2341

2342
  *ppUser = sdbAcquire(pSdb, SDB_USER, userName);
75,042,092✔
2343
  if (*ppUser == NULL) {
75,042,784✔
2344
    if (terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
47,916✔
2345
      code = TSDB_CODE_MND_USER_NOT_EXIST;
47,916✔
2346
    } else {
UNCOV
2347
      code = TSDB_CODE_MND_USER_NOT_AVAILABLE;
×
2348
    }
2349
  }
2350
  TAOS_RETURN(code);
75,042,975✔
2351
}
2352

2353
void mndReleaseUser(SMnode *pMnode, SUserObj *pUser) {
81,759,409✔
2354
  SSdb *pSdb = pMnode->pSdb;
81,759,409✔
2355
  sdbRelease(pSdb, pUser);
81,760,478✔
2356
}
81,760,478✔
2357

UNCOV
2358
int32_t mndAcquireUserById(SMnode *pMnode, int64_t userId, SUserObj **ppUser) {
×
UNCOV
2359
  void     *pIter = NULL;
×
UNCOV
2360
  SUserObj *pObj;
×
UNCOV
2361
  SSdb     *pSdb = pMnode->pSdb;
×
UNCOV
2362
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pObj))) {
×
UNCOV
2363
    if (pObj->uid == userId) {
×
2364
      return mndAcquireUser(pMnode, pObj->user, ppUser);
×
2365
    }
2366
  }
UNCOV
2367
  return 0;
×
2368
}
2369

2370
int32_t mndBuildUidNamesHash(SMnode *pMnode, SSHashObj **ppHash) {
452,438✔
2371
  int32_t    code = 0;
452,438✔
2372
  void      *pIter = NULL;
452,438✔
2373
  SUserObj  *pObj;
452,438✔
2374
  SSHashObj *pHash = NULL;
452,438✔
2375

2376
  int32_t nUser = sdbGetSize(pMnode->pSdb, SDB_USER);
452,438✔
2377

2378
  pHash = tSimpleHashInit(nUser, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT));
452,438✔
2379
  if (pHash == NULL) {
452,438✔
2380
    TAOS_RETURN(terrno);
×
2381
  }
2382

2383
  while ((pIter = sdbFetch(pMnode->pSdb, SDB_USER, pIter, (void **)&pObj))) {
915,977✔
2384
    code = tSimpleHashPut(pHash, &pObj->uid, sizeof(pObj->uid), pObj->name, strlen(pObj->name) + 1);
463,539✔
2385
    if (code != 0) {
463,539✔
2386
      sdbRelease(pMnode->pSdb, pObj);
×
2387
      sdbCancelFetch(pMnode->pSdb, pIter);
×
UNCOV
2388
      tSimpleHashCleanup(pHash);
×
UNCOV
2389
      TAOS_RETURN(code);
×
2390
    }
2391
    sdbRelease(pMnode->pSdb, pObj);
463,539✔
2392
  }
2393

2394
  *ppHash = pHash;
452,438✔
2395
  TAOS_RETURN(code);
452,438✔
2396
}
2397

2398
int32_t mndEncryptPass(char *pass, const char* salt, int8_t *algo) {
49,989✔
2399
  int32_t code = 0;
49,989✔
2400
  if (tsMetaKey[0] == '\0') {
49,989✔
2401
    return 0;
49,989✔
2402
  }
2403

UNCOV
2404
  if (salt[0] != 0) {
×
2405
    char passAndSalt[TSDB_PASSWORD_LEN - 1 + TSDB_PASSWORD_SALT_LEN];
×
2406
    (void)memcpy(passAndSalt, pass, TSDB_PASSWORD_LEN - 1);
×
UNCOV
2407
    (void)memcpy(passAndSalt + TSDB_PASSWORD_LEN - 1, salt, TSDB_PASSWORD_SALT_LEN);
×
2408
    taosEncryptPass_c((uint8_t *)passAndSalt, sizeof(passAndSalt), pass);
2409
  }
2410

2411
  unsigned char packetData[TSDB_PASSWORD_LEN] = {0};
×
UNCOV
2412
  SCryptOpts opts = {0};
×
2413
  opts.len = TSDB_PASSWORD_LEN;
×
2414
  opts.source = pass;
×
2415
  opts.result = packetData;
×
UNCOV
2416
  opts.unitLen = TSDB_PASSWORD_LEN;
×
2417
  tstrncpy(opts.key, tsDbKey, ENCRYPT_KEY_LEN + 1);
×
2418
  int newLen = Builtin_CBC_Encrypt(&opts);
×
2419
  if (newLen <= 0) return terrno;
×
2420

UNCOV
2421
  memcpy(pass, packetData, newLen);
×
2422
  if (algo != NULL) {
×
2423
    *algo = DND_CA_SM4;
×
2424
  }
2425

UNCOV
2426
  return 0;
×
2427
}
2428

2429

2430

2431
static void generateSalt(char *salt, size_t len) {
46,143✔
2432
  const char* set = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
46,143✔
2433
  int32_t     setLen = 62;
46,143✔
2434
  for (int32_t i = 0; i < len - 1; ++i) {
1,476,576✔
2435
    salt[i] = set[taosSafeRand() % setLen];
1,430,433✔
2436
  }
2437
  salt[len - 1] = 0;
46,143✔
2438
}
46,143✔
2439

2440

2441

2442
static int32_t addDefaultIpToTable(int8_t enableIpv6, SHashObj *pUniqueTab) {
467✔
2443
  int32_t code = 0;
467✔
2444
  int32_t lino = 0;
467✔
2445
  int32_t dummpy = 0;
467✔
2446

2447
  SIpRange ipv4 = {0}, ipv6 = {0};
467✔
2448
  code = createDefaultIp4Range(&ipv4);
467✔
2449
  TSDB_CHECK_CODE(code, lino, _error);
467✔
2450

2451
  code = taosHashPut(pUniqueTab, &ipv4, sizeof(ipv4), &dummpy, sizeof(dummpy));
467✔
2452
  TSDB_CHECK_CODE(code, lino, _error);
467✔
2453

2454
  if (enableIpv6) {
467✔
UNCOV
2455
    code = createDefaultIp6Range(&ipv6);
×
UNCOV
2456
    TSDB_CHECK_CODE(code, lino, _error);
×
2457

UNCOV
2458
    code = taosHashPut(pUniqueTab, &ipv6, sizeof(ipv6), &dummpy, sizeof(dummpy));
×
UNCOV
2459
    TSDB_CHECK_CODE(code, lino, _error);
×
2460
  }
2461
_error:
467✔
2462
  if (code != 0) {
467✔
UNCOV
2463
    mError("failed to add default ip range to table since %s", tstrerror(code));
×
2464
  }
2465
  return code;
467✔
2466
}
2467

2468
static int32_t mndCreateUser(SMnode *pMnode, char *acct, SCreateUserReq *pCreate, SRpcMsg *pReq) {
45,829✔
2469
  int32_t  code = 0;
45,829✔
2470
  int32_t  lino = 0;
45,829✔
2471
  SUserObj userObj = {0};
45,829✔
2472

2473
  userObj.passwords = taosMemoryCalloc(1, sizeof(SUserPassword));
45,829✔
2474
  if (userObj.passwords == NULL) {
45,829✔
2475
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2476
  }
2477
  userObj.numOfPasswords = 1;
45,829✔
2478

2479
  if (pCreate->isImport == 1) {
45,829✔
2480
    memset(userObj.salt, 0, sizeof(userObj.salt));
×
2481
    memcpy(userObj.passwords[0].pass, pCreate->pass, TSDB_PASSWORD_LEN);
×
2482
  } else {
2483
    generateSalt(userObj.salt, sizeof(userObj.salt));
45,829✔
2484
    taosEncryptPass_c((uint8_t *)pCreate->pass, strlen(pCreate->pass), userObj.passwords[0].pass);
45,829✔
2485
    userObj.passwords[0].pass[sizeof(userObj.passwords[0].pass) - 1] = 0;
45,829✔
2486
    TAOS_CHECK_GOTO(mndEncryptPass(userObj.passwords[0].pass, userObj.salt, &userObj.passEncryptAlgorithm), &lino, _OVER);
45,829✔
2487
  }
2488
  userObj.passwords[0].setTime = taosGetTimestampSec();
45,829✔
2489

2490
  tstrncpy(userObj.user, pCreate->user, TSDB_USER_LEN);
45,829✔
2491
  tstrncpy(userObj.acct, acct, TSDB_USER_LEN);
45,829✔
2492
  if (pCreate->totpseed[0] != 0) {
45,829✔
UNCOV
2493
    int len = taosGenerateTotpSecret(pCreate->totpseed, 0, userObj.totpsecret, sizeof(userObj.totpsecret));
×
UNCOV
2494
    if (len < 0) {
×
UNCOV
2495
      TAOS_CHECK_GOTO(TSDB_CODE_PAR_INVALID_OPTION_VALUE, &lino, _OVER);
×
2496
    }
2497
  }
2498

2499
  userObj.createdTime = taosGetTimestampMs();
45,829✔
2500
  userObj.updateTime = userObj.createdTime;
45,829✔
2501
  userObj.superUser = 0;  // pCreate->superUser;
45,829✔
2502
  userObj.sysInfo = pCreate->sysInfo;
45,829✔
2503
  userObj.enable = pCreate->enable;
45,829✔
2504
  userObj.createdb = pCreate->createDb;
45,829✔
2505
  userObj.uid = mndGenerateUid(userObj.user, strlen(userObj.user));
45,829✔
2506

2507
  userObj.changePass = pCreate->changepass;
45,829✔
2508
  userObj.sessionPerUser = pCreate->sessionPerUser;
45,829✔
2509
  userObj.connectTime = pCreate->connectTime;
45,829✔
2510
  userObj.connectIdleTime = pCreate->connectIdleTime;
45,829✔
2511
  userObj.callPerSession = pCreate->callPerSession;
45,829✔
2512
  userObj.vnodePerCall = pCreate->vnodePerCall;
45,829✔
2513
  userObj.failedLoginAttempts = pCreate->failedLoginAttempts;
45,829✔
2514
  userObj.passwordLifeTime = pCreate->passwordLifeTime;
45,829✔
2515
  userObj.passwordReuseTime = pCreate->passwordReuseTime;
45,829✔
2516
  userObj.passwordReuseMax = pCreate->passwordReuseMax;
45,829✔
2517
  userObj.passwordLockTime = pCreate->passwordLockTime;
45,829✔
2518
  userObj.passwordGraceTime = pCreate->passwordGraceTime;
45,829✔
2519
  userObj.inactiveAccountTime = pCreate->inactiveAccountTime;
45,829✔
2520
  userObj.allowTokenNum = pCreate->allowTokenNum;
45,829✔
2521
  userObj.tokenNum = 0;
45,829✔
2522

2523
  if (pCreate->numIpRanges == 0) {
45,829✔
2524
    TAOS_CHECK_GOTO(createDefaultIpWhiteList(&userObj.pIpWhiteListDual), &lino, _OVER);
45,362✔
2525
  } else {
2526
    SHashObj *pUniqueTab = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
467✔
2527
    if (pUniqueTab == NULL) {
467✔
UNCOV
2528
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2529
    }
2530
    int32_t dummpy = 0;
467✔
2531
    
2532
    for (int i = 0; i < pCreate->numIpRanges; i++) {
1,244✔
2533
      SIpRange range = {0};
777✔
2534
      copyIpRange(&range, pCreate->pIpDualRanges + i);
777✔
2535
      if ((code = taosHashPut(pUniqueTab, &range, sizeof(range), &dummpy, sizeof(dummpy))) != 0) {
777✔
UNCOV
2536
        taosHashCleanup(pUniqueTab);
×
UNCOV
2537
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2538
      }
2539
    }
2540

2541
    code = addDefaultIpToTable(tsEnableIpv6, pUniqueTab);
467✔
2542
    if (code != 0) {
467✔
UNCOV
2543
      taosHashCleanup(pUniqueTab);
×
UNCOV
2544
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2545
    }
2546

2547
    if (taosHashGetSize(pUniqueTab) > MND_MAX_USER_IP_RANGE) {
467✔
UNCOV
2548
      taosHashCleanup(pUniqueTab);
×
2549
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_IP_RANGE, &lino, _OVER);
×
2550
    }
2551

2552
    int32_t           numOfRanges = taosHashGetSize(pUniqueTab);
467✔
2553
    SIpWhiteListDual *p = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + numOfRanges * sizeof(SIpRange));
467✔
2554
    if (p == NULL) {
467✔
UNCOV
2555
      taosHashCleanup(pUniqueTab);
×
UNCOV
2556
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2557
    }
2558

2559
    void   *pIter = taosHashIterate(pUniqueTab, NULL);
467✔
2560
    for (int32_t i = 0; i < numOfRanges; i++) {
1,399✔
2561
      size_t    len = 0;
932✔
2562
      SIpRange *key = taosHashGetKey(pIter, &len);
932✔
2563
      memcpy(&p->pIpRanges[i], key, sizeof(SIpRange));
932✔
2564
      pIter = taosHashIterate(pUniqueTab, pIter);
932✔
2565
    }
2566

2567
    taosHashCleanup(pUniqueTab);
467✔
2568
    p->num = numOfRanges;
467✔
2569
    sortIpWhiteList(p);
467✔
2570
    userObj.pIpWhiteListDual = p;
467✔
2571
  }
2572

2573
  if (pCreate->numTimeRanges == 0) {
45,829✔
2574
    userObj.pTimeWhiteList = (SDateTimeWhiteList*)taosMemoryCalloc(1, sizeof(SDateTimeWhiteList));
45,829✔
2575
    if (userObj.pTimeWhiteList == NULL) {
45,829✔
UNCOV
2576
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2577
    }
2578
  } else {
UNCOV
2579
    SHashObj *pUniqueTab = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
×
UNCOV
2580
    if (pUniqueTab == NULL) {
×
UNCOV
2581
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2582
    }
UNCOV
2583
    int32_t dummpy = 0;
×
2584
    
UNCOV
2585
    for (int i = 0; i < pCreate->numIpRanges; i++) {
×
UNCOV
2586
      SDateTimeRange* src = pCreate->pTimeRanges + i;
×
UNCOV
2587
      SDateTimeWhiteListItem range = {0};
×
UNCOV
2588
      DateTimeRangeToWhiteListItem(&range, src);
×
2589

2590
      // no need to add expired range
UNCOV
2591
      if (isDateTimeWhiteListItemExpired(&range)) {
×
UNCOV
2592
        continue;
×
2593
      }
2594

UNCOV
2595
      if ((code = taosHashPut(pUniqueTab, &range, sizeof(range), &dummpy, sizeof(dummpy))) != 0) {
×
UNCOV
2596
        taosHashCleanup(pUniqueTab);
×
UNCOV
2597
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2598
      }
2599
    }
2600

UNCOV
2601
    if (taosHashGetSize(pUniqueTab) > MND_MAX_USER_TIME_RANGE) {
×
UNCOV
2602
      taosHashCleanup(pUniqueTab);
×
UNCOV
2603
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_TIME_RANGE, &lino, _OVER);
×
2604
    }
2605

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

UNCOV
2613
    void   *pIter = taosHashIterate(pUniqueTab, NULL);
×
UNCOV
2614
    for (int32_t i = 0; i < numOfRanges; i++) {
×
UNCOV
2615
      size_t    len = 0;
×
UNCOV
2616
      SDateTimeWhiteListItem *key = taosHashGetKey(pIter, &len);
×
UNCOV
2617
      memcpy(p->ranges + i, key, sizeof(SDateTimeWhiteListItem));
×
UNCOV
2618
      pIter = taosHashIterate(pUniqueTab, pIter);
×
2619
    }
2620

UNCOV
2621
    taosHashCleanup(pUniqueTab);
×
UNCOV
2622
    p->num = numOfRanges;
×
UNCOV
2623
    sortTimeWhiteList(p);
×
UNCOV
2624
    userObj.pTimeWhiteList = p;
×
2625
  }
2626

2627
  userObj.ipWhiteListVer = taosGetTimestampMs();
45,829✔
2628
  userObj.timeWhiteListVer = userObj.ipWhiteListVer;
45,829✔
2629

2630
  userObj.roles = taosHashInit(1, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
45,829✔
2631
  if (userObj.roles == NULL) {
45,829✔
UNCOV
2632
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2633
  }
2634

2635
  if ((code = taosHashPut(userObj.roles, TSDB_ROLE_SYSINFO_1, strlen(TSDB_ROLE_SYSINFO_1) + 1, NULL, 0)) != 0) {
45,829✔
UNCOV
2636
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2637
  }
2638

2639
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "create-user");
45,829✔
2640
  if (pTrans == NULL) {
45,829✔
UNCOV
2641
    mError("user:%s, failed to create since %s", pCreate->user, terrstr());
×
2642
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2643
  }
2644
  mInfo("trans:%d, used to create user:%s", pTrans->id, pCreate->user);
45,829✔
2645

2646
  SSdbRaw *pCommitRaw = mndUserActionEncode(&userObj);
45,829✔
2647
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
45,829✔
UNCOV
2648
    mError("trans:%d, failed to commit redo log since %s", pTrans->id, terrstr());
×
UNCOV
2649
    mndTransDrop(pTrans);
×
UNCOV
2650
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2651
  }
2652
  TAOS_CHECK_GOTO(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY), &lino, _OVER);
45,829✔
2653

2654
  if (mndTransPrepare(pMnode, pTrans) != 0) {
45,829✔
2655
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
UNCOV
2656
    mndTransDrop(pTrans);
×
UNCOV
2657
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2658
  }
2659

2660
  if ((code = userCacheUpdateWhiteList(pMnode, &userObj)) != 0) {
45,829✔
UNCOV
2661
    mndTransDrop(pTrans);
×
UNCOV
2662
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2663
  }
2664

2665
  mndTransDrop(pTrans);
45,829✔
2666

2667
_OVER:
45,829✔
2668
  mndUserFreeObj(&userObj);
45,829✔
2669
  TAOS_RETURN(code);
45,829✔
2670
}
2671

2672

2673
static int32_t mndCheckPasswordFmt(const char *pwd) {
49,989✔
2674
  if (strcmp(pwd, "taosdata") == 0) {
49,989✔
2675
    return 0;
9,587✔
2676
  }
2677

2678
  if (tsEnableStrongPassword == 0) {
40,402✔
2679
    for (char c = *pwd; c != 0; c = *(++pwd)) {
43,018✔
2680
      if (c == ' ' || c == '\'' || c == '\"' || c == '`' || c == '\\') {
42,547✔
UNCOV
2681
        return TSDB_CODE_MND_INVALID_PASS_FORMAT;
×
2682
      }
2683
    }
2684
    return 0;
471✔
2685
  }
2686

2687
  int32_t len = strlen(pwd);
39,931✔
2688
  if (len < TSDB_PASSWORD_MIN_LEN) {
39,931✔
UNCOV
2689
    return TSDB_CODE_PAR_PASSWD_TOO_SHORT_OR_EMPTY;
×
2690
  }
2691

2692
  if (len > TSDB_PASSWORD_MAX_LEN) {
39,931✔
UNCOV
2693
    return TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG;
×
2694
  }
2695

2696
  if (taosIsComplexString(pwd)) {
39,931✔
2697
    return 0;
39,931✔
2698
  }
2699

2700
  return TSDB_CODE_MND_INVALID_PASS_FORMAT;
×
2701
}
2702

2703

2704

UNCOV
2705
static int32_t mndCheckTotpSeedFmt(const char *seed) {
×
UNCOV
2706
  int32_t len = strlen(seed);
×
UNCOV
2707
  if (len < TSDB_USER_TOTPSEED_MIN_LEN) {
×
UNCOV
2708
    return TSDB_CODE_PAR_OPTION_VALUE_TOO_SHORT;
×
2709
  }
2710

UNCOV
2711
  if (taosIsComplexString(seed)) {
×
UNCOV
2712
    return 0;
×
2713
  }
2714

2715
  return TSDB_CODE_PAR_INVALID_OPTION_VALUE;
×
2716
}
2717

2718

2719

UNCOV
2720
static int32_t mndProcessGetUserDateTimeWhiteListReq(SRpcMsg *pReq) {
×
UNCOV
2721
  SMnode              *pMnode = pReq->info.node;
×
UNCOV
2722
  int32_t              code = 0;
×
UNCOV
2723
  int32_t              lino = 0;
×
UNCOV
2724
  int32_t              contLen = 0;
×
UNCOV
2725
  void                *pRsp = NULL;
×
UNCOV
2726
  SUserObj            *pUser = NULL;
×
UNCOV
2727
  SGetUserWhiteListReq wlReq = {0};
×
UNCOV
2728
  SUserDateTimeWhiteList wlRsp = {0};
×
2729

UNCOV
2730
  if (tDeserializeSGetUserWhiteListReq(pReq->pCont, pReq->contLen, &wlReq) != 0) {
×
UNCOV
2731
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
2732
  }
UNCOV
2733
  mTrace("user: %s, start to get date time whitelist", wlReq.user);
×
2734

UNCOV
2735
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, wlReq.user, &pUser), &lino, _OVER);
×
UNCOV
2736
  TAOS_CHECK_GOTO(mndSetUserDateTimeWhiteListRsp(pMnode, pUser, &wlRsp), &lino, _OVER);
×
2737

UNCOV
2738
  contLen = tSerializeSUserDateTimeWhiteList(NULL, 0, &wlRsp);
×
UNCOV
2739
  if (contLen < 0) {
×
UNCOV
2740
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2741
  }
2742
  pRsp = rpcMallocCont(contLen);
×
UNCOV
2743
  if (pRsp == NULL) {
×
UNCOV
2744
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2745
  }
2746
  
2747
  contLen = tSerializeSUserDateTimeWhiteList(pRsp, contLen, &wlRsp);
×
UNCOV
2748
  if (contLen < 0) {
×
UNCOV
2749
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2750
  }
2751

UNCOV
2752
_OVER:
×
UNCOV
2753
  mndReleaseUser(pMnode, pUser);
×
UNCOV
2754
  tFreeSUserDateTimeWhiteList(&wlRsp);
×
UNCOV
2755
  if (code < 0) {
×
2756
    mError("user:%s, failed to get whitelist at line %d since %s", wlReq.user, lino, tstrerror(code));
×
UNCOV
2757
    rpcFreeCont(pRsp);
×
UNCOV
2758
    pRsp = NULL;
×
UNCOV
2759
    contLen = 0;
×
2760
  }
2761
  pReq->code = code;
×
UNCOV
2762
  pReq->info.rsp = pRsp;
×
UNCOV
2763
  pReq->info.rspLen = contLen;
×
2764

2765
  TAOS_RETURN(code);
×
2766
  return 0;
2767
}
2768

2769

2770

2771
static int32_t buildRetrieveDateTimeWhiteListRsp(SRetrieveDateTimeWhiteListRsp *pRsp) {
466✔
2772
  (void)taosThreadRwlockRdlock(&userCache.rw);
466✔
2773
  
2774
  int32_t count = taosHashGetSize(userCache.users);
466✔
2775
  pRsp->pUsers = taosMemoryCalloc(count, sizeof(SUserDateTimeWhiteList));
466✔
2776
  if (pRsp->pUsers == NULL) {
466✔
UNCOV
2777
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
UNCOV
2778
    TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
2779
  }
2780

2781
  count = 0;
466✔
2782
  void   *pIter = taosHashIterate(userCache.users, NULL);
466✔
2783
  while (pIter) {
932✔
2784
    SDateTimeWhiteList *wl = (*(SCachedUserInfo **)pIter)->wlTime;
466✔
2785
    if (wl == NULL || wl->num <= 0) {
466✔
2786
      pIter = taosHashIterate(userCache.users, pIter);
466✔
2787
      continue;
466✔
2788
    }
2789

2790
    SUserDateTimeWhiteList *pUser = &pRsp->pUsers[count];
×
UNCOV
2791
    pUser->ver = userCache.verTime;
×
2792

UNCOV
2793
    size_t klen;
×
UNCOV
2794
    char  *key = taosHashGetKey(pIter, &klen);
×
UNCOV
2795
    (void)memcpy(pUser->user, key, klen);
×
2796

2797
    pUser->numWhiteLists = wl->num;
×
2798
    pUser->pWhiteLists = taosMemoryCalloc(wl->num, sizeof(SDateTimeWhiteListItem));
×
UNCOV
2799
    if (pUser->pWhiteLists == NULL) {
×
UNCOV
2800
      (void)taosThreadRwlockUnlock(&userCache.rw);
×
UNCOV
2801
      TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
2802
    }
2803

UNCOV
2804
    (void)memcpy(pUser->pWhiteLists, wl->ranges, wl->num * sizeof(SDateTimeWhiteListItem));
×
UNCOV
2805
    count++;
×
UNCOV
2806
    pIter = taosHashIterate(userCache.users, pIter);
×
2807
  }
2808

2809
  pRsp->numOfUser = count;
466✔
2810
  pRsp->ver = userCache.verTime;
466✔
2811
  (void)taosThreadRwlockUnlock(&userCache.rw);
466✔
2812
  TAOS_RETURN(0);
466✔
2813
}
2814

2815

2816

2817
static int32_t mndProcessRetrieveDateTimeWhiteListReq(SRpcMsg *pReq) {
466✔
2818
  int32_t        code = 0;
466✔
2819
  int32_t        lino = 0;
466✔
2820
  int32_t        len = 0;
466✔
2821
  void          *pRsp = NULL;
466✔
2822
  SRetrieveDateTimeWhiteListRsp wlRsp = {0};
466✔
2823

2824
  // impl later
2825
  SRetrieveWhiteListReq req = {0};
466✔
2826
  if (tDeserializeRetrieveWhiteListReq(pReq->pCont, pReq->contLen, &req) != 0) {
466✔
UNCOV
2827
    code = TSDB_CODE_INVALID_MSG;
×
UNCOV
2828
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2829
  }
2830

2831
  TAOS_CHECK_GOTO(buildRetrieveDateTimeWhiteListRsp(&wlRsp), &lino, _OVER);
466✔
2832

2833
  len = tSerializeSRetrieveDateTimeWhiteListRsp(NULL, 0, &wlRsp);
466✔
2834
  if (len < 0) {
466✔
2835
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
2836
  }
2837

2838
  pRsp = rpcMallocCont(len);
466✔
2839
  if (!pRsp) {
466✔
UNCOV
2840
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2841
  }
2842
  len = tSerializeSRetrieveDateTimeWhiteListRsp(pRsp, len, &wlRsp);
466✔
2843
  if (len < 0) {
466✔
UNCOV
2844
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
2845
  }
2846

2847
_OVER:
466✔
2848
  if (code < 0) {
466✔
UNCOV
2849
    mError("failed to process retrieve ip white request at line %d since %s", lino, tstrerror(code));
×
UNCOV
2850
    rpcFreeCont(pRsp);
×
UNCOV
2851
    pRsp = NULL;
×
UNCOV
2852
    len = 0;
×
2853
  }
2854
  pReq->code = code;
466✔
2855
  pReq->info.rsp = pRsp;
466✔
2856
  pReq->info.rspLen = len;
466✔
2857

2858
  tFreeSRetrieveDateTimeWhiteListRsp(&wlRsp);
466✔
2859
  TAOS_RETURN(code);
466✔
2860
}
2861

2862

2863

2864
static int32_t mndProcessCreateUserReq(SRpcMsg *pReq) {
45,829✔
2865
  SMnode        *pMnode = pReq->info.node;
45,829✔
2866
  int32_t        code = 0;
45,829✔
2867
  int32_t        lino = 0;
45,829✔
2868
  SRoleObj      *pRole = NULL;
45,829✔
2869
  SUserObj      *pUser = NULL;
45,829✔
2870
  SUserObj      *pOperUser = NULL;
45,829✔
2871
  SCreateUserReq createReq = {0};
45,829✔
2872
  int64_t        tss = taosGetTimestampMs();
45,829✔
2873

2874
  if (tDeserializeSCreateUserReq(pReq->pCont, pReq->contLen, &createReq) != 0) {
45,829✔
UNCOV
2875
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
2876
  }
2877

2878
  mInfo("user:%s, start to create, createdb:%d, is_import:%d", createReq.user, createReq.createDb, createReq.isImport);
45,829✔
2879

2880
#ifndef TD_ENTERPRISE
2881
  if (createReq.isImport == 1) {
2882
    TAOS_CHECK_GOTO(TSDB_CODE_OPS_NOT_SUPPORT, &lino, _OVER);  // enterprise feature
2883
  }
2884
#endif
2885
  code = mndAcquireUser(pMnode, RPC_MSG_USER(pReq), &pOperUser);
45,829✔
2886
  if (pOperUser == NULL) {
45,829✔
UNCOV
2887
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_USER_FROM_CONN, &lino, _OVER);
×
2888
  }
2889

2890
  if (createReq.isImport != 1) {
45,829✔
2891
    // TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, RPC_MSG_USER(pReq), MND_OPER_CREATE_USER), &lino, _OVER);
2892
    TAOS_CHECK_GOTO(mndCheckSysObjPrivilege(pMnode, pOperUser, PRIV_USER_CREATE, 0, 0, NULL, NULL), &lino, _OVER);
45,829✔
UNCOV
2893
  } else if (strcmp(RPC_MSG_USER(pReq), "root") != 0) {
×
UNCOV
2894
    mError("The operation is not permitted to create user:%s", RPC_MSG_USER(pReq));
×
UNCOV
2895
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_RIGHTS, &lino, _OVER);
×
2896
  }
2897

2898
  if (createReq.user[0] == 0) {
45,829✔
UNCOV
2899
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
2900
  }
2901

2902
  if (createReq.isImport != 1) {
45,829✔
2903
    code = mndCheckPasswordFmt(createReq.pass);
45,829✔
2904
    TAOS_CHECK_GOTO(code, &lino, _OVER);
45,829✔
2905
  }
2906

2907
  if (createReq.totpseed[0] != 0) {
45,829✔
UNCOV
2908
    code = mndCheckTotpSeedFmt(createReq.totpseed);
×
UNCOV
2909
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2910
  }
2911

2912
  code = mndAcquireUser(pMnode, createReq.user, &pUser);
45,829✔
2913
  if (pUser != NULL) {
45,829✔
UNCOV
2914
    TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_ALREADY_EXIST, &lino, _OVER);
×
2915
  }
2916

2917
  code = mndAcquireRole(pMnode, createReq.user, &pRole);
45,829✔
2918
  if (pRole != NULL) {
45,829✔
UNCOV
2919
    TAOS_CHECK_GOTO(TSDB_CODE_MND_ROLE_ALREADY_EXIST, &lino, _OVER);
×
2920
  }
2921

2922
  TAOS_CHECK_GOTO(grantCheck(TSDB_GRANT_USER), &lino, _OVER);
45,829✔
2923

2924
  code = mndCreateUser(pMnode, pOperUser->acct, &createReq, pReq);
45,829✔
2925
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
45,829✔
2926

2927
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
45,829✔
2928
    char detail[1000] = {0};
45,829✔
2929
    (void)tsnprintf(detail, sizeof(detail), "enable:%d, superUser:%d, sysInfo:%d, password:xxx", createReq.enable,
45,829✔
2930
                    createReq.superUser, createReq.sysInfo);
45,829✔
2931
    char operation[15] = {0};
45,829✔
2932
    if (createReq.isImport == 1) {
45,829✔
2933
      tstrncpy(operation, "importUser", sizeof(operation));
×
2934
    } else {
2935
      tstrncpy(operation, "createUser", sizeof(operation));
45,829✔
2936
    }
2937

2938
    int64_t tse = taosGetTimestampMs();
45,829✔
2939
    double  duration = (double)(tse - tss);
45,829✔
2940
    duration = duration / 1000;
45,829✔
2941
    auditRecord(pReq, pMnode->clusterId, operation, "", createReq.user, detail, strlen(detail), duration, 0);
45,829✔
2942
  }
2943

2944
_OVER:
45,829✔
2945
  if (code == TSDB_CODE_MND_USER_ALREADY_EXIST && createReq.ignoreExists) {
45,829✔
2946
    code = 0;
×
2947
  } else if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
45,829✔
UNCOV
2948
    mError("user:%s, failed to create at line %d since %s", createReq.user, lino, tstrerror(code));
×
2949
  }
2950

2951
  mndReleaseRole(pMnode, pRole);
45,829✔
2952
  mndReleaseUser(pMnode, pUser);
45,829✔
2953
  mndReleaseUser(pMnode, pOperUser);
45,829✔
2954
  tFreeSCreateUserReq(&createReq);
45,829✔
2955

2956
  TAOS_RETURN(code);
45,829✔
2957
}
2958

2959

2960

2961
static int32_t mndProcessGetUserIpWhiteListReq(SRpcMsg *pReq) {
10,046✔
2962
  SMnode              *pMnode = pReq->info.node;
10,046✔
2963
  int32_t              code = 0;
10,046✔
2964
  int32_t              lino = 0;
10,046✔
2965
  int32_t              contLen = 0;
10,046✔
2966
  void                *pRsp = NULL;
10,046✔
2967
  SUserObj            *pUser = NULL;
10,046✔
2968
  SGetUserWhiteListReq wlReq = {0};
10,046✔
2969
  SGetUserIpWhiteListRsp wlRsp = {0};
10,046✔
2970

2971
  int32_t (*serialFn)(void *, int32_t, SGetUserIpWhiteListRsp *) = NULL;
10,046✔
2972
  int32_t (*setRspFn)(SMnode * pMnode, SUserObj * pUser, SGetUserIpWhiteListRsp * pRsp) = NULL;
10,046✔
2973

2974
  if (pReq->msgType == TDMT_MND_GET_USER_IP_WHITELIST_DUAL) {
10,046✔
2975
    serialFn = tSerializeSGetUserIpWhiteListDualRsp;
10,046✔
2976
    setRspFn = mndSetUserIpWhiteListDualRsp;
10,046✔
2977
  } else {
2978
    serialFn = tSerializeSGetUserIpWhiteListRsp;
×
UNCOV
2979
    setRspFn = mndSetUserIpWhiteListRsp;
×
2980
  }
2981
  if (tDeserializeSGetUserWhiteListReq(pReq->pCont, pReq->contLen, &wlReq) != 0) {
10,046✔
UNCOV
2982
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
2983
  }
2984
  mTrace("user: %s, start to get ip whitelist", wlReq.user);
10,046✔
2985

2986
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, wlReq.user, &pUser), &lino, _OVER);
10,046✔
2987
  TAOS_CHECK_GOTO(setRspFn(pMnode, pUser, &wlRsp), &lino, _OVER);
10,046✔
2988

2989
  contLen = serialFn(NULL, 0, &wlRsp);
10,046✔
2990
  if (contLen < 0) {
10,046✔
UNCOV
2991
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2992
  }
2993
  pRsp = rpcMallocCont(contLen);
10,046✔
2994
  if (pRsp == NULL) {
10,046✔
UNCOV
2995
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2996
  }
2997

2998
  contLen = serialFn(pRsp, contLen, &wlRsp);
10,046✔
2999
  if (contLen < 0) {
10,046✔
UNCOV
3000
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3001
  }
3002

3003
_OVER:
10,046✔
3004
  mndReleaseUser(pMnode, pUser);
10,046✔
3005
  tFreeSGetUserIpWhiteListDualRsp(&wlRsp);
10,046✔
3006
  if (code < 0) {
10,046✔
UNCOV
3007
    mError("user:%s, failed to get whitelist at line %d since %s", wlReq.user, lino, tstrerror(code));
×
UNCOV
3008
    rpcFreeCont(pRsp);
×
UNCOV
3009
    pRsp = NULL;
×
3010
    contLen = 0;
×
3011
  }
3012
  pReq->code = code;
10,046✔
3013
  pReq->info.rsp = pRsp;
10,046✔
3014
  pReq->info.rspLen = contLen;
10,046✔
3015

3016
  TAOS_RETURN(code);
10,046✔
3017
}
3018

3019

3020

3021
static int32_t buildRetrieveIpWhiteListRsp(SUpdateIpWhite *pUpdate) {
466✔
3022
  (void)taosThreadRwlockRdlock(&userCache.rw);
466✔
3023

3024
  int32_t count = taosHashGetSize(userCache.users);
466✔
3025
  pUpdate->pUserIpWhite = taosMemoryCalloc(count, sizeof(SUpdateUserIpWhite));
466✔
3026
  if (pUpdate->pUserIpWhite == NULL) {
466✔
UNCOV
3027
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
UNCOV
3028
    TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
3029
  }
3030

3031
  count = 0;
466✔
3032
  void   *pIter = taosHashIterate(userCache.users, NULL);
466✔
3033
  while (pIter) {
932✔
3034
    SIpWhiteListDual   *wl = (*(SCachedUserInfo**)pIter)->wlIp;
466✔
3035
    if (wl == NULL || wl->num <= 0) {
466✔
UNCOV
3036
      pIter = taosHashIterate(userCache.users, pIter);
×
UNCOV
3037
      continue;
×
3038
    }
3039

3040
    SUpdateUserIpWhite *pUser = &pUpdate->pUserIpWhite[count];
466✔
3041
    pUser->ver = userCache.verIp;
466✔
3042

3043
    size_t klen;
466✔
3044
    char  *key = taosHashGetKey(pIter, &klen);
466✔
3045
    (void)memcpy(pUser->user, key, klen);
466✔
3046

3047
    pUser->numOfRange = wl->num;
466✔
3048
    pUser->pIpRanges = taosMemoryCalloc(wl->num, sizeof(SIpRange));
466✔
3049
    if (pUser->pIpRanges == NULL) {
466✔
UNCOV
3050
      (void)taosThreadRwlockUnlock(&userCache.rw);
×
UNCOV
3051
      TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
3052
    }
3053

3054
    (void)memcpy(pUser->pIpRanges, wl->pIpRanges, wl->num * sizeof(SIpRange));
466✔
3055
    count++;
466✔
3056
    pIter = taosHashIterate(userCache.users, pIter);
466✔
3057
  }
3058

3059
  pUpdate->numOfUser = count;
466✔
3060
  pUpdate->ver = userCache.verIp;
466✔
3061
  (void)taosThreadRwlockUnlock(&userCache.rw);
466✔
3062
  TAOS_RETURN(0);
466✔
3063
}
3064

3065

3066

3067
int32_t mndProcessRetrieveIpWhiteListReq(SRpcMsg *pReq) {
466✔
3068
  int32_t        code = 0;
466✔
3069
  int32_t        lino = 0;
466✔
3070
  int32_t        len = 0;
466✔
3071
  void          *pRsp = NULL;
466✔
3072
  SUpdateIpWhite ipWhite = {0};
466✔
3073

3074
  // impl later
3075
  SRetrieveWhiteListReq req = {0};
466✔
3076
  if (tDeserializeRetrieveWhiteListReq(pReq->pCont, pReq->contLen, &req) != 0) {
466✔
UNCOV
3077
    code = TSDB_CODE_INVALID_MSG;
×
UNCOV
3078
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3079
  }
3080

3081
  int32_t (*fn)(void *, int32_t, SUpdateIpWhite *) = NULL;
466✔
3082
  if (pReq->msgType == TDMT_MND_RETRIEVE_IP_WHITELIST) {
466✔
UNCOV
3083
    fn = tSerializeSUpdateIpWhite;
×
3084
  } else if (pReq->msgType == TDMT_MND_RETRIEVE_IP_WHITELIST_DUAL) {
466✔
3085
    fn = tSerializeSUpdateIpWhiteDual;
466✔
3086
  }
3087

3088
  TAOS_CHECK_GOTO(buildRetrieveIpWhiteListRsp(&ipWhite), &lino, _OVER);
466✔
3089

3090
  len = fn(NULL, 0, &ipWhite);
466✔
3091
  if (len < 0) {
466✔
UNCOV
3092
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
3093
  }
3094

3095
  pRsp = rpcMallocCont(len);
466✔
3096
  if (!pRsp) {
466✔
UNCOV
3097
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3098
  }
3099
  len = fn(pRsp, len, &ipWhite);
466✔
3100
  if (len < 0) {
466✔
UNCOV
3101
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
3102
  }
3103

3104
_OVER:
466✔
3105
  if (code < 0) {
466✔
UNCOV
3106
    mError("failed to process retrieve ip white request at line %d since %s", lino, tstrerror(code));
×
UNCOV
3107
    rpcFreeCont(pRsp);
×
UNCOV
3108
    pRsp = NULL;
×
UNCOV
3109
    len = 0;
×
3110
  }
3111
  pReq->code = code;
466✔
3112
  pReq->info.rsp = pRsp;
466✔
3113
  pReq->info.rspLen = len;
466✔
3114

3115
  tFreeSUpdateIpWhiteReq(&ipWhite);
466✔
3116
  TAOS_RETURN(code);
466✔
3117
}
3118

3119
static int32_t mndAlterUser(SMnode *pMnode, SUserObj *pNew, SRpcMsg *pReq) {
950,915✔
3120
  int32_t code = 0, lino = 0;
950,915✔
3121
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "alter-user");
950,915✔
3122
  if (pTrans == NULL) {
950,915✔
UNCOV
3123
    mError("user:%s, failed to alter since %s", pNew->user, terrstr());
×
UNCOV
3124
    TAOS_RETURN(terrno);
×
3125
  }
3126
  mInfo("trans:%d, used to alter user:%s", pTrans->id, pNew->user);
950,915✔
3127

3128
  SSdbRaw *pCommitRaw = mndUserActionEncode(pNew);
950,915✔
3129
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
950,915✔
UNCOV
3130
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
UNCOV
3131
    mndTransDrop(pTrans);
×
UNCOV
3132
    TAOS_RETURN(terrno);
×
3133
  }
3134
  TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
950,915✔
3135

3136
  if (mndTransPrepare(pMnode, pTrans) != 0) {
950,915✔
UNCOV
3137
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
UNCOV
3138
    mndTransDrop(pTrans);
×
UNCOV
3139
    TAOS_RETURN(terrno);
×
3140
  }
3141
  if ((code = userCacheUpdateWhiteList(pMnode, pNew)) != 0) {
950,915✔
UNCOV
3142
    mndTransDrop(pTrans);
×
UNCOV
3143
    TAOS_RETURN(code);
×
3144
  }
3145
_exit:
950,915✔
3146
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
950,915✔
UNCOV
3147
    mError("user:%s, failed to alter at line %d since %s", pNew->user, lino, tstrerror(code));
×
3148
  }
3149
  mndTransDrop(pTrans);
950,915✔
3150
  TAOS_RETURN(code);
950,915✔
3151
}
3152

UNCOV
3153
static int32_t mndDupObjHash(SHashObj *pOld, int32_t dataLen, SHashObj **ppNew) {
×
UNCOV
3154
  int32_t code = 0;
×
3155

UNCOV
3156
  *ppNew =
×
UNCOV
3157
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
UNCOV
3158
  if (*ppNew == NULL) {
×
UNCOV
3159
    code = terrno ? terrno : TSDB_CODE_OUT_OF_MEMORY;
×
UNCOV
3160
    TAOS_RETURN(code);
×
3161
  }
3162

UNCOV
3163
  char *db = taosHashIterate(pOld, NULL);
×
UNCOV
3164
  while (db != NULL) {
×
UNCOV
3165
    int32_t len = strlen(db) + 1;
×
UNCOV
3166
    if ((code = taosHashPut(*ppNew, db, len, db, dataLen)) != 0) {
×
UNCOV
3167
      taosHashCancelIterate(pOld, db);
×
UNCOV
3168
      taosHashCleanup(*ppNew);
×
UNCOV
3169
      TAOS_RETURN(code);
×
3170
    }
UNCOV
3171
    db = taosHashIterate(pOld, db);
×
3172
  }
3173

3174
  TAOS_RETURN(code);
×
3175
}
3176

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

UNCOV
3179
int32_t mndDupTopicHash(SHashObj *pOld, SHashObj **ppNew) { return mndDupObjHash(pOld, TSDB_TOPIC_FNAME_LEN, ppNew); }
×
3180

UNCOV
3181
static int32_t mndTablePriviledge(SMnode *pMnode, SHashObj *hash, SHashObj *useDbHash, SAlterUserReq *alterReq,
×
3182
                                  SSdb *pSdb) {
UNCOV
3183
  void *pIter = NULL;
×
UNCOV
3184
  char  tbFName[TSDB_TABLE_FNAME_LEN] = {0};
×
3185

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

UNCOV
3189
  if (alterReq->tagCond != NULL && alterReq->tagCondLen != 0) {
×
UNCOV
3190
    char *value = taosHashGet(hash, tbFName, len);
×
UNCOV
3191
    if (value != NULL) {
×
UNCOV
3192
      TAOS_RETURN(TSDB_CODE_MND_PRIVILEGE_EXIST);
×
3193
    }
3194

3195
    int32_t condLen = alterReq->tagCondLen;
×
3196
    TAOS_CHECK_RETURN(taosHashPut(hash, tbFName, len, alterReq->tagCond, condLen));
×
3197
  } else {
3198
    TAOS_CHECK_RETURN(taosHashPut(hash, tbFName, len, alterReq->isView ? "v" : "t", 2));
×
3199
  }
3200

UNCOV
3201
  int32_t  dbKeyLen = strlen(alterReq->objname) + 1;
×
UNCOV
3202
  int32_t  ref = 1;
×
UNCOV
3203
  int32_t *currRef = taosHashGet(useDbHash, alterReq->objname, dbKeyLen);
×
UNCOV
3204
  if (NULL != currRef) {
×
UNCOV
3205
    ref = (*currRef) + 1;
×
3206
  }
UNCOV
3207
  TAOS_CHECK_RETURN(taosHashPut(useDbHash, alterReq->objname, dbKeyLen, &ref, sizeof(ref)));
×
3208

UNCOV
3209
  TAOS_RETURN(0);
×
3210
}
3211

UNCOV
3212
static int32_t mndRemoveTablePriviledge(SMnode *pMnode, SHashObj *hash, SHashObj *useDbHash, SAlterUserReq *alterReq,
×
3213
                                        SSdb *pSdb) {
UNCOV
3214
  void *pIter = NULL;
×
UNCOV
3215
  char  tbFName[TSDB_TABLE_FNAME_LEN] = {0};
×
UNCOV
3216
  (void)snprintf(tbFName, sizeof(tbFName), "%s.%s", alterReq->objname, alterReq->tabName);
×
UNCOV
3217
  int32_t len = strlen(tbFName) + 1;
×
3218

UNCOV
3219
  if (taosHashRemove(hash, tbFName, len) != 0) {
×
UNCOV
3220
    TAOS_RETURN(0);  // not found
×
3221
  }
3222

3223
  int32_t  dbKeyLen = strlen(alterReq->objname) + 1;
×
3224
  int32_t *currRef = taosHashGet(useDbHash, alterReq->objname, dbKeyLen);
×
UNCOV
3225
  if (NULL == currRef) {
×
UNCOV
3226
    return 0;
×
3227
  }
3228

3229
  if (1 == *currRef) {
×
UNCOV
3230
    if (taosHashRemove(useDbHash, alterReq->objname, dbKeyLen) != 0) {
×
UNCOV
3231
      TAOS_RETURN(0);  // not found
×
3232
    }
3233
    return 0;
×
3234
  }
UNCOV
3235
  int32_t ref = (*currRef) - 1;
×
UNCOV
3236
  TAOS_CHECK_RETURN(taosHashPut(useDbHash, alterReq->objname, dbKeyLen, &ref, sizeof(ref)));
×
3237

3238
  return 0;
×
3239
}
3240

3241

3242
#if 0
3243
static int32_t mndProcessAlterUserPrivilegesReq(SRpcMsg* pReq, SAlterUserReq *pAlterReq) {
3244
  SMnode   *pMnode = pReq->info.node;
3245
  SSdb     *pSdb = pMnode->pSdb;
3246
  int32_t   code = 0, lino = 0;
3247
  SUserObj *pUser = NULL;
3248
  SUserObj  newUser = {0};
3249
  int64_t   tss = taosGetTimestampMs();
3250

3251
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, pAlterReq->user, &pUser), &lino, _OVER);
3252
  TAOS_CHECK_GOTO(mndCheckAlterUserPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser, pAlterReq), &lino, _OVER);
3253
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
3254

3255
#if 0
3256
  if (ALTER_USER_ADD_READ_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName) ||
3257
      ALTER_USER_ADD_ALL_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName)) {
3258
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
3259
      int32_t len = strlen(pAlterReq->objname) + 1;
3260
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
3261
      if (pDb == NULL) {
3262
        mndReleaseDb(pMnode, pDb);
3263
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
3264
      }
3265
      if ((code = taosHashPut(newUser.readDbs, pAlterReq->objname, len, pAlterReq->objname, TSDB_DB_FNAME_LEN)) !=
3266
          0) {
3267
        mndReleaseDb(pMnode, pDb);
3268
        TAOS_CHECK_GOTO(code, &lino, _OVER);
3269
      }
3270
      mndReleaseDb(pMnode, pDb);
3271
    } else {
3272
      void   *pIter = NULL;
3273
      while (1) {
3274
        SDbObj *pDb = NULL;
3275
        pIter = sdbFetch(pSdb, SDB_DB, pIter, (void **)&pDb);
3276
        if (pIter == NULL) break;
3277
        int32_t len = strlen(pDb->name) + 1;
3278
        if ((code = taosHashPut(newUser.readDbs, pDb->name, len, pDb->name, TSDB_DB_FNAME_LEN)) != 0) {
3279
          sdbRelease(pSdb, pDb);
3280
          sdbCancelFetch(pSdb, pIter);
3281
          TAOS_CHECK_GOTO(code, &lino, _OVER);
3282
        }
3283
        sdbRelease(pSdb, pDb);
3284
      }
3285
    }
3286
  }
3287

3288
  if (ALTER_USER_ADD_WRITE_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName) ||
3289
      ALTER_USER_ADD_ALL_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName)) {
3290
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
3291
      int32_t len = strlen(pAlterReq->objname) + 1;
3292
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
3293
      if (pDb == NULL) {
3294
        mndReleaseDb(pMnode, pDb);
3295
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
3296
      }
3297
      if ((code = taosHashPut(newUser.writeDbs, pAlterReq->objname, len, pAlterReq->objname, TSDB_DB_FNAME_LEN)) !=
3298
          0) {
3299
        mndReleaseDb(pMnode, pDb);
3300
        TAOS_CHECK_GOTO(code, &lino, _OVER);
3301
      }
3302
      mndReleaseDb(pMnode, pDb);
3303
    } else {
3304
      void   *pIter = NULL;
3305
      while (1) {
3306
        SDbObj *pDb = NULL;
3307
        pIter = sdbFetch(pSdb, SDB_DB, pIter, (void **)&pDb);
3308
        if (pIter == NULL) break;
3309
        int32_t len = strlen(pDb->name) + 1;
3310
        if ((code = taosHashPut(newUser.writeDbs, pDb->name, len, pDb->name, TSDB_DB_FNAME_LEN)) != 0) {
3311
          sdbRelease(pSdb, pDb);
3312
          sdbCancelFetch(pSdb, pIter);
3313
          TAOS_CHECK_GOTO(code, &lino, _OVER);
3314
        }
3315
        sdbRelease(pSdb, pDb);
3316
      }
3317
    }
3318
  }
3319

3320
  if (ALTER_USER_DEL_READ_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName) ||
3321
      ALTER_USER_DEL_ALL_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName)) {
3322
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
3323
      int32_t len = strlen(pAlterReq->objname) + 1;
3324
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
3325
      if (pDb == NULL) {
3326
        mndReleaseDb(pMnode, pDb);
3327
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
3328
      }
3329
      code = taosHashRemove(newUser.readDbs, pAlterReq->objname, len);
3330
      if (code < 0) {
3331
        mError("read db:%s, failed to remove db:%s since %s", newUser.user, pAlterReq->objname, terrstr());
3332
      }
3333
      mndReleaseDb(pMnode, pDb);
3334
    } else {
3335
      taosHashClear(newUser.readDbs);
3336
    }
3337
  }
3338

3339
  if (ALTER_USER_DEL_WRITE_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName) ||
3340
      ALTER_USER_DEL_ALL_DB_PRIV(pAlterReq->alterType, &pAlterReq->privileges, pAlterReq->tabName)) {
3341
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
3342
      int32_t len = strlen(pAlterReq->objname) + 1;
3343
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
3344
      if (pDb == NULL) {
3345
        mndReleaseDb(pMnode, pDb);
3346
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
3347
      }
3348
      code = taosHashRemove(newUser.writeDbs, pAlterReq->objname, len);
3349
      if (code < 0) {
3350
        mError("user:%s, failed to remove db:%s since %s", newUser.user, pAlterReq->objname, terrstr());
3351
      }
3352
      mndReleaseDb(pMnode, pDb);
3353
    } else {
3354
      taosHashClear(newUser.writeDbs);
3355
    }
3356
  }
3357

3358
  SHashObj *pReadTbs = newUser.readTbs;
3359
  SHashObj *pWriteTbs = newUser.writeTbs;
3360
  SHashObj *pAlterTbs = newUser.alterTbs;
3361

3362
#ifdef TD_ENTERPRISE
3363
  if (pAlterReq->isView) {
3364
    pReadTbs = newUser.readViews;
3365
    pWriteTbs = newUser.writeViews;
3366
    pAlterTbs = newUser.alterViews;
3367
  }
3368
#endif
3369

3370
  if (ALTER_USER_ADD_READ_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3371
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3372
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pReadTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3373
  }
3374

3375
  if (ALTER_USER_ADD_WRITE_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3376
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3377
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pWriteTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3378
  }
3379

3380
  if (ALTER_USER_ADD_ALTER_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3381
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3382
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pAlterTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3383
  }
3384

3385
  if (ALTER_USER_DEL_READ_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3386
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3387
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pReadTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3388
  }
3389

3390
  if (ALTER_USER_DEL_WRITE_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3391
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3392
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pWriteTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3393
  }
3394

3395
  if (ALTER_USER_DEL_ALTER_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3396
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3397
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pAlterTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3398
  }
3399
#endif
3400

3401
#if 0
3402
// #ifdef USE_TOPIC
3403
  if (ALTER_USER_ADD_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, &pAlterReq->privileges)) {
3404
    int32_t      len = strlen(pAlterReq->objname) + 1;
3405
    SMqTopicObj *pTopic = NULL;
3406
    if ((code = mndAcquireTopic(pMnode, pAlterReq->objname, &pTopic)) != 0) {
3407
      TAOS_CHECK_GOTO(code, &lino, _OVER);
3408
    }
3409
    taosRLockLatch(&pTopic->lock);
3410
    code = taosHashPut(newUser.topics, pTopic->name, len, pTopic->name, TSDB_TOPIC_FNAME_LEN);
3411
    taosRUnLockLatch(&pTopic->lock);
3412
    mndReleaseTopic(pMnode, pTopic);
3413
    TAOS_CHECK_GOTO(code, &lino, _OVER);
3414
  }
3415

3416
  if (ALTER_USER_DEL_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, &pAlterReq->privileges)) {
3417
    int32_t      len = strlen(pAlterReq->objname) + 1;
3418
    SMqTopicObj *pTopic = NULL;
3419
    if ((code = mndAcquireTopic(pMnode, pAlterReq->objname, &pTopic)) != 0) {
3420
      TAOS_CHECK_GOTO(code, &lino, _OVER);
3421
    }
3422
    taosRLockLatch(&pTopic->lock);
3423
    code = taosHashRemove(newUser.topics, pAlterReq->objname, len);
3424
    if (code < 0) {
3425
      mError("user:%s, failed to remove topic:%s since %s", newUser.user, pAlterReq->objname, tstrerror(code));
3426
    }
3427
    taosRUnLockLatch(&pTopic->lock);
3428
    mndReleaseTopic(pMnode, pTopic);
3429
  }
3430
#endif
3431

3432
  TAOS_CHECK_GOTO(mndAlterUser(pMnode, &newUser, pReq), &lino, _OVER);
3433
  code = TSDB_CODE_ACTION_IN_PROGRESS;
3434

3435
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
3436
    int64_t tse = taosGetTimestampMs();
3437
    double  duration = (double)(tse - tss);
3438
    duration = duration / 1000;
3439
    if (ALTER_USER_ADD_READ_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3440
              ALTER_USER_ADD_WRITE_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3441
              ALTER_USER_ADD_ALL_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3442
              ALTER_USER_ADD_READ_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3443
              ALTER_USER_ADD_WRITE_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3444
              ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3445
      if (strcmp(pAlterReq->objname, "1.*") != 0) {
3446
        SName name = {0};
3447
        TAOS_CHECK_GOTO(tNameFromString(&name, pAlterReq->objname, T_NAME_ACCT | T_NAME_DB), &lino, _OVER);
3448
        auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", name.dbname, pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
3449
      } else {
3450
        auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", "", pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
3451
      }
3452
    } else if (ALTER_USER_ADD_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, pAlterReq->privileges)) {
3453
      auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", pAlterReq->objname, pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
3454
    } else if (ALTER_USER_DEL_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, pAlterReq->privileges)) {
3455
      auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", pAlterReq->objname, pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
3456
    } else {
3457
      if (strcmp(pAlterReq->objname, "1.*") != 0) {
3458
        SName name = {0};
3459
        TAOS_CHECK_GOTO(tNameFromString(&name, pAlterReq->objname, T_NAME_ACCT | T_NAME_DB), &lino, _OVER);
3460
        auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", name.dbname, pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
3461
      } else {
3462
        auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", "", pAlterReq->user, pAlterReq->sql, pAlterReq->sqlLen, duration, 0);
3463
      }
3464
    }
3465
  }
3466
  
3467
_OVER:
3468
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
3469
    mError("user:%s, failed to alter user privileges at line %d since %s", pAlterReq->user, lino, tstrerror(code));
3470
  }
3471
  mndReleaseUser(pMnode, pUser);
3472
  mndUserFreeObj(&newUser);
3473
  TAOS_RETURN(code);
3474
}
3475
#endif
3476

3477
#ifdef TD_ENTERPRISE
3478
extern int32_t mndAlterUserPrivInfo(SMnode *pMnode, SUserObj *pOperUser, SUserObj *pOld, SUserObj *pNew, SAlterRoleReq *pAlterReq);
3479
extern int32_t mndAlterUserRoleInfo(SMnode *pMnode, SUserObj *pOperUser, SUserObj *pOld, SUserObj *pNew, SAlterRoleReq *pAlterReq);
3480
#endif
3481

3482
int32_t mndAlterUserFromRole(SRpcMsg *pReq, SUserObj *pOperUser, SAlterRoleReq *pAlterReq) {
942,517✔
3483
  SMnode   *pMnode = pReq->info.node;
942,517✔
3484
  SSdb     *pSdb = pMnode->pSdb;
942,517✔
3485
  void     *pIter = NULL;
942,517✔
3486
  int32_t   code = 0, lino = 0;
942,517✔
3487
  SUserObj *pUser = NULL;
942,517✔
3488
  SUserObj  newUser = {0};
942,517✔
3489

3490
  TAOS_CHECK_EXIT(mndAcquireUser(pMnode, pAlterReq->principal, &pUser));
942,517✔
3491

3492
  if (pUser->enable == 0) {
941,579✔
UNCOV
3493
    TAOS_CHECK_EXIT(TSDB_CODE_MND_USER_DISABLED);
×
3494
  }
3495

3496
  if (pAlterReq->alterType == TSDB_ALTER_ROLE_PRIVILEGES) {
941,579✔
3497
#ifdef TD_ENTERPRISE
3498
    TAOS_CHECK_EXIT(mndUserDupObj(pUser, &newUser));
938,209✔
3499
    if ((code = mndAlterUserPrivInfo(pMnode, pOperUser, pUser, &newUser, pAlterReq)) == TSDB_CODE_QRY_DUPLICATED_OPERATION) {
938,209✔
3500
      code = 0;
×
3501
      goto _exit;
×
3502
    } else {
3503
      TAOS_CHECK_EXIT(code);
938,209✔
3504
    }
3505
  } else if (pAlterReq->alterType == TSDB_ALTER_ROLE_ROLE) {
3,370✔
3506
    if ((code = mndAlterUserRoleInfo(pMnode, pOperUser, pUser, &newUser, pAlterReq)) == TSDB_CODE_QRY_DUPLICATED_OPERATION) {
3,370✔
3507
      code = 0;
150✔
3508
      goto _exit;
150✔
3509
    } else {
3510
      TAOS_CHECK_EXIT(code);
3,220✔
3511
    }
3512
#endif
3513
  } else {
UNCOV
3514
    TAOS_CHECK_EXIT(TSDB_CODE_INVALID_MSG);
×
3515
  }
3516
  code = mndAlterUser(pMnode, &newUser, pReq);
940,979✔
3517
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
940,979✔
3518

3519
_exit:
942,517✔
3520
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
942,517✔
3521
    mError("user:%s, failed to alter user at line %d since %s", pAlterReq->principal, lino, tstrerror(code));
1,388✔
3522
  }
3523
  mndReleaseUser(pMnode, pUser);
942,517✔
3524
  mndUserFreeObj(&newUser);
942,517✔
3525
  TAOS_RETURN(code);
942,517✔
3526
}
3527

3528

3529
static int32_t mndProcessAlterUserBasicInfoReq(SRpcMsg *pReq, SAlterUserReq *pAlterReq) {
12,468✔
3530
  SMnode       *pMnode = pReq->info.node;
12,468✔
3531
  int32_t       code = 0, lino = 0;
12,468✔
3532
  SUserObj     *pUser = NULL;
12,468✔
3533
  SUserObj      newUser = {0};
12,468✔
3534
  char          auditLog[1000] = {0};
12,468✔
3535
  int32_t       auditLen = 0;
12,468✔
3536
  int64_t       tss = taosGetTimestampMs();
12,468✔
3537

3538
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, pAlterReq->user, &pUser), &lino, _OVER);
12,468✔
3539
  TAOS_CHECK_GOTO(mndCheckAlterUserPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser, pAlterReq), &lino, _OVER);
11,812✔
3540
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
10,093✔
3541

3542
  if (pAlterReq->hasPassword) {
10,093✔
3543
    auditLen += tsnprintf(auditLog, sizeof(auditLog), "password,");
4,160✔
3544

3545
    TAOS_CHECK_GOTO(mndCheckPasswordFmt(pAlterReq->pass), &lino, _OVER);
4,160✔
3546
    if (newUser.salt[0] == 0) {
4,160✔
3547
      generateSalt(newUser.salt, sizeof(newUser.salt));
314✔
3548
    }
3549
    char pass[TSDB_PASSWORD_LEN] = {0};
4,160✔
3550
    taosEncryptPass_c((uint8_t *)pAlterReq->pass, strlen(pAlterReq->pass), pass);
4,160✔
3551
    pass[sizeof(pass) - 1] = 0;
4,160✔
3552
    TAOS_CHECK_GOTO(mndEncryptPass(pass, newUser.salt, &newUser.passEncryptAlgorithm), &lino, _OVER);
4,160✔
3553

3554
    if (newUser.passwordReuseMax > 0 || newUser.passwordReuseTime > 0) {
4,160✔
3555
      for(int32_t i = 0; i < newUser.numOfPasswords; ++i) {
10,933✔
3556
        if (0 == strncmp(newUser.passwords[i].pass, pass, TSDB_PASSWORD_LEN)) {
7,743✔
3557
          TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_PASSWORD_REUSE, &lino, _OVER);
157✔
3558
        }
3559
      }
3560
      SUserPassword *passwords = taosMemoryCalloc(newUser.numOfPasswords + 1, sizeof(SUserPassword));
3,190✔
3561
      if (passwords == NULL) {
3,190✔
UNCOV
3562
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3563
      }
3564
      memcpy(passwords + 1, newUser.passwords, newUser.numOfPasswords * sizeof(SUserPassword));
3,190✔
3565
      memcpy(passwords[0].pass, pass, TSDB_PASSWORD_LEN);
3,190✔
3566
      passwords[0].setTime = taosGetTimestampSec();
3,190✔
3567
      taosMemoryFree(newUser.passwords);
3,190✔
3568
      newUser.passwords = passwords;
3,190✔
3569
      ++newUser.numOfPasswords;
3,190✔
3570
      ++newUser.passVersion;
3,190✔
3571
      newUser.changePass = 2;
3,190✔
3572
    } else if (0 != strncmp(newUser.passwords[0].pass, pass, TSDB_PASSWORD_LEN)) {
813✔
3573
      memcpy(newUser.passwords[0].pass, pass, TSDB_PASSWORD_LEN);
314✔
3574
      newUser.passwords[0].setTime = taosGetTimestampSec();
314✔
3575
      ++newUser.passVersion;
314✔
3576
      newUser.changePass = 2;
314✔
3577
    }
3578
  }
3579

3580
  if (pAlterReq->hasTotpseed) {
9,936✔
UNCOV
3581
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "totpseed,");
×
3582

UNCOV
3583
    if (pAlterReq->totpseed[0] == 0) { // clear totp secret
×
UNCOV
3584
      memset(newUser.totpsecret, 0, sizeof(newUser.totpsecret));
×
UNCOV
3585
    } else if (taosGenerateTotpSecret(pAlterReq->totpseed, 0, newUser.totpsecret, sizeof(newUser.totpsecret)) < 0) {
×
UNCOV
3586
      TAOS_CHECK_GOTO(TSDB_CODE_PAR_INVALID_OPTION_VALUE, &lino, _OVER);
×
3587
    }
3588
  }
3589

3590
  if (pAlterReq->hasEnable) {
9,936✔
3591
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "enable:%d,", pAlterReq->enable);
656✔
3592

3593
    newUser.enable = pAlterReq->enable; // lock or unlock user manually
656✔
3594
    if (newUser.enable) {
656✔
3595
      // reset login info to allow login immediately
3596
      userCacheResetLoginInfo(newUser.user);
499✔
3597
    }
3598
  }
3599

3600
  if (pAlterReq->hasSysinfo) {
9,936✔
3601
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "sysinfo:%d,", pAlterReq->sysinfo);
3,425✔
3602
    newUser.sysInfo = pAlterReq->sysinfo;
3,425✔
3603
  }
3604

3605
  if (pAlterReq->hasCreatedb) {
9,936✔
3606
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "createdb:%d,", pAlterReq->createdb);
1,542✔
3607
    newUser.createdb = pAlterReq->createdb;
1,542✔
3608
  }
3609

3610
  if (pAlterReq->hasChangepass) {
9,936✔
UNCOV
3611
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "changepass:%d,", pAlterReq->changepass);
×
UNCOV
3612
    newUser.changePass = pAlterReq->changepass;
×
3613
  }
3614

3615
  if (pAlterReq->hasSessionPerUser) {
9,936✔
UNCOV
3616
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "sessionPerUser:%d,", pAlterReq->sessionPerUser);
×
UNCOV
3617
    newUser.sessionPerUser = pAlterReq->sessionPerUser;
×
3618
  }
3619

3620
  if (pAlterReq->hasConnectTime) {
9,936✔
3621
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "connectTime:%d,", pAlterReq->connectTime);
×
UNCOV
3622
    newUser.connectTime = pAlterReq->connectTime;
×
3623
  }
3624
  
3625
  if (pAlterReq->hasConnectIdleTime) {
9,936✔
UNCOV
3626
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "connectIdleTime:%d,", pAlterReq->connectIdleTime);
×
UNCOV
3627
    newUser.connectIdleTime = pAlterReq->connectIdleTime;
×
3628
  }
3629

3630
  if (pAlterReq->hasCallPerSession) {
9,936✔
UNCOV
3631
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "callPerSession:%d,", pAlterReq->callPerSession);
×
UNCOV
3632
    newUser.callPerSession = pAlterReq->callPerSession;
×
3633
  }
3634

3635
  if (pAlterReq->hasVnodePerCall) {
9,936✔
UNCOV
3636
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "vnodePerCall:%d,", pAlterReq->vnodePerCall);
×
UNCOV
3637
    newUser.vnodePerCall = pAlterReq->vnodePerCall;
×
3638
  }
3639

3640
  if (pAlterReq->hasFailedLoginAttempts) {
9,936✔
UNCOV
3641
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "failedLoginAttempts:%d,", pAlterReq->failedLoginAttempts);
×
UNCOV
3642
    newUser.failedLoginAttempts = pAlterReq->failedLoginAttempts;
×
3643
  }
3644

3645
  if (pAlterReq->hasPasswordLifeTime) {
9,936✔
UNCOV
3646
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordLifeTime:%d,", pAlterReq->passwordLifeTime);
×
UNCOV
3647
    newUser.passwordLifeTime = pAlterReq->passwordLifeTime;
×
3648
  }
3649

3650
  if (pAlterReq->hasPasswordReuseTime) {
9,936✔
UNCOV
3651
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordReuseTime:%d,", pAlterReq->passwordReuseTime);
×
UNCOV
3652
    newUser.passwordReuseTime = pAlterReq->passwordReuseTime;
×
3653
  }
3654

3655
  if (pAlterReq->hasPasswordReuseMax) {
9,936✔
UNCOV
3656
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordReuseMax:%d,", pAlterReq->passwordReuseMax);
×
UNCOV
3657
    newUser.passwordReuseMax = pAlterReq->passwordReuseMax;
×
3658
  }
3659

3660
  if (pAlterReq->hasPasswordLockTime) {
9,936✔
UNCOV
3661
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordLockTime:%d,", pAlterReq->passwordLockTime);
×
UNCOV
3662
    newUser.passwordLockTime = pAlterReq->passwordLockTime;
×
3663
  }
3664

3665
  if (pAlterReq->hasPasswordGraceTime) {
9,936✔
UNCOV
3666
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordGraceTime:%d,", pAlterReq->passwordGraceTime);
×
UNCOV
3667
    newUser.passwordGraceTime = pAlterReq->passwordGraceTime;
×
3668
  }
3669

3670
  if (pAlterReq->hasInactiveAccountTime) {
9,936✔
UNCOV
3671
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "inactiveAccountTime:%d,", pAlterReq->inactiveAccountTime);
×
UNCOV
3672
    newUser.inactiveAccountTime = pAlterReq->inactiveAccountTime;
×
3673
  }
3674

3675
  if (pAlterReq->hasAllowTokenNum) {
9,936✔
UNCOV
3676
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "allowTokenNum:%d,", pAlterReq->allowTokenNum);
×
UNCOV
3677
    newUser.allowTokenNum = pAlterReq->allowTokenNum;
×
3678
  }
3679

3680
  if (pAlterReq->numDropIpRanges > 0 || pAlterReq->numIpRanges > 0) {
9,936✔
3681
    int32_t dummy = 0;
310✔
3682

3683
    // put previous ip whitelist into hash table
3684
    SHashObj *m = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
310✔
3685
    if (m == NULL) {
310✔
UNCOV
3686
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3687
    }
3688

3689
    for (int32_t i = 0; i < newUser.pIpWhiteListDual->num; i++) {
1,085✔
3690
      SIpRange range;
775✔
3691
      copyIpRange(&range, newUser.pIpWhiteListDual->pIpRanges + i);
775✔
3692
      code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
775✔
3693
      if (code != 0) {
775✔
UNCOV
3694
        taosHashCleanup(m);
×
UNCOV
3695
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3696
      }
3697
    }
3698

3699
    if (pAlterReq->numDropIpRanges > 0) {
310✔
3700
      auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "dropIpRanges:%d,", pAlterReq->numDropIpRanges);
155✔
3701

3702
      for (int32_t i = 0; i < pAlterReq->numDropIpRanges; i++) {
310✔
3703
        if (taosHashGetSize(m) == 0) {
155✔
UNCOV
3704
          break;
×
3705
        }
3706

3707
        SIpRange range;
155✔
3708
        copyIpRange(&range, pAlterReq->pDropIpRanges + i);
155✔
3709

3710
        // for white list, drop default ip ranges is allowed, otherwise, we can never
3711
        // convert white list to black list.
3712

3713
        code = taosHashRemove(m, &range, sizeof(range));
155✔
3714
        if (code == TSDB_CODE_NOT_FOUND) {
155✔
3715
          // treat not exist as success
3716
          code = 0;
155✔
3717
        }
3718
        if (code != 0) {
155✔
UNCOV
3719
          taosHashCleanup(m);
×
UNCOV
3720
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3721
        }
3722
      }
3723
    }
3724

3725
    if (pAlterReq->numIpRanges > 0) {
310✔
3726
      auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "addIpRanges:%d,", pAlterReq->numIpRanges);
155✔
3727
      for (int32_t i = 0; i < pAlterReq->numIpRanges; i++) {
310✔
3728
        SIpRange range;
155✔
3729
        copyIpRange(&range, pAlterReq->pIpRanges + i);
155✔
3730
        code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
155✔
3731
        if (code != 0) {
155✔
UNCOV
3732
          taosHashCleanup(m);
×
UNCOV
3733
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3734
        }
3735
      }
3736
    }
3737

3738
    int32_t numOfRanges = taosHashGetSize(m);
310✔
3739
    if (numOfRanges > MND_MAX_USER_IP_RANGE) {
310✔
UNCOV
3740
      taosHashCleanup(m);
×
UNCOV
3741
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_IP_RANGE, &lino, _OVER);
×
3742
    }
3743

3744
    SIpWhiteListDual *p = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + numOfRanges * sizeof(SIpRange));
310✔
3745
    if (p == NULL) {
310✔
UNCOV
3746
      taosHashCleanup(m);
×
UNCOV
3747
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3748
    }
3749

3750
    void *pIter = taosHashIterate(m, NULL);
310✔
3751
    int32_t i = 0;
310✔
3752
    while (pIter) {
1,240✔
3753
      size_t len = 0;
930✔
3754
      SIpRange *key = taosHashGetKey(pIter, &len);
930✔
3755
      memcpy(p->pIpRanges + i, key, sizeof(SIpRange));
930✔
3756
      pIter = taosHashIterate(m, pIter);
930✔
3757
      i++;
930✔
3758
    }
3759

3760
    taosHashCleanup(m);
310✔
3761
    p->num = numOfRanges;
310✔
3762
    taosMemoryFreeClear(newUser.pIpWhiteListDual);
310✔
3763
    sortIpWhiteList(p);
310✔
3764
    newUser.pIpWhiteListDual = p;
310✔
3765

3766
    newUser.ipWhiteListVer++;
310✔
3767
  }
3768

3769

3770
  if (pAlterReq->numTimeRanges > 0 || pAlterReq->numDropTimeRanges) {
9,936✔
3771
    int32_t dummy = 0;
×
3772

3773
    // put previous ip whitelist into hash table
3774
    SHashObj *m = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
×
3775
    if (m == NULL) {
×
3776
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3777
    }
3778

3779
    for (int32_t i = 0; i < newUser.pTimeWhiteList->num; i++) {
×
UNCOV
3780
      SDateTimeWhiteListItem *range = &newUser.pTimeWhiteList->ranges[i];
×
3781
      if (isDateTimeWhiteListItemExpired(range)) {
×
3782
        continue;
×
3783
      }
UNCOV
3784
      code = taosHashPut(m, range, sizeof(*range), &dummy, sizeof(dummy));
×
3785
      if (code != 0) {
×
3786
        taosHashCleanup(m);
×
3787
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3788
      }
3789
    }
3790

3791
    if (pAlterReq->numDropTimeRanges > 0) {
×
3792
      auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "dropTimeRanges:%d,", pAlterReq->numDropTimeRanges);
×
3793
      for (int32_t i = 0; i < pAlterReq->numDropTimeRanges; i++) {
×
UNCOV
3794
        if (taosHashGetSize(m) == 0) {
×
3795
          break;
×
3796
        }
3797
        SDateTimeWhiteListItem range = { 0 };
×
UNCOV
3798
        DateTimeRangeToWhiteListItem(&range, pAlterReq->pDropTimeRanges + i);
×
3799

3800
        code = taosHashRemove(m, &range, sizeof(range));
×
3801
        if (code == TSDB_CODE_NOT_FOUND) {
×
3802
          // treat not exist as success
3803
          code = 0;
×
3804
        }
3805
        if (code != 0) {
×
3806
          taosHashCleanup(m);
×
UNCOV
3807
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3808
        }
3809
      }
3810
    }
3811

3812
    if (pAlterReq->numTimeRanges > 0) {
×
3813
      auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "addTimeRanges:%d,", pAlterReq->numTimeRanges);
×
3814
      for (int32_t i = 0; i < pAlterReq->numTimeRanges; i++) {
×
3815
        SDateTimeWhiteListItem range = { 0 };
×
UNCOV
3816
        DateTimeRangeToWhiteListItem(&range, pAlterReq->pTimeRanges + i);
×
3817
        if (isDateTimeWhiteListItemExpired(&range)) {
×
3818
          continue;
×
3819
        }
UNCOV
3820
        code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
×
3821
        if (code != 0) {
×
3822
          taosHashCleanup(m);
×
3823
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3824
        }
3825
      }
3826
    }
3827

3828
    int32_t numOfRanges = taosHashGetSize(m);
×
3829
    if (numOfRanges > MND_MAX_USER_TIME_RANGE) {
×
UNCOV
3830
      taosHashCleanup(m);
×
3831
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_TIME_RANGE, &lino, _OVER);
×
3832
    }
3833

UNCOV
3834
    SDateTimeWhiteList *p = taosMemoryCalloc(1, sizeof(SDateTimeWhiteList) + numOfRanges * sizeof(SDateTimeWhiteListItem));
×
3835
    if (p == NULL) {
×
3836
      taosHashCleanup(m);
×
3837
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3838
    }
3839

3840
    void *pIter = taosHashIterate(m, NULL);
×
3841
    int32_t i = 0;
×
UNCOV
3842
    while (pIter) {
×
UNCOV
3843
      size_t len = 0;
×
UNCOV
3844
      SDateTimeWhiteListItem *key = taosHashGetKey(pIter, &len);
×
UNCOV
3845
      memcpy(&p->ranges[i], key, sizeof(SDateTimeWhiteListItem));
×
UNCOV
3846
      pIter = taosHashIterate(m, pIter);
×
UNCOV
3847
      i++;
×
3848
    }
3849

3850
    taosHashCleanup(m);
×
3851
    p->num = numOfRanges;
×
UNCOV
3852
    taosMemoryFreeClear(newUser.pTimeWhiteList);
×
3853
    sortTimeWhiteList(p);
×
3854
    newUser.pTimeWhiteList = p;
×
3855
    newUser.timeWhiteListVer++;
×
3856
  }
3857

3858
  TAOS_CHECK_GOTO(mndAlterUser(pMnode, &newUser, pReq), &lino, _OVER);
9,936✔
3859
  code = TSDB_CODE_ACTION_IN_PROGRESS;
9,936✔
3860

3861
  if (auditLen > 0) {
9,936✔
3862
    auditLog[--auditLen] = 0; // remove last ','
9,936✔
3863
  }
3864
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
9,936✔
3865
    int64_t tse = taosGetTimestampMs();
9,936✔
3866
    double  duration = (double)(tse - tss);
9,936✔
3867
    duration = duration / 1000;
9,936✔
3868
    auditRecord(pReq, pMnode->clusterId, "alterUser", "", pAlterReq->user, auditLog, auditLen, duration, 0);
9,936✔
3869
  }
3870

3871
_OVER:
12,468✔
3872
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
12,468✔
3873
    mError("user:%s, failed to alter at line %d since %s", pAlterReq->user, lino, tstrerror(code));
2,532✔
3874
  }
3875

3876
  mndReleaseUser(pMnode, pUser);
12,468✔
3877
  mndUserFreeObj(&newUser);
12,468✔
3878
  return code;
12,468✔
3879
}
3880

3881

3882

3883
static int32_t mndProcessAlterUserReq(SRpcMsg *pReq) {
12,468✔
3884
  SAlterUserReq alterReq = {0};
12,468✔
3885

3886
  int32_t code = tDeserializeSAlterUserReq(pReq->pCont, pReq->contLen, &alterReq);
12,468✔
3887
  if (code != 0) {
12,468✔
3888
    mError("failed to deserialize alter user request at line %d since %s", __LINE__, tstrerror(code));
×
UNCOV
3889
    TAOS_RETURN(code);
×
3890
  }
3891

3892
  if (alterReq.user[0] == 0) {
12,468✔
3893
    tFreeSAlterUserReq(&alterReq);
×
3894
    mError("failed to alter user at line %d since invalid user format", __LINE__);
×
UNCOV
3895
    TAOS_RETURN(TSDB_CODE_MND_INVALID_USER_FORMAT);
×
3896
  }
3897

3898
  mInfo("user:%s, start to alter", alterReq.user);
12,468✔
3899
  if (alterReq.alterType == TSDB_ALTER_USER_BASIC_INFO) {
12,468✔
3900
    code = mndProcessAlterUserBasicInfoReq(pReq, &alterReq);
12,468✔
3901
  } else {
3902
    // code = mndProcessAlterUserPrivilegesReq(pReq, &alterReq); // obsolete
3903
  }
3904

3905
  tFreeSAlterUserReq(&alterReq);
12,468✔
3906
  TAOS_RETURN(code);
12,468✔
3907
}
3908

3909
int32_t mndGetAuditUser(SMnode *pMnode, char* user){
38,043,597✔
3910
  (void)tsnprintf(user, TSDB_USER_LEN, "audit");
38,043,597✔
3911
  return 0;
38,043,597✔
3912
}
3913

3914
static int32_t mndDropUser(SMnode *pMnode, SRpcMsg *pReq, SUserObj *pUser) {
19,418✔
3915
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "drop-user");
19,418✔
3916
  if (pTrans == NULL) {
19,418✔
3917
    mError("user:%s, failed to drop since %s", pUser->user, terrstr());
×
UNCOV
3918
    TAOS_RETURN(terrno);
×
3919
  }
3920
  mInfo("trans:%d, used to drop user:%s", pTrans->id, pUser->user);
19,418✔
3921

3922
  SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
19,418✔
3923
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
19,418✔
3924
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
UNCOV
3925
    mndTransDrop(pTrans);
×
UNCOV
3926
    TAOS_RETURN(terrno);
×
3927
  }
3928
  if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED) < 0) {
19,418✔
3929
    mndTransDrop(pTrans);
×
3930
    TAOS_RETURN(terrno);
×
3931
  }
3932

3933
  if (mndDropTokensByUser(pMnode, pTrans, pUser->user) != 0) {
19,418✔
UNCOV
3934
    mndTransDrop(pTrans);
×
UNCOV
3935
    TAOS_RETURN(terrno);
×
3936
  }
3937

3938
  if (mndTransPrepare(pMnode, pTrans) != 0) {
19,418✔
3939
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
3940
    mndTransDrop(pTrans);
×
3941
    TAOS_RETURN(terrno);
×
3942
  }
3943

3944
  userCacheRemoveUser(pUser->user);
19,418✔
3945
  mndDropCachedTokensByUser(pUser->user);
19,418✔
3946

3947
  mndTransDrop(pTrans);
19,418✔
3948
  TAOS_RETURN(0);
19,418✔
3949
}
3950

3951
static int32_t mndProcessDropUserReq(SRpcMsg *pReq) {
19,418✔
3952
  SMnode      *pMnode = pReq->info.node;
19,418✔
3953
  int32_t      code = 0;
19,418✔
3954
  int32_t      lino = 0;
19,418✔
3955
  SUserObj    *pOperUser = NULL;
19,418✔
3956
  SUserObj    *pUser = NULL;
19,418✔
3957
  SDropUserReq dropReq = {0};
19,418✔
3958
  int64_t      tss = taosGetTimestampMs();
19,418✔
3959

3960
  TAOS_CHECK_GOTO(tDeserializeSDropUserReq(pReq->pCont, pReq->contLen, &dropReq), &lino, _OVER);
19,418✔
3961

3962
  mInfo("user:%s, start to drop", dropReq.user);
19,418✔
3963

3964
  if (dropReq.user[0] == 0) {
19,418✔
UNCOV
3965
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
3966
  }
3967

3968
  if (0 == strcmp(dropReq.user, TSDB_DEFAULT_USER)) {
19,418✔
UNCOV
3969
    return TSDB_CODE_MND_NO_RIGHTS;
×
3970
  }
3971

3972
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, dropReq.user, &pUser), &lino, _OVER);
19,418✔
3973

3974
  code = mndAcquireUser(pMnode, RPC_MSG_USER(pReq), &pOperUser);
19,418✔
3975
  if (pOperUser == NULL) {
19,418✔
UNCOV
3976
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_USER_FROM_CONN, &lino, _OVER);
×
3977
  }
3978

3979
  // TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, RPC_MSG_USER(pReq), MND_OPER_DROP_USER), &lino, _OVER);
3980
  TAOS_CHECK_GOTO(mndCheckSysObjPrivilege(pMnode, pOperUser, PRIV_USER_DROP, 0, 0, NULL, NULL), &lino, _OVER);
19,418✔
3981

3982
  TAOS_CHECK_GOTO(mndDropUser(pMnode, pReq, pUser), &lino, _OVER);
19,418✔
3983
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
19,418✔
3984

3985
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
19,418✔
3986
    int64_t tse = taosGetTimestampMs();
19,418✔
3987
    double  duration = (double)(tse - tss);
19,418✔
3988
    duration = duration / 1000;
19,418✔
3989
    auditRecord(pReq, pMnode->clusterId, "dropUser", "", dropReq.user, dropReq.sql, dropReq.sqlLen, duration, 0);
19,418✔
3990
  }
3991

3992
_OVER:
19,418✔
3993
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
19,418✔
3994
    mError("user:%s, failed to drop at line %d since %s", dropReq.user, lino, tstrerror(code));
×
3995
  }
3996

3997
  mndReleaseUser(pMnode, pUser);
19,418✔
3998
  mndReleaseUser(pMnode, pOperUser);
19,418✔
3999
  tFreeSDropUserReq(&dropReq);
19,418✔
4000
  TAOS_RETURN(code);
19,418✔
4001
}
4002

4003
static int32_t mndProcessGetUserAuthReq(SRpcMsg *pReq) {
5,333,602✔
4004
  SMnode         *pMnode = pReq->info.node;
5,333,602✔
4005
  int32_t         code = 0;
5,334,289✔
4006
  int32_t         lino = 0;
5,334,289✔
4007
  int32_t         contLen = 0;
5,334,289✔
4008
  void           *pRsp = NULL;
5,334,289✔
4009
  SUserObj       *pUser = NULL;
5,334,289✔
4010
  SGetUserAuthReq authReq = {0};
5,334,289✔
4011
  SGetUserAuthRsp authRsp = {0};
5,334,289✔
4012

4013
  TAOS_CHECK_EXIT(tDeserializeSGetUserAuthReq(pReq->pCont, pReq->contLen, &authReq));
5,333,602✔
4014
  mTrace("user:%s, start to get auth", authReq.user);
5,334,289✔
4015

4016
  TAOS_CHECK_EXIT(mndAcquireUser(pMnode, authReq.user, &pUser));
5,334,289✔
4017

4018
  TAOS_CHECK_EXIT(mndSetUserAuthRsp(pMnode, pUser, &authRsp));
5,334,289✔
4019

4020
  contLen = tSerializeSGetUserAuthRsp(NULL, 0, &authRsp);
5,334,289✔
4021
  if (contLen < 0) {
5,334,289✔
4022
    TAOS_CHECK_EXIT(contLen);
×
4023
  }
4024
  pRsp = rpcMallocCont(contLen);
5,334,289✔
4025
  if (pRsp == NULL) {
5,333,602✔
UNCOV
4026
    TAOS_CHECK_EXIT(terrno);
×
4027
  }
4028

4029
  contLen = tSerializeSGetUserAuthRsp(pRsp, contLen, &authRsp);
5,333,602✔
4030
  if (contLen < 0) {
5,334,289✔
UNCOV
4031
    TAOS_CHECK_EXIT(contLen);
×
4032
  }
4033

4034
_exit:
5,334,289✔
4035
  mndReleaseUser(pMnode, pUser);
5,334,289✔
4036
  tFreeSGetUserAuthRsp(&authRsp);
5,334,289✔
4037
  if (code < 0) {
5,333,602✔
UNCOV
4038
    mError("user:%s, failed to get auth at line %d since %s", authReq.user, lino, tstrerror(code));
×
UNCOV
4039
    rpcFreeCont(pRsp);
×
4040
    pRsp = NULL;
×
4041
    contLen = 0;
×
4042
  }
4043
  pReq->info.rsp = pRsp;
5,333,602✔
4044
  pReq->info.rspLen = contLen;
5,333,602✔
4045
  pReq->code = code;
5,334,289✔
4046

4047
  TAOS_RETURN(code);
5,334,289✔
4048
}
4049

4050

4051
bool mndIsTotpEnabledUser(SUserObj *pUser) {
1,924,473✔
4052
  for (int32_t i = 0; i < sizeof(pUser->totpsecret); i++) {
63,490,239✔
4053
    if (pUser->totpsecret[i] != 0) {
61,566,484✔
UNCOV
4054
      return true;
×
4055
    }
4056
  }
4057
  return false;
1,923,755✔
4058
}
4059

4060

4061
static int32_t mndRetrieveUsers(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
7,266✔
4062
  SMnode   *pMnode = pReq->info.node;
7,266✔
4063
  SSdb     *pSdb = pMnode->pSdb;
7,266✔
4064
  int32_t   code = 0;
7,266✔
4065
  int32_t   lino = 0;
7,266✔
4066
  int32_t   numOfRows = 0;
7,266✔
4067
  SUserObj *pUser = NULL;
7,266✔
4068
  int32_t   cols = 0;
7,266✔
4069
  int8_t    flag = 0;
7,266✔
4070
  char     *pWrite = NULL;
7,266✔
4071
  char     *buf = NULL;
7,266✔
4072
  char     *varstr = NULL;
7,266✔
4073
  int32_t   bufSize = TSDB_MAX_SUBROLE * TSDB_ROLE_LEN + VARSTR_HEADER_SIZE;
7,266✔
4074
  char      tBuf[TSDB_MAX_SUBROLE * TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
7,266✔
4075

4076
  while (numOfRows < rows) {
25,681✔
4077
    pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
25,681✔
4078
    if (pShow->pIter == NULL) break;
25,681✔
4079

4080
    cols = 0;
18,415✔
4081
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
18,415✔
4082
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
18,415✔
4083
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
18,415✔
4084
    COL_DATA_SET_VAL_GOTO((const char *)name, false, pUser, pShow->pIter, _exit);
18,415✔
4085

4086
    cols++;
18,415✔
4087
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
18,415✔
4088
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->superUser, false, pUser, pShow->pIter, _exit);
18,415✔
4089

4090
    cols++;
18,415✔
4091
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
18,415✔
4092
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->enable, false, pUser, pShow->pIter, _exit);
18,415✔
4093

4094
    cols++;
18,415✔
4095
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
18,415✔
4096
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sysInfo, false, pUser, pShow->pIter, _exit);
18,415✔
4097

4098
    cols++;
18,415✔
4099
    flag = pUser->createdb ? 1 : 0;
18,415✔
4100
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
18,415✔
4101
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
18,415✔
4102

4103
    cols++;
18,415✔
4104
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
18,415✔
4105
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->createdTime, false, pUser, pShow->pIter, _exit);
18,415✔
4106

4107
    cols++;
18,415✔
4108
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
18,415✔
4109
    flag = mndIsTotpEnabledUser(pUser) ? 1 : 0;
18,415✔
4110
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
18,415✔
4111

4112
    cols++;
18,415✔
4113

4114
    int32_t tlen = convertIpWhiteListToStr(pUser, &buf);
18,415✔
4115
    if (tlen != 0) {
18,415✔
4116
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
18,415✔
4117
      if (varstr == NULL) {
18,415✔
UNCOV
4118
        sdbRelease(pSdb, pUser);
×
UNCOV
4119
        sdbCancelFetch(pSdb, pShow->pIter);
×
UNCOV
4120
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
4121
      }
4122
      varDataSetLen(varstr, tlen);
18,415✔
4123
      (void)memcpy(varDataVal(varstr), buf, tlen);
18,415✔
4124

4125
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
18,415✔
4126
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
18,415✔
4127

4128
      taosMemoryFreeClear(buf);
18,415✔
4129
    } else {
UNCOV
4130
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4131
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
4132
    }
4133

4134
    cols++;
18,415✔
4135
    tlen = convertTimeRangesToStr(pUser, &buf);
18,415✔
4136
    if (tlen != 0) {
18,415✔
4137
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
18,415✔
4138
      if (varstr == NULL) {
18,415✔
UNCOV
4139
        sdbRelease(pSdb, pUser);
×
UNCOV
4140
        sdbCancelFetch(pSdb, pShow->pIter);
×
UNCOV
4141
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
4142
      }
4143
      varDataSetLen(varstr, tlen);
18,415✔
4144
      (void)memcpy(varDataVal(varstr), buf, tlen);
18,415✔
4145

4146
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
18,415✔
4147
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
18,415✔
4148

4149
      taosMemoryFreeClear(buf);
18,415✔
4150
    } else {
UNCOV
4151
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4152
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
4153
    }
4154

4155
    if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
18,415✔
4156
      void  *pIter = NULL;
18,415✔
4157
      size_t klen = 0, tlen = 0;
18,415✔
4158
      char  *pBuf = POINTER_SHIFT(tBuf, VARSTR_HEADER_SIZE);
18,415✔
4159
      while ((pIter = taosHashIterate(pUser->roles, pIter))) {
51,662✔
4160
        char *roleName = taosHashGetKey(pIter, &klen);
33,247✔
4161
        tlen += snprintf(pBuf + tlen, bufSize - tlen, "%s,", roleName);
33,247✔
4162
      }
4163
      if (tlen > 0) {
18,415✔
4164
        pBuf[tlen - 1] = 0;  // remove last ','
18,415✔
4165
      } else {
UNCOV
4166
        pBuf[0] = 0;
×
4167
      }
4168
      varDataSetLen(tBuf, tlen);
18,415✔
4169
      COL_DATA_SET_VAL_GOTO((const char *)tBuf, false, pUser, pShow->pIter, _exit);
18,415✔
4170
    }
4171

4172
    numOfRows++;
18,415✔
4173
    sdbRelease(pSdb, pUser);
18,415✔
4174
  }
4175

4176
  pShow->numOfRows += numOfRows;
7,266✔
4177
_exit:
7,266✔
4178
  taosMemoryFreeClear(buf);
7,266✔
4179
  taosMemoryFreeClear(varstr);
7,266✔
4180
  if (code < 0) {
7,266✔
UNCOV
4181
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
UNCOV
4182
    TAOS_RETURN(code);
×
4183
  }
4184
  return numOfRows;
7,266✔
4185
}
4186

UNCOV
4187
static int32_t mndRetrieveUsersFull(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
×
UNCOV
4188
  int32_t numOfRows = 0;
×
4189
#ifdef TD_ENTERPRISE
UNCOV
4190
  SMnode   *pMnode = pReq->info.node;
×
UNCOV
4191
  SSdb     *pSdb = pMnode->pSdb;
×
UNCOV
4192
  SUserObj *pUser = NULL;
×
UNCOV
4193
  int32_t   code = 0;
×
UNCOV
4194
  int32_t   lino = 0;
×
UNCOV
4195
  int32_t   cols = 0;
×
UNCOV
4196
  int8_t    flag = 0;
×
UNCOV
4197
  char     *pWrite = NULL;
×
UNCOV
4198
  char     *buf = NULL;
×
UNCOV
4199
  char     *varstr = NULL;
×
4200

UNCOV
4201
  while (numOfRows < rows) {
×
UNCOV
4202
    pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
×
4203
    if (pShow->pIter == NULL) break;
×
4204

4205
    cols = 0;
×
UNCOV
4206
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4207
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
×
UNCOV
4208
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
×
UNCOV
4209
    COL_DATA_SET_VAL_GOTO((const char *)name, false, pUser, pShow->pIter, _exit);
×
4210

UNCOV
4211
    cols++;
×
UNCOV
4212
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4213
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->superUser, false, pUser, pShow->pIter, _exit);
×
4214

UNCOV
4215
    cols++;
×
UNCOV
4216
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4217
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->enable, false, pUser, pShow->pIter, _exit);
×
4218

4219
    cols++;
×
4220
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4221
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sysInfo, false, pUser, pShow->pIter, _exit);
×
4222

UNCOV
4223
    cols++;
×
UNCOV
4224
    flag = pUser->createdb ? 1 : 0;
×
UNCOV
4225
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4226
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
×
4227

UNCOV
4228
    cols++;
×
UNCOV
4229
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4230
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->createdTime, false, pUser, pShow->pIter, _exit);
×
4231

UNCOV
4232
    cols++;
×
UNCOV
4233
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4234
    flag = mndIsTotpEnabledUser(pUser) ? 1 : 0;
×
UNCOV
4235
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
×
4236

UNCOV
4237
    cols++;
×
UNCOV
4238
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4239
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->changePass, false, pUser, pShow->pIter, _exit);
×
4240

UNCOV
4241
    cols++;
×
UNCOV
4242
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4243
    char pass[TSDB_PASSWORD_LEN + VARSTR_HEADER_SIZE] = {0};
×
UNCOV
4244
    STR_WITH_MAXSIZE_TO_VARSTR(pass, pUser->passwords[0].pass, pShow->pMeta->pSchemas[cols].bytes);
×
UNCOV
4245
    COL_DATA_SET_VAL_GOTO((const char *)pass, false, pUser, pShow->pIter, _exit);
×
4246

UNCOV
4247
    cols++;
×
UNCOV
4248
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4249
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sessionPerUser, false, pUser, pShow->pIter, _exit);
×
4250

UNCOV
4251
    cols++;
×
UNCOV
4252
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4253
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->connectTime, false, pUser, pShow->pIter, _exit);
×
4254

UNCOV
4255
    cols++;
×
UNCOV
4256
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4257
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->connectIdleTime, false, pUser, pShow->pIter, _exit);
×
4258

UNCOV
4259
    cols++;
×
UNCOV
4260
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4261
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->callPerSession, false, pUser, pShow->pIter, _exit);
×
4262

4263
    /* not supported yet
4264
    cols++;
4265
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
4266
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->vnodePerSession, false, pUser, pShow->pIter, _exit);
4267
*/
4268

UNCOV
4269
    cols++;
×
UNCOV
4270
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4271
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->failedLoginAttempts, false, pUser, pShow->pIter, _exit);
×
4272

UNCOV
4273
    cols++;
×
4274
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4275
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordLifeTime, false, pUser, pShow->pIter, _exit);
×
4276

UNCOV
4277
    cols++;
×
UNCOV
4278
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4279
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordReuseTime, false, pUser, pShow->pIter, _exit);
×
4280

UNCOV
4281
    cols++;
×
UNCOV
4282
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4283
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordReuseMax, false, pUser, pShow->pIter, _exit);
×
4284

UNCOV
4285
    cols++;
×
UNCOV
4286
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4287
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordLockTime, false, pUser, pShow->pIter, _exit);
×
4288

UNCOV
4289
    cols++;
×
UNCOV
4290
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4291
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordGraceTime, false, pUser, pShow->pIter, _exit);
×
4292

UNCOV
4293
    cols++;
×
UNCOV
4294
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4295
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->inactiveAccountTime, false, pUser, pShow->pIter, _exit);
×
4296

UNCOV
4297
    cols++;
×
4298
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4299
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->allowTokenNum, false, pUser, pShow->pIter, _exit);
×
4300

UNCOV
4301
    cols++;
×
UNCOV
4302
    int32_t tlen = convertIpWhiteListToStr(pUser, &buf);
×
UNCOV
4303
    if (tlen != 0) {
×
4304
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
×
4305
      if (varstr == NULL) {
×
4306
        sdbRelease(pSdb, pUser);
×
4307
        sdbCancelFetch(pSdb, pShow->pIter);
×
UNCOV
4308
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
4309
      }
UNCOV
4310
      varDataSetLen(varstr, tlen);
×
UNCOV
4311
      (void)memcpy(varDataVal(varstr), buf, tlen);
×
4312

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

UNCOV
4316
      taosMemoryFreeClear(buf);
×
4317
    } else {
UNCOV
4318
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4319
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
4320
    }
4321

UNCOV
4322
    cols++;
×
UNCOV
4323
    tlen = convertTimeRangesToStr(pUser, &buf);
×
UNCOV
4324
    if (tlen != 0) {
×
UNCOV
4325
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
×
UNCOV
4326
      if (varstr == NULL) {
×
UNCOV
4327
        sdbRelease(pSdb, pUser);
×
UNCOV
4328
        sdbCancelFetch(pSdb, pShow->pIter);
×
UNCOV
4329
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
4330
      }
UNCOV
4331
      varDataSetLen(varstr, tlen);
×
UNCOV
4332
      (void)memcpy(varDataVal(varstr), buf, tlen);
×
4333

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

UNCOV
4337
      taosMemoryFreeClear(buf);
×
4338
    } else {
UNCOV
4339
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
4340
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
4341
    }
4342

UNCOV
4343
    numOfRows++;
×
UNCOV
4344
    sdbRelease(pSdb, pUser);
×
4345
  }
4346

4347
  pShow->numOfRows += numOfRows;
×
UNCOV
4348
_exit:
×
UNCOV
4349
  taosMemoryFreeClear(buf);
×
UNCOV
4350
  taosMemoryFreeClear(varstr);
×
4351
  if (code < 0) {
×
4352
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4353
    TAOS_RETURN(code);
×
4354
  }
4355
#endif
UNCOV
4356
  return numOfRows;
×
4357
}
4358

UNCOV
4359
static void mndCancelGetNextUser(SMnode *pMnode, void *pIter) {
×
UNCOV
4360
  SSdb *pSdb = pMnode->pSdb;
×
UNCOV
4361
  sdbCancelFetchByType(pSdb, pIter, SDB_USER);
×
UNCOV
4362
}
×
4363

UNCOV
4364
static int32_t mndLoopHash(SHashObj *hash, char *priType, SSDataBlock *pBlock, int32_t *pNumOfRows, SSdb *pSdb,
×
4365
                           SUserObj *pUser, SShowObj *pShow, char **condition, char **sql) {
UNCOV
4366
  char   *value = taosHashIterate(hash, NULL);
×
UNCOV
4367
  char   *user = pUser->user;
×
UNCOV
4368
  int32_t code = 0;
×
4369
  int32_t lino = 0;
×
UNCOV
4370
  int32_t cols = 0;
×
UNCOV
4371
  int32_t numOfRows = *pNumOfRows;
×
4372

4373
  while (value != NULL) {
×
UNCOV
4374
    cols = 0;
×
UNCOV
4375
    char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
×
UNCOV
4376
    STR_WITH_MAXSIZE_TO_VARSTR(userName, user, pShow->pMeta->pSchemas[cols].bytes);
×
4377
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
UNCOV
4378
    COL_DATA_SET_VAL_GOTO((const char *)userName, false, NULL, NULL, _exit);
×
4379

UNCOV
4380
    char privilege[20] = {0};
×
UNCOV
4381
    STR_WITH_MAXSIZE_TO_VARSTR(privilege, priType, pShow->pMeta->pSchemas[cols].bytes);
×
4382
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4383
    COL_DATA_SET_VAL_GOTO((const char *)privilege, false, NULL, NULL, _exit);
×
4384

UNCOV
4385
    size_t keyLen = 0;
×
UNCOV
4386
    void  *key = taosHashGetKey(value, &keyLen);
×
4387

UNCOV
4388
    char dbName[TSDB_DB_NAME_LEN] = {0};
×
UNCOV
4389
    (void)mndExtractShortDbNameFromStbFullName(key, dbName);
×
UNCOV
4390
    char dbNameContent[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
×
UNCOV
4391
    STR_WITH_MAXSIZE_TO_VARSTR(dbNameContent, dbName, pShow->pMeta->pSchemas[cols].bytes);
×
UNCOV
4392
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
UNCOV
4393
    COL_DATA_SET_VAL_GOTO((const char *)dbNameContent, false, NULL, NULL, _exit);
×
4394

UNCOV
4395
    char tableName[TSDB_TABLE_NAME_LEN] = {0};
×
UNCOV
4396
    mndExtractTbNameFromStbFullName(key, tableName, TSDB_TABLE_NAME_LEN);
×
UNCOV
4397
    char tableNameContent[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
×
UNCOV
4398
    STR_WITH_MAXSIZE_TO_VARSTR(tableNameContent, tableName, pShow->pMeta->pSchemas[cols].bytes);
×
UNCOV
4399
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
UNCOV
4400
    COL_DATA_SET_VAL_GOTO((const char *)tableNameContent, false, NULL, NULL, _exit);
×
4401

UNCOV
4402
    if (strcmp("t", value) != 0 && strcmp("v", value) != 0) {
×
UNCOV
4403
      SNode  *pAst = NULL;
×
UNCOV
4404
      int32_t sqlLen = 0;
×
UNCOV
4405
      size_t  bufSz = strlen(value) + 1;
×
UNCOV
4406
      if (bufSz < 6) bufSz = 6;
×
UNCOV
4407
      TAOS_MEMORY_REALLOC(*sql, bufSz);
×
UNCOV
4408
      if (*sql == NULL) {
×
UNCOV
4409
        code = terrno;
×
UNCOV
4410
        goto _exit;
×
4411
      }
UNCOV
4412
      TAOS_MEMORY_REALLOC(*condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
×
UNCOV
4413
      if ((*condition) == NULL) {
×
UNCOV
4414
        code = terrno;
×
UNCOV
4415
        goto _exit;
×
4416
      }
4417

UNCOV
4418
      if (nodesStringToNode(value, &pAst) == 0) {
×
UNCOV
4419
        if (nodesNodeToSQLFormat(pAst, *sql, bufSz, &sqlLen, true) != 0) {
×
UNCOV
4420
          sqlLen = tsnprintf(*sql, bufSz, "error");
×
4421
        }
UNCOV
4422
        nodesDestroyNode(pAst);
×
4423
      }
4424

UNCOV
4425
      if (sqlLen == 0) {
×
UNCOV
4426
        sqlLen = tsnprintf(*sql, bufSz, "error");
×
4427
      }
4428

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

UNCOV
4431
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
UNCOV
4432
      COL_DATA_SET_VAL_GOTO((const char *)(*condition), false, NULL, NULL, _exit);
×
4433

UNCOV
4434
      char notes[2] = {0};
×
UNCOV
4435
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
×
UNCOV
4436
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
UNCOV
4437
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, NULL, NULL, _exit);
×
4438
    } else {
UNCOV
4439
      TAOS_MEMORY_REALLOC(*condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
×
UNCOV
4440
      if ((*condition) == NULL) {
×
UNCOV
4441
        code = terrno;
×
UNCOV
4442
        goto _exit;
×
4443
      }
UNCOV
4444
      STR_WITH_MAXSIZE_TO_VARSTR((*condition), "", pShow->pMeta->pSchemas[cols].bytes);
×
UNCOV
4445
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
UNCOV
4446
      COL_DATA_SET_VAL_GOTO((const char *)(*condition), false, NULL, NULL, _exit);
×
4447

UNCOV
4448
      char notes[64 + VARSTR_HEADER_SIZE] = {0};
×
UNCOV
4449
      STR_WITH_MAXSIZE_TO_VARSTR(notes, value[0] == 'v' ? "view" : "", sizeof(notes));
×
UNCOV
4450
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
UNCOV
4451
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, NULL, NULL, _exit);
×
4452
    }
4453

UNCOV
4454
    numOfRows++;
×
UNCOV
4455
    value = taosHashIterate(hash, value);
×
4456
  }
UNCOV
4457
  *pNumOfRows = numOfRows;
×
UNCOV
4458
_exit:
×
UNCOV
4459
  if (code < 0) {
×
UNCOV
4460
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
UNCOV
4461
    sdbRelease(pSdb, pUser);
×
UNCOV
4462
    sdbCancelFetch(pSdb, pShow->pIter);
×
4463
  }
UNCOV
4464
  TAOS_RETURN(code);
×
4465
}
4466

4467
#if 0
4468
static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
4469
  int32_t   code = 0;
4470
  int32_t   lino = 0;
4471
  SMnode   *pMnode = pReq->info.node;
4472
  SSdb     *pSdb = pMnode->pSdb;
4473
  int32_t   numOfRows = 0;
4474
  SUserObj *pUser = NULL;
4475
  int32_t   cols = 0;
4476
  char     *pWrite = NULL;
4477
  char     *condition = NULL;
4478
  char     *sql = NULL;
4479

4480
  bool fetchNextUser = pShow->restore ? false : true;
4481
  pShow->restore = false;
4482

4483
  while (numOfRows < rows) {
4484
    if (fetchNextUser) {
4485
      pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
4486
      if (pShow->pIter == NULL) break;
4487
    } else {
4488
      fetchNextUser = true;
4489
      void *pKey = taosHashGetKey(pShow->pIter, NULL);
4490
      pUser = sdbAcquire(pSdb, SDB_USER, pKey);
4491
      if (!pUser) {
4492
        continue;
4493
      }
4494
    }
4495

4496
    int32_t numOfReadDbs = 0; //taosHashGetSize(pUser->readDbs);
4497
    int32_t numOfWriteDbs = 0; //taosHashGetSize(pUser->writeDbs);
4498
    int32_t numOfTopics = taosHashGetSize(pUser->topics);
4499
    int32_t numOfReadTbs = taosHashGetSize(pUser->selectTbs);
4500
    int32_t numOfWriteTbs = taosHashGetSize(pUser->insertTbs);
4501
    int32_t numOfAlterTbs = taosHashGetSize(pUser->alterTbs);
4502
    int32_t numOfReadViews = taosHashGetSize(pUser->readViews);
4503
    int32_t numOfWriteViews = taosHashGetSize(pUser->writeViews);
4504
    int32_t numOfAlterViews = taosHashGetSize(pUser->alterViews);
4505
    if (numOfRows + numOfReadDbs + numOfWriteDbs + numOfTopics + numOfReadTbs + numOfWriteTbs + numOfAlterTbs +
4506
            numOfReadViews + numOfWriteViews + numOfAlterViews >=
4507
        rows) {
4508
      mInfo(
4509
          "will restore. current num of rows: %d, read dbs %d, write dbs %d, topics %d, read tables %d, write tables "
4510
          "%d, alter tables %d, select views %d, write views %d, alter views %d",
4511
          numOfRows, numOfReadDbs, numOfWriteDbs, numOfTopics, numOfReadTbs, numOfWriteTbs, numOfAlterTbs,
4512
          numOfReadViews, numOfWriteViews, numOfAlterViews);
4513
      pShow->restore = true;
4514
      sdbRelease(pSdb, pUser);
4515
      break;
4516
    }
4517

4518
    if (pUser->superUser) {
4519
      cols = 0;
4520
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
4521
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
4522
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4523
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
4524

4525
      char privilege[20] = {0};
4526
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "all", pShow->pMeta->pSchemas[cols].bytes);
4527
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4528
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
4529

4530
      char objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4531
      STR_WITH_MAXSIZE_TO_VARSTR(objName, "all", pShow->pMeta->pSchemas[cols].bytes);
4532
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4533
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
4534

4535
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4536
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
4537
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4538
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
4539

4540
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
4541
      if (condition == NULL) {
4542
        sdbRelease(pSdb, pUser);
4543
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
4544
      }
4545
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
4546
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4547
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
4548

4549
      char notes[2] = {0};
4550
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
4551
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4552
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
4553

4554
      numOfRows++;
4555
    }
4556
#if 0
4557
    char *db = taosHashIterate(pUser->readDbs, NULL);
4558
    while (db != NULL) {
4559
      cols = 0;
4560
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
4561
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
4562
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4563
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
4564

4565
      char privilege[20] = {0};
4566
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "read", pShow->pMeta->pSchemas[cols].bytes);
4567
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4568
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
4569

4570
      SName name = {0};
4571
      char  objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4572
      code = tNameFromString(&name, db, T_NAME_ACCT | T_NAME_DB);
4573
      if (code < 0) {
4574
        sdbRelease(pSdb, pUser);
4575
        sdbCancelFetch(pSdb, pShow->pIter);
4576
        TAOS_CHECK_GOTO(code, &lino, _exit);
4577
      }
4578
      (void)tNameGetDbName(&name, varDataVal(objName));
4579
      varDataSetLen(objName, strlen(varDataVal(objName)));
4580
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4581
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
4582

4583
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4584
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
4585
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4586
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
4587

4588
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
4589
      if (condition == NULL) {
4590
        sdbRelease(pSdb, pUser);
4591
        sdbCancelFetch(pSdb, pShow->pIter);
4592
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
4593
      }
4594
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
4595
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4596
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
4597

4598
      char notes[2] = {0};
4599
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
4600
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4601
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
4602

4603
      numOfRows++;
4604
      db = taosHashIterate(pUser->readDbs, db);
4605
    }
4606

4607
    db = taosHashIterate(pUser->writeDbs, NULL);
4608
    while (db != NULL) {
4609
      cols = 0;
4610
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
4611
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
4612
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4613
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
4614

4615
      char privilege[20] = {0};
4616
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "write", pShow->pMeta->pSchemas[cols].bytes);
4617
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4618
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
4619

4620
      SName name = {0};
4621
      char  objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4622
      code = tNameFromString(&name, db, T_NAME_ACCT | T_NAME_DB);
4623
      if (code < 0) {
4624
        sdbRelease(pSdb, pUser);
4625
        sdbCancelFetch(pSdb, pShow->pIter);
4626
        TAOS_CHECK_GOTO(code, &lino, _exit);
4627
      }
4628
      (void)tNameGetDbName(&name, varDataVal(objName));
4629
      varDataSetLen(objName, strlen(varDataVal(objName)));
4630
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4631
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
4632

4633
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4634
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
4635
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4636
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
4637

4638
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
4639
      if (condition == NULL) {
4640
        sdbRelease(pSdb, pUser);
4641
        sdbCancelFetch(pSdb, pShow->pIter);
4642
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
4643
      }
4644
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
4645
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4646
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
4647

4648
      char notes[2] = {0};
4649
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
4650
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4651
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
4652

4653
      numOfRows++;
4654
      db = taosHashIterate(pUser->writeDbs, db);
4655
    }
4656
#endif
4657
    TAOS_CHECK_EXIT(mndLoopHash(pUser->selectTbs, "select", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
4658

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

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

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

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

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

4669
    char *topic = taosHashIterate(pUser->topics, NULL);
4670
    while (topic != NULL) {
4671
      cols = 0;
4672
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
4673
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
4674
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4675
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
4676

4677
      char privilege[20] = {0};
4678
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "subscribe", pShow->pMeta->pSchemas[cols].bytes);
4679
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4680
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
4681

4682
      char topicName[TSDB_TOPIC_NAME_LEN + VARSTR_HEADER_SIZE + 5] = {0};
4683
      tstrncpy(varDataVal(topicName), mndGetDbStr(topic), TSDB_TOPIC_NAME_LEN - 2);
4684
      varDataSetLen(topicName, strlen(varDataVal(topicName)));
4685
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4686
      COL_DATA_SET_VAL_GOTO((const char *)topicName, false, pUser, pShow->pIter, _exit);
4687

4688
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4689
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
4690
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4691
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
4692

4693
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
4694
      if (condition == NULL) {
4695
        sdbRelease(pSdb, pUser);
4696
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
4697
      }
4698
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
4699
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4700
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
4701

4702
      char notes[2] = {0};
4703
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
4704
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4705
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
4706

4707
      numOfRows++;
4708
      topic = taosHashIterate(pUser->topics, topic);
4709
    }
4710

4711
    sdbRelease(pSdb, pUser);
4712
  }
4713

4714
  pShow->numOfRows += numOfRows;
4715
_exit:
4716
  taosMemoryFreeClear(condition);
4717
  taosMemoryFreeClear(sql);
4718
  if (code < 0) {
4719
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
4720
    TAOS_RETURN(code);
4721
  }
4722
  return numOfRows;
4723
}
4724
#endif
4725

4726
static int32_t mndShowTablePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows, SUserObj *pObj,
131,636✔
4727
                                      SHashObj *privTbs, EPrivType privType, char *pBuf, int32_t bufSize, int32_t *pNumOfRows) {
4728
  int32_t     code = 0, lino = 0;
131,636✔
4729
  SMnode     *pMnode = pReq->info.node;
131,636✔
4730
  SSdb       *pSdb = pMnode->pSdb;
131,636✔
4731
  int32_t     cols = 0, qBufSize = bufSize - VARSTR_HEADER_SIZE;
131,636✔
4732
  int32_t     numOfRows = *pNumOfRows;
131,636✔
4733
  char       *qBuf = NULL;
131,636✔
4734
  char       *sql = NULL;
131,636✔
4735
  char        roleName[TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
131,636✔
4736
  const char *privName = privInfoGetName(privType);
131,636✔
4737

4738
  STR_WITH_MAXSIZE_TO_VARSTR(roleName, pObj->name, pShow->pMeta->pSchemas[cols].bytes);
131,636✔
4739

4740
  void *pIter = NULL;
131,636✔
4741
  while ((pIter = taosHashIterate(privTbs, pIter))) {
167,070✔
4742
    SPrivTblPolicies *pPolices = (SPrivTblPolicies *)pIter;
35,434✔
4743
    SArray           *tblPolicies = pPolices->policy;
35,434✔
4744

4745
    char   *key = taosHashGetKey(pPolices, NULL);
35,434✔
4746
    int32_t objType = PRIV_OBJ_UNKNOWN;
35,434✔
4747
    char    dbName[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
35,434✔
4748
    char    tblName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
35,434✔
4749
    if ((code = privObjKeyParse(key, &objType, dbName, sizeof(dbName), tblName, sizeof(tblName), false))) {
35,434✔
UNCOV
4750
      sdbRelease(pSdb, pObj);
×
UNCOV
4751
      sdbCancelFetch(pSdb, pShow->pIter);
×
UNCOV
4752
      TAOS_CHECK_EXIT(code);
×
4753
    }
4754

4755
    int32_t nTbPolicies = taosArrayGetSize(tblPolicies);
35,434✔
4756
    for (int32_t i = 0; i < nTbPolicies; ++i) {
70,868✔
4757
      SPrivTblPolicy *tbPolicy = (SPrivTblPolicy *)TARRAY_GET_ELEM(tblPolicies, i);
35,434✔
4758
      cols = 0;
35,434✔
4759
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
35,434✔
4760
      COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
35,434✔
4761

4762
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
35,434✔
4763
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privName, pShow->pMeta->pSchemas[cols].bytes);
35,434✔
4764
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
35,434✔
4765
      }
4766

4767
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
35,434✔
4768
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privObjGetName(objType), pShow->pMeta->pSchemas[cols].bytes);
35,434✔
4769
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
35,434✔
4770
      }
4771

4772
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
35,434✔
4773
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, dbName, pShow->pMeta->pSchemas[cols].bytes);
35,434✔
4774
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
35,434✔
4775
      }
4776

4777
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
35,434✔
4778
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, tblName, pShow->pMeta->pSchemas[cols].bytes);
35,434✔
4779
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
35,434✔
4780
      }
4781
      // condition
4782
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
35,434✔
4783
        SNode  *pAst = NULL;
35,434✔
4784
        int32_t sqlLen = 0;
35,434✔
4785
        qBuf = POINTER_SHIFT(pBuf, VARSTR_HEADER_SIZE);
35,434✔
4786
        if (tbPolicy->condLen > 0) {
35,434✔
4787
          if (nodesStringToNode(tbPolicy->cond, &pAst) == 0) {
35,434✔
4788
            if (nodesNodeToSQLFormat(pAst, qBuf, qBufSize, &sqlLen, true) != 0) {
35,434✔
UNCOV
4789
              sqlLen = tsnprintf(qBuf, qBufSize, "error");
×
4790
            }
4791
            nodesDestroyNode(pAst);
35,434✔
4792
          }
4793
          if (sqlLen == 0) {
35,434✔
UNCOV
4794
            sqlLen = tsnprintf(qBuf, qBufSize, "error");
×
4795
          }
4796
        } else {
UNCOV
4797
          sqlLen = tsnprintf(qBuf, qBufSize, "");
×
4798
        }
4799
        varDataSetLen(pBuf, sqlLen);
35,434✔
4800
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
35,434✔
4801
      }
4802
      // notes
4803
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
35,434✔
4804
        STR_WITH_MAXSIZE_TO_VARSTR((pBuf), "", 2);
35,434✔
4805
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
35,434✔
4806
      }
4807
      // columns
4808
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
35,434✔
4809
        SArray *pCols = tbPolicy->cols;
35,434✔
4810
        int32_t nCols = taosArrayGetSize(pCols);
35,434✔
4811
        int32_t totalLen = 0;
35,434✔
4812
        qBuf = POINTER_SHIFT(pBuf, VARSTR_HEADER_SIZE);
35,434✔
4813
        for (int32_t j = 0; j < nCols; ++j) {
35,434✔
UNCOV
4814
          SColNameFlag *pCol = (SColNameFlag *)TARRAY_GET_ELEM(pCols, j);
×
UNCOV
4815
          char          tmpBuf[TSDB_COL_NAME_LEN + 16] = {0};
×
UNCOV
4816
          int32_t       tmpLen = 0;
×
UNCOV
4817
          if (IS_MASK_ON(pCol)) {
×
UNCOV
4818
            tmpLen = snprintf(tmpBuf, sizeof(tmpBuf), "mask(%s)%s", pCol->colName, j == nCols - 1 ? "" : ",");
×
4819
          } else {
UNCOV
4820
            tmpLen = snprintf(tmpBuf, sizeof(tmpBuf), "%s%s", pCol->colName, j == nCols - 1 ? "" : ",");
×
4821
          }
UNCOV
4822
          if(totalLen + tmpLen > qBufSize) {
×
UNCOV
4823
            break;
×
4824
          }
UNCOV
4825
          (void)memcpy(POINTER_SHIFT(qBuf, totalLen), tmpBuf, tmpLen);
×
UNCOV
4826
          totalLen += tmpLen;
×
4827
        }
4828
        varDataSetLen(pBuf, totalLen);
35,434✔
4829
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
35,434✔
4830
      }
4831
      // update_time
4832
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
35,434✔
4833
        char updateTime[40] = {0};
35,434✔
4834
        (void)formatTimestampLocal(updateTime, tbPolicy->updateUs, TSDB_TIME_PRECISION_MICRO);
35,434✔
4835
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, updateTime, pShow->pMeta->pSchemas[cols].bytes);
35,434✔
4836
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
35,434✔
4837
      }
4838
      ++numOfRows;
35,434✔
4839
    }
4840
  }
4841
  *pNumOfRows = numOfRows;
131,636✔
4842
_exit:
131,636✔
4843
  TAOS_RETURN(code);
131,636✔
4844
}
4845

4846
static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
4,983✔
4847
  int32_t   code = 0, lino = 0;
4,983✔
4848
  SMnode   *pMnode = pReq->info.node;
4,983✔
4849
  SSdb     *pSdb = pMnode->pSdb;
4,983✔
4850
  int32_t   numOfRows = 0;
4,983✔
4851
  int32_t   cols = 0;
4,983✔
4852
  SUserObj *pObj = NULL;
4,983✔
4853
  char     *pBuf = NULL, *qBuf = NULL;
4,983✔
4854
  char     *sql = NULL;
4,983✔
4855
  char      roleName[TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
4,983✔
4856
  int32_t   bufSize = TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE;
4,983✔
4857

4858
  bool fetchNextInstance = pShow->restore ? false : true;
4,983✔
4859
  pShow->restore = false;
4,983✔
4860

4861
  while (numOfRows < rows) {
37,892✔
4862
    if (fetchNextInstance) {
37,892✔
4863
      pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pObj);
37,892✔
4864
      if (pShow->pIter == NULL) break;
37,892✔
4865
    } else {
UNCOV
4866
      fetchNextInstance = true;
×
UNCOV
4867
      void *pKey = taosHashGetKey(pShow->pIter, NULL);
×
UNCOV
4868
      if (!(pObj = sdbAcquire(pSdb, SDB_USER, pKey))) {
×
UNCOV
4869
        continue;
×
4870
      }
4871
    }
4872

4873
    int32_t nSysPrivileges = 0, nObjPrivileges = 0;
32,909✔
4874
    if (nSysPrivileges + nObjPrivileges >= rows) {
32,909✔
UNCOV
4875
      pShow->restore = true;
×
UNCOV
4876
      sdbRelease(pSdb, pObj);
×
UNCOV
4877
      break;
×
4878
    }
4879

4880
    if (!pBuf && !(pBuf = taosMemoryMalloc(bufSize))) {
32,909✔
UNCOV
4881
      sdbCancelFetch(pSdb, pShow->pIter);
×
UNCOV
4882
      sdbRelease(pSdb, pObj);
×
UNCOV
4883
      TAOS_CHECK_EXIT(terrno);
×
4884
    }
4885

4886
    cols = 0;
32,909✔
4887
    STR_WITH_MAXSIZE_TO_VARSTR(roleName, pObj->name, pShow->pMeta->pSchemas[cols].bytes);
32,909✔
4888

4889
    // system privileges
4890
    SPrivIter privIter = {0};
32,909✔
4891
    privIterInit(&privIter, &pObj->sysPrivs);
32,909✔
4892
    SPrivInfo *pPrivInfo = NULL;
32,909✔
4893
    while (privIterNext(&privIter, &pPrivInfo)) {
34,781✔
4894
      cols = 0;
1,872✔
4895
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
1,872✔
4896
      COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
1,872✔
4897

4898
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
1,872✔
4899
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, pPrivInfo->name, pShow->pMeta->pSchemas[cols].bytes);
1,872✔
4900
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
1,872✔
4901
      }
4902
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
1,872✔
4903
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privObjGetName(PRIV_OBJ_CLUSTER), pShow->pMeta->pSchemas[cols].bytes);
1,872✔
4904
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
1,872✔
4905
      }
4906
      // skip db, table, condition, notes, columns, update_time
4907
      COL_DATA_SET_EMPTY_VARCHAR(pBuf, 6);
13,104✔
4908
      numOfRows++;
1,872✔
4909
    }
4910

4911
    // object privileges
4912
    void *pIter = NULL;
32,909✔
4913
    while ((pIter = taosHashIterate(pObj->objPrivs, pIter))) {
52,716✔
4914
      SPrivObjPolicies *pPolices = (SPrivObjPolicies *)pIter;
19,807✔
4915

4916
      char   *key = taosHashGetKey(pPolices, NULL);
19,807✔
4917
      int32_t objType = PRIV_OBJ_UNKNOWN;
19,807✔
4918
      char    dbName[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
19,807✔
4919
      char    tblName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
19,807✔
4920
      if ((code = privObjKeyParse(key, &objType, dbName, sizeof(dbName), tblName, sizeof(tblName), false))) {
19,807✔
UNCOV
4921
        sdbRelease(pSdb, pObj);
×
UNCOV
4922
        sdbCancelFetch(pSdb, pShow->pIter);
×
UNCOV
4923
        TAOS_CHECK_EXIT(code);
×
4924
      }
4925

4926
      SPrivIter privIter = {0};
19,807✔
4927
      privIterInit(&privIter, &pPolices->policy);
19,807✔
4928
      SPrivInfo *pPrivInfo = NULL;
19,807✔
4929
      while (privIterNext(&privIter, &pPrivInfo)) {
111,355✔
4930
        cols = 0;
91,548✔
4931
        SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
91,548✔
4932
        COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
91,548✔
4933

4934
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
91,548✔
4935
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, pPrivInfo->name, pShow->pMeta->pSchemas[cols].bytes);
91,548✔
4936
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
91,548✔
4937
        }
4938

4939
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
91,548✔
4940
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privObjGetName(objType), pShow->pMeta->pSchemas[cols].bytes);
91,548✔
4941
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
91,548✔
4942
        }
4943

4944
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
91,548✔
4945
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, dbName, pShow->pMeta->pSchemas[cols].bytes);
91,548✔
4946
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
91,548✔
4947
        }
4948

4949
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
91,548✔
4950
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, tblName, pShow->pMeta->pSchemas[cols].bytes);
91,548✔
4951
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
91,548✔
4952
        }
4953

4954
        // skip condition, notes, columns, update_time
4955
        COL_DATA_SET_EMPTY_VARCHAR(pBuf, 4);
457,740✔
4956

4957
        numOfRows++;
91,548✔
4958
      }
4959
    }
4960

4961
    // table level privileges
4962
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->selectTbs,
32,909✔
4963
                                           PRIV_TBL_SELECT, pBuf, bufSize, &numOfRows));
4964
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->insertTbs,
32,909✔
4965
                                           PRIV_TBL_INSERT, pBuf, bufSize, &numOfRows));
4966
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->updateTbs,
32,909✔
4967
                                           PRIV_TBL_UPDATE, pBuf, bufSize, &numOfRows));
4968
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->deleteTbs,
32,909✔
4969
                                           PRIV_TBL_DELETE, pBuf, bufSize, &numOfRows));
4970
#if 0
4971
    while ((pIter = taosHashIterate(pObj->selectTbs, pIter))) {
4972
      SPrivTblPolicies *pPolices = (SPrivTblPolicies *)pIter;
4973
      SArray           *tblPolicies = pPolices->policy;
4974

4975
      char   *key = taosHashGetKey(pPolices, NULL);
4976
      int32_t objType = PRIV_OBJ_UNKNOWN;
4977
      char    dbName[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
4978
      char    tblName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4979
      if ((code = privObjKeyParse(key, &objType, dbName, sizeof(dbName), tblName, sizeof(tblName), false))) {
4980
        sdbRelease(pSdb, pObj);
4981
        sdbCancelFetch(pSdb, pShow->pIter);
4982
        TAOS_CHECK_EXIT(code);
4983
      }
4984

4985
      int32_t nTbPolicies = taosArrayGetSize(tblPolicies);
4986
      for (int32_t i = 0; i < nTbPolicies; ++i) {
4987
        SPrivTblPolicy *tbPolicy = (SPrivTblPolicy *)TARRAY_GET_ELEM(tblPolicies, i);
4988
        cols = 0;
4989
        SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
4990
        COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
4991

4992
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
4993
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privInfoGetName(PRIV_TBL_SELECT), pShow->pMeta->pSchemas[cols].bytes);
4994
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
4995
        }
4996

4997
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
4998
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, dbName, pShow->pMeta->pSchemas[cols].bytes);
4999
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
5000
        }
5001

5002
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
5003
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, tblName, pShow->pMeta->pSchemas[cols].bytes);
5004
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
5005
        }
5006

5007
        // skip condition, notes, columns, update_time
5008
        COL_DATA_SET_EMPTY_VARCHAR(pBuf, 4);
5009

5010
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
5011
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privObjGetName(objType), pShow->pMeta->pSchemas[cols].bytes);
5012
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
5013
        }
5014
        numOfRows++;
5015
      }
5016
    }
5017
#endif
5018
    sdbRelease(pSdb, pObj);
32,909✔
5019
  }
5020

5021
  pShow->numOfRows += numOfRows;
4,983✔
5022
_exit:
4,983✔
5023
  taosMemoryFreeClear(pBuf);
4,983✔
5024
  taosMemoryFreeClear(sql);
4,983✔
5025
  if (code < 0) {
4,983✔
UNCOV
5026
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
UNCOV
5027
    TAOS_RETURN(code);
×
5028
  }
5029
  return numOfRows;
4,983✔
5030
}
5031

UNCOV
5032
static void mndCancelGetNextPrivileges(SMnode *pMnode, void *pIter) {
×
UNCOV
5033
  SSdb *pSdb = pMnode->pSdb;
×
UNCOV
5034
  sdbCancelFetchByType(pSdb, pIter, SDB_USER);
×
UNCOV
5035
}
×
5036

5037
int32_t mndValidateUserAuthInfo(SMnode *pMnode, SUserAuthVersion *pUsers, int32_t numOfUses, void **ppRsp,
17,382,134✔
5038
                                int32_t *pRspLen, int64_t ipWhiteListVer) {
5039
  int32_t           code = 0;
17,382,134✔
5040
  int32_t           lino = 0;
17,382,134✔
5041
  int32_t           rspLen = 0;
17,382,134✔
5042
  void             *pRsp = NULL;
17,382,134✔
5043
  SUserAuthBatchRsp batchRsp = {0};
17,382,134✔
5044

5045
  batchRsp.pArray = taosArrayInit(numOfUses, sizeof(SGetUserAuthRsp));
17,382,134✔
5046
  if (batchRsp.pArray == NULL) {
17,382,134✔
UNCOV
5047
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
5048
  }
5049
  int64_t now = taosGetTimestampMs();
17,382,134✔
5050
  for (int32_t i = 0; i < numOfUses; ++i) {
34,818,890✔
5051
    SUserObj *pUser = NULL;
17,436,756✔
5052
    code = mndAcquireUser(pMnode, pUsers[i].user, &pUser);
17,436,756✔
5053
    if (pUser == NULL) {
17,436,274✔
5054
      if (TSDB_CODE_MND_USER_NOT_EXIST == code) {
324✔
5055
        SGetUserAuthRsp rsp = {.dropped = 1};
324✔
5056
        (void)memcpy(rsp.user, pUsers[i].user, TSDB_USER_LEN);
324✔
5057
        TSDB_CHECK_NULL(taosArrayPush(batchRsp.pArray, &rsp), code, lino, _OVER, TSDB_CODE_OUT_OF_MEMORY);
648✔
5058
      }
5059
      mError("user:%s, failed to auth user since %s", pUsers[i].user, tstrerror(code));
324✔
5060
      code = 0;
324✔
5061
      continue;
2,036✔
5062
    }
5063

5064
    pUsers[i].version = ntohl(pUsers[i].version);
17,435,950✔
5065
    if ((pUser->authVersion <= pUsers[i].version) && (ipWhiteListVer == pMnode->ipWhiteVer) &&
17,435,950✔
5066
        !mndNeedRetrieveRole(pUser)) {
16,779,848✔
5067
      mndReleaseUser(pMnode, pUser);
16,690,279✔
5068
      continue;
16,690,279✔
5069
    }
5070

5071
    SGetUserAuthRsp rsp = {0};
746,153✔
5072
    code = mndSetUserAuthRsp(pMnode, pUser, &rsp);
746,153✔
5073
    if (code) {
746,153✔
UNCOV
5074
      mndReleaseUser(pMnode, pUser);
×
UNCOV
5075
      tFreeSGetUserAuthRsp(&rsp);
×
UNCOV
5076
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
5077
    }
5078

5079
    if (!(taosArrayPush(batchRsp.pArray, &rsp))) {
1,492,306✔
UNCOV
5080
      code = terrno;
×
UNCOV
5081
      mndReleaseUser(pMnode, pUser);
×
UNCOV
5082
      tFreeSGetUserAuthRsp(&rsp);
×
UNCOV
5083
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
5084
    }
5085
    pUser->lastRoleRetrieve = now;  // update user's last retrieve time
746,153✔
5086
    mndReleaseUser(pMnode, pUser);
746,153✔
5087
  }
5088

5089
  if (taosArrayGetSize(batchRsp.pArray) <= 0) {
17,382,134✔
5090
    *ppRsp = NULL;
16,674,635✔
5091
    *pRspLen = 0;
16,674,635✔
5092

5093
    tFreeSUserAuthBatchRsp(&batchRsp);
16,674,635✔
5094
    return 0;
16,674,635✔
5095
  }
5096

5097
  rspLen = tSerializeSUserAuthBatchRsp(NULL, 0, &batchRsp);
707,499✔
5098
  if (rspLen < 0) {
707,499✔
UNCOV
5099
    TAOS_CHECK_GOTO(rspLen, &lino, _OVER);
×
5100
  }
5101
  pRsp = taosMemoryMalloc(rspLen);
707,499✔
5102
  if (pRsp == NULL) {
707,499✔
UNCOV
5103
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
5104
  }
5105
  rspLen = tSerializeSUserAuthBatchRsp(pRsp, rspLen, &batchRsp);
707,499✔
5106
  if (rspLen < 0) {
707,499✔
UNCOV
5107
    TAOS_CHECK_GOTO(rspLen, &lino, _OVER);
×
5108
  }
5109
_OVER:
707,499✔
5110
  tFreeSUserAuthBatchRsp(&batchRsp);
707,499✔
5111
  if (code < 0) {
707,344✔
UNCOV
5112
    for (int32_t i = 0; i < numOfUses; ++i) {
×
UNCOV
5113
      SUserObj *pUser = NULL;
×
UNCOV
5114
      if (mndAcquireUser(pMnode, pUsers[i].user, &pUser) != 0) {
×
UNCOV
5115
        continue;
×
5116
      }
UNCOV
5117
      pUser->lastRoleRetrieve = 0;  // reset last retrieve time on error
×
UNCOV
5118
      mndReleaseUser(pMnode, pUser);
×
5119
    }
UNCOV
5120
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
UNCOV
5121
    taosMemoryFreeClear(pRsp);
×
UNCOV
5122
    rspLen = 0;
×
5123
  }
5124
  *ppRsp = pRsp;
707,344✔
5125
  *pRspLen = rspLen;
707,499✔
5126

5127
  TAOS_RETURN(code);
707,344✔
5128
}
5129

UNCOV
5130
static int32_t mndRemoveDbPrivileges(SHashObj *pHash, const char *dbFName, int32_t dbFNameLen, int32_t *nRemoved) {
×
UNCOV
5131
  void *pVal = NULL;
×
UNCOV
5132
  while ((pVal = taosHashIterate(pHash, pVal))) {
×
UNCOV
5133
    size_t keyLen = 0;
×
UNCOV
5134
    char  *pKey = (char *)taosHashGetKey(pVal, &keyLen);
×
UNCOV
5135
    if (pKey == NULL || keyLen <= dbFNameLen) continue;
×
UNCOV
5136
    if ((*(pKey + dbFNameLen) == '.') && strncmp(pKey, dbFName, dbFNameLen) == 0) {
×
UNCOV
5137
      TAOS_CHECK_RETURN(taosHashRemove(pHash, pKey, keyLen));
×
UNCOV
5138
      if (nRemoved) ++(*nRemoved);
×
5139
    }
5140
  }
UNCOV
5141
  TAOS_RETURN(0);
×
5142
}
5143

UNCOV
5144
int32_t mndUserDropRole(SMnode *pMnode, STrans *pTrans, SRoleObj *pObj) {
×
UNCOV
5145
  int32_t   code = 0, lino = 0;
×
UNCOV
5146
  SSdb     *pSdb = pMnode->pSdb;
×
UNCOV
5147
  SUserObj *pUser = NULL;
×
UNCOV
5148
  void     *pIter = NULL;
×
5149

UNCOV
5150
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser))) {
×
UNCOV
5151
    SHashObj *pRole = taosHashGet(pUser->roles, pObj->name, strlen(pObj->name) + 1);
×
UNCOV
5152
    if (!pRole) {
×
UNCOV
5153
      sdbRelease(pSdb, pUser);
×
UNCOV
5154
      pUser = NULL;
×
UNCOV
5155
      continue;
×
5156
    }
5157

UNCOV
5158
    SUserObj newUser = {0};
×
UNCOV
5159
    TAOS_CHECK_EXIT(mndUserDupObj(pUser, &newUser));
×
UNCOV
5160
    code = taosHashRemove(newUser.roles, pObj->name, strlen(pObj->name) + 1);
×
UNCOV
5161
    if (code == TSDB_CODE_NOT_FOUND) {
×
UNCOV
5162
      sdbRelease(pSdb, pUser);
×
UNCOV
5163
      pUser = NULL;
×
UNCOV
5164
      mndUserFreeObj(&newUser);
×
UNCOV
5165
      continue;
×
5166
    }
UNCOV
5167
    if (code != 0) {
×
UNCOV
5168
      mndUserFreeObj(&newUser);
×
UNCOV
5169
      TAOS_CHECK_EXIT(code);
×
5170
    }
UNCOV
5171
    SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
×
UNCOV
5172
    if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
×
UNCOV
5173
      mndUserFreeObj(&newUser);
×
UNCOV
5174
      TAOS_CHECK_EXIT(TSDB_CODE_OUT_OF_MEMORY);
×
5175
    }
UNCOV
5176
    if ((code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY))) {
×
UNCOV
5177
      mndUserFreeObj(&newUser);
×
UNCOV
5178
      TAOS_CHECK_EXIT(code);
×
5179
    }
UNCOV
5180
    sdbRelease(pSdb, pUser);
×
UNCOV
5181
    pUser = NULL;
×
UNCOV
5182
    mndUserFreeObj(&newUser);
×
5183
  }
UNCOV
5184
_exit:
×
UNCOV
5185
  if (pIter) sdbCancelFetch(pSdb, pIter);
×
UNCOV
5186
  if (pUser) sdbRelease(pSdb, pUser);
×
UNCOV
5187
  if (code < 0) {
×
UNCOV
5188
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
5189
  }
UNCOV
5190
  TAOS_RETURN(code);
×
5191
}
5192

5193
int32_t mndUserRemoveDb(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SSHashObj **ppUsers) {
580,186✔
5194
  int32_t    code = 0, lino = 0;
580,186✔
5195
  SSdb      *pSdb = pMnode->pSdb;
580,186✔
5196
  int32_t    dbLen = strlen(pDb->name);
580,186✔
5197
  void      *pIter = NULL;
580,186✔
5198
  SUserObj  *pUser = NULL;
580,186✔
5199
  SUserObj   newUser = {0};
580,186✔
5200
  SSHashObj *pUsers = ppUsers ? *ppUsers : NULL;
580,186✔
5201
  bool       output = (ppUsers != NULL);
580,186✔
5202
#ifdef PRIV_TODO
5203
  while (1) {
5204
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
5205
    if (pIter == NULL) break;
5206

5207
    bool update = false;
5208
    bool inReadDb = false; //(taosHashGet(pUser->readDbs, pDb->name, dbLen + 1) != NULL);
5209
    bool inWriteDb = false; //(taosHashGet(pUser->writeDbs, pDb->name, dbLen + 1) != NULL);
5210
    bool inUseDb = (taosHashGet(pUser->useDbs, pDb->name, dbLen + 1) != NULL);
5211
    bool inReadTbs = taosHashGetSize(pUser->selectTbs) > 0;
5212
    bool inWriteTbs = taosHashGetSize(pUser->insertTbs) > 0;
5213
    bool inAlterTbs = taosHashGetSize(pUser->alterTbs) > 0;
5214
    bool inReadViews = taosHashGetSize(pUser->readViews) > 0;
5215
    bool inWriteViews = taosHashGetSize(pUser->writeViews) > 0;
5216
    bool inAlterViews = taosHashGetSize(pUser->alterViews) > 0;
5217
    // no need remove pUser->topics since topics must be dropped ahead of db
5218
    if (!inReadDb && !inWriteDb && !inReadTbs && !inWriteTbs && !inAlterTbs && !inReadViews && !inWriteViews &&
5219
        !inAlterViews) {
5220
      sdbRelease(pSdb, pUser);
5221
      continue;
5222
    }
5223
    SUserObj *pTargetUser = &newUser;
5224
    if (output) {
5225
      if (!pUsers) {
5226
        TSDB_CHECK_NULL(pUsers = tSimpleHashInit(32, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY)), code, lino,
5227
                        _exit, TSDB_CODE_OUT_OF_MEMORY);
5228
        *ppUsers = pUsers;
5229
      }
5230
      void   *pVal = NULL;
5231
      int32_t userLen = strlen(pUser->user) + 1;
5232
      if ((pVal = tSimpleHashGet(pUsers, pUser->user, userLen)) != NULL) {
5233
        pTargetUser = (SUserObj *)pVal;
5234
      } else {
5235
        TAOS_CHECK_EXIT(mndUserDupObj(pUser, &newUser));
5236
        TAOS_CHECK_EXIT(tSimpleHashPut(pUsers, pUser->user, userLen, &newUser, sizeof(SUserObj)));
5237
        TSDB_CHECK_NULL((pVal = tSimpleHashGet(pUsers, pUser->user, userLen)), code, lino, _exit,
5238
                        TSDB_CODE_OUT_OF_MEMORY);
5239
        pTargetUser = (SUserObj *)pVal;
5240
      }
5241
    } else {
5242
      TAOS_CHECK_EXIT(mndUserDupObj(pUser, &newUser));
5243
    }
5244
    if (inReadDb) {
5245
      // TAOS_CHECK_EXIT(taosHashRemove(pTargetUser->readDbs, pDb->name, dbLen + 1));
5246
    }
5247
    if (inWriteDb) {
5248
      // TAOS_CHECK_EXIT(taosHashRemove(pTargetUser->writeDbs, pDb->name, dbLen + 1));
5249
    }
5250
    if (inUseDb) {
5251
      TAOS_CHECK_EXIT(taosHashRemove(pTargetUser->useDbs, pDb->name, dbLen + 1));
5252
    }
5253
    update = inReadDb || inWriteDb || inUseDb;
5254

5255
    int32_t nRemovedReadTbs = 0;
5256
    int32_t nRemovedWriteTbs = 0;
5257
    int32_t nRemovedAlterTbs = 0;
5258
    if (inReadTbs || inWriteTbs || inAlterTbs) {
5259
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->selectTbs, pDb->name, dbLen, &nRemovedReadTbs));
5260
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->insertTbs, pDb->name, dbLen, &nRemovedWriteTbs));
5261
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->alterTbs, pDb->name, dbLen, &nRemovedAlterTbs));
5262
      if (!update) update = nRemovedReadTbs > 0 || nRemovedWriteTbs > 0 || nRemovedAlterTbs > 0;
5263
    }
5264

5265
    int32_t nRemovedReadViews = 0;
5266
    int32_t nRemovedWriteViews = 0;
5267
    int32_t nRemovedAlterViews = 0;
5268
    if (inReadViews || inWriteViews || inAlterViews) {
5269
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->readViews, pDb->name, dbLen, &nRemovedReadViews));
5270
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->writeViews, pDb->name, dbLen, &nRemovedWriteViews));
5271
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->alterViews, pDb->name, dbLen, &nRemovedAlterViews));
5272
      if (!update) update = nRemovedReadViews > 0 || nRemovedWriteViews > 0 || nRemovedAlterViews > 0;
5273
    }
5274

5275
    if (!output) {
5276
      if (update) {
5277
        SSdbRaw *pCommitRaw = mndUserActionEncode(pTargetUser);
5278
        if (pCommitRaw == NULL) {
5279
          TAOS_CHECK_EXIT(terrno);
5280
        }
5281
        TAOS_CHECK_EXIT(mndTransAppendCommitlog(pTrans, pCommitRaw));
5282
        TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
5283
      }
5284
      mndUserFreeObj(&newUser);
5285
    }
5286
    sdbRelease(pSdb, pUser);
5287
  }
5288
#endif
5289
_exit:
580,186✔
5290
  if (code < 0) {
580,186✔
UNCOV
5291
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
UNCOV
5292
    mndUserFreeObj(&newUser);
×
5293
  }
5294
  if (pUser != NULL) sdbRelease(pSdb, pUser);
580,186✔
5295
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
580,186✔
5296
  if (!output) mndUserFreeObj(&newUser);
580,186✔
5297
  TAOS_RETURN(code);
580,186✔
5298
}
5299

5300
int32_t mndUserRemoveStb(SMnode *pMnode, STrans *pTrans, char *stb) {
422,094✔
5301
  int32_t   code = 0;
422,094✔
5302
  SSdb     *pSdb = pMnode->pSdb;
422,094✔
5303
  int32_t   len = strlen(stb) + 1;
422,094✔
5304
  void     *pIter = NULL;
422,094✔
5305
  SUserObj *pUser = NULL;
422,094✔
5306
  SUserObj  newUser = {0};
422,094✔
5307
#ifdef PRIV_TODO
5308
  while (1) {
5309
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
5310
    if (pIter == NULL) break;
5311

5312
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
5313
      break;
5314
    }
5315

5316
    bool inRead = (taosHashGet(newUser.selectTbs, stb, len) != NULL);
5317
    bool inWrite = (taosHashGet(newUser.insertTbs, stb, len) != NULL);
5318
    bool inAlter = (taosHashGet(newUser.alterTbs, stb, len) != NULL);
5319
    if (inRead || inWrite || inAlter) {
5320
      code = taosHashRemove(newUser.selectTbs, stb, len);
5321
      if (code < 0) {
5322
        mError("failed to remove selectTbs:%s from user:%s", stb, pUser->user);
5323
      }
5324
      code = taosHashRemove(newUser.insertTbs, stb, len);
5325
      if (code < 0) {
5326
        mError("failed to remove insertTbs:%s from user:%s", stb, pUser->user);
5327
      }
5328
      code = taosHashRemove(newUser.alterTbs, stb, len);
5329
      if (code < 0) {
5330
        mError("failed to remove alterTbs:%s from user:%s", stb, pUser->user);
5331
      }
5332

5333
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
5334
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
5335
        code = TSDB_CODE_OUT_OF_MEMORY;
5336
        break;
5337
      }
5338
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
5339
      if (code != 0) {
5340
        mndUserFreeObj(&newUser);
5341
        sdbRelease(pSdb, pUser);
5342
        TAOS_RETURN(code);
5343
      }
5344
    }
5345

5346
    mndUserFreeObj(&newUser);
5347
    sdbRelease(pSdb, pUser);
5348
  }
5349
#endif
5350
  if (pUser != NULL) sdbRelease(pSdb, pUser);
422,094✔
5351
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
422,094✔
5352
  mndUserFreeObj(&newUser);
422,094✔
5353
  TAOS_RETURN(code);
422,094✔
5354
}
5355

UNCOV
5356
int32_t mndUserRemoveView(SMnode *pMnode, STrans *pTrans, char *view) {
×
UNCOV
5357
  int32_t   code = 0;
×
UNCOV
5358
  SSdb     *pSdb = pMnode->pSdb;
×
UNCOV
5359
  int32_t   len = strlen(view) + 1;
×
UNCOV
5360
  void     *pIter = NULL;
×
UNCOV
5361
  SUserObj *pUser = NULL;
×
UNCOV
5362
  SUserObj  newUser = {0};
×
5363
#ifdef PRIV_TODO
5364
  while (1) {
5365
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
5366
    if (pIter == NULL) break;
5367

5368
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
5369
      break;
5370
    }
5371

5372
    bool inRead = (taosHashGet(newUser.readViews, view, len) != NULL);
5373
    bool inWrite = (taosHashGet(newUser.writeViews, view, len) != NULL);
5374
    bool inAlter = (taosHashGet(newUser.alterViews, view, len) != NULL);
5375
    if (inRead || inWrite || inAlter) {
5376
      code = taosHashRemove(newUser.readViews, view, len);
5377
      if (code < 0) {
5378
        mError("failed to remove readViews:%s from user:%s", view, pUser->user);
5379
      }
5380
      code = taosHashRemove(newUser.writeViews, view, len);
5381
      if (code < 0) {
5382
        mError("failed to remove writeViews:%s from user:%s", view, pUser->user);
5383
      }
5384
      code = taosHashRemove(newUser.alterViews, view, len);
5385
      if (code < 0) {
5386
        mError("failed to remove alterViews:%s from user:%s", view, pUser->user);
5387
      }
5388

5389
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
5390
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
5391
        code = TSDB_CODE_OUT_OF_MEMORY;
5392
        break;
5393
      }
5394
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
5395
      if (code < 0) {
5396
        mndUserFreeObj(&newUser);
5397
        sdbRelease(pSdb, pUser);
5398
        TAOS_RETURN(code);
5399
      }
5400
    }
5401

5402
    mndUserFreeObj(&newUser);
5403
    sdbRelease(pSdb, pUser);
5404
  }
5405
#endif
UNCOV
5406
  if (pUser != NULL) sdbRelease(pSdb, pUser);
×
UNCOV
5407
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
×
UNCOV
5408
  mndUserFreeObj(&newUser);
×
UNCOV
5409
  TAOS_RETURN(code);
×
5410
}
5411

5412
int32_t mndUserRemoveTopic(SMnode *pMnode, STrans *pTrans, char *topic) {
91,163✔
5413
  int32_t   code = 0;
91,163✔
5414
  SSdb     *pSdb = pMnode->pSdb;
91,163✔
5415
  int32_t   len = strlen(topic) + 1;
91,163✔
5416
  void     *pIter = NULL;
91,163✔
5417
  SUserObj *pUser = NULL;
91,163✔
5418
  SUserObj  newUser = {0};
91,163✔
5419
#ifdef PRIV_TODO
5420
  while (1) {
5421
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
5422
    if (pIter == NULL) {
5423
      break;
5424
    }
5425

5426
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
5427
      break;
5428
    }
5429

5430
    bool inTopic = (taosHashGet(newUser.topics, topic, len) != NULL);
5431
    if (inTopic) {
5432
      code = taosHashRemove(newUser.topics, topic, len);
5433
      if (code < 0) {
5434
        mError("failed to remove topic:%s from user:%s", topic, pUser->user);
5435
      }
5436
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
5437
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
5438
        code = TSDB_CODE_OUT_OF_MEMORY;
5439
        break;
5440
      }
5441
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
5442
      if (code < 0) {
5443
        mndUserFreeObj(&newUser);
5444
        sdbRelease(pSdb, pUser);
5445
        TAOS_RETURN(code);
5446
      }
5447
    }
5448

5449
    mndUserFreeObj(&newUser);
5450
    sdbRelease(pSdb, pUser);
5451
  }
5452
#endif
5453
  if (pUser != NULL) sdbRelease(pSdb, pUser);
91,163✔
5454
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
91,163✔
5455
  mndUserFreeObj(&newUser);
91,163✔
5456
  TAOS_RETURN(code);
91,163✔
5457
}
5458

UNCOV
5459
int64_t mndGetUserIpWhiteListVer(SMnode *pMnode, SUserObj *pUser) {
×
5460
  // ver = 0, disable ip white list
5461
  // ver > 0, enable ip white list
UNCOV
5462
  return tsEnableWhiteList ? pUser->ipWhiteListVer : 0;
×
5463
}
5464

UNCOV
5465
int64_t mndGetUserTimeWhiteListVer(SMnode *pMnode, SUserObj *pUser) {
×
5466
  // ver = 0, disable datetime white list
5467
  // ver > 0, enable datetime white list
UNCOV
5468
  return tsEnableWhiteList ? pUser->timeWhiteListVer : 0;
×
5469
}
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