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

taosdata / TDengine / #4933

20 Jan 2026 10:44AM UTC coverage: 66.671% (+0.03%) from 66.646%
#4933

push

travis-ci

web-flow
merge: from main to 3.0 #34340

73 of 178 new or added lines in 9 files covered. (41.01%)

1199 existing lines in 124 files now uncovered.

203121 of 304663 relevant lines covered (66.67%)

132228377.94 hits per line

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

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

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

35
// clang-format on
36

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

42
#define USER_RESERVE_SIZE                    63
43

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

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

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

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

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

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

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

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

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

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

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

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

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

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

145

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

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

159
static SUserCache userCache;
160

161

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

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

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

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

178

179

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

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

197
  (void)taosThreadRwlockDestroy(&userCache.rw);
398,656✔
198
}
199

200

201

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

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

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

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

224

225

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

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

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

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

241

242

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

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

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

260
  return pInfo;
432,293✔
261
}
262

263

264

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

268
  (void)taosThreadRwlockRdlock(&userCache.rw);
2,259,032✔
269

270
  SCachedUserInfo **ppInfo = taosHashGet(userCache.users, user, userLen);
2,258,751✔
271
  if (ppInfo != NULL && *ppInfo != NULL) {
2,258,945✔
272
    pLoginInfo->lastLoginTime = (*ppInfo)->loginInfo.lastLoginTime;
1,980,985✔
273
    pLoginInfo->failedLoginCount = (*ppInfo)->loginInfo.failedLoginCount;
1,981,072✔
274
    pLoginInfo->lastFailedLoginTime = (*ppInfo)->loginInfo.lastFailedLoginTime;
1,981,072✔
275
  } else {
276
    pLoginInfo->lastLoginTime = taosGetTimestampSec();
277,960✔
277
    pLoginInfo->failedLoginCount = 0;
277,960✔
278
    pLoginInfo->lastFailedLoginTime = 0;
277,960✔
279
  }
280

281
  (void)taosThreadRwlockUnlock(&userCache.rw);
2,259,032✔
282

283
  if (pLoginInfo->lastLoginTime == 0) {
2,259,144✔
284
    pLoginInfo->lastLoginTime = taosGetTimestampSec();
31,520✔
285
  }
286
}
2,258,715✔
287

288

289

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

293
  (void)taosThreadRwlockWrlock(&userCache.rw);
2,254,454✔
294

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

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

305

306

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

312
  if (a == NULL || b == NULL) {
1,034,570✔
313
    return false;
54,833✔
314
  }
315

316
  if (a->num != b->num) {
979,737✔
317
    return false;
256✔
318
  }
319

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

329
  return true;
979,481✔
330
}
331

332

333

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

337
  (void)taosThreadRwlockWrlock(&userCache.rw);
1,034,570✔
338

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

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

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

364
_OVER:
1,034,570✔
365
  (void)taosThreadRwlockUnlock(&userCache.rw);
1,034,570✔
366
  if (code < 0) {
1,034,570✔
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,034,570✔
370
}
371

372

373

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

377
  SSdb     *pSdb = pMnode->pSdb;
481,087✔
378
  void     *pIter = NULL;
481,087✔
379
  while (1) {
182,771✔
380
    SUserObj *pUser = NULL;
663,858✔
381
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
663,858✔
382
    if (pIter == NULL) {
663,858✔
383
      break;
481,087✔
384
    }
385

386
    SCachedUserInfo *pInfo = getCachedUserInfo(pUser->user);
182,771✔
387
    if (pInfo == NULL) {
182,771✔
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);
182,771✔
394
    if (wl == NULL) {
182,771✔
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);
182,771✔
401
    pInfo->wlIp = wl;
182,771✔
402

403
    sdbRelease(pSdb, pUser);
182,771✔
404
  }
405

406
  userCache.verIp++;
481,087✔
407

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

415

416

417
int64_t mndGetIpWhiteListVersion(SMnode *pMnode) {
42,665,616✔
418
  int64_t ver = 0;
42,665,616✔
419
  int32_t code = 0;
42,665,616✔
420

421
  if (mndEnableIpWhiteList(pMnode) != 0 && tsEnableWhiteList) {
42,665,616✔
422
    (void)taosThreadRwlockWrlock(&userCache.rw);
3,811✔
423

424
    if (userCache.verIp == 0) {
3,811✔
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;
3,811✔
434

435
    (void)taosThreadRwlockUnlock(&userCache.rw);
3,811✔
436
  }
437

438
  mDebug("ip-white-list on mnode ver: %" PRId64, ver);
42,665,616✔
439
  return ver;
42,665,616✔
440
}
441

442

443

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

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

455
  TAOS_RETURN(code);
481,087✔
456
}
457

458

459

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

463
  SSdb     *pSdb = pMnode->pSdb;
472,698✔
464
  void     *pIter = NULL;
472,698✔
465
  while (1) {
174,382✔
466
    SUserObj *pUser = NULL;
647,080✔
467
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
647,080✔
468
    if (pIter == NULL) {
647,080✔
469
      break;
472,698✔
470
    }
471

472
    SCachedUserInfo *pInfo = getCachedUserInfo(pUser->user);
174,382✔
473
    if (pInfo == NULL) {
174,382✔
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);
174,382✔
480
    if (wl == NULL) {
174,382✔
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);
174,382✔
487
    pInfo->wlTime = wl;
174,382✔
488

489
    sdbRelease(pSdb, pUser);
174,382✔
490
  }
491

492
  userCache.verTime++;
472,698✔
493

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

501

502

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

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

514
  TAOS_RETURN(code);
472,698✔
515
}
516

517

518

519
int64_t mndGetTimeWhiteListVersion(SMnode *pMnode) {
42,665,616✔
520
  int64_t ver = 0;
42,665,616✔
521
  int32_t code = 0;
42,665,616✔
522

523
  if (mndEnableTimeWhiteList(pMnode) != 0 && tsEnableWhiteList) {
42,665,616✔
524
    (void)taosThreadRwlockWrlock(&userCache.rw);
3,811✔
525

526
    if (userCache.verIp == 0) {
3,811✔
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;
3,811✔
536

537
    (void)taosThreadRwlockUnlock(&userCache.rw);
3,811✔
538
  }
539

540
  mDebug("datetime-white-list on mnode ver: %" PRId64, ver);
42,665,616✔
541
  return ver;
42,665,616✔
542
}
543

544

545

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

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

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

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

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

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

585

586

587
void mndCleanupUser(SMnode *pMnode) {
398,656✔
588
  userCacheCleanup();
398,656✔
589
}
398,656✔
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) {
1,327,247✔
616
  int32_t len = 0;
1,327,247✔
617
  for (int i = 0; i < num; i++) {
3,991,321✔
618
    SIpRange *pRange = &range[i];
2,664,074✔
619
    SIpAddr   addr = {0};
2,664,074✔
620
    int32_t code = tIpUintToStr(pRange, &addr);
2,664,074✔
621
    if (code != 0) {
2,664,074✔
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);
2,664,074✔
626
  }
627
  if (len > 0) buf[len - 2] = 0;
1,327,247✔
628
  return len;
1,327,247✔
629
}
630

631

632

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

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

649

650

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

660
  if (a->num != b->num) {
979,737✔
661
    return false;
411✔
662
  }
663
  for (int i = 0; i < a->num; i++) {
2,937,978✔
664
    if (!isIpRangeEqual(&a->pIpRanges[i], &b->pIpRanges[i])) {
1,958,652✔
665
      return false;
×
666
    }
667
  }
668
  return true;
979,326✔
669
}
670

671

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

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

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

684
  if (ra->type == 0) {
2,217✔
685
    if (ra->ipV4.ip != rb->ipV4.ip) {
2,217✔
686
      return (ra->ipV4.ip < rb->ipV4.ip) ? -1 : 1;
1,907✔
687
    }
688
    return (ra->ipV4.mask < rb->ipV4.mask) ? -1 : 1;
310✔
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) {
1,673✔
701
  (void)taosqsort(pList->pIpRanges, pList->num, sizeof(SIpRange), NULL, compareIpRange);
1,673✔
702
}
1,673✔
703

704

705

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

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

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

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

727

728

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

736
  TAOS_CHECK_GOTO(tStartEncode(&encoder), &lino, _OVER);
2,248,304✔
737
  TAOS_CHECK_GOTO(tEncodeI32(&encoder, pList->num), &lino, _OVER);
4,496,608✔
738

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

744
  tEndEncode(&encoder);
2,248,304✔
745

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

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

762
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
1,497,436✔
763
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &pList->num), &lino, _OVER);
2,994,872✔
764

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

770
_OVER:
1,497,436✔
771
  tEndDecode(&decoder);
1,497,436✔
772
  tDecoderClear(&decoder);
1,497,436✔
773
  if (code < 0) {
1,497,436✔
774
    mError("failed to deserialize ip white list at line %d since %s", lino, tstrerror(code));
×
775
  }
776
  TAOS_RETURN(code);
1,497,436✔
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,497,436✔
804
  int32_t           code = 0;
1,497,436✔
805
  int32_t           lino = 0;
1,497,436✔
806
  int32_t           num = 0;
1,497,436✔
807
  SIpWhiteListDual *p = NULL;
1,497,436✔
808
  SDecoder          decoder = {0};
1,497,436✔
809
  tDecoderInit(&decoder, buf, len);
1,497,436✔
810

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

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

820
_OVER:
1,497,436✔
821
  tEndDecode(&decoder);
1,497,436✔
822
  tDecoderClear(&decoder);
1,497,436✔
823
  if (code < 0) {
1,497,436✔
824
    taosMemoryFreeClear(p);
×
825
    mError("failed to create ip white list at line %d since %s", lino, tstrerror(code));
×
826
  }
827
  *ppList = p;
1,497,436✔
828
  TAOS_RETURN(code);
1,497,436✔
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) {
339,655✔
860
  int32_t code = 0;
339,655✔
861
  int32_t lino = 0;
339,655✔
862
  *ppWhiteList = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + sizeof(SIpRange) * 2);
339,655✔
863
  if (*ppWhiteList == NULL) {
339,655✔
864
    TAOS_RETURN(terrno);
×
865
  }
866
  (*ppWhiteList)->num = 2;
339,655✔
867

868
  SIpRange v4 = {0};
339,655✔
869
  SIpRange v6 = {0};
339,655✔
870

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

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

878
#endif
879

880
_error:
339,655✔
881
  if (code != 0) {
339,655✔
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));
339,655✔
887
    memcpy(&(*ppWhiteList)->pIpRanges[1], &v6, sizeof(SIpRange));
339,655✔
888
  }
889
  return 0;
339,655✔
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) {
1,327,247✔
896
  int32_t bufLen = pUser->pTimeWhiteList->num * 32 + 8;
1,327,247✔
897
  *buf = taosMemoryCalloc(1, bufLen);
1,327,247✔
898
  if (*buf == NULL) {
1,327,247✔
899
    return 0;
×
900
  }
901

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

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

912
    if (range->absolute) {
35,328✔
913
      struct STm tm;
25,344✔
914
      (void)taosTs2Tm(range->start, TSDB_TIME_PRECISION_SECONDS, &tm, NULL);
25,344✔
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);
25,344✔
916
    } else {
917
      int day = range->start / 86400;
9,984✔
918
      int hour = (range->start % 86400) / 3600;
9,984✔
919
      int minute = (range->start % 3600) / 60;
9,984✔
920
      pos += tsnprintf(*buf + pos, bufLen - pos, "%c%s %02d:%02d %dm, ", range->neg ? '-' : '+', weekdays[day], hour, minute, duration);
9,984✔
921
    }
922
  }
923

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

928
  return pos;
33,024✔
929
}
930

931

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

936
  if (pA->neg != pB->neg) {
128✔
937
    return pA->neg ? -1 : 1;
128✔
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) {
1,280✔
956
  (void)taosqsort(pList->ranges, pList->num, sizeof(SDateTimeWhiteListItem), NULL, compareDateTimeInterval);
1,280✔
957
}
1,280✔
958

959

960

961

962
static void dropOldPasswords(SUserObj *pUser) {
4,759,512✔
963
  if (pUser->numOfPasswords <= pUser->passwordReuseMax) {
4,759,512✔
964
    return;
4,749,193✔
965
  }
966

967
  int32_t reuseMax = pUser->passwordReuseMax;
10,319✔
968
  if (reuseMax == 0) {
10,319✔
969
    reuseMax = 1; // keep at least one password
8,022✔
970
  }
971

972
  int32_t now = taosGetTimestampSec();
10,319✔
973
  int32_t index = reuseMax;
10,319✔
974
  while(index < pUser->numOfPasswords) {
15,657✔
975
    // the set time of the n-th password is the expire time of the n+1-th password
976
    int32_t expireTime = pUser->passwords[index - 1].setTime;
5,594✔
977
    if (now - expireTime >= pUser->passwordReuseTime) {
5,594✔
978
      break;
256✔
979
    }
980
    index++;
5,338✔
981
  }
982

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

991

992

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

998
  userObj.passwords = taosMemCalloc(1, sizeof(SUserPassword));
286,089✔
999
  if (userObj.passwords == NULL) {
286,089✔
1000
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _ERROR);
×
1001
  }
1002
  taosEncryptPass_c((uint8_t *)pass, strlen(pass), userObj.passwords[0].pass);
286,089✔
1003
  userObj.passwords[0].pass[sizeof(userObj.passwords[0].pass) - 1] = 0;
286,089✔
1004
  if (tsiEncryptPassAlgorithm == DND_CA_SM4 && strlen(tsDbKey) > 0) {
286,089✔
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();
286,089✔
1010
  userObj.numOfPasswords = 1;
286,089✔
1011

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

1020
#ifdef TD_ENTERPRISE
1021

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

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

1043
#else // TD_ENTERPRISE
1044

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

1063
#endif // TD_ENTERPRISE
1064

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

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

1089
  if ((code = taosHashPut(userObj.roles, TSDB_ROLE_SYSDBA, strlen(TSDB_ROLE_SYSDBA) + 1, NULL, 0)) ||
572,178✔
1090
      (code = taosHashPut(userObj.roles, TSDB_ROLE_SYSSEC, strlen(TSDB_ROLE_SYSSEC) + 1, NULL, 0)) ||
572,178✔
1091
      (code = taosHashPut(userObj.roles, TSDB_ROLE_SYSAUDIT, strlen(TSDB_ROLE_SYSAUDIT) + 1, NULL, 0))) {
286,089✔
1092
    TAOS_CHECK_GOTO(code, &lino, _ERROR);
×
1093
  }
1094

1095
  SSdbRaw *pRaw = mndUserActionEncode(&userObj);
286,089✔
1096
  if (pRaw == NULL) goto _ERROR;
286,089✔
1097
  TAOS_CHECK_GOTO(sdbSetRawStatus(pRaw, SDB_STATUS_READY), &lino, _ERROR);
286,089✔
1098

1099
  mInfo("user:%s, will be created when deploying, raw:%p", userObj.user, pRaw);
286,089✔
1100

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

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

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

1122
  mndTransDrop(pTrans);
286,089✔
1123
  mndUserFreeObj(&userObj);
286,089✔
1124
  return 0;
286,089✔
1125

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

1135
static int32_t mndCreateDefaultUsers(SMnode *pMnode) {
286,089✔
1136
  return mndCreateDefaultUser(pMnode, TSDB_DEFAULT_USER, TSDB_DEFAULT_USER, TSDB_DEFAULT_PASS);
286,089✔
1137
}
1138

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

1146
  TAOS_CHECK_EXIT(tStartEncode(&encoder));
4,496,608✔
1147
  TAOS_CHECK_EXIT(tEncodeI64v(&encoder, pObj->uid));
8,993,216✔
1148

1149
  TAOS_CHECK_EXIT(tSerializePrivSysObjPolicies(&encoder, &pObj->sysPrivs, pObj->objPrivs));
4,496,608✔
1150

1151
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->selectTbs));
4,496,608✔
1152
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->insertTbs));
4,496,608✔
1153
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->updateTbs));
4,496,608✔
1154
  TAOS_CHECK_EXIT(tSerializePrivTblPolicies(&encoder, pObj->deleteTbs));
4,496,608✔
1155

1156
  int32_t nRoles = taosHashGetSize(pObj->roles);
4,496,608✔
1157
  TAOS_CHECK_EXIT(tEncodeI32v(&encoder, nRoles));
4,496,608✔
1158

1159
  while ((pIter = taosHashIterate(pObj->roles, pIter))) {
13,195,238✔
1160
    size_t keyLen = 0;
8,698,630✔
1161
    char  *key = taosHashGetKey(pIter, &keyLen);  // key: role name
8,698,630✔
1162
    TAOS_CHECK_EXIT(tEncodeCStr(&encoder, key));
8,698,630✔
1163

1164
    uint8_t flag = *(int8_t *)pIter;
8,698,630✔
1165
    TAOS_CHECK_EXIT(tEncodeU8(&encoder, flag));  // value: 0 reset, 1 set(default)
17,397,260✔
1166
  }
1167

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

1177
  return tlen;
4,496,608✔
1178
}
1179

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

1185
  TAOS_CHECK_EXIT(tStartDecode(&decoder));
1,497,436✔
1186
  TAOS_CHECK_EXIT(tDecodeI64v(&decoder, &pObj->uid));
2,994,872✔
1187
  TAOS_CHECK_EXIT(tDeserializePrivSysObjPolicies(&decoder, &pObj->sysPrivs, &pObj->objPrivs));
1,497,436✔
1188
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->selectTbs));
1,497,436✔
1189
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->insertTbs));
1,497,436✔
1190
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->updateTbs));
1,497,436✔
1191
  TAOS_CHECK_EXIT(tDeserializePrivTblPolicies(&decoder, &pObj->deleteTbs));
1,497,436✔
1192
  int32_t nRoles = 0;
1,497,436✔
1193
  TAOS_CHECK_EXIT(tDecodeI32v(&decoder, &nRoles));
1,497,436✔
1194
  if (nRoles > 0) {
1,497,436✔
1195
    if (!pObj->roles &&
1,497,281✔
1196
        !(pObj->roles = taosHashInit(nRoles, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), 1, HASH_ENTRY_LOCK))) {
1,497,281✔
1197
      TAOS_CHECK_EXIT(terrno);
×
1198
    }
1199
    for (int32_t i = 0; i < nRoles; i++) {
3,794,684✔
1200
      int32_t keyLen = 0;
2,297,403✔
1201
      char   *key = NULL;
2,297,403✔
1202
      TAOS_CHECK_EXIT(tDecodeCStrAndLen(&decoder, &key, &keyLen));
2,297,403✔
1203
      uint8_t flag = 0;
2,297,403✔
1204
      TAOS_CHECK_EXIT(tDecodeU8(&decoder, &flag));
2,297,403✔
1205
      TAOS_CHECK_EXIT(taosHashPut(pObj->roles, key, keyLen + 1, &flag, sizeof(flag)));
2,297,403✔
1206
    }
1207
  }
1208

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

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

1240
  char *stb = NULL;
2,248,304✔
1241
#if 0
1242
  stb = taosHashIterate(pUser->readTbs, 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->readTbs, stb);
1254
  }
1255

1256
  stb = taosHashIterate(pUser->writeTbs, 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->writeTbs, stb);
1268
  }
1269
  stb = taosHashIterate(pUser->alterTbs, NULL);
1270
  while (stb != NULL) {
1271
    size_t keyLen = 0;
1272
    void  *key = taosHashGetKey(stb, &keyLen);
1273
    size += sizeof(int32_t);
1274
    size += keyLen;
1275

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

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

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

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

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

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

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

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

1341
  pRaw = sdbAllocRaw(SDB_USER, USER_VER_NUMBER, size);
2,248,304✔
1342
  if (pRaw == NULL) {
2,248,304✔
1343
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1344
  }
1345

1346
  int32_t dataPos = 0;
2,248,304✔
1347
  SDB_SET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN, _OVER)
2,248,304✔
1348

1349
  dropOldPasswords(pUser);
2,248,304✔
1350
  SDB_SET_INT32(pRaw, dataPos, pUser->numOfPasswords, _OVER)
2,248,304✔
1351
  for (int32_t i = 0; i < pUser->numOfPasswords; i++) {
5,200,763✔
1352
    SDB_SET_BINARY(pRaw, dataPos, pUser->passwords[i].pass, sizeof(pUser->passwords[i].pass), _OVER)
2,952,459✔
1353
    SDB_SET_INT32(pRaw, dataPos, pUser->passwords[i].setTime, _OVER)
2,952,459✔
1354
  }
1355
  SDB_SET_BINARY(pRaw, dataPos, pUser->salt, sizeof(pUser->salt), _OVER)
2,248,304✔
1356

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

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

1395
#if 0
1396
  stb = taosHashIterate(pUser->readTbs, 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->readTbs, stb);
