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

taosdata / TDengine / #4913

06 Jan 2026 01:30AM UTC coverage: 64.884% (-0.004%) from 64.888%
#4913

push

travis-ci

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

180 of 319 new or added lines in 14 files covered. (56.43%)

571 existing lines in 128 files now uncovered.

195016 of 300563 relevant lines covered (64.88%)

117540852.85 hits per line

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

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

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

35
// clang-format on
36

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

42
#define USER_RESERVE_SIZE                    63
43

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

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

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

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

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

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

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

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

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

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

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

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

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

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

145

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

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

159
static SUserCache userCache;
160

161

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

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

170
  userCache.users = users;
402,071✔
171
  userCache.verIp = 0;
402,071✔
172
  userCache.verTime = 0;
402,071✔
173

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

178

179

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

185
  void *pIter = taosHashIterate(userCache.users, NULL);
402,010✔
186
  while (pIter) {
811,063✔
187
    SCachedUserInfo *pInfo = *(SCachedUserInfo **)pIter;
409,053✔
188
    if (pInfo != NULL) {
409,053✔
189
      taosMemoryFree(pInfo->wlIp);
409,053✔
190
      taosMemoryFree(pInfo->wlTime);
409,053✔
191
      taosMemoryFree(pInfo);
409,053✔
192
    }
193
    pIter = taosHashIterate(userCache.users, pIter);
409,053✔
194
  }
195
  taosHashCleanup(userCache.users);
402,010✔
196

197
  (void)taosThreadRwlockDestroy(&userCache.rw);
402,010✔
198
}
199

200

201

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

205
  (void)taosThreadRwlockWrlock(&userCache.rw);
20,324✔
206

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

221
  (void)taosThreadRwlockUnlock(&userCache.rw);
20,324✔
222
}
20,324✔
223

224

225

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

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

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

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

241

242

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

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

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

260
  return pInfo;
429,377✔
261
}
262

263

264

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

268
  (void)taosThreadRwlockRdlock(&userCache.rw);
2,382,298✔
269

270
  SCachedUserInfo **ppInfo = taosHashGet(userCache.users, user, userLen);
2,382,812✔
271
  if (ppInfo != NULL && *ppInfo != NULL) {
2,382,812✔
272
    pLoginInfo->lastLoginTime = (*ppInfo)->loginInfo.lastLoginTime;
2,102,476✔
273
    pLoginInfo->failedLoginCount = (*ppInfo)->loginInfo.failedLoginCount;
2,101,734✔
274
    pLoginInfo->lastFailedLoginTime = (*ppInfo)->loginInfo.lastFailedLoginTime;
2,101,953✔
275
  } else {
276
    pLoginInfo->lastLoginTime = taosGetTimestampSec();
280,336✔
277
    pLoginInfo->failedLoginCount = 0;
280,336✔
278
    pLoginInfo->lastFailedLoginTime = 0;
280,336✔
279
  }
280

281
  (void)taosThreadRwlockUnlock(&userCache.rw);
2,382,252✔
282

283
  if (pLoginInfo->lastLoginTime == 0) {
2,382,634✔
284
    pLoginInfo->lastLoginTime = taosGetTimestampSec();
26,809✔
285
  }
286
}
2,382,634✔
287

288

289

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

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

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

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

305

306

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

312
  if (a == NULL || b == NULL) {
1,019,962✔
313
    return false;
48,071✔
314
  }
315

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

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

329
  return true;
971,891✔
330
}
331

332

333

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

337
  (void)taosThreadRwlockWrlock(&userCache.rw);
1,019,962✔
338

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

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

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

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

372

373

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

377
  SSdb     *pSdb = pMnode->pSdb;
485,720✔
378
  void     *pIter = NULL;
485,720✔
379
  while (1) {
185,585✔
380
    SUserObj *pUser = NULL;
671,305✔
381
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
671,305✔
382
    if (pIter == NULL) {
671,305✔
383
      break;
485,720✔
384
    }
385

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

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

400
    taosMemoryFree(pInfo->wlIp);
185,585✔
401
    pInfo->wlIp = wl;
185,585✔
402

403
    sdbRelease(pSdb, pUser);
185,585✔
404
  }
405

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

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

415

416

417
int64_t mndGetIpWhiteListVersion(SMnode *pMnode) {
40,291,411✔
418
  int64_t ver = 0;
40,291,411✔
419
  int32_t code = 0;
40,291,411✔
420

421
  if (mndEnableIpWhiteList(pMnode) != 0 && tsEnableWhiteList) {
40,291,411✔
422
    (void)taosThreadRwlockWrlock(&userCache.rw);
4,918✔
423

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

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

438
  mDebug("ip-white-list on mnode ver: %" PRId64, ver);
40,291,411✔
439
  return ver;
40,291,411✔
440
}
441

442

443

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

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

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

458

459

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

463
  SSdb     *pSdb = pMnode->pSdb;
477,126✔
464
  void     *pIter = NULL;
477,126✔
465
  while (1) {
176,991✔
466
    SUserObj *pUser = NULL;
654,117✔
467
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
654,117✔
468
    if (pIter == NULL) {
654,117✔
469
      break;
477,126✔
470
    }
471

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

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

486
    taosMemoryFree(pInfo->wlTime);
176,991✔
487
    pInfo->wlTime = wl;
176,991✔
488

489
    sdbRelease(pSdb, pUser);
176,991✔
490
  }
491

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

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

501

502

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

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

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

517

518

519
int64_t mndGetTimeWhiteListVersion(SMnode *pMnode) {
40,291,411✔
520
  int64_t ver = 0;
40,291,411✔
521
  int32_t code = 0;
40,291,411✔
522

523
  if (mndEnableTimeWhiteList(pMnode) != 0 && tsEnableWhiteList) {
40,291,411✔
524
    (void)taosThreadRwlockWrlock(&userCache.rw);
4,918✔
525

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

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

540
  mDebug("datetime-white-list on mnode ver: %" PRId64, ver);
40,291,411✔
541
  return ver;
40,291,411✔
542
}
543

544

545

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

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

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

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

573
  mndSetMsgHandle(pMnode, TDMT_MND_CREATE_TOTP_SECRET, mndProcessCreateTotpSecretReq);
402,071✔
574
  mndSetMsgHandle(pMnode, TDMT_MND_DROP_TOTP_SECRET, mndProcessDropTotpSecretReq);
402,071✔
575

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

585

586

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

591

592

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

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

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

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

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

613

614

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

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

631

632

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

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

649

650

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

660
  if (a->num != b->num) {
971,891✔
661
    return false;
163✔
662
  }
663
  for (int i = 0; i < a->num; i++) {
2,915,184✔
664
    if (!isIpRangeEqual(&a->pIpRanges[i], &b->pIpRanges[i])) {
1,943,456✔
665
      return false;
×
666
    }
667
  }
668
  return true;
971,728✔
669
}
670

671

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

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

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

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

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

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

704

705

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

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

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

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

727

728

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

736
  TAOS_CHECK_GOTO(tStartEncode(&encoder), &lino, _OVER);
2,192,713✔
737
  TAOS_CHECK_GOTO(tEncodeI32(&encoder, pList->num), &lino, _OVER);
4,385,426✔
738

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

744
  tEndEncode(&encoder);
2,192,713✔
745

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

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

762
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
1,454,927✔
763
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &pList->num), &lino, _OVER);
2,909,854✔
764

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

868
  SIpRange v4 = {0};
336,230✔
869
  SIpRange v6 = {0};
336,230✔
870

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

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

878
#endif
879

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

892

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

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

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

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

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

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

928
  return pos;
×
929
}
930

931

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

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

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

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

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

952
  return 0;
×
953
}
954

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

959

960

961

962
static void dropOldPasswords(SUserObj *pUser) {
3,647,640✔
963
  if (pUser->numOfPasswords <= pUser->passwordReuseMax) {
3,647,640✔
964
    return;
3,642,523✔
965
  }
966

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

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

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

990

991

992

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

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

1009
  userObj.passwords[0].setTime = taosGetTimestampSec();
288,812✔
1010
  userObj.numOfPasswords = 1;
288,812✔
1011

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

1037
  userObj.pTimeWhiteList = taosMemoryCalloc(1, sizeof(SDateTimeWhiteList));
288,812✔
1038
  if (userObj.pTimeWhiteList == NULL) {
288,812✔
1039
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _ERROR);
×
1040
  }
1041
  
1042
  TAOS_CHECK_GOTO(createDefaultIpWhiteList(&userObj.pIpWhiteListDual), &lino, _ERROR);
288,812✔
1043
  if (strcmp(user, TSDB_DEFAULT_USER) == 0) {
288,812✔
1044
    userObj.superUser = 1;
288,812✔
1045
    userObj.createdb = 1;
288,812✔
1046
    userObj.sessionPerUser = -1;
288,812✔
1047
    userObj.callPerSession = -1;
288,812✔
1048
    userObj.vnodePerCall = -1;
288,812✔
1049
    userObj.failedLoginAttempts = -1;
288,812✔
1050
    userObj.passwordLifeTime = -1;
288,812✔
1051
    userObj.passwordLockTime = 1;
288,812✔
1052
    userObj.inactiveAccountTime = -1;
288,812✔
1053
    userObj.allowTokenNum = -1;
288,812✔
1054
    userObj.tokenNum = 0;
288,812✔
1055
  }
1056

1057
  userObj.roles = taosHashInit(1, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
288,812✔
1058
  if (userObj.roles == NULL) {
288,812✔
1059
    TAOS_CHECK_GOTO(terrno, &lino, _ERROR);
×
1060
  }
1061

1062
  if ((code = taosHashPut(userObj.roles, TSDB_ROLE_SYSDBA, strlen(TSDB_ROLE_SYSDBA) + 1, NULL, 0)) ||
577,624✔
1063
      (code = taosHashPut(userObj.roles, TSDB_ROLE_SYSSEC, strlen(TSDB_ROLE_SYSSEC) + 1, NULL, 0)) ||
577,624✔
1064
      (code = taosHashPut(userObj.roles, TSDB_ROLE_SYSAUDIT, strlen(TSDB_ROLE_SYSAUDIT) + 1, NULL, 0))) {
288,812✔
1065
    TAOS_CHECK_GOTO(code, &lino, _ERROR);
×
1066
  }
1067

1068
  SSdbRaw *pRaw = mndUserActionEncode(&userObj);
288,812✔
1069
  if (pRaw == NULL) goto _ERROR;
288,812✔
1070
  TAOS_CHECK_GOTO(sdbSetRawStatus(pRaw, SDB_STATUS_READY), &lino, _ERROR);
288,812✔
1071

1072
  mInfo("user:%s, will be created when deploying, raw:%p", userObj.user, pRaw);
288,812✔
1073

1074
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_ROLE, NULL, "create-user");
288,812✔
1075
  if (pTrans == NULL) {
288,812✔
1076
    sdbFreeRaw(pRaw);
×
1077
    mError("user:%s, failed to create since %s", userObj.user, terrstr());
×
1078
    goto _ERROR;
×
1079
  }
1080
  mInfo("trans:%d, used to create user:%s", pTrans->id, userObj.user);
288,812✔
1081

1082
  if (mndTransAppendCommitlog(pTrans, pRaw) != 0) {
288,812✔
1083
    mError("trans:%d, failed to commit redo log since %s", pTrans->id, terrstr());
×
1084
    mndTransDrop(pTrans);
×
1085
    goto _ERROR;
×
1086
  }
1087
  TAOS_CHECK_GOTO(sdbSetRawStatus(pRaw, SDB_STATUS_READY), &lino, _ERROR);
288,812✔
1088

1089
  if (mndTransPrepare(pMnode, pTrans) != 0) {
288,812✔
1090
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
1091
    mndTransDrop(pTrans);
×
1092
    goto _ERROR;
×
1093
  }
1094

1095
  mndTransDrop(pTrans);
288,812✔
1096
  mndUserFreeObj(&userObj);
288,812✔
1097
  return 0;
288,812✔
1098

1099
_ERROR:
×
1100
  mndUserFreeObj(&userObj);
×
1101
  if (code == 0) {
×
1102
    code = terrno ? terrno : TSDB_CODE_APP_ERROR;
×
1103
  }
1104
  mError("user:%s, failed to create default user since %s", user, tstrerror(code));
×
1105
  TAOS_RETURN(code);
×
1106
}
1107

1108
static int32_t mndCreateDefaultUsers(SMnode *pMnode) {
288,812✔
1109
  return mndCreateDefaultUser(pMnode, TSDB_DEFAULT_USER, TSDB_DEFAULT_USER, TSDB_DEFAULT_PASS);
288,812✔
1110
}
1111

1112
static int32_t tSerializeUserObjExt(void *buf, int32_t bufLen, SUserObj *pObj) {
4,385,426✔
1113
  int32_t  code = 0, lino = 0;
4,385,426✔
1114
  int32_t  tlen = 0;
4,385,426✔
1115
  void    *pIter = NULL;
4,385,426✔
1116
  SEncoder encoder = {0};
4,385,426✔
1117
  tEncoderInit(&encoder, buf, bufLen);
4,385,426✔
1118

1119
  TAOS_CHECK_EXIT(tStartEncode(&encoder));
4,385,426✔
1120
  TAOS_CHECK_EXIT(tEncodeI64v(&encoder, pObj->uid));
8,770,852✔
1121

1122
  TAOS_CHECK_EXIT(tSerializePrivSysObjPolicies(&encoder, &pObj->sysPrivs, pObj->objPrivs));
4,385,426✔
1123

1124
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->selectTbs));
4,385,426✔
1125
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->insertTbs));
4,385,426✔
1126
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->updateTbs));
4,385,426✔
1127
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->deleteTbs));
4,385,426✔
1128

1129
  int32_t nRoles = taosHashGetSize(pObj->roles);
4,385,426✔
1130
  TAOS_CHECK_EXIT(tEncodeI32v(&encoder, nRoles));
4,385,426✔
1131

1132
  while ((pIter = taosHashIterate(pObj->roles, pIter))) {
12,997,614✔
1133
    size_t keyLen = 0;
8,612,188✔
1134
    char  *key = taosHashGetKey(pIter, &keyLen);  // key: role name
8,612,188✔
1135
    TAOS_CHECK_EXIT(tEncodeCStr(&encoder, key));
8,612,188✔
1136

1137
    uint8_t flag = *(int8_t *)pIter;
8,612,188✔
1138
    TAOS_CHECK_EXIT(tEncodeU8(&encoder, flag));  // value: 0 reset, 1 set(default)
17,224,376✔
1139
  }
1140

1141
  tEndEncode(&encoder);
4,385,426✔
1142
  tlen = encoder.pos;
4,385,426✔
1143
_exit:
4,385,426✔
1144
  tEncoderClear(&encoder);
4,385,426✔
1145
  if (code < 0) {
4,385,426✔
1146
    mError("user:%s, %s failed at line %d since %s", pObj->user, __func__, lino, tstrerror(code));
×
1147
    TAOS_RETURN(code);
×
1148
  }
1149

1150
  return tlen;
4,385,426✔
1151
}
1152

1153
static int32_t tDeserializeUserObjExt(void *buf, int32_t bufLen, SUserObj *pObj) {
1,454,927✔
1154
  int32_t  code = 0, lino = 0;
1,454,927✔
1155
  SDecoder decoder = {0};
1,454,927✔
1156
  tDecoderInit(&decoder, buf, bufLen);
1,454,927✔
1157

1158
  TAOS_CHECK_EXIT(tStartDecode(&decoder));
1,454,927✔
1159
  TAOS_CHECK_EXIT(tDecodeI64v(&decoder, &pObj->uid));
2,909,854✔
1160
  TAOS_CHECK_EXIT(tDeserializePrivSysObjPolicies(&decoder, &pObj->sysPrivs, &pObj->objPrivs));
1,454,927✔
1161
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->selectTbs));
1,454,927✔
1162
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->insertTbs));
1,454,927✔
1163
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->updateTbs));
1,454,927✔
1164
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->deleteTbs));
1,454,927✔
1165
  int32_t nRoles = 0;
1,454,927✔
1166
  TAOS_CHECK_EXIT(tDecodeI32v(&decoder, &nRoles));
1,454,927✔
1167
  if (nRoles > 0) {
1,454,927✔
1168
    if (!pObj->roles &&
1,454,766✔
1169
        !(pObj->roles = taosHashInit(nRoles, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), 1, HASH_ENTRY_LOCK))) {
1,454,766✔
1170
      TAOS_CHECK_EXIT(terrno);
×
1171
    }
1172
    for (int32_t i = 0; i < nRoles; i++) {
3,715,582✔
1173
      int32_t keyLen = 0;
2,260,816✔
1174
      char   *key = NULL;
2,260,816✔
1175
      TAOS_CHECK_EXIT(tDecodeCStrAndLen(&decoder, &key, &keyLen));
2,260,816✔
1176
      uint8_t flag = 0;
2,260,816✔
1177
      TAOS_CHECK_EXIT(tDecodeU8(&decoder, &flag));
2,260,816✔
1178
      TAOS_CHECK_EXIT(taosHashPut(pObj->roles, key, keyLen + 1, &flag, sizeof(flag)));
2,260,816✔
1179
    }
1180
  }
1181

1182
_exit:
1,454,927✔
1183
  tEndDecode(&decoder);
1,454,927✔
1184
  tDecoderClear(&decoder);
1,454,927✔
1185
  if (code < 0) {
1,454,927✔
1186
    mError("user, %s failed at line %d since %s, row:%p", __func__, lino, tstrerror(code), pObj);
×
1187
  }
1188
  TAOS_RETURN(code);
1,454,927✔
1189
}
1190

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

1213
  char *stb = NULL;
2,192,713✔
1214
#if 0
1215
  stb = taosHashIterate(pUser->readTbs, NULL);
1216
  while (stb != NULL) {
1217
    size_t keyLen = 0;
1218
    void  *key = taosHashGetKey(stb, &keyLen);
1219
    size += sizeof(int32_t);
1220
    size += keyLen;
1221

1222
    size_t valueLen = 0;
1223
    valueLen = strlen(stb) + 1;
1224
    size += sizeof(int32_t);
1225
    size += valueLen;
1226
    stb = taosHashIterate(pUser->readTbs, stb);
1227
  }
1228

1229
  stb = taosHashIterate(pUser->writeTbs, NULL);
1230
  while (stb != NULL) {
1231
    size_t keyLen = 0;
1232
    void  *key = taosHashGetKey(stb, &keyLen);
1233
    size += sizeof(int32_t);
1234
    size += keyLen;
1235

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

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

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

1263
    size_t valueLen = 0;
1264
    valueLen = strlen(stb) + 1;
1265
    size += sizeof(int32_t);
1266
    size += valueLen;
1267
    stb = taosHashIterate(pUser->readViews, stb);
1268
  }
1269

1270
  stb = taosHashIterate(pUser->writeViews, NULL);
1271
  while (stb != NULL) {
1272
    size_t keyLen = 0;
1273
    void  *key = taosHashGetKey(stb, &keyLen);
1274
    size += sizeof(int32_t);
1275
    size += keyLen;
1276

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

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

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

1298
  int32_t *useDb = taosHashIterate(pUser->useDbs, NULL);
1299
  while (useDb != NULL) {
1300
    size_t keyLen = 0;
1301
    void  *key = taosHashGetKey(useDb, &keyLen);
1302
    size += sizeof(int32_t);
1303
    size += keyLen;
1304
    size += sizeof(int32_t);
1305
    useDb = taosHashIterate(pUser->useDbs, useDb);
1306
  }
1307
#endif
1308
  int32_t sizeExt = tSerializeUserObjExt(NULL, 0, pUser);
2,192,713✔
1309
  if (sizeExt < 0) {
2,192,713✔
1310
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1311
  }
1312
  size += sizeExt;
2,192,713✔
1313

1314
  pRaw = sdbAllocRaw(SDB_USER, USER_VER_NUMBER, size);
2,192,713✔
1315
  if (pRaw == NULL) {
2,192,713✔
1316
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1317
  }
1318

1319
  int32_t dataPos = 0;
2,192,713✔
1320
  SDB_SET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN, _OVER)
2,192,713✔
1321

1322
  dropOldPasswords(pUser);
2,192,713✔
1323
  SDB_SET_INT32(pRaw, dataPos, pUser->numOfPasswords, _OVER)
2,192,713✔
1324
  for (int32_t i = 0; i < pUser->numOfPasswords; i++) {
4,397,687✔
1325
    SDB_SET_BINARY(pRaw, dataPos, pUser->passwords[i].pass, sizeof(pUser->passwords[i].pass), _OVER)
2,204,974✔
1326
    SDB_SET_INT32(pRaw, dataPos, pUser->passwords[i].setTime, _OVER)
2,204,974✔
1327
  }
1328
  SDB_SET_BINARY(pRaw, dataPos, pUser->salt, sizeof(pUser->salt), _OVER)
2,192,713✔
1329

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

1349
  db = taosHashIterate(pUser->writeDbs, NULL);
1350
  while (db != NULL) {
1351
    SDB_SET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER);
1352
    db = taosHashIterate(pUser->writeDbs, db);
1353
  }
1354
  char *topic = taosHashIterate(pUser->topics, NULL);
1355
  while (topic != NULL) {
1356
    SDB_SET_BINARY(pRaw, dataPos, topic, TSDB_TOPIC_FNAME_LEN, _OVER);
1357
    topic = taosHashIterate(pUser->topics, topic);
1358
  }
1359
#endif
1360
  SDB_SET_INT32(pRaw, dataPos, numOfReadTbs, _OVER)
2,192,713✔
1361
  SDB_SET_INT32(pRaw, dataPos, numOfWriteTbs, _OVER)
2,192,713✔
1362
  SDB_SET_INT32(pRaw, dataPos, numOfAlterTbs, _OVER)
2,192,713✔
1363
  SDB_SET_INT32(pRaw, dataPos, numOfReadViews, _OVER)
2,192,713✔
1364
  SDB_SET_INT32(pRaw, dataPos, numOfWriteViews, _OVER)
2,192,713✔
1365
  SDB_SET_INT32(pRaw, dataPos, numOfAlterViews, _OVER)
2,192,713✔
1366
  SDB_SET_INT32(pRaw, dataPos, numOfUseDbs, _OVER)
2,192,713✔
1367

1368
#if 0
1369
  stb = taosHashIterate(pUser->readTbs, NULL);
1370
  while (stb != NULL) {
1371
    size_t keyLen = 0;
1372
    void  *key = taosHashGetKey(stb, &keyLen);
1373
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1374
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1375

1376
    size_t valueLen = 0;
1377
    valueLen = strlen(stb) + 1;
1378
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
1379
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
1380
    stb = taosHashIterate(pUser->readTbs, stb);
1381
  }
1382

1383
  stb = taosHashIterate(pUser->writeTbs, NULL);
1384
  while (stb != NULL) {
1385
    size_t keyLen = 0;
1386
    void  *key = taosHashGetKey(stb, &keyLen);
1387
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1388
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1389

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

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

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

1417
    size_t valueLen = 0;
1418
    valueLen = strlen(stb) + 1;
1419
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
1420
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
1421
    stb = taosHashIterate(pUser->readViews, stb);
1422
  }
1423

1424
  stb = taosHashIterate(pUser->writeViews, NULL);
1425
  while (stb != NULL) {
1426
    size_t keyLen = 0;
1427
    void  *key = taosHashGetKey(stb, &keyLen);
1428
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1429
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1430

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

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

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

1452
  useDb = taosHashIterate(pUser->useDbs, NULL);
1453
  while (useDb != NULL) {
1454
    size_t keyLen = 0;
1455
    void  *key = taosHashGetKey(useDb, &keyLen);
1456
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1457
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1458

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

1473
  SDB_SET_INT32(pRaw, dataPos, len, _OVER);
2,192,713✔
1474
  SDB_SET_BINARY(pRaw, dataPos, buf, len, _OVER);
2,192,713✔
1475

1476
  SDB_SET_INT64(pRaw, dataPos, pUser->ipWhiteListVer, _OVER);
2,192,713✔
1477
  SDB_SET_INT8(pRaw, dataPos, pUser->passEncryptAlgorithm, _OVER);
2,192,713✔
1478

1479
  SDB_SET_BINARY(pRaw, dataPos, pUser->totpsecret, sizeof(pUser->totpsecret), _OVER);
2,192,713✔
1480
  SDB_SET_INT8(pRaw, dataPos, pUser->changePass, _OVER);
2,192,713✔
1481
  SDB_SET_INT32(pRaw, dataPos, pUser->sessionPerUser, _OVER);
2,192,713✔
1482
  SDB_SET_INT32(pRaw, dataPos, pUser->connectTime, _OVER);
2,192,713✔
1483
  SDB_SET_INT32(pRaw, dataPos, pUser->connectIdleTime, _OVER);
2,192,713✔
1484
  SDB_SET_INT32(pRaw, dataPos, pUser->callPerSession, _OVER);
2,192,713✔
1485
  SDB_SET_INT32(pRaw, dataPos, pUser->vnodePerCall, _OVER);
2,192,713✔
1486
  SDB_SET_INT32(pRaw, dataPos, pUser->failedLoginAttempts, _OVER);
2,192,713✔
1487
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordLifeTime, _OVER);
2,192,713✔
1488
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordReuseTime, _OVER);
2,192,713✔
1489
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordReuseMax, _OVER);
2,192,713✔
1490
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordLockTime, _OVER);
2,192,713✔
1491
  SDB_SET_INT32(pRaw, dataPos, pUser->passwordGraceTime, _OVER);
2,192,713✔
1492
  SDB_SET_INT32(pRaw, dataPos, pUser->inactiveAccountTime, _OVER);
2,192,713✔
1493
  SDB_SET_INT32(pRaw, dataPos, pUser->allowTokenNum, _OVER);
2,192,713✔
1494
  SDB_SET_INT32(pRaw, dataPos, pUser->tokenNum, _OVER);
