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

taosdata / TDengine / #4935

22 Jan 2026 06:38AM UTC coverage: 66.708% (+0.02%) from 66.691%
#4935

push

travis-ci

web-flow
merge: from main to 3.0 #34371

121 of 271 new or added lines in 17 files covered. (44.65%)

9066 existing lines in 149 files now uncovered.

203884 of 305637 relevant lines covered (66.71%)

125811266.68 hits per line

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

68.98
/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() {
395,742✔
163
  _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
395,742✔
164

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

170
  userCache.users = users;
395,742✔
171
  userCache.verIp = 0;
395,742✔
172
  userCache.verTime = 0;
395,742✔
173

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

178

179

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

185
  void *pIter = taosHashIterate(userCache.users, NULL);
395,684✔
186
  while (pIter) {
806,413✔
187
    SCachedUserInfo *pInfo = *(SCachedUserInfo **)pIter;
410,729✔
188
    if (pInfo != NULL) {
410,729✔
189
      taosMemoryFree(pInfo->wlIp);
410,729✔
190
      taosMemoryFree(pInfo->wlTime);
410,729✔
191
      taosMemoryFree(pInfo);
410,729✔
192
    }
193
    pIter = taosHashIterate(userCache.users, pIter);
410,729✔
194
  }
195
  taosHashCleanup(userCache.users);
395,684✔
196

197
  (void)taosThreadRwlockDestroy(&userCache.rw);
395,684✔
198
}
199

200

201

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

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

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

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

224

225

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

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

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

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

241

242

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

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

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

260
  return pInfo;
430,290✔
261
}
262

263

264

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

268
  (void)taosThreadRwlockRdlock(&userCache.rw);
2,270,872✔
269

270
  SCachedUserInfo **ppInfo = taosHashGet(userCache.users, user, userLen);
2,271,235✔
271
  if (ppInfo != NULL && *ppInfo != NULL) {
2,271,235✔
272
    pLoginInfo->lastLoginTime = (*ppInfo)->loginInfo.lastLoginTime;
1,997,130✔
273
    pLoginInfo->failedLoginCount = (*ppInfo)->loginInfo.failedLoginCount;
1,996,796✔
274
    pLoginInfo->lastFailedLoginTime = (*ppInfo)->loginInfo.lastFailedLoginTime;
1,996,729✔
275
  } else {
276
    pLoginInfo->lastLoginTime = taosGetTimestampSec();
274,105✔
277
    pLoginInfo->failedLoginCount = 0;
274,105✔
278
    pLoginInfo->lastFailedLoginTime = 0;
274,105✔
279
  }
280

281
  (void)taosThreadRwlockUnlock(&userCache.rw);
2,270,872✔
282

283
  if (pLoginInfo->lastLoginTime == 0) {
2,271,235✔
284
    pLoginInfo->lastLoginTime = taosGetTimestampSec();
32,350✔
285
  }
286
}
2,271,101✔
287

288

289

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

293
  (void)taosThreadRwlockWrlock(&userCache.rw);
2,266,258✔
294

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

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

305

306

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

312
  if (a == NULL || b == NULL) {
1,026,579✔
313
    return false;
55,432✔
314
  }
315

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

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

329
  return true;
970,643✔
330
}
331

332

333

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

337
  (void)taosThreadRwlockWrlock(&userCache.rw);
1,026,579✔
338

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

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

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

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

372

373

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

377
  SSdb     *pSdb = pMnode->pSdb;
479,181✔
378
  void     *pIter = NULL;
479,181✔
379
  while (1) {
184,965✔
380
    SUserObj *pUser = NULL;
664,146✔
381
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
664,146✔
382
    if (pIter == NULL) {
664,146✔
383
      break;
479,181✔
384
    }
385

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

403
    sdbRelease(pSdb, pUser);
184,965✔
404
  }
405

406
  userCache.verIp++;
479,181✔
407

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

415

416

417
int64_t mndGetIpWhiteListVersion(SMnode *pMnode) {
41,304,612✔
418
  int64_t ver = 0;
41,304,612✔
419
  int32_t code = 0;
41,304,612✔
420

421
  if (mndEnableIpWhiteList(pMnode) != 0 && tsEnableWhiteList) {
41,304,612✔
422
    (void)taosThreadRwlockWrlock(&userCache.rw);
3,659✔
423

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

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

438
  mDebug("ip-white-list on mnode ver: %" PRId64, ver);
41,304,612✔
439
  return ver;
41,304,612✔
440
}
441

442

443

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

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

455
  TAOS_RETURN(code);
479,181✔
456
}
457

458

459

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

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

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

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

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

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

492
  userCache.verTime++;
470,865✔
493

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

501

502

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

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

514
  TAOS_RETURN(code);
470,865✔
515
}
516

517

518

519
int64_t mndGetTimeWhiteListVersion(SMnode *pMnode) {
41,304,612✔
520
  int64_t ver = 0;
41,304,612✔
521
  int32_t code = 0;
41,304,612✔
522

523
  if (mndEnableTimeWhiteList(pMnode) != 0 && tsEnableWhiteList) {
41,304,612✔
524
    (void)taosThreadRwlockWrlock(&userCache.rw);
3,659✔
525

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

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

540
  mDebug("datetime-white-list on mnode ver: %" PRId64, ver);
41,304,612✔
541
  return ver;
41,304,612✔
542
}
543

544

545

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

549
  SSdbTable table = {
395,742✔
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);
395,742✔
562
  mndSetMsgHandle(pMnode, TDMT_MND_ALTER_USER, mndProcessAlterUserReq);
395,742✔
563
  mndSetMsgHandle(pMnode, TDMT_MND_DROP_USER, mndProcessDropUserReq);
395,742✔
564
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_AUTH, mndProcessGetUserAuthReq);
395,742✔
565

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

573
  mndSetMsgHandle(pMnode, TDMT_MND_CREATE_TOTP_SECRET, mndProcessCreateTotpSecretReq);
395,742✔
574
  mndSetMsgHandle(pMnode, TDMT_MND_DROP_TOTP_SECRET, mndProcessDropTotpSecretReq);
395,742✔
575

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

585

586

587
void mndCleanupUser(SMnode *pMnode) {
395,684✔
588
  userCacheCleanup();
395,684✔
589
}
395,684✔
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,417,342✔
616
  int32_t len = 0;
1,417,342✔
617
  for (int i = 0; i < num; i++) {
4,276,468✔
618
    SIpRange *pRange = &range[i];
2,859,126✔
619
    SIpAddr   addr = {0};
2,859,126✔
620
    int32_t code = tIpUintToStr(pRange, &addr);
2,859,126✔
621
    if (code != 0) {
2,859,126✔
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,859,126✔
626
  }
627
  if (len > 0) buf[len - 2] = 0;
1,417,342✔
628
  return len;
1,417,342✔
629
}
630

631

632

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

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

649

650

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

660
  if (a->num != b->num) {
971,147✔
661
    return false;
409✔
662
  }
663
  for (int i = 0; i < a->num; i++) {
2,912,718✔
664
    if (!isIpRangeEqual(&a->pIpRanges[i], &b->pIpRanges[i])) {
1,941,980✔
665
      return false;
×
666
    }
667
  }
668
  return true;
970,738✔
669
}
670

671

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

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

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

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

704

705

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

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

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

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

727

728

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

736
  TAOS_CHECK_GOTO(tStartEncode(&encoder), &lino, _OVER);
2,241,975✔
737
  TAOS_CHECK_GOTO(tEncodeI32(&encoder, pList->num), &lino, _OVER);
4,483,950✔
738

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

744
  tEndEncode(&encoder);
2,241,975✔
745

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

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

762
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
1,489,279✔
763
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &pList->num), &lino, _OVER);
2,978,558✔
764

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

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

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

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

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

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

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

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

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

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

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

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

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

878
#endif
879

880
_error:
336,072✔
881
  if (code != 0) {
336,072✔
882
    taosMemoryFree(*ppWhiteList);
×
883
    *ppWhiteList = NULL;
×
884
    mError("failed to create default ip white list at line %d since %s", __LINE__, tstrerror(code));
×
885
  } else {
886
    memcpy(&(*ppWhiteList)->pIpRanges[0], &v4, sizeof(SIpRange));
336,072✔
887
    memcpy(&(*ppWhiteList)->pIpRanges[1], &v6, sizeof(SIpRange));
336,072✔
888
  }