1408
  }
1409

1410
  stb = taosHashIterate(pUser->writeTbs, 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->writeTbs, stb);
1422
  }
1423
  stb = taosHashIterate(pUser->alterTbs, NULL);
1424
  while (stb != NULL) {
1425
    size_t keyLen = 0;
1426
    void  *key = taosHashGetKey(stb, &keyLen);
1427
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
1428
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
1429

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

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

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

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

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

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

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

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

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

1500
  SDB_SET_INT32(pRaw, dataPos, len, _OVER);
2,248,304✔
1501
  SDB_SET_BINARY(pRaw, dataPos, buf, len, _OVER);
2,248,304✔
1502

1503
  SDB_SET_INT64(pRaw, dataPos, pUser->ipWhiteListVer, _OVER);
2,248,304✔
1504
  SDB_SET_INT8(pRaw, dataPos, pUser->passEncryptAlgorithm, _OVER);
2,248,304✔
1505

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

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

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

1539
  SDB_SET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
2,248,304✔
1540

1541
  SDB_SET_DATALEN(pRaw, dataPos, _OVER)
2,248,304✔
1542

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

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

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

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

1576
  int8_t sver = 0;
1,497,436✔
1577
  if (sdbGetRawSoftVer(pRaw, &sver) != 0) {
1,497,436✔
1578
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_PTR, &lino, _OVER);
×
1579
  }
1580

1581
  if (sver < 1 || sver > USER_VER_NUMBER) {
1,497,436✔
1582
    TAOS_CHECK_GOTO(TSDB_CODE_SDB_INVALID_DATA_VER, &lino, _OVER);
×
1583
  }
1584

1585
  pRow = sdbAllocRow(sizeof(SUserObj));
1,497,436✔
1586
  if (pRow == NULL) {
1,497,436✔
1587
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1588
  }
1589

1590
  pUser = sdbGetRowObj(pRow);
1,497,436✔
1591
  if (pUser == NULL) {
1,497,436✔
1592
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1593
  }
1594

1595
  int32_t dataPos = 0;
1,497,436✔
1596
  SDB_GET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN, _OVER)
1,497,436✔
1597

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

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

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

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

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

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

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

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

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

1729
    for (int32_t i = 0; i < numOfReadTbs; ++i) {
1,497,436✔
1730
      int32_t keyLen = 0;
×
1731
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
1732

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

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

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

1752
    for (int32_t i = 0; i < numOfWriteTbs; ++i) {
1,497,436✔
1753
      int32_t keyLen = 0;
×
1754
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
1755

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

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

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

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

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

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

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

1799
      for (int32_t i = 0; i < numOfReadViews; ++i) {
1,497,436✔
1800
        int32_t keyLen = 0;
×
1801
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
1802

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

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

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

1822
      for (int32_t i = 0; i < numOfWriteViews; ++i) {
1,497,436✔
1823
        int32_t keyLen = 0;
×
1824
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
1825

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

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

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

1845
      for (int32_t i = 0; i < numOfAlterViews; ++i) {
1,497,436✔
1846
        int32_t keyLen = 0;
×
1847
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
1848

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

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

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

1869
    for (int32_t i = 0; i < numOfUseDbs; ++i) {
1,497,436✔
1870
      int32_t keyLen = 0;
×
1871
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
×
1872

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

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

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

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

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

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

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

1909
      taosMemoryFreeClear(pIpWhiteList);
×
1910

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

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

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

1926
  if (pUser->pIpWhiteListDual == NULL) {
1,497,436✔
1927
    TAOS_CHECK_GOTO(createDefaultIpWhiteList(&pUser->pIpWhiteListDual), &lino, _OVER);
×
1928
    pUser->ipWhiteListVer = taosGetTimestampMs();
×
1929
  }
1930

1931
  SDB_GET_INT8(pRaw, dataPos, &pUser->passEncryptAlgorithm, _OVER);
1,497,436✔
1932

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

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

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

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

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

2016
  SDB_GET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
1,497,436✔
2017

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

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

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

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

2061
  return 0;
458,191✔
2062
}
2063

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

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

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

2086
  TAOS_RETURN(code);
×
2087
}
2088

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

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

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

2110
  TAOS_RETURN(code);
×
2111
}
2112

2113
int32_t mndDupRoleHash(SHashObj *pOld, SHashObj **ppNew) {
1,014,940✔
2114
  if (!(*ppNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true,
1,014,940✔
2115
                              HASH_ENTRY_LOCK))) {
2116
    TAOS_RETURN(terrno);
×
2117
  }
2118

2119
  int32_t  code = 0;
1,014,940✔
2120
  uint8_t *flag = NULL;
1,014,940✔
2121
  while ((flag = taosHashIterate(pOld, flag))) {
2,030,989✔
2122
    size_t keyLen = 0;
1,016,049✔
2123
    char  *key = taosHashGetKey(flag, &keyLen);
1,016,049✔
2124

2125
    if ((code = taosHashPut(*ppNew, key, keyLen, flag, sizeof(*flag))) != 0) {
1,016,049✔
2126
      taosHashCancelIterate(pOld, flag);
×
2127
      taosHashCleanup(*ppNew);
×
2128
      TAOS_RETURN(code);
×
2129
    }
2130
  }
2131

2132
  TAOS_RETURN(code);
1,014,940✔
2133
}
2134

2135
int32_t mndMergePrivObjHash(SHashObj *pOld, SHashObj **ppNew) {
83,550,236✔
2136
  if (!(*ppNew)) return mndDupPrivObjHash(pOld, ppNew);
83,550,236✔
2137

2138
  int32_t           code = 0, lino = 0;
83,551,656✔
2139
  SHashObj         *pNew = *ppNew;
83,551,656✔
2140
  SPrivObjPolicies *policies = NULL;
83,551,392✔
2141
  while ((policies = taosHashIterate(pOld, policies))) {
779,685,708✔
2142
    size_t klen = 0;
696,137,795✔
2143
    char  *key = taosHashGetKey(policies, &klen);
696,137,085✔
2144
    size_t vlen = taosHashGetValueSize(policies);
696,134,953✔
2145

2146
    SPrivObjPolicies *pNewPolicies = taosHashGet(pNew, key, klen);
696,137,083✔
2147
    if (pNewPolicies) {
696,136,217✔
2148
      size_t newVlen = taosHashGetValueSize(pNewPolicies);
443,592,106✔
2149
      if (newVlen > 0 && vlen > 0) {
443,591,120✔
2150
        privAddSet(&pNewPolicies->policy, &policies->policy);
443,591,120✔
2151
      }
2152
      continue;
443,590,288✔
2153
    }
2154

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

2163
  TAOS_RETURN(code);
83,551,380✔
2164
}
2165

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

2173
  int32_t           code = 0, lino = 0;
250,654,042✔
2174
  SHashObj         *pNew = *ppNew;
250,654,042✔
2175
  SPrivTblPolicies *policies = NULL;
250,654,440✔
2176
  while ((policies = taosHashIterate(pOld, policies))) {
250,654,440✔
2177
    size_t klen = 0;
×
2178
    char  *key = taosHashGetKey(policies, &klen);
×
2179
    size_t vlen = taosHashGetValueSize(policies);
×
2180

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

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

2206
_exit:
250,654,306✔
2207
  TAOS_RETURN(code);
250,654,306✔
2208
}
2209

2210
int32_t mndDupPrivObjHash(SHashObj *pOld, SHashObj **ppNew) {
29,116,437✔
2211
  if (!(*ppNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true,
29,116,437✔
2212
                             HASH_ENTRY_LOCK))) {
2213
    TAOS_RETURN(terrno);
×
2214
  }
2215
  int32_t           code = 0;
29,115,730✔
2216
  SPrivObjPolicies *policies = NULL;
29,115,730✔
2217
  while ((policies = taosHashIterate(pOld, policies))) {
31,901,497✔
2218
    size_t klen = 0;
2,785,767✔
2219
    char  *key = taosHashGetKey(policies, &klen);
2,785,767✔
2220
    size_t vlen = taosHashGetValueSize(policies);
2,785,767✔
2221

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

2229
  TAOS_RETURN(code);
29,116,200✔
2230
}
2231

2232
int32_t mndDupPrivTblHash(SHashObj *pOld, SHashObj **ppNew, bool setUpdateTimeMax) {
88,364,376✔
2233
  if (!(*ppNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true,
88,364,376✔
2234
                              HASH_ENTRY_LOCK))) {
2235
    TAOS_RETURN(terrno);
×
2236
  }
2237
  taosHashSetFreeFp(*ppNew, privTblPoliciesFree);
88,365,086✔
2238

2239
  int32_t           code = 0, lino = 0;
88,365,086✔
2240
  SPrivTblPolicies *policies = NULL, *pTmpPolicies = NULL;
88,365,086✔
2241
  SPrivTblPolicies  tmpPolicies = {0};
88,365,086✔
2242
  while ((policies = taosHashIterate(pOld, policies))) {
88,418,238✔
2243
    size_t klen = 0;
53,152✔
2244
    char  *key = taosHashGetKey(policies, &klen);
53,152✔
2245
    size_t vlen = taosHashGetValueSize(policies);
53,152✔
2246
    memset(&tmpPolicies, 0, sizeof(tmpPolicies));
53,152✔
2247
    pTmpPolicies = &tmpPolicies;
53,152✔
2248
    if (vlen > 0) {
53,152✔
2249
      TAOS_CHECK_EXIT(privTblPoliciesAdd(&tmpPolicies, policies, true, setUpdateTimeMax));
53,152✔
2250
    }
2251
    TAOS_CHECK_EXIT(taosHashPut(*ppNew, key, klen, vlen > 0 ? &tmpPolicies : NULL, vlen));
53,152✔
2252
    pTmpPolicies = NULL;
53,152✔
2253
  }
2254

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

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

2275
  pNew->passwords = NULL;
1,013,772✔
2276
  pNew->pIpWhiteListDual = NULL;
1,013,772✔
2277
  pNew->passwords = NULL;
1,013,772✔
2278
  pNew->objPrivs = NULL;
1,013,772✔
2279
  pNew->selectTbs = NULL;
1,013,772✔
2280
  pNew->insertTbs = NULL;
1,013,772✔
2281
  pNew->updateTbs = NULL;
1,013,772✔
2282
  pNew->deleteTbs = NULL;
1,013,772✔
2283
  pNew->pTimeWhiteList = NULL;
1,013,772✔
2284
  pNew->roles = NULL;
1,013,772✔
2285

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

2305
  pNew->pTimeWhiteList = cloneDateTimeWhiteList(pUser->pTimeWhiteList);
1,013,772✔
2306
  if (pNew->pTimeWhiteList == NULL) {
1,013,772✔
2307
    code = TSDB_CODE_OUT_OF_MEMORY;
×
2308
    goto _OVER;
×
2309
  }
2310

2311
_OVER:
1,013,772✔
2312
  taosRUnLockLatch(&pUser->lock);
1,013,772✔
2313
  if (code == 0) {
1,013,772✔
2314
    dropOldPasswords(pNew);
1,013,772✔
2315
  }
2316
  TAOS_RETURN(code);
1,013,772✔
2317
}
2318

2319
void mndUserFreeObj(SUserObj *pUser) {
5,096,044✔
2320
  taosHashCleanup(pUser->objPrivs);
5,096,044✔
2321
  taosHashCleanup(pUser->selectTbs);
5,096,044✔
2322
  taosHashCleanup(pUser->insertTbs);
5,096,044✔
2323
  taosHashCleanup(pUser->updateTbs);
5,096,044✔
2324
  taosHashCleanup(pUser->deleteTbs);
5,096,044✔
2325
  taosHashCleanup(pUser->roles);
5,096,044✔
2326
  taosMemoryFreeClear(pUser->passwords);
5,096,044✔
2327
  taosMemoryFreeClear(pUser->pIpWhiteListDual);
5,096,044✔
2328
  taosMemoryFreeClear(pUser->pTimeWhiteList);
5,096,044✔
2329
  pUser->objPrivs = NULL;
5,096,044✔
2330
  pUser->selectTbs = NULL;
5,096,044✔
2331
  pUser->insertTbs = NULL;
5,096,044✔
2332
  pUser->updateTbs = NULL;
5,096,044✔
2333
  pUser->deleteTbs = NULL;
5,096,044✔
2334
  pUser->roles = NULL;
5,096,044✔
2335
}
5,096,044✔
2336

2337
static int32_t mndUserActionDelete(SSdb *pSdb, SUserObj *pUser) {
1,497,393✔
2338
  mTrace("user:%s, perform delete action, row:%p", pUser->user, pUser);
1,497,393✔
2339
  mndUserFreeObj(pUser);
1,497,393✔
2340
  return 0;
1,497,393✔
2341
}
2342

2343
static int32_t mndUserActionUpdate(SSdb *pSdb, SUserObj *pOld, SUserObj *pNew) {
1,016,548✔
2344
  mTrace("user:%s, perform update action, old row:%p new row:%p", pOld->user, pOld, pNew);
1,016,548✔
2345
  taosWLockLatch(&pOld->lock);
1,016,548✔
2346
  pOld->updateTime = pNew->updateTime;
1,016,548✔
2347
  pOld->authVersion = pNew->authVersion;
1,016,548✔
2348
  pOld->passVersion = pNew->passVersion;
1,016,548✔
2349
  pOld->sysInfo = pNew->sysInfo;
1,016,548✔
2350
  pOld->enable = pNew->enable;
1,016,548✔
2351
  pOld->flag = pNew->flag;
1,016,548✔
2352
  pOld->changePass = pNew->changePass;
1,016,548✔
2353
  pOld->uid = pNew->uid;
1,016,548✔
2354

2355
  pOld->sessionPerUser = pNew->sessionPerUser;
1,016,548✔
2356
  pOld->connectTime = pNew->connectTime;
1,016,548✔
2357
  pOld->connectIdleTime = pNew->connectIdleTime;
1,016,548✔
2358
  pOld->callPerSession = pNew->callPerSession;
1,016,548✔
2359
  pOld->vnodePerCall = pNew->vnodePerCall;
1,016,548✔
2360
  pOld->failedLoginAttempts = pNew->failedLoginAttempts;
1,016,548✔
2361
  pOld->passwordLifeTime = pNew->passwordLifeTime;
1,016,548✔
2362
  pOld->passwordReuseTime = pNew->passwordReuseTime;
1,016,548✔
2363
  pOld->passwordReuseMax = pNew->passwordReuseMax;
1,016,548✔
2364
  pOld->passwordLockTime = pNew->passwordLockTime;
1,016,548✔
2365
  pOld->passwordGraceTime = pNew->passwordGraceTime;
1,016,548✔
2366
  pOld->inactiveAccountTime = pNew->inactiveAccountTime;
1,016,548✔
2367
  pOld->allowTokenNum = pNew->allowTokenNum;
1,016,548✔
2368
  pOld->tokenNum = pNew->tokenNum;
1,016,548✔
2369

2370
  pOld->numOfPasswords = pNew->numOfPasswords;
1,016,548✔
2371
  TSWAP(pOld->passwords, pNew->passwords);
1,016,548✔
2372
  (void)memcpy(pOld->salt, pNew->salt, sizeof(pOld->salt));
1,016,548✔
2373
  (void)memcpy(pOld->totpsecret, pNew->totpsecret, sizeof(pOld->totpsecret));
1,016,548✔
2374
  pOld->sysPrivs = pNew->sysPrivs;
1,016,548✔
2375
  TSWAP(pOld->objPrivs, pNew->objPrivs);
1,016,548✔
2376
  TSWAP(pOld->selectTbs, pNew->selectTbs);
1,016,548✔
2377
  TSWAP(pOld->insertTbs, pNew->insertTbs);
1,016,548✔
2378
  TSWAP(pOld->updateTbs, pNew->updateTbs);
1,016,548✔
2379
  TSWAP(pOld->deleteTbs, pNew->deleteTbs);
1,016,548✔
2380
  TSWAP(pOld->roles, pNew->roles);
1,016,548✔
2381

2382
  TSWAP(pOld->pIpWhiteListDual, pNew->pIpWhiteListDual);
1,016,548✔
2383
  pOld->ipWhiteListVer = pNew->ipWhiteListVer;
1,016,548✔
2384
  TSWAP(pOld->pTimeWhiteList, pNew->pTimeWhiteList);
1,016,548✔
2385
  pOld->timeWhiteListVer = pNew->timeWhiteListVer;
1,016,548✔
2386
  pOld->passEncryptAlgorithm = pNew->passEncryptAlgorithm;
1,016,548✔
2387

2388
  taosWUnLockLatch(&pOld->lock);
1,016,548✔
2389

2390
  return 0;
1,016,548✔
2391
}
2392

2393
int32_t mndAcquireUser(SMnode *pMnode, const char *userName, SUserObj **ppUser) {
85,619,572✔
2394
  int32_t code = 0;
85,619,572✔
2395
  SSdb   *pSdb = pMnode->pSdb;
85,619,572✔
2396

2397
  *ppUser = sdbAcquire(pSdb, SDB_USER, userName);
85,622,560✔
2398
  if (*ppUser == NULL) {
85,620,612✔
2399
    if (terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
59,320✔
2400
      code = TSDB_CODE_MND_USER_NOT_EXIST;
59,320✔
2401
    } else {
2402
      code = TSDB_CODE_MND_USER_NOT_AVAILABLE;
×
2403
    }
2404
  }
2405
  TAOS_RETURN(code);
85,621,322✔
2406
}
2407

2408
void mndReleaseUser(SMnode *pMnode, SUserObj *pUser) {
92,720,145✔
2409
  SSdb *pSdb = pMnode->pSdb;
92,720,145✔
2410
  sdbRelease(pSdb, pUser);
92,720,574✔
2411
}
92,721,629✔
2412

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

2425
int32_t mndBuildUidNamesHash(SMnode *pMnode, SSHashObj **ppHash) {
477,995✔
2426
  int32_t    code = 0;
477,995✔
2427
  void      *pIter = NULL;
477,995✔
2428
  SUserObj  *pObj;
477,995✔
2429
  SSHashObj *pHash = NULL;
477,995✔
2430

2431
  int32_t nUser = sdbGetSize(pMnode->pSdb, SDB_USER);
477,995✔
2432

2433
  pHash = tSimpleHashInit(nUser, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT));
477,995✔
2434
  if (pHash == NULL) {
477,995✔
2435
    TAOS_RETURN(terrno);
×
2436
  }
2437

2438
  while ((pIter = sdbFetch(pMnode->pSdb, SDB_USER, pIter, (void **)&pObj))) {
1,122,730✔
2439
    code = tSimpleHashPut(pHash, &pObj->uid, sizeof(pObj->uid), pObj->name, strlen(pObj->name) + 1);
644,735✔
2440
    if (code != 0) {
644,735✔
2441
      sdbRelease(pMnode->pSdb, pObj);
×
2442
      sdbCancelFetch(pMnode->pSdb, pIter);
×
2443
      tSimpleHashCleanup(pHash);
×
2444
      TAOS_RETURN(code);
×
2445
    }
2446
    sdbRelease(pMnode->pSdb, pObj);
644,735✔
2447
  }
2448

2449
  *ppHash = pHash;
477,995✔
2450
  TAOS_RETURN(code);
477,995✔
2451
}
2452

2453
int32_t mndEncryptPass(char *pass, const char* salt, int8_t *algo) {
73,255✔
2454
  int32_t code = 0;
73,255✔
2455
  if (tsMetaKey[0] == '\0') {
73,255✔
2456
    return 0;
73,193✔
2457
  }
2458

2459
  if (salt[0] != 0) {
62✔
2460
    char passAndSalt[TSDB_PASSWORD_LEN - 1 + TSDB_PASSWORD_SALT_LEN];
62✔
2461
    (void)memcpy(passAndSalt, pass, TSDB_PASSWORD_LEN - 1);
62✔
2462
    (void)memcpy(passAndSalt + TSDB_PASSWORD_LEN - 1, salt, TSDB_PASSWORD_SALT_LEN);
62✔
2463
    taosEncryptPass_c((uint8_t *)passAndSalt, sizeof(passAndSalt), pass);
2464
  }
2465

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

2476
  memcpy(pass, packetData, newLen);
62✔
2477
  if (algo != NULL) {
62✔
2478
    *algo = DND_CA_SM4;
62✔
2479
  }
2480

2481
  return 0;
62✔
2482
}
2483

2484

2485

2486
static void generateSalt(char *salt, size_t len) {
54,833✔
2487
  const char* set = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
54,833✔
2488
  int32_t     setLen = 62;
54,833✔
2489
  for (int32_t i = 0; i < len - 1; ++i) {
1,754,656✔
2490
    salt[i] = set[taosSafeRand() % setLen];
1,699,823✔
2491
  }
2492
  salt[len - 1] = 0;
54,833✔
2493
}
54,833✔
2494

2495

2496

2497
static int32_t addDefaultIpToTable(int8_t enableIpv6, SHashObj *pUniqueTab) {
1,107✔
2498
  int32_t code = 0;
1,107✔
2499
  int32_t lino = 0;
1,107✔
2500
  int32_t dummy = 0;
1,107✔
2501

2502
  SIpRange ipv4 = {0}, ipv6 = {0};
1,107✔
2503
  code = createDefaultIp4Range(&ipv4);
1,107✔
2504
  TSDB_CHECK_CODE(code, lino, _error);
1,107✔
2505

2506
  code = taosHashPut(pUniqueTab, &ipv4, sizeof(ipv4), &dummy, sizeof(dummy));
1,107✔
2507
  TSDB_CHECK_CODE(code, lino, _error);
1,107✔
2508

2509
  if (enableIpv6) {
1,107✔
2510
    code = createDefaultIp6Range(&ipv6);
×
2511
    TSDB_CHECK_CODE(code, lino, _error);
×
2512

2513
    code = taosHashPut(pUniqueTab, &ipv6, sizeof(ipv6), &dummy, sizeof(dummy));
×
2514
    TSDB_CHECK_CODE(code, lino, _error);
×
2515
  }
2516
_error:
1,107✔
2517
  if (code != 0) {
1,107✔
2518
    mError("failed to add default ip range to table since %s", tstrerror(code));
×
2519
  }
2520
  return code;
1,107✔
2521
}
2522

2523
static int32_t mndCreateUser(SMnode *pMnode, char *acct, SCreateUserReq *pCreate, SRpcMsg *pReq) {
54,673✔
2524
  int32_t  code = 0;
54,673✔
2525
  int32_t  lino = 0;
54,673✔
2526
  SUserObj userObj = {0};
54,673✔
2527

2528
  userObj.passwords = taosMemoryCalloc(1, sizeof(SUserPassword));
54,673✔
2529
  if (userObj.passwords == NULL) {
54,673✔
2530
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2531
  }
2532
  userObj.numOfPasswords = 1;
54,673✔
2533

2534
  if (pCreate->isImport == 1) {
54,673✔
2535
    memset(userObj.salt, 0, sizeof(userObj.salt));
×
2536
    memcpy(userObj.passwords[0].pass, pCreate->pass, TSDB_PASSWORD_LEN);
×
2537
  } else {
2538
    generateSalt(userObj.salt, sizeof(userObj.salt));
54,673✔
2539
    taosEncryptPass_c((uint8_t *)pCreate->pass, strlen(pCreate->pass), userObj.passwords[0].pass);
54,673✔
2540
    userObj.passwords[0].pass[sizeof(userObj.passwords[0].pass) - 1] = 0;
54,673✔
2541
    TAOS_CHECK_GOTO(mndEncryptPass(userObj.passwords[0].pass, userObj.salt, &userObj.passEncryptAlgorithm), &lino, _OVER);
54,673✔
2542
  }
2543
  userObj.passwords[0].setTime = taosGetTimestampSec();
54,673✔
2544

2545
  tstrncpy(userObj.user, pCreate->user, TSDB_USER_LEN);
54,673✔
2546
  tstrncpy(userObj.acct, acct, TSDB_USER_LEN);
54,673✔
2547
  if (pCreate->totpseed[0] != 0) {
54,673✔
2548
    int len = taosGenerateTotpSecret(pCreate->totpseed, 0, userObj.totpsecret, sizeof(userObj.totpsecret));
×
2549
    if (len < 0) {
×
2550
      TAOS_CHECK_GOTO(TSDB_CODE_PAR_INVALID_OPTION_VALUE, &lino, _OVER);
×
2551
    }
2552
  }
2553

2554
  userObj.createdTime = taosGetTimestampMs();
54,673✔
2555
  userObj.updateTime = userObj.createdTime;
54,673✔
2556
  userObj.superUser = 0;  // pCreate->superUser;
54,673✔
2557
  userObj.sysInfo = pCreate->sysInfo;
54,673✔
2558
  userObj.enable = pCreate->enable;
54,673✔
2559
  userObj.createdb = pCreate->createDb;
54,673✔
2560
  userObj.uid = mndGenerateUid(userObj.user, strlen(userObj.user));
54,673✔
2561

2562
#ifdef TD_ENTERPRISE
2563

2564
  userObj.changePass = pCreate->changepass;
54,673✔
2565
  userObj.sessionPerUser = pCreate->sessionPerUser;
54,673✔
2566
  userObj.connectTime = pCreate->connectTime;
54,673✔
2567
  userObj.connectIdleTime = pCreate->connectIdleTime;
54,673✔
2568
  userObj.callPerSession = pCreate->callPerSession;
54,673✔
2569
  userObj.vnodePerCall = pCreate->vnodePerCall;
54,673✔
2570
  userObj.failedLoginAttempts = pCreate->failedLoginAttempts;
54,673✔
2571
  userObj.passwordLifeTime = pCreate->passwordLifeTime;
54,673✔
2572
  userObj.passwordReuseTime = pCreate->passwordReuseTime;
54,673✔
2573
  userObj.passwordReuseMax = pCreate->passwordReuseMax;
54,673✔
2574
  userObj.passwordLockTime = pCreate->passwordLockTime;
54,673✔
2575
  userObj.passwordGraceTime = pCreate->passwordGraceTime;
54,673✔
2576
  userObj.inactiveAccountTime = pCreate->inactiveAccountTime;
54,673✔
2577
  userObj.allowTokenNum = pCreate->allowTokenNum;
54,673✔
2578
  userObj.tokenNum = 0;
54,673✔
2579

2580
  if (pCreate->numIpRanges == 0) {
54,673✔
2581
    TAOS_CHECK_GOTO(createDefaultIpWhiteList(&userObj.pIpWhiteListDual), &lino, _OVER);
53,566✔
2582
  } else {
2583
    SHashObj *pUniqueTab = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
1,107✔
2584
    if (pUniqueTab == NULL) {
1,107✔
2585
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2586
    }
2587
    
2588
    for (int i = 0; i < pCreate->numIpRanges; i++) {
2,652✔
2589
      SIpRange range = {0};
1,545✔
2590
      copyIpRange(&range, pCreate->pIpDualRanges + i);
1,545✔
2591
      int32_t dummy = 0;
1,545✔
2592
      if ((code = taosHashPut(pUniqueTab, &range, sizeof(range), &dummy, sizeof(dummy))) != 0) {
1,545✔
2593
        taosHashCleanup(pUniqueTab);
×
2594
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2595
      }
2596
    }
2597

2598
    code = addDefaultIpToTable(tsEnableIpv6, pUniqueTab);
1,107✔
2599
    if (code != 0) {
1,107✔
2600
      taosHashCleanup(pUniqueTab);
×
2601
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2602
    }
2603

2604
    if (taosHashGetSize(pUniqueTab) > MND_MAX_USER_IP_RANGE) {
1,107✔
2605
      taosHashCleanup(pUniqueTab);
×
2606
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_IP_RANGE, &lino, _OVER);
×
2607
    }
2608

2609
    int32_t           numOfRanges = taosHashGetSize(pUniqueTab);
1,107✔
2610
    SIpWhiteListDual *p = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + numOfRanges * sizeof(SIpRange));
1,107✔
2611
    if (p == NULL) {
1,107✔
2612
      taosHashCleanup(pUniqueTab);
×
2613
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2614
    }
2615

2616
    void   *pIter = taosHashIterate(pUniqueTab, NULL);
1,107✔
2617
    for (int32_t i = 0; i < numOfRanges; i++) {
3,447✔
2618
      size_t    len = 0;
2,340✔
2619
      SIpRange *key = taosHashGetKey(pIter, &len);
2,340✔
2620
      memcpy(&p->pIpRanges[i], key, sizeof(SIpRange));
2,340✔
2621
      pIter = taosHashIterate(pUniqueTab, pIter);
2,340✔
2622
    }
2623

2624
    taosHashCleanup(pUniqueTab);
1,107✔
2625
    p->num = numOfRanges;
1,107✔
2626
    sortIpWhiteList(p);
1,107✔
2627
    userObj.pIpWhiteListDual = p;
1,107✔
2628
  }