2,192,713✔
1495

1496
  SDB_SET_INT32(pRaw, dataPos, pUser->pTimeWhiteList->num, _OVER);
2,192,713✔
1497
  for (int32_t i = 0; i < pUser->pTimeWhiteList->num; i++) {
2,192,713✔
1498
    SDateTimeWhiteListItem *range = &pUser->pTimeWhiteList->ranges[i];
×
1499
    SDB_SET_BOOL(pRaw, dataPos, range->absolute, _OVER);
×
1500
    SDB_SET_BOOL(pRaw, dataPos, range->neg, _OVER);
×
1501
    SDB_SET_INT64(pRaw, dataPos, range->start, _OVER);
×
1502
    SDB_SET_INT32(pRaw, dataPos, range->duration, _OVER);
×
1503
  }
1504

1505
  sizeExt = tSerializeUserObjExt(buf, sizeExt, pUser);
2,192,713✔
1506
  if (sizeExt < 0) {
2,192,713✔
1507
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1508
  }
1509
  SDB_SET_INT32(pRaw, dataPos, sizeExt, _OVER);
2,192,713✔
1510
  SDB_SET_BINARY(pRaw, dataPos, buf, sizeExt, _OVER);
2,192,713✔
1511

1512
  SDB_SET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
2,192,713✔
1513

1514
  SDB_SET_DATALEN(pRaw, dataPos, _OVER)
2,192,713✔
1515

1516
_OVER:
2,192,713✔
1517
  taosMemoryFree(buf);
2,192,713✔
1518
  if (code < 0) {
2,192,713✔
1519
    mError("user:%s, failed to encode user action to raw:%p at line %d since %s", pUser->user, pRaw, lino,
×
1520
           tstrerror(code));
1521
    sdbFreeRaw(pRaw);
×
1522
    pRaw = NULL;
×
1523
    terrno = code;
×
1524
  }
1525

1526
  mTrace("user:%s, encode user action to raw:%p, row:%p", pUser->user, pRaw, pUser);
2,192,713✔
1527
  return pRaw;
2,192,713✔
1528
}
1529

1530
static SSdbRow *mndUserActionDecode(SSdbRaw *pRaw) {
1,454,927✔
1531
  int32_t   code = 0;
1,454,927✔
1532
  int32_t   lino = 0;
1,454,927✔
1533
  SSdbRow  *pRow = NULL;
1,454,927✔
1534
  SUserObj *pUser = NULL;
1,454,927✔
1535
  char     *key = NULL;
1,454,927✔
1536
  char     *value = NULL;
1,454,927✔
1537

1538
  SHashObj *pReadDbs = NULL;
1,454,927✔
1539
  SHashObj *pWriteDbs = NULL;
1,454,927✔
1540
  SHashObj *pReadTbs = NULL;
1,454,927✔
1541
  SHashObj *pWriteTbs = NULL;
1,454,927✔
1542
  SHashObj *pTopics = NULL;
1,454,927✔
1543
  SHashObj *pAlterTbs = NULL;
1,454,927✔
1544
  SHashObj *pReadViews = NULL;
1,454,927✔
1545
  SHashObj *pWriteViews = NULL;
1,454,927✔
1546
  SHashObj *pAlterViews = NULL;
1,454,927✔
1547
  SHashObj *pUseDbs = NULL;
1,454,927✔
1548

1549
  int8_t sver = 0;
1,454,927✔
1550
  if (sdbGetRawSoftVer(pRaw, &sver) != 0) {
1,454,927✔
1551
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_PTR, &lino, _OVER);
×
1552
  }
1553

1554
  if (sver < 1 || sver > USER_VER_NUMBER) {
1,454,927✔
1555
    TAOS_CHECK_GOTO(TSDB_CODE_SDB_INVALID_DATA_VER, &lino, _OVER);
×
1556
  }
1557

1558
  pRow = sdbAllocRow(sizeof(SUserObj));
1,454,927✔
1559
  if (pRow == NULL) {
1,454,927✔
1560
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1561
  }
1562

1563
  pUser = sdbGetRowObj(pRow);
1,454,927✔
1564
  if (pUser == NULL) {
1,454,927✔
1565
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1566
  }
1567

1568
  int32_t dataPos = 0;
1,454,927✔
1569
  SDB_GET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN, _OVER)
1,454,927✔
1570

1571
  if (sver < USER_VER_SUPPORT_ADVANCED_SECURITY) {
1,454,927✔
1572
    pUser->passwords = taosMemoryCalloc(1, sizeof(SUserPassword));
×
1573
    if (pUser->passwords == NULL) {
×
1574
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
1575
    }
1576
    SDB_GET_BINARY(pRaw, dataPos, pUser->passwords[0].pass, TSDB_PASSWORD_LEN, _OVER)
×
1577
    pUser->numOfPasswords = 1;
×
1578
    memset(pUser->salt, 0, sizeof(pUser->salt));
×
1579
  } else {
1580
    SDB_GET_INT32(pRaw, dataPos, &pUser->numOfPasswords, _OVER)
1,454,927✔
1581
    pUser->passwords = taosMemoryCalloc(pUser->numOfPasswords, sizeof(SUserPassword));
1,454,927✔
1582
    if (pUser->passwords == NULL) {
1,454,927✔
1583
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
1584
    }
1585
    for (int32_t i = 0; i < pUser->numOfPasswords; ++i) {
2,928,256✔
1586
      SDB_GET_BINARY(pRaw, dataPos, pUser->passwords[i].pass, sizeof(pUser->passwords[i].pass), _OVER);
1,473,329✔
1587
      SDB_GET_INT32(pRaw, dataPos, &pUser->passwords[i].setTime, _OVER);
1,473,329✔
1588
    }
1589
    SDB_GET_BINARY(pRaw, dataPos, pUser->salt, sizeof(pUser->salt), _OVER)
1,454,927✔
1590
  }
1591
  
1592
  SDB_GET_BINARY(pRaw, dataPos, pUser->acct, TSDB_USER_LEN, _OVER)
1,454,927✔
1593
  SDB_GET_INT64(pRaw, dataPos, &pUser->createdTime, _OVER)
1,454,927✔
1594
  SDB_GET_INT64(pRaw, dataPos, &pUser->updateTime, _OVER)
1,454,927✔
1595
  if (sver < USER_VER_SUPPORT_ADVANCED_SECURITY) {
1,454,927✔
1596
    pUser->passwords[0].setTime = (int32_t)(pUser->updateTime / 1000);
×
1597
  }
1598

1599
  SDB_GET_INT8(pRaw, dataPos, &pUser->superUser, _OVER)
1,454,927✔
1600
  SDB_GET_INT8(pRaw, dataPos, &pUser->sysInfo, _OVER)
1,454,927✔
1601
  SDB_GET_INT8(pRaw, dataPos, &pUser->enable, _OVER)
1,454,927✔
1602
  SDB_GET_UINT8(pRaw, dataPos, &pUser->flag, _OVER)
1,454,927✔
1603
  if (pUser->superUser) pUser->createdb = 1;
1,454,927✔
1604
  SDB_GET_INT32(pRaw, dataPos, &pUser->authVersion, _OVER)
1,454,927✔
1605
  if (sver >= 4) {
1,454,927✔
1606
    SDB_GET_INT32(pRaw, dataPos, &pUser->passVersion, _OVER)
1,454,927✔
1607
  }
1608

1609
  int32_t numOfReadDbs = 0;
1,454,927✔
1610
  int32_t numOfWriteDbs = 0;
1,454,927✔
1611
  int32_t numOfTopics = 0;
1,454,927✔
1612
  SDB_GET_INT32(pRaw, dataPos, &numOfReadDbs, _OVER)
1,454,927✔
1613
  SDB_GET_INT32(pRaw, dataPos, &numOfWriteDbs, _OVER)
1,454,927✔
1614
  if (sver >= 2) {
1,454,927✔
1615
    SDB_GET_INT32(pRaw, dataPos, &numOfTopics, _OVER)
1,454,927✔
1616
  }
1617

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

1643
  for (int32_t i = 0; i < numOfWriteDbs; ++i) {
1,454,927✔
1644
    char db[TSDB_DB_FNAME_LEN] = {0};
×
1645
    SDB_GET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER)
×
1646
    int32_t len = strlen(db) + 1;
×
1647
    TAOS_CHECK_GOTO(taosHashPut(pWriteDbs, db, len, db, TSDB_DB_FNAME_LEN), &lino, _OVER);
×
1648
  }
1649

1650
  if (sver >= 2) {
1,454,927✔
1651
    for (int32_t i = 0; i < numOfTopics; ++i) {
1,454,927✔
1652
      char topic[TSDB_TOPIC_FNAME_LEN] = {0};
×
1653
      SDB_GET_BINARY(pRaw, dataPos, topic, TSDB_TOPIC_FNAME_LEN, _OVER)
×
1654
      int32_t len = strlen(topic) + 1;
×
1655
      TAOS_CHECK_GOTO(taosHashPut(pTopics, topic, len, topic, TSDB_TOPIC_FNAME_LEN), &lino, _OVER);
×
1656
    }
1657
  }
1658

1659
  if (sver >= 3) {
1,454,927✔
1660
    int32_t numOfReadTbs = 0;
1,454,927✔
1661
    int32_t numOfWriteTbs = 0;
1,454,927✔
1662
    int32_t numOfAlterTbs = 0;
1,454,927✔
1663
    int32_t numOfReadViews = 0;
1,454,927✔
1664
    int32_t numOfWriteViews = 0;
1,454,927✔
1665
    int32_t numOfAlterViews = 0;
1,454,927✔
1666
    int32_t numOfUseDbs = 0;
1,454,927✔
1667
    SDB_GET_INT32(pRaw, dataPos, &numOfReadTbs, _OVER)
1,454,927✔
1668
    SDB_GET_INT32(pRaw, dataPos, &numOfWriteTbs, _OVER)
1,454,927✔
1669
    if (sver >= 6) {
1,454,927✔
1670
      SDB_GET_INT32(pRaw, dataPos, &numOfAlterTbs, _OVER)
1,454,927✔
1671
      SDB_GET_INT32(pRaw, dataPos, &numOfReadViews, _OVER)
1,454,927✔
1672
      SDB_GET_INT32(pRaw, dataPos, &numOfWriteViews, _OVER)
1,454,927✔
1673
      SDB_GET_INT32(pRaw, dataPos, &numOfAlterViews, _OVER)
1,454,927✔
1674
    }
1675
    SDB_GET_INT32(pRaw, dataPos, &numOfUseDbs, _OVER)
1,454,927✔
1676

1677
    if (numOfReadTbs > 0) {
1,454,927✔
1678
      pReadTbs = taosHashInit(numOfReadTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
1679
      if (pReadTbs == NULL) {
×
1680
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1681
      }
1682
    }
1683
    if (numOfWriteTbs > 0) {
1,454,927✔
1684
      pWriteTbs = taosHashInit(numOfWriteTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
1685
      if (pWriteTbs == NULL) {
×
1686
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1687
      }
1688
    }
1689
    pAlterTbs = taosHashInit(numOfAlterTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,454,927✔
1690
    pReadViews = taosHashInit(numOfReadViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,454,927✔
1691
    pWriteViews =
1692
        taosHashInit(numOfWriteViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,454,927✔
1693
    pAlterViews =
1694
        taosHashInit(numOfAlterViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,454,927✔
1695
    pUseDbs = taosHashInit(numOfUseDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,454,927✔
1696

1697
    if (pAlterTbs == NULL || pReadViews == NULL || pWriteViews == NULL || pAlterViews == NULL || pUseDbs == NULL) {
1,454,927✔
1698
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1699
      goto _OVER;
×
1700
    }
1701

1702
    for (int32_t i = 0; i < numOfReadTbs; ++i) {
1,454,927✔
1703
      int32_t keyLen = 0;
×
1704
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
1705

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

1713
      int32_t valuelen = 0;
×
1714
      SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
×
1715
      TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
×
1716
      if (value == NULL) {
×
1717
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1718
      }
1719
      (void)memset(value, 0, valuelen);
×
1720
      SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
×
1721

1722
      TAOS_CHECK_GOTO(taosHashPut(pReadTbs, key, keyLen, value, valuelen), &lino, _OVER);
×
1723
    }
1724

1725
    for (int32_t i = 0; i < numOfWriteTbs; ++i) {
1,454,927✔
1726
      int32_t keyLen = 0;
×
1727
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
1728

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

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

1745
      TAOS_CHECK_GOTO(taosHashPut(pWriteTbs, key, keyLen, value, valuelen), &lino, _OVER);
×
1746
    }
1747

1748
    if (sver >= 6) {
1,454,927✔
1749
      for (int32_t i = 0; i < numOfAlterTbs; ++i) {
1,454,927✔
1750
        int32_t keyLen = 0;
×
1751
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
1752

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

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

1769
        TAOS_CHECK_GOTO(taosHashPut(pAlterTbs, key, keyLen, value, valuelen), &lino, _OVER);
×
1770
      }
1771

1772
      for (int32_t i = 0; i < numOfReadViews; ++i) {
1,454,927✔
1773
        int32_t keyLen = 0;
×
1774
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
1775

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

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

1792
        TAOS_CHECK_GOTO(taosHashPut(pReadViews, key, keyLen, value, valuelen), &lino, _OVER);
×
1793
      }
1794

1795
      for (int32_t i = 0; i < numOfWriteViews; ++i) {
1,454,927✔
1796
        int32_t keyLen = 0;
×
1797
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
1798

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

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

1815
        TAOS_CHECK_GOTO(taosHashPut(pWriteViews, key, keyLen, value, valuelen), &lino, _OVER);
×
1816
      }
1817

1818
      for (int32_t i = 0; i < numOfAlterViews; ++i) {
1,454,927✔
1819
        int32_t keyLen = 0;
×
1820
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
1821

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

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

1838
        TAOS_CHECK_GOTO(taosHashPut(pAlterViews, key, keyLen, value, valuelen), &lino, _OVER);
×
1839
      }
1840
    }
1841

1842
    for (int32_t i = 0; i < numOfUseDbs; ++i) {
1,454,927✔
1843
      int32_t keyLen = 0;
×
1844
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
1845

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

1853
      int32_t ref = 0;
×
1854
      SDB_GET_INT32(pRaw, dataPos, &ref, _OVER);
×
1855

1856
      TAOS_CHECK_GOTO(taosHashPut(pUseDbs, key, keyLen, &ref, sizeof(ref)), &lino, _OVER);
×
1857
    }
1858
  }
1859
  // decoder white list
1860
  if (sver >= USER_VER_SUPPORT_WHITELIST) {
1,454,927✔
1861
    if (sver < USER_VER_SUPPORT_WHITELIT_DUAL_STACK) {
1,454,927✔
1862
      int32_t len = 0;
×
1863
      SDB_GET_INT32(pRaw, dataPos, &len, _OVER);
×
1864

1865
      TAOS_MEMORY_REALLOC(key, len);
×
1866
      if (key == NULL) {
×
1867
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1868
      }
1869
      SDB_GET_BINARY(pRaw, dataPos, key, len, _OVER);
×
1870

1871
      SIpWhiteList *pIpWhiteList = NULL;
×
1872
      TAOS_CHECK_GOTO(createIpWhiteListFromOldVer(key, len, &pIpWhiteList), &lino, _OVER);
×
1873

1874
      SDB_GET_INT64(pRaw, dataPos, &pUser->ipWhiteListVer, _OVER);
×
1875

1876
      code = cvtIpWhiteListToDual(pIpWhiteList, &pUser->pIpWhiteListDual);
×
1877
      if (code != 0) {
×
1878
        taosMemoryFreeClear(pIpWhiteList);
×
1879
      }
1880
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
1881

1882
      taosMemoryFreeClear(pIpWhiteList);
×
1883

1884
    } else if (sver >= USER_VER_SUPPORT_WHITELIT_DUAL_STACK) {
1,454,927✔
1885
      int32_t len = 0;
1,454,927✔
1886
      SDB_GET_INT32(pRaw, dataPos, &len, _OVER);
1,454,927✔
1887

1888
      TAOS_MEMORY_REALLOC(key, len);
1,454,927✔
1889
      if (key == NULL) {
1,454,927✔
1890
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1891
      }
1892
      SDB_GET_BINARY(pRaw, dataPos, key, len, _OVER);
1,454,927✔
1893

1894
      TAOS_CHECK_GOTO(createIpWhiteList(key, len, &pUser->pIpWhiteListDual, sver >= USER_VER_SUPPORT_ADVANCED_SECURITY), &lino, _OVER);
1,454,927✔
1895
      SDB_GET_INT64(pRaw, dataPos, &pUser->ipWhiteListVer, _OVER);
1,454,927✔
1896
    }
1897
  }
1898

1899
  if (pUser->pIpWhiteListDual == NULL) {
1,454,927✔
1900
    TAOS_CHECK_GOTO(createDefaultIpWhiteList(&pUser->pIpWhiteListDual), &lino, _OVER);
×
1901
    pUser->ipWhiteListVer = taosGetTimestampMs();
×
1902
  }
1903

1904
  SDB_GET_INT8(pRaw, dataPos, &pUser->passEncryptAlgorithm, _OVER);
1,454,927✔
1905

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

1943
    int32_t num = 0;
1,454,927✔
1944
    SDB_GET_INT32(pRaw, dataPos, &num, _OVER);
1,454,927✔
1945
    pUser->pTimeWhiteList = taosMemCalloc(1, sizeof(SDateTimeWhiteList) + num * sizeof(SDateTimeWhiteListItem));
1,454,927✔
1946
    if (pUser->pTimeWhiteList == NULL) {
1,454,927✔
1947
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1948
    }
1949

1950
    pUser->pTimeWhiteList->num = num;
1,454,927✔
1951
    for (int32_t i = 0; i < num; i++) {
1,454,927✔
1952
      SDateTimeWhiteListItem *range = &pUser->pTimeWhiteList->ranges[i];
×
1953
      SDB_GET_BOOL(pRaw, dataPos, &range->absolute, _OVER);
×
1954
      SDB_GET_BOOL(pRaw, dataPos, &range->neg, _OVER);
×
1955
      SDB_GET_INT64(pRaw, dataPos, &range->start, _OVER);
×
1956
      SDB_GET_INT32(pRaw, dataPos, &range->duration, _OVER);
×
1957
    }
1958

1959
    int32_t extLen = 0;
1,454,927✔
1960
    SDB_GET_INT32(pRaw, dataPos, &extLen, _OVER);
1,454,927✔
1961
    TAOS_MEMORY_REALLOC(key, extLen);
1,454,927✔
1962
    if (key == NULL) {
1,454,927✔
1963
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1964
    }
1965
    SDB_GET_BINARY(pRaw, dataPos, key, extLen, _OVER);
1,454,927✔
1966
    TAOS_CHECK_GOTO(tDeserializeUserObjExt(key, extLen, pUser), &lino, _OVER);
1,454,927✔
1967
  }
1968

1969
  SDB_GET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
1,454,927✔
1970

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

1998
  mTrace("user:%s, decode from raw:%p, row:%p", pUser->user, pRaw, pUser);
1,454,927✔
1999
  return pRow;
1,454,927✔
2000
}
2001

2002
static int32_t mndUserActionInsert(SSdb *pSdb, SUserObj *pUser) {
455,338✔
2003
  mTrace("user:%s, perform insert action, row:%p", pUser->user, pUser);
455,338✔
2004

2005
  SAcctObj *pAcct = sdbAcquire(pSdb, SDB_ACCT, pUser->acct);
455,338✔
2006
  if (pAcct == NULL) {
455,338✔
2007
    terrno = TSDB_CODE_MND_ACCT_NOT_EXIST;
×
2008
    mError("user:%s, failed to perform insert action since %s", pUser->user, terrstr());
×
2009
    TAOS_RETURN(terrno);
×
2010
  }
2011
  pUser->acctId = pAcct->acctId;
455,338✔
2012
  sdbRelease(pSdb, pAcct);
455,338✔
2013

2014
  return 0;
455,338✔
2015
}
2016

2017
int32_t mndDupTableHash(SHashObj *pOld, SHashObj **ppNew) {
×
2018
  int32_t code = 0;
×
2019
  *ppNew =
×
2020
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
2021
  if (*ppNew == NULL) {
×
2022
    TAOS_RETURN(terrno);
×
2023
  }
2024

2025
  char *tb = taosHashIterate(pOld, NULL);
×
2026
  while (tb != NULL) {
×
2027
    size_t keyLen = 0;
×
2028
    char  *key = taosHashGetKey(tb, &keyLen);
×
2029

2030
    int32_t valueLen = strlen(tb) + 1;
×
2031
    if ((code = taosHashPut(*ppNew, key, keyLen, tb, valueLen)) != 0) {
×
2032
      taosHashCancelIterate(pOld, tb);
×
2033
      taosHashCleanup(*ppNew);
×
2034
      TAOS_RETURN(code);
×
2035
    }
2036
    tb = taosHashIterate(pOld, tb);
×
2037
  }
2038

2039
  TAOS_RETURN(code);
×
2040
}
2041

2042
int32_t mndDupUseDbHash(SHashObj *pOld, SHashObj **ppNew) {
×
2043
  int32_t code = 0;
×
2044
  *ppNew =
×
2045
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
2046
  if (*ppNew == NULL) {
×
2047
    TAOS_RETURN(terrno);
×
2048
  }
2049

2050
  int32_t *db = taosHashIterate(pOld, NULL);
×
2051
  while (db != NULL) {
×
2052
    size_t keyLen = 0;
×
2053
    char  *key = taosHashGetKey(db, &keyLen);
×
2054

2055
    if ((code = taosHashPut(*ppNew, key, keyLen, db, sizeof(*db))) != 0) {
×
2056
      taosHashCancelIterate(pOld, db);
×
2057
      taosHashCleanup(*ppNew);
×
2058
      TAOS_RETURN(code);
×
2059
    }
2060
    db = taosHashIterate(pOld, db);
×
2061
  }
2062

2063
  TAOS_RETURN(code);
×
2064
}
2065

2066
int32_t mndDupRoleHash(SHashObj *pOld, SHashObj **ppNew) {
973,597✔
2067
  if (!(*ppNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true,
973,597✔
2068
                              HASH_ENTRY_LOCK))) {
2069
    TAOS_RETURN(terrno);
×
2070
  }
2071

2072
  int32_t  code = 0;
973,597✔
2073
  uint8_t *flag = NULL;
973,597✔
2074
  while ((flag = taosHashIterate(pOld, flag))) {
1,947,689✔
2075
    size_t keyLen = 0;
974,092✔
2076
    char  *key = taosHashGetKey(flag, &keyLen);
974,092✔
2077

2078
    if ((code = taosHashPut(*ppNew, key, keyLen, flag, sizeof(*flag))) != 0) {
974,092✔
2079
      taosHashCancelIterate(pOld, flag);
×
2080
      taosHashCleanup(*ppNew);
×
2081
      TAOS_RETURN(code);
×
2082
    }
2083
  }
2084

2085
  TAOS_RETURN(code);
973,597✔
2086
}
2087

2088
int32_t mndMergePrivObjHash(SHashObj *pOld, SHashObj **ppNew) {
21,116,205✔
2089
  if (!(*ppNew)) return mndDupPrivObjHash(pOld, ppNew);
21,116,205✔
2090

2091
  int32_t           code = 0, lino = 0;
21,114,895✔
2092
  SHashObj         *pNew = *ppNew;
21,114,895✔
2093
  SPrivObjPolicies *policies = NULL;
21,115,550✔
2094
  while ((policies = taosHashIterate(pOld, policies))) {
197,023,925✔
2095
    size_t klen = 0;
175,914,597✔
2096
    char  *key = taosHashGetKey(policies, &klen);
175,914,597✔
2097
    size_t vlen = taosHashGetValueSize(policies);
175,913,189✔
2098

2099
    SPrivObjPolicies *pNewPolicies = taosHashGet(pNew, key, klen);
175,911,781✔
2100
    if (pNewPolicies) {
175,915,416✔
2101
      size_t newVlen = taosHashGetValueSize(pNewPolicies);
111,650,988✔
2102
      if (newVlen > 0 && vlen > 0) {
111,650,988✔
2103
        privAddSet(&pNewPolicies->policy, &policies->policy);
111,650,988✔
2104
      }
2105
      continue;
111,646,545✔
2106
    }
2107

2108
    if ((code = taosHashPut(pNew, key, klen, vlen ? policies : NULL, vlen)) != 0) {
64,264,428✔
2109
      taosHashCancelIterate(pOld, policies);
267✔
2110
      taosHashCleanup(pNew);
×
2111
      *ppNew = NULL;
×
2112
      TAOS_RETURN(code);
×
2113
    }
2114
  }
2115

2116
  TAOS_RETURN(code);
21,117,176✔
2117
}
2118

2119
/**
2120
 * 1. Prefer to use SPrivTblPolicies from user object(the updateUs of policy in user object is INT64_MAX)
2121
 * 2. If two or more roles have SPrivTblPolicies, the policy with latest update time take effect.
2122
 */
2123
int32_t mndMergePrivTblHash(SHashObj *pOld, SHashObj **ppNew, bool updateWithLatest) {
63,350,141✔
2124
  if (!(*ppNew)) return mndDupPrivTblHash(pOld, ppNew, false);
63,350,141✔
2125

2126
  int32_t           code = 0, lino = 0;
63,350,141✔
2127
  SHashObj         *pNew = *ppNew;
63,350,141✔
2128
  SPrivTblPolicies *policies = NULL;
63,351,064✔
2129
  while ((policies = taosHashIterate(pOld, policies))) {
63,351,064✔
2130
    size_t klen = 0;
×
2131
    char  *key = taosHashGetKey(policies, &klen);
×
2132
    size_t vlen = taosHashGetValueSize(policies);
×
2133

2134
    SPrivTblPolicies *pNewPolicies = taosHashGet(pNew, key, klen);
×
2135
    if (pNewPolicies) {
×
2136
      size_t newVlen = taosHashGetValueSize(pNewPolicies);
×
2137
      if (newVlen > 0 && vlen > 0) {
×
2138
        TAOS_CHECK_EXIT(privTblPoliciesMerge(pNewPolicies, policies, updateWithLatest));
×
2139
      }
2140
      continue;
×
2141
    }
2142

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

2159
_exit:
63,351,064✔
2160
  TAOS_RETURN(code);
63,351,064✔
2161
}
2162

2163
int32_t mndDupPrivObjHash(SHashObj *pOld, SHashObj **ppNew) {
8,133,578✔
2164
  if (!(*ppNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true,
8,133,578✔
2165
                             HASH_ENTRY_LOCK))) {
2166
    TAOS_RETURN(terrno);
×
2167
  }
2168
  int32_t           code = 0;
8,132,681✔
2169
  SPrivObjPolicies *policies = NULL;
8,132,681✔
2170
  while ((policies = taosHashIterate(pOld, policies))) {
10,820,361✔
2171
    size_t klen = 0;
2,687,680✔
2172
    char  *key = taosHashGetKey(policies, &klen);
2,687,680✔
2173
    size_t vlen = taosHashGetValueSize(policies);
2,687,680✔
2174

2175
    if ((code = taosHashPut(*ppNew, key, klen, vlen > 0 ? policies : NULL, vlen)) != 0) {
2,687,680✔
2176
      taosHashCancelIterate(pOld, policies);
×
2177
      taosHashCleanup(*ppNew);
×
2178
      TAOS_RETURN(code);
×
2179
    }
2180
  }
2181

2182
  TAOS_RETURN(code);
8,133,578✔
2183
}
2184

2185
int32_t mndDupPrivTblHash(SHashObj *pOld, SHashObj **ppNew, bool setUpdateTimeMax) {
25,373,299✔
2186
  if (!(*ppNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true,
25,373,299✔
2187
                              HASH_ENTRY_LOCK))) {
2188
    TAOS_RETURN(terrno);
×
2189
  }
2190
  taosHashSetFreeFp(*ppNew, privTblPoliciesFree);
25,373,591✔
2191

2192
  int32_t           code = 0, lino = 0;
25,374,243✔
2193
  SPrivTblPolicies *policies = NULL, *pTmpPolicies = NULL;
25,374,243✔
2194
  SPrivTblPolicies  tmpPolicies = {0};
25,374,243✔
2195
  while ((policies = taosHashIterate(pOld, policies))) {
25,435,277✔
2196
    size_t klen = 0;
61,034✔
2197
    char  *key = taosHashGetKey(policies, &klen);
61,034✔
2198
    size_t vlen = taosHashGetValueSize(policies);
61,034✔
2199
    memset(&tmpPolicies, 0, sizeof(tmpPolicies));
61,034✔
2200
    pTmpPolicies = &tmpPolicies;
61,034✔
2201
    if (vlen > 0) {
61,034✔
2202
      TAOS_CHECK_EXIT(privTblPoliciesAdd(&tmpPolicies, policies, true, setUpdateTimeMax));
61,034✔
2203
    }
2204
    TAOS_CHECK_EXIT(taosHashPut(*ppNew, key, klen, vlen > 0 ? &tmpPolicies : NULL, vlen));
61,034✔
2205
    pTmpPolicies = NULL;
61,034✔
2206
  }
2207

2208
_exit:
25,373,979✔
2209
  if (code != 0) {
25,373,979✔
2210
    if (!pTmpPolicies) {
×
2211
      privTblPoliciesFree(pTmpPolicies);
2212
      pTmpPolicies = NULL;
×
2213
    }
2214
    if (policies) taosHashCancelIterate(pOld, policies);
×
2215
    taosHashCleanup(*ppNew);
×
2216
    *ppNew = NULL;
×
2217
  }
2218
  TAOS_RETURN(code);
25,373,979✔
2219
}
2220

2221
int32_t mndUserDupObj(SUserObj *pUser, SUserObj *pNew) {
972,309✔
2222
  int32_t code = 0;
972,309✔
2223
  (void)memcpy(pNew, pUser, sizeof(SUserObj));
972,309✔
2224
  pNew->authVersion++;
972,309✔
2225
  pNew->updateTime = taosGetTimestampMs();
972,309✔
2226
  taosInitRWLatch(&pNew->lock);
972,309✔
2227

2228
  pNew->passwords = NULL;
972,309✔
2229
  pNew->pIpWhiteListDual = NULL;
972,309✔
2230
  pNew->passwords = NULL;
972,309✔
2231
  pNew->objPrivs = NULL;
972,309✔
2232
  pNew->selectTbs = NULL;
972,309✔
2233
  pNew->insertTbs = NULL;
972,309✔
2234
  pNew->updateTbs = NULL;
972,309✔
2235
  pNew->deleteTbs = NULL;
972,309✔
2236
  pNew->pTimeWhiteList = NULL;
972,309✔
2237
  pNew->roles = NULL;
972,309✔
2238

2239
  taosRLockLatch(&pUser->lock);
972,309✔
2240
  pNew->passwords = taosMemoryCalloc(pUser->numOfPasswords, sizeof(SUserPassword));
972,309✔
2241
  if (pNew->passwords == NULL) {
972,309✔
2242
    code = TSDB_CODE_OUT_OF_MEMORY;
×
2243
    goto _OVER;
×
2244
  }
2245
  (void)memcpy(pNew->passwords, pUser->passwords, pUser->numOfPasswords * sizeof(SUserPassword));
972,309✔
2246
  TAOS_CHECK_GOTO(mndDupPrivObjHash(pUser->objPrivs, &pNew->objPrivs), NULL, _OVER);
972,309✔
2247
  TAOS_CHECK_GOTO(mndDupPrivTblHash(pUser->selectTbs, &pNew->selectTbs, false), NULL, _OVER);
972,309✔
2248
  TAOS_CHECK_GOTO(mndDupPrivTblHash(pUser->insertTbs, &pNew->insertTbs, false), NULL, _OVER);
972,309✔
2249
  TAOS_CHECK_GOTO(mndDupPrivTblHash(pUser->updateTbs, &pNew->updateTbs, false), NULL, _OVER);
972,309✔
2250
  TAOS_CHECK_GOTO(mndDupPrivTblHash(pUser->deleteTbs, &pNew->deleteTbs, false), NULL, _OVER);
972,309✔
2251
  TAOS_CHECK_GOTO(mndDupRoleHash(pUser->roles, &pNew->roles), NULL, _OVER);
972,309✔
2252
  pNew->pIpWhiteListDual = cloneIpWhiteList(pUser->pIpWhiteListDual);
972,309✔
2253
  if (pNew->pIpWhiteListDual == NULL) {
972,309✔
2254
    code = TSDB_CODE_OUT_OF_MEMORY;
×
2255
    goto _OVER;
×
2256
  }
2257

2258
  pNew->pTimeWhiteList = cloneDateTimeWhiteList(pUser->pTimeWhiteList);
972,309✔
2259
  if (pNew->pTimeWhiteList == NULL) {
972,309✔
2260
    code = TSDB_CODE_OUT_OF_MEMORY;
×
2261
    goto _OVER;
×
2262
  }
2263

2264
_OVER:
972,309✔
2265
  taosRUnLockLatch(&pUser->lock);
972,309✔
2266
  TAOS_RETURN(code);
972,309✔
2267
}
2268

2269
void mndUserFreeObj(SUserObj *pUser) {
5,003,171✔
2270
  taosHashCleanup(pUser->objPrivs);
5,003,171✔
2271
  taosHashCleanup(pUser->selectTbs);
5,003,171✔
2272
  taosHashCleanup(pUser->insertTbs);
5,003,171✔
2273
  taosHashCleanup(pUser->updateTbs);
5,003,171✔
2274
  taosHashCleanup(pUser->deleteTbs);
5,003,171✔
2275
  taosHashCleanup(pUser->roles);
5,003,171✔
2276
  taosMemoryFreeClear(pUser->passwords);
5,003,171✔
2277
  taosMemoryFreeClear(pUser->pIpWhiteListDual);
5,003,171✔
2278
  taosMemoryFreeClear(pUser->pTimeWhiteList);
5,003,171✔
2279
  pUser->objPrivs = NULL;
5,003,171✔
2280
  pUser->selectTbs = NULL;
5,003,171✔
2281
  pUser->insertTbs = NULL;
5,003,171✔
2282
  pUser->updateTbs = NULL;
5,003,171✔
2283
  pUser->deleteTbs = NULL;
5,003,171✔
2284
  pUser->roles = NULL;
5,003,171✔
2285
}
5,003,171✔
2286

2287
static int32_t mndUserActionDelete(SSdb *pSdb, SUserObj *pUser) {
1,454,881✔
2288
  mTrace("user:%s, perform delete action, row:%p", pUser->user, pUser);
1,454,881✔
2289
  mndUserFreeObj(pUser);
1,454,881✔
2290
  return 0;
1,454,881✔
2291
}
2292

2293
static int32_t mndUserActionUpdate(SSdb *pSdb, SUserObj *pOld, SUserObj *pNew) {
975,705✔
2294
  mTrace("user:%s, perform update action, old row:%p new row:%p", pOld->user, pOld, pNew);
975,705✔
2295
  taosWLockLatch(&pOld->lock);
975,705✔
2296
  pOld->updateTime = pNew->updateTime;
975,705✔
2297
  pOld->authVersion = pNew->authVersion;
975,705✔
2298
  pOld->passVersion = pNew->passVersion;
975,705✔
2299
  pOld->sysInfo = pNew->sysInfo;
975,705✔
2300
  pOld->enable = pNew->enable;
975,705✔
2301
  pOld->flag = pNew->flag;
975,705✔
2302
  pOld->changePass = pNew->changePass;
975,705✔
2303
  pOld->uid = pNew->uid;
975,705✔
2304

2305
  pOld->sessionPerUser = pNew->sessionPerUser;
975,705✔
2306
  pOld->connectTime = pNew->connectTime;
975,705✔
2307
  pOld->connectIdleTime = pNew->connectIdleTime;
975,705✔
2308
  pOld->callPerSession = pNew->callPerSession;
975,705✔
2309
  pOld->vnodePerCall = pNew->vnodePerCall;
975,705✔
2310
  pOld->failedLoginAttempts = pNew->failedLoginAttempts;
975,705✔
2311
  pOld->passwordLifeTime = pNew->passwordLifeTime;
975,705✔
2312
  pOld->passwordReuseTime = pNew->passwordReuseTime;
975,705✔
2313
  pOld->passwordReuseMax = pNew->passwordReuseMax;
975,705✔
2314
  pOld->passwordLockTime = pNew->passwordLockTime;
975,705✔
2315
  pOld->passwordGraceTime = pNew->passwordGraceTime;
975,705✔
2316
  pOld->inactiveAccountTime = pNew->inactiveAccountTime;
975,705✔
2317
  pOld->allowTokenNum = pNew->allowTokenNum;
975,705✔
2318
  pOld->tokenNum = pNew->tokenNum;
975,705✔
2319

2320
  pOld->numOfPasswords = pNew->numOfPasswords;
975,705✔
2321
  TSWAP(pOld->passwords, pNew->passwords);
975,705✔
2322
  (void)memcpy(pOld->salt, pNew->salt, sizeof(pOld->salt));
975,705✔
2323
  (void)memcpy(pOld->totpsecret, pNew->totpsecret, sizeof(pOld->totpsecret));
975,705✔
2324
  pOld->sysPrivs = pNew->sysPrivs;
975,705✔
2325
  TSWAP(pOld->objPrivs, pNew->objPrivs);
975,705✔
2326
  TSWAP(pOld->selectTbs, pNew->selectTbs);
975,705✔
2327
  TSWAP(pOld->insertTbs, pNew->insertTbs);
975,705✔
2328
  TSWAP(pOld->updateTbs, pNew->updateTbs);
975,705✔
2329
  TSWAP(pOld->deleteTbs, pNew->deleteTbs);
975,705✔
2330
  TSWAP(pOld->roles, pNew->roles);
975,705✔
2331

2332
  TSWAP(pOld->pIpWhiteListDual, pNew->pIpWhiteListDual);
975,705✔
2333
  pOld->ipWhiteListVer = pNew->ipWhiteListVer;
975,705✔
2334
  TSWAP(pOld->pTimeWhiteList, pNew->pTimeWhiteList);
975,705✔
2335
  pOld->timeWhiteListVer = pNew->timeWhiteListVer;
975,705✔
2336
  pOld->passEncryptAlgorithm = pNew->passEncryptAlgorithm;
975,705✔
2337

2338
  taosWUnLockLatch(&pOld->lock);
975,705✔
2339

2340
  return 0;
975,705✔
2341
}
2342

2343
int32_t mndAcquireUser(SMnode *pMnode, const char *userName, SUserObj **ppUser) {
81,190,861✔
2344
  int32_t code = 0;
81,190,861✔
2345
  SSdb   *pSdb = pMnode->pSdb;
81,190,861✔
2346

2347
  *ppUser = sdbAcquire(pSdb, SDB_USER, userName);
81,190,867✔
2348
  if (*ppUser == NULL) {
81,191,894✔
2349
    if (terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
50,035✔
2350
      code = TSDB_CODE_MND_USER_NOT_EXIST;
50,035✔
2351
    } else {
2352
      code = TSDB_CODE_MND_USER_NOT_AVAILABLE;
×
2353
    }
2354
  }
2355
  TAOS_RETURN(code);
81,191,894✔
2356
}
2357

2358
void mndReleaseUser(SMnode *pMnode, SUserObj *pUser) {
88,231,175✔
2359
  SSdb *pSdb = pMnode->pSdb;
88,231,175✔
2360
  sdbRelease(pSdb, pUser);
88,231,623✔
2361
}
88,231,944✔
2362

2363
int32_t mndAcquireUserById(SMnode *pMnode, int64_t userId, SUserObj **ppUser) {
×
2364
  void     *pIter = NULL;
×
2365
  SUserObj *pObj;
×
2366
  SSdb     *pSdb = pMnode->pSdb;
×
2367
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pObj))) {
×
2368
    if (pObj->uid == userId) {
×
2369
      return mndAcquireUser(pMnode, pObj->user, ppUser);
×
2370
    }
2371
  }
2372
  return 0;
×
2373
}
2374