889
  return 0;
336,072✔
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,417,342✔
896
  int32_t bufLen = pUser->pTimeWhiteList->num * 32 + 8;
1,417,342✔
897
  *buf = taosMemoryCalloc(1, bufLen);
1,417,342✔
898
  if (*buf == NULL) {
1,417,342✔
899
    return 0;
×
900
  }
901

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

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

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

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

928
  return pos;
67,158✔
929
}
930

931

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

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

940
  if (pA->absolute != pB->absolute) {
252✔
941
    return pA->absolute ? 1 : -1;
252✔
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) {
2,142✔
956
  (void)taosqsort(pList->ranges, pList->num, sizeof(SDateTimeWhiteListItem), NULL, compareDateTimeInterval);
2,142✔
957
}
2,142✔
958

959

960

961

962
static void dropOldPasswords(SUserObj *pUser) {
4,739,001✔
963
  if (pUser->numOfPasswords <= pUser->passwordReuseMax) {
4,739,001✔
964
    return;
4,728,472✔
965
  }
966

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

972
  int32_t now = taosGetTimestampSec();
10,529✔
973
  int32_t index = reuseMax;
10,529✔
974
  while(index < pUser->numOfPasswords) {
15,901✔
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,624✔
977
    if (now - expireTime >= pUser->passwordReuseTime) {
5,624✔
978
      break;
252✔
979
    }
980
    index++;
5,372✔
981
  }
982

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

991

992

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

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

1012
  tstrncpy(userObj.user, user, TSDB_USER_LEN);
282,152✔
1013
  tstrncpy(userObj.acct, acct, TSDB_USER_LEN);
282,152✔
1014
  userObj.createdTime = taosGetTimestampMs();
282,152✔
1015
  userObj.updateTime = userObj.createdTime;
282,152✔
1016
  userObj.uid = mndGenerateUid(userObj.user, strlen(userObj.user));
282,152✔
1017
  userObj.sysInfo = 1;
282,152✔
1018
  userObj.enable = 1;
282,152✔
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;
282,152✔
1025

1026
  userObj.ipWhiteListVer = taosGetTimestampMs();
282,152✔
1027
  userObj.timeWhiteListVer = userObj.ipWhiteListVer;
282,152✔
1028
  userObj.connectTime = TSDB_USER_CONNECT_TIME_DEFAULT;
282,152✔
1029
  userObj.connectIdleTime = TSDB_USER_CONNECT_IDLE_TIME_DEFAULT;
282,152✔
1030
  userObj.callPerSession = TSDB_USER_CALL_PER_SESSION_DEFAULT;
282,152✔
1031
  userObj.vnodePerCall = TSDB_USER_VNODE_PER_CALL_DEFAULT;
282,152✔
1032
  userObj.passwordReuseTime = TSDB_USER_PASSWORD_REUSE_TIME_DEFAULT;
282,152✔
1033
  userObj.passwordReuseMax = TSDB_USER_PASSWORD_REUSE_MAX_DEFAULT;
282,152✔
1034
  userObj.passwordLockTime = TSDB_USER_PASSWORD_LOCK_TIME_DEFAULT;
282,152✔
1035
  userObj.sessionPerUser = TSDB_USER_SESSION_PER_USER_DEFAULT;
282,152✔
1036
  userObj.failedLoginAttempts = TSDB_USER_FAILED_LOGIN_ATTEMPTS_DEFAULT;
282,152✔
1037
  userObj.passwordLifeTime = TSDB_USER_PASSWORD_LIFE_TIME_DEFAULT;
282,152✔
1038
  userObj.passwordGraceTime = TSDB_USER_PASSWORD_GRACE_TIME_DEFAULT;
282,152✔
1039
  userObj.inactiveAccountTime = TSDB_USER_INACTIVE_ACCOUNT_TIME_DEFAULT;
282,152✔
1040
  userObj.allowTokenNum = TSDB_USER_ALLOW_TOKEN_NUM_DEFAULT;
282,152✔
1041
  userObj.tokenNum = 0;
282,152✔
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));
282,152✔
1066
  if (userObj.pTimeWhiteList == NULL) {
282,152✔
1067
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _ERROR);
×
1068
  }
1069
  
1070
  TAOS_CHECK_GOTO(createDefaultIpWhiteList(&userObj.pIpWhiteListDual), &lino, _ERROR);
282,152✔
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) {
282,152✔
1073
    userObj.superUser = 1;
282,152✔
1074
    userObj.createdb = 1;
282,152✔
1075
    userObj.sessionPerUser = -1;
282,152✔
1076
    userObj.callPerSession = -1;
282,152✔
1077
    userObj.vnodePerCall = -1;
282,152✔
1078
    userObj.failedLoginAttempts = -1;
282,152✔
1079
    userObj.passwordGraceTime = -1;
282,152✔
1080
    userObj.inactiveAccountTime = -1;
282,152✔
1081
    userObj.allowTokenNum = -1;
282,152✔
1082
  }
1083

1084
  userObj.roles = taosHashInit(1, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
282,152✔
1085
  if (userObj.roles == NULL) {
282,152✔
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)) ||
564,304✔
1090
      (code = taosHashPut(userObj.roles, TSDB_ROLE_SYSSEC, strlen(TSDB_ROLE_SYSSEC) + 1, NULL, 0)) ||
564,304✔
1091
      (code = taosHashPut(userObj.roles, TSDB_ROLE_SYSAUDIT, strlen(TSDB_ROLE_SYSAUDIT) + 1, NULL, 0))) {
282,152✔
1092
    TAOS_CHECK_GOTO(code, &lino, _ERROR);
×
1093
  }
1094

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

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

1101
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_ROLE, NULL, "create-user");
282,152✔
1102
  if (pTrans == NULL) {
282,152✔
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);
282,152✔
1108

1109
  if (mndTransAppendCommitlog(pTrans, pRaw) != 0) {
282,152✔
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);
282,152✔
1115

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

1122
  mndTransDrop(pTrans);
282,152✔
1123
  mndUserFreeObj(&userObj);
282,152✔
1124
  return 0;
282,152✔
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) {
282,152✔
1136
  return mndCreateDefaultUser(pMnode, TSDB_DEFAULT_USER, TSDB_DEFAULT_USER, TSDB_DEFAULT_PASS);
282,152✔
1137
}
1138

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

1146
  TAOS_CHECK_EXIT(tStartEncode(&encoder));
4,483,950✔
1147
  TAOS_CHECK_EXIT(tEncodeI64v(&encoder, pObj->uid));
8,967,900✔
1148

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

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

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

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

1164
    uint8_t flag = *(int8_t *)pIter;
8,662,336✔
1165
    TAOS_CHECK_EXIT(tEncodeU8(&encoder, flag));  // value: 0 reset, 1 set(default)
17,324,672✔
1166
  }
1167

1168
  tEndEncode(&encoder);
4,483,950✔
1169
  tlen = encoder.pos;
4,483,950✔
1170
_exit:
4,483,950✔
1171
  tEncoderClear(&encoder);
4,483,950✔
1172
  if (code < 0) {
4,483,950✔
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,483,950✔
1178
}
1179

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

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

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

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

1240
  char *stb = NULL;
2,241,975✔
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,241,975✔
1336
  if (sizeExt < 0) {
2,241,975✔
1337
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1338
  }
1339
  size += sizeExt;
2,241,975✔
1340

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

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

1349
  dropOldPasswords(pUser);
2,241,975✔
1350
  SDB_SET_INT32(pRaw, dataPos, pUser->numOfPasswords, _OVER)
2,241,975✔
1351
  for (int32_t i = 0; i < pUser->numOfPasswords; i++) {
5,190,343✔
1352
    SDB_SET_BINARY(pRaw, dataPos, pUser->passwords[i].pass, sizeof(pUser->passwords[i].pass), _OVER)
2,948,368✔
1353
    SDB_SET_INT32(pRaw, dataPos, pUser->passwords[i].setTime, _OVER)
2,948,368✔
1354
  }
1355
  SDB_SET_BINARY(pRaw, dataPos, pUser->salt, sizeof(pUser->salt), _OVER)
2,241,975✔
1356

1357
  SDB_SET_BINARY(pRaw, dataPos, pUser->acct, TSDB_USER_LEN, _OVER)
2,241,975✔
1358
  SDB_SET_INT64(pRaw, dataPos, pUser->createdTime, _OVER)