2629

2630
  if (pCreate->numTimeRanges == 0) {
54,673✔
2631
    userObj.pTimeWhiteList = (SDateTimeWhiteList*)taosMemoryCalloc(1, sizeof(SDateTimeWhiteList));
53,649✔
2632
    if (userObj.pTimeWhiteList == NULL) {
53,649✔
2633
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2634
    }
2635
  } else {
2636
    SHashObj *pUniqueTab = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
1,024✔
2637
    if (pUniqueTab == NULL) {
1,024✔
2638
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2639
    }
2640
    
2641
    for (int i = 0; i < pCreate->numTimeRanges; i++) {
2,048✔
2642
      SDateTimeRange* src = pCreate->pTimeRanges + i;
1,024✔
2643
      SDateTimeWhiteListItem range = {0};
1,024✔
2644
      DateTimeRangeToWhiteListItem(&range, src);
1,024✔
2645

2646
      // no need to add expired range
2647
      if (isDateTimeWhiteListItemExpired(&range)) {
1,024✔
2648
        continue;
256✔
2649
      }
2650

2651
      int32_t dummy = 0;
768✔
2652
      if ((code = taosHashPut(pUniqueTab, &range, sizeof(range), &dummy, sizeof(dummy))) != 0) {
768✔
2653
        taosHashCleanup(pUniqueTab);
×
2654
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2655
      }
2656
    }
2657

2658
    if (taosHashGetSize(pUniqueTab) > MND_MAX_USER_TIME_RANGE) {
1,024✔
2659
      taosHashCleanup(pUniqueTab);
×
2660
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_TIME_RANGE, &lino, _OVER);
×
2661
    }
2662

2663
    int32_t           numOfRanges = taosHashGetSize(pUniqueTab);
1,024✔
2664
    SDateTimeWhiteList *p = taosMemoryCalloc(1, sizeof(SDateTimeWhiteList) + numOfRanges * sizeof(SDateTimeWhiteListItem));
1,024✔
2665
    if (p == NULL) {
1,024✔
2666
      taosHashCleanup(pUniqueTab);
×
2667
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2668
    }
2669

2670
    void   *pIter = taosHashIterate(pUniqueTab, NULL);
1,024✔
2671
    for (int32_t i = 0; i < numOfRanges; i++) {
1,792✔
2672
      size_t    len = 0;
768✔
2673
      SDateTimeWhiteListItem *key = taosHashGetKey(pIter, &len);
768✔
2674
      memcpy(p->ranges + i, key, sizeof(SDateTimeWhiteListItem));
768✔
2675
      pIter = taosHashIterate(pUniqueTab, pIter);
768✔
2676
    }
2677

2678
    taosHashCleanup(pUniqueTab);
1,024✔
2679
    p->num = numOfRanges;
1,024✔
2680
    sortTimeWhiteList(p);
1,024✔
2681
    userObj.pTimeWhiteList = p;
1,024✔
2682
  }
2683

2684
  userObj.ipWhiteListVer = taosGetTimestampMs();
54,673✔
2685
  userObj.timeWhiteListVer = userObj.ipWhiteListVer;
54,673✔
2686

2687
#else // TD_ENTERPRISE
2688

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

2705
  TAOS_CHECK_GOTO(createDefaultIpWhiteList(&userObj.pIpWhiteListDual), &lino, _OVER);
2706
  userObj.pTimeWhiteList = (SDateTimeWhiteList*)taosMemoryCalloc(1, sizeof(SDateTimeWhiteList));
2707
  if (userObj.pTimeWhiteList == NULL) {
2708
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
2709
  }
2710

2711
  userObj.ipWhiteListVer = 0;
2712
  userObj.timeWhiteListVer = 0;
2713

2714
#endif // TD_ENTERPRISE
2715

2716
  userObj.roles = taosHashInit(1, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
54,673✔
2717
  if (userObj.roles == NULL) {
54,673✔
2718
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2719
  }
2720

2721
  if ((code = taosHashPut(userObj.roles, TSDB_ROLE_SYSINFO_1, strlen(TSDB_ROLE_SYSINFO_1) + 1, NULL, 0)) != 0) {
54,673✔
2722
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2723
  }
2724

2725
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "create-user");
54,673✔
2726
  if (pTrans == NULL) {
54,673✔
2727
    mError("user:%s, failed to create since %s", pCreate->user, terrstr());
×
2728
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2729
  }
2730
  mInfo("trans:%d, used to create user:%s", pTrans->id, pCreate->user);
54,673✔
2731

2732
  SSdbRaw *pCommitRaw = mndUserActionEncode(&userObj);
54,673✔
2733
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
54,673✔
2734
    mError("trans:%d, failed to commit redo log since %s", pTrans->id, terrstr());
×
2735
    mndTransDrop(pTrans);
×
2736
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2737
  }
2738
  TAOS_CHECK_GOTO(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY), &lino, _OVER);
54,673✔
2739

2740
  if (mndTransPrepare(pMnode, pTrans) != 0) {
54,673✔
2741
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
2742
    mndTransDrop(pTrans);
×
2743
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2744
  }
2745

2746
  if ((code = userCacheUpdateWhiteList(pMnode, &userObj)) != 0) {
54,673✔
2747
    mndTransDrop(pTrans);
×
2748
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2749
  }
2750

2751
  mndTransDrop(pTrans);
54,673✔
2752

2753
_OVER:
54,673✔
2754
  mndUserFreeObj(&userObj);
54,673✔
2755
  TAOS_RETURN(code);
54,673✔
2756
}
2757

2758

2759
static int32_t mndCheckPasswordFmt(const char *pwd) {
73,255✔
2760
  if (tsEnableStrongPassword == 0) {
73,255✔
2761
    for (char c = *pwd; c != 0; c = *(++pwd)) {
43,018✔
2762
      if (c == ' ' || c == '\'' || c == '\"' || c == '`' || c == '\\') {
42,547✔
2763
        return TSDB_CODE_MND_INVALID_PASS_FORMAT;
×
2764
      }
2765
    }
2766
    return 0;
471✔
2767
  }
2768

2769
  int32_t len = strlen(pwd);
72,784✔
2770
  if (len < TSDB_PASSWORD_MIN_LEN) {
72,784✔
2771
    return TSDB_CODE_PAR_PASSWD_TOO_SHORT_OR_EMPTY;
×
2772
  }
2773

2774
  if (len > TSDB_PASSWORD_MAX_LEN) {
72,784✔
2775
    return TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG;
×
2776
  }
2777

2778
  if (taosIsComplexString(pwd)) {
72,784✔
2779
    return 0;
72,784✔
2780
  }
2781

2782
  return TSDB_CODE_MND_INVALID_PASS_FORMAT;
×
2783
}
2784

2785

2786

2787
static int32_t mndCheckTotpSeedFmt(const char *seed) {
×
2788
  int32_t len = strlen(seed);
×
2789
  if (len < TSDB_USER_TOTPSEED_MIN_LEN) {
×
2790
    return TSDB_CODE_PAR_OPTION_VALUE_TOO_SHORT;
×
2791
  }
2792

2793
  if (taosIsComplexString(seed)) {
×
2794
    return 0;
×
2795
  }
2796

2797
  return TSDB_CODE_PAR_INVALID_OPTION_VALUE;
×
2798
}
2799

2800

2801

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

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

2817
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, wlReq.user, &pUser), &lino, _OVER);
×
2818
  TAOS_CHECK_GOTO(mndSetUserDateTimeWhiteListRsp(pMnode, pUser, &wlRsp), &lino, _OVER);
×
2819

2820
  contLen = tSerializeSUserDateTimeWhiteList(NULL, 0, &wlRsp);
×
2821
  if (contLen < 0) {
×
2822
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2823
  }
2824
  pRsp = rpcMallocCont(contLen);
×
2825
  if (pRsp == NULL) {
×
2826
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2827
  }
2828
  
2829
  contLen = tSerializeSUserDateTimeWhiteList(pRsp, contLen, &wlRsp);
×
2830
  if (contLen < 0) {
×
2831
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2832
  }
2833

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

2847
  TAOS_RETURN(code);
×
2848
  return 0;
2849
}
2850

2851

2852

2853
static int32_t buildRetrieveDateTimeWhiteListRsp(SRetrieveDateTimeWhiteListRsp *pRsp) {
431✔
2854
  (void)taosThreadRwlockRdlock(&userCache.rw);
431✔
2855
  
2856
  int32_t count = taosHashGetSize(userCache.users);
431✔
2857
  pRsp->pUsers = taosMemoryCalloc(count, sizeof(SUserDateTimeWhiteList));
431✔
2858
  if (pRsp->pUsers == NULL) {
431✔
2859
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
2860
    TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
2861
  }
2862

2863
  count = 0;
431✔
2864
  void   *pIter = taosHashIterate(userCache.users, NULL);
431✔
2865
  while (pIter) {
862✔
2866
    SDateTimeWhiteList *wl = (*(SCachedUserInfo **)pIter)->wlTime;
431✔
2867
    if (wl == NULL || wl->num <= 0) {
431✔
2868
      pIter = taosHashIterate(userCache.users, pIter);
431✔
2869
      continue;
431✔
2870
    }
2871

2872
    SUserDateTimeWhiteList *pUser = &pRsp->pUsers[count];
×
2873
    pUser->ver = userCache.verTime;
×
2874

2875
    size_t klen;
×
2876
    char  *key = taosHashGetKey(pIter, &klen);
×
2877
    (void)memcpy(pUser->user, key, klen);
×
2878

2879
    pUser->numWhiteLists = wl->num;
×
2880
    pUser->pWhiteLists = taosMemoryCalloc(wl->num, sizeof(SDateTimeWhiteListItem));
×
2881
    if (pUser->pWhiteLists == NULL) {
×
2882
      (void)taosThreadRwlockUnlock(&userCache.rw);
×
2883
      TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
2884
    }
2885

2886
    (void)memcpy(pUser->pWhiteLists, wl->ranges, wl->num * sizeof(SDateTimeWhiteListItem));
×
2887
    count++;
×
2888
    pIter = taosHashIterate(userCache.users, pIter);
×
2889
  }
2890

2891
  pRsp->numOfUser = count;
431✔
2892
  pRsp->ver = userCache.verTime;
431✔
2893
  (void)taosThreadRwlockUnlock(&userCache.rw);
431✔
2894
  TAOS_RETURN(0);
431✔
2895
}
2896

2897

2898

2899
static int32_t mndProcessRetrieveDateTimeWhiteListReq(SRpcMsg *pReq) {
431✔
2900
  int32_t        code = 0;
431✔
2901
  int32_t        lino = 0;
431✔
2902
  int32_t        len = 0;
431✔
2903
  void          *pRsp = NULL;
431✔
2904
  SRetrieveDateTimeWhiteListRsp wlRsp = {0};
431✔
2905

2906
  // impl later
2907
  SRetrieveWhiteListReq req = {0};
431✔
2908
  if (tDeserializeRetrieveWhiteListReq(pReq->pCont, pReq->contLen, &req) != 0) {
431✔
2909
    code = TSDB_CODE_INVALID_MSG;
×
2910
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2911
  }
2912

2913
  TAOS_CHECK_GOTO(buildRetrieveDateTimeWhiteListRsp(&wlRsp), &lino, _OVER);
431✔
2914

2915
  len = tSerializeSRetrieveDateTimeWhiteListRsp(NULL, 0, &wlRsp);
431✔
2916
  if (len < 0) {
431✔
2917
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
2918
  }
2919

2920
  pRsp = rpcMallocCont(len);
431✔
2921
  if (!pRsp) {
431✔
2922
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2923
  }
2924
  len = tSerializeSRetrieveDateTimeWhiteListRsp(pRsp, len, &wlRsp);
431✔
2925
  if (len < 0) {
431✔
2926
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
2927
  }
2928

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

2940
  tFreeSRetrieveDateTimeWhiteListRsp(&wlRsp);
431✔
2941
  TAOS_RETURN(code);
431✔
2942
}
2943

2944

2945

2946
static int32_t mndProcessCreateUserReq(SRpcMsg *pReq) {
54,673✔
2947
  SMnode        *pMnode = pReq->info.node;
54,673✔
2948
  int32_t        code = 0;
54,673✔
2949
  int32_t        lino = 0;
54,673✔
2950
  SRoleObj      *pRole = NULL;
54,673✔
2951
  SUserObj      *pUser = NULL;
54,673✔
2952
  SUserObj      *pOperUser = NULL;
54,673✔
2953
  SCreateUserReq createReq = {0};
54,673✔
2954
  int64_t        tss = taosGetTimestampMs();
54,673✔
2955

2956
  if (tDeserializeSCreateUserReq(pReq->pCont, pReq->contLen, &createReq) != 0) {
54,673✔
2957
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
2958
  }
2959

2960
  mInfo("user:%s, start to create, createdb:%d, is_import:%d", createReq.user, createReq.createDb, createReq.isImport);
54,673✔
2961

2962
#ifndef TD_ENTERPRISE
2963
  if (createReq.isImport == 1) {
2964
    TAOS_CHECK_GOTO(TSDB_CODE_OPS_NOT_SUPPORT, &lino, _OVER);  // enterprise feature
2965
  }
2966
#endif
2967
  code = mndAcquireUser(pMnode, RPC_MSG_USER(pReq), &pOperUser);
54,673✔
2968
  if (pOperUser == NULL) {
54,673✔
2969
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_USER_FROM_CONN, &lino, _OVER);
×
2970
  }