2375
int32_t mndBuildUidNamesHash(SMnode *pMnode, SSHashObj **ppHash) {
477,803✔
2376
  int32_t    code = 0;
477,803✔
2377
  void      *pIter = NULL;
477,803✔
2378
  SUserObj  *pObj;
477,803✔
2379
  SSHashObj *pHash = NULL;
477,803✔
2380

2381
  int32_t nUser = sdbGetSize(pMnode->pSdb, SDB_USER);
477,803✔
2382

2383
  pHash = tSimpleHashInit(nUser, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT));
477,803✔
2384
  if (pHash == NULL) {
477,803✔
2385
    TAOS_RETURN(terrno);
×
2386
  }
2387

2388
  while ((pIter = sdbFetch(pMnode->pSdb, SDB_USER, pIter, (void **)&pObj))) {
967,984✔
2389
    code = tSimpleHashPut(pHash, &pObj->uid, sizeof(pObj->uid), pObj->name, strlen(pObj->name) + 1);
490,181✔
2390
    if (code != 0) {
490,181✔
2391
      sdbRelease(pMnode->pSdb, pObj);
×
2392
      sdbCancelFetch(pMnode->pSdb, pIter);
×
2393
      tSimpleHashCleanup(pHash);
×
2394
      TAOS_RETURN(code);
×
2395
    }
2396
    sdbRelease(pMnode->pSdb, pObj);
490,181✔
2397
  }
2398

2399
  *ppHash = pHash;
477,803✔
2400
  TAOS_RETURN(code);
477,803✔
2401
}
2402

2403
int32_t mndEncryptPass(char *pass, const char* salt, int8_t *algo) {
52,366✔
2404
  int32_t code = 0;
52,366✔
2405
  if (tsMetaKey[0] == '\0') {
52,366✔
2406
    return 0;
52,366✔
2407
  }
2408

2409
  if (salt[0] != 0) {
×
2410
    char passAndSalt[TSDB_PASSWORD_LEN - 1 + TSDB_PASSWORD_SALT_LEN];
×
2411
    (void)memcpy(passAndSalt, pass, TSDB_PASSWORD_LEN - 1);
×
2412
    (void)memcpy(passAndSalt + TSDB_PASSWORD_LEN - 1, salt, TSDB_PASSWORD_SALT_LEN);
×
2413
    taosEncryptPass_c((uint8_t *)passAndSalt, sizeof(passAndSalt), pass);
2414
  }
2415

2416
  unsigned char packetData[TSDB_PASSWORD_LEN] = {0};
×
2417
  SCryptOpts opts = {0};
×
2418
  opts.len = TSDB_PASSWORD_LEN;
×
2419
  opts.source = pass;
×
2420
  opts.result = packetData;
×
2421
  opts.unitLen = TSDB_PASSWORD_LEN;
×
2422
  tstrncpy(opts.key, tsDbKey, ENCRYPT_KEY_LEN + 1);
×
2423
  int newLen = Builtin_CBC_Encrypt(&opts);
×
2424
  if (newLen <= 0) return terrno;
×
2425

2426
  memcpy(pass, packetData, newLen);
×
2427
  if (algo != NULL) {
×
2428
    *algo = DND_CA_SM4;
×
2429
  }
2430

2431
  return 0;
×
2432
}
2433

2434

2435

2436
static void generateSalt(char *salt, size_t len) {
48,235✔
2437
  const char* set = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
48,235✔
2438
  int32_t     setLen = 62;
48,235✔
2439
  for (int32_t i = 0; i < len - 1; ++i) {
1,543,520✔
2440
    salt[i] = set[taosSafeRand() % setLen];
1,495,285✔
2441
  }
2442
  salt[len - 1] = 0;
48,235✔
2443
}
48,235✔
2444

2445

2446

2447
static int32_t addDefaultIpToTable(int8_t enableIpv6, SHashObj *pUniqueTab) {
489✔
2448
  int32_t code = 0;
489✔
2449
  int32_t lino = 0;
489✔
2450
  int32_t dummpy = 0;
489✔
2451

2452
  SIpRange ipv4 = {0}, ipv6 = {0};
489✔
2453
  code = createDefaultIp4Range(&ipv4);
489✔
2454
  TSDB_CHECK_CODE(code, lino, _error);
489✔
2455

2456
  code = taosHashPut(pUniqueTab, &ipv4, sizeof(ipv4), &dummpy, sizeof(dummpy));
489✔
2457
  TSDB_CHECK_CODE(code, lino, _error);
489✔
2458

2459
  if (enableIpv6) {
489✔
2460
    code = createDefaultIp6Range(&ipv6);
×
2461
    TSDB_CHECK_CODE(code, lino, _error);
×
2462

2463
    code = taosHashPut(pUniqueTab, &ipv6, sizeof(ipv6), &dummpy, sizeof(dummpy));
×
2464
    TSDB_CHECK_CODE(code, lino, _error);
×
2465
  }
2466
_error:
489✔
2467
  if (code != 0) {
489✔
2468
    mError("failed to add default ip range to table since %s", tstrerror(code));
×
2469
  }
2470
  return code;
489✔
2471
}
2472

2473
static int32_t mndCreateUser(SMnode *pMnode, char *acct, SCreateUserReq *pCreate, SRpcMsg *pReq) {
47,907✔
2474
  int32_t  code = 0;
47,907✔
2475
  int32_t  lino = 0;
47,907✔
2476
  SUserObj userObj = {0};
47,907✔
2477

2478
  userObj.passwords = taosMemoryCalloc(1, sizeof(SUserPassword));
47,907✔
2479
  if (userObj.passwords == NULL) {
47,907✔
2480
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2481
  }
2482
  userObj.numOfPasswords = 1;
47,907✔
2483

2484
  if (pCreate->isImport == 1) {
47,907✔
2485
    memset(userObj.salt, 0, sizeof(userObj.salt));
×
2486
    memcpy(userObj.passwords[0].pass, pCreate->pass, TSDB_PASSWORD_LEN);
×
2487
  } else {
2488
    generateSalt(userObj.salt, sizeof(userObj.salt));
47,907✔
2489
    taosEncryptPass_c((uint8_t *)pCreate->pass, strlen(pCreate->pass), userObj.passwords[0].pass);
47,907✔
2490
    userObj.passwords[0].pass[sizeof(userObj.passwords[0].pass) - 1] = 0;
47,907✔
2491
    TAOS_CHECK_GOTO(mndEncryptPass(userObj.passwords[0].pass, userObj.salt, &userObj.passEncryptAlgorithm), &lino, _OVER);
47,907✔
2492
  }
2493
  userObj.passwords[0].setTime = taosGetTimestampSec();
47,907✔
2494

2495
  tstrncpy(userObj.user, pCreate->user, TSDB_USER_LEN);
47,907✔
2496
  tstrncpy(userObj.acct, acct, TSDB_USER_LEN);
47,907✔
2497
  if (pCreate->totpseed[0] != 0) {
47,907✔
2498
    int len = taosGenerateTotpSecret(pCreate->totpseed, 0, userObj.totpsecret, sizeof(userObj.totpsecret));
×
2499
    if (len < 0) {
×
2500
      TAOS_CHECK_GOTO(TSDB_CODE_PAR_INVALID_OPTION_VALUE, &lino, _OVER);
×
2501
    }
2502
  }
2503

2504
  userObj.createdTime = taosGetTimestampMs();
47,907✔
2505
  userObj.updateTime = userObj.createdTime;
47,907✔
2506
  userObj.superUser = 0;  // pCreate->superUser;
47,907✔
2507
  userObj.sysInfo = pCreate->sysInfo;
47,907✔
2508
  userObj.enable = pCreate->enable;
47,907✔
2509
  userObj.createdb = pCreate->createDb;
47,907✔
2510
  userObj.uid = mndGenerateUid(userObj.user, strlen(userObj.user));
47,907✔
2511

2512
  userObj.changePass = pCreate->changepass;
47,907✔
2513
  userObj.sessionPerUser = pCreate->sessionPerUser;
47,907✔
2514
  userObj.connectTime = pCreate->connectTime;
47,907✔
2515
  userObj.connectIdleTime = pCreate->connectIdleTime;
47,907✔
2516
  userObj.callPerSession = pCreate->callPerSession;
47,907✔
2517
  userObj.vnodePerCall = pCreate->vnodePerCall;
47,907✔
2518
  userObj.failedLoginAttempts = pCreate->failedLoginAttempts;
47,907✔
2519
  userObj.passwordLifeTime = pCreate->passwordLifeTime;
47,907✔
2520
  userObj.passwordReuseTime = pCreate->passwordReuseTime;
47,907✔
2521
  userObj.passwordReuseMax = pCreate->passwordReuseMax;
47,907✔
2522
  userObj.passwordLockTime = pCreate->passwordLockTime;
47,907✔
2523
  userObj.passwordGraceTime = pCreate->passwordGraceTime;
47,907✔
2524
  userObj.inactiveAccountTime = pCreate->inactiveAccountTime;
47,907✔
2525
  userObj.allowTokenNum = pCreate->allowTokenNum;
47,907✔
2526
  userObj.tokenNum = 0;
47,907✔
2527

2528
  if (pCreate->numIpRanges == 0) {
47,907✔
2529
    TAOS_CHECK_GOTO(createDefaultIpWhiteList(&userObj.pIpWhiteListDual), &lino, _OVER);
47,418✔
2530
  } else {
2531
    SHashObj *pUniqueTab = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
489✔
2532
    if (pUniqueTab == NULL) {
489✔
2533
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2534
    }
2535
    int32_t dummpy = 0;
489✔
2536
    
2537
    for (int i = 0; i < pCreate->numIpRanges; i++) {
1,304✔
2538
      SIpRange range = {0};
815✔
2539
      copyIpRange(&range, pCreate->pIpDualRanges + i);
815✔
2540
      if ((code = taosHashPut(pUniqueTab, &range, sizeof(range), &dummpy, sizeof(dummpy))) != 0) {
815✔
2541
        taosHashCleanup(pUniqueTab);
×
2542
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2543
      }
2544
    }
2545

2546
    code = addDefaultIpToTable(tsEnableIpv6, pUniqueTab);
489✔
2547
    if (code != 0) {
489✔
2548
      taosHashCleanup(pUniqueTab);
×
2549
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2550
    }
2551

2552
    if (taosHashGetSize(pUniqueTab) > MND_MAX_USER_IP_RANGE) {
489✔
2553
      taosHashCleanup(pUniqueTab);
×
2554
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_IP_RANGE, &lino, _OVER);
×
2555
    }
2556

2557
    int32_t           numOfRanges = taosHashGetSize(pUniqueTab);
489✔
2558
    SIpWhiteListDual *p = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + numOfRanges * sizeof(SIpRange));
489✔
2559
    if (p == NULL) {
489✔
2560
      taosHashCleanup(pUniqueTab);
×
2561
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2562
    }
2563

2564
    void   *pIter = taosHashIterate(pUniqueTab, NULL);
489✔
2565
    for (int32_t i = 0; i < numOfRanges; i++) {
1,467✔
2566
      size_t    len = 0;
978✔
2567
      SIpRange *key = taosHashGetKey(pIter, &len);
978✔
2568
      memcpy(&p->pIpRanges[i], key, sizeof(SIpRange));
978✔
2569
      pIter = taosHashIterate(pUniqueTab, pIter);
978✔
2570
    }
2571

2572
    taosHashCleanup(pUniqueTab);
489✔
2573
    p->num = numOfRanges;
489✔
2574
    sortIpWhiteList(p);
489✔
2575
    userObj.pIpWhiteListDual = p;
489✔
2576
  }
2577

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

2595
      // no need to add expired range
2596
      if (isDateTimeWhiteListItemExpired(&range)) {
×
2597
        continue;
×
2598
      }
2599