2,241,975✔
1359
  SDB_SET_INT64(pRaw, dataPos, pUser->updateTime, _OVER)
2,241,975✔
1360
  SDB_SET_INT8(pRaw, dataPos, pUser->superUser, _OVER)
2,241,975✔
1361
  SDB_SET_INT8(pRaw, dataPos, pUser->sysInfo, _OVER)
2,241,975✔
1362
  SDB_SET_INT8(pRaw, dataPos, pUser->enable, _OVER)
2,241,975✔
1363
  SDB_SET_UINT8(pRaw, dataPos, pUser->flag, _OVER)
2,241,975✔
1364
  SDB_SET_INT32(pRaw, dataPos, pUser->authVersion, _OVER)
2,241,975✔
1365
  SDB_SET_INT32(pRaw, dataPos, pUser->passVersion, _OVER)
2,241,975✔
1366
  SDB_SET_INT32(pRaw, dataPos, numOfReadDbs, _OVER)
2,241,975✔
1367
  SDB_SET_INT32(pRaw, dataPos, numOfWriteDbs, _OVER)
2,241,975✔
1368
  SDB_SET_INT32(pRaw, dataPos, numOfTopics, _OVER)
2,241,975✔
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,241,975✔
1388
  SDB_SET_INT32(pRaw, dataPos, numOfWriteTbs, _OVER)
2,241,975✔
1389
  SDB_SET_INT32(pRaw, dataPos, numOfAlterTbs, _OVER)
2,241,975✔
1390
  SDB_SET_INT32(pRaw, dataPos, numOfReadViews, _OVER)
2,241,975✔
1391
  SDB_SET_INT32(pRaw, dataPos, numOfWriteViews, _OVER)
2,241,975✔
1392
  SDB_SET_INT32(pRaw, dataPos, numOfAlterViews, _OVER)
2,241,975✔
1393
  SDB_SET_INT32(pRaw, dataPos, numOfUseDbs, _OVER)
2,241,975✔
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,241,975✔
1492
  int32_t tlen = sizeof(SIpWhiteListDual) + num * sizeof(SIpRange) + 4;
2,241,975✔
1493
  int32_t maxBufLen = TMAX(tlen, sizeExt);
2,241,975✔
1494
  if ((buf = taosMemoryCalloc(1, maxBufLen)) == NULL) {
2,241,975✔
1495
    TAOS_CHECK_GOTO(terrno, NULL, _OVER);
×
1496
  }
1497
  int32_t len = 0;
2,241,975✔
1498
  TAOS_CHECK_GOTO(tSerializeIpWhiteList(buf, tlen, pUser->pIpWhiteListDual, &len), &lino, _OVER);
2,241,975✔
1499

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

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

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

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

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

1539
  SDB_SET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
2,241,975✔
1540

1541
  SDB_SET_DATALEN(pRaw, dataPos, _OVER)
2,241,975✔
1542

1543
_OVER:
2,241,975✔
1544
  taosMemoryFree(buf);
2,241,975✔
1545
  if (code < 0) {
2,241,975✔
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,241,975✔
1554
  return pRaw;
2,241,975✔
1555
}
1556

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

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

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

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

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

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

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

1598
  if (sver < USER_VER_SUPPORT_ADVANCED_SECURITY) {
1,489,279✔
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,489,279✔
1608
    pUser->passwords = taosMemoryCalloc(pUser->numOfPasswords, sizeof(SUserPassword));
1,489,279✔
1609
    if (pUser->passwords == NULL) {
1,489,279✔
1610
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
1611
    }
1612
    for (int32_t i = 0; i < pUser->numOfPasswords; ++i) {
3,645,233✔
1613
      SDB_GET_BINARY(pRaw, dataPos, pUser->passwords[i].pass, sizeof(pUser->passwords[i].pass), _OVER);
2,155,954✔
1614
      SDB_GET_INT32(pRaw, dataPos, &pUser->passwords[i].setTime, _OVER);
2,155,954✔
1615
    }
1616
    SDB_GET_BINARY(pRaw, dataPos, pUser->salt, sizeof(pUser->salt), _OVER)
1,489,279✔
1617
  }
1618
  
1619
  SDB_GET_BINARY(pRaw, dataPos, pUser->acct, TSDB_USER_LEN, _OVER)
1,489,279✔
1620
  SDB_GET_INT64(pRaw, dataPos, &pUser->createdTime, _OVER)
1,489,279✔
1621
  SDB_GET_INT64(pRaw, dataPos, &pUser->updateTime, _OVER)
1,489,279✔
1622
  if (sver < USER_VER_SUPPORT_ADVANCED_SECURITY) {
1,489,279✔
1623
    pUser->passwords[0].setTime = (int32_t)(pUser->updateTime / 1000);
×
1624
  }
1625

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

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