2971

2972
  if (createReq.isImport != 1) {
54,673✔
2973
    // TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, RPC_MSG_USER(pReq), MND_OPER_CREATE_USER), &lino, _OVER);
2974
    TAOS_CHECK_GOTO(mndCheckSysObjPrivilege(pMnode, pOperUser, PRIV_USER_CREATE, 0, 0, NULL, NULL), &lino, _OVER);
54,673✔
2975
  } else if (strcmp(RPC_MSG_USER(pReq), "root") != 0) {
×
2976
    mError("The operation is not permitted to create user:%s", RPC_MSG_USER(pReq));
×
2977
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_RIGHTS, &lino, _OVER);
×
2978
  }
2979

2980
  if (createReq.user[0] == 0) {
54,673✔
2981
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
2982
  }
2983

2984
  if (createReq.isImport != 1) {
54,673✔
2985
    code = mndCheckPasswordFmt(createReq.pass);
54,673✔
2986
    TAOS_CHECK_GOTO(code, &lino, _OVER);
54,673✔
2987
  }
2988

2989
  if (createReq.totpseed[0] != 0) {
54,673✔
2990
    code = mndCheckTotpSeedFmt(createReq.totpseed);
×
2991
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2992
  }
2993

2994
  code = mndAcquireUser(pMnode, createReq.user, &pUser);
54,673✔
2995
  if (pUser != NULL) {
54,673✔
2996
    TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_ALREADY_EXIST, &lino, _OVER);
×
2997
  }
2998

2999
  code = mndAcquireRole(pMnode, createReq.user, &pRole);
54,673✔
3000
  if (pRole != NULL) {
54,673✔
3001
    TAOS_CHECK_GOTO(TSDB_CODE_MND_ROLE_ALREADY_EXIST, &lino, _OVER);
×
3002
  }
3003

3004
  TAOS_CHECK_GOTO(grantCheck(TSDB_GRANT_USER), &lino, _OVER);
54,673✔
3005

3006
  code = mndCreateUser(pMnode, pOperUser->acct, &createReq, pReq);
54,673✔
3007
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
54,673✔
3008

3009
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
54,673✔
3010
    char detail[1000] = {0};
54,673✔
3011
    (void)tsnprintf(detail, sizeof(detail), "enable:%d, superUser:%d, sysInfo:%d, password:xxx", createReq.enable,
54,673✔
3012
                    createReq.superUser, createReq.sysInfo);
54,673✔
3013
    char operation[15] = {0};
54,673✔
3014
    if (createReq.isImport == 1) {
54,673✔
3015
      tstrncpy(operation, "importUser", sizeof(operation));
×
3016
    } else {
3017
      tstrncpy(operation, "createUser", sizeof(operation));
54,673✔
3018
    }
3019

3020
    int64_t tse = taosGetTimestampMs();
54,673✔
3021
    double  duration = (double)(tse - tss);
54,673✔
3022
    duration = duration / 1000;
54,673✔
3023
    auditRecord(pReq, pMnode->clusterId, operation, "", createReq.user, detail, strlen(detail), duration, 0);
54,673✔
3024
  }
3025

3026
_OVER:
54,673✔
3027
  if (code == TSDB_CODE_MND_USER_ALREADY_EXIST && createReq.ignoreExists) {
54,673✔
3028
    code = 0;
×
3029
  } else if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
54,673✔
3030
    mError("user:%s, failed to create at line %d since %s", createReq.user, lino, tstrerror(code));
×
3031
  }
3032

3033
  mndReleaseRole(pMnode, pRole);
54,673✔
3034
  mndReleaseUser(pMnode, pUser);
54,673✔
3035
  mndReleaseUser(pMnode, pOperUser);
54,673✔
3036
  tFreeSCreateUserReq(&createReq);
54,673✔
3037

3038
  TAOS_RETURN(code);
54,673✔
3039
}
3040

3041

3042

3043
static int32_t mndProcessGetUserIpWhiteListReq(SRpcMsg *pReq) {
9,522✔
3044
  SMnode              *pMnode = pReq->info.node;
9,522✔
3045
  int32_t              code = 0;
9,522✔
3046
  int32_t              lino = 0;
9,522✔
3047
  int32_t              contLen = 0;
9,522✔
3048
  void                *pRsp = NULL;
9,522✔
3049
  SUserObj            *pUser = NULL;
9,522✔
3050
  SGetUserWhiteListReq wlReq = {0};
9,522✔
3051
  SGetUserIpWhiteListRsp wlRsp = {0};
9,522✔
3052

3053
  int32_t (*serialFn)(void *, int32_t, SGetUserIpWhiteListRsp *) = NULL;
9,522✔
3054
  int32_t (*setRspFn)(SMnode * pMnode, SUserObj * pUser, SGetUserIpWhiteListRsp * pRsp) = NULL;
9,522✔
3055

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

3068
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, wlReq.user, &pUser), &lino, _OVER);
9,522✔
3069
  TAOS_CHECK_GOTO(setRspFn(pMnode, pUser, &wlRsp), &lino, _OVER);
9,522✔
3070

3071
  contLen = serialFn(NULL, 0, &wlRsp);
9,522✔
3072
  if (contLen < 0) {
9,522✔
3073
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3074
  }
3075
  pRsp = rpcMallocCont(contLen);
9,522✔
3076
  if (pRsp == NULL) {
9,522✔
3077
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3078
  }
3079

3080
  contLen = serialFn(pRsp, contLen, &wlRsp);
9,522✔
3081
  if (contLen < 0) {
9,522✔
3082
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3083
  }
3084

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

3098
  TAOS_RETURN(code);
9,522✔
3099
}
3100

3101

3102

3103
static int32_t buildRetrieveIpWhiteListRsp(SUpdateIpWhite *pUpdate) {
431✔
3104
  (void)taosThreadRwlockRdlock(&userCache.rw);
431✔
3105

3106
  int32_t count = taosHashGetSize(userCache.users);
431✔
3107
  pUpdate->pUserIpWhite = taosMemoryCalloc(count, sizeof(SUpdateUserIpWhite));
431✔
3108
  if (pUpdate->pUserIpWhite == NULL) {
431✔
3109
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
3110
    TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
3111
  }
3112

3113
  count = 0;
431✔
3114
  void   *pIter = taosHashIterate(userCache.users, NULL);
431✔
3115
  while (pIter) {
862✔
3116
    SIpWhiteListDual   *wl = (*(SCachedUserInfo**)pIter)->wlIp;
431✔
3117
    if (wl == NULL || wl->num <= 0) {
431✔
3118
      pIter = taosHashIterate(userCache.users, pIter);
×
3119
      continue;
×
3120
    }
3121

3122
    SUpdateUserIpWhite *pUser = &pUpdate->pUserIpWhite[count];
431✔
3123
    pUser->ver = userCache.verIp;
431✔
3124

3125
    size_t klen;
431✔
3126
    char  *key = taosHashGetKey(pIter, &klen);
431✔
3127
    (void)memcpy(pUser->user, key, klen);
431✔
3128

3129
    pUser->numOfRange = wl->num;
431✔
3130
    pUser->pIpRanges = taosMemoryCalloc(wl->num, sizeof(SIpRange));
431✔
3131
    if (pUser->pIpRanges == NULL) {
431✔
3132
      (void)taosThreadRwlockUnlock(&userCache.rw);
×
3133
      TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
3134
    }
3135

3136
    (void)memcpy(pUser->pIpRanges, wl->pIpRanges, wl->num * sizeof(SIpRange));
431✔
3137
    count++;
431✔
3138
    pIter = taosHashIterate(userCache.users, pIter);
431✔
3139
  }
3140

3141
  pUpdate->numOfUser = count;
431✔
3142
  pUpdate->ver = userCache.verIp;
431✔
3143
  (void)taosThreadRwlockUnlock(&userCache.rw);
431✔
3144
  TAOS_RETURN(0);
431✔
3145
}
3146

3147

3148

3149
int32_t mndProcessRetrieveIpWhiteListReq(SRpcMsg *pReq) {
431✔
3150
  int32_t        code = 0;
431✔
3151
  int32_t        lino = 0;
431✔
3152
  int32_t        len = 0;
431✔
3153
  void          *pRsp = NULL;
431✔
3154
  SUpdateIpWhite ipWhite = {0};
431✔
3155

3156
  // impl later
3157
  SRetrieveWhiteListReq req = {0};
431✔
3158
  if (tDeserializeRetrieveWhiteListReq(pReq->pCont, pReq->contLen, &req) != 0) {
431✔
3159
    code = TSDB_CODE_INVALID_MSG;
×
3160
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3161
  }
3162

3163
  int32_t (*fn)(void *, int32_t, SUpdateIpWhite *) = NULL;
431✔
3164
  if (pReq->msgType == TDMT_MND_RETRIEVE_IP_WHITELIST) {
431✔
3165
    fn = tSerializeSUpdateIpWhite;
×
3166
  } else if (pReq->msgType == TDMT_MND_RETRIEVE_IP_WHITELIST_DUAL) {
431✔
3167
    fn = tSerializeSUpdateIpWhiteDual;
431✔
3168
  }
3169

3170
  TAOS_CHECK_GOTO(buildRetrieveIpWhiteListRsp(&ipWhite), &lino, _OVER);
431✔
3171

3172
  len = fn(NULL, 0, &ipWhite);
431✔
3173
  if (len < 0) {
431✔
3174
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
3175
  }
3176

3177
  pRsp = rpcMallocCont(len);
431✔
3178
  if (!pRsp) {
431✔
3179
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3180
  }
3181
  len = fn(pRsp, len, &ipWhite);
431✔
3182
  if (len < 0) {
431✔
3183
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
3184
  }
3185

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

3197
  tFreeSUpdateIpWhiteReq(&ipWhite);
431✔
3198
  TAOS_RETURN(code);
431✔
3199
}
3200

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

3210
  SSdbRaw *pCommitRaw = mndUserActionEncode(pNew);
979,897✔
3211
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
979,897✔
3212
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
3213
    mndTransDrop(pTrans);
×
3214
    TAOS_RETURN(terrno);
×
3215
  }
3216
  TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
979,897✔
3217

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

3235
static int32_t mndDupObjHash(SHashObj *pOld, int32_t dataLen, SHashObj **ppNew) {
×
3236
  int32_t code = 0;
×
3237

3238
  *ppNew =
×
3239
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
×
3240
  if (*ppNew == NULL) {
×
3241
    code = terrno ? terrno : TSDB_CODE_OUT_OF_MEMORY;
×
3242
    TAOS_RETURN(code);
×
3243
  }
3244

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

3256
  TAOS_RETURN(code);
×
3257
}
3258

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

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

3263
static int32_t mndTablePriviledge(SMnode *pMnode, SHashObj *hash, SHashObj *useDbHash, SAlterUserReq *alterReq,
×
3264
                                  SSdb *pSdb) {
3265
  void *pIter = NULL;
×
3266
  char  tbFName[TSDB_TABLE_FNAME_LEN] = {0};
×
3267

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

3271
  if (alterReq->tagCond != NULL && alterReq->tagCondLen != 0) {
×
3272
    char *value = taosHashGet(hash, tbFName, len);
×
3273
    if (value != NULL) {
×
3274
      TAOS_RETURN(TSDB_CODE_MND_PRIVILEGE_EXIST);
×
3275
    }
3276

3277
    int32_t condLen = alterReq->tagCondLen;
×
3278
    TAOS_CHECK_RETURN(taosHashPut(hash, tbFName, len, alterReq->tagCond, condLen));
×
3279
  } else {
3280
    TAOS_CHECK_RETURN(taosHashPut(hash, tbFName, len, alterReq->isView ? "v" : "t", 2));
×
3281
  }
3282

3283
  int32_t  dbKeyLen = strlen(alterReq->objname) + 1;
×
3284
  int32_t  ref = 1;
×
3285
  int32_t *currRef = taosHashGet(useDbHash, alterReq->objname, dbKeyLen);
×
3286
  if (NULL != currRef) {
×
3287
    ref = (*currRef) + 1;
×
3288
  }
3289
  TAOS_CHECK_RETURN(taosHashPut(useDbHash, alterReq->objname, dbKeyLen, &ref, sizeof(ref)));
×
3290

3291
  TAOS_RETURN(0);
×
3292
}
3293

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

3301
  if (taosHashRemove(hash, tbFName, len) != 0) {
×
3302
    TAOS_RETURN(0);  // not found
×
3303
  }
3304

3305
  int32_t  dbKeyLen = strlen(alterReq->objname) + 1;
×
3306
  int32_t *currRef = taosHashGet(useDbHash, alterReq->objname, dbKeyLen);
×
3307
  if (NULL == currRef) {
×
3308
    return 0;
×
3309
  }
3310

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

3320
  return 0;
×
3321
}
3322

3323

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

3333
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, pAlterReq->user, &pUser), &lino, _OVER);
3334
  TAOS_CHECK_GOTO(mndCheckAlterUserPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser, pAlterReq), &lino, _OVER);
3335
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
3336

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

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

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

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

3440
  SHashObj *pReadTbs = newUser.readTbs;
3441
  SHashObj *pWriteTbs = newUser.writeTbs;
3442
  SHashObj *pAlterTbs = newUser.alterTbs;
3443

3444
#ifdef TD_ENTERPRISE
3445
  if (pAlterReq->isView) {
3446
    pReadTbs = newUser.readViews;
3447
    pWriteTbs = newUser.writeViews;
3448
    pAlterTbs = newUser.alterViews;
3449
  }
3450
#endif
3451

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

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

3462
  if (ALTER_USER_ADD_ALTER_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3463
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3464
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pAlterTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3465
  }
3466

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

3472
  if (ALTER_USER_DEL_WRITE_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3473
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3474
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pWriteTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3475
  }
3476

3477
  if (ALTER_USER_DEL_ALTER_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
3478
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
3479
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pAlterTbs, newUser.useDbs, pAlterReq, pSdb), &lino, _OVER);
3480
  }
3481
#endif
3482

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

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

3514
  TAOS_CHECK_GOTO(mndAlterUser(pMnode, &newUser, pReq), &lino, _OVER);
3515
  code = TSDB_CODE_ACTION_IN_PROGRESS;
3516

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

3559
#ifdef TD_ENTERPRISE
3560
extern int32_t mndAlterUserPrivInfo(SMnode *pMnode, SUserObj *pOperUser, SUserObj *pOld, SUserObj *pNew, SAlterRoleReq *pAlterReq);
3561
extern int32_t mndAlterUserRoleInfo(SMnode *pMnode, SUserObj *pOperUser, SUserObj *pOld, SUserObj *pNew, SAlterRoleReq *pAlterReq);
3562
#endif
3563

3564
int32_t mndAlterUserFromRole(SRpcMsg *pReq, SUserObj *pOperUser, SAlterRoleReq *pAlterReq) {
955,190✔
3565
  SMnode   *pMnode = pReq->info.node;
955,190✔
3566
  SSdb     *pSdb = pMnode->pSdb;
955,190✔
3567
  void     *pIter = NULL;
955,190✔
3568
  int32_t   code = 0, lino = 0;
955,190✔
3569
  SUserObj *pUser = NULL;
955,190✔
3570
  SUserObj  newUser = {0};
955,190✔
3571

3572
  TAOS_CHECK_EXIT(mndAcquireUser(pMnode, pAlterReq->principal, &pUser));
955,190✔
3573

3574
  if (pUser->enable == 0) {
954,256✔
3575
    TAOS_CHECK_EXIT(TSDB_CODE_MND_USER_DISABLED);
×
3576
  }
3577

3578
  if (pAlterReq->alterType == TSDB_ALTER_ROLE_PRIVILEGES) {
954,256✔
3579
#ifdef TD_ENTERPRISE
3580
    TAOS_CHECK_EXIT(mndUserDupObj(pUser, &newUser));
950,918✔
3581
    if ((code = mndAlterUserPrivInfo(pMnode, pOperUser, pUser, &newUser, pAlterReq)) == TSDB_CODE_QRY_DUPLICATED_OPERATION) {
950,918✔
3582
      code = 0;
×
3583
      goto _exit;
×
3584
    } else {
3585
      TAOS_CHECK_EXIT(code);
950,918✔
3586
    }
3587
  } else if (pAlterReq->alterType == TSDB_ALTER_ROLE_ROLE) {
3,338✔
3588
    if ((code = mndAlterUserRoleInfo(pMnode, pOperUser, pUser, &newUser, pAlterReq)) == TSDB_CODE_QRY_DUPLICATED_OPERATION) {
3,338✔
3589
      code = 0;
146✔
3590
      goto _exit;
146✔
3591
    } else {
3592
      TAOS_CHECK_EXIT(code);
3,192✔
3593
    }
3594
#endif
3595
  } else {
3596
    TAOS_CHECK_EXIT(TSDB_CODE_INVALID_MSG);
×
3597
  }
3598
  code = mndAlterUser(pMnode, &newUser, pReq);
953,672✔
3599
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
953,672✔
3600

3601
_exit:
955,190✔
3602
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
955,190✔
3603
    mError("user:%s, failed to alter user at line %d since %s", pAlterReq->principal, lino, tstrerror(code));
1,372✔
3604
  }
3605
  mndReleaseUser(pMnode, pUser);
955,190✔
3606
  mndUserFreeObj(&newUser);
955,190✔
3607
  TAOS_RETURN(code);
955,190✔
3608
}
3609

3610

3611
static int32_t mndProcessAlterUserBasicInfoReq(SRpcMsg *pReq, SAlterUserReq *pAlterReq) {
28,685✔
3612
  SMnode       *pMnode = pReq->info.node;
28,685✔
3613
  int32_t       code = 0, lino = 0;
28,685✔
3614
  SUserObj     *pUser = NULL;
28,685✔
3615
  SUserObj      newUser = {0};
28,685✔
3616
  char          auditLog[1000] = {0};
28,685✔
3617
  int32_t       auditLen = 0;
28,685✔
3618
  int64_t       tss = taosGetTimestampMs();
28,685✔
3619

3620
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, pAlterReq->user, &pUser), &lino, _OVER);
28,685✔
3621
  TAOS_CHECK_GOTO(mndCheckAlterUserPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser, pAlterReq), &lino, _OVER);
28,035✔
3622
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
26,327✔
3623

3624
  if (pAlterReq->hasPassword) {
26,327✔
3625
    auditLen += tsnprintf(auditLog, sizeof(auditLog), "password,");
18,582✔
3626

3627
    TAOS_CHECK_GOTO(mndCheckPasswordFmt(pAlterReq->pass), &lino, _OVER);
18,582✔
3628
    if (newUser.salt[0] == 0) {
18,582✔
3629
      generateSalt(newUser.salt, sizeof(newUser.salt));
160✔
3630
    }
3631
    char pass[TSDB_PASSWORD_LEN] = {0};
18,582✔
3632
    taosEncryptPass_c((uint8_t *)pAlterReq->pass, strlen(pAlterReq->pass), pass);
18,582✔
3633
    pass[sizeof(pass) - 1] = 0;
18,582✔
3634
    TAOS_CHECK_GOTO(mndEncryptPass(pass, newUser.salt, &newUser.passEncryptAlgorithm), &lino, _OVER);
18,582✔
3635

3636
    if (newUser.passwordReuseMax > 0 || newUser.passwordReuseTime > 0) {
18,582✔
3637
      for(int32_t i = 0; i < newUser.numOfPasswords; ++i) {
697,226✔
3638
        if (0 == strncmp(newUser.passwords[i].pass, pass, TSDB_PASSWORD_LEN)) {
680,603✔
3639
          TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_PASSWORD_REUSE, &lino, _OVER);
384✔
3640
        }
3641
      }
3642
      SUserPassword *passwords = taosMemoryCalloc(newUser.numOfPasswords + 1, sizeof(SUserPassword));
16,623✔
3643
      if (passwords == NULL) {
16,623✔
3644
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
3645
      }
3646
      memcpy(passwords + 1, newUser.passwords, newUser.numOfPasswords * sizeof(SUserPassword));
16,623✔
3647
      memcpy(passwords[0].pass, pass, TSDB_PASSWORD_LEN);
16,623✔
3648
      passwords[0].setTime = taosGetTimestampSec();
16,623✔
3649
      taosMemoryFree(newUser.passwords);
16,623✔
3650
      newUser.passwords = passwords;
16,623✔
3651
      ++newUser.numOfPasswords;
16,623✔
3652
      ++newUser.passVersion;
16,623✔
3653
      newUser.changePass = 2;
16,623✔
3654
    } else if (0 != strncmp(newUser.passwords[0].pass, pass, TSDB_PASSWORD_LEN)) {
1,575✔
3655
      memcpy(newUser.passwords[0].pass, pass, TSDB_PASSWORD_LEN);
1,396✔
3656
      newUser.passwords[0].setTime = taosGetTimestampSec();
1,396✔
3657
      ++newUser.passVersion;
1,396✔
3658
      newUser.changePass = 2;
1,396✔
3659
    }