2600
      if ((code = taosHashPut(pUniqueTab, &range, sizeof(range), &dummpy, sizeof(dummpy))) != 0) {
×
2601
        taosHashCleanup(pUniqueTab);
×
2602
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2603
      }
2604
    }
2605

2606
    if (taosHashGetSize(pUniqueTab) > MND_MAX_USER_TIME_RANGE) {
×
2607
      taosHashCleanup(pUniqueTab);
×
2608
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_TIME_RANGE, &lino, _OVER);
×
2609
    }
2610

2611
    int32_t           numOfRanges = taosHashGetSize(pUniqueTab);
×
2612
    SDateTimeWhiteList *p = taosMemoryCalloc(1, sizeof(SDateTimeWhiteList) + numOfRanges * sizeof(SDateTimeWhiteListItem));
×
2613
    if (p == NULL) {
×
2614
      taosHashCleanup(pUniqueTab);
×
2615
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2616
    }
2617

2618
    void   *pIter = taosHashIterate(pUniqueTab, NULL);
×
2619
    for (int32_t i = 0; i < numOfRanges; i++) {
×
2620
      size_t    len = 0;
×
2621
      SDateTimeWhiteListItem *key = taosHashGetKey(pIter, &len);
×
2622
      memcpy(p->ranges + i, key, sizeof(SDateTimeWhiteListItem));
×
2623
      pIter = taosHashIterate(pUniqueTab, pIter);
×
2624
    }
2625

2626
    taosHashCleanup(pUniqueTab);
×
2627
    p->num = numOfRanges;
×
2628
    sortTimeWhiteList(p);
×
2629
    userObj.pTimeWhiteList = p;
×
2630
  }
2631

2632
  userObj.ipWhiteListVer = taosGetTimestampMs();
47,907✔
2633
  userObj.timeWhiteListVer = userObj.ipWhiteListVer;
47,907✔
2634

2635
  userObj.roles = taosHashInit(1, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
47,907✔
2636
  if (userObj.roles == NULL) {
47,907✔
2637
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2638
  }
2639

2640
  if ((code = taosHashPut(userObj.roles, TSDB_ROLE_SYSINFO_1, strlen(TSDB_ROLE_SYSINFO_1) + 1, NULL, 0)) != 0) {
47,907✔
2641
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2642
  }
2643

2644
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "create-user");
47,907✔
2645
  if (pTrans == NULL) {
47,907✔
2646
    mError("user:%s, failed to create since %s", pCreate->user, terrstr());
×
2647
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2648
  }
2649
  mInfo("trans:%d, used to create user:%s", pTrans->id, pCreate->user);
47,907✔
2650

2651
  SSdbRaw *pCommitRaw = mndUserActionEncode(&userObj);
47,907✔
2652
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
47,907✔
2653
    mError("trans:%d, failed to commit redo log since %s", pTrans->id, terrstr());
×
2654
    mndTransDrop(pTrans);
×
2655
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2656
  }
2657
  TAOS_CHECK_GOTO(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY), &lino, _OVER);
47,907✔
2658

2659
  if (mndTransPrepare(pMnode, pTrans) != 0) {
47,907✔
2660
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
2661
    mndTransDrop(pTrans);
×
2662
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2663
  }
2664

2665
  if ((code = userCacheUpdateWhiteList(pMnode, &userObj)) != 0) {
47,907✔
2666
    mndTransDrop(pTrans);
×
2667
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2668
  }
2669

2670
  mndTransDrop(pTrans);
47,907✔
2671

2672
_OVER:
47,907✔
2673
  mndUserFreeObj(&userObj);
47,907✔
2674
  TAOS_RETURN(code);
47,907✔
2675
}
2676

2677

2678
static int32_t mndCheckPasswordFmt(const char *pwd) {
52,366✔
2679
  if (strcmp(pwd, "taosdata") == 0) {
52,366✔
2680
    return 0;
10,011✔
2681
  }
2682

2683
  if (tsEnableStrongPassword == 0) {
42,355✔
2684
    for (char c = *pwd; c != 0; c = *(++pwd)) {
44,662✔
2685
      if (c == ' ' || c == '\'' || c == '\"' || c == '`' || c == '\\') {
44,173✔
2686
        return TSDB_CODE_MND_INVALID_PASS_FORMAT;
×
2687
      }
2688
    }
2689
    return 0;
489✔
2690
  }
2691

2692
  int32_t len = strlen(pwd);
41,866✔
2693
  if (len < TSDB_PASSWORD_MIN_LEN) {
41,866✔
2694
    return TSDB_CODE_PAR_PASSWD_TOO_SHORT_OR_EMPTY;
×
2695
  }
2696

2697
  if (len > TSDB_PASSWORD_MAX_LEN) {
41,866✔
2698
    return TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG;
×
2699
  }
2700

2701
  if (taosIsComplexString(pwd)) {
41,866✔
2702
    return 0;
41,866✔
2703
  }
2704

2705
  return TSDB_CODE_MND_INVALID_PASS_FORMAT;
×
2706
}
2707

2708

2709

2710
static int32_t mndCheckTotpSeedFmt(const char *seed) {
×
2711
  int32_t len = strlen(seed);
×
2712
  if (len < TSDB_USER_TOTPSEED_MIN_LEN) {
×
2713
    return TSDB_CODE_PAR_OPTION_VALUE_TOO_SHORT;
×
2714
  }
2715

2716
  if (taosIsComplexString(seed)) {
×
2717
    return 0;
×
2718
  }
2719

2720
  return TSDB_CODE_PAR_INVALID_OPTION_VALUE;
×
2721
}
2722

2723

2724

2725
static int32_t mndProcessGetUserDateTimeWhiteListReq(SRpcMsg *pReq) {
×
2726
  SMnode              *pMnode = pReq->info.node;
×
2727
  int32_t              code = 0;
×
2728
  int32_t              lino = 0;
×
2729
  int32_t              contLen = 0;
×
2730
  void                *pRsp = NULL;
×
2731
  SUserObj            *pUser = NULL;
×
2732
  SGetUserWhiteListReq wlReq = {0};
×
2733
  SUserDateTimeWhiteList wlRsp = {0};
×
2734

2735
  if (tDeserializeSGetUserWhiteListReq(pReq->pCont, pReq->contLen, &wlReq) != 0) {
×
2736
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
2737
  }
2738
  mTrace("user: %s, start to get date time whitelist", wlReq.user);
×
2739

2740
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, wlReq.user, &pUser), &lino, _OVER);
×
2741
  TAOS_CHECK_GOTO(mndSetUserDateTimeWhiteListRsp(pMnode, pUser, &wlRsp), &lino, _OVER);
×
2742

2743
  contLen = tSerializeSUserDateTimeWhiteList(NULL, 0, &wlRsp);
×
2744
  if (contLen < 0) {
×
2745
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2746
  }
2747
  pRsp = rpcMallocCont(contLen);
×
2748
  if (pRsp == NULL) {
×
2749
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2750
  }
2751
  
2752
  contLen = tSerializeSUserDateTimeWhiteList(pRsp, contLen, &wlRsp);
×
2753
  if (contLen < 0) {
×
2754
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2755
  }
2756

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

2770
  TAOS_RETURN(code);
×
2771
  return 0;
2772
}
2773

2774

2775

2776
static int32_t buildRetrieveDateTimeWhiteListRsp(SRetrieveDateTimeWhiteListRsp *pRsp) {
570✔
2777
  (void)taosThreadRwlockRdlock(&userCache.rw);
570✔
2778
  
2779
  int32_t count = taosHashGetSize(userCache.users);
570✔
2780
  pRsp->pUsers = taosMemoryCalloc(count, sizeof(SUserDateTimeWhiteList));
570✔
2781
  if (pRsp->pUsers == NULL) {
570✔
2782
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
2783
    TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
2784
  }
2785

2786
  count = 0;
570✔
2787
  void   *pIter = taosHashIterate(userCache.users, NULL);
570✔
2788
  while (pIter) {
1,140✔
2789
    SDateTimeWhiteList *wl = (*(SCachedUserInfo **)pIter)->wlTime;
570✔
2790
    if (wl == NULL || wl->num <= 0) {
570✔
2791
      pIter = taosHashIterate(userCache.users, pIter);
570✔
2792
      continue;
570✔
2793
    }
2794

2795
    SUserDateTimeWhiteList *pUser = &pRsp->pUsers[count];
×
2796
    pUser->ver = userCache.verTime;
×
2797

2798
    size_t klen;
×
2799
    char  *key = taosHashGetKey(pIter, &klen);
×
2800
    (void)memcpy(pUser->user, key, klen);
×
2801

2802
    pUser->numWhiteLists = wl->num;
×
2803
    pUser->pWhiteLists = taosMemoryCalloc(wl->num, sizeof(SDateTimeWhiteListItem));
×
2804
    if (pUser->pWhiteLists == NULL) {
×
2805
      (void)taosThreadRwlockUnlock(&userCache.rw);
×
2806
      TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
2807
    }
2808

2809
    (void)memcpy(pUser->pWhiteLists, wl->ranges, wl->num * sizeof(SDateTimeWhiteListItem));
×
2810
    count++;
×
2811
    pIter = taosHashIterate(userCache.users, pIter);
×
2812
  }
2813

2814
  pRsp->numOfUser = count;
570✔
2815
  pRsp->ver = userCache.verTime;
570✔
2816
  (void)taosThreadRwlockUnlock(&userCache.rw);
570✔
2817
  TAOS_RETURN(0);
570✔
2818
}
2819

2820

2821

2822
static int32_t mndProcessRetrieveDateTimeWhiteListReq(SRpcMsg *pReq) {
570✔
2823
  int32_t        code = 0;
570✔
2824
  int32_t        lino = 0;
570✔
2825
  int32_t        len = 0;
570✔
2826
  void          *pRsp = NULL;
570✔
2827
  SRetrieveDateTimeWhiteListRsp wlRsp = {0};
570✔
2828

2829
  // impl later
2830
  SRetrieveWhiteListReq req = {0};
570✔
2831
  if (tDeserializeRetrieveWhiteListReq(pReq->pCont, pReq->contLen, &req) != 0) {
570✔
2832
    code = TSDB_CODE_INVALID_MSG;
×
2833
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2834
  }
2835

2836
  TAOS_CHECK_GOTO(buildRetrieveDateTimeWhiteListRsp(&wlRsp), &lino, _OVER);
570✔
2837

2838
  len = tSerializeSRetrieveDateTimeWhiteListRsp(NULL, 0, &wlRsp);
570✔
2839
  if (len < 0) {
570✔
2840
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
2841
  }
2842

2843
  pRsp = rpcMallocCont(len);
570✔
2844
  if (!pRsp) {
570✔
2845
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2846
  }
2847
  len = tSerializeSRetrieveDateTimeWhiteListRsp(pRsp, len, &wlRsp);
570✔
2848
  if (len < 0) {
570✔
2849
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
2850
  }
2851

2852
_OVER:
570✔
2853
  if (code < 0) {
570✔
2854
    mError("failed to process retrieve ip white request at line %d since %s", lino, tstrerror(code));
×
2855
    rpcFreeCont(pRsp);
×
2856
    pRsp = NULL;
×
2857
    len = 0;
×
2858
  }
2859
  pReq->code = code;
570✔
2860
  pReq->info.rsp = pRsp;
570✔
2861
  pReq->info.rspLen = len;
570✔
2862

2863
  tFreeSRetrieveDateTimeWhiteListRsp(&wlRsp);
570✔
2864
  TAOS_RETURN(code);
570✔
2865
}
2866

2867

2868

2869
static int32_t mndProcessCreateUserReq(SRpcMsg *pReq) {
47,907✔
2870
  SMnode        *pMnode = pReq->info.node;
47,907✔
2871
  int32_t        code = 0;
47,907✔
2872
  int32_t        lino = 0;
47,907✔
2873
  SRoleObj      *pRole = NULL;
47,907✔
2874
  SUserObj      *pUser = NULL;
47,907✔
2875
  SUserObj      *pOperUser = NULL;
47,907✔
2876
  SCreateUserReq createReq = {0};
47,907✔
2877
  int64_t        tss = taosGetTimestampMs();
47,907✔
2878

2879
  if (tDeserializeSCreateUserReq(pReq->pCont, pReq->contLen, &createReq) != 0) {
47,907✔
2880
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
2881
  }
2882

2883
  mInfo("user:%s, start to create, createdb:%d, is_import:%d", createReq.user, createReq.createDb, createReq.isImport);
47,907✔
2884

2885
#ifndef TD_ENTERPRISE
2886
  if (createReq.isImport == 1) {
2887
    TAOS_CHECK_GOTO(TSDB_CODE_OPS_NOT_SUPPORT, &lino, _OVER);  // enterprise feature
2888
  }
2889
#endif
2890
  code = mndAcquireUser(pMnode, RPC_MSG_USER(pReq), &pOperUser);
47,907✔
2891
  if (pOperUser == NULL) {
47,907✔
2892
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_USER_FROM_CONN, &lino, _OVER);
×
2893
  }
2894

2895
  if (createReq.isImport != 1) {
47,907✔
2896
    // TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, RPC_MSG_USER(pReq), MND_OPER_CREATE_USER), &lino, _OVER);
2897
    TAOS_CHECK_GOTO(mndCheckSysObjPrivilege(pMnode, pOperUser, PRIV_USER_CREATE, 0, 0, NULL, NULL), &lino, _OVER);
47,907✔
2898
  } else if (strcmp(RPC_MSG_USER(pReq), "root") != 0) {
×
2899
    mError("The operation is not permitted to create user:%s", RPC_MSG_USER(pReq));
×
2900
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_RIGHTS, &lino, _OVER);
×
2901
  }
2902

2903
  if (createReq.user[0] == 0) {
47,907✔
2904
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
2905
  }
2906

2907
  if (createReq.isImport != 1) {
47,907✔
2908
    code = mndCheckPasswordFmt(createReq.pass);
47,907✔
2909
    TAOS_CHECK_GOTO(code, &lino, _OVER);
47,907✔
2910
  }
2911

2912
  if (createReq.totpseed[0] != 0) {
47,907✔
2913
    code = mndCheckTotpSeedFmt(createReq.totpseed);
×
2914
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2915
  }
2916

2917
  code = mndAcquireUser(pMnode, createReq.user, &pUser);
47,907✔
2918
  if (pUser != NULL) {
47,907✔
2919
    TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_ALREADY_EXIST, &lino, _OVER);
×
2920
  }
2921

2922
  code = mndAcquireRole(pMnode, createReq.user, &pRole);
47,907✔
2923
  if (pRole != NULL) {
47,907✔
2924
    TAOS_CHECK_GOTO(TSDB_CODE_MND_ROLE_ALREADY_EXIST, &lino, _OVER);
×
2925
  }
2926

2927
  TAOS_CHECK_GOTO(grantCheck(TSDB_GRANT_USER), &lino, _OVER);
47,907✔
2928

2929
  code = mndCreateUser(pMnode, pOperUser->acct, &createReq, pReq);
47,907✔
2930
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
47,907✔
2931

2932
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
47,907✔
2933
    char detail[1000] = {0};
47,907✔
2934
    (void)tsnprintf(detail, sizeof(detail), "enable:%d, superUser:%d, sysInfo:%d, password:xxx", createReq.enable,
47,907✔
2935
                    createReq.superUser, createReq.sysInfo);
47,907✔
2936
    char operation[15] = {0};
47,907✔
2937
    if (createReq.isImport == 1) {
47,907✔
2938
      tstrncpy(operation, "importUser", sizeof(operation));
×
2939
    } else {
2940
      tstrncpy(operation, "createUser", sizeof(operation));
47,907✔
2941
    }
2942

2943
    int64_t tse = taosGetTimestampMs();
47,907✔
2944
    double  duration = (double)(tse - tss);
47,907✔
2945
    duration = duration / 1000;
47,907✔
2946
    auditRecord(pReq, pMnode->clusterId, operation, "", createReq.user, detail, strlen(detail), duration, 0);
47,907✔
2947
  }
2948

2949
_OVER:
47,907✔
2950
  if (code == TSDB_CODE_MND_USER_ALREADY_EXIST && createReq.ignoreExists) {
47,907✔
2951
    code = 0;
×
2952
  } else if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
47,907✔
2953
    mError("user:%s, failed to create at line %d since %s", createReq.user, lino, tstrerror(code));
×
2954
  }
2955

2956
  mndReleaseRole(pMnode, pRole);
47,907✔
2957
  mndReleaseUser(pMnode, pUser);
47,907✔
2958
  mndReleaseUser(pMnode, pOperUser);
47,907✔
2959
  tFreeSCreateUserReq(&createReq);
47,907✔
2960

2961
  TAOS_RETURN(code);
47,907✔
2962
}
2963

2964

2965

2966
static int32_t mndProcessGetUserIpWhiteListReq(SRpcMsg *pReq) {
16,548✔
2967
  SMnode              *pMnode = pReq->info.node;
16,548✔
2968
  int32_t              code = 0;
16,548✔
2969
  int32_t              lino = 0;
16,548✔
2970
  int32_t              contLen = 0;
16,548✔
2971
  void                *pRsp = NULL;
16,548✔
2972
  SUserObj            *pUser = NULL;
16,548✔
2973
  SGetUserWhiteListReq wlReq = {0};
16,548✔
2974
  SGetUserIpWhiteListRsp wlRsp = {0};
16,548✔
2975

2976
  int32_t (*serialFn)(void *, int32_t, SGetUserIpWhiteListRsp *) = NULL;
16,548✔
2977
  int32_t (*setRspFn)(SMnode * pMnode, SUserObj * pUser, SGetUserIpWhiteListRsp * pRsp) = NULL;
16,548✔
2978

2979
  if (pReq->msgType == TDMT_MND_GET_USER_IP_WHITELIST_DUAL) {
16,548✔
2980
    serialFn = tSerializeSGetUserIpWhiteListDualRsp;
16,548✔
2981
    setRspFn = mndSetUserIpWhiteListDualRsp;
16,548✔
2982
  } else {
2983
    serialFn = tSerializeSGetUserIpWhiteListRsp;
×
2984
    setRspFn = mndSetUserIpWhiteListRsp;
×
2985
  }
2986
  if (tDeserializeSGetUserWhiteListReq(pReq->pCont, pReq->contLen, &wlReq) != 0) {
16,548✔
2987
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
2988
  }
2989
  mTrace("user: %s, start to get ip whitelist", wlReq.user);
16,548✔
2990

2991
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, wlReq.user, &pUser), &lino, _OVER);
16,548✔
2992
  TAOS_CHECK_GOTO(setRspFn(pMnode, pUser, &wlRsp), &lino, _OVER);
16,548✔
2993

2994
  contLen = serialFn(NULL, 0, &wlRsp);
16,548✔
2995
  if (contLen < 0) {
16,548✔
2996
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2997
  }
2998
  pRsp = rpcMallocCont(contLen);
16,548✔
2999
  if (pRsp == NULL) {
16,548✔
3000
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3001
  }
3002

3003
  contLen = serialFn(pRsp, contLen, &wlRsp);
16,548✔
3004
  if (contLen < 0) {
16,548✔
3005
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3006
  }
3007

3008
_OVER:
16,548✔
3009
  mndReleaseUser(pMnode, pUser);
16,548✔
3010
  tFreeSGetUserIpWhiteListDualRsp(&wlRsp);
16,548✔
3011
  if (code < 0) {
16,548✔
3012
    mError("user:%s, failed to get whitelist at line %d since %s", wlReq.user, lino, tstrerror(code));
×
3013
    rpcFreeCont(pRsp);
×
3014
    pRsp = NULL;
×
3015
    contLen = 0;
×
3016
  }
3017
  pReq->code = code;
16,548✔
3018
  pReq->info.rsp = pRsp;
16,548✔
3019
  pReq->info.rspLen = contLen;
16,548✔
3020

3021
  TAOS_RETURN(code);
16,548✔
3022
}
3023

3024

3025

3026
static int32_t buildRetrieveIpWhiteListRsp(SUpdateIpWhite *pUpdate) {
570✔
3027
  (void)taosThreadRwlockRdlock(&userCache.rw);
570✔
3028

3029
  int32_t count = taosHashGetSize(userCache.users);
570✔
3030
  pUpdate->pUserIpWhite = taosMemoryCalloc(count, sizeof(SUpdateUserIpWhite));
570✔
3031
  if (pUpdate->pUserIpWhite == NULL) {
570✔
3032
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
3033
    TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
3034
  }
3035

3036
  count = 0;
570✔
3037
  void   *pIter = taosHashIterate(userCache.users, NULL);
570✔
3038
  while (pIter) {
1,140✔
3039
    SIpWhiteListDual   *wl = (*(SCachedUserInfo**)pIter)->wlIp;
570✔
3040
    if (wl == NULL || wl->num <= 0) {
570✔
3041
      pIter = taosHashIterate(userCache.users, pIter);
×
3042
      continue;
×
3043
    }
3044

3045
    SUpdateUserIpWhite *pUser = &pUpdate->pUserIpWhite[count];
570✔
3046
    pUser->ver = userCache.verIp;
570✔
3047

3048
    size_t klen;
570✔
3049
    char  *key = taosHashGetKey(pIter, &klen);
570✔
3050
    (void)memcpy(pUser->user, key, klen);
570✔
3051

3052
    pUser->numOfRange = wl->num;
570✔
3053
    pUser->pIpRanges = taosMemoryCalloc(wl->num, sizeof(SIpRange));
570✔
3054
    if (pUser->pIpRanges == NULL) {
570✔
3055
      (void)taosThreadRwlockUnlock(&userCache.rw);
×
3056
      TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
3057
    }
3058

3059
    (void)memcpy(pUser->pIpRanges, wl->pIpRanges, wl->num * sizeof(SIpRange));
570✔
3060
    count++;
570✔
3061
    pIter = taosHashIterate(userCache.users, pIter);
570✔
3062
  }
3063

3064
  pUpdate->numOfUser = count;
570✔
3065
  pUpdate->ver = userCache.verIp;
570✔
3066
  (void)taosThreadRwlockUnlock(&userCache.rw);
570✔
3067
  TAOS_RETURN(0);
570✔
3068
}
3069

3070

3071

3072
int32_t mndProcessRetrieveIpWhiteListReq(SRpcMsg *pReq) {
570✔
3073
  int32_t        code = 0;
570✔
3074
  int32_t        lino = 0;
570✔
3075
  int32_t        len = 0;
570✔
3076
  void          *pRsp = NULL;
570✔
3077
  SUpdateIpWhite ipWhite = {0};
570✔
3078

3079
  // impl later
3080
  SRetrieveWhiteListReq req = {0};
570✔
3081
  if (tDeserializeRetrieveWhiteListReq(pReq->pCont, pReq->contLen, &req) != 0) {
570✔
3082
    code = TSDB_CODE_INVALID_MSG;
×
3083
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3084
  }
3085

3086
  int32_t (*fn)(void *, int32_t, SUpdateIpWhite *) = NULL;
570✔
3087
  if (pReq->msgType == TDMT_MND_RETRIEVE_IP_WHITELIST) {
570✔
3088
    fn = tSerializeSUpdateIpWhite;
×
3089
  } else if (pReq->msgType == TDMT_MND_RETRIEVE_IP_WHITELIST_DUAL) {
570✔
3090
    fn = tSerializeSUpdateIpWhiteDual;
570✔
3091
  }
3092

3093
  TAOS_CHECK_GOTO(buildRetrieveIpWhiteListRsp(&ipWhite), &lino, _OVER);
570✔
3094

3095
  len = fn(NULL, 0, &ipWhite);
570✔
3096
  if (len < 0) {
570✔
3097
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
3098
  }
3099

3100
  pRsp = rpcMallocCont(len);
570✔
3101
  if (!pRsp) {
570✔
3102
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3103
  }
3104
  len = fn(pRsp, len, &ipWhite);
570✔
3105
  if (len < 0) {
570✔
3106
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
3107
  }
3108

3109
_OVER:
570✔
3110
  if (code < 0) {
570✔
3111
    mError("failed to process retrieve ip white request at line %d since %s", lino, tstrerror(code));
×
3112
    rpcFreeCont(pRsp);
×
3113
    pRsp = NULL;
×
3114
    len = 0;
×
3115
  }
3116
  pReq->code = code;
570✔
3117
  pReq->info.rsp = pRsp;
570✔
3118
  pReq->info.rspLen = len;
570✔
3119

3120
  tFreeSUpdateIpWhiteReq(&ipWhite);
570✔
3121
  TAOS_RETURN(code);
570✔
3122
}
3123

3124
static int32_t mndAlterUser(SMnode *pMnode, SUserObj *pNew, SRpcMsg *pReq) {
972,055✔
3125
  int32_t code = 0, lino = 0;
972,055✔
3126
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "alter-user");
972,055✔
3127
  if (pTrans == NULL) {
972,055✔
3128
    mError("user:%s, failed to alter since %s", pNew->user, terrstr());
×
3129
    TAOS_RETURN(terrno);
×
3130
  }
3131
  mInfo("trans:%d, used to alter user:%s", pTrans->id, pNew->user);
972,055✔
3132

3133
  SSdbRaw *pCommitRaw = mndUserActionEncode(pNew);
972,055✔
3134
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
972,055✔
3135
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
3136
    mndTransDrop(pTrans);
×
3137
    TAOS_RETURN(terrno);
×
3138
  }
3139
  TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
972,055✔
3140

3141
  if (mndTransPrepare(pMnode, pTrans) != 0) {
972,055✔
3142
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
3143
    mndTransDrop(pTrans);
×
3144
    TAOS_RETURN(terrno);
×
3145
  }
3146
  if ((code = userCacheUpdateWhiteList(pMnode, pNew)) != 0) {
972,055✔
3147
    mndTransDrop(pTrans);
×
3148
    TAOS_RETURN(code);
×
3149
  }
3150
_exit:
972,055✔
3151
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
972,055✔
3152
    mError("user:%s, failed to alter at line %d since %s", pNew->user, lino, tstrerror(code));