1645
  if (numOfReadDbs > 0) {
1,489,279✔
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,489,279✔
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,489,279✔
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,489,279✔
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,489,279✔
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,489,279✔
1678
    for (int32_t i = 0; i < numOfTopics; ++i) {
1,489,279✔
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,489,279✔
1687
    int32_t numOfReadTbs = 0;
1,489,279✔
1688
    int32_t numOfWriteTbs = 0;
1,489,279✔
1689
    int32_t numOfAlterTbs = 0;
1,489,279✔
1690
    int32_t numOfReadViews = 0;
1,489,279✔
1691
    int32_t numOfWriteViews = 0;
1,489,279✔
1692
    int32_t numOfAlterViews = 0;
1,489,279✔
1693
    int32_t numOfUseDbs = 0;
1,489,279✔
1694
    SDB_GET_INT32(pRaw, dataPos, &numOfReadTbs, _OVER)
1,489,279✔
1695
    SDB_GET_INT32(pRaw, dataPos, &numOfWriteTbs, _OVER)
1,489,279✔
1696
    if (sver >= 6) {
1,489,279✔
1697
      SDB_GET_INT32(pRaw, dataPos, &numOfAlterTbs, _OVER)
1,489,279✔
1698
      SDB_GET_INT32(pRaw, dataPos, &numOfReadViews, _OVER)
1,489,279✔
1699
      SDB_GET_INT32(pRaw, dataPos, &numOfWriteViews, _OVER)
1,489,279✔
1700
      SDB_GET_INT32(pRaw, dataPos, &numOfAlterViews, _OVER)
1,489,279✔
1701
    }
1702
    SDB_GET_INT32(pRaw, dataPos, &numOfUseDbs, _OVER)
1,489,279✔
1703

1704
    if (numOfReadTbs > 0) {
1,489,279✔
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,489,279✔
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,489,279✔
1717
    pReadViews = taosHashInit(numOfReadViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,489,279✔
1718
    pWriteViews =
1719
        taosHashInit(numOfWriteViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,489,279✔
1720
    pAlterViews =
1721
        taosHashInit(numOfAlterViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,489,279✔
1722
    pUseDbs = taosHashInit(numOfUseDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
1,489,279✔
1723

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

1729
    for (int32_t i = 0; i < numOfReadTbs; ++i) {
1,489,279✔
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,489,279✔
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,489,279✔
1776
      for (int32_t i = 0; i < numOfAlterTbs; ++i) {
1,489,279✔
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,489,279✔
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,489,279✔
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,489,279✔
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,489,279✔
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,489,279✔
1888
    if (sver < USER_VER_SUPPORT_WHITELIT_DUAL_STACK) {
1,489,279✔
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,489,279✔
1912
      int32_t len = 0;
1,489,279✔
1913
      SDB_GET_INT32(pRaw, dataPos, &len, _OVER);
1,489,279✔
1914

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

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

1926
  if (pUser->pIpWhiteListDual == NULL) {
1,489,279✔
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,489,279✔
1932

1933
  if (sver < USER_VER_SUPPORT_ADVANCED_SECURITY) {
1,489,279✔
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,489,279✔
1955
    SDB_GET_INT8(pRaw, dataPos, &pUser->changePass, _OVER);
1,489,279✔
1956
    SDB_GET_INT32(pRaw, dataPos, &pUser->sessionPerUser, _OVER);
1,489,279✔
1957
    SDB_GET_INT32(pRaw, dataPos, &pUser->connectTime, _OVER);
1,489,279✔
1958
    SDB_GET_INT32(pRaw, dataPos, &pUser->connectIdleTime, _OVER);
1,489,279✔
1959
    SDB_GET_INT32(pRaw, dataPos, &pUser->callPerSession, _OVER);
1,489,279✔
1960
    SDB_GET_INT32(pRaw, dataPos, &pUser->vnodePerCall, _OVER);
1,489,279✔
1961
    SDB_GET_INT32(pRaw, dataPos, &pUser->failedLoginAttempts, _OVER);
1,489,279✔
1962
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordLifeTime, _OVER);
1,489,279✔
1963
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordReuseTime, _OVER);
1,489,279✔
1964
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordReuseMax, _OVER);
1,489,279✔
1965
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordLockTime, _OVER);
1,489,279✔
1966
    SDB_GET_INT32(pRaw, dataPos, &pUser->passwordGraceTime, _OVER);
1,489,279✔
1967
    SDB_GET_INT32(pRaw, dataPos, &pUser->inactiveAccountTime, _OVER);
1,489,279✔
1968
    SDB_GET_INT32(pRaw, dataPos, &pUser->allowTokenNum, _OVER);
1,489,279✔
1969
    SDB_GET_INT32(pRaw, dataPos, &pUser->tokenNum, _OVER);
1,489,279✔
1970

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

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

1987
    int32_t extLen = 0;
1,489,279✔
1988
    SDB_GET_INT32(pRaw, dataPos, &extLen, _OVER);
1,489,279✔
1989
    TAOS_MEMORY_REALLOC(key, extLen);
1,489,279✔
1990
    if (key == NULL) {
1,489,279✔
1991
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1992
    }
1993
    SDB_GET_BINARY(pRaw, dataPos, key, extLen, _OVER);
1,489,279✔
1994
    TAOS_CHECK_GOTO(tDeserializeUserObjExt(key, extLen, pUser), &lino, _OVER);
1,489,279✔
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,489,279✔
2017

2018
  taosInitRWLatch(&pUser->lock);
1,489,279✔
2019
  dropOldPasswords(pUser);
1,489,279✔
2020
  // TODO: migrate legacy privileges to new hash tables
2021
_OVER:
1,489,279✔
2022
  taosMemoryFree(key);
1,489,279✔
2023
  taosMemoryFree(value);
1,489,279✔
2024
  taosHashCleanup(pReadDbs);
1,489,279✔
2025
  taosHashCleanup(pWriteDbs);
1,489,279✔
2026
  taosHashCleanup(pTopics);
1,489,279✔
2027
  taosHashCleanup(pReadTbs);
1,489,279✔
2028
  taosHashCleanup(pWriteTbs);
1,489,279✔
2029
  taosHashCleanup(pAlterTbs);
1,489,279✔
2030
  taosHashCleanup(pReadViews);
1,489,279✔
2031
  taosHashCleanup(pWriteViews);
1,489,279✔
2032
  taosHashCleanup(pAlterViews);
1,489,279✔
2033
  taosHashCleanup(pUseDbs);
1,489,279✔
2034
  if (code < 0) {
1,489,279✔
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,489,279✔
2046
  return pRow;
1,489,279✔
2047
}
2048

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

2052
  SAcctObj *pAcct = sdbAcquire(pSdb, SDB_ACCT, pUser->acct);
455,889✔
2053
  if (pAcct == NULL) {
455,889✔
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;
455,889✔
2059
  sdbRelease(pSdb, pAcct);
455,889✔
2060

2061
  return 0;
455,889✔
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,008,955✔
2114
  if (!(*ppNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true,
1,008,955✔
2115
                              HASH_ENTRY_LOCK))) {
2116
    TAOS_RETURN(terrno);
×
2117
  }
2118

2119
  int32_t  code = 0;
1,008,955✔
2120
  uint8_t *flag = NULL;
1,008,955✔
2121
  while ((flag = taosHashIterate(pOld, flag))) {
2,024,707✔
2122
    size_t keyLen = 0;
1,015,752✔
2123
    char  *key = taosHashGetKey(flag, &keyLen);
1,015,752✔
2124

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

2132
  TAOS_RETURN(code);
1,008,955✔
2133
}
2134

2135
int32_t mndMergePrivObjHash(SHashObj *pOld, SHashObj **ppNew) {
77,517,442✔
2136
  if (!(*ppNew)) return mndDupPrivObjHash(pOld, ppNew);
77,517,442✔
2137

2138
  int32_t           code = 0, lino = 0;
77,517,533✔
2139
  SHashObj         *pNew = *ppNew;
77,517,533✔
2140
  SPrivObjPolicies *policies = NULL;
77,517,533✔
2141
  while ((policies = taosHashIterate(pOld, policies))) {
723,377,169✔
2142
    size_t klen = 0;
645,865,479✔
2143
    char  *key = taosHashGetKey(policies, &klen);
645,865,479✔
2144
    size_t vlen = taosHashGetValueSize(policies);
645,864,776✔
2145

2146
    SPrivObjPolicies *pNewPolicies = taosHashGet(pNew, key, klen);
645,864,776✔
2147
    if (pNewPolicies) {
645,864,802✔
2148
      size_t newVlen = taosHashGetValueSize(pNewPolicies);
411,458,752✔
2149
      if (newVlen > 0 && vlen > 0) {
411,458,752✔
2150
        privAddSet(&pNewPolicies->policy, &policies->policy);
411,458,049✔
2151
      }
2152
      continue;
411,454,155✔
2153
    }
2154

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

2163
  TAOS_RETURN(code);
77,518,098✔
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) {
232,555,092✔
2171
  if (!(*ppNew)) return mndDupPrivTblHash(pOld, ppNew, false);
232,555,092✔
2172

2173
  int32_t           code = 0, lino = 0;
232,555,092✔
2174
  SHashObj         *pNew = *ppNew;
232,555,092✔
2175
  SPrivTblPolicies *policies = NULL;
232,555,185✔
2176
  while ((policies = taosHashIterate(pOld, policies))) {
232,555,185✔
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:
232,555,864✔
2207
  TAOS_RETURN(code);
232,555,864✔
2208
}
2209

2210
int32_t mndDupPrivObjHash(SHashObj *pOld, SHashObj **ppNew) {
27,094,585✔
2211
  if (!(*ppNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true,
27,094,585✔
2212
                             HASH_ENTRY_LOCK))) {
2213
    TAOS_RETURN(terrno);
×
2214
  }
2215
  int32_t           code = 0;
27,094,709✔
2216
  SPrivObjPolicies *policies = NULL;
27,094,709✔
2217
  while ((policies = taosHashIterate(pOld, policies))) {
29,845,168✔
2218
    size_t klen = 0;
2,750,459✔
2219
    char  *key = taosHashGetKey(policies, &klen);
2,750,459✔
2220
    size_t vlen = taosHashGetValueSize(policies);
2,750,459✔
2221

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

2229
  TAOS_RETURN(code);
27,094,202✔
2230
}
2231

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

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

2255
_exit:
82,292,484✔
2256
  if (code != 0) {
82,292,484✔
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);
82,292,484✔
2266
}
2267

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

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

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

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

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

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

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

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

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

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

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

2388
  taosWUnLockLatch(&pOld->lock);
1,010,599✔
2389

2390
  return 0;
1,010,599✔
2391
}
2392

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

2397
  *ppUser = sdbAcquire(pSdb, SDB_USER, userName);
84,310,139✔
2398
  if (*ppUser == NULL) {
84,310,515✔
2399
    if (terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
59,930✔
2400
      code = TSDB_CODE_MND_USER_NOT_EXIST;
59,930✔
2401
    } else {
2402
      code = TSDB_CODE_MND_USER_NOT_AVAILABLE;
×
2403
    }
2404
  }
2405
  TAOS_RETURN(code);
84,310,547✔
2406
}
2407

2408
void mndReleaseUser(SMnode *pMnode, SUserObj *pUser) {
91,369,398✔
2409
  SSdb *pSdb = pMnode->pSdb;
91,369,398✔
2410
  sdbRelease(pSdb, pUser);
91,369,402✔
2411
}
91,369,577✔
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) {
476,372✔
2426
  int32_t    code = 0;
476,372✔
2427
  void      *pIter = NULL;
476,372✔
2428
  SUserObj  *pObj;
476,372✔
2429
  SSHashObj *pHash = NULL;
476,372✔
2430

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

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

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

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

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

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

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

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

2481
  return 0;
65✔
2482
}
2483

2484

2485

2486
static void generateSalt(char *salt, size_t len) {
55,432✔
2487
  const char* set = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
55,432✔
2488
  int32_t     setLen = 62;
55,432✔
2489
  for (int32_t i = 0; i < len - 1; ++i) {
1,773,824✔
2490
    salt[i] = set[taosSafeRand() % setLen];
1,718,392✔
2491
  }
2492
  salt[len - 1] = 0;
55,432✔
2493
}
55,432✔
2494

2495

2496

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

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

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

2509
  if (enableIpv6) {
1,354✔
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,354✔
2517
  if (code != 0) {
1,354✔
2518
    mError("failed to add default ip range to table since %s", tstrerror(code));
×
2519
  }
2520
  return code;
1,354✔
2521
}
2522

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

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

2534
  if (pCreate->isImport == 1) {
55,274✔
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));
55,274✔
2539
    taosEncryptPass_c((uint8_t *)pCreate->pass, strlen(pCreate->pass), userObj.passwords[0].pass);
55,274✔
2540
    userObj.passwords[0].pass[sizeof(userObj.passwords[0].pass) - 1] = 0;
55,274✔
2541
    TAOS_CHECK_GOTO(mndEncryptPass(userObj.passwords[0].pass, userObj.salt, &userObj.passEncryptAlgorithm), &lino, _OVER);
55,274✔
2542
  }
2543
  userObj.passwords[0].setTime = taosGetTimestampSec();
55,274✔
2544

2545
  tstrncpy(userObj.user, pCreate->user, TSDB_USER_LEN);
55,274✔
2546
  tstrncpy(userObj.acct, acct, TSDB_USER_LEN);
55,274✔
2547
  if (pCreate->totpseed[0] != 0) {
55,274✔
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();
55,274✔
2555
  userObj.updateTime = userObj.createdTime;
55,274✔
2556
  userObj.superUser = 0;  // pCreate->superUser;
55,274✔
2557
  userObj.sysInfo = pCreate->sysInfo;
55,274✔
2558
  userObj.enable = pCreate->enable;
55,274✔
2559
  userObj.createdb = pCreate->createDb;
55,274✔
2560
  userObj.uid = mndGenerateUid(userObj.user, strlen(userObj.user));
55,274✔
2561

2562
#ifdef TD_ENTERPRISE
2563

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

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

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

2604
    if (taosHashGetSize(pUniqueTab) > MND_MAX_USER_IP_RANGE) {
1,354✔
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,354✔
2610
    SIpWhiteListDual *p = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + numOfRanges * sizeof(SIpRange));
1,354✔
2611
    if (p == NULL) {
1,354✔
2612
      taosHashCleanup(pUniqueTab);
×
2613
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2614
    }
2615

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

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

2630
  if (pCreate->numTimeRanges == 0) {
55,274✔
2631
    userObj.pTimeWhiteList = (SDateTimeWhiteList*)taosMemoryCalloc(1, sizeof(SDateTimeWhiteList));
53,636✔
2632
    if (userObj.pTimeWhiteList == NULL) {
53,636✔
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,638✔
2637
    if (pUniqueTab == NULL) {
1,638✔
2638
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2639
    }
2640
    
2641
    for (int i = 0; i < pCreate->numTimeRanges; i++) {
3,654✔
2642
      SDateTimeRange* src = pCreate->pTimeRanges + i;
2,016✔
2643
      SDateTimeWhiteListItem range = {0};
2,016✔
2644
      DateTimeRangeToWhiteListItem(&range, src);
2,016✔
2645

2646
      // no need to add expired range
2647
      if (isDateTimeWhiteListItemExpired(&range)) {
2,016✔
2648
        continue;
252✔
2649
      }
2650

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

2658
    if (taosHashGetSize(pUniqueTab) > MND_MAX_USER_TIME_RANGE) {
1,638✔
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,638✔
2664
    SDateTimeWhiteList *p = taosMemoryCalloc(1, sizeof(SDateTimeWhiteList) + numOfRanges * sizeof(SDateTimeWhiteListItem));
1,638✔
2665
    if (p == NULL) {
1,638✔
2666
      taosHashCleanup(pUniqueTab);
×
2667
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2668
    }
2669

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

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

2684
  userObj.ipWhiteListVer = taosGetTimestampMs();
55,274✔
2685
  userObj.timeWhiteListVer = userObj.ipWhiteListVer;
55,274✔
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);
55,274✔
2717
  if (userObj.roles == NULL) {
55,274✔
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) {
55,274✔
2722
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2723
  }
2724

2725
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "create-user");
55,274✔
2726
  if (pTrans == NULL) {
55,274✔
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);
55,274✔
2731

2732
  SSdbRaw *pCommitRaw = mndUserActionEncode(&userObj);
55,274✔
2733
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
55,274✔
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);
55,274✔
2739

2740
  if (mndTransPrepare(pMnode, pTrans) != 0) {
55,274✔
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) {
55,274✔
2747
    mndTransDrop(pTrans);
×
2748
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2749
  }
2750

2751
  mndTransDrop(pTrans);
55,274✔
2752

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

2758

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

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

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

2778
  if (taosIsComplexString(pwd)) {
73,185✔
2779
    return 0;
73,185✔
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) {
436✔
2854
  (void)taosThreadRwlockRdlock(&userCache.rw);
436✔
2855
  
2856
  int32_t count = taosHashGetSize(userCache.users);
436✔
2857
  pRsp->pUsers = taosMemoryCalloc(count, sizeof(SUserDateTimeWhiteList));
436✔
2858
  if (pRsp->pUsers == NULL) {
436✔
2859
    (void)taosThreadRwlockUnlock(&userCache.rw);
×
2860
    TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
2861
  }
2862

2863
  count = 0;
436✔
2864
  void   *pIter = taosHashIterate(userCache.users, NULL);
436✔
2865
  while (pIter) {
872✔
2866
    SDateTimeWhiteList *wl = (*(SCachedUserInfo **)pIter)->wlTime;
436✔
2867
    if (wl == NULL || wl->num <= 0) {
436✔
2868
      pIter = taosHashIterate(userCache.users, pIter);
436✔
2869
      continue;
436✔
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;
436✔
2892
  pRsp->ver = userCache.verTime;
436✔
2893
  (void)taosThreadRwlockUnlock(&userCache.rw);
436✔
2894
  TAOS_RETURN(0);
436✔
2895
}
2896

2897

2898

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

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

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

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

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

2929
_OVER:
436✔
2930
  if (code < 0) {
436✔
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;
436✔
2937
  pReq->info.rsp = pRsp;
436✔
2938
  pReq->info.rspLen = len;
436✔
2939

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

2944

2945

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

2956
  if (tDeserializeSCreateUserReq(pReq->pCont, pReq->contLen, &createReq) != 0) {
55,274✔
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);
55,274✔
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);
55,274✔
2968
  if (pOperUser == NULL) {
55,274✔
2969
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_USER_FROM_CONN, &lino, _OVER);
×
2970
  }
2971

2972
  if (createReq.isImport != 1) {
55,274✔
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);
55,274✔
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) {
55,274✔
2981
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
2982
  }
2983

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

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

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

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

3004
  TAOS_CHECK_GOTO(grantCheck(TSDB_GRANT_USER), &lino, _OVER);
55,274✔
3005

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

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

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

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

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

3038
  TAOS_RETURN(code);
55,274✔
3039
}
3040

3041

3042

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

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

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

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

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

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

3085
_OVER:
9,714✔
3086
  mndReleaseUser(pMnode, pUser);
9,714✔
3087
  tFreeSGetUserIpWhiteListDualRsp(&wlRsp);
9,714✔
3088
  if (code < 0) {
9,714✔
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,714✔
3095
  pReq->info.rsp = pRsp;
9,714✔
3096
  pReq->info.rspLen = contLen;
9,714✔
3097

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

3101

3102

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

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

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

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

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

3129
    pUser->numOfRange = wl->num;
436✔
3130
    pUser->pIpRanges = taosMemoryCalloc(wl->num, sizeof(SIpRange));
436✔
3131
    if (pUser->pIpRanges == NULL) {
436✔
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));
436✔
3137
    count++;
436✔
3138
    pIter = taosHashIterate(userCache.users, pIter);
436✔
3139
  }
3140

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

3147

3148

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

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

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

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

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

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

3186
_OVER:
436✔
3187
  if (code < 0) {
436✔
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;
436✔
3194
  pReq->info.rsp = pRsp;
436✔
3195
  pReq->info.rspLen = len;
436✔
3196

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

3201
static int32_t mndAlterUser(SMnode *pMnode, SUserObj *pNew, SRpcMsg *pReq) {
971,305✔
3202
  int32_t code = 0, lino = 0;
971,305✔
3203
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "alter-user");
971,305✔
3204
  if (pTrans == NULL) {
971,305✔
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);
971,305✔
3209

3210
  SSdbRaw *pCommitRaw = mndUserActionEncode(pNew);
971,305✔
3211
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
971,305✔
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));
971,305✔
3217

3218
  if (mndTransPrepare(pMnode, pTrans) != 0) {
971,305✔
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) {
971,305✔
3224
    mndTransDrop(pTrans);
×
3225
    TAOS_RETURN(code);
×
3226
  }
3227
_exit:
971,305✔
3228
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
971,305✔
3229
    mError("user:%s, failed to alter at line %d since %s", pNew->user, lino, tstrerror(code));
×
3230
  }
3231
  mndTransDrop(pTrans);
971,305✔
3232
  TAOS_RETURN(code);
971,305✔
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) {
946,599✔
3565
  SMnode   *pMnode = pReq->info.node;
946,599✔
3566
  SSdb     *pSdb = pMnode->pSdb;
946,599✔
3567
  void     *pIter = NULL;
946,599✔
3568
  int32_t   code = 0, lino = 0;
946,599✔
3569
  SUserObj *pUser = NULL;
946,599✔
3570
  SUserObj  newUser = {0};
946,599✔
3571

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

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

3578
  if (pAlterReq->alterType == TSDB_ALTER_ROLE_PRIVILEGES) {
945,655✔
3579
#ifdef TD_ENTERPRISE
3580
    TAOS_CHECK_EXIT(mndUserDupObj(pUser, &newUser));
942,305✔
3581
    if ((code = mndAlterUserPrivInfo(pMnode, pOperUser, pUser, &newUser, pAlterReq)) == TSDB_CODE_QRY_DUPLICATED_OPERATION) {
942,305✔
3582
      code = 0;
×
3583
      goto _exit;
×
3584
    } else {
3585
      TAOS_CHECK_EXIT(code);
942,305✔
3586
    }
3587
  } else if (pAlterReq->alterType == TSDB_ALTER_ROLE_ROLE) {
3,350✔
3588
    if ((code = mndAlterUserRoleInfo(pMnode, pOperUser, pUser, &newUser, pAlterReq)) == TSDB_CODE_QRY_DUPLICATED_OPERATION) {
3,350✔
3589
      code = 0;
151✔
3590
      goto _exit;
151✔
3591
    } else {
3592
      TAOS_CHECK_EXIT(code);
3,199✔
3593
    }
3594
#endif
3595
  } else {
3596
    TAOS_CHECK_EXIT(TSDB_CODE_INVALID_MSG);
×
3597
  }
3598
  code = mndAlterUser(pMnode, &newUser, pReq);
945,051✔
3599
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
945,051✔
3600

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

3610

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

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

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

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

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

3662
  if (pAlterReq->hasTotpseed) {
25,974✔
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,974✔
3673
    auditLen += tsnprintf(auditLog + auditLen, sizeof(auditLog) - auditLen, "enable:%d,", pAlterReq->enable);
905✔
3674

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

3763
  if (pAlterReq->numDropIpRanges > 0 || pAlterReq->numIpRanges > 0) {
25,974✔
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,107✔
3773
      SIpRange range;
1,541✔
3774
      copyIpRange(&range, newUser.pIpWhiteListDual->pIpRanges + i);
1,541✔
3775
      code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
1,541✔
3776
      if (code != 0) {
1,541✔
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++) {
692✔
3786
        if (taosHashGetSize(m) == 0) {
409✔
3787
          break;
×
3788
        }
3789

3790
        SIpRange range;
409✔
3791
        copyIpRange(&range, pAlterReq->pDropIpRanges + i);
409✔
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));
409✔
3797
        if (code == TSDB_CODE_NOT_FOUND) {
409✔
3798
          // treat not exist as success
3799
          code = 0;
157✔
3800
        }
3801
        if (code != 0) {
409✔
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++) {
692✔
3811
        SIpRange range;
409✔
3812
        copyIpRange(&range, pAlterReq->pIpRanges + i);
409✔
3813
        code = taosHashPut(m, &range, sizeof(range), &dummy, sizeof(dummy));
409✔
3814
        if (code != 0) {
409✔
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,974✔
3854
    int32_t dummy = 0;
504✔
3855

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

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

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

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

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

3911
    int32_t numOfRanges = taosHashGetSize(m);
504✔
3912
    if (numOfRanges > MND_MAX_USER_TIME_RANGE) {
504✔
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));
504✔
3918
    if (p == NULL) {
504✔
3919
      taosHashCleanup(m);
×
3920
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3921
    }
3922

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

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

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

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

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

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

3965

3966

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

3970
  int32_t code = tDeserializeSAlterUserReq(pReq->pCont, pReq->contLen, &alterReq);
28,691✔
3971
  if (code != 0) {
28,691✔
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,691✔
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,691✔
3983
  if (alterReq.alterType == TSDB_ALTER_USER_BASIC_INFO) {
28,691✔
3984
    code = mndProcessAlterUserBasicInfoReq(pReq, &alterReq);
28,691✔
3985
  } else {
3986
    // code = mndProcessAlterUserPrivilegesReq(pReq, &alterReq); // obsolete
3987
  }
3988

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

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

3998
static int32_t mndDropUser(SMnode *pMnode, SRpcMsg *pReq, SUserObj *pUser) {
19,561✔
3999
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_ROLE, pReq, "drop-user");
19,561✔
4000
  if (pTrans == NULL) {
19,561✔
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,561✔
4005

4006
  SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
19,561✔
4007
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
19,561✔
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,561✔
4013
    mndTransDrop(pTrans);
×
4014
    TAOS_RETURN(terrno);
×
4015
  }
4016

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

4022
  if (mndTransPrepare(pMnode, pTrans) != 0) {
19,561✔
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,561✔
4029
  mndDropCachedTokensByUser(pUser->user);
19,561✔
4030

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

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

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

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

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

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

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

4058
  code = mndAcquireUser(pMnode, RPC_MSG_USER(pReq), &pOperUser);
19,561✔
4059
  if (pOperUser == NULL) {
19,561✔
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,561✔
4065

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

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

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

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

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

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

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

4104
  TAOS_CHECK_EXIT(mndSetUserAuthRsp(pMnode, pUser, &authRsp));
5,568,453✔
4105

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

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

4120
_exit:
5,568,453✔
4121
  mndReleaseUser(pMnode, pUser);
5,568,453✔
4122
  tFreeSGetUserAuthRsp(&authRsp);
5,568,453✔
4123
  if (code < 0) {
5,568,453✔
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,568,453✔
4130
  pReq->info.rspLen = contLen;
5,568,453✔
4131
  pReq->code = code;
5,568,453✔
4132

4133
  TAOS_RETURN(code);
5,568,453✔
4134
}
4135

4136

4137

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

4142
  // process all input bytes
4143
  for (int i = 0; i < inLen; i++) {
514,140✔
4144
    buffer = (buffer << 8) | in[i];
498,560✔
4145
    bits += 8;
498,560✔
4146

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

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

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

4163

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

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

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

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

4180
  if (tSerializeSCreateTotpSecretRsp(pData, len, &rsp) != len) {
15,580✔
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,580✔
4186
  if (pTrans == NULL) {
15,580✔
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,580✔
4192

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

4195
  SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
15,580✔
4196
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
15,580✔
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,580✔
4202
    mndTransDrop(pTrans);
×
4203
    TAOS_RETURN(terrno);
×
4204
  }
4205

4206
  if (mndTransPrepare(pMnode, pTrans) != 0) {
15,580✔
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,580✔
4213
  TAOS_RETURN(0);
15,580✔
4214
}
4215

4216

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

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

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

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

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

4250

4251

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

4261

4262

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

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

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

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

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

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

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

4301

4302

4303
bool mndIsTotpEnabledUser(SUserObj *pUser) {
3,684,525✔
4304
  for (int32_t i = 0; i < sizeof(pUser->totpsecret); i++) {
119,979,563✔
4305
    if (pUser->totpsecret[i] != 0) {
116,348,933✔
4306
      return true;
49,080✔
4307
    }
4308
  }
4309
  return false;
3,630,630✔
4310
}
4311

4312

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

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

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

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

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

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

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

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

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

4364
    cols++;
929,974✔
4365

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

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

4380
      taosMemoryFreeClear(buf);
929,974✔
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++;
929,974✔
4387
    tlen = convertTimeRangesToStr(pUser, &buf);
929,974✔
4388
    if (tlen != 0) {
929,974✔
4389
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
929,974✔
4390
      if (varstr == NULL) {
929,974✔
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);
929,974✔
4396
      (void)memcpy(varDataVal(varstr), buf, tlen);
929,974✔
4397

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

4401
      taosMemoryFreeClear(buf);
929,974✔
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))) {
929,974✔
4408
      void  *pIter = NULL;
929,974✔
4409
      size_t klen = 0, tlen = 0;
929,974✔
4410
      char  *pBuf = POINTER_SHIFT(tBuf, VARSTR_HEADER_SIZE);
929,974✔
4411
      while ((pIter = taosHashIterate(pUser->roles, pIter))) {
2,108,902✔
4412
        char *roleName = taosHashGetKey(pIter, &klen);
1,178,928✔
4413
        tlen += snprintf(pBuf + tlen, bufSize - tlen, "%s,", roleName);
1,178,928✔
4414
      }
4415
      if (tlen > 0) {
929,974✔
4416
        pBuf[tlen - 1] = 0;  // remove last ','
929,974✔
4417
      } else {
4418
        pBuf[0] = 0;
×
4419
      }
4420
      varDataSetLen(tBuf, tlen);
929,974✔
4421
      COL_DATA_SET_VAL_GOTO((const char *)tBuf, false, pUser, pShow->pIter, _exit);
929,974✔
4422
    }
4423

4424
    numOfRows++;
929,974✔
4425
    sdbRelease(pSdb, pUser);
929,974✔
4426
  }
4427

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

4554
    cols++;
487,368✔
4555
    int32_t tlen = convertIpWhiteListToStr(pUser, &buf);
487,368✔
4556
    if (tlen != 0) {
487,368✔
4557
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
487,368✔
4558
      if (varstr == NULL) {
487,368✔
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);
487,368✔
4564
      (void)memcpy(varDataVal(varstr), buf, tlen);
487,368✔
4565

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

4569
      taosMemoryFreeClear(buf);
487,368✔
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++;
487,368✔
4576
    tlen = convertTimeRangesToStr(pUser, &buf);
487,368✔
4577
    if (tlen != 0) {
487,368✔
4578
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
487,368✔
4579
      if (varstr == NULL) {
487,368✔
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);
487,368✔
4585
      (void)memcpy(varDataVal(varstr), buf, tlen);
487,368✔
4586

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

4590
      taosMemoryFreeClear(buf);
487,368✔
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))) {
487,368✔
4597
      void  *pIter = NULL;
487,368✔
4598
      size_t klen = 0, tlen = 0;
487,368✔
4599
      char  *pBuf = POINTER_SHIFT(tBuf, VARSTR_HEADER_SIZE);
487,368✔
4600
      while ((pIter = taosHashIterate(pUser->roles, pIter))) {
997,164✔
4601
        char *roleName = taosHashGetKey(pIter, &klen);
509,796✔
4602
        tlen += snprintf(pBuf + tlen, bufSize - tlen, "%s,", roleName);
509,796✔
4603
      }
4604
      if (tlen > 0) {
487,368✔
4605
        pBuf[tlen - 1] = 0;  // remove last ','
487,368✔
4606
      } else {
4607
        pBuf[0] = 0;
×
4608
      }
4609
      varDataSetLen(tBuf, tlen);
487,368✔
4610
      COL_DATA_SET_VAL_GOTO((const char *)tBuf, false, pUser, pShow->pIter, _exit);
487,368✔
4611
    }
4612

4613
    numOfRows++;
487,368✔
4614
    sdbRelease(pSdb, pUser);
487,368✔
4615
  }
4616

4617
  pShow->numOfRows += numOfRows;
11,214✔
4618
_exit:
11,214✔
4619
  taosMemoryFreeClear(buf);
11,214✔
4620
  taosMemoryFreeClear(varstr);
11,214✔
4621
  if (code < 0) {
11,214✔
4622
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4623
    TAOS_RETURN(code);
×
4624
  }
4625
#endif
4626
  return numOfRows;
11,214✔
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,
132,432✔
4997
                                      SHashObj *privTbs, EPrivType privType, char *pBuf, int32_t bufSize, int32_t *pNumOfRows) {
4998
  int32_t     code = 0, lino = 0;
132,432✔
4999
  SMnode     *pMnode = pReq->info.node;
132,432✔
5000
  SSdb       *pSdb = pMnode->pSdb;
132,432✔
5001
  int32_t     cols = 0, qBufSize = bufSize - VARSTR_HEADER_SIZE;
132,432✔
5002
  int32_t     numOfRows = *pNumOfRows;
132,432✔
5003
  char       *qBuf = NULL;
132,432✔
5004
  char       *sql = NULL;
132,432✔
5005
  char        roleName[TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
132,432✔
5006
  const char *privName = privInfoGetName(privType);
132,432✔
5007

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

5010
  void *pIter = NULL;
132,432✔
5011
  while ((pIter = taosHashIterate(privTbs, pIter))) {
167,407✔
5012
    SPrivTblPolicies *pPolices = (SPrivTblPolicies *)pIter;
34,975✔
5013
    SArray           *tblPolicies = pPolices->policy;
34,975✔
5014

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

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

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

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

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

5047
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
34,975✔
5048
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, tblName, pShow->pMeta->pSchemas[cols].bytes);
34,975✔
5049
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
34,975✔
5050
      }
5051
      // condition
5052
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
34,975✔
5053
        SNode  *pAst = NULL;
34,975✔
5054
        int32_t sqlLen = 0;
34,975✔
5055
        qBuf = POINTER_SHIFT(pBuf, VARSTR_HEADER_SIZE);
34,975✔
5056
        if (tbPolicy->condLen > 0) {
34,975✔
5057
          if (nodesStringToNode(tbPolicy->cond, &pAst) == 0) {
34,975✔
5058
            if (nodesNodeToSQLFormat(pAst, qBuf, qBufSize, &sqlLen, true) != 0) {
34,975✔
5059
              sqlLen = tsnprintf(qBuf, qBufSize, "error");
×
5060
            }
5061
            nodesDestroyNode(pAst);
34,975✔
5062
          }
5063
          if (sqlLen == 0) {
34,975✔
5064
            sqlLen = tsnprintf(qBuf, qBufSize, "error");
×
5065
          }
5066
        } else {
5067
          sqlLen = tsnprintf(qBuf, qBufSize, "");
×
5068
        }
5069
        varDataSetLen(pBuf, sqlLen);
34,975✔
5070
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
34,975✔
5071
      }
5072
      // notes
5073
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
34,975✔
5074
        STR_WITH_MAXSIZE_TO_VARSTR((pBuf), "", 2);
34,975✔
5075
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
34,975✔
5076
      }
5077
      // columns
5078
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
34,975✔
5079
        SArray *pCols = tbPolicy->cols;
34,975✔
5080
        int32_t nCols = taosArrayGetSize(pCols);
34,975✔
5081
        int32_t totalLen = 0;
34,975✔
5082
        qBuf = POINTER_SHIFT(pBuf, VARSTR_HEADER_SIZE);
34,975✔
5083
        for (int32_t j = 0; j < nCols; ++j) {
34,975✔
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);
34,975✔
5099
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
34,975✔
5100
      }
5101
      // update_time
5102
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
34,975✔
5103
        char updateTime[40] = {0};
34,975✔
5104
        (void)formatTimestampLocal(updateTime, tbPolicy->updateUs, TSDB_TIME_PRECISION_MICRO);
34,975✔
5105
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, updateTime, pShow->pMeta->pSchemas[cols].bytes);
34,975✔
5106
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
34,975✔
5107
      }