3660
  }
3661

3662
  if (pAlterReq->hasTotpseed) {
25,943✔
3663
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "totpseed,");
×
3664

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

3672
  if (pAlterReq->hasEnable) {
25,943✔
3673
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "enable:%d,", pAlterReq->enable);
918✔
3674

3675
    newUser.enable = pAlterReq->enable; // lock or unlock user manually
918✔
3676
    if (newUser.enable) {
918✔
3677
      // reset login info to allow login immediately
3678
      userCacheResetLoginInfo(newUser.user);
758✔
3679
    }
3680
  }
3681

3682
  if (pAlterReq->hasSysinfo) {
25,943✔
3683
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "sysinfo:%d,", pAlterReq->sysinfo);
3,509✔
3684
    newUser.sysInfo = pAlterReq->sysinfo;
3,509✔
3685
  }
3686

3687
  if (pAlterReq->hasCreatedb) {
25,943✔
3688
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "createdb:%d,", pAlterReq->createdb);
1,600✔
3689
    newUser.createdb = pAlterReq->createdb;
1,600✔
3690
  }
3691

3692
#ifdef TD_ENTERPRISE
3693
  if (pAlterReq->hasChangepass) {
25,943✔
3694
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "changepass:%d,", pAlterReq->changepass);
×
3695
    newUser.changePass = pAlterReq->changepass;
×
3696
  }
3697

3698
  if (pAlterReq->hasSessionPerUser) {
25,943✔
3699
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "sessionPerUser:%d,", pAlterReq->sessionPerUser);
256✔
3700
    newUser.sessionPerUser = pAlterReq->sessionPerUser;
256✔
3701
  }
3702

3703
  if (pAlterReq->hasConnectTime) {
25,943✔
3704
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "connectTime:%d,", pAlterReq->connectTime);
128✔
3705
    newUser.connectTime = pAlterReq->connectTime;
128✔
3706
  }
3707
  
3708
  if (pAlterReq->hasConnectIdleTime) {
25,943✔
3709
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "connectIdleTime:%d,", pAlterReq->connectIdleTime);
128✔
3710
    newUser.connectIdleTime = pAlterReq->connectIdleTime;
128✔
3711
  }
3712

3713
  if (pAlterReq->hasCallPerSession) {
25,943✔
3714
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "callPerSession:%d,", pAlterReq->callPerSession);
384✔
3715
    newUser.callPerSession = pAlterReq->callPerSession;
384✔
3716
  }
3717

3718
  if (pAlterReq->hasVnodePerCall) {
25,943✔
3719
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "vnodePerCall:%d,", pAlterReq->vnodePerCall);
256✔
3720
    newUser.vnodePerCall = pAlterReq->vnodePerCall;
256✔
3721
  }
3722

3723
  if (pAlterReq->hasFailedLoginAttempts) {
25,943✔
3724
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "failedLoginAttempts:%d,", pAlterReq->failedLoginAttempts);
384✔
3725
    newUser.failedLoginAttempts = pAlterReq->failedLoginAttempts;
384✔
3726
  }
3727

3728
  if (pAlterReq->hasPasswordLifeTime) {
25,943✔
3729
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordLifeTime:%d,", pAlterReq->passwordLifeTime);
128✔
3730
    newUser.passwordLifeTime = pAlterReq->passwordLifeTime;
128✔
3731
  }
3732

3733
  if (pAlterReq->hasPasswordReuseTime) {
25,943✔
3734
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordReuseTime:%d,", pAlterReq->passwordReuseTime);
384✔
3735
    newUser.passwordReuseTime = pAlterReq->passwordReuseTime;
384✔
3736
  }
3737

3738
  if (pAlterReq->hasPasswordReuseMax) {
25,943✔
3739
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordReuseMax:%d,", pAlterReq->passwordReuseMax);
384✔
3740
    newUser.passwordReuseMax = pAlterReq->passwordReuseMax;
384✔
3741
  }
3742

3743
  if (pAlterReq->hasPasswordLockTime) {
25,943✔
3744
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordLockTime:%d,", pAlterReq->passwordLockTime);
128✔
3745
    newUser.passwordLockTime = pAlterReq->passwordLockTime;
128✔
3746
  }
3747

3748
  if (pAlterReq->hasPasswordGraceTime) {
25,943✔
3749
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "passwordGraceTime:%d,", pAlterReq->passwordGraceTime);
128✔
3750
    newUser.passwordGraceTime = pAlterReq->passwordGraceTime;
128✔
3751
  }
3752

3753
  if (pAlterReq->hasInactiveAccountTime) {
25,943✔
3754
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "inactiveAccountTime:%d,", pAlterReq->inactiveAccountTime);
128✔
3755
    newUser.inactiveAccountTime = pAlterReq->inactiveAccountTime;
128✔
3756
  }
3757

3758
  if (pAlterReq->hasAllowTokenNum) {
25,943✔
3759
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "allowTokenNum:%d,", pAlterReq->allowTokenNum);
256✔
3760
    newUser.allowTokenNum = pAlterReq->allowTokenNum;
256✔
3761
  }
3762

3763
  if (pAlterReq->numDropIpRanges > 0 || pAlterReq->numIpRanges > 0) {
25,943✔
3764
    int32_t dummy = 0;
566✔
3765

3766
    // put previous ip whitelist into hash table
3767
    SHashObj *m = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
566✔
3768
    if (m == NULL) {
566✔
3769
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3770
    }
3771

3772
    for (int32_t i = 0; i < newUser.pIpWhiteListDual->num; i++) {
2,109✔
3773
      SIpRange range;
1,543✔
3774
      copyIpRange(&range, newUser.pIpWhiteListDual->pIpRanges + i);
1,543✔
3775
      code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
1,543✔
3776
      if (code != 0) {
1,543✔
3777
        taosHashCleanup(m);
×
3778
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3779
      }
3780
    }
3781

3782
    if (pAlterReq->numDropIpRanges > 0) {
566✔
3783
      auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "dropIpRanges:%d,", pAlterReq->numDropIpRanges);
283✔
3784

3785
      for (int32_t i = 0; i < pAlterReq->numDropIpRanges; i++) {
694✔
3786
        if (taosHashGetSize(m) == 0) {
411✔
3787
          break;
×
3788
        }
3789

3790
        SIpRange range;
411✔
3791
        copyIpRange(&range, pAlterReq->pDropIpRanges + i);
411✔
3792

3793
        // for white list, drop default ip ranges is allowed, otherwise, we can never
3794
        // convert white list to black list.
3795

3796
        code = taosHashRemove(m, &range, sizeof(range));
411✔
3797
        if (code == TSDB_CODE_NOT_FOUND) {
411✔
3798
          // treat not exist as success
3799
          code = 0;
155✔
3800
        }
3801
        if (code != 0) {
411✔
3802
          taosHashCleanup(m);
×
3803
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3804
        }
3805
      }
3806
    }
3807

3808
    if (pAlterReq->numIpRanges > 0) {
566✔
3809
      auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "addIpRanges:%d,", pAlterReq->numIpRanges);
283✔
3810
      for (int32_t i = 0; i < pAlterReq->numIpRanges; i++) {
694✔
3811
        SIpRange range;
411✔
3812
        copyIpRange(&range, pAlterReq->pIpRanges + i);
411✔
3813
        code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
411✔
3814
        if (code != 0) {
411✔
3815
          taosHashCleanup(m);
×
3816
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3817
        }
3818
      }
3819
    }
3820

3821
    int32_t numOfRanges = taosHashGetSize(m);
566✔
3822
    if (numOfRanges > MND_MAX_USER_IP_RANGE) {
566✔
3823
      taosHashCleanup(m);
×
3824
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_IP_RANGE, &lino, _OVER);
×
3825
    }
3826

3827
    SIpWhiteListDual *p = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + numOfRanges * sizeof(SIpRange));
566✔
3828
    if (p == NULL) {
566✔
3829
      taosHashCleanup(m);
×
3830
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3831
    }
3832

3833
    void *pIter = taosHashIterate(m, NULL);
566✔
3834
    int32_t i = 0;
566✔
3835
    while (pIter) {
2,264✔
3836
      size_t len = 0;
1,698✔
3837
      SIpRange *key = taosHashGetKey(pIter, &len);
1,698✔
3838
      memcpy(p->pIpRanges + i, key, sizeof(SIpRange));
1,698✔
3839
      pIter = taosHashIterate(m, pIter);
1,698✔
3840
      i++;
1,698✔
3841
    }
3842

3843
    taosHashCleanup(m);
566✔
3844
    p->num = numOfRanges;
566✔
3845
    taosMemoryFreeClear(newUser.pIpWhiteListDual);
566✔
3846
    sortIpWhiteList(p);
566✔
3847
    newUser.pIpWhiteListDual = p;
566✔
3848

3849
    newUser.ipWhiteListVer++;
566✔
3850
  }
3851

3852

3853
  if (pAlterReq->numTimeRanges > 0 || pAlterReq->numDropTimeRanges) {
25,943✔
3854
    int32_t dummy = 0;
256✔
3855

3856
    // put previous ip whitelist into hash table
3857
    SHashObj *m = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
256✔
3858
    if (m == NULL) {
256✔
3859
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3860
    }
3861

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

3874
    if (pAlterReq->numDropTimeRanges > 0) {
256✔
3875
      auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "dropTimeRanges:%d,", pAlterReq->numDropTimeRanges);
128✔
3876
      for (int32_t i = 0; i < pAlterReq->numDropTimeRanges; i++) {
384✔
3877
        if (taosHashGetSize(m) == 0) {
256✔
3878
          break;
×
3879
        }
3880
        SDateTimeWhiteListItem range = { 0 };
256✔
3881
        DateTimeRangeToWhiteListItem(&range, pAlterReq->pDropTimeRanges + i);
256✔
3882

3883
        code = taosHashRemove(m, &range, sizeof(range));
256✔
3884
        if (code == TSDB_CODE_NOT_FOUND) {
256✔
3885
          // treat not exist as success
3886
          code = 0;
×
3887
        }
3888
        if (code != 0) {
256✔
3889
          taosHashCleanup(m);
×
3890
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3891
        }
3892
      }
3893
    }
3894

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

3911
    int32_t numOfRanges = taosHashGetSize(m);
256✔
3912
    if (numOfRanges > MND_MAX_USER_TIME_RANGE) {
256✔
3913
      taosHashCleanup(m);
×
3914
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_TIME_RANGE, &lino, _OVER);
×
3915
    }
3916

3917
    SDateTimeWhiteList *p = taosMemoryCalloc(1, sizeof(SDateTimeWhiteList) + numOfRanges * sizeof(SDateTimeWhiteListItem));
256✔
3918
    if (p == NULL) {
256✔
3919
      taosHashCleanup(m);
×
3920
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3921
    }
3922

3923
    void *pIter = taosHashIterate(m, NULL);
256✔
3924
    int32_t i = 0;
256✔
3925
    while (pIter) {
512✔
3926
      size_t len = 0;
256✔
3927
      SDateTimeWhiteListItem *key = taosHashGetKey(pIter, &len);
256✔
3928
      memcpy(&p->ranges[i], key, sizeof(SDateTimeWhiteListItem));
256✔
3929
      pIter = taosHashIterate(m, pIter);
256✔
3930
      i++;
256✔
3931
    }
3932

3933
    taosHashCleanup(m);
256✔
3934
    p->num = numOfRanges;
256✔
3935
    taosMemoryFreeClear(newUser.pTimeWhiteList);
256✔
3936
    sortTimeWhiteList(p);
256✔
3937
    newUser.pTimeWhiteList = p;
256✔
3938
    newUser.timeWhiteListVer++;
256✔
3939
  }
3940
#endif // TD_ENTERPRISE
3941

3942
  TAOS_CHECK_GOTO(mndAlterUser(pMnode, &newUser, pReq), &lino, _OVER);
25,943✔
3943
  code = TSDB_CODE_ACTION_IN_PROGRESS;
25,943✔
3944

3945
  if (auditLen > 0) {
25,943✔
3946
    auditLog[--auditLen] = 0; // remove last ','
25,943✔
3947
  }
3948
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
25,943✔
3949
    int64_t tse = taosGetTimestampMs();
25,943✔
3950
    double  duration = (double)(tse - tss);
25,943✔
3951
    duration = duration / 1000;
25,943✔
3952
    auditRecord(pReq, pMnode->clusterId, "alterUser", "", pAlterReq->user, auditLog, auditLen, duration, 0);
25,943✔
3953
  }
3954

3955
_OVER:
28,685✔
3956
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
28,685✔
3957
    mError("user:%s, failed to alter at line %d since %s", pAlterReq->user, lino, tstrerror(code));
2,742✔
3958
  }
3959

3960
  mndReleaseUser(pMnode, pUser);
28,685✔
3961
  mndUserFreeObj(&newUser);
28,685✔
3962
  return code;
28,685✔
3963
}
3964

3965

3966

3967
static int32_t mndProcessAlterUserReq(SRpcMsg *pReq) {
28,685✔
3968
  SAlterUserReq alterReq = {0};
28,685✔
3969

3970
  int32_t code = tDeserializeSAlterUserReq(pReq->pCont, pReq->contLen, &alterReq);
28,685✔
3971
  if (code != 0) {
28,685✔
3972
    mError("failed to deserialize alter user request at line %d since %s", __LINE__, tstrerror(code));
×
3973
    TAOS_RETURN(code);
×
3974
  }
3975

3976
  if (alterReq.user[0] == 0) {
28,685✔
3977
    tFreeSAlterUserReq(&alterReq);
×
3978
    mError("failed to alter user at line %d since invalid user format", __LINE__);
×
3979
    TAOS_RETURN(TSDB_CODE_MND_INVALID_USER_FORMAT);
×
3980
  }
3981

3982
  mInfo("user:%s, start to alter", alterReq.user);
28,685✔
3983
  if (alterReq.alterType == TSDB_ALTER_USER_BASIC_INFO) {
28,685✔
3984
    code = mndProcessAlterUserBasicInfoReq(pReq, &alterReq);
28,685✔
3985
  } else {
3986
    // code = mndProcessAlterUserPrivilegesReq(pReq, &alterReq); // obsolete
3987
  }
3988

3989
  tFreeSAlterUserReq(&alterReq);
28,685✔
3990
  TAOS_RETURN(code);
28,685✔
3991
}
3992

3993
int32_t mndGetAuditUser(SMnode *pMnode, char* user){
42,665,616✔
3994
  (void)tsnprintf(user, TSDB_USER_LEN, "audit");
42,665,616✔
3995
  return 0;
42,665,616✔
3996
}
3997

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

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

4017
  if (mndDropTokensByUser(pMnode, pTrans, pUser->user) != 0) {
19,537✔
4018
    mndTransDrop(pTrans);
×
4019
    TAOS_RETURN(terrno);
×
4020
  }
4021

4022
  if (mndTransPrepare(pMnode, pTrans) != 0) {
19,537✔
4023
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
4024
    mndTransDrop(pTrans);
×
4025
    TAOS_RETURN(terrno);
×
4026
  }
4027

4028
  userCacheRemoveUser(pUser->user);
19,537✔
4029
  mndDropCachedTokensByUser(pUser->user);
19,537✔
4030

4031
  mndTransDrop(pTrans);
19,537✔
4032
  TAOS_RETURN(0);
19,537✔
4033
}
4034

4035
static int32_t mndProcessDropUserReq(SRpcMsg *pReq) {
20,121✔
4036
  SMnode      *pMnode = pReq->info.node;
20,121✔
4037
  int32_t      code = 0;
20,121✔
4038
  int32_t      lino = 0;
20,121✔
4039
  SUserObj    *pOperUser = NULL;
20,121✔
4040
  SUserObj    *pUser = NULL;
20,121✔
4041
  SDropUserReq dropReq = {0};
20,121✔
4042
  int64_t      tss = taosGetTimestampMs();
20,121✔
4043

4044
  TAOS_CHECK_GOTO(tDeserializeSDropUserReq(pReq->pCont, pReq->contLen, &dropReq), &lino, _OVER);
20,121✔
4045

4046
  mInfo("user:%s, start to drop", dropReq.user);
20,121✔
4047

4048
  if (dropReq.user[0] == 0) {
20,121✔
4049
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
4050
  }
4051

4052
  if (0 == strcmp(dropReq.user, TSDB_DEFAULT_USER)) {
20,121✔
4053
    return TSDB_CODE_MND_NO_RIGHTS;
×
4054
  }
4055

4056
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, dropReq.user, &pUser), &lino, _OVER);
20,121✔
4057

4058
  code = mndAcquireUser(pMnode, RPC_MSG_USER(pReq), &pOperUser);
19,537✔
4059
  if (pOperUser == NULL) {
19,537✔
4060
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_USER_FROM_CONN, &lino, _OVER);
×
4061
  }
4062

4063
  // TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, RPC_MSG_USER(pReq), MND_OPER_DROP_USER), &lino, _OVER);
4064
  TAOS_CHECK_GOTO(mndCheckSysObjPrivilege(pMnode, pOperUser, PRIV_USER_DROP, 0, 0, NULL, NULL), &lino, _OVER);
19,537✔
4065

4066
  TAOS_CHECK_GOTO(mndDropUser(pMnode, pReq, pUser), &lino, _OVER);
19,537✔
4067
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
19,537✔
4068

4069
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
19,537✔
4070
    int64_t tse = taosGetTimestampMs();
19,537✔
4071
    double  duration = (double)(tse - tss);
19,537✔
4072
    duration = duration / 1000;
19,537✔
4073
    auditRecord(pReq, pMnode->clusterId, "dropUser", "", dropReq.user, dropReq.sql, dropReq.sqlLen, duration, 0);
19,537✔
4074
  }
4075

4076
_OVER:
20,121✔
4077
  if (dropReq.ignoreNotExists && code == TSDB_CODE_MND_USER_NOT_EXIST) {
20,121✔
4078
    code = 0;
456✔
4079
  } else if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
19,665✔
4080
    mError("user:%s, failed to drop at line %d since %s", dropReq.user, lino, tstrerror(code));
128✔
4081
  }
4082

4083
  mndReleaseUser(pMnode, pUser);
20,121✔
4084
  mndReleaseUser(pMnode, pOperUser);
20,121✔
4085
  tFreeSDropUserReq(&dropReq);
20,121✔
4086
  TAOS_RETURN(code);
20,121✔
4087
}
4088

4089
static int32_t mndProcessGetUserAuthReq(SRpcMsg *pReq) {
5,594,611✔
4090
  SMnode         *pMnode = pReq->info.node;
5,594,611✔
4091
  int32_t         code = 0;
5,594,611✔
4092
  int32_t         lino = 0;
5,594,611✔
4093
  int32_t         contLen = 0;
5,594,611✔
4094
  void           *pRsp = NULL;
5,594,611✔
4095
  SUserObj       *pUser = NULL;
5,594,611✔
4096
  SGetUserAuthReq authReq = {0};
5,594,611✔
4097
  SGetUserAuthRsp authRsp = {0};
5,594,611✔
4098

4099
  TAOS_CHECK_EXIT(tDeserializeSGetUserAuthReq(pReq->pCont, pReq->contLen, &authReq));
5,594,611✔
4100
  mTrace("user:%s, start to get auth", authReq.user);
5,594,611✔
4101

4102
  TAOS_CHECK_EXIT(mndAcquireUser(pMnode, authReq.user, &pUser));
5,594,611✔
4103

4104
  TAOS_CHECK_EXIT(mndSetUserAuthRsp(pMnode, pUser, &authRsp));
5,593,901✔
4105

4106
  contLen = tSerializeSGetUserAuthRsp(NULL, 0, &authRsp);
5,593,191✔
4107
  if (contLen < 0) {
5,593,191✔
4108
    TAOS_CHECK_EXIT(contLen);
×
4109
  }
4110
  pRsp = rpcMallocCont(contLen);
5,593,191✔
4111
  if (pRsp == NULL) {
5,593,191✔
4112
    TAOS_CHECK_EXIT(terrno);
×
4113
  }
4114

4115
  contLen = tSerializeSGetUserAuthRsp(pRsp, contLen, &authRsp);
5,593,191✔
4116
  if (contLen < 0) {
5,593,901✔
4117
    TAOS_CHECK_EXIT(contLen);
×
4118
  }
4119

4120
_exit:
5,593,901✔
4121
  mndReleaseUser(pMnode, pUser);
5,593,901✔
4122
  tFreeSGetUserAuthRsp(&authRsp);
5,594,611✔
4123
  if (code < 0) {
5,593,901✔
4124
    mError("user:%s, failed to get auth at line %d since %s", authReq.user, lino, tstrerror(code));
×
4125
    rpcFreeCont(pRsp);
×
4126
    pRsp = NULL;
×
4127
    contLen = 0;
×
4128
  }
4129
  pReq->info.rsp = pRsp;
5,593,901✔
4130
  pReq->info.rspLen = contLen;
5,593,191✔
4131
  pReq->code = code;
5,592,481✔
4132

4133
  TAOS_RETURN(code);
5,593,191✔
4134
}
4135