×
3153
  }
3154
  mndTransDrop(pTrans);
972,055✔
3155
  TAOS_RETURN(code);
972,055✔
3156
}
3157

3158
static int32_t mndDupObjHash(SHashObj *pOld, int32_t dataLen, SHashObj **ppNew) {
×
3159
  int32_t code = 0;
×
3160

3161
  *ppNew =
×
3162
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
3163
  if (*ppNew == NULL) {
×
3164
    code = terrno ? terrno : TSDB_CODE_OUT_OF_MEMORY;
×
3165
    TAOS_RETURN(code);
×
3166
  }
3167

3168
  char *db = taosHashIterate(pOld, NULL);
×
3169
  while (db != NULL) {
×
3170
    int32_t len = strlen(db) + 1;
×
3171
    if ((code = taosHashPut(*ppNew, db, len, db, dataLen)) != 0) {
×
3172
      taosHashCancelIterate(pOld, db);
×
3173
      taosHashCleanup(*ppNew);
×
3174
      TAOS_RETURN(code);
×
3175
    }
3176
    db = taosHashIterate(pOld, db);
×
3177
  }
3178

3179
  TAOS_RETURN(code);
×
3180
}
3181

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

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

3186
static int32_t mndTablePriviledge(SMnode *pMnode, SHashObj *hash, SHashObj *useDbHash, SAlterUserReq *alterReq,
×
3187
                                  SSdb *pSdb) {
3188
  void *pIter = NULL;
×
3189
  char  tbFName[TSDB_TABLE_FNAME_LEN] = {0};
×
3190

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

3194
  if (alterReq->tagCond != NULL && alterReq->tagCondLen != 0) {
×
3195
    char *value = taosHashGet(hash, tbFName, len);
×
3196
    if (value != NULL) {
×
3197
      TAOS_RETURN(TSDB_CODE_MND_PRIVILEGE_EXIST);
×
3198
    }
3199

3200
    int32_t condLen = alterReq->tagCondLen;
×
3201
    TAOS_CHECK_RETURN(taosHashPut(hash, tbFName, len, alterReq->tagCond, condLen));
×
3202
  } else {
3203
    TAOS_CHECK_RETURN(taosHashPut(hash, tbFName, len, alterReq->isView ? "v" : "t", 2));
×
3204
  }
3205

3206
  int32_t  dbKeyLen = strlen(alterReq->objname) + 1;
×
3207
  int32_t  ref = 1;
×
3208
  int32_t *currRef = taosHashGet(useDbHash, alterReq->objname, dbKeyLen);
×
3209
  if (NULL != currRef) {
×
3210
    ref = (*currRef) + 1;
×
3211
  }
3212
  TAOS_CHECK_RETURN(taosHashPut(useDbHash, alterReq->objname, dbKeyLen, &ref, sizeof(ref)));
×
3213

3214
  TAOS_RETURN(0);
×
3215
}
3216

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

3224
  if (taosHashRemove(hash, tbFName, len) != 0) {
×
3225
    TAOS_RETURN(0);  // not found
×
3226
  }
3227

3228
  int32_t  dbKeyLen = strlen(alterReq->objname) + 1;
×
3229
  int32_t *currRef = taosHashGet(useDbHash, alterReq->objname, dbKeyLen);
×
3230
  if (NULL == currRef) {
×
3231
    return 0;
×
3232
  }
3233

3234
  if (1 == *currRef) {
×
3235
    if (taosHashRemove(useDbHash, alterReq->objname, dbKeyLen) != 0) {
×
3236
      TAOS_RETURN(0);  // not found
×
3237
    }
3238
    return 0;
×
3239
  }
3240
  int32_t ref = (*currRef) - 1;
×
3241
  TAOS_CHECK_RETURN(taosHashPut(useDbHash, alterReq->objname, dbKeyLen, &ref, sizeof(ref)));
×
3242

3243
  return 0;
×
3244
}
3245

3246

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

3256
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, pAlterReq->user, &pUser), &lino, _OVER);
3257
  TAOS_CHECK_GOTO(mndCheckAlterUserPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser, pAlterReq), &lino, _OVER);
3258
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
3259

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

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

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

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

3363
  SHashObj *pReadTbs = newUser.readTbs;
3364
  SHashObj *pWriteTbs = newUser.writeTbs;
3365
  SHashObj *pAlterTbs = newUser.alterTbs;
3366

3367
#ifdef TD_ENTERPRISE
3368
  if (pAlterReq->isView) {
3369
    pReadTbs = newUser.readViews;
3370
    pWriteTbs = newUser.writeViews;
3371
    pAlterTbs = newUser.alterViews;
3372
  }
3373
#endif
3374

3375
  if (ALTER_USER_ADD_READ_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, pReadTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3378
  }
3379

3380
  if (ALTER_USER_ADD_WRITE_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, pWriteTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3383
  }
3384

3385
  if (ALTER_USER_ADD_ALTER_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3386
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3387
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pAlterTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3388
  }
3389

3390
  if (ALTER_USER_DEL_READ_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, pReadTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3393
  }
3394

3395
  if (ALTER_USER_DEL_WRITE_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, pWriteTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3398
  }
3399

3400
  if (ALTER_USER_DEL_ALTER_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3401
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3402
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pAlterTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3403
  }
3404
#endif
3405

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

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

3437
  TAOS_CHECK_GOTO(mndAlterUser(pMnode, &newUser, pReq), &lino, _OVER);
3438
  code = TSDB_CODE_ACTION_IN_PROGRESS;
3439

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

3482
#ifdef TD_ENTERPRISE
3483
extern int32_t mndAlterUserPrivInfo(SMnode *pMnode, SUserObj *pOperUser, SUserObj *pOld, SUserObj *pNew, SAlterRoleReq *pAlterReq);
3484
extern int32_t mndAlterUserRoleInfo(SMnode *pMnode, SUserObj *pOperUser, SUserObj *pOld, SUserObj *pNew, SAlterRoleReq *pAlterReq);
3485
#endif
3486

3487
int32_t mndAlterUserFromRole(SRpcMsg *pReq, SUserObj *pOperUser, SAlterRoleReq *pAlterReq) {
963,123✔
3488
  SMnode   *pMnode = pReq->info.node;
963,123✔
3489
  SSdb     *pSdb = pMnode->pSdb;
963,123✔
3490
  void     *pIter = NULL;
963,123✔
3491
  int32_t   code = 0, lino = 0;
963,123✔
3492
  SUserObj *pUser = NULL;
963,123✔
3493
  SUserObj  newUser = {0};
963,123✔
3494

3495
  TAOS_CHECK_EXIT(mndAcquireUser(pMnode, pAlterReq->principal, &pUser));
963,123✔
3496

3497
  if (pUser->enable == 0) {
962,145✔
3498
    TAOS_CHECK_EXIT(TSDB_CODE_MND_USER_DISABLED);
×
3499
  }
3500

3501
  if (pAlterReq->alterType == TSDB_ALTER_ROLE_PRIVILEGES) {
962,145✔
3502
#ifdef TD_ENTERPRISE
3503
    TAOS_CHECK_EXIT(mndUserDupObj(pUser, &newUser));
958,603✔
3504
    if ((code = mndAlterUserPrivInfo(pMnode, pOperUser, pUser, &newUser, pAlterReq)) == TSDB_CODE_QRY_DUPLICATED_OPERATION) {
958,603✔
3505
      code = 0;
×
3506
      goto _exit;
×
3507
    } else {
3508
      TAOS_CHECK_EXIT(code);
958,603✔
3509
    }
3510
  } else if (pAlterReq->alterType == TSDB_ALTER_ROLE_ROLE) {
3,542✔
3511
    if ((code = mndAlterUserRoleInfo(pMnode, pOperUser, pUser, &newUser, pAlterReq)) == TSDB_CODE_QRY_DUPLICATED_OPERATION) {
3,542✔
3512
      code = 0;
161✔
3513
      goto _exit;
161✔
3514
    } else {
3515
      TAOS_CHECK_EXIT(code);
3,381✔
3516
    }
3517
#endif
3518
  } else {
3519
    TAOS_CHECK_EXIT(TSDB_CODE_INVALID_MSG);
×
3520
  }
3521
  code = mndAlterUser(pMnode, &newUser, pReq);
961,501✔
3522
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
961,501✔
3523

3524
_exit:
963,123✔
3525
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
963,123✔
3526
    mError("user:%s, failed to alter user at line %d since %s", pAlterReq->principal, lino, tstrerror(code));
1,461✔
3527
  }
3528
  mndReleaseUser(pMnode, pUser);
963,123✔
3529
  mndUserFreeObj(&newUser);
963,123✔
3530
  TAOS_RETURN(code);
963,123✔
3531
}
3532

3533

3534
static int32_t mndProcessAlterUserBasicInfoReq(SRpcMsg *pReq, SAlterUserReq *pAlterReq) {
13,200✔
3535
  SMnode       *pMnode = pReq->info.node;
13,200✔
3536
  int32_t       code = 0, lino = 0;
13,200✔
3537
  SUserObj     *pUser = NULL;
13,200✔
3538
  SUserObj      newUser = {0};
13,200✔
3539
  char          auditLog[1000] = {0};
13,200✔
3540
  int32_t       auditLen = 0;
13,200✔
3541
  int64_t       tss = taosGetTimestampMs();
13,200✔
3542

3543
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, pAlterReq->user, &pUser), &lino, _OVER);
13,200✔
3544
  TAOS_CHECK_GOTO(mndCheckAlterUserPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser, pAlterReq), &lino, _OVER);
12,509✔
3545
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
10,718✔
3546

3547
  if (pAlterReq->hasPassword) {
10,718✔
3548
    auditLen += tsnprintf(auditLog, sizeof(auditLog), "password,");
4,459✔
3549

3550
    TAOS_CHECK_GOTO(mndCheckPasswordFmt(pAlterReq->pass), &lino, _OVER);
4,459✔
3551
    if (newUser.salt[0] == 0) {
4,459✔
3552
      generateSalt(newUser.salt, sizeof(newUser.salt));
328✔
3553
    }
3554
    char pass[TSDB_PASSWORD_LEN] = {0};
4,459✔
3555
    taosEncryptPass_c((uint8_t *)pAlterReq->pass, strlen(pAlterReq->pass), pass);
4,459✔
3556
    pass[sizeof(pass) - 1] = 0;
4,459✔
3557
    TAOS_CHECK_GOTO(mndEncryptPass(pass, newUser.salt, &newUser.passEncryptAlgorithm), &lino, _OVER);
4,459✔
3558

3559
    if (newUser.passwordReuseMax > 0 || newUser.passwordReuseTime > 0) {
4,459✔
3560
      for(int32_t i = 0; i < newUser.numOfPasswords; ++i) {
11,610✔
3561
        if (0 == strncmp(newUser.passwords[i].pass, pass, TSDB_PASSWORD_LEN)) {
8,169✔
3562
          TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_PASSWORD_REUSE, &lino, _OVER);
164✔
3563
        }
3564
      }
3565
      SUserPassword *passwords = taosMemoryCalloc(newUser.numOfPasswords + 1, sizeof(SUserPassword));
3,441✔
3566
      if (passwords == NULL) {
3,441✔
3567
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3568
      }
3569
      memcpy(passwords + 1, newUser.passwords, newUser.numOfPasswords * sizeof(SUserPassword));
3,441✔
3570
      memcpy(passwords[0].pass, pass, TSDB_PASSWORD_LEN);
3,441✔
3571
      passwords[0].setTime = taosGetTimestampSec();
3,441✔
3572
      taosMemoryFree(newUser.passwords);
3,441✔
3573
      newUser.passwords = passwords;
3,441✔
3574
      ++newUser.numOfPasswords;
3,441✔
3575
      ++newUser.passVersion;
3,441✔
3576
      newUser.changePass = 2;
3,441✔
3577
    } else if (0 != strncmp(newUser.passwords[0].pass, pass, TSDB_PASSWORD_LEN)) {
854✔
3578
      memcpy(newUser.passwords[0].pass, pass, TSDB_PASSWORD_LEN);
326✔
3579
      newUser.passwords[0].setTime = taosGetTimestampSec();
326✔
3580
      ++newUser.passVersion;
326✔
3581
      newUser.changePass = 2;
326✔
3582
    }
3583
  }
3584

3585
  if (pAlterReq->hasTotpseed) {
10,554✔
3586
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "totpseed,");
×
3587

3588
    if (pAlterReq->totpseed[0] == 0) { // clear totp secret
×
3589
      memset(newUser.totpsecret, 0, sizeof(newUser.totpsecret));
×
3590
    } else if (taosGenerateTotpSecret(pAlterReq->totpseed, 0, newUser.totpsecret, sizeof(newUser.totpsecret)) < 0) {
×
3591
      TAOS_CHECK_GOTO(TSDB_CODE_PAR_INVALID_OPTION_VALUE, &lino, _OVER);
×
3592
    }
3593
  }
3594

3595
  if (pAlterReq->hasEnable) {
10,554✔
3596
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "enable:%d,", pAlterReq->enable);
695✔
3597

3598
    newUser.enable = pAlterReq->enable; // lock or unlock user manually
695✔
3599
    if (newUser.enable) {
695✔
3600
      // reset login info to allow login immediately
3601
      userCacheResetLoginInfo(newUser.user);
531✔
3602
    }
3603
  }
3604

3605
  if (pAlterReq->hasSysinfo) {
10,554✔
3606
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "sysinfo:%d,", pAlterReq->sysinfo);
3,610✔
3607
    newUser.sysInfo = pAlterReq->sysinfo;
3,610✔
3608
  }
3609

3610
  if (pAlterReq->hasCreatedb) {
10,554✔
3611
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "createdb:%d,", pAlterReq->createdb);
1,628✔
3612
    newUser.createdb = pAlterReq->createdb;
1,628✔
3613
  }
3614

3615
  if (pAlterReq->hasChangepass) {
10,554✔
3616
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "changepass:%d,", pAlterReq->changepass);
×
3617
    newUser.changePass = pAlterReq->changepass;
×
3618
  }
3619

3620
  if (pAlterReq->hasSessionPerUser) {
10,554✔
3621
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "sessionPerUser:%d,", pAlterReq->sessionPerUser);
×
3622
    newUser.sessionPerUser = pAlterReq->sessionPerUser;
×
3623
  }
3624

3625
  if (pAlterReq->hasConnectTime) {
10,554✔
3626
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "connectTime:%d,", pAlterReq->connectTime);
×
3627
    newUser.connectTime = pAlterReq->connectTime;
×
3628
  }
3629
  
3630
  if (pAlterReq->hasConnectIdleTime) {
10,554✔
3631
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "connectIdleTime:%d,", pAlterReq->connectIdleTime);
×
3632
    newUser.connectIdleTime = pAlterReq->connectIdleTime;
×
3633
  }
3634

3635
  if (pAlterReq->hasCallPerSession) {
10,554✔
3636
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "callPerSession:%d,", pAlterReq->callPerSession);
×
3637
    newUser.callPerSession = pAlterReq->callPerSession;
×
3638
  }
3639

3640
  if (pAlterReq->hasVnodePerCall) {
10,554✔
3641
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "vnodePerCall:%d,", pAlterReq->vnodePerCall);
×
3642
    newUser.vnodePerCall = pAlterReq->vnodePerCall;
×
3643
  }
3644

3645
  if (pAlterReq->hasFailedLoginAttempts) {
10,554✔
3646
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "failedLoginAttempts:%d,", pAlterReq->failedLoginAttempts);
×
3647
    newUser.failedLoginAttempts = pAlterReq->failedLoginAttempts;
×
3648
  }
3649

3650
  if (pAlterReq->hasPasswordLifeTime) {
10,554✔
3651
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordLifeTime:%d,", pAlterReq->passwordLifeTime);
×
3652
    newUser.passwordLifeTime = pAlterReq->passwordLifeTime;
×
3653
  }
3654

3655
  if (pAlterReq->hasPasswordReuseTime) {
10,554✔
3656
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordReuseTime:%d,", pAlterReq->passwordReuseTime);
×
3657
    newUser.passwordReuseTime = pAlterReq->passwordReuseTime;
×
3658
  }
3659

3660
  if (pAlterReq->hasPasswordReuseMax) {
10,554✔
3661
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordReuseMax:%d,", pAlterReq->passwordReuseMax);
×
3662
    newUser.passwordReuseMax = pAlterReq->passwordReuseMax;
×
3663
  }
3664

3665
  if (pAlterReq->hasPasswordLockTime) {
10,554✔
3666
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordLockTime:%d,", pAlterReq->passwordLockTime);
×
3667
    newUser.passwordLockTime = pAlterReq->passwordLockTime;
×
3668
  }
3669

3670
  if (pAlterReq->hasPasswordGraceTime) {
10,554✔
3671
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordGraceTime:%d,", pAlterReq->passwordGraceTime);
×
3672
    newUser.passwordGraceTime = pAlterReq->passwordGraceTime;
×
3673
  }
3674

3675
  if (pAlterReq->hasInactiveAccountTime) {
10,554✔
3676
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "inactiveAccountTime:%d,", pAlterReq->inactiveAccountTime);
×
3677
    newUser.inactiveAccountTime = pAlterReq->inactiveAccountTime;
×
3678
  }
3679

3680
  if (pAlterReq->hasAllowTokenNum) {
10,554✔
3681
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "allowTokenNum:%d,", pAlterReq->allowTokenNum);
×
3682
    newUser.allowTokenNum = pAlterReq->allowTokenNum;
×
3683
  }
3684

3685
  if (pAlterReq->numDropIpRanges > 0 || pAlterReq->numIpRanges > 0) {
10,554✔
3686
    int32_t dummy = 0;
326✔
3687

3688
    // put previous ip whitelist into hash table
3689
    SHashObj *m = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
326✔
3690
    if (m == NULL) {
326✔
3691
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3692
    }
3693

3694
    for (int32_t i = 0; i < newUser.pIpWhiteListDual->num; i++) {
1,141✔
3695
      SIpRange range;
815✔
3696
      copyIpRange(&range, newUser.pIpWhiteListDual->pIpRanges + i);
815✔
3697
      code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
815✔
3698
      if (code != 0) {
815✔
3699
        taosHashCleanup(m);
×
3700
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3701
      }
3702
    }
3703

3704
    if (pAlterReq->numDropIpRanges > 0) {
326✔
3705
      auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "dropIpRanges:%d,", pAlterReq->numDropIpRanges);
163✔
3706

3707
      for (int32_t i = 0; i < pAlterReq->numDropIpRanges; i++) {
326✔
3708
        if (taosHashGetSize(m) == 0) {
163✔
3709
          break;
×
3710
        }
3711

3712
        SIpRange range;
163✔
3713
        copyIpRange(&range, pAlterReq->pDropIpRanges + i);
163✔
3714

3715
        // for white list, drop default ip ranges is allowed, otherwise, we can never
3716
        // convert white list to black list.
3717

3718
        code = taosHashRemove(m, &range, sizeof(range));
163✔
3719
        if (code == TSDB_CODE_NOT_FOUND) {
163✔
3720
          // treat not exist as success
3721
          code = 0;
163✔
3722
        }
3723
        if (code != 0) {
163✔
3724
          taosHashCleanup(m);
×
3725
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3726
        }
3727
      }
3728
    }
3729

3730
    if (pAlterReq->numIpRanges > 0) {
326✔
3731
      auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "addIpRanges:%d,", pAlterReq->numIpRanges);
163✔
3732
      for (int32_t i = 0; i < pAlterReq->numIpRanges; i++) {
326✔
3733
        SIpRange range;
163✔
3734
        copyIpRange(&range, pAlterReq->pIpRanges + i);
163✔
3735
        code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
163✔
3736
        if (code != 0) {
163✔
3737
          taosHashCleanup(m);
×
3738
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3739
        }
3740
      }
3741
    }
3742

3743
    int32_t numOfRanges = taosHashGetSize(m);
326✔
3744
    if (numOfRanges > MND_MAX_USER_IP_RANGE) {
326✔
3745
      taosHashCleanup(m);
×
3746
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_IP_RANGE, &lino, _OVER);
×
3747
    }
3748

3749
    SIpWhiteListDual *p = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + numOfRanges * sizeof(SIpRange));
326✔
3750
    if (p == NULL) {
326✔
3751
      taosHashCleanup(m);
×
3752
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3753
    }
3754

3755
    void *pIter = taosHashIterate(m, NULL);
326✔
3756
    int32_t i = 0;
326✔
3757
    while (pIter) {
1,304✔
3758
      size_t len = 0;
978✔
3759
      SIpRange *key = taosHashGetKey(pIter, &len);
978✔
3760
      memcpy(p->pIpRanges + i, key, sizeof(SIpRange));
978✔
3761
      pIter = taosHashIterate(m, pIter);
978✔
3762
      i++;
978✔
3763
    }
3764

3765
    taosHashCleanup(m);
326✔
3766
    p->num = numOfRanges;
326✔
3767
    taosMemoryFreeClear(newUser.pIpWhiteListDual);
326✔
3768
    sortIpWhiteList(p);
326✔
3769
    newUser.pIpWhiteListDual = p;
326✔
3770

3771
    newUser.ipWhiteListVer++;
326✔
3772
  }
3773

3774

3775
  if (pAlterReq->numTimeRanges > 0 || pAlterReq->numDropTimeRanges) {
10,554✔
3776
    int32_t dummy = 0;
×
3777

3778
    // put previous ip whitelist into hash table
3779
    SHashObj *m = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
×
3780
    if (m == NULL) {
×
3781
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3782
    }
3783

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

3796
    if (pAlterReq->numDropTimeRanges > 0) {
×
3797
      auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "dropTimeRanges:%d,", pAlterReq->numDropTimeRanges);
×
3798
      for (int32_t i = 0; i < pAlterReq->numDropTimeRanges; i++) {
×
3799
        if (taosHashGetSize(m) == 0) {
×
3800
          break;
×
3801
        }
3802
        SDateTimeWhiteListItem range = { 0 };
×
3803
        DateTimeRangeToWhiteListItem(&range, pAlterReq->pDropTimeRanges + i);
×
3804

3805
        code = taosHashRemove(m, &range, sizeof(range));
×
3806
        if (code == TSDB_CODE_NOT_FOUND) {
×
3807
          // treat not exist as success
3808
          code = 0;
×
3809
        }
3810
        if (code != 0) {
×
3811
          taosHashCleanup(m);
×
3812
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3813
        }
3814
      }
3815
    }
3816

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

3833
    int32_t numOfRanges = taosHashGetSize(m);
×
3834
    if (numOfRanges > MND_MAX_USER_TIME_RANGE) {
×
3835
      taosHashCleanup(m);
×
3836
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_TIME_RANGE, &lino, _OVER);
×
3837
    }
3838

3839
    SDateTimeWhiteList *p = taosMemoryCalloc(1, sizeof(SDateTimeWhiteList) + numOfRanges * sizeof(SDateTimeWhiteListItem));
×
3840
    if (p == NULL) {
×
3841
      taosHashCleanup(m);
×
3842
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3843
    }
3844

3845
    void *pIter = taosHashIterate(m, NULL);
×
3846
    int32_t i = 0;
×
3847
    while (pIter) {
×
3848
      size_t len = 0;
×
3849
      SDateTimeWhiteListItem *key = taosHashGetKey(pIter, &len);
×
3850
      memcpy(&p->ranges[i], key, sizeof(SDateTimeWhiteListItem));
×
3851
      pIter = taosHashIterate(m, pIter);
×
3852
      i++;
×
3853
    }
3854

3855
    taosHashCleanup(m);
×
3856
    p->num = numOfRanges;
×
3857
    taosMemoryFreeClear(newUser.pTimeWhiteList);
×
3858
    sortTimeWhiteList(p);
×
3859
    newUser.pTimeWhiteList = p;
×
3860
    newUser.timeWhiteListVer++;
×
3861
  }
3862

3863
  TAOS_CHECK_GOTO(mndAlterUser(pMnode, &newUser, pReq), &lino, _OVER);
10,554✔
3864
  code = TSDB_CODE_ACTION_IN_PROGRESS;
10,554✔
3865

3866
  if (auditLen > 0) {
10,554✔
3867
    auditLog[--auditLen] = 0; // remove last ','
10,554✔
3868
  }
3869
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
10,554✔
3870
    int64_t tse = taosGetTimestampMs();
10,554✔
3871
    double  duration = (double)(tse - tss);
10,554✔
3872
    duration = duration / 1000;
10,554✔
3873
    auditRecord(pReq, pMnode->clusterId, "alterUser", "", pAlterReq->user, auditLog, auditLen, duration, 0);
10,554✔
3874
  }
3875

3876
_OVER:
13,200✔
3877
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
13,200✔
3878
    mError("user:%s, failed to alter at line %d since %s", pAlterReq->user, lino, tstrerror(code));
2,646✔
3879
  }
3880

3881
  mndReleaseUser(pMnode, pUser);
13,200✔
3882
  mndUserFreeObj(&newUser);
13,200✔
3883
  return code;
13,200✔
3884
}
3885

3886

3887

3888
static int32_t mndProcessAlterUserReq(SRpcMsg *pReq) {
13,200✔
3889
  SAlterUserReq alterReq = {0};
13,200✔
3890

3891
  int32_t code = tDeserializeSAlterUserReq(pReq->pCont, pReq->contLen, &alterReq);
13,200✔
3892
  if (code != 0) {
13,200✔
3893
    mError("failed to deserialize alter user request at line %d since %s", __LINE__, tstrerror(code));
×
3894
    TAOS_RETURN(code);
×
3895
  }
3896

3897
  if (alterReq.user[0] == 0) {
13,200✔
3898
    tFreeSAlterUserReq(&alterReq);
×
3899
    mError("failed to alter user at line %d since invalid user format", __LINE__);
×
3900
    TAOS_RETURN(TSDB_CODE_MND_INVALID_USER_FORMAT);
×
3901
  }
3902

3903
  mInfo("user:%s, start to alter", alterReq.user);
13,200✔
3904
  if (alterReq.alterType == TSDB_ALTER_USER_BASIC_INFO) {
13,200✔
3905
    code = mndProcessAlterUserBasicInfoReq(pReq, &alterReq);
13,200✔
3906
  } else {
3907
    // code = mndProcessAlterUserPrivilegesReq(pReq, &alterReq); // obsolete
3908
  }
3909

3910
  tFreeSAlterUserReq(&alterReq);
13,200✔
3911
  TAOS_RETURN(code);
13,200✔
3912
}
3913