5108
      ++numOfRows;
34,975✔
5109
    }
5110
  }
5111
  *pNumOfRows = numOfRows;
132,432✔
5112
_exit:
132,432✔
5113
  TAOS_RETURN(code);
132,432✔
5114
}
5115

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

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

5131
  while (numOfRows < rows) {
38,147✔
5132
    if (fetchNextInstance) {
38,147✔
5133
      pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pObj);
38,147✔
5134
      if (pShow->pIter == NULL) break;
38,147✔
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;
33,108✔
5144
    if (nSysPrivileges + nObjPrivileges >= rows) {
33,108✔
5145
      pShow->restore = true;
×
5146
      sdbRelease(pSdb, pObj);
×
5147
      break;
×
5148
    }
5149

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

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

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

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

5181
    // object privileges
5182
    void *pIter = NULL;
33,108✔
5183
    while ((pIter = taosHashIterate(pObj->objPrivs, pIter))) {
52,974✔
5184
      SPrivObjPolicies *pPolices = (SPrivObjPolicies *)pIter;
19,866✔
5185

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

5196
      SPrivIter privIter = {0};
19,866✔
5197
      privIterInit(&privIter, &pPolices->policy);
19,866✔
5198
      SPrivInfo *pPrivInfo = NULL;
19,866✔
5199
      while (privIterNext(&privIter, &pPrivInfo)) {
110,690✔
5200
        cols = 0;
90,824✔
5201
        SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
90,824✔
5202
        COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
90,824✔
5203

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

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

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

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

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

5227
        numOfRows++;
90,824✔
5228
      }
5229
    }
5230

5231
    // table level privileges
5232
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->selectTbs,
33,108✔
5233
                                           PRIV_TBL_SELECT, pBuf, bufSize, &numOfRows));