4136

4137

4138
static void base32Encode(const uint8_t *in, int32_t inLen, char *out) {
15,692✔
4139
  int buffer = 0, bits = 0;
15,692✔
4140
  int outLen = 0;
15,692✔
4141

4142
  // process all input bytes
4143
  for (int i = 0; i < inLen; i++) {
517,836✔
4144
    buffer = (buffer << 8) | in[i];
502,144✔
4145
    bits += 8;
502,144✔
4146

4147
    while (bits >= 5) {
1,302,436✔
4148
      int v = (buffer >> (bits - 5)) & 0x1F;
800,292✔
4149
      out[outLen++] = (v >= 26) ? (v - 26 + '2') : (v + 'A');
800,292✔
4150
      bits -= 5;
800,292✔
4151
    }
4152
  }
4153

4154
  // process remaining bits
4155
  if (bits > 0) {
15,692✔
4156
    int v = (buffer << (5 - bits)) & 0x1F;
15,692✔
4157
    out[outLen++] = (v >= 26) ? (v - 26 + '2') : (v + 'A');
15,692✔
4158
  }
4159

4160
  out[outLen] = '\0';
15,692✔
4161
}
15,692✔
4162

4163

4164
static int32_t mndCreateTotpSecret(SMnode *pMnode, SUserObj *pUser, SRpcMsg *pReq) {
15,692✔
4165
  SCreateTotpSecretRsp rsp = {0};
15,692✔
4166

4167
  base32Encode((uint8_t *)pUser->totpsecret, sizeof(pUser->totpsecret), rsp.totpSecret);
15,692✔
4168
  tstrncpy(rsp.user, pUser->user, sizeof(rsp.user));
15,692✔
4169

4170
  int32_t len = tSerializeSCreateTotpSecretRsp(NULL, 0, &rsp);
15,692✔
4171
  if (len < 0) {
15,692✔
4172
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
4173
  }
4174

4175
  void *pData = taosMemoryMalloc(len);
15,692✔
4176
  if (pData == NULL) {
15,692✔
4177
    TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
4178
  }
4179

4180
  if (tSerializeSCreateTotpSecretRsp(pData, len, &rsp) != len) {
15,692✔
4181
    taosMemoryFree(pData);
×
4182
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
4183
  }
4184

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

4193
  mndTransSetUserData(pTrans, pData, len);
15,692✔
4194

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

4206
  if (mndTransPrepare(pMnode, pTrans) != 0) {
15,692✔
4207
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
4208
    mndTransDrop(pTrans);
×
4209
    TAOS_RETURN(terrno);
×
4210
  }
4211

4212
  mndTransDrop(pTrans);
15,692✔
4213
  TAOS_RETURN(0);
15,692✔
4214
}
4215

4216

4217
static int32_t mndProcessCreateTotpSecretReq(SRpcMsg *pReq) {
15,833✔
4218
  SMnode              *pMnode = pReq->info.node;
15,833✔
4219
  int32_t              code = 0;
15,833✔
4220
  int32_t              lino = 0;
15,833✔
4221
  SUserObj            *pUser = NULL;
15,833✔
4222
  SUserObj             newUser = {0};
15,833✔
4223
  SCreateTotpSecretReq req = {0};
15,833✔
4224
  int64_t              tss = taosGetTimestampMs();
15,833✔
4225

4226
  TAOS_CHECK_GOTO(tDeserializeSCreateTotpSecretReq(pReq->pCont, pReq->contLen, &req), &lino, _OVER);
15,833✔
4227
  mTrace("user:%s, start to create/update totp secret", req.user);
15,833✔
4228

4229
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, req.user, &pUser), &lino, _OVER);
15,833✔
4230
  TAOS_CHECK_GOTO(mndCheckTotpSecretPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser), &lino, _OVER);
15,692✔
4231
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
15,692✔
4232
  taosSafeRandBytes((uint8_t *)newUser.totpsecret, sizeof(newUser.totpsecret));
15,692✔
4233
  TAOS_CHECK_GOTO(mndCreateTotpSecret(pMnode, &newUser, pReq), &lino, _OVER); 
15,692✔
4234

4235
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
15,692✔
4236
    double  duration = (double)(taosGetTimestampMs()- tss) / 1000.0;
15,692✔
4237
    auditRecord(pReq, pMnode->clusterId, "createTotpSecret", "", req.user, req.sql, req.sqlLen, duration, 0);
15,692✔
4238
  }
4239

4240
_OVER:
15,833✔
4241
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
15,833✔
4242
    mError("user:%s, failed to create totp secret at line %d since %s", req.user, lino, tstrerror(code));
141✔
4243
  }
4244
  mndReleaseUser(pMnode, pUser);
15,833✔
4245
  mndUserFreeObj(&newUser);
15,833✔
4246
  tFreeSCreateTotpSecretReq(&req);
15,833✔
4247
  TAOS_RETURN(code);
15,833✔
4248
}
4249

4250

4251

4252
int32_t mndBuildSMCreateTotpSecretResp(STrans *pTrans, void **ppResp, int32_t *pRespLen) {
15,692✔
4253
  // user data is the response
4254
  *ppResp = pTrans->userData;
15,692✔
4255
  *pRespLen = pTrans->userDataLen;
15,692✔
4256
  pTrans->userData = NULL;
15,692✔
4257
  pTrans->userDataLen = 0;
15,692✔
4258
  return 0;
15,692✔
4259
}
4260

4261

4262

4263
static int32_t mndProcessDropTotpSecretReq(SRpcMsg *pReq) {
5,922✔
4264
  SMnode            *pMnode = pReq->info.node;
5,922✔
4265
  int32_t            code = 0;
5,922✔
4266
  int32_t            lino = 0;
5,922✔
4267
  SUserObj          *pUser = NULL;
5,922✔
4268
  SUserObj           newUser = {0};
5,922✔
4269
  SDropTotpSecretReq req = {0};
5,922✔
4270
  int64_t            tss = taosGetTimestampMs();
5,922✔
4271

4272
  TAOS_CHECK_GOTO(tDeserializeSDropTotpSecretReq(pReq->pCont, pReq->contLen, &req), &lino, _OVER);
5,922✔
4273
  mTrace("user:%s, start to drop totp secret", req.user);
5,922✔
4274

4275
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, req.user, &pUser), &lino, _OVER);
5,922✔
4276
  TAOS_CHECK_GOTO(mndCheckTotpSecretPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser), &lino, _OVER);
4,512✔
4277

4278
  if (!mndIsTotpEnabledUser(pUser)) {
4,512✔
4279
    TAOS_CHECK_GOTO(TSDB_CODE_MND_TOTP_SECRET_NOT_EXIST, &lino, _OVER);
4,230✔
4280
  }
4281

4282
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
282✔
4283
  (void)memset(newUser.totpsecret, 0, sizeof(newUser.totpsecret));
282✔
4284
  TAOS_CHECK_GOTO(mndAlterUser(pMnode, &newUser, pReq), &lino, _OVER); 
282✔
4285

4286
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
282✔
4287
    double  duration = (double)(taosGetTimestampMs()- tss) / 1000.0;
282✔
4288
    auditRecord(pReq, pMnode->clusterId, "dropTotpSecret", "", req.user, req.sql, req.sqlLen, duration, 0);
282✔
4289
  }
4290

4291
_OVER:
5,922✔
4292
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
5,922✔
4293
    mError("user:%s, failed to drop totp secret at line %d since %s", req.user, lino, tstrerror(code));
5,640✔
4294
  }
4295
  mndReleaseUser(pMnode, pUser);
5,922✔
4296
  mndUserFreeObj(&newUser);
5,922✔
4297
  tFreeSDropTotpSecretReq(&req);
5,922✔
4298
  TAOS_RETURN(code);
5,922✔
4299
}
4300

4301

4302

4303
bool mndIsTotpEnabledUser(SUserObj *pUser) {
3,583,422✔
4304
  for (int32_t i = 0; i < sizeof(pUser->totpsecret); i++) {
116,673,232✔
4305
    if (pUser->totpsecret[i] != 0) {
113,132,806✔
4306
      return true;
49,432✔
4307
    }
4308
  }
4309
  return false;
3,540,426✔
4310
}
4311

4312

4313
static int32_t mndRetrieveUsers(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
126,058✔
4314
  SMnode   *pMnode = pReq->info.node;
126,058✔
4315
  SSdb     *pSdb = pMnode->pSdb;
126,058✔
4316
  int32_t   code = 0;
126,058✔
4317
  int32_t   lino = 0;
126,058✔
4318
  int32_t   numOfRows = 0;
126,058✔
4319
  SUserObj *pUser = NULL;
126,058✔
4320
  int32_t   cols = 0;
126,058✔
4321
  int8_t    flag = 0;
126,058✔
4322
  char     *pWrite = NULL;
126,058✔
4323
  char     *buf = NULL;
126,058✔
4324
  char     *varstr = NULL;
126,058✔
4325
  char      tBuf[TSDB_MAX_SUBROLE * TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
126,058✔
4326
  int32_t   bufSize = sizeof(tBuf) - VARSTR_HEADER_SIZE;
126,058✔
4327

4328
  while (numOfRows < rows) {
1,066,873✔
4329
    pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
1,066,873✔
4330
    if (pShow->pIter == NULL) break;
1,066,873✔
4331

4332
    cols = 0;
940,815✔
4333
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
940,815✔
4334
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
940,815✔
4335
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
940,815✔
4336
    COL_DATA_SET_VAL_GOTO((const char *)name, false, pUser, pShow->pIter, _exit);
940,815✔
4337

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

4342
    cols++;
940,815✔
4343
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
940,815✔
4344
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->enable, false, pUser, pShow->pIter, _exit);
940,815✔
4345

4346
    cols++;
940,815✔
4347
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
940,815✔
4348
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sysInfo, false, pUser, pShow->pIter, _exit);
940,815✔
4349

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

4355
    cols++;
940,815✔
4356
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
940,815✔
4357
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->createdTime, false, pUser, pShow->pIter, _exit);
940,815✔
4358

4359
    cols++;
940,815✔
4360
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
940,815✔
4361
    flag = mndIsTotpEnabledUser(pUser) ? 1 : 0;
940,815✔
4362
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
940,815✔
4363

4364
    cols++;
940,815✔
4365

4366
    int32_t tlen = convertIpWhiteListToStr(pUser, &buf);
940,815✔
4367
    if (tlen != 0) {
940,815✔
4368
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
940,815✔
4369
      if (varstr == NULL) {
940,815✔
4370
        sdbRelease(pSdb, pUser);
×
4371
        sdbCancelFetch(pSdb, pShow->pIter);
×
4372
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
4373
      }
4374
      varDataSetLen(varstr, tlen);
940,815✔
4375
      (void)memcpy(varDataVal(varstr), buf, tlen);
940,815✔
4376

4377
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
940,815✔
4378
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
940,815✔
4379

4380
      taosMemoryFreeClear(buf);
940,815✔
4381
    } else {
4382
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4383
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
4384
    }
4385

4386
    cols++;
940,815✔
4387
    tlen = convertTimeRangesToStr(pUser, &buf);
940,815✔
4388
    if (tlen != 0) {
940,815✔
4389
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
940,815✔
4390
      if (varstr == NULL) {
940,815✔
4391
        sdbRelease(pSdb, pUser);
×
4392
        sdbCancelFetch(pSdb, pShow->pIter);
×
4393
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
4394
      }
4395
      varDataSetLen(varstr, tlen);
940,815✔
4396
      (void)memcpy(varDataVal(varstr), buf, tlen);
940,815✔
4397

4398
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
940,815✔
4399
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
940,815✔
4400

4401
      taosMemoryFreeClear(buf);
940,815✔
4402
    } else {
4403
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4404
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
4405
    }
4406

4407
    if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
940,815✔
4408
      void  *pIter = NULL;
940,815✔
4409
      size_t klen = 0, tlen = 0;
940,815✔
4410
      char  *pBuf = POINTER_SHIFT(tBuf, VARSTR_HEADER_SIZE);
940,815✔
4411
      while ((pIter = taosHashIterate(pUser->roles, pIter))) {
2,134,038✔
4412
        char *roleName = taosHashGetKey(pIter, &klen);
1,193,223✔
4413
        tlen += snprintf(pBuf + tlen, bufSize - tlen, "%s,", roleName);
1,193,223✔
4414
      }
4415
      if (tlen > 0) {
940,815✔
4416
        pBuf[tlen - 1] = 0;  // remove last ','
940,815✔
4417
      } else {
4418
        pBuf[0] = 0;
×
4419
      }
4420
      varDataSetLen(tBuf, tlen);
940,815✔
4421
      COL_DATA_SET_VAL_GOTO((const char *)tBuf, false, pUser, pShow->pIter, _exit);
940,815✔
4422
    }
4423

4424
    numOfRows++;
940,815✔
4425
    sdbRelease(pSdb, pUser);
940,815✔
4426
  }
4427

4428
  pShow->numOfRows += numOfRows;
126,058✔
4429
_exit:
126,058✔
4430
  taosMemoryFreeClear(buf);
126,058✔
4431
  taosMemoryFreeClear(varstr);
126,058✔
4432
  if (code < 0) {
126,058✔
4433
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4434
    TAOS_RETURN(code);
×
4435
  }
4436
  return numOfRows;
126,058✔
4437
}
4438

4439
static int32_t mndRetrieveUsersFull(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
9,856✔
4440
  int32_t numOfRows = 0;
9,856✔
4441
#ifdef TD_ENTERPRISE
4442
  SMnode   *pMnode = pReq->info.node;
9,856✔
4443
  SSdb     *pSdb = pMnode->pSdb;
9,856✔
4444
  SUserObj *pUser = NULL;
9,856✔
4445
  int32_t   code = 0;
9,856✔
4446
  int32_t   lino = 0;
9,856✔
4447
  int32_t   cols = 0;
9,856✔
4448
  int8_t    flag = 0;
9,856✔
4449
  char     *pWrite = NULL;
9,856✔
4450
  char     *buf = NULL;
9,856✔
4451
  char     *varstr = NULL;
9,856✔
4452
  char     *pBuf = NULL;
9,856✔
4453
  char      tBuf[TSDB_MAX_SUBROLE * TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
9,856✔
4454
  int32_t   bufSize = sizeof(tBuf) - VARSTR_HEADER_SIZE;
9,856✔
4455

4456
  while (numOfRows < rows) {
396,288✔
4457
    pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
396,288✔
4458
    if (pShow->pIter == NULL) break;
396,288✔
4459

4460
    cols = 0;
386,432✔
4461
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
386,432✔
4462
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
386,432✔
4463
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
386,432✔
4464
    COL_DATA_SET_VAL_GOTO((const char *)name, false, pUser, pShow->pIter, _exit);
386,432✔
4465

4466
    cols++;
386,432✔
4467
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
386,432✔
4468
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->superUser, false, pUser, pShow->pIter, _exit);
386,432✔
4469

4470
    cols++;
386,432✔
4471
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
386,432✔
4472
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->enable, false, pUser, pShow->pIter, _exit);
386,432✔
4473

4474
    cols++;
386,432✔
4475
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
386,432✔
4476
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sysInfo, false, pUser, pShow->pIter, _exit);
386,432✔
4477

4478
    cols++;
386,432✔
4479
    flag = pUser->createdb ? 1 : 0;
386,432✔
4480
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
386,432✔
4481
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
386,432✔
4482

4483
    cols++;
386,432✔
4484
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
386,432✔
4485
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->createdTime, false, pUser, pShow->pIter, _exit);
386,432✔
4486

4487
    cols++;
386,432✔
4488
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
386,432✔
4489
    flag = mndIsTotpEnabledUser(pUser) ? 1 : 0;
386,432✔
4490
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
386,432✔
4491

4492
    cols++;
386,432✔
4493
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
386,432✔
4494
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->changePass, false, pUser, pShow->pIter, _exit);
386,432✔
4495

4496
    cols++;
386,432✔
4497
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
386,432✔
4498
    char pass[TSDB_PASSWORD_LEN + VARSTR_HEADER_SIZE] = {0};
386,432✔
4499
    STR_WITH_MAXSIZE_TO_VARSTR(pass, pUser->passwords[0].pass, pShow->pMeta->pSchemas[cols].bytes);
386,432✔
4500
    COL_DATA_SET_VAL_GOTO((const char *)pass, false, pUser, pShow->pIter, _exit);
386,432✔
4501

4502
    cols++;
386,432✔
4503
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
386,432✔
4504
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sessionPerUser, false, pUser, pShow->pIter, _exit);
386,432✔
4505

4506
    cols++;
386,432✔
4507
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
386,432✔
4508
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->connectTime, false, pUser, pShow->pIter, _exit);
386,432✔
4509

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

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

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

4522
    cols++;
386,432✔
4523
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
386,432✔
4524
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->failedLoginAttempts, false, pUser, pShow->pIter, _exit);
386,432✔
4525

4526
    cols++;
386,432✔
4527
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
386,432✔
4528
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordLifeTime, false, pUser, pShow->pIter, _exit);
386,432✔
4529

4530
    cols++;
386,432✔
4531
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
386,432✔
4532
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordReuseTime, false, pUser, pShow->pIter, _exit);
386,432✔
4533

4534
    cols++;
386,432✔
4535
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
386,432✔
4536
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordReuseMax, false, pUser, pShow->pIter, _exit);
386,432✔
4537

4538
    cols++;
386,432✔
4539
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
386,432✔
4540
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordLockTime, false, pUser, pShow->pIter, _exit);
386,432✔
4541

4542
    cols++;
386,432✔
4543
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
386,432✔
4544
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->passwordGraceTime, false, pUser, pShow->pIter, _exit);
386,432✔
4545

4546
    cols++;
386,432✔
4547
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
386,432✔
4548
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->inactiveAccountTime, false, pUser, pShow->pIter, _exit);
386,432✔
4549

4550
    cols++;
386,432✔
4551
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
386,432✔
4552
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->allowTokenNum, false, pUser, pShow->pIter, _exit);
386,432✔
4553

4554
    cols++;
386,432✔
4555
    int32_t tlen = convertIpWhiteListToStr(pUser, &buf);
386,432✔
4556
    if (tlen != 0) {
386,432✔
4557
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
386,432✔
4558
      if (varstr == NULL) {
386,432✔
4559
        sdbRelease(pSdb, pUser);
×
4560
        sdbCancelFetch(pSdb, pShow->pIter);
×
4561
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
4562
      }
4563
      varDataSetLen(varstr, tlen);
386,432✔
4564
      (void)memcpy(varDataVal(varstr), buf, tlen);
386,432✔
4565

4566
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
386,432✔
4567
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
386,432✔
4568

4569
      taosMemoryFreeClear(buf);
386,432✔
4570
    } else {
4571
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4572
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
4573
    }
4574

4575
    cols++;
386,432✔
4576
    tlen = convertTimeRangesToStr(pUser, &buf);
386,432✔
4577
    if (tlen != 0) {
386,432✔
4578
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
386,432✔
4579
      if (varstr == NULL) {
386,432✔
4580
        sdbRelease(pSdb, pUser);
×
4581
        sdbCancelFetch(pSdb, pShow->pIter);
×
4582
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
4583
      }
4584
      varDataSetLen(varstr, tlen);
386,432✔
4585
      (void)memcpy(varDataVal(varstr), buf, tlen);
386,432✔
4586

4587
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
386,432✔
4588
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
386,432✔
4589

4590
      taosMemoryFreeClear(buf);
386,432✔
4591
    } else {
4592
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4593
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
4594
    }
4595

4596
    if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
386,432✔
4597
      void  *pIter = NULL;
386,432✔
4598
      size_t klen = 0, tlen = 0;