3914
int32_t mndGetAuditUser(SMnode *pMnode, char* user){
40,291,411✔
3915
  (void)tsnprintf(user, TSDB_USER_LEN, "audit");
40,291,411✔
3916
  return 0;
40,291,411✔
3917
}
3918

3919
static int32_t mndDropUser(SMnode *pMnode, SRpcMsg *pReq, SUserObj *pUser) {
20,324✔
3920
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "drop-user");
20,324✔
3921
  if (pTrans == NULL) {
20,324✔
3922
    mError("user:%s, failed to drop since %s", pUser->user, terrstr());
×
3923
    TAOS_RETURN(terrno);
×
3924
  }
3925
  mInfo("trans:%d, used to drop user:%s", pTrans->id, pUser->user);
20,324✔
3926

3927
  SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
20,324✔
3928
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
20,324✔
3929
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
3930
    mndTransDrop(pTrans);
×
3931
    TAOS_RETURN(terrno);
×
3932
  }
3933
  if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED) < 0) {
20,324✔
3934
    mndTransDrop(pTrans);
×
3935
    TAOS_RETURN(terrno);
×
3936
  }
3937

3938
  if (mndDropTokensByUser(pMnode, pTrans, pUser->user) != 0) {
20,324✔
3939
    mndTransDrop(pTrans);
×
3940
    TAOS_RETURN(terrno);
×
3941
  }
3942

3943
  if (mndTransPrepare(pMnode, pTrans) != 0) {
20,324✔
3944
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
3945
    mndTransDrop(pTrans);
×
3946
    TAOS_RETURN(terrno);
×
3947
  }
3948

3949
  userCacheRemoveUser(pUser->user);
20,324✔
3950
  mndDropCachedTokensByUser(pUser->user);
20,324✔
3951

3952
  mndTransDrop(pTrans);
20,324✔
3953
  TAOS_RETURN(0);
20,324✔
3954
}
3955

3956
static int32_t mndProcessDropUserReq(SRpcMsg *pReq) {
20,324✔
3957
  SMnode      *pMnode = pReq->info.node;
20,324✔
3958
  int32_t      code = 0;
20,324✔
3959
  int32_t      lino = 0;
20,324✔
3960
  SUserObj    *pOperUser = NULL;
20,324✔
3961
  SUserObj    *pUser = NULL;
20,324✔
3962
  SDropUserReq dropReq = {0};
20,324✔
3963
  int64_t      tss = taosGetTimestampMs();
20,324✔
3964

3965
  TAOS_CHECK_GOTO(tDeserializeSDropUserReq(pReq->pCont, pReq->contLen, &dropReq), &lino, _OVER);
20,324✔
3966

3967
  mInfo("user:%s, start to drop", dropReq.user);
20,324✔
3968

3969
  if (dropReq.user[0] == 0) {
20,324✔
3970
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
3971
  }
3972

3973
  if (0 == strcmp(dropReq.user, TSDB_DEFAULT_USER)) {
20,324✔
3974
    return TSDB_CODE_MND_NO_RIGHTS;
×
3975
  }
3976

3977
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, dropReq.user, &pUser), &lino, _OVER);
20,324✔
3978

3979
  code = mndAcquireUser(pMnode, RPC_MSG_USER(pReq), &pOperUser);
20,324✔
3980
  if (pOperUser == NULL) {
20,324✔
3981
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_USER_FROM_CONN, &lino, _OVER);
×
3982
  }
3983

3984
  // TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, RPC_MSG_USER(pReq), MND_OPER_DROP_USER), &lino, _OVER);
3985
  TAOS_CHECK_GOTO(mndCheckSysObjPrivilege(pMnode, pOperUser, PRIV_USER_DROP, 0, 0, NULL, NULL), &lino, _OVER);
20,324✔
3986

3987
  TAOS_CHECK_GOTO(mndDropUser(pMnode, pReq, pUser), &lino, _OVER);
20,324✔
3988
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
20,324✔
3989

3990
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
20,324✔
3991
    int64_t tse = taosGetTimestampMs();
20,324✔
3992
    double  duration = (double)(tse - tss);
20,324✔
3993
    duration = duration / 1000;
20,324✔
3994
    auditRecord(pReq, pMnode->clusterId, "dropUser", "", dropReq.user, dropReq.sql, dropReq.sqlLen, duration, 0);
20,324✔
3995
  }
3996

3997
_OVER:
20,324✔
3998
  if (dropReq.ignoreNotExists && code == TSDB_CODE_MND_USER_NOT_EXIST) {
20,324✔
3999
    code = 0;
×
4000
  } else if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
20,324✔
4001
    mError("user:%s, failed to drop at line %d since %s", dropReq.user, lino, tstrerror(code));
×
4002
  }
4003

4004
  mndReleaseUser(pMnode, pUser);
20,324✔
4005
  mndReleaseUser(pMnode, pOperUser);
20,324✔
4006
  tFreeSDropUserReq(&dropReq);
20,324✔
4007
  TAOS_RETURN(code);
20,324✔
4008
}
4009

4010
static int32_t mndProcessGetUserAuthReq(SRpcMsg *pReq) {
6,220,074✔
4011
  SMnode         *pMnode = pReq->info.node;
6,220,074✔
4012
  int32_t         code = 0;
6,220,074✔
4013
  int32_t         lino = 0;
6,220,074✔
4014
  int32_t         contLen = 0;
6,220,074✔
4015
  void           *pRsp = NULL;
6,220,074✔
4016
  SUserObj       *pUser = NULL;
6,220,074✔
4017
  SGetUserAuthReq authReq = {0};
6,220,074✔
4018
  SGetUserAuthRsp authRsp = {0};
6,220,074✔
4019

4020
  TAOS_CHECK_EXIT(tDeserializeSGetUserAuthReq(pReq->pCont, pReq->contLen, &authReq));
6,220,074✔
4021
  mTrace("user:%s, start to get auth", authReq.user);
6,220,074✔
4022

4023
  TAOS_CHECK_EXIT(mndAcquireUser(pMnode, authReq.user, &pUser));
6,220,074✔
4024

4025
  TAOS_CHECK_EXIT(mndSetUserAuthRsp(pMnode, pUser, &authRsp));
6,220,071✔
4026

4027
  contLen = tSerializeSGetUserAuthRsp(NULL, 0, &authRsp);
6,220,074✔
4028
  if (contLen < 0) {
6,220,074✔
4029
    TAOS_CHECK_EXIT(contLen);
×
4030
  }
4031
  pRsp = rpcMallocCont(contLen);
6,220,074✔
4032
  if (pRsp == NULL) {
6,220,071✔
4033
    TAOS_CHECK_EXIT(terrno);
×
4034
  }
4035

4036
  contLen = tSerializeSGetUserAuthRsp(pRsp, contLen, &authRsp);
6,220,071✔
4037
  if (contLen < 0) {
6,220,071✔
4038
    TAOS_CHECK_EXIT(contLen);
×
4039
  }
4040

4041
_exit:
6,220,071✔
4042
  mndReleaseUser(pMnode, pUser);
6,220,071✔
4043
  tFreeSGetUserAuthRsp(&authRsp);
6,220,074✔
4044
  if (code < 0) {
6,219,370✔
4045
    mError("user:%s, failed to get auth at line %d since %s", authReq.user, lino, tstrerror(code));
×
4046
    rpcFreeCont(pRsp);
×
4047
    pRsp = NULL;
×
4048
    contLen = 0;
×
4049
  }
4050
  pReq->info.rsp = pRsp;
6,219,370✔
4051
  pReq->info.rspLen = contLen;
6,219,370✔
4052
  pReq->code = code;
6,219,370✔
4053

4054
  TAOS_RETURN(code);
6,220,074✔
4055
}
4056

4057

4058

4059
static void base32Encode(const uint8_t *in, int32_t inLen, char *out) {
45✔
4060
  int buffer = 0, bits = 0;
45✔
4061
  int outLen = 0;
45✔
4062

4063
  // process all input bytes
4064
  for (int i = 0; i < inLen; i++) {
1,485✔
4065
    buffer = (buffer << 8) | in[i];
1,440✔
4066
    bits += 8;
1,440✔
4067

4068
    while (bits >= 5) {
3,735✔
4069
      int v = (buffer >> (bits - 5)) & 0x1F;
2,295✔
4070
      out[outLen++] = (v >= 26) ? (v - 26 + '2') : (v + 'A');
2,295✔
4071
      bits -= 5;
2,295✔
4072
    }
4073
  }
4074

4075
  // process remaining bits
4076
  if (bits > 0) {
45✔
4077
    int v = (buffer << (5 - bits)) & 0x1F;
45✔
4078
    out[outLen++] = (v >= 26) ? (v - 26 + '2') : (v + 'A');
45✔
4079
  }
4080

4081
  out[outLen] = '\0';
45✔
4082
}
45✔
4083

4084

4085
static int32_t mndCreateTotpSecret(SMnode *pMnode, SUserObj *pUser, SRpcMsg *pReq) {
45✔
4086
  SCreateTotpSecretRsp rsp = {0};
45✔
4087

4088
  base32Encode((uint8_t *)pUser->totpsecret, sizeof(pUser->totpsecret), rsp.totpSecret);
45✔
4089
  tstrncpy(rsp.user, pUser->user, sizeof(rsp.user));
45✔
4090

4091
  int32_t len = tSerializeSCreateTotpSecretRsp(NULL, 0, &rsp);
45✔
4092
  if (len < 0) {
45✔
NEW
4093
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
4094
  }
4095

4096
  void *pData = taosMemoryMalloc(len);
45✔
4097
  if (pData == NULL) {
45✔
NEW
4098
    TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
4099
  }
4100

4101
  if (tSerializeSCreateTotpSecretRsp(pData, len, &rsp) != len) {
45✔
NEW
4102
    taosMemoryFree(pData);
×
NEW
4103
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
4104
  }
4105

4106
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "create-totp-secret");
45✔
4107
  if (pTrans == NULL) {
45✔
NEW
4108
    mError("user:%s, failed to create totp secret since %s", pUser->user, terrstr());
×
NEW
4109
    taosMemoryFree(pData);
×
NEW
4110
    TAOS_RETURN(terrno);
×
4111
  }
4112
  mInfo("trans:%d, used to create totp secret for user:%s", pTrans->id, pUser->user);
45✔
4113

4114
  mndTransSetUserData(pTrans, pData, len);
45✔
4115

4116
  SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
45✔
4117
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
45✔
NEW
4118
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
NEW
4119
    mndTransDrop(pTrans);
×
NEW
4120
    TAOS_RETURN(terrno);
×
4121
  }
4122
  if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY) < 0) {
45✔
NEW
4123
    mndTransDrop(pTrans);
×
NEW
4124
    TAOS_RETURN(terrno);
×
4125
  }
4126

4127
  if (mndTransPrepare(pMnode, pTrans) != 0) {
45✔
NEW
4128
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
NEW
4129
    mndTransDrop(pTrans);
×
NEW
4130
    TAOS_RETURN(terrno);
×
4131
  }
4132

4133
  mndTransDrop(pTrans);
45✔
4134
  TAOS_RETURN(0);
45✔
4135
}
4136

4137

4138
static int32_t mndProcessCreateTotpSecretReq(SRpcMsg *pReq) {
45✔
4139
  SMnode              *pMnode = pReq->info.node;
45✔
4140
  int32_t              code = 0;
45✔
4141
  int32_t              lino = 0;
45✔
4142
  SUserObj            *pUser = NULL;
45✔
4143
  SUserObj             newUser = {0};
45✔
4144
  SCreateTotpSecretReq req = {0};
45✔
4145
  int64_t              tss = taosGetTimestampMs();
45✔
4146

4147
  TAOS_CHECK_GOTO(tDeserializeSCreateTotpSecretReq(pReq->pCont, pReq->contLen, &req), &lino, _OVER);
45✔
4148
  mTrace("user:%s, start to create/update totp secret", req.user);
45✔
4149

4150
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, req.user, &pUser), &lino, _OVER);
45✔
4151
  TAOS_CHECK_GOTO(mndCheckTotpSecretPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser), &lino, _OVER);
45✔
4152
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
45✔
4153
  taosSafeRandBytes((uint8_t *)newUser.totpsecret, sizeof(newUser.totpsecret));
45✔
4154
  TAOS_CHECK_GOTO(mndCreateTotpSecret(pMnode, &newUser, pReq), &lino, _OVER); 
45✔
4155

4156
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
45✔
4157
    double  duration = (double)(taosGetTimestampMs()- tss) / 1000.0;
45✔
4158
    auditRecord(pReq, pMnode->clusterId, "createTotpSecret", "", req.user, req.sql, req.sqlLen, duration, 0);
45✔
4159
  }
4160

4161
_OVER:
45✔
4162
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
45✔
NEW
4163
    mError("user:%s, failed to create totp secret at line %d since %s", req.user, lino, tstrerror(code));
×
4164
  }
4165
  mndReleaseUser(pMnode, pUser);
45✔
4166
  mndUserFreeObj(&newUser);
45✔
4167
  tFreeSCreateTotpSecretReq(&req);
45✔
4168
  TAOS_RETURN(code);
45✔
4169
}
4170

4171

4172

4173
int32_t mndBuildSMCreateTotpSecretResp(STrans *pTrans, void **ppResp, int32_t *pRespLen) {
45✔
4174
  // user data is the response
4175
  *ppResp = pTrans->userData;
45✔
4176
  *pRespLen = pTrans->userDataLen;
45✔
4177
  pTrans->userData = NULL;
45✔
4178
  pTrans->userDataLen = 0;
45✔
4179
  return 0;
45✔
4180
}
4181

4182

4183

NEW
4184
static int32_t mndProcessDropTotpSecretReq(SRpcMsg *pReq) {
×
NEW
4185
  SMnode            *pMnode = pReq->info.node;
×
NEW
4186
  int32_t            code = 0;
×
NEW
4187
  int32_t            lino = 0;
×
NEW
4188
  SUserObj          *pUser = NULL;
×
NEW
4189
  SDropTotpSecretReq req = {0};
×
NEW
4190
  int64_t            tss = taosGetTimestampMs();
×
4191

NEW
4192
  TAOS_CHECK_GOTO(tDeserializeSDropTotpSecretReq(pReq->pCont, pReq->contLen, &req), &lino, _OVER);
×
NEW
4193
  mTrace("user:%s, start to drop totp secret", req.user);
×
4194

NEW
4195
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, req.user, &pUser), &lino, _OVER);
×
NEW
4196
  TAOS_CHECK_GOTO(mndCheckTotpSecretPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser), &lino, _OVER);
×
4197

NEW
4198
  SUserObj newUser = {0};
×
NEW
4199
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
×
NEW
4200
  (void)memset(newUser.totpsecret, 0, sizeof(newUser.totpsecret));
×
NEW
4201
  TAOS_CHECK_GOTO(mndAlterUser(pMnode, &newUser, pReq), &lino, _OVER); 
×
4202

NEW
4203
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
×
NEW
4204
    double  duration = (double)(taosGetTimestampMs()- tss) / 1000.0;
×
NEW
4205
    auditRecord(pReq, pMnode->clusterId, "dropTotpSecret", "", req.user, req.sql, req.sqlLen, duration, 0);
×
4206
  }
4207

NEW
4208
_OVER:
×
NEW
4209
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
×
NEW
4210
    mError("user:%s, failed to drop totp secret at line %d since %s", req.user, lino, tstrerror(code));
×
4211
  }
NEW
4212
  mndReleaseUser(pMnode, pUser);
×
NEW
4213
  mndUserFreeObj(&newUser);
×
NEW
4214
  tFreeSDropTotpSecretReq(&req);
×
NEW
4215
  TAOS_RETURN(code);
×
4216
}
4217

4218

4219

4220
bool mndIsTotpEnabledUser(SUserObj *pUser) {
2,401,679✔
4221
  for (int32_t i = 0; i < sizeof(pUser->totpsecret); i++) {
79,235,732✔
4222
    if (pUser->totpsecret[i] != 0) {
76,834,974✔
4223
      return true;
90✔
4224
    }
4225
  }
4226
  return false;
2,400,758✔
4227
}
4228

4229

4230
static int32_t mndRetrieveUsers(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
7,707✔
4231
  SMnode   *pMnode = pReq->info.node;
7,707✔
4232
  SSdb     *pSdb = pMnode->pSdb;
7,707✔
4233
  int32_t   code = 0;
7,707✔
4234
  int32_t   lino = 0;
7,707✔
4235
  int32_t   numOfRows = 0;
7,707✔
4236
  SUserObj *pUser = NULL;
7,707✔
4237
  int32_t   cols = 0;
7,707✔
4238
  int8_t    flag = 0;
7,707✔
4239
  char     *pWrite = NULL;
7,707✔
4240
  char     *buf = NULL;
7,707✔
4241
  char     *varstr = NULL;
7,707✔
4242
  char      tBuf[TSDB_MAX_SUBROLE * TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
7,707✔
4243
  int32_t   bufSize = sizeof(tBuf) - VARSTR_HEADER_SIZE;
7,707✔
4244

4245
  while (numOfRows < rows) {
27,178✔
4246
    pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
27,178✔
4247
    if (pShow->pIter == NULL) break;
27,178✔
4248

4249
    cols = 0;
19,471✔
4250
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
19,471✔
4251
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
19,471✔
4252
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
19,471✔
4253
    COL_DATA_SET_VAL_GOTO((const char *)name, false, pUser, pShow->pIter, _exit);
19,471✔
4254

4255
    cols++;
19,471✔
4256
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
19,471✔
4257
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->superUser, false, pUser, pShow->pIter, _exit);
19,471✔
4258

4259
    cols++;
19,471✔
4260
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
19,471✔
4261
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->enable, false, pUser, pShow->pIter, _exit);
19,471✔
4262

4263
    cols++;
19,471✔
4264
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
19,471✔
4265
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sysInfo, false, pUser, pShow->pIter, _exit);
19,471✔
4266

4267
    cols++;
19,471✔
4268
    flag = pUser->createdb ? 1 : 0;
19,471✔
4269
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
19,471✔
4270
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
19,471✔
4271

4272
    cols++;
19,471✔
4273
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
19,471✔
4274
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->createdTime, false, pUser, pShow->pIter, _exit);
19,471✔
4275

4276
    cols++;
19,471✔
4277
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
19,471✔
4278
    flag = mndIsTotpEnabledUser(pUser) ? 1 : 0;
19,471✔
4279
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
19,471✔
4280

4281
    cols++;
19,471✔
4282

4283
    int32_t tlen = convertIpWhiteListToStr(pUser, &buf);
19,471✔
4284
    if (tlen != 0) {
19,471✔
4285
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
19,471✔
4286
      if (varstr == NULL) {
19,471✔
4287
        sdbRelease(pSdb, pUser);
×
4288
        sdbCancelFetch(pSdb, pShow->pIter);
×
4289
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
4290
      }
4291
      varDataSetLen(varstr, tlen);
19,471✔
4292
      (void)memcpy(varDataVal(varstr), buf, tlen);
19,471✔
4293

4294
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
19,471✔
4295
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
19,471✔
4296

4297
      taosMemoryFreeClear(buf);
19,471✔
4298
    } else {
4299
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4300
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
4301
    }
4302

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

4315
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
19,471✔
4316
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
19,471✔
4317

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

4324
    if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
19,471✔
4325
      void  *pIter = NULL;
19,471✔
4326
      size_t klen = 0, tlen = 0;
19,471✔
4327
      char  *pBuf = POINTER_SHIFT(tBuf, VARSTR_HEADER_SIZE);
19,471✔
4328
      while ((pIter = taosHashIterate(pUser->roles, pIter))) {
54,678✔
4329
        char *roleName = taosHashGetKey(pIter, &klen);
35,207✔
4330
        tlen += snprintf(pBuf + tlen, bufSize - tlen, "%s,", roleName);
35,207✔
4331
      }
4332
      if (tlen > 0) {
19,471✔
4333
        pBuf[tlen - 1] = 0;  // remove last ','
19,471✔
4334
      } else {
4335
        pBuf[0] = 0;
×
4336
      }
4337
      varDataSetLen(tBuf, tlen);
19,471✔
4338
      COL_DATA_SET_VAL_GOTO((const char *)tBuf, false, pUser, pShow->pIter, _exit);
19,471✔
4339
    }
4340

4341
    numOfRows++;
19,471✔
4342
    sdbRelease(pSdb, pUser);
19,471✔
4343
  }
4344

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

4356
static int32_t mndRetrieveUsersFull(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
×
4357
  int32_t numOfRows = 0;
×
4358
#ifdef TD_ENTERPRISE
4359
  SMnode   *pMnode = pReq->info.node;
×
4360
  SSdb     *pSdb = pMnode->pSdb;
×
4361
  SUserObj *pUser = NULL;
×
4362
  int32_t   code = 0;
×
4363
  int32_t   lino = 0;
×
4364
  int32_t   cols = 0;
×
4365
  int8_t    flag = 0;
×
4366
  char     *pWrite = NULL;
×
4367
  char     *buf = NULL;
×
4368
  char     *varstr = NULL;
×
4369
  char     *pBuf = NULL;
×
4370
  char      tBuf[TSDB_MAX_SUBROLE * TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
×
4371
  int32_t   bufSize = sizeof(tBuf) - VARSTR_HEADER_SIZE;
×
4372

4373
  while (numOfRows < rows) {
×
4374
    pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
×
4375
    if (pShow->pIter == NULL) break;
×
4376

4377
    cols = 0;
×
4378
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4379
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
×
4380
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
×
4381
    COL_DATA_SET_VAL_GOTO((const char *)name, false, pUser, pShow->pIter, _exit);
×
4382

4383
    cols++;
×
4384
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4385
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->superUser, false, pUser, pShow->pIter, _exit);
×
4386

4387
    cols++;
×
4388
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4389
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->enable, false, pUser, pShow->pIter, _exit);
×
4390

4391
    cols++;
×
4392
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4393
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sysInfo, false, pUser, pShow->pIter, _exit);
×
4394

4395
    cols++;
×
4396
    flag = pUser->createdb ? 1 : 0;
×
4397
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4398
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
×
4399

4400
    cols++;
×
4401
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4402
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->createdTime, false, pUser, pShow->pIter, _exit);
×
4403

4404
    cols++;
×
4405
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4406
    flag = mndIsTotpEnabledUser(pUser) ? 1 : 0;
×
4407
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
×
4408

4409
    cols++;
×
4410
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4411
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->changePass, false, pUser, pShow->pIter, _exit);
×
4412

4413
    cols++;
×
4414
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4415
    char pass[TSDB_PASSWORD_LEN + VARSTR_HEADER_SIZE] = {0};
×
4416
    STR_WITH_MAXSIZE_TO_VARSTR(pass, pUser->passwords[0].pass, pShow->pMeta->pSchemas[cols].bytes);
×
4417
    COL_DATA_SET_VAL_GOTO((const char *)pass, false, pUser, pShow->pIter, _exit);
×
4418

4419
    cols++;
×
4420
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4421
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sessionPerUser, false, pUser, pShow->pIter, _exit);
×
4422

4423
    cols++;
×
4424
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4425
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->connectTime, false, pUser, pShow->pIter, _exit);
×
4426

4427
    cols++;
×
4428
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4429
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->connectIdleTime, false, pUser, pShow->pIter, _exit);
×
4430

4431
    cols++;
×
4432
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4433
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->callPerSession, false, pUser, pShow->pIter, _exit);
×
4434

4435
    cols++;
×
4436
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4437
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->vnodePerCall, false, pUser, pShow->pIter, _exit);
×
4438

4439
    cols++;
×
4440
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4441
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->failedLoginAttempts, false, pUser, pShow->pIter, _exit);
×
4442

4443
    cols++;
×
4444
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4445
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordLifeTime, false, pUser, pShow->pIter, _exit);
×
4446

4447
    cols++;
×
4448
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4449
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordReuseTime, false, pUser, pShow->pIter, _exit);
×
4450

4451
    cols++;
×
4452
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4453
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordReuseMax, false, pUser, pShow->pIter, _exit);
×
4454

4455
    cols++;
×
4456
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4457
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordLockTime, false, pUser, pShow->pIter, _exit);
×
4458

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

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

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

4471
    cols++;
×
4472
    int32_t tlen = convertIpWhiteListToStr(pUser, &buf);
×
4473
    if (tlen != 0) {
×
4474
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
×
4475
      if (varstr == NULL) {
×
4476
        sdbRelease(pSdb, pUser);
×
4477
        sdbCancelFetch(pSdb, pShow->pIter);
×
4478
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
4479
      }
4480
      varDataSetLen(varstr, tlen);
×
4481
      (void)memcpy(varDataVal(varstr), buf, tlen);
×
4482

4483
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4484
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
×
4485

4486
      taosMemoryFreeClear(buf);
×
4487
    } else {
4488
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4489
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
4490
    }
4491

4492
    cols++;
×
4493
    tlen = convertTimeRangesToStr(pUser, &buf);
×
4494
    if (tlen != 0) {
×
4495
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
×
4496
      if (varstr == NULL) {
×
4497
        sdbRelease(pSdb, pUser);
×
4498
        sdbCancelFetch(pSdb, pShow->pIter);
×
4499
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
4500
      }
4501
      varDataSetLen(varstr, tlen);
×
4502
      (void)memcpy(varDataVal(varstr), buf, tlen);
×
4503

4504
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4505
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
×
4506

4507
      taosMemoryFreeClear(buf);
×
4508
    } else {
4509
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4510
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
4511
    }