5234
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->insertTbs,
33,108✔
5235
                                           PRIV_TBL_INSERT, pBuf, bufSize, &numOfRows));
5236
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->updateTbs,
33,108✔
5237
                                           PRIV_TBL_UPDATE, pBuf, bufSize, &numOfRows));
5238
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->deleteTbs,
33,108✔
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);
33,108✔
5289
  }
5290

5291
  pShow->numOfRows += numOfRows;
5,039✔
5292
_exit:
5,039✔
5293
  taosMemoryFreeClear(pBuf);
5,039✔
5294
  taosMemoryFreeClear(sql);
5,039✔
5295
  if (code < 0) {
5,039✔
5296
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
5297
    TAOS_RETURN(code);
×
5298
  }
5299
  return numOfRows;
5,039✔
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,
20,293,855✔
5308
                                int32_t *pRspLen, int64_t ipWhiteListVer) {
5309
  int32_t           code = 0;
20,293,855✔
5310
  int32_t           lino = 0;
20,293,855✔
5311
  int32_t           rspLen = 0;
20,293,855✔
5312
  void             *pRsp = NULL;
20,293,855✔
5313
  SUserAuthBatchRsp batchRsp = {0};
20,293,855✔
5314

5315
  batchRsp.pArray = taosArrayInit(numOfUses, sizeof(SGetUserAuthRsp));
20,293,855✔
5316
  if (batchRsp.pArray == NULL) {
20,293,855✔
5317
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
5318
  }
5319
  int64_t now = taosGetTimestampMs();
20,293,592✔
5320
  for (int32_t i = 0; i < numOfUses; ++i) {
40,811,743✔
5321
    SUserObj *pUser = NULL;
20,517,888✔
5322
    code = mndAcquireUser(pMnode, pUsers[i].user, &pUser);
20,517,888✔
5323
    if (pUser == NULL) {
20,518,151✔
5324
      if (TSDB_CODE_MND_USER_NOT_EXIST == code) {
244✔
5325
        SGetUserAuthRsp rsp = {.dropped = 1};
244✔
5326
        (void)memcpy(rsp.user, pUsers[i].user, TSDB_USER_LEN);
244✔
5327
        TSDB_CHECK_NULL(taosArrayPush(batchRsp.pArray, &rsp), code, lino, _OVER, TSDB_CODE_OUT_OF_MEMORY);
488✔
5328
      }
5329
      mError("user:%s, failed to auth user since %s", pUsers[i].user, tstrerror(code));
244✔
5330
      code = 0;
244✔
5331
      continue;
244✔
5332
    }
5333

5334
    pUsers[i].version = ntohl(pUsers[i].version);
20,517,907✔
5335
    if ((pUser->authVersion <= pUsers[i].version) && (ipWhiteListVer == pMnode->ipWhiteVer) &&
20,517,907✔
UNCOV
5336
        !mndNeedRetrieveRole(pUser)) {
×
UNCOV
5337
      mndReleaseUser(pMnode, pUser);
×
UNCOV
5338
      continue;
×
5339
    }
5340

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

5349
    if (!(taosArrayPush(batchRsp.pArray, &rsp))) {
41,035,133✔
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
20,517,226✔
5356
    mndReleaseUser(pMnode, pUser);
20,517,907✔
5357
  }
5358

5359
  if (taosArrayGetSize(batchRsp.pArray) <= 0) {
20,293,855✔
UNCOV
5360
    *ppRsp = NULL;
×
UNCOV
5361
    *pRspLen = 0;
×
5362

UNCOV
5363
    tFreeSUserAuthBatchRsp(&batchRsp);
×
UNCOV
5364
    return 0;
×
5365
  }
5366

5367
  rspLen = tSerializeSUserAuthBatchRsp(NULL, 0, &batchRsp);
20,293,855✔
5368
  if (rspLen < 0) {
20,293,855✔
5369
    TAOS_CHECK_GOTO(rspLen, &lino, _OVER);
×
5370
  }
5371
  pRsp = taosMemoryMalloc(rspLen);
20,293,855✔
5372
  if (pRsp == NULL) {
20,293,305✔
5373
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
5374
  }
5375
  rspLen = tSerializeSUserAuthBatchRsp(pRsp, rspLen, &batchRsp);
20,293,305✔
5376
  if (rspLen < 0) {
20,293,855✔
5377
    TAOS_CHECK_GOTO(rspLen, &lino, _OVER);
×
5378
  }
5379
_OVER:
20,293,855✔
5380
  tFreeSUserAuthBatchRsp(&batchRsp);
20,293,855✔
5381
  if (code < 0) {
20,293,059✔
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;
20,293,059✔
5395
  *pRspLen = rspLen;
20,293,855✔
5396

5397
  TAOS_RETURN(code);
20,292,247✔
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) {
599,126✔
5464
  int32_t    code = 0, lino = 0;
599,126✔
5465
  SSdb      *pSdb = pMnode->pSdb;
599,126✔
5466
  int32_t    dbLen = strlen(pDb->name);
599,126✔
5467
  void      *pIter = NULL;
599,126✔
5468
  SUserObj  *pUser = NULL;
599,126✔
5469
  SUserObj   newUser = {0};
599,126✔
5470
  SSHashObj *pUsers = ppUsers ? *ppUsers : NULL;
599,126✔
5471
  bool       output = (ppUsers != NULL);
599,126✔
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:
599,126✔
5560
  if (code < 0) {
599,126✔
5561
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
5562
    mndUserFreeObj(&newUser);
×
5563
  }
5564
  if (pUser != NULL) sdbRelease(pSdb, pUser);
599,126✔
5565
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
599,126✔
5566
  if (!output) mndUserFreeObj(&newUser);
599,126✔
5567
  TAOS_RETURN(code);
599,126✔
5568
}
5569

5570
int32_t mndUserRemoveStb(SMnode *pMnode, STrans *pTrans, char *stb) {
428,030✔
5571
  int32_t   code = 0;
428,030✔
5572
  SSdb     *pSdb = pMnode->pSdb;
428,030✔
5573
  int32_t   len = strlen(stb) + 1;
428,030✔
5574
  void     *pIter = NULL;
428,030✔
5575
  SUserObj *pUser = NULL;
428,030✔
5576
  SUserObj  newUser = {0};
428,030✔
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);
428,030✔
5621
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
428,030✔
5622
  mndUserFreeObj(&newUser);
428,030✔
5623
  TAOS_RETURN(code);
428,030✔
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) {
96,689✔
5683
  int32_t   code = 0;
96,689✔
5684
  SSdb     *pSdb = pMnode->pSdb;
96,689✔
5685
  int32_t   len = strlen(topic) + 1;
96,689✔
5686
  void     *pIter = NULL;
96,689✔
5687
  SUserObj *pUser = NULL;
96,689✔
5688
  SUserObj  newUser = {0};
96,689✔
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);
96,689✔
5724
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
96,689✔
5725
  mndUserFreeObj(&newUser);
96,689✔
5726
  TAOS_RETURN(code);
96,689✔
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