386,432✔
4599
      char  *pBuf = POINTER_SHIFT(tBuf, VARSTR_HEADER_SIZE);
386,432✔
4600
      while ((pIter = taosHashIterate(pUser->roles, pIter))) {
792,576✔
4601
        char *roleName = taosHashGetKey(pIter, &klen);
406,144✔
4602
        tlen += snprintf(pBuf + tlen, bufSize - tlen, "%s,", roleName);
406,144✔
4603
      }
4604
      if (tlen > 0) {
386,432✔
4605
        pBuf[tlen - 1] = 0;  // remove last ','
386,432✔
4606
      } else {
4607
        pBuf[0] = 0;
×
4608
      }
4609
      varDataSetLen(tBuf, tlen);
386,432✔
4610
      COL_DATA_SET_VAL_GOTO((const char *)tBuf, false, pUser, pShow->pIter, _exit);
386,432✔
4611
    }
4612

4613
    numOfRows++;
386,432✔
4614
    sdbRelease(pSdb, pUser);
386,432✔
4615
  }
4616

4617
  pShow->numOfRows += numOfRows;
9,856✔
4618
_exit:
9,856✔
4619
  taosMemoryFreeClear(buf);
9,856✔
4620
  taosMemoryFreeClear(varstr);
9,856✔
4621
  if (code < 0) {
9,856✔
4622
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4623
    TAOS_RETURN(code);
×
4624
  }
4625
#endif
4626
  return numOfRows;
9,856✔
4627
}
4628

4629
static void mndCancelGetNextUser(SMnode *pMnode, void *pIter) {
×
4630
  SSdb *pSdb = pMnode->pSdb;
×
4631
  sdbCancelFetchByType(pSdb, pIter, SDB_USER);
×
4632
}
×
4633

4634
static int32_t mndLoopHash(SHashObj *hash, char *priType, SSDataBlock *pBlock, int32_t *pNumOfRows, SSdb *pSdb,
×
4635
                           SUserObj *pUser, SShowObj *pShow, char **condition, char **sql) {
4636
  char   *value = taosHashIterate(hash, NULL);
×
4637
  char   *user = pUser->user;
×
4638
  int32_t code = 0;
×
4639
  int32_t lino = 0;
×
4640
  int32_t cols = 0;
×
4641
  int32_t numOfRows = *pNumOfRows;
×
4642

4643
  while (value != NULL) {
×
4644
    cols = 0;
×
4645
    char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
×
4646
    STR_WITH_MAXSIZE_TO_VARSTR(userName, user, pShow->pMeta->pSchemas[cols].bytes);
×
4647
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4648
    COL_DATA_SET_VAL_GOTO((const char *)userName, false, NULL, NULL, _exit);
×
4649

4650
    char privilege[20] = {0};
×
4651
    STR_WITH_MAXSIZE_TO_VARSTR(privilege, priType, pShow->pMeta->pSchemas[cols].bytes);
×
4652
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4653
    COL_DATA_SET_VAL_GOTO((const char *)privilege, false, NULL, NULL, _exit);
×
4654

4655
    size_t keyLen = 0;
×
4656
    void  *key = taosHashGetKey(value, &keyLen);
×
4657

4658
    char dbName[TSDB_DB_NAME_LEN] = {0};
×
4659
    (void)mndExtractShortDbNameFromStbFullName(key, dbName);
×
4660
    char dbNameContent[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
×
4661
    STR_WITH_MAXSIZE_TO_VARSTR(dbNameContent, dbName, pShow->pMeta->pSchemas[cols].bytes);
×
4662
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4663
    COL_DATA_SET_VAL_GOTO((const char *)dbNameContent, false, NULL, NULL, _exit);
×
4664

4665
    char tableName[TSDB_TABLE_NAME_LEN] = {0};
×
4666
    mndExtractTbNameFromStbFullName(key, tableName, TSDB_TABLE_NAME_LEN);
×
4667
    char tableNameContent[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
×
4668
    STR_WITH_MAXSIZE_TO_VARSTR(tableNameContent, tableName, pShow->pMeta->pSchemas[cols].bytes);
×
4669
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4670
    COL_DATA_SET_VAL_GOTO((const char *)tableNameContent, false, NULL, NULL, _exit);
×
4671

4672
    if (strcmp("t", value) != 0 && strcmp("v", value) != 0) {
×
4673
      SNode  *pAst = NULL;
×
4674
      int32_t sqlLen = 0;
×
4675
      size_t  bufSz = strlen(value) + 1;
×
4676
      if (bufSz < 6) bufSz = 6;
×
4677
      TAOS_MEMORY_REALLOC(*sql, bufSz);
×
4678
      if (*sql == NULL) {
×
4679
        code = terrno;
×
4680
        goto _exit;
×
4681
      }
4682
      TAOS_MEMORY_REALLOC(*condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
×
4683
      if ((*condition) == NULL) {
×
4684
        code = terrno;
×
4685
        goto _exit;
×
4686
      }
4687

4688
      if (nodesStringToNode(value, &pAst) == 0) {
×
4689
        if (nodesNodeToSQLFormat(pAst, *sql, bufSz, &sqlLen, true) != 0) {
×
4690
          sqlLen = tsnprintf(*sql, bufSz, "error");
×
4691
        }
4692
        nodesDestroyNode(pAst);
×
4693
      }
4694

4695
      if (sqlLen == 0) {
×
4696
        sqlLen = tsnprintf(*sql, bufSz, "error");
×
4697
      }
4698

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

4701
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4702
      COL_DATA_SET_VAL_GOTO((const char *)(*condition), false, NULL, NULL, _exit);
×
4703

4704
      char notes[2] = {0};
×
4705
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
×
4706
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4707
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, NULL, NULL, _exit);
×
4708
    } else {
4709
      TAOS_MEMORY_REALLOC(*condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
×
4710
      if ((*condition) == NULL) {
×
4711
        code = terrno;
×
4712
        goto _exit;
×
4713
      }
4714
      STR_WITH_MAXSIZE_TO_VARSTR((*condition), "", pShow->pMeta->pSchemas[cols].bytes);
×
4715
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4716
      COL_DATA_SET_VAL_GOTO((const char *)(*condition), false, NULL, NULL, _exit);
×
4717

4718
      char notes[64 + VARSTR_HEADER_SIZE] = {0};
×
4719
      STR_WITH_MAXSIZE_TO_VARSTR(notes, value[0] == 'v' ? "view" : "", sizeof(notes));
×
4720
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4721
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, NULL, NULL, _exit);
×
4722
    }
4723

4724
    numOfRows++;
×
4725
    value = taosHashIterate(hash, value);
×
4726
  }
4727
  *pNumOfRows = numOfRows;
×
4728
_exit:
×
4729
  if (code < 0) {
×
4730
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4731
    sdbRelease(pSdb, pUser);
×
4732
    sdbCancelFetch(pSdb, pShow->pIter);
×
4733
  }
4734
  TAOS_RETURN(code);
×
4735
}
4736

4737
#if 0
4738
static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
4739
  int32_t   code = 0;
4740
  int32_t   lino = 0;
4741
  SMnode   *pMnode = pReq->info.node;
4742
  SSdb     *pSdb = pMnode->pSdb;
4743
  int32_t   numOfRows = 0;
4744
  SUserObj *pUser = NULL;
4745
  int32_t   cols = 0;
4746
  char     *pWrite = NULL;
4747
  char     *condition = NULL;
4748
  char     *sql = NULL;
4749

4750
  bool fetchNextUser = pShow->restore ? false : true;
4751
  pShow->restore = false;
4752

4753
  while (numOfRows < rows) {
4754
    if (fetchNextUser) {
4755
      pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
4756
      if (pShow->pIter == NULL) break;
4757
    } else {
4758
      fetchNextUser = true;
4759
      void *pKey = taosHashGetKey(pShow->pIter, NULL);
4760
      pUser = sdbAcquire(pSdb, SDB_USER, pKey);
4761
      if (!pUser) {
4762
        continue;
4763
      }
4764
    }
4765

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

4788
    if (pUser->superUser) {
4789
      cols = 0;
4790
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
4791
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
4792
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4793
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
4794

4795
      char privilege[20] = {0};
4796
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "all", pShow->pMeta->pSchemas[cols].bytes);
4797
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4798
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
4799

4800
      char objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4801
      STR_WITH_MAXSIZE_TO_VARSTR(objName, "all", pShow->pMeta->pSchemas[cols].bytes);
4802
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4803
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
4804

4805
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4806
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
4807
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4808
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
4809

4810
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
4811
      if (condition == NULL) {
4812
        sdbRelease(pSdb, pUser);
4813
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
4814
      }
4815
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
4816
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4817
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
4818

4819
      char notes[2] = {0};
4820
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
4821
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4822
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
4823

4824
      numOfRows++;
4825
    }
4826
#if 0
4827
    char *db = taosHashIterate(pUser->readDbs, NULL);
4828
    while (db != NULL) {
4829
      cols = 0;
4830
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
4831
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
4832
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4833
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
4834

4835
      char privilege[20] = {0};
4836
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "read", pShow->pMeta->pSchemas[cols].bytes);
4837
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4838
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
4839

4840
      SName name = {0};
4841
      char  objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4842
      code = tNameFromString(&name, db, T_NAME_ACCT | T_NAME_DB);
4843
      if (code < 0) {
4844
        sdbRelease(pSdb, pUser);
4845
        sdbCancelFetch(pSdb, pShow->pIter);
4846
        TAOS_CHECK_GOTO(code, &lino, _exit);
4847
      }
4848
      (void)tNameGetDbName(&name, varDataVal(objName));
4849
      varDataSetLen(objName, strlen(varDataVal(objName)));
4850
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4851
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
4852

4853
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4854
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
4855
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4856
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
4857

4858
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
4859
      if (condition == NULL) {
4860
        sdbRelease(pSdb, pUser);
4861
        sdbCancelFetch(pSdb, pShow->pIter);
4862
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
4863
      }
4864
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
4865
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4866
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
4867

4868
      char notes[2] = {0};
4869
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
4870
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4871
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
4872

4873
      numOfRows++;
4874
      db = taosHashIterate(pUser->readDbs, db);
4875
    }
4876

4877
    db = taosHashIterate(pUser->writeDbs, NULL);
4878
    while (db != NULL) {
4879
      cols = 0;
4880
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
4881
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
4882
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4883
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
4884

4885
      char privilege[20] = {0};
4886
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "write", pShow->pMeta->pSchemas[cols].bytes);
4887
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4888
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
4889

4890
      SName name = {0};
4891
      char  objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4892
      code = tNameFromString(&name, db, T_NAME_ACCT | T_NAME_DB);
4893
      if (code < 0) {
4894
        sdbRelease(pSdb, pUser);
4895
        sdbCancelFetch(pSdb, pShow->pIter);
4896
        TAOS_CHECK_GOTO(code, &lino, _exit);
4897
      }
4898
      (void)tNameGetDbName(&name, varDataVal(objName));
4899
      varDataSetLen(objName, strlen(varDataVal(objName)));
4900
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4901
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
4902

4903
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4904
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
4905
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4906
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
4907

4908
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
4909
      if (condition == NULL) {
4910
        sdbRelease(pSdb, pUser);
4911
        sdbCancelFetch(pSdb, pShow->pIter);
4912
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
4913
      }
4914
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
4915
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4916
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
4917

4918
      char notes[2] = {0};
4919
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
4920
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4921
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
4922

4923
      numOfRows++;
4924
      db = taosHashIterate(pUser->writeDbs, db);
4925
    }
4926
#endif
4927
    TAOS_CHECK_EXIT(mndLoopHash(pUser->selectTbs, "select", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
4928

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

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

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

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

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

4939
    char *topic = taosHashIterate(pUser->topics, NULL);
4940
    while (topic != NULL) {
4941
      cols = 0;
4942
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
4943
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
4944
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4945
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
4946

4947
      char privilege[20] = {0};
4948
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "subscribe", pShow->pMeta->pSchemas[cols].bytes);
4949
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4950
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
4951

4952
      char topicName[TSDB_TOPIC_NAME_LEN + VARSTR_HEADER_SIZE + 5] = {0};
4953
      tstrncpy(varDataVal(topicName), mndGetDbStr(topic), TSDB_TOPIC_NAME_LEN - 2);
4954
      varDataSetLen(topicName, strlen(varDataVal(topicName)));
4955
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4956
      COL_DATA_SET_VAL_GOTO((const char *)topicName, false, pUser, pShow->pIter, _exit);
4957

4958
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4959
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
4960
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4961
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
4962

4963
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
4964
      if (condition == NULL) {
4965
        sdbRelease(pSdb, pUser);
4966
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
4967
      }
4968
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
4969
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4970
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
4971

4972
      char notes[2] = {0};
4973
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
4974
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4975
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
4976

4977
      numOfRows++;
4978
      topic = taosHashIterate(pUser->topics, topic);
4979
    }
4980

4981
    sdbRelease(pSdb, pUser);
4982
  }
4983

4984
  pShow->numOfRows += numOfRows;
4985
_exit:
4986
  taosMemoryFreeClear(condition);
4987
  taosMemoryFreeClear(sql);
4988
  if (code < 0) {
4989
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
4990
    TAOS_RETURN(code);
4991
  }
4992
  return numOfRows;
4993
}
4994
#endif
4995

4996
static int32_t mndShowTablePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows, SUserObj *pObj,
131,860✔
4997
                                      SHashObj *privTbs, EPrivType privType, char *pBuf, int32_t bufSize, int32_t *pNumOfRows) {
4998
  int32_t     code = 0, lino = 0;
131,860✔
4999
  SMnode     *pMnode = pReq->info.node;
131,860✔
5000
  SSdb       *pSdb = pMnode->pSdb;
131,860✔
5001
  int32_t     cols = 0, qBufSize = bufSize - VARSTR_HEADER_SIZE;
131,860✔
5002
  int32_t     numOfRows = *pNumOfRows;
131,860✔
5003
  char       *qBuf = NULL;
131,860✔
5004
  char       *sql = NULL;
131,860✔
5005
  char        roleName[TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
131,860✔
5006
  const char *privName = privInfoGetName(privType);
131,860✔
5007

5008
  STR_WITH_MAXSIZE_TO_VARSTR(roleName, pObj->name, pShow->pMeta->pSchemas[cols].bytes);
131,860✔
5009

5010
  void *pIter = NULL;
131,860✔
5011
  while ((pIter = taosHashIterate(privTbs, pIter))) {
160,682✔
5012
    SPrivTblPolicies *pPolices = (SPrivTblPolicies *)pIter;
28,822✔
5013
    SArray           *tblPolicies = pPolices->policy;
28,822✔
5014

5015
    char   *key = taosHashGetKey(pPolices, NULL);
28,822✔
5016
    int32_t objType = PRIV_OBJ_UNKNOWN;
28,822✔
5017
    char    dbName[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
28,822✔
5018
    char    tblName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
28,822✔
5019
    if ((code = privObjKeyParse(key, &objType, dbName, sizeof(dbName), tblName, sizeof(tblName), false))) {
28,822✔
5020
      sdbRelease(pSdb, pObj);
×
5021
      sdbCancelFetch(pSdb, pShow->pIter);
×
5022
      TAOS_CHECK_EXIT(code);
×
5023
    }
5024

5025
    int32_t nTbPolicies = taosArrayGetSize(tblPolicies);
28,822✔
5026
    for (int32_t i = 0; i < nTbPolicies; ++i) {
57,644✔
5027
      SPrivTblPolicy *tbPolicy = (SPrivTblPolicy *)TARRAY_GET_ELEM(tblPolicies, i);
28,822✔
5028
      cols = 0;
28,822✔
5029
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
28,822✔
5030
      COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
28,822✔
5031

5032
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
28,822✔
5033
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privName, pShow->pMeta->pSchemas[cols].bytes);
28,822✔
5034
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
28,822✔
5035
      }
5036

5037
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
28,822✔
5038
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privObjGetName(objType), pShow->pMeta->pSchemas[cols].bytes);
28,822✔
5039
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
28,822✔
5040
      }
5041

5042
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
28,822✔
5043
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, dbName, pShow->pMeta->pSchemas[cols].bytes);
28,822✔
5044
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
28,822✔
5045
      }
5046

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

5116
static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
5,011✔
5117
  int32_t   code = 0, lino = 0;
5,011✔
5118
  SMnode   *pMnode = pReq->info.node;
5,011✔
5119
  SSdb     *pSdb = pMnode->pSdb;
5,011✔
5120
  int32_t   numOfRows = 0;
5,011✔
5121
  int32_t   cols = 0;
5,011✔
5122
  SUserObj *pObj = NULL;
5,011✔
5123
  char     *pBuf = NULL, *qBuf = NULL;
5,011✔
5124
  char     *sql = NULL;
5,011✔
5125
  char      roleName[TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
5,011✔
5126
  int32_t   bufSize = TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE;
5,011✔
5127

5128
  bool fetchNextInstance = pShow->restore ? false : true;
5,011✔
5129
  pShow->restore = false;
5,011✔
5130

5131
  while (numOfRows < rows) {
37,976✔
5132
    if (fetchNextInstance) {
37,976✔
5133
      pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pObj);
37,976✔
5134
      if (pShow->pIter == NULL) break;
37,976✔
5135
    } else {
5136
      fetchNextInstance = true;
×
5137
      void *pKey = taosHashGetKey(pShow->pIter, NULL);
×
5138
      if (!(pObj = sdbAcquire(pSdb, SDB_USER, pKey))) {
×
5139
        continue;
×
5140
      }
5141
    }
5142

5143
    int32_t nSysPrivileges = 0, nObjPrivileges = 0;
32,965✔
5144
    if (nSysPrivileges + nObjPrivileges >= rows) {
32,965✔
5145
      pShow->restore = true;
×
5146
      sdbRelease(pSdb, pObj);
×
5147
      break;
×
5148
    }
5149

5150
    if (!pBuf && !(pBuf = taosMemoryMalloc(bufSize))) {
32,965✔
5151
      sdbCancelFetch(pSdb, pShow->pIter);
×
5152
      sdbRelease(pSdb, pObj);
×
5153
      TAOS_CHECK_EXIT(terrno);
×
5154
    }
5155

5156
    cols = 0;
32,965✔
5157
    STR_WITH_MAXSIZE_TO_VARSTR(roleName, pObj->name, pShow->pMeta->pSchemas[cols].bytes);
32,965✔
5158

5159
    // system privileges
5160
    SPrivIter privIter = {0};
32,965✔
5161
    privIterInit(&privIter, &pObj->sysPrivs);
32,965✔
5162
    SPrivInfo *pPrivInfo = NULL;
32,965✔
5163
    while (privIterNext(&privIter, &pPrivInfo)) {
34,837✔
5164
      cols = 0;
1,872✔
5165
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
1,872✔
5166
      COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
1,872✔
5167

5168
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
1,872✔
5169
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, pPrivInfo->name, pShow->pMeta->pSchemas[cols].bytes);
1,872✔
5170
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
1,872✔
5171
      }
5172
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
1,872✔
5173
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privObjGetName(PRIV_OBJ_CLUSTER), pShow->pMeta->pSchemas[cols].bytes);
1,872✔
5174
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
1,872✔
5175
      }
5176
      // skip db, table, condition, notes, columns, update_time
5177
      COL_DATA_SET_EMPTY_VARCHAR(pBuf, 6);
13,104✔
5178
      numOfRows++;
1,872✔
5179
    }
5180

5181
    // object privileges
5182
    void *pIter = NULL;
32,965✔
5183
    while ((pIter = taosHashIterate(pObj->objPrivs, pIter))) {
50,689✔
5184
      SPrivObjPolicies *pPolices = (SPrivObjPolicies *)pIter;
17,724✔
5185

5186
      char   *key = taosHashGetKey(pPolices, NULL);
17,724✔
5187
      int32_t objType = PRIV_OBJ_UNKNOWN;
17,724✔
5188
      char    dbName[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
17,724✔
5189
      char    tblName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
17,724✔
5190
      if ((code = privObjKeyParse(key, &objType, dbName, sizeof(dbName), tblName, sizeof(tblName), false))) {
17,724✔
5191
        sdbRelease(pSdb, pObj);
×
5192
        sdbCancelFetch(pSdb, pShow->pIter);
×
5193
        TAOS_CHECK_EXIT(code);
×
5194
      }
5195

5196
      SPrivIter privIter = {0};
17,724✔
5197
      privIterInit(&privIter, &pPolices->policy);
17,724✔
5198
      SPrivInfo *pPrivInfo = NULL;
17,724✔
5199
      while (privIterNext(&privIter, &pPrivInfo)) {
96,426✔
5200
        cols = 0;
78,702✔
5201
        SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
78,702✔
5202
        COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
78,702✔
5203

5204
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
78,702✔
5205
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, pPrivInfo->name, pShow->pMeta->pSchemas[cols].bytes);
78,702✔
5206
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
78,702✔
5207
        }
5208

5209
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
78,702✔
5210
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privObjGetName(objType), pShow->pMeta->pSchemas[cols].bytes);
78,702✔
5211
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
78,702✔
5212
        }