4512

4513
    if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
×
4514
      void  *pIter = NULL;
×
4515
      size_t klen = 0, tlen = 0;
×
4516
      char  *pBuf = POINTER_SHIFT(tBuf, VARSTR_HEADER_SIZE);
×
4517
      while ((pIter = taosHashIterate(pUser->roles, pIter))) {
×
4518
        char *roleName = taosHashGetKey(pIter, &klen);
×
4519
        tlen += snprintf(pBuf + tlen, bufSize - tlen, "%s,", roleName);
×
4520
      }
4521
      if (tlen > 0) {
×
4522
        pBuf[tlen - 1] = 0;  // remove last ','
×
4523
      } else {
4524
        pBuf[0] = 0;
×
4525
      }
4526
      varDataSetLen(tBuf, tlen);
×
4527
      COL_DATA_SET_VAL_GOTO((const char *)tBuf, false, pUser, pShow->pIter, _exit);
×
4528
    }
4529

4530
    numOfRows++;
×
4531
    sdbRelease(pSdb, pUser);
×
4532
  }
4533

4534
  pShow->numOfRows += numOfRows;
×
4535
_exit:
×
4536
  taosMemoryFreeClear(buf);
×
4537
  taosMemoryFreeClear(varstr);
×
4538
  if (code < 0) {
×
4539
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4540
    TAOS_RETURN(code);
×
4541
  }
4542
#endif
4543
  return numOfRows;
×
4544
}
4545

4546
static void mndCancelGetNextUser(SMnode *pMnode, void *pIter) {
×
4547
  SSdb *pSdb = pMnode->pSdb;
×
4548
  sdbCancelFetchByType(pSdb, pIter, SDB_USER);
×
4549
}
×
4550

4551
static int32_t mndLoopHash(SHashObj *hash, char *priType, SSDataBlock *pBlock, int32_t *pNumOfRows, SSdb *pSdb,
×
4552
                           SUserObj *pUser, SShowObj *pShow, char **condition, char **sql) {
4553
  char   *value = taosHashIterate(hash, NULL);
×
4554
  char   *user = pUser->user;
×
4555
  int32_t code = 0;
×
4556
  int32_t lino = 0;
×
4557
  int32_t cols = 0;
×
4558
  int32_t numOfRows = *pNumOfRows;
×
4559

4560
  while (value != NULL) {
×
4561
    cols = 0;
×
4562
    char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
×
4563
    STR_WITH_MAXSIZE_TO_VARSTR(userName, user, pShow->pMeta->pSchemas[cols].bytes);
×
4564
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4565
    COL_DATA_SET_VAL_GOTO((const char *)userName, false, NULL, NULL, _exit);
×
4566

4567
    char privilege[20] = {0};
×
4568
    STR_WITH_MAXSIZE_TO_VARSTR(privilege, priType, pShow->pMeta->pSchemas[cols].bytes);
×
4569
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4570
    COL_DATA_SET_VAL_GOTO((const char *)privilege, false, NULL, NULL, _exit);
×
4571

4572
    size_t keyLen = 0;
×
4573
    void  *key = taosHashGetKey(value, &keyLen);
×
4574

4575
    char dbName[TSDB_DB_NAME_LEN] = {0};
×
4576
    (void)mndExtractShortDbNameFromStbFullName(key, dbName);
×
4577
    char dbNameContent[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
×
4578
    STR_WITH_MAXSIZE_TO_VARSTR(dbNameContent, dbName, pShow->pMeta->pSchemas[cols].bytes);
×
4579
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4580
    COL_DATA_SET_VAL_GOTO((const char *)dbNameContent, false, NULL, NULL, _exit);
×
4581

4582
    char tableName[TSDB_TABLE_NAME_LEN] = {0};
×
4583
    mndExtractTbNameFromStbFullName(key, tableName, TSDB_TABLE_NAME_LEN);
×
4584
    char tableNameContent[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
×
4585
    STR_WITH_MAXSIZE_TO_VARSTR(tableNameContent, tableName, pShow->pMeta->pSchemas[cols].bytes);
×
4586
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4587
    COL_DATA_SET_VAL_GOTO((const char *)tableNameContent, false, NULL, NULL, _exit);
×
4588

4589
    if (strcmp("t", value) != 0 && strcmp("v", value) != 0) {
×
4590
      SNode  *pAst = NULL;
×
4591
      int32_t sqlLen = 0;
×
4592
      size_t  bufSz = strlen(value) + 1;
×
4593
      if (bufSz < 6) bufSz = 6;
×
4594
      TAOS_MEMORY_REALLOC(*sql, bufSz);
×
4595
      if (*sql == NULL) {
×
4596
        code = terrno;
×
4597
        goto _exit;
×
4598
      }
4599
      TAOS_MEMORY_REALLOC(*condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
×
4600
      if ((*condition) == NULL) {
×
4601
        code = terrno;
×
4602
        goto _exit;
×
4603
      }
4604

4605
      if (nodesStringToNode(value, &pAst) == 0) {
×
4606
        if (nodesNodeToSQLFormat(pAst, *sql, bufSz, &sqlLen, true) != 0) {
×
4607
          sqlLen = tsnprintf(*sql, bufSz, "error");
×
4608
        }
4609
        nodesDestroyNode(pAst);
×
4610
      }
4611

4612
      if (sqlLen == 0) {
×
4613
        sqlLen = tsnprintf(*sql, bufSz, "error");
×
4614
      }
4615

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

4618
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4619
      COL_DATA_SET_VAL_GOTO((const char *)(*condition), false, NULL, NULL, _exit);
×
4620

4621
      char notes[2] = {0};
×
4622
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
×
4623
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4624
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, NULL, NULL, _exit);
×
4625
    } else {
4626
      TAOS_MEMORY_REALLOC(*condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
×
4627
      if ((*condition) == NULL) {
×
4628
        code = terrno;
×
4629
        goto _exit;
×
4630
      }
4631
      STR_WITH_MAXSIZE_TO_VARSTR((*condition), "", pShow->pMeta->pSchemas[cols].bytes);
×
4632
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4633
      COL_DATA_SET_VAL_GOTO((const char *)(*condition), false, NULL, NULL, _exit);
×
4634

4635
      char notes[64 + VARSTR_HEADER_SIZE] = {0};
×
4636
      STR_WITH_MAXSIZE_TO_VARSTR(notes, value[0] == 'v' ? "view" : "", sizeof(notes));
×
4637
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4638
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, NULL, NULL, _exit);
×
4639
    }
4640

4641
    numOfRows++;
×
4642
    value = taosHashIterate(hash, value);
×
4643
  }
4644
  *pNumOfRows = numOfRows;
×
4645
_exit:
×
4646
  if (code < 0) {
×
4647
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4648
    sdbRelease(pSdb, pUser);
×
4649
    sdbCancelFetch(pSdb, pShow->pIter);
×
4650
  }
4651
  TAOS_RETURN(code);
×
4652
}
4653

4654
#if 0
4655
static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
4656
  int32_t   code = 0;
4657
  int32_t   lino = 0;
4658
  SMnode   *pMnode = pReq->info.node;
4659
  SSdb     *pSdb = pMnode->pSdb;
4660
  int32_t   numOfRows = 0;
4661
  SUserObj *pUser = NULL;
4662
  int32_t   cols = 0;
4663
  char     *pWrite = NULL;
4664
  char     *condition = NULL;
4665
  char     *sql = NULL;
4666

4667
  bool fetchNextUser = pShow->restore ? false : true;
4668
  pShow->restore = false;
4669

4670
  while (numOfRows < rows) {
4671
    if (fetchNextUser) {
4672
      pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
4673
      if (pShow->pIter == NULL) break;
4674
    } else {
4675
      fetchNextUser = true;
4676
      void *pKey = taosHashGetKey(pShow->pIter, NULL);
4677
      pUser = sdbAcquire(pSdb, SDB_USER, pKey);
4678
      if (!pUser) {
4679
        continue;
4680
      }
4681
    }
4682

4683
    int32_t numOfReadDbs = 0; //taosHashGetSize(pUser->readDbs);
4684
    int32_t numOfWriteDbs = 0; //taosHashGetSize(pUser->writeDbs);
4685
    int32_t numOfTopics = taosHashGetSize(pUser->topics);
4686
    int32_t numOfReadTbs = taosHashGetSize(pUser->selectTbs);
4687
    int32_t numOfWriteTbs = taosHashGetSize(pUser->insertTbs);
4688
    int32_t numOfAlterTbs = taosHashGetSize(pUser->alterTbs);
4689
    int32_t numOfReadViews = taosHashGetSize(pUser->readViews);
4690
    int32_t numOfWriteViews = taosHashGetSize(pUser->writeViews);
4691
    int32_t numOfAlterViews = taosHashGetSize(pUser->alterViews);
4692
    if (numOfRows + numOfReadDbs + numOfWriteDbs + numOfTopics + numOfReadTbs + numOfWriteTbs + numOfAlterTbs +
4693
            numOfReadViews + numOfWriteViews + numOfAlterViews >=
4694
        rows) {
4695
      mInfo(
4696
          "will restore. current num of rows: %d, read dbs %d, write dbs %d, topics %d, read tables %d, write tables "
4697
          "%d, alter tables %d, select views %d, write views %d, alter views %d",
4698
          numOfRows, numOfReadDbs, numOfWriteDbs, numOfTopics, numOfReadTbs, numOfWriteTbs, numOfAlterTbs,
4699
          numOfReadViews, numOfWriteViews, numOfAlterViews);
4700
      pShow->restore = true;
4701
      sdbRelease(pSdb, pUser);
4702
      break;
4703
    }
4704

4705
    if (pUser->superUser) {
4706
      cols = 0;
4707
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
4708
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
4709
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4710
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
4711

4712
      char privilege[20] = {0};
4713
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "all", pShow->pMeta->pSchemas[cols].bytes);
4714
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4715
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
4716

4717
      char objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4718
      STR_WITH_MAXSIZE_TO_VARSTR(objName, "all", pShow->pMeta->pSchemas[cols].bytes);
4719
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4720
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
4721

4722
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4723
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
4724
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4725
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
4726

4727
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
4728
      if (condition == NULL) {
4729
        sdbRelease(pSdb, pUser);
4730
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
4731
      }
4732
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
4733
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4734
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
4735

4736
      char notes[2] = {0};
4737
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
4738
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4739
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
4740

4741
      numOfRows++;
4742
    }
4743
#if 0
4744
    char *db = taosHashIterate(pUser->readDbs, NULL);
4745
    while (db != NULL) {
4746
      cols = 0;
4747
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
4748
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
4749
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4750
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
4751

4752
      char privilege[20] = {0};
4753
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "read", pShow->pMeta->pSchemas[cols].bytes);
4754
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4755
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
4756

4757
      SName name = {0};
4758
      char  objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4759
      code = tNameFromString(&name, db, T_NAME_ACCT | T_NAME_DB);
4760
      if (code < 0) {
4761
        sdbRelease(pSdb, pUser);
4762
        sdbCancelFetch(pSdb, pShow->pIter);
4763
        TAOS_CHECK_GOTO(code, &lino, _exit);
4764
      }
4765
      (void)tNameGetDbName(&name, varDataVal(objName));
4766
      varDataSetLen(objName, strlen(varDataVal(objName)));
4767
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4768
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
4769

4770
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4771
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
4772
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4773
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
4774

4775
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
4776
      if (condition == NULL) {
4777
        sdbRelease(pSdb, pUser);
4778
        sdbCancelFetch(pSdb, pShow->pIter);
4779
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
4780
      }
4781
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
4782
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4783
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
4784

4785
      char notes[2] = {0};
4786
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
4787
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4788
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
4789

4790
      numOfRows++;
4791
      db = taosHashIterate(pUser->readDbs, db);
4792
    }
4793

4794
    db = taosHashIterate(pUser->writeDbs, NULL);
4795
    while (db != NULL) {
4796
      cols = 0;
4797
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
4798
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
4799
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4800
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
4801

4802
      char privilege[20] = {0};
4803
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "write", pShow->pMeta->pSchemas[cols].bytes);
4804
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4805
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
4806

4807
      SName name = {0};
4808
      char  objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4809
      code = tNameFromString(&name, db, T_NAME_ACCT | T_NAME_DB);
4810
      if (code < 0) {
4811
        sdbRelease(pSdb, pUser);
4812
        sdbCancelFetch(pSdb, pShow->pIter);
4813
        TAOS_CHECK_GOTO(code, &lino, _exit);
4814
      }
4815
      (void)tNameGetDbName(&name, varDataVal(objName));
4816
      varDataSetLen(objName, strlen(varDataVal(objName)));
4817
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4818
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
4819

4820
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4821
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
4822
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4823
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
4824

4825
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
4826
      if (condition == NULL) {
4827
        sdbRelease(pSdb, pUser);
4828
        sdbCancelFetch(pSdb, pShow->pIter);
4829
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
4830
      }
4831
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
4832
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4833
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
4834

4835
      char notes[2] = {0};
4836
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
4837
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4838
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
4839

4840
      numOfRows++;
4841
      db = taosHashIterate(pUser->writeDbs, db);
4842
    }
4843
#endif
4844
    TAOS_CHECK_EXIT(mndLoopHash(pUser->selectTbs, "select", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
4845

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

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

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

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

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

4856
    char *topic = taosHashIterate(pUser->topics, NULL);
4857
    while (topic != NULL) {
4858
      cols = 0;
4859
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
4860
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
4861
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4862
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
4863

4864
      char privilege[20] = {0};
4865
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "subscribe", pShow->pMeta->pSchemas[cols].bytes);
4866
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4867
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
4868

4869
      char topicName[TSDB_TOPIC_NAME_LEN + VARSTR_HEADER_SIZE + 5] = {0};
4870
      tstrncpy(varDataVal(topicName), mndGetDbStr(topic), TSDB_TOPIC_NAME_LEN - 2);
4871
      varDataSetLen(topicName, strlen(varDataVal(topicName)));
4872
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4873
      COL_DATA_SET_VAL_GOTO((const char *)topicName, false, pUser, pShow->pIter, _exit);
4874

4875
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4876
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
4877
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4878
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
4879

4880
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
4881
      if (condition == NULL) {
4882
        sdbRelease(pSdb, pUser);
4883
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
4884
      }
4885
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
4886
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4887
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
4888

4889
      char notes[2] = {0};
4890
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
4891
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4892
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
4893

4894
      numOfRows++;
4895
      topic = taosHashIterate(pUser->topics, topic);
4896
    }
4897

4898
    sdbRelease(pSdb, pUser);
4899
  }
4900

4901
  pShow->numOfRows += numOfRows;
4902
_exit:
4903
  taosMemoryFreeClear(condition);
4904
  taosMemoryFreeClear(sql);
4905
  if (code < 0) {
4906
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
4907
    TAOS_RETURN(code);
4908
  }
4909
  return numOfRows;
4910
}
4911
#endif
4912

4913
static int32_t mndShowTablePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows, SUserObj *pObj,
138,136✔
4914
                                      SHashObj *privTbs, EPrivType privType, char *pBuf, int32_t bufSize, int32_t *pNumOfRows) {
4915
  int32_t     code = 0, lino = 0;
138,136✔
4916
  SMnode     *pMnode = pReq->info.node;
138,136✔
4917
  SSdb       *pSdb = pMnode->pSdb;
138,136✔
4918
  int32_t     cols = 0, qBufSize = bufSize - VARSTR_HEADER_SIZE;
138,136✔
4919
  int32_t     numOfRows = *pNumOfRows;
138,136✔
4920
  char       *qBuf = NULL;
138,136✔
4921
  char       *sql = NULL;
138,136✔
4922
  char        roleName[TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
138,136✔
4923
  const char *privName = privInfoGetName(privType);
138,136✔
4924

4925
  STR_WITH_MAXSIZE_TO_VARSTR(roleName, pObj->name, pShow->pMeta->pSchemas[cols].bytes);
138,136✔
4926

4927
  void *pIter = NULL;
138,136✔
4928
  while ((pIter = taosHashIterate(privTbs, pIter))) {
175,940✔
4929
    SPrivTblPolicies *pPolices = (SPrivTblPolicies *)pIter;
37,804✔
4930
    SArray           *tblPolicies = pPolices->policy;
37,804✔
4931

4932
    char   *key = taosHashGetKey(pPolices, NULL);
37,804✔
4933
    int32_t objType = PRIV_OBJ_UNKNOWN;
37,804✔
4934
    char    dbName[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
37,804✔
4935
    char    tblName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
37,804✔
4936
    if ((code = privObjKeyParse(key, &objType, dbName, sizeof(dbName), tblName, sizeof(tblName), false))) {
37,804✔
4937
      sdbRelease(pSdb, pObj);
×
4938
      sdbCancelFetch(pSdb, pShow->pIter);
×
4939
      TAOS_CHECK_EXIT(code);
×
4940
    }
4941

4942
    int32_t nTbPolicies = taosArrayGetSize(tblPolicies);
37,804✔
4943
    for (int32_t i = 0; i < nTbPolicies; ++i) {
75,608✔
4944
      SPrivTblPolicy *tbPolicy = (SPrivTblPolicy *)TARRAY_GET_ELEM(tblPolicies, i);
37,804✔
4945
      cols = 0;
37,804✔
4946
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
37,804✔
4947
      COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
37,804✔
4948

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

4954
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
37,804✔
4955
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privObjGetName(objType), pShow->pMeta->pSchemas[cols].bytes);
37,804✔
4956
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
37,804✔
4957
      }
4958

4959
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
37,804✔
4960
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, dbName, pShow->pMeta->pSchemas[cols].bytes);
37,804✔
4961
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
37,804✔
4962
      }
4963

4964
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
37,804✔
4965
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, tblName, pShow->pMeta->pSchemas[cols].bytes);
37,804✔
4966
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
37,804✔
4967
      }
4968
      // condition
4969
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
37,804✔
4970
        SNode  *pAst = NULL;
37,804✔
4971
        int32_t sqlLen = 0;
37,804✔
4972
        qBuf = POINTER_SHIFT(pBuf, VARSTR_HEADER_SIZE);
37,804✔
4973
        if (tbPolicy->condLen > 0) {
37,804✔
4974
          if (nodesStringToNode(tbPolicy->cond, &pAst) == 0) {
37,804✔
4975
            if (nodesNodeToSQLFormat(pAst, qBuf, qBufSize, &sqlLen, true) != 0) {
37,804✔
4976
              sqlLen = tsnprintf(qBuf, qBufSize, "error");
×
4977
            }
4978
            nodesDestroyNode(pAst);
37,804✔
4979
          }
4980
          if (sqlLen == 0) {
37,804✔
4981
            sqlLen = tsnprintf(qBuf, qBufSize, "error");
×
4982
          }
4983
        } else {
4984
          sqlLen = tsnprintf(qBuf, qBufSize, "");
×
4985
        }
4986
        varDataSetLen(pBuf, sqlLen);
37,804✔
4987
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
37,804✔
4988
      }
4989
      // notes
4990
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
37,804✔
4991
        STR_WITH_MAXSIZE_TO_VARSTR((pBuf), "", 2);
37,804✔
4992
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
37,804✔
4993
      }
4994
      // columns
4995
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
37,804✔
4996
        SArray *pCols = tbPolicy->cols;
37,804✔
4997
        int32_t nCols = taosArrayGetSize(pCols);
37,804✔
4998
        int32_t totalLen = 0;
37,804✔
4999
        qBuf = POINTER_SHIFT(pBuf, VARSTR_HEADER_SIZE);
37,804✔
5000
        for (int32_t j = 0; j < nCols; ++j) {
37,804✔
5001
          SColNameFlag *pCol = (SColNameFlag *)TARRAY_GET_ELEM(pCols, j);
×
5002
          char          tmpBuf[TSDB_COL_NAME_LEN + 16] = {0};
×
5003
          int32_t       tmpLen = 0;
×
5004
          if (IS_MASK_ON(pCol)) {
×
5005
            tmpLen = snprintf(tmpBuf, sizeof(tmpBuf), "mask(%s)%s", pCol->colName, j == nCols - 1 ? "" : ",");
×
5006
          } else {
5007
            tmpLen = snprintf(tmpBuf, sizeof(tmpBuf), "%s%s", pCol->colName, j == nCols - 1 ? "" : ",");
×
5008
          }
5009
          if(totalLen + tmpLen > qBufSize) {
×
5010
            break;
×
5011
          }
5012
          (void)memcpy(POINTER_SHIFT(qBuf, totalLen), tmpBuf, tmpLen);
×
5013
          totalLen += tmpLen;
×
5014
        }
5015
        varDataSetLen(pBuf, totalLen);
37,804✔
5016
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
37,804✔
5017
      }
5018
      // update_time
5019
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
37,804✔
5020
        char updateTime[40] = {0};
37,804✔
5021
        (void)formatTimestampLocal(updateTime, tbPolicy->updateUs, TSDB_TIME_PRECISION_MICRO);
37,804✔
5022
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, updateTime, pShow->pMeta->pSchemas[cols].bytes);
37,804✔
5023
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
37,804✔
5024
      }
5025
      ++numOfRows;
37,804✔
5026
    }
5027
  }
5028
  *pNumOfRows = numOfRows;
138,136✔
5029
_exit:
138,136✔
5030
  TAOS_RETURN(code);
138,136✔
5031
}
5032

5033
static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
5,302✔
5034
  int32_t   code = 0, lino = 0;
5,302✔
5035
  SMnode   *pMnode = pReq->info.node;
5,302✔
5036
  SSdb     *pSdb = pMnode->pSdb;
5,302✔
5037
  int32_t   numOfRows = 0;
5,302✔
5038
  int32_t   cols = 0;
5,302✔
5039
  SUserObj *pObj = NULL;
5,302✔
5040
  char     *pBuf = NULL, *qBuf = NULL;
5,302✔
5041
  char     *sql = NULL;
5,302✔
5042
  char      roleName[TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
5,302✔
5043
  int32_t   bufSize = TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE;
5,302✔
5044

5045
  bool fetchNextInstance = pShow->restore ? false : true;
5,302✔
5046
  pShow->restore = false;
5,302✔
5047

5048
  while (numOfRows < rows) {
39,836✔
5049
    if (fetchNextInstance) {
39,836✔
5050
      pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pObj);
39,836✔
5051
      if (pShow->pIter == NULL) break;
39,836✔
5052
    } else {
5053
      fetchNextInstance = true;
×
5054
      void *pKey = taosHashGetKey(pShow->pIter, NULL);
×
5055
      if (!(pObj = sdbAcquire(pSdb, SDB_USER, pKey))) {
×
5056
        continue;
×
5057
      }
5058
    }
5059

5060
    int32_t nSysPrivileges = 0, nObjPrivileges = 0;
34,534✔
5061
    if (nSysPrivileges + nObjPrivileges >= rows) {
34,534✔
5062
      pShow->restore = true;
×
5063
      sdbRelease(pSdb, pObj);
×
5064
      break;
×
5065
    }
5066

5067
    if (!pBuf && !(pBuf = taosMemoryMalloc(bufSize))) {
34,534✔
5068
      sdbCancelFetch(pSdb, pShow->pIter);
×
5069
      sdbRelease(pSdb, pObj);
×
5070
      TAOS_CHECK_EXIT(terrno);
×
5071
    }
5072

5073
    cols = 0;
34,534✔
5074
    STR_WITH_MAXSIZE_TO_VARSTR(roleName, pObj->name, pShow->pMeta->pSchemas[cols].bytes);
34,534✔
5075

5076
    // system privileges
5077
    SPrivIter privIter = {0};
34,534✔
5078
    privIterInit(&privIter, &pObj->sysPrivs);
34,534✔
5079
    SPrivInfo *pPrivInfo = NULL;
34,534✔
5080
    while (privIterNext(&privIter, &pPrivInfo)) {
36,478✔
5081
      cols = 0;
1,944✔
5082
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
1,944✔
5083
      COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
1,944✔
5084

5085
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
1,944✔
5086
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, pPrivInfo->name, pShow->pMeta->pSchemas[cols].bytes);
1,944✔
5087
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
1,944✔
5088
      }
5089
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
1,944✔
5090
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privObjGetName(PRIV_OBJ_CLUSTER), pShow->pMeta->pSchemas[cols].bytes);
1,944✔
5091
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
1,944✔
5092
      }
5093
      // skip db, table, condition, notes, columns, update_time
5094
      COL_DATA_SET_EMPTY_VARCHAR(pBuf, 6);
13,608✔
5095
      numOfRows++;
1,944✔
5096
    }
5097

5098
    // object privileges
5099
    void *pIter = NULL;
34,534✔
5100
    while ((pIter = taosHashIterate(pObj->objPrivs, pIter))) {
55,795✔
5101
      SPrivObjPolicies *pPolices = (SPrivObjPolicies *)pIter;
21,261✔
5102

5103
      char   *key = taosHashGetKey(pPolices, NULL);
21,261✔
5104
      int32_t objType = PRIV_OBJ_UNKNOWN;
21,261✔
5105
      char    dbName[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
21,261✔
5106
      char    tblName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
21,261✔
5107
      if ((code = privObjKeyParse(key, &objType, dbName, sizeof(dbName), tblName, sizeof(tblName), false))) {
21,261✔
5108
        sdbRelease(pSdb, pObj);
×
5109
        sdbCancelFetch(pSdb, pShow->pIter);
×
5110
        TAOS_CHECK_EXIT(code);
×
5111
      }
5112

5113
      SPrivIter privIter = {0};
21,261✔
5114
      privIterInit(&privIter, &pPolices->policy);
21,261✔
5115
      SPrivInfo *pPrivInfo = NULL;
21,261✔
5116
      while (privIterNext(&privIter, &pPrivInfo)) {
119,361✔
5117
        cols = 0;
98,100✔
5118
        SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
98,100✔
5119
        COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
98,100✔
5120

5121
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
98,100✔
5122
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, pPrivInfo->name, pShow->pMeta->pSchemas[cols].bytes);
98,100✔
5123
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
98,100✔
5124
        }
5125

5126
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
98,100✔
5127
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privObjGetName(objType), pShow->pMeta->pSchemas[cols].bytes);
98,100✔
5128
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
98,100✔
5129
        }
5130

5131
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
98,100✔
5132
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, dbName, pShow->pMeta->pSchemas[cols].bytes);
98,100✔
5133
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
98,100✔
5134
        }
5135

5136
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
98,100✔
5137
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, tblName, pShow->pMeta->pSchemas[cols].bytes);
98,100✔
5138
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
98,100✔
5139
        }
5140

5141
        // skip condition, notes, columns, update_time
5142
        COL_DATA_SET_EMPTY_VARCHAR(pBuf, 4);
490,500✔
5143

5144
        numOfRows++;
98,100✔
5145
      }
5146
    }
5147

5148
    // table level privileges
5149
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->selectTbs,
34,534✔
5150
                                           PRIV_TBL_SELECT, pBuf, bufSize, &numOfRows));
5151
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->insertTbs,
34,534✔
5152
                                           PRIV_TBL_INSERT, pBuf, bufSize, &numOfRows));
5153
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->updateTbs,
34,534✔
5154
                                           PRIV_TBL_UPDATE, pBuf, bufSize, &numOfRows));
5155
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->deleteTbs,
34,534✔
5156
                                           PRIV_TBL_DELETE, pBuf, bufSize, &numOfRows));
5157
#if 0
5158
    while ((pIter = taosHashIterate(pObj->selectTbs, pIter))) {
5159
      SPrivTblPolicies *pPolices = (SPrivTblPolicies *)pIter;
5160
      SArray           *tblPolicies = pPolices->policy;
5161

5162
      char   *key = taosHashGetKey(pPolices, NULL);
5163
      int32_t objType = PRIV_OBJ_UNKNOWN;
5164
      char    dbName[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
5165
      char    tblName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
5166
      if ((code = privObjKeyParse(key, &objType, dbName, sizeof(dbName), tblName, sizeof(tblName), false))) {
5167
        sdbRelease(pSdb, pObj);
5168
        sdbCancelFetch(pSdb, pShow->pIter);
5169
        TAOS_CHECK_EXIT(code);
5170
      }
5171

5172
      int32_t nTbPolicies = taosArrayGetSize(tblPolicies);
5173
      for (int32_t i = 0; i < nTbPolicies; ++i) {
5174
        SPrivTblPolicy *tbPolicy = (SPrivTblPolicy *)TARRAY_GET_ELEM(tblPolicies, i);
5175
        cols = 0;
5176
        SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
5177
        COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
5178

5179
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
5180
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privInfoGetName(PRIV_TBL_SELECT), pShow->pMeta->pSchemas[cols].bytes);
5181
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
5182
        }
5183

5184
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
5185
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, dbName, pShow->pMeta->pSchemas[cols].bytes);
5186
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
5187
        }
5188

5189
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
5190
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, tblName, pShow->pMeta->pSchemas[cols].bytes);
5191
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
5192
        }
5193

5194
        // skip condition, notes, columns, update_time
5195
        COL_DATA_SET_EMPTY_VARCHAR(pBuf, 4);
5196

5197
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
5198
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privObjGetName(objType), pShow->pMeta->pSchemas[cols].bytes);
5199
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
5200
        }
5201
        numOfRows++;
5202
      }
5203
    }
5204
#endif
5205
    sdbRelease(pSdb, pObj);
34,534✔
5206
  }
5207

5208
  pShow->numOfRows += numOfRows;
5,302✔
5209
_exit:
5,302✔
5210
  taosMemoryFreeClear(pBuf);
5,302✔
5211
  taosMemoryFreeClear(sql);
5,302✔
5212
  if (code < 0) {
5,302✔
5213
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
5214
    TAOS_RETURN(code);
×
5215
  }
5216
  return numOfRows;
5,302✔
5217
}
5218

5219
static void mndCancelGetNextPrivileges(SMnode *pMnode, void *pIter) {
×
5220
  SSdb *pSdb = pMnode->pSdb;
×
5221
  sdbCancelFetchByType(pSdb, pIter, SDB_USER);
×
5222
}
×
5223

5224
int32_t mndValidateUserAuthInfo(SMnode *pMnode, SUserAuthVersion *pUsers, int32_t numOfUses, void **ppRsp,
18,651,040✔
5225
                                int32_t *pRspLen, int64_t ipWhiteListVer) {
5226
  int32_t           code = 0;
18,651,040✔
5227
  int32_t           lino = 0;
18,651,040✔
5228
  int32_t           rspLen = 0;
18,651,307✔
5229
  void             *pRsp = NULL;
18,651,307✔
5230
  SUserAuthBatchRsp batchRsp = {0};
18,651,307✔
5231

5232
  batchRsp.pArray = taosArrayInit(numOfUses, sizeof(SGetUserAuthRsp));
18,651,307✔
5233
  if (batchRsp.pArray == NULL) {
18,650,651✔
5234
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
5235
  }
5236
  int64_t now = taosGetTimestampMs();
18,651,307✔
5237
  for (int32_t i = 0; i < numOfUses; ++i) {
37,352,936✔
5238
    SUserObj *pUser = NULL;
18,701,629✔
5239
    code = mndAcquireUser(pMnode, pUsers[i].user, &pUser);
18,701,629✔
5240
    if (pUser == NULL) {
18,700,442✔
5241
      if (TSDB_CODE_MND_USER_NOT_EXIST == code) {
181✔
5242
        SGetUserAuthRsp rsp = {.dropped = 1};
181✔
5243
        (void)memcpy(rsp.user, pUsers[i].user, TSDB_USER_LEN);
181✔
5244
        TSDB_CHECK_NULL(taosArrayPush(batchRsp.pArray, &rsp), code, lino, _OVER, TSDB_CODE_OUT_OF_MEMORY);
362✔
5245
      }
5246
      mError("user:%s, failed to auth user since %s", pUsers[i].user, tstrerror(code));
181✔
5247
      code = 0;
181✔
5248
      continue;
2,029✔
5249
    }
5250

5251
    pUsers[i].version = ntohl(pUsers[i].version);
18,700,261✔
5252
    if ((pUser->authVersion <= pUsers[i].version) && (ipWhiteListVer == pMnode->ipWhiteVer) &&
18,700,650✔
5253
        !mndNeedRetrieveRole(pUser)) {
17,855,081✔
5254
      mndReleaseUser(pMnode, pUser);
17,760,630✔
5255
      continue;
17,760,630✔
5256
    }
5257

5258
    SGetUserAuthRsp rsp = {0};
941,349✔
5259
    code = mndSetUserAuthRsp(pMnode, pUser, &rsp);
940,818✔
5260
    if (code) {
940,818✔
5261
      mndReleaseUser(pMnode, pUser);
×
5262
      tFreeSGetUserAuthRsp(&rsp);
×
5263
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
5264
    }
5265

5266
    if (!(taosArrayPush(batchRsp.pArray, &rsp))) {
1,881,636✔
5267
      code = terrno;
×
5268
      mndReleaseUser(pMnode, pUser);
×
5269
      tFreeSGetUserAuthRsp(&rsp);
×
5270
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
5271
    }
5272
    pUser->lastRoleRetrieve = now;  // update user's last retrieve time
940,818✔
5273
    mndReleaseUser(pMnode, pUser);
940,551✔
5274
  }
5275

5276
  if (taosArrayGetSize(batchRsp.pArray) <= 0) {
18,651,307✔
5277
    *ppRsp = NULL;
17,744,457✔
5278
    *pRspLen = 0;
17,744,457✔
5279

5280
    tFreeSUserAuthBatchRsp(&batchRsp);
17,744,457✔
5281
    return 0;
17,743,926✔
5282
  }
5283

5284
  rspLen = tSerializeSUserAuthBatchRsp(NULL, 0, &batchRsp);
906,850✔
5285
  if (rspLen < 0) {
906,583✔
5286
    TAOS_CHECK_GOTO(rspLen, &lino, _OVER);
×
5287
  }
5288
  pRsp = taosMemoryMalloc(rspLen);
906,583✔
5289
  if (pRsp == NULL) {
906,850✔
5290
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
5291
  }
5292
  rspLen = tSerializeSUserAuthBatchRsp(pRsp, rspLen, &batchRsp);
906,850✔
5293
  if (rspLen < 0) {
906,583✔
5294
    TAOS_CHECK_GOTO(rspLen, &lino, _OVER);
×
5295
  }
5296
_OVER:
906,583✔
5297
  tFreeSUserAuthBatchRsp(&batchRsp);
906,583✔
5298
  if (code < 0) {
906,608✔
5299
    for (int32_t i = 0; i < numOfUses; ++i) {
×
5300
      SUserObj *pUser = NULL;
×
5301
      if (mndAcquireUser(pMnode, pUsers[i].user, &pUser) != 0) {
×
5302
        continue;
×
5303
      }
5304
      pUser->lastRoleRetrieve = 0;  // reset last retrieve time on error
×
5305
      mndReleaseUser(pMnode, pUser);
×
5306
    }
5307
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
5308
    taosMemoryFreeClear(pRsp);
×
5309
    rspLen = 0;
×
5310
  }
5311
  *ppRsp = pRsp;
906,608✔
5312
  *pRspLen = rspLen;
906,341✔
5313

5314
  TAOS_RETURN(code);
906,341✔
5315
}
5316

5317
static int32_t mndRemoveDbPrivileges(SHashObj *pHash, const char *dbFName, int32_t dbFNameLen, int32_t *nRemoved) {
×
5318
  void *pVal = NULL;
×
5319
  while ((pVal = taosHashIterate(pHash, pVal))) {
×
5320
    size_t keyLen = 0;
×
5321
    char  *pKey = (char *)taosHashGetKey(pVal, &keyLen);
×
5322
    if (pKey == NULL || keyLen <= dbFNameLen) continue;
×
5323
    if ((*(pKey + dbFNameLen) == '.') && strncmp(pKey, dbFName, dbFNameLen) == 0) {
×
5324
      TAOS_CHECK_RETURN(taosHashRemove(pHash, pKey, keyLen));
×
5325
      if (nRemoved) ++(*nRemoved);
×
5326
    }
5327
  }
5328
  TAOS_RETURN(0);
×
5329
}
5330

5331
int32_t mndUserDropRole(SMnode *pMnode, STrans *pTrans, SRoleObj *pObj) {
×
5332
  int32_t   code = 0, lino = 0;
×
5333
  SSdb     *pSdb = pMnode->pSdb;
×
5334
  SUserObj *pUser = NULL;
×
5335
  void     *pIter = NULL;
×
5336

5337
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser))) {
×
5338
    SHashObj *pRole = taosHashGet(pUser->roles, pObj->name, strlen(pObj->name) + 1);
×
5339
    if (!pRole) {
×
5340
      sdbRelease(pSdb, pUser);
×
5341
      pUser = NULL;
×
5342
      continue;
×
5343
    }
5344

5345
    SUserObj newUser = {0};
×
5346
    TAOS_CHECK_EXIT(mndUserDupObj(pUser, &newUser));
×
5347
    code = taosHashRemove(newUser.roles, pObj->name, strlen(pObj->name) + 1);
×
5348
    if (code == TSDB_CODE_NOT_FOUND) {
×
5349
      sdbRelease(pSdb, pUser);
×
5350
      pUser = NULL;
×
5351
      mndUserFreeObj(&newUser);
×
5352
      continue;
×
5353
    }
5354
    if (code != 0) {
×
5355
      mndUserFreeObj(&newUser);
×
5356
      TAOS_CHECK_EXIT(code);
×
5357
    }
5358
    SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
×
5359
    if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
×
5360
      mndUserFreeObj(&newUser);
×
5361
      TAOS_CHECK_EXIT(TSDB_CODE_OUT_OF_MEMORY);
×
5362
    }
5363
    if ((code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY))) {
×
5364
      mndUserFreeObj(&newUser);
×
5365
      TAOS_CHECK_EXIT(code);
×
5366
    }
5367
    sdbRelease(pSdb, pUser);
×
5368
    pUser = NULL;
×
5369
    mndUserFreeObj(&newUser);
×
5370
  }
5371
_exit:
×
5372
  if (pIter) sdbCancelFetch(pSdb, pIter);
×
5373
  if (pUser) sdbRelease(pSdb, pUser);
×
5374
  if (code < 0) {
×
5375
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
5376
  }
5377
  TAOS_RETURN(code);
×
5378
}
5379

5380
int32_t mndUserRemoveDb(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SSHashObj **ppUsers) {
606,107✔
5381
  int32_t    code = 0, lino = 0;
606,107✔
5382
  SSdb      *pSdb = pMnode->pSdb;
606,107✔
5383
  int32_t    dbLen = strlen(pDb->name);
606,107✔
5384
  void      *pIter = NULL;
606,107✔
5385
  SUserObj  *pUser = NULL;
606,107✔
5386
  SUserObj   newUser = {0};
606,107✔
5387
  SSHashObj *pUsers = ppUsers ? *ppUsers : NULL;
606,107✔
5388
  bool       output = (ppUsers != NULL);
606,107✔
5389
#ifdef PRIV_TODO
5390
  while (1) {
5391
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
5392
    if (pIter == NULL) break;
5393

5394
    bool update = false;
5395
    bool inReadDb = false; //(taosHashGet(pUser->readDbs, pDb->name, dbLen + 1) != NULL);
5396
    bool inWriteDb = false; //(taosHashGet(pUser->writeDbs, pDb->name, dbLen + 1) != NULL);
5397
    bool inUseDb = (taosHashGet(pUser->useDbs, pDb->name, dbLen + 1) != NULL);
5398
    bool inReadTbs = taosHashGetSize(pUser->selectTbs) > 0;
5399
    bool inWriteTbs = taosHashGetSize(pUser->insertTbs) > 0;
5400
    bool inAlterTbs = taosHashGetSize(pUser->alterTbs) > 0;
5401
    bool inReadViews = taosHashGetSize(pUser->readViews) > 0;
5402
    bool inWriteViews = taosHashGetSize(pUser->writeViews) > 0;
5403
    bool inAlterViews = taosHashGetSize(pUser->alterViews) > 0;
5404
    // no need remove pUser->topics since topics must be dropped ahead of db
5405
    if (!inReadDb && !inWriteDb && !inReadTbs && !inWriteTbs && !inAlterTbs && !inReadViews && !inWriteViews &&
5406
        !inAlterViews) {
5407
      sdbRelease(pSdb, pUser);
5408
      continue;
5409
    }
5410
    SUserObj *pTargetUser = &newUser;
5411
    if (output) {
5412
      if (!pUsers) {
5413
        TSDB_CHECK_NULL(pUsers = tSimpleHashInit(32, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY)), code, lino,
5414
                        _exit, TSDB_CODE_OUT_OF_MEMORY);
5415
        *ppUsers = pUsers;
5416
      }
5417
      void   *pVal = NULL;
5418
      int32_t userLen = strlen(pUser->user) + 1;
5419
      if ((pVal = tSimpleHashGet(pUsers, pUser->user, userLen)) != NULL) {
5420
        pTargetUser = (SUserObj *)pVal;
5421
      } else {
5422
        TAOS_CHECK_EXIT(mndUserDupObj(pUser, &newUser));
5423
        TAOS_CHECK_EXIT(tSimpleHashPut(pUsers, pUser->user, userLen, &newUser, sizeof(SUserObj)));
5424
        TSDB_CHECK_NULL((pVal = tSimpleHashGet(pUsers, pUser->user, userLen)), code, lino, _exit,
5425
                        TSDB_CODE_OUT_OF_MEMORY);
5426
        pTargetUser = (SUserObj *)pVal;
5427
      }
5428
    } else {
5429
      TAOS_CHECK_EXIT(mndUserDupObj(pUser, &newUser));
5430
    }
5431
    if (inReadDb) {
5432
      // TAOS_CHECK_EXIT(taosHashRemove(pTargetUser->readDbs, pDb->name, dbLen + 1));
5433
    }
5434
    if (inWriteDb) {
5435
      // TAOS_CHECK_EXIT(taosHashRemove(pTargetUser->writeDbs, pDb->name, dbLen + 1));
5436
    }
5437
    if (inUseDb) {
5438
      TAOS_CHECK_EXIT(taosHashRemove(pTargetUser->useDbs, pDb->name, dbLen + 1));
5439
    }
5440
    update = inReadDb || inWriteDb || inUseDb;
5441

5442
    int32_t nRemovedReadTbs = 0;
5443
    int32_t nRemovedWriteTbs = 0;
5444
    int32_t nRemovedAlterTbs = 0;
5445
    if (inReadTbs || inWriteTbs || inAlterTbs) {
5446
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->selectTbs, pDb->name, dbLen, &nRemovedReadTbs));
5447
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->insertTbs, pDb->name, dbLen, &nRemovedWriteTbs));
5448
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->alterTbs, pDb->name, dbLen, &nRemovedAlterTbs));
5449
      if (!update) update = nRemovedReadTbs > 0 || nRemovedWriteTbs > 0 || nRemovedAlterTbs > 0;
5450
    }
5451

5452
    int32_t nRemovedReadViews = 0;
5453
    int32_t nRemovedWriteViews = 0;
5454
    int32_t nRemovedAlterViews = 0;
5455
    if (inReadViews || inWriteViews || inAlterViews) {
5456
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->readViews, pDb->name, dbLen, &nRemovedReadViews));
5457
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->writeViews, pDb->name, dbLen, &nRemovedWriteViews));
5458
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->alterViews, pDb->name, dbLen, &nRemovedAlterViews));
5459
      if (!update) update = nRemovedReadViews > 0 || nRemovedWriteViews > 0 || nRemovedAlterViews > 0;
5460
    }
5461

5462
    if (!output) {
5463
      if (update) {
5464
        SSdbRaw *pCommitRaw = mndUserActionEncode(pTargetUser);
5465
        if (pCommitRaw == NULL) {
5466
          TAOS_CHECK_EXIT(terrno);
5467
        }
5468
        TAOS_CHECK_EXIT(mndTransAppendCommitlog(pTrans, pCommitRaw));
5469
        TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
5470
      }
5471
      mndUserFreeObj(&newUser);
5472
    }
5473
    sdbRelease(pSdb, pUser);
5474
  }
5475
#endif
5476
_exit:
606,107✔
5477
  if (code < 0) {
606,107✔
5478
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
5479
    mndUserFreeObj(&newUser);
×
5480
  }
5481
  if (pUser != NULL) sdbRelease(pSdb, pUser);
606,107✔
5482
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
606,107✔
5483
  if (!output) mndUserFreeObj(&newUser);
606,107✔
5484
  TAOS_RETURN(code);
606,107✔
5485
}
5486

5487
int32_t mndUserRemoveStb(SMnode *pMnode, STrans *pTrans, char *stb) {
434,264✔
5488
  int32_t   code = 0;
434,264✔
5489
  SSdb     *pSdb = pMnode->pSdb;
434,264✔
5490
  int32_t   len = strlen(stb) + 1;
434,264✔
5491
  void     *pIter = NULL;
434,264✔
5492
  SUserObj *pUser = NULL;
434,264✔
5493
  SUserObj  newUser = {0};
434,264✔
5494
#ifdef PRIV_TODO
5495
  while (1) {
5496
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
5497
    if (pIter == NULL) break;
5498

5499
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
5500
      break;
5501
    }
5502

5503
    bool inRead = (taosHashGet(newUser.selectTbs, stb, len) != NULL);
5504
    bool inWrite = (taosHashGet(newUser.insertTbs, stb, len) != NULL);
5505
    bool inAlter = (taosHashGet(newUser.alterTbs, stb, len) != NULL);
5506
    if (inRead || inWrite || inAlter) {
5507
      code = taosHashRemove(newUser.selectTbs, stb, len);
5508
      if (code < 0) {
5509
        mError("failed to remove selectTbs:%s from user:%s", stb, pUser->user);
5510
      }
5511
      code = taosHashRemove(newUser.insertTbs, stb, len);
5512
      if (code < 0) {
5513
        mError("failed to remove insertTbs:%s from user:%s", stb, pUser->user);
5514
      }
5515
      code = taosHashRemove(newUser.alterTbs, stb, len);
5516
      if (code < 0) {
5517
        mError("failed to remove alterTbs:%s from user:%s", stb, pUser->user);
5518
      }
5519

5520
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
5521
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
5522
        code = TSDB_CODE_OUT_OF_MEMORY;
5523
        break;
5524
      }
5525
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
5526
      if (code != 0) {
5527
        mndUserFreeObj(&newUser);
5528
        sdbRelease(pSdb, pUser);
5529
        TAOS_RETURN(code);
5530
      }
5531
    }
5532

5533
    mndUserFreeObj(&newUser);
5534
    sdbRelease(pSdb, pUser);
5535
  }
5536
#endif
5537
  if (pUser != NULL) sdbRelease(pSdb, pUser);
434,264✔
5538
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
434,264✔
5539
  mndUserFreeObj(&newUser);
434,264✔
5540
  TAOS_RETURN(code);
434,264✔
5541
}
5542

5543
int32_t mndUserRemoveView(SMnode *pMnode, STrans *pTrans, char *view) {
×
5544
  int32_t   code = 0;
×
5545
  SSdb     *pSdb = pMnode->pSdb;
×
5546
  int32_t   len = strlen(view) + 1;
×
5547
  void     *pIter = NULL;
×
5548
  SUserObj *pUser = NULL;
×
5549
  SUserObj  newUser = {0};
×
5550
#ifdef PRIV_TODO
5551
  while (1) {
5552
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
5553
    if (pIter == NULL) break;
5554

5555
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
5556
      break;
5557
    }
5558

5559
    bool inRead = (taosHashGet(newUser.readViews, view, len) != NULL);
5560
    bool inWrite = (taosHashGet(newUser.writeViews, view, len) != NULL);
5561
    bool inAlter = (taosHashGet(newUser.alterViews, view, len) != NULL);
5562
    if (inRead || inWrite || inAlter) {
5563
      code = taosHashRemove(newUser.readViews, view, len);
5564
      if (code < 0) {
5565
        mError("failed to remove readViews:%s from user:%s", view, pUser->user);
5566
      }
5567
      code = taosHashRemove(newUser.writeViews, view, len);
5568
      if (code < 0) {
5569
        mError("failed to remove writeViews:%s from user:%s", view, pUser->user);
5570
      }
5571
      code = taosHashRemove(newUser.alterViews, view, len);
5572
      if (code < 0) {
5573
        mError("failed to remove alterViews:%s from user:%s", view, pUser->user);
5574
      }
5575

5576
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
5577
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
5578
        code = TSDB_CODE_OUT_OF_MEMORY;
5579
        break;
5580
      }
5581
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
5582
      if (code < 0) {
5583
        mndUserFreeObj(&newUser);
5584
        sdbRelease(pSdb, pUser);
5585
        TAOS_RETURN(code);
5586
      }
5587
    }
5588

5589
    mndUserFreeObj(&newUser);
5590
    sdbRelease(pSdb, pUser);
5591
  }
5592
#endif
5593
  if (pUser != NULL) sdbRelease(pSdb, pUser);
×
5594
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
×
5595
  mndUserFreeObj(&newUser);
×
5596
  TAOS_RETURN(code);
×
5597
}
5598

5599
int32_t mndUserRemoveTopic(SMnode *pMnode, STrans *pTrans, char *topic) {
95,223✔
5600
  int32_t   code = 0;
95,223✔
5601
  SSdb     *pSdb = pMnode->pSdb;
95,223✔
5602
  int32_t   len = strlen(topic) + 1;
95,223✔
5603
  void     *pIter = NULL;
95,223✔
5604
  SUserObj *pUser = NULL;
95,223✔
5605
  SUserObj  newUser = {0};
95,223✔
5606
#ifdef PRIV_TODO
5607
  while (1) {
5608
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
5609
    if (pIter == NULL) {
5610
      break;
5611
    }
5612

5613
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
5614
      break;
5615
    }
5616

5617
    bool inTopic = (taosHashGet(newUser.topics, topic, len) != NULL);
5618
    if (inTopic) {
5619
      code = taosHashRemove(newUser.topics, topic, len);
5620
      if (code < 0) {
5621
        mError("failed to remove topic:%s from user:%s", topic, pUser->user);
5622
      }
5623
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
5624
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
5625
        code = TSDB_CODE_OUT_OF_MEMORY;
5626
        break;
5627
      }
5628
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
5629
      if (code < 0) {
5630
        mndUserFreeObj(&newUser);
5631
        sdbRelease(pSdb, pUser);
5632
        TAOS_RETURN(code);
5633
      }
5634
    }
5635

5636
    mndUserFreeObj(&newUser);
5637
    sdbRelease(pSdb, pUser);
5638
  }
5639
#endif
5640
  if (pUser != NULL) sdbRelease(pSdb, pUser);
95,223✔
5641
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
95,223✔
5642
  mndUserFreeObj(&newUser);
95,223✔
5643
  TAOS_RETURN(code);
95,223✔
5644
}
5645

5646
int64_t mndGetUserIpWhiteListVer(SMnode *pMnode, SUserObj *pUser) {
×
5647
  // ver = 0, disable ip white list
5648
  // ver > 0, enable ip white list
5649
  return tsEnableWhiteList ? pUser->ipWhiteListVer : 0;
×
5650
}
5651

5652
int64_t mndGetUserTimeWhiteListVer(SMnode *pMnode, SUserObj *pUser) {
×
5653
  // ver = 0, disable datetime white list
5654
  // ver > 0, enable datetime white list
5655
  return tsEnableWhiteList ? pUser->timeWhiteListVer : 0;
×
5656
}
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