5213

5214
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
78,702✔
5215
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, dbName, pShow->pMeta->pSchemas[cols].bytes);
78,702✔
5216
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
78,702✔
5217
        }
5218

5219
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
78,702✔
5220
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, tblName, pShow->pMeta->pSchemas[cols].bytes);
78,702✔
5221
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
78,702✔
5222
        }
5223

5224
        // skip condition, notes, columns, update_time
5225
        COL_DATA_SET_EMPTY_VARCHAR(pBuf, 4);
393,510✔
5226

5227
        numOfRows++;
78,702✔
5228
      }
5229
    }
5230

5231
    // table level privileges
5232
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->selectTbs,
32,965✔
5233
                                           PRIV_TBL_SELECT, pBuf, bufSize, &numOfRows));
5234
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->insertTbs,
32,965✔
5235
                                           PRIV_TBL_INSERT, pBuf, bufSize, &numOfRows));
5236
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->updateTbs,
32,965✔
5237
                                           PRIV_TBL_UPDATE, pBuf, bufSize, &numOfRows));
5238
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->deleteTbs,
32,965✔
5239
                                           PRIV_TBL_DELETE, pBuf, bufSize, &numOfRows));
5240
#if 0
5241
    while ((pIter = taosHashIterate(pObj->selectTbs, pIter))) {
5242
      SPrivTblPolicies *pPolices = (SPrivTblPolicies *)pIter;
5243
      SArray           *tblPolicies = pPolices->policy;
5244

5245
      char   *key = taosHashGetKey(pPolices, NULL);
5246
      int32_t objType = PRIV_OBJ_UNKNOWN;
5247
      char    dbName[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
5248
      char    tblName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
5249
      if ((code = privObjKeyParse(key, &objType, dbName, sizeof(dbName), tblName, sizeof(tblName), false))) {
5250
        sdbRelease(pSdb, pObj);
5251
        sdbCancelFetch(pSdb, pShow->pIter);
5252
        TAOS_CHECK_EXIT(code);
5253
      }
5254

5255
      int32_t nTbPolicies = taosArrayGetSize(tblPolicies);
5256
      for (int32_t i = 0; i < nTbPolicies; ++i) {
5257
        SPrivTblPolicy *tbPolicy = (SPrivTblPolicy *)TARRAY_GET_ELEM(tblPolicies, i);
5258
        cols = 0;
5259
        SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
5260
        COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
5261

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

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

5272
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
5273
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, tblName, pShow->pMeta->pSchemas[cols].bytes);
5274
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
5275
        }
5276

5277
        // skip condition, notes, columns, update_time
5278
        COL_DATA_SET_EMPTY_VARCHAR(pBuf, 4);
5279

5280
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
5281
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privObjGetName(objType), pShow->pMeta->pSchemas[cols].bytes);
5282
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
5283
        }
5284
        numOfRows++;
5285
      }
5286
    }
5287
#endif
5288
    sdbRelease(pSdb, pObj);
32,965✔
5289
  }
5290

5291
  pShow->numOfRows += numOfRows;
5,011✔
5292
_exit:
5,011✔
5293
  taosMemoryFreeClear(pBuf);
5,011✔
5294
  taosMemoryFreeClear(sql);
5,011✔
5295
  if (code < 0) {
5,011✔
5296
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
5297
    TAOS_RETURN(code);
×
5298
  }
5299
  return numOfRows;
5,011✔
5300
}
5301

5302
static void mndCancelGetNextPrivileges(SMnode *pMnode, void *pIter) {
×
5303
  SSdb *pSdb = pMnode->pSdb;
×
5304
  sdbCancelFetchByType(pSdb, pIter, SDB_USER);
×
5305
}
×
5306

5307
int32_t mndValidateUserAuthInfo(SMnode *pMnode, SUserAuthVersion *pUsers, int32_t numOfUses, void **ppRsp,
22,278,883✔
5308
                                int32_t *pRspLen, int64_t ipWhiteListVer) {
5309
  int32_t           code = 0;
22,278,883✔
5310
  int32_t           lino = 0;
22,278,883✔
5311
  int32_t           rspLen = 0;
22,278,883✔
5312
  void             *pRsp = NULL;
22,278,883✔
5313
  SUserAuthBatchRsp batchRsp = {0};
22,278,883✔
5314

5315
  batchRsp.pArray = taosArrayInit(numOfUses, sizeof(SGetUserAuthRsp));
22,278,883✔
5316
  if (batchRsp.pArray == NULL) {
22,278,883✔
5317
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
5318
  }
5319
  int64_t now = taosGetTimestampMs();
22,278,883✔
5320
  for (int32_t i = 0; i < numOfUses; ++i) {
44,788,143✔
5321
    SUserObj *pUser = NULL;
22,509,260✔
5322
    code = mndAcquireUser(pMnode, pUsers[i].user, &pUser);
22,509,260✔
5323
    if (pUser == NULL) {
22,509,260✔
5324
      if (TSDB_CODE_MND_USER_NOT_EXIST == code) {
241✔
5325
        SGetUserAuthRsp rsp = {.dropped = 1};
241✔
5326
        (void)memcpy(rsp.user, pUsers[i].user, TSDB_USER_LEN);
241✔
5327
        TSDB_CHECK_NULL(taosArrayPush(batchRsp.pArray, &rsp), code, lino, _OVER, TSDB_CODE_OUT_OF_MEMORY);
482✔
5328
      }
5329
      mError("user:%s, failed to auth user since %s", pUsers[i].user, tstrerror(code));
241✔
5330
      code = 0;
241✔
5331
      continue;
241✔
5332
    }
5333

5334
    pUsers[i].version = ntohl(pUsers[i].version);
22,509,019✔
5335
    if ((pUser->authVersion <= pUsers[i].version) && (ipWhiteListVer == pMnode->ipWhiteVer) &&
22,509,019✔
5336
        !mndNeedRetrieveRole(pUser)) {
1,076✔
5337
      mndReleaseUser(pMnode, pUser);
1,076✔
5338
      continue;
1,076✔
5339
    }
5340

5341
    SGetUserAuthRsp rsp = {0};
22,507,943✔
5342
    code = mndSetUserAuthRsp(pMnode, pUser, &rsp);
22,507,943✔
5343
    if (code) {
22,507,610✔
5344
      mndReleaseUser(pMnode, pUser);
×
5345
      tFreeSGetUserAuthRsp(&rsp);
×
5346
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
5347
    }
5348

5349
    if (!(taosArrayPush(batchRsp.pArray, &rsp))) {
45,015,065✔
5350
      code = terrno;
×
5351
      mndReleaseUser(pMnode, pUser);
×
5352
      tFreeSGetUserAuthRsp(&rsp);
×
5353
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
5354
    }
5355
    pUser->lastRoleRetrieve = now;  // update user's last retrieve time
22,507,455✔
5356
    mndReleaseUser(pMnode, pUser);
22,507,610✔
5357
  }
5358

5359
  if (taosArrayGetSize(batchRsp.pArray) <= 0) {
22,278,883✔
5360
    *ppRsp = NULL;
1,076✔
5361
    *pRspLen = 0;
1,076✔
5362

5363
    tFreeSUserAuthBatchRsp(&batchRsp);
1,076✔
5364
    return 0;
1,076✔
5365
  }
5366

5367
  rspLen = tSerializeSUserAuthBatchRsp(NULL, 0, &batchRsp);
22,277,807✔
5368
  if (rspLen < 0) {
22,277,474✔
5369
    TAOS_CHECK_GOTO(rspLen, &lino, _OVER);
×
5370
  }
5371
  pRsp = taosMemoryMalloc(rspLen);
22,277,474✔
5372
  if (pRsp == NULL) {
22,277,474✔
5373
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
5374
  }
5375
  rspLen = tSerializeSUserAuthBatchRsp(pRsp, rspLen, &batchRsp);
22,277,474✔
5376
  if (rspLen < 0) {
22,277,513✔
5377
    TAOS_CHECK_GOTO(rspLen, &lino, _OVER);
×
5378
  }
5379
_OVER:
22,277,513✔
5380
  tFreeSUserAuthBatchRsp(&batchRsp);
22,277,807✔
5381
  if (code < 0) {
22,277,215✔
5382
    for (int32_t i = 0; i < numOfUses; ++i) {
×
5383
      SUserObj *pUser = NULL;
×
5384
      if (mndAcquireUser(pMnode, pUsers[i].user, &pUser) != 0) {
×
5385
        continue;
×
5386
      }
5387
      pUser->lastRoleRetrieve = 0;  // reset last retrieve time on error
×
5388
      mndReleaseUser(pMnode, pUser);
×
5389
    }
5390
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
5391
    taosMemoryFreeClear(pRsp);
×
5392
    rspLen = 0;
×
5393
  }
5394
  *ppRsp = pRsp;
22,277,215✔
5395
  *pRspLen = rspLen;
22,277,474✔
5396

5397
  TAOS_RETURN(code);
22,274,013✔
5398
}
5399

5400
static int32_t mndRemoveDbPrivileges(SHashObj *pHash, const char *dbFName, int32_t dbFNameLen, int32_t *nRemoved) {
×
5401
  void *pVal = NULL;
×
5402
  while ((pVal = taosHashIterate(pHash, pVal))) {
×
5403
    size_t keyLen = 0;
×
5404
    char  *pKey = (char *)taosHashGetKey(pVal, &keyLen);
×
5405
    if (pKey == NULL || keyLen <= dbFNameLen) continue;
×
5406
    if ((*(pKey + dbFNameLen) == '.') && strncmp(pKey, dbFName, dbFNameLen) == 0) {
×
5407
      TAOS_CHECK_RETURN(taosHashRemove(pHash, pKey, keyLen));
×
5408
      if (nRemoved) ++(*nRemoved);
×
5409
    }
5410
  }
5411
  TAOS_RETURN(0);
×
5412
}
5413

5414
int32_t mndUserDropRole(SMnode *pMnode, STrans *pTrans, SRoleObj *pObj) {
×
5415
  int32_t   code = 0, lino = 0;
×
5416
  SSdb     *pSdb = pMnode->pSdb;
×
5417
  SUserObj *pUser = NULL;
×
5418
  void     *pIter = NULL;
×
5419

5420
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser))) {
×
5421
    SHashObj *pRole = taosHashGet(pUser->roles, pObj->name, strlen(pObj->name) + 1);
×
5422
    if (!pRole) {
×
5423
      sdbRelease(pSdb, pUser);
×
5424
      pUser = NULL;
×
5425
      continue;
×
5426
    }
5427

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

5463
int32_t mndUserRemoveDb(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SSHashObj **ppUsers) {
602,747✔
5464
  int32_t    code = 0, lino = 0;
602,747✔
5465
  SSdb      *pSdb = pMnode->pSdb;
602,747✔
5466
  int32_t    dbLen = strlen(pDb->name);
602,747✔
5467
  void      *pIter = NULL;
602,747✔
5468
  SUserObj  *pUser = NULL;
602,747✔
5469
  SUserObj   newUser = {0};
602,747✔
5470
  SSHashObj *pUsers = ppUsers ? *ppUsers : NULL;
602,747✔
5471
  bool       output = (ppUsers != NULL);
602,747✔
5472
#ifdef PRIV_TODO
5473
  while (1) {
5474
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
5475
    if (pIter == NULL) break;
5476

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

5525
    int32_t nRemovedReadTbs = 0;
5526
    int32_t nRemovedWriteTbs = 0;
5527
    int32_t nRemovedAlterTbs = 0;
5528
    if (inReadTbs || inWriteTbs || inAlterTbs) {
5529
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->selectTbs, pDb->name, dbLen, &nRemovedReadTbs));
5530
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->insertTbs, pDb->name, dbLen, &nRemovedWriteTbs));
5531
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->alterTbs, pDb->name, dbLen, &nRemovedAlterTbs));
5532
      if (!update) update = nRemovedReadTbs > 0 || nRemovedWriteTbs > 0 || nRemovedAlterTbs > 0;
5533
    }
5534

5535
    int32_t nRemovedReadViews = 0;
5536
    int32_t nRemovedWriteViews = 0;
5537
    int32_t nRemovedAlterViews = 0;
5538
    if (inReadViews || inWriteViews || inAlterViews) {
5539
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->readViews, pDb->name, dbLen, &nRemovedReadViews));
5540
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->writeViews, pDb->name, dbLen, &nRemovedWriteViews));
5541
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->alterViews, pDb->name, dbLen, &nRemovedAlterViews));
5542
      if (!update) update = nRemovedReadViews > 0 || nRemovedWriteViews > 0 || nRemovedAlterViews > 0;
5543
    }
5544

5545
    if (!output) {
5546
      if (update) {
5547
        SSdbRaw *pCommitRaw = mndUserActionEncode(pTargetUser);
5548
        if (pCommitRaw == NULL) {
5549
          TAOS_CHECK_EXIT(terrno);
5550
        }
5551
        TAOS_CHECK_EXIT(mndTransAppendCommitlog(pTrans, pCommitRaw));
5552
        TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
5553
      }
5554
      mndUserFreeObj(&newUser);
5555
    }
5556
    sdbRelease(pSdb, pUser);
5557
  }
5558
#endif
5559
_exit:
602,747✔
5560
  if (code < 0) {
602,747✔
5561
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
5562
    mndUserFreeObj(&newUser);
×
5563
  }
5564
  if (pUser != NULL) sdbRelease(pSdb, pUser);
602,747✔
5565
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
602,747✔
5566
  if (!output) mndUserFreeObj(&newUser);
602,747✔
5567
  TAOS_RETURN(code);
602,747✔
5568
}
5569

5570
int32_t mndUserRemoveStb(SMnode *pMnode, STrans *pTrans, char *stb) {
432,691✔
5571
  int32_t   code = 0;
432,691✔
5572
  SSdb     *pSdb = pMnode->pSdb;
432,691✔
5573
  int32_t   len = strlen(stb) + 1;
432,691✔
5574
  void     *pIter = NULL;
432,691✔
5575
  SUserObj *pUser = NULL;
432,691✔
5576
  SUserObj  newUser = {0};
432,691✔
5577
#ifdef PRIV_TODO
5578
  while (1) {
5579
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
5580
    if (pIter == NULL) break;
5581

5582
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
5583
      break;
5584
    }
5585

5586
    bool inRead = (taosHashGet(newUser.selectTbs, stb, len) != NULL);
5587
    bool inWrite = (taosHashGet(newUser.insertTbs, stb, len) != NULL);
5588
    bool inAlter = (taosHashGet(newUser.alterTbs, stb, len) != NULL);
5589
    if (inRead || inWrite || inAlter) {
5590
      code = taosHashRemove(newUser.selectTbs, stb, len);
5591
      if (code < 0) {
5592
        mError("failed to remove selectTbs:%s from user:%s", stb, pUser->user);
5593
      }
5594
      code = taosHashRemove(newUser.insertTbs, stb, len);
5595
      if (code < 0) {
5596
        mError("failed to remove insertTbs:%s from user:%s", stb, pUser->user);
5597
      }
5598
      code = taosHashRemove(newUser.alterTbs, stb, len);
5599
      if (code < 0) {
5600
        mError("failed to remove alterTbs:%s from user:%s", stb, pUser->user);
5601
      }
5602

5603
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
5604
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
5605
        code = TSDB_CODE_OUT_OF_MEMORY;
5606
        break;
5607
      }
5608
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
5609
      if (code != 0) {
5610
        mndUserFreeObj(&newUser);
5611
        sdbRelease(pSdb, pUser);
5612
        TAOS_RETURN(code);
5613
      }
5614
    }
5615

5616
    mndUserFreeObj(&newUser);
5617
    sdbRelease(pSdb, pUser);
5618
  }
5619
#endif
5620
  if (pUser != NULL) sdbRelease(pSdb, pUser);
432,691✔
5621
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
432,691✔
5622
  mndUserFreeObj(&newUser);
432,691✔
5623
  TAOS_RETURN(code);
432,691✔
5624
}
5625

5626
int32_t mndUserRemoveView(SMnode *pMnode, STrans *pTrans, char *view) {
×
5627
  int32_t   code = 0;
×
5628
  SSdb     *pSdb = pMnode->pSdb;
×
5629
  int32_t   len = strlen(view) + 1;
×
5630
  void     *pIter = NULL;
×
5631
  SUserObj *pUser = NULL;
×
5632
  SUserObj  newUser = {0};
×
5633
#ifdef PRIV_TODO
5634
  while (1) {
5635
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
5636
    if (pIter == NULL) break;
5637

5638
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
5639
      break;
5640
    }
5641

5642
    bool inRead = (taosHashGet(newUser.readViews, view, len) != NULL);
5643
    bool inWrite = (taosHashGet(newUser.writeViews, view, len) != NULL);
5644
    bool inAlter = (taosHashGet(newUser.alterViews, view, len) != NULL);
5645
    if (inRead || inWrite || inAlter) {
5646
      code = taosHashRemove(newUser.readViews, view, len);
5647
      if (code < 0) {
5648
        mError("failed to remove readViews:%s from user:%s", view, pUser->user);
5649
      }
5650
      code = taosHashRemove(newUser.writeViews, view, len);
5651
      if (code < 0) {
5652
        mError("failed to remove writeViews:%s from user:%s", view, pUser->user);
5653
      }
5654
      code = taosHashRemove(newUser.alterViews, view, len);
5655
      if (code < 0) {
5656
        mError("failed to remove alterViews:%s from user:%s", view, pUser->user);
5657
      }
5658

5659
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
5660
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
5661
        code = TSDB_CODE_OUT_OF_MEMORY;
5662
        break;
5663
      }
5664
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
5665
      if (code < 0) {
5666
        mndUserFreeObj(&newUser);
5667
        sdbRelease(pSdb, pUser);
5668
        TAOS_RETURN(code);
5669
      }
5670
    }
5671

5672
    mndUserFreeObj(&newUser);
5673
    sdbRelease(pSdb, pUser);
5674
  }
5675
#endif
5676
  if (pUser != NULL) sdbRelease(pSdb, pUser);
×
5677
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
×
5678
  mndUserFreeObj(&newUser);
×
5679
  TAOS_RETURN(code);
×
5680
}
5681

5682
int32_t mndUserRemoveTopic(SMnode *pMnode, STrans *pTrans, char *topic) {
94,855✔
5683
  int32_t   code = 0;
94,855✔
5684
  SSdb     *pSdb = pMnode->pSdb;
94,855✔
5685
  int32_t   len = strlen(topic) + 1;
94,855✔
5686
  void     *pIter = NULL;
94,855✔
5687
  SUserObj *pUser = NULL;
94,855✔
5688
  SUserObj  newUser = {0};
94,855✔
5689
#ifdef PRIV_TODO
5690
  while (1) {
5691
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
5692
    if (pIter == NULL) {
5693
      break;
5694
    }
5695

5696
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
5697
      break;
5698
    }
5699

5700
    bool inTopic = (taosHashGet(newUser.topics, topic, len) != NULL);
5701
    if (inTopic) {
5702
      code = taosHashRemove(newUser.topics, topic, len);
5703
      if (code < 0) {
5704
        mError("failed to remove topic:%s from user:%s", topic, pUser->user);
5705
      }
5706
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
5707
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
5708
        code = TSDB_CODE_OUT_OF_MEMORY;
5709
        break;
5710
      }
5711
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
5712
      if (code < 0) {
5713
        mndUserFreeObj(&newUser);
5714
        sdbRelease(pSdb, pUser);
5715
        TAOS_RETURN(code);
5716
      }
5717
    }
5718

5719
    mndUserFreeObj(&newUser);
5720
    sdbRelease(pSdb, pUser);
5721
  }
5722
#endif
5723
  if (pUser != NULL) sdbRelease(pSdb, pUser);
94,855✔
5724
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
94,855✔
5725
  mndUserFreeObj(&newUser);
94,855✔
5726
  TAOS_RETURN(code);
94,855✔
5727
}
5728

5729
int64_t mndGetUserIpWhiteListVer(SMnode *pMnode, SUserObj *pUser) {
×
5730
  // ver = 0, disable ip white list
5731
  // ver > 0, enable ip white list
5732
  return tsEnableWhiteList ? pUser->ipWhiteListVer : 0;
×
5733
}
5734

5735
int64_t mndGetUserTimeWhiteListVer(SMnode *pMnode, SUserObj *pUser) {
×
5736
  // ver = 0, disable datetime white list
5737
  // ver > 0, enable datetime white list
5738
  return tsEnableWhiteList ? pUser->timeWhiteListVer : 0;
×
5739
}
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