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

taosdata / TDengine / #4911

04 Jan 2026 09:05AM UTC coverage: 65.028% (-0.8%) from 65.864%
#4911

push

travis-ci

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

1206 of 4524 new or added lines in 22 files covered. (26.66%)

1517 existing lines in 134 files now uncovered.

195276 of 300296 relevant lines covered (65.03%)

116931714.52 hits per line

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

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

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

35
// clang-format on
36

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

42
#define USER_RESERVE_SIZE                    63
43

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

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

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

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

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

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

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

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

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

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

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

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

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

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

143

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

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

157
static SUserCache userCache;
158

159

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

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

168
  userCache.users = users;
385,252✔
169
  userCache.verIp = 0;
385,252✔
170
  userCache.verTime = 0;
385,252✔
171

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

176

177

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

183
  void *pIter = taosHashIterate(userCache.users, NULL);
385,191✔
184
  while (pIter) {
777,239✔
185
    SCachedUserInfo *pInfo = *(SCachedUserInfo **)pIter;
392,048✔
186
    if (pInfo != NULL) {
392,048✔
187
      taosMemoryFree(pInfo->wlIp);
392,048✔
188
      taosMemoryFree(pInfo->wlTime);
392,048✔
189
      taosMemoryFree(pInfo);
392,048✔
190
    }
191
    pIter = taosHashIterate(userCache.users, pIter);
392,048✔
192
  }
193
  taosHashCleanup(userCache.users);
385,191✔
194

195
  (void)taosThreadRwlockDestroy(&userCache.rw);
385,191✔
196
}
197

198

199

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

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

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

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

222

223

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

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

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

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

239

240

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

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

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

258
  return pInfo;
411,164✔
259
}
260

261

262

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

266
  (void)taosThreadRwlockRdlock(&userCache.rw);
1,943,606✔
267

268
  SCachedUserInfo **ppInfo = taosHashGet(userCache.users, user, userLen);
1,943,667✔
269
  if (ppInfo != NULL && *ppInfo != NULL) {
1,943,671✔
270
    pLoginInfo->lastLoginTime = (*ppInfo)->loginInfo.lastLoginTime;
1,674,726✔
271
    pLoginInfo->failedLoginCount = (*ppInfo)->loginInfo.failedLoginCount;
1,674,661✔
272
    pLoginInfo->lastFailedLoginTime = (*ppInfo)->loginInfo.lastFailedLoginTime;
1,674,722✔
273
  } else {
274
    pLoginInfo->lastLoginTime = taosGetTimestampSec();
268,945✔
275
    pLoginInfo->failedLoginCount = 0;
268,945✔
276
    pLoginInfo->lastFailedLoginTime = 0;
268,945✔
277
  }
278

279
  (void)taosThreadRwlockUnlock(&userCache.rw);
1,943,610✔
280

281
  if (pLoginInfo->lastLoginTime == 0) {
1,943,671✔
282
    pLoginInfo->lastLoginTime = taosGetTimestampSec();
26,770✔
283
  }
284
}
1,943,602✔
285

286

287

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

291
  (void)taosThreadRwlockWrlock(&userCache.rw);
1,943,354✔
292

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

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

303

304

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

310
  if (a == NULL || b == NULL) {
993,530✔
311
    return false;
45,333✔
312
  }
313

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

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

327
  return true;
948,197✔
328
}
329

330

331

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

335
  (void)taosThreadRwlockWrlock(&userCache.rw);
993,530✔
336

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

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

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

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

370

371

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

375
  SSdb     *pSdb = pMnode->pSdb;
466,676✔
376
  void     *pIter = NULL;
466,676✔
377
  while (1) {
179,194✔
378
    SUserObj *pUser = NULL;
645,870✔
379
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
645,870✔
380
    if (pIter == NULL) {
645,870✔
381
      break;
466,676✔
382
    }
383

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

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

398
    taosMemoryFree(pInfo->wlIp);
179,194✔
399
    pInfo->wlIp = wl;
179,194✔
400

401
    sdbRelease(pSdb, pUser);
179,194✔
402
  }
403

404
  userCache.verIp++;
466,676✔
405

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

413

414

415
int64_t mndGetIpWhiteListVersion(SMnode *pMnode) {
39,141,278✔
416
  int64_t ver = 0;
39,141,278✔
417
  int32_t code = 0;
39,141,278✔
418

419
  if (mndEnableIpWhiteList(pMnode) != 0 && tsEnableWhiteList) {
39,141,278✔
420
    (void)taosThreadRwlockWrlock(&userCache.rw);
3,741✔
421

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

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

436
  mDebug("ip-white-list on mnode ver: %" PRId64, ver);
39,141,278✔
437
  return ver;
39,141,278✔
438
}
439

440

441

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

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

453
  TAOS_RETURN(code);
466,676✔
454
}
455

456

457

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

461
  SSdb     *pSdb = pMnode->pSdb;
458,445✔
462
  void     *pIter = NULL;
458,445✔
463
  while (1) {
170,963✔
464
    SUserObj *pUser = NULL;
629,408✔
465
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
629,408✔
466
    if (pIter == NULL) {
629,408✔
467
      break;
458,445✔
468
    }
469

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

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

484
    taosMemoryFree(pInfo->wlTime);
170,963✔
485
    pInfo->wlTime = wl;
170,963✔
486

487
    sdbRelease(pSdb, pUser);
170,963✔
488
  }
489

490
  userCache.verTime++;
458,445✔
491

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

499

500

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

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

512
  TAOS_RETURN(code);
458,445✔
513
}
514

515

516

517
int64_t mndGetTimeWhiteListVersion(SMnode *pMnode) {
39,141,278✔
518
  int64_t ver = 0;
39,141,278✔
519
  int32_t code = 0;
39,141,278✔
520

521
  if (mndEnableTimeWhiteList(pMnode) != 0 && tsEnableWhiteList) {
39,141,278✔
522
    (void)taosThreadRwlockWrlock(&userCache.rw);
3,741✔
523

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

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

538
  mDebug("datetime-white-list on mnode ver: %" PRId64, ver);
39,141,278✔
539
  return ver;
39,141,278✔
540
}
541

542

543

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

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

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

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

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

580

581

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

586

587

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

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

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

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

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

608

609

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

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

626

627

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

633
  if (a->type == 0) {
1,896,104✔
634
    SIpV4Range *a4 = &a->ipV4;
948,197✔
635
    SIpV4Range *b4 = &b->ipV4;
948,197✔
636
    return (a4->ip == b4->ip && a4->mask == b4->mask);
948,197✔
637
  }
638
  
639
  SIpV6Range *a6 = &a->ipV6;
947,907✔
640
  SIpV6Range *b6 = &b->ipV6;
947,907✔
641
  return (a6->addr[0] == b6->addr[0] && a6->addr[1] == b6->addr[1] && a6->mask == b6->mask);
947,907✔
642
}
643

644

645

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

655
  if (a->num != b->num) {
948,197✔
656
    return false;
145✔
657
  }
658
  for (int i = 0; i < a->num; i++) {
2,844,156✔
659
    if (!isIpRangeEqual(&a->pIpRanges[i], &b->pIpRanges[i])) {
1,896,104✔
660
      return false;
×
661
    }
662
  }
663
  return true;
948,052✔
664
}
665

666

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

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

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

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

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

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

699

700

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

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

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

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

722

723

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

731
  TAOS_CHECK_GOTO(tStartEncode(&encoder), &lino, _OVER);
2,122,076✔
732
  TAOS_CHECK_GOTO(tEncodeI32(&encoder, pList->num), &lino, _OVER);
4,244,152✔
733

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

739
  tEndEncode(&encoder);
2,122,076✔
740

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

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

757
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
1,409,008✔
758
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &pList->num), &lino, _OVER);
2,818,016✔
759

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

863
  SIpRange v4 = {0};
322,003✔
864
  SIpRange v6 = {0};
322,003✔
865

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

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

873
#endif
874

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

887

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

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

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

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

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

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

923
  return pos;
×
924
}
925

926

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

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

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

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

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

947
  return 0;
×
948
}
949

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

954

955

956

957
static void dropOldPasswords(SUserObj *pUser) {
3,531,084✔
958
  if (pUser->numOfPasswords <= pUser->passwordReuseMax) {
3,531,084✔
959
    return;
3,526,514✔
960
  }
961

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

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

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

985

986

987

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

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

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

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

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

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

1057
  if ((code = taosHashPut(userObj.roles, TSDB_ROLE_SYSDBA, strlen(TSDB_ROLE_SYSDBA) + 1, NULL, 0)) ||
554,532✔
1058
      (code = taosHashPut(userObj.roles, TSDB_ROLE_SYSSEC, strlen(TSDB_ROLE_SYSSEC) + 1, NULL, 0)) ||
554,532✔
1059
      (code = taosHashPut(userObj.roles, TSDB_ROLE_SYSAUDIT, strlen(TSDB_ROLE_SYSAUDIT) + 1, NULL, 0))) {
277,266✔
1060
    TAOS_CHECK_GOTO(code, &lino, _ERROR);
×
1061
  }
1062

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

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

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

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

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

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

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

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

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

1114
  TAOS_CHECK_EXIT(tStartEncode(&encoder));
4,244,152✔
1115
  TAOS_CHECK_EXIT(tEncodeI64v(&encoder, pObj->uid));
8,488,304✔
1116

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

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

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

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

1132
    uint8_t flag = *(int8_t *)pIter;
8,317,214✔
1133
    TAOS_CHECK_EXIT(tEncodeU8(&encoder, flag));  // value: 0 reset, 1 set(default)
16,634,428✔
1134
  }
1135

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

1145
  return tlen;
4,244,152✔
1146
}
1147

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1317
  dropOldPasswords(pUser);
2,122,076✔
1318
  SDB_SET_INT32(pRaw, dataPos, pUser->numOfPasswords, _OVER)
2,122,076✔
1319
  for (int32_t i = 0; i < pUser->numOfPasswords; i++) {
4,255,339✔
1320
    SDB_SET_BINARY(pRaw, dataPos, pUser->passwords[i].pass, sizeof(pUser->passwords[i].pass), _OVER)
2,133,263✔
1321
    SDB_SET_INT32(pRaw, dataPos, pUser->passwords[i].setTime, _OVER)
2,133,263✔
1322
  }
1323
  SDB_SET_BINARY(pRaw, dataPos, pUser->salt, sizeof(pUser->salt), _OVER)
2,122,076✔
1324

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1507
  SDB_SET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
2,122,076✔
1508

1509
  SDB_SET_DATALEN(pRaw, dataPos, _OVER)
2,122,076✔
1510

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1877
      taosMemoryFreeClear(pIpWhiteList);
×
1878

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

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

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

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

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

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

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

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

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

1964
  SDB_GET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
1,409,008✔
1965

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

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

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

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

2009
  return 0;
435,199✔
2010
}
2011

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

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

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

2034
  TAOS_RETURN(code);
×
2035
}
2036

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

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

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

2058
  TAOS_RETURN(code);
×
2059
}
2060

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

2067
  int32_t  code = 0;
949,661✔
2068
  uint8_t *flag = NULL;
949,661✔
2069
  while ((flag = taosHashIterate(pOld, flag))) {
1,899,807✔
2070
    size_t keyLen = 0;
950,146✔
2071
    char  *key = taosHashGetKey(flag, &keyLen);
950,146✔
2072

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

2080
  TAOS_RETURN(code);
949,661✔
2081
}
2082

2083
int32_t mndMergePrivObjHash(SHashObj *pOld, SHashObj **ppNew) {
18,279,736✔
2084
  if (!(*ppNew)) return mndDupPrivObjHash(pOld, ppNew);
18,279,736✔
2085

2086
  int32_t           code = 0, lino = 0;
18,279,736✔
2087
  SHashObj         *pNew = *ppNew;
18,279,736✔
2088
  SPrivObjPolicies *policies = NULL;
18,279,736✔
2089
  while ((policies = taosHashIterate(pOld, policies))) {
170,549,785✔
2090
    size_t klen = 0;
152,270,669✔
2091
    char  *key = taosHashGetKey(policies, &klen);
152,270,669✔
2092
    size_t vlen = taosHashGetValueSize(policies);
152,270,665✔
2093

2094
    SPrivObjPolicies *pNewPolicies = taosHashGet(pNew, key, klen);
152,270,665✔
2095
    if (pNewPolicies) {
152,270,748✔
2096
      size_t newVlen = taosHashGetValueSize(pNewPolicies);
96,525,760✔
2097
      if (newVlen > 0 && vlen > 0) {
96,525,760✔
2098
        privAddSet(&pNewPolicies->policy, &policies->policy);
96,525,760✔
2099
      }
2100
      continue;
96,525,061✔
2101
    }
2102

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

2111
  TAOS_RETURN(code);
18,279,037✔
2112
}
2113

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

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

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

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

2154
_exit:
54,839,208✔
2155
  TAOS_RETURN(code);
54,839,208✔
2156
}
2157

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

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

2177
  TAOS_RETURN(code);
7,163,101✔
2178
}
2179

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2333
  taosWUnLockLatch(&pOld->lock);
951,523✔
2334

2335
  return 0;
951,523✔
2336
}
2337

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

2342
  *ppUser = sdbAcquire(pSdb, SDB_USER, userName);
76,408,905✔
2343
  if (*ppUser == NULL) {
76,408,868✔
2344
    if (terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
47,185✔
2345
      code = TSDB_CODE_MND_USER_NOT_EXIST;
47,185✔
2346
    } else {
2347
      code = TSDB_CODE_MND_USER_NOT_AVAILABLE;
×
2348
    }
2349
  }
2350
  TAOS_RETURN(code);
76,408,868✔
2351
}
2352

2353
void mndReleaseUser(SMnode *pMnode, SUserObj *pUser) {
83,188,608✔
2354
  SSdb *pSdb = pMnode->pSdb;
83,188,608✔
2355
  sdbRelease(pSdb, pUser);
83,188,608✔
2356
}
83,188,608✔
2357

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

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

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

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

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

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

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

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

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

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

2426
  return 0;
×
2427
}
2428

2429

2430

2431
static void generateSalt(char *salt, size_t len) {
45,489✔
2432
  const char* set = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
45,489✔
2433
  int32_t     setLen = 62;
45,489✔
2434
  for (int32_t i = 0; i < len - 1; ++i) {
1,455,648✔
2435
    salt[i] = set[taosSafeRand() % setLen];
1,410,159✔
2436
  }
2437
  salt[len - 1] = 0;
45,489✔
2438
}
45,489✔
2439

2440

2441

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2665
  mndTransDrop(pTrans);
45,177✔
2666

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

2672

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

2678
  if (tsEnableStrongPassword == 0) {
39,734✔
2679
    for (char c = *pwd; c != 0; c = *(++pwd)) {
41,100✔
2680
      if (c == ' ' || c == '\'' || c == '\"' || c == '`' || c == '\\') {
40,650✔
2681
        return TSDB_CODE_MND_INVALID_PASS_FORMAT;
×
2682
      }
2683
    }
2684
    return 0;
450✔
2685
  }
2686

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

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

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

2700
  return TSDB_CODE_MND_INVALID_PASS_FORMAT;
×
2701
}
2702

2703

2704

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

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

2715
  return TSDB_CODE_PAR_INVALID_OPTION_VALUE;
×
2716
}
2717

2718

2719

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

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

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

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

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

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

2769

2770

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

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

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

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

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

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

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

2815

2816

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

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

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

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

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

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

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

2862

2863

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2959

2960

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

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

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

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

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

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

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

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

3019

3020

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

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

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

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

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

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

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

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

3065

3066

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

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

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

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

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

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

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

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

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

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

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

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

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

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

3174
  TAOS_RETURN(code);
×
3175
}
3176

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

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

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

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

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

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

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

3209
  TAOS_RETURN(0);
×
3210
}
3211

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

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

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

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

3238
  return 0;
×
3239
}
3240

3241

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

3496
  if (pAlterReq->alterType == TSDB_ALTER_ROLE_PRIVILEGES) {
939,224✔
3497
#ifdef TD_ENTERPRISE
3498
    TAOS_CHECK_EXIT(mndUserDupObj(pUser, &newUser));
936,042✔
3499
    if ((code = mndAlterUserPrivInfo(pMnode, pOperUser, pUser, &newUser, pAlterReq)) == TSDB_CODE_QRY_DUPLICATED_OPERATION) {
936,042✔
3500
      code = 0;
×
3501
      goto _exit;
×
3502
    } else {
3503
      TAOS_CHECK_EXIT(code);
936,042✔
3504
    }
3505
  } else if (pAlterReq->alterType == TSDB_ALTER_ROLE_ROLE) {
3,182✔
3506
    if ((code = mndAlterUserRoleInfo(pMnode, pOperUser, pUser, &newUser, pAlterReq)) == TSDB_CODE_QRY_DUPLICATED_OPERATION) {
3,182✔
3507
      code = 0;
144✔
3508
      goto _exit;
144✔
3509
    } else {
3510
      TAOS_CHECK_EXIT(code);
3,038✔
3511
    }
3512
#endif
3513
  } else {
3514
    TAOS_CHECK_EXIT(TSDB_CODE_INVALID_MSG);
×
3515
  }
3516
  code = mndAlterUser(pMnode, &newUser, pReq);
938,648✔
3517
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
938,648✔
3518

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

3528

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

3538
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, pAlterReq->user, &pUser), &lino, _OVER);
12,149✔
3539
  TAOS_CHECK_GOTO(mndCheckAlterUserPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), pUser, pAlterReq), &lino, _OVER);
11,527✔
3540
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
9,861✔
3541

3542
  if (pAlterReq->hasPassword) {
9,861✔
3543
    auditLen += tsnprintf(auditLog, sizeof(auditLog), "password,");
4,034✔
3544

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

3769

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

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

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

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

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

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

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

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

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

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

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

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

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

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

3881

3882

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

3999
  mndReleaseUser(pMnode, pUser);
19,116✔
4000
  mndReleaseUser(pMnode, pOperUser);
19,116✔
4001
  tFreeSDropUserReq(&dropReq);
19,116✔
4002
  TAOS_RETURN(code);
19,116✔
4003
}
4004

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

4015
  TAOS_CHECK_EXIT(tDeserializeSGetUserAuthReq(pReq->pCont, pReq->contLen, &authReq));
5,416,692✔
4016
  mTrace("user:%s, start to get auth", authReq.user);
5,416,692✔
4017

4018
  TAOS_CHECK_EXIT(mndAcquireUser(pMnode, authReq.user, &pUser));
5,416,692✔
4019

4020
  TAOS_CHECK_EXIT(mndSetUserAuthRsp(pMnode, pUser, &authRsp));
5,416,692✔
4021

4022
  contLen = tSerializeSGetUserAuthRsp(NULL, 0, &authRsp);
5,416,692✔
4023
  if (contLen < 0) {
5,416,692✔
4024
    TAOS_CHECK_EXIT(contLen);
×
4025
  }
4026
  pRsp = rpcMallocCont(contLen);
5,416,692✔
4027
  if (pRsp == NULL) {
5,416,692✔
4028
    TAOS_CHECK_EXIT(terrno);
×
4029
  }
4030

4031
  contLen = tSerializeSGetUserAuthRsp(pRsp, contLen, &authRsp);
5,416,692✔
4032
  if (contLen < 0) {
5,416,692✔
4033
    TAOS_CHECK_EXIT(contLen);
×
4034
  }
4035

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

4049
  TAOS_RETURN(code);
5,416,692✔
4050
}
4051

4052

4053
bool mndIsTotpEnabledUser(SUserObj *pUser) {
1,961,511✔
4054
  for (int32_t i = 0; i < sizeof(pUser->totpsecret); i++) {
64,699,997✔
4055
    if (pUser->totpsecret[i] != 0) {
62,739,470✔
4056
      return true;
×
4057
    }
4058
  }
4059
  return false;
1,960,527✔
4060
}
4061

4062

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

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

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

4088
    cols++;
17,905✔
4089
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
17,905✔
4090
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->superUser, false, pUser, pShow->pIter, _exit);
17,905✔
4091

4092
    cols++;
17,905✔
4093
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
17,905✔
4094
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->enable, false, pUser, pShow->pIter, _exit);
17,905✔
4095

4096
    cols++;
17,905✔
4097
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
17,905✔
4098
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sysInfo, false, pUser, pShow->pIter, _exit);
17,905✔
4099

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

4105
    cols++;
17,905✔
4106
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
17,905✔
4107
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->createdTime, false, pUser, pShow->pIter, _exit);
17,905✔
4108

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

4114
    cols++;
17,905✔
4115

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

4127
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
17,905✔
4128
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
17,905✔
4129

4130
      taosMemoryFreeClear(buf);
17,905✔
4131
    } else {
4132
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4133
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
4134
    }
4135

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

4148
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
17,905✔
4149
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
17,905✔
4150

4151
      taosMemoryFreeClear(buf);
17,905✔
4152
    } else {
4153
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4154
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, pShow->pIter, _exit);
×
4155
    }
4156

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

4174
    numOfRows++;
17,905✔
4175
    sdbRelease(pSdb, pUser);
17,905✔
4176
  }
4177

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

4189
static int32_t mndRetrieveUsersFull(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
×
4190
  int32_t numOfRows = 0;
×
4191
#ifdef TD_ENTERPRISE
4192
  SMnode   *pMnode = pReq->info.node;
×
4193
  SSdb     *pSdb = pMnode->pSdb;
×
4194
  SUserObj *pUser = NULL;
×
4195
  int32_t   code = 0;
×
4196
  int32_t   lino = 0;
×
4197
  int32_t   cols = 0;
×
4198
  int8_t    flag = 0;
×
4199
  char     *pWrite = NULL;
×
4200
  char     *buf = NULL;
×
4201
  char     *varstr = NULL;
×
4202
  char     *pBuf = NULL;
×
4203
  char      tBuf[TSDB_MAX_SUBROLE * TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
×
4204
  int32_t   bufSize = sizeof(tBuf) - VARSTR_HEADER_SIZE;
×
4205

4206
  while (numOfRows < rows) {
×
4207
    pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
×
4208
    if (pShow->pIter == NULL) break;
×
4209

4210
    cols = 0;
×
4211
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4212
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
×
4213
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
×
4214
    COL_DATA_SET_VAL_GOTO((const char *)name, false, pUser, pShow->pIter, _exit);
×
4215

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

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

4224
    cols++;
×
4225
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4226
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sysInfo, false, pUser, pShow->pIter, _exit);
×
4227

4228
    cols++;
×
4229
    flag = pUser->createdb ? 1 : 0;
×
4230
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4231
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
×
4232

4233
    cols++;
×
4234
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4235
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->createdTime, false, pUser, pShow->pIter, _exit);
×
4236

4237
    cols++;
×
4238
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4239
    flag = mndIsTotpEnabledUser(pUser) ? 1 : 0;
×
4240
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, pShow->pIter, _exit);
×
4241

4242
    cols++;
×
4243
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4244
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->changePass, false, pUser, pShow->pIter, _exit);
×
4245

4246
    cols++;
×
4247
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4248
    char pass[TSDB_PASSWORD_LEN + VARSTR_HEADER_SIZE] = {0};
×
4249
    STR_WITH_MAXSIZE_TO_VARSTR(pass, pUser->passwords[0].pass, pShow->pMeta->pSchemas[cols].bytes);
×
4250
    COL_DATA_SET_VAL_GOTO((const char *)pass, false, pUser, pShow->pIter, _exit);
×
4251

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

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

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

4264
    cols++;
×
4265
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4266
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->callPerSession, false, pUser, pShow->pIter, _exit);
×
4267

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

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

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

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

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

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

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

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

4300
    cols++;
×
4301
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4302
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->allowTokenNum, false, pUser, pShow->pIter, _exit);
×
4303

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

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

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

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

4337
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
4338
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, pShow->pIter, _exit);
×
4339

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

4346
    if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
×
4347
      void  *pIter = NULL;
×
4348
      size_t klen = 0, tlen = 0;
×
4349
      char  *pBuf = POINTER_SHIFT(tBuf, VARSTR_HEADER_SIZE);
×
4350
      while ((pIter = taosHashIterate(pUser->roles, pIter))) {
×
4351
        char *roleName = taosHashGetKey(pIter, &klen);
×
4352
        tlen += snprintf(pBuf + tlen, bufSize - tlen, "%s,", roleName);
×
4353
      }
4354
      if (tlen > 0) {
×
4355
        pBuf[tlen - 1] = 0;  // remove last ','
×
4356
      } else {
4357
        pBuf[0] = 0;
×
4358
      }
4359
      varDataSetLen(tBuf, tlen);
×
4360
      COL_DATA_SET_VAL_GOTO((const char *)tBuf, false, pUser, pShow->pIter, _exit);
×
4361
    }
4362

4363
    numOfRows++;
×
4364
    sdbRelease(pSdb, pUser);
×
4365
  }
4366

4367
  pShow->numOfRows += numOfRows;
×
4368
_exit:
×
4369
  taosMemoryFreeClear(buf);
×
4370
  taosMemoryFreeClear(varstr);
×
4371
  if (code < 0) {
×
4372
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4373
    TAOS_RETURN(code);
×
4374
  }
4375
#endif
4376
  return numOfRows;
×
4377
}
4378

4379
static void mndCancelGetNextUser(SMnode *pMnode, void *pIter) {
×
4380
  SSdb *pSdb = pMnode->pSdb;
×
4381
  sdbCancelFetchByType(pSdb, pIter, SDB_USER);
×
4382
}
×
4383

4384
static int32_t mndLoopHash(SHashObj *hash, char *priType, SSDataBlock *pBlock, int32_t *pNumOfRows, SSdb *pSdb,
×
4385
                           SUserObj *pUser, SShowObj *pShow, char **condition, char **sql) {
4386
  char   *value = taosHashIterate(hash, NULL);
×
4387
  char   *user = pUser->user;
×
4388
  int32_t code = 0;
×
4389
  int32_t lino = 0;
×
4390
  int32_t cols = 0;
×
4391
  int32_t numOfRows = *pNumOfRows;
×
4392

4393
  while (value != NULL) {
×
4394
    cols = 0;
×
4395
    char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
×
4396
    STR_WITH_MAXSIZE_TO_VARSTR(userName, user, pShow->pMeta->pSchemas[cols].bytes);
×
4397
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4398
    COL_DATA_SET_VAL_GOTO((const char *)userName, false, NULL, NULL, _exit);
×
4399

4400
    char privilege[20] = {0};
×
4401
    STR_WITH_MAXSIZE_TO_VARSTR(privilege, priType, pShow->pMeta->pSchemas[cols].bytes);
×
4402
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4403
    COL_DATA_SET_VAL_GOTO((const char *)privilege, false, NULL, NULL, _exit);
×
4404

4405
    size_t keyLen = 0;
×
4406
    void  *key = taosHashGetKey(value, &keyLen);
×
4407

4408
    char dbName[TSDB_DB_NAME_LEN] = {0};
×
4409
    (void)mndExtractShortDbNameFromStbFullName(key, dbName);
×
4410
    char dbNameContent[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
×
4411
    STR_WITH_MAXSIZE_TO_VARSTR(dbNameContent, dbName, pShow->pMeta->pSchemas[cols].bytes);
×
4412
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4413
    COL_DATA_SET_VAL_GOTO((const char *)dbNameContent, false, NULL, NULL, _exit);
×
4414

4415
    char tableName[TSDB_TABLE_NAME_LEN] = {0};
×
4416
    mndExtractTbNameFromStbFullName(key, tableName, TSDB_TABLE_NAME_LEN);
×
4417
    char tableNameContent[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
×
4418
    STR_WITH_MAXSIZE_TO_VARSTR(tableNameContent, tableName, pShow->pMeta->pSchemas[cols].bytes);
×
4419
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4420
    COL_DATA_SET_VAL_GOTO((const char *)tableNameContent, false, NULL, NULL, _exit);
×
4421

4422
    if (strcmp("t", value) != 0 && strcmp("v", value) != 0) {
×
4423
      SNode  *pAst = NULL;
×
4424
      int32_t sqlLen = 0;
×
4425
      size_t  bufSz = strlen(value) + 1;
×
4426
      if (bufSz < 6) bufSz = 6;
×
4427
      TAOS_MEMORY_REALLOC(*sql, bufSz);
×
4428
      if (*sql == NULL) {
×
4429
        code = terrno;
×
4430
        goto _exit;
×
4431
      }
4432
      TAOS_MEMORY_REALLOC(*condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
×
4433
      if ((*condition) == NULL) {
×
4434
        code = terrno;
×
4435
        goto _exit;
×
4436
      }
4437

4438
      if (nodesStringToNode(value, &pAst) == 0) {
×
4439
        if (nodesNodeToSQLFormat(pAst, *sql, bufSz, &sqlLen, true) != 0) {
×
4440
          sqlLen = tsnprintf(*sql, bufSz, "error");
×
4441
        }
4442
        nodesDestroyNode(pAst);
×
4443
      }
4444

4445
      if (sqlLen == 0) {
×
4446
        sqlLen = tsnprintf(*sql, bufSz, "error");
×
4447
      }
4448

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

4451
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4452
      COL_DATA_SET_VAL_GOTO((const char *)(*condition), false, NULL, NULL, _exit);
×
4453

4454
      char notes[2] = {0};
×
4455
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
×
4456
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4457
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, NULL, NULL, _exit);
×
4458
    } else {
4459
      TAOS_MEMORY_REALLOC(*condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
×
4460
      if ((*condition) == NULL) {
×
4461
        code = terrno;
×
4462
        goto _exit;
×
4463
      }
4464
      STR_WITH_MAXSIZE_TO_VARSTR((*condition), "", pShow->pMeta->pSchemas[cols].bytes);
×
4465
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4466
      COL_DATA_SET_VAL_GOTO((const char *)(*condition), false, NULL, NULL, _exit);
×
4467

4468
      char notes[64 + VARSTR_HEADER_SIZE] = {0};
×
4469
      STR_WITH_MAXSIZE_TO_VARSTR(notes, value[0] == 'v' ? "view" : "", sizeof(notes));
×
4470
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4471
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, NULL, NULL, _exit);
×
4472
    }
4473

4474
    numOfRows++;
×
4475
    value = taosHashIterate(hash, value);
×
4476
  }
4477
  *pNumOfRows = numOfRows;
×
4478
_exit:
×
4479
  if (code < 0) {
×
4480
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4481
    sdbRelease(pSdb, pUser);
×
4482
    sdbCancelFetch(pSdb, pShow->pIter);
×
4483
  }
4484
  TAOS_RETURN(code);
×
4485
}
4486

4487
#if 0
4488
static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
4489
  int32_t   code = 0;
4490
  int32_t   lino = 0;
4491
  SMnode   *pMnode = pReq->info.node;
4492
  SSdb     *pSdb = pMnode->pSdb;
4493
  int32_t   numOfRows = 0;
4494
  SUserObj *pUser = NULL;
4495
  int32_t   cols = 0;
4496
  char     *pWrite = NULL;
4497
  char     *condition = NULL;
4498
  char     *sql = NULL;
4499

4500
  bool fetchNextUser = pShow->restore ? false : true;
4501
  pShow->restore = false;
4502

4503
  while (numOfRows < rows) {
4504
    if (fetchNextUser) {
4505
      pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
4506
      if (pShow->pIter == NULL) break;
4507
    } else {
4508
      fetchNextUser = true;
4509
      void *pKey = taosHashGetKey(pShow->pIter, NULL);
4510
      pUser = sdbAcquire(pSdb, SDB_USER, pKey);
4511
      if (!pUser) {
4512
        continue;
4513
      }
4514
    }
4515

4516
    int32_t numOfReadDbs = 0; //taosHashGetSize(pUser->readDbs);
4517
    int32_t numOfWriteDbs = 0; //taosHashGetSize(pUser->writeDbs);
4518
    int32_t numOfTopics = taosHashGetSize(pUser->topics);
4519
    int32_t numOfReadTbs = taosHashGetSize(pUser->selectTbs);
4520
    int32_t numOfWriteTbs = taosHashGetSize(pUser->insertTbs);
4521
    int32_t numOfAlterTbs = taosHashGetSize(pUser->alterTbs);
4522
    int32_t numOfReadViews = taosHashGetSize(pUser->readViews);
4523
    int32_t numOfWriteViews = taosHashGetSize(pUser->writeViews);
4524
    int32_t numOfAlterViews = taosHashGetSize(pUser->alterViews);
4525
    if (numOfRows + numOfReadDbs + numOfWriteDbs + numOfTopics + numOfReadTbs + numOfWriteTbs + numOfAlterTbs +
4526
            numOfReadViews + numOfWriteViews + numOfAlterViews >=
4527
        rows) {
4528
      mInfo(
4529
          "will restore. current num of rows: %d, read dbs %d, write dbs %d, topics %d, read tables %d, write tables "
4530
          "%d, alter tables %d, select views %d, write views %d, alter views %d",
4531
          numOfRows, numOfReadDbs, numOfWriteDbs, numOfTopics, numOfReadTbs, numOfWriteTbs, numOfAlterTbs,
4532
          numOfReadViews, numOfWriteViews, numOfAlterViews);
4533
      pShow->restore = true;
4534
      sdbRelease(pSdb, pUser);
4535
      break;
4536
    }
4537

4538
    if (pUser->superUser) {
4539
      cols = 0;
4540
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
4541
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
4542
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4543
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
4544

4545
      char privilege[20] = {0};
4546
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "all", pShow->pMeta->pSchemas[cols].bytes);
4547
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4548
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
4549

4550
      char objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4551
      STR_WITH_MAXSIZE_TO_VARSTR(objName, "all", pShow->pMeta->pSchemas[cols].bytes);
4552
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4553
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
4554

4555
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4556
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
4557
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4558
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
4559

4560
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
4561
      if (condition == NULL) {
4562
        sdbRelease(pSdb, pUser);
4563
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
4564
      }
4565
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
4566
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4567
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
4568

4569
      char notes[2] = {0};
4570
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
4571
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4572
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
4573

4574
      numOfRows++;
4575
    }
4576
#if 0
4577
    char *db = taosHashIterate(pUser->readDbs, NULL);
4578
    while (db != NULL) {
4579
      cols = 0;
4580
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
4581
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
4582
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4583
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
4584

4585
      char privilege[20] = {0};
4586
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "read", pShow->pMeta->pSchemas[cols].bytes);
4587
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4588
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
4589

4590
      SName name = {0};
4591
      char  objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4592
      code = tNameFromString(&name, db, T_NAME_ACCT | T_NAME_DB);
4593
      if (code < 0) {
4594
        sdbRelease(pSdb, pUser);
4595
        sdbCancelFetch(pSdb, pShow->pIter);
4596
        TAOS_CHECK_GOTO(code, &lino, _exit);
4597
      }
4598
      (void)tNameGetDbName(&name, varDataVal(objName));
4599
      varDataSetLen(objName, strlen(varDataVal(objName)));
4600
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4601
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
4602

4603
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4604
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
4605
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4606
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
4607

4608
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
4609
      if (condition == NULL) {
4610
        sdbRelease(pSdb, pUser);
4611
        sdbCancelFetch(pSdb, pShow->pIter);
4612
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
4613
      }
4614
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
4615
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4616
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
4617

4618
      char notes[2] = {0};
4619
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
4620
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4621
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
4622

4623
      numOfRows++;
4624
      db = taosHashIterate(pUser->readDbs, db);
4625
    }
4626

4627
    db = taosHashIterate(pUser->writeDbs, NULL);
4628
    while (db != NULL) {
4629
      cols = 0;
4630
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
4631
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
4632
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4633
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
4634

4635
      char privilege[20] = {0};
4636
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "write", pShow->pMeta->pSchemas[cols].bytes);
4637
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4638
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
4639

4640
      SName name = {0};
4641
      char  objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4642
      code = tNameFromString(&name, db, T_NAME_ACCT | T_NAME_DB);
4643
      if (code < 0) {
4644
        sdbRelease(pSdb, pUser);
4645
        sdbCancelFetch(pSdb, pShow->pIter);
4646
        TAOS_CHECK_GOTO(code, &lino, _exit);
4647
      }
4648
      (void)tNameGetDbName(&name, varDataVal(objName));
4649
      varDataSetLen(objName, strlen(varDataVal(objName)));
4650
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4651
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, pShow->pIter, _exit);
4652

4653
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4654
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
4655
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4656
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
4657

4658
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
4659
      if (condition == NULL) {
4660
        sdbRelease(pSdb, pUser);
4661
        sdbCancelFetch(pSdb, pShow->pIter);
4662
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
4663
      }
4664
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
4665
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4666
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
4667

4668
      char notes[2] = {0};
4669
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
4670
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4671
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
4672

4673
      numOfRows++;
4674
      db = taosHashIterate(pUser->writeDbs, db);
4675
    }
4676
#endif
4677
    TAOS_CHECK_EXIT(mndLoopHash(pUser->selectTbs, "select", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
4678

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

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

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

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

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

4689
    char *topic = taosHashIterate(pUser->topics, NULL);
4690
    while (topic != NULL) {
4691
      cols = 0;
4692
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
4693
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
4694
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4695
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, pShow->pIter, _exit);
4696

4697
      char privilege[20] = {0};
4698
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "subscribe", pShow->pMeta->pSchemas[cols].bytes);
4699
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4700
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, pShow->pIter, _exit);
4701

4702
      char topicName[TSDB_TOPIC_NAME_LEN + VARSTR_HEADER_SIZE + 5] = {0};
4703
      tstrncpy(varDataVal(topicName), mndGetDbStr(topic), TSDB_TOPIC_NAME_LEN - 2);
4704
      varDataSetLen(topicName, strlen(varDataVal(topicName)));
4705
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4706
      COL_DATA_SET_VAL_GOTO((const char *)topicName, false, pUser, pShow->pIter, _exit);
4707

4708
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4709
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
4710
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4711
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, pShow->pIter, _exit);
4712

4713
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
4714
      if (condition == NULL) {
4715
        sdbRelease(pSdb, pUser);
4716
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
4717
      }
4718
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
4719
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4720
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, pShow->pIter, _exit);
4721

4722
      char notes[2] = {0};
4723
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
4724
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4725
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, pShow->pIter, _exit);
4726

4727
      numOfRows++;
4728
      topic = taosHashIterate(pUser->topics, topic);
4729
    }
4730

4731
    sdbRelease(pSdb, pUser);
4732
  }
4733

4734
  pShow->numOfRows += numOfRows;
4735
_exit:
4736
  taosMemoryFreeClear(condition);
4737
  taosMemoryFreeClear(sql);
4738
  if (code < 0) {
4739
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
4740
    TAOS_RETURN(code);
4741
  }
4742
  return numOfRows;
4743
}
4744
#endif
4745

4746
static int32_t mndShowTablePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows, SUserObj *pObj,
127,820✔
4747
                                      SHashObj *privTbs, EPrivType privType, char *pBuf, int32_t bufSize, int32_t *pNumOfRows) {
4748
  int32_t     code = 0, lino = 0;
127,820✔
4749
  SMnode     *pMnode = pReq->info.node;
127,820✔
4750
  SSdb       *pSdb = pMnode->pSdb;
127,820✔
4751
  int32_t     cols = 0, qBufSize = bufSize - VARSTR_HEADER_SIZE;
127,820✔
4752
  int32_t     numOfRows = *pNumOfRows;
127,820✔
4753
  char       *qBuf = NULL;
127,820✔
4754
  char       *sql = NULL;
127,820✔
4755
  char        roleName[TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
127,820✔
4756
  const char *privName = privInfoGetName(privType);
127,820✔
4757

4758
  STR_WITH_MAXSIZE_TO_VARSTR(roleName, pObj->name, pShow->pMeta->pSchemas[cols].bytes);
127,820✔
4759

4760
  void *pIter = NULL;
127,820✔
4761
  while ((pIter = taosHashIterate(privTbs, pIter))) {
159,982✔
4762
    SPrivTblPolicies *pPolices = (SPrivTblPolicies *)pIter;
32,162✔
4763
    SArray           *tblPolicies = pPolices->policy;
32,162✔
4764

4765
    char   *key = taosHashGetKey(pPolices, NULL);
32,162✔
4766
    int32_t objType = PRIV_OBJ_UNKNOWN;
32,162✔
4767
    char    dbName[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
32,162✔
4768
    char    tblName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
32,162✔
4769
    if ((code = privObjKeyParse(key, &objType, dbName, sizeof(dbName), tblName, sizeof(tblName), false))) {
32,162✔
4770
      sdbRelease(pSdb, pObj);
×
4771
      sdbCancelFetch(pSdb, pShow->pIter);
×
4772
      TAOS_CHECK_EXIT(code);
×
4773
    }
4774

4775
    int32_t nTbPolicies = taosArrayGetSize(tblPolicies);
32,162✔
4776
    for (int32_t i = 0; i < nTbPolicies; ++i) {
64,324✔
4777
      SPrivTblPolicy *tbPolicy = (SPrivTblPolicy *)TARRAY_GET_ELEM(tblPolicies, i);
32,162✔
4778
      cols = 0;
32,162✔
4779
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
32,162✔
4780
      COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
32,162✔
4781

4782
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
32,162✔
4783
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privName, pShow->pMeta->pSchemas[cols].bytes);
32,162✔
4784
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
32,162✔
4785
      }
4786

4787
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
32,162✔
4788
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privObjGetName(objType), pShow->pMeta->pSchemas[cols].bytes);
32,162✔
4789
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
32,162✔
4790
      }
4791

4792
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
32,162✔
4793
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, dbName, pShow->pMeta->pSchemas[cols].bytes);
32,162✔
4794
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
32,162✔
4795
      }
4796

4797
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
32,162✔
4798
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, tblName, pShow->pMeta->pSchemas[cols].bytes);
32,162✔
4799
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
32,162✔
4800
      }
4801
      // condition
4802
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
32,162✔
4803
        SNode  *pAst = NULL;
32,162✔
4804
        int32_t sqlLen = 0;
32,162✔
4805
        qBuf = POINTER_SHIFT(pBuf, VARSTR_HEADER_SIZE);
32,162✔
4806
        if (tbPolicy->condLen > 0) {
32,162✔
4807
          if (nodesStringToNode(tbPolicy->cond, &pAst) == 0) {
32,162✔
4808
            if (nodesNodeToSQLFormat(pAst, qBuf, qBufSize, &sqlLen, true) != 0) {
32,162✔
4809
              sqlLen = tsnprintf(qBuf, qBufSize, "error");
×
4810
            }
4811
            nodesDestroyNode(pAst);
32,162✔
4812
          }
4813
          if (sqlLen == 0) {
32,162✔
4814
            sqlLen = tsnprintf(qBuf, qBufSize, "error");
×
4815
          }
4816
        } else {
4817
          sqlLen = tsnprintf(qBuf, qBufSize, "");
×
4818
        }
4819
        varDataSetLen(pBuf, sqlLen);
32,162✔
4820
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
32,162✔
4821
      }
4822
      // notes
4823
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
32,162✔
4824
        STR_WITH_MAXSIZE_TO_VARSTR((pBuf), "", 2);
32,162✔
4825
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
32,162✔
4826
      }
4827
      // columns
4828
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
32,162✔
4829
        SArray *pCols = tbPolicy->cols;
32,162✔
4830
        int32_t nCols = taosArrayGetSize(pCols);
32,162✔
4831
        int32_t totalLen = 0;
32,162✔
4832
        qBuf = POINTER_SHIFT(pBuf, VARSTR_HEADER_SIZE);
32,162✔
4833
        for (int32_t j = 0; j < nCols; ++j) {
32,162✔
4834
          SColNameFlag *pCol = (SColNameFlag *)TARRAY_GET_ELEM(pCols, j);
×
4835
          char          tmpBuf[TSDB_COL_NAME_LEN + 16] = {0};
×
4836
          int32_t       tmpLen = 0;
×
4837
          if (IS_MASK_ON(pCol)) {
×
4838
            tmpLen = snprintf(tmpBuf, sizeof(tmpBuf), "mask(%s)%s", pCol->colName, j == nCols - 1 ? "" : ",");
×
4839
          } else {
4840
            tmpLen = snprintf(tmpBuf, sizeof(tmpBuf), "%s%s", pCol->colName, j == nCols - 1 ? "" : ",");
×
4841
          }
4842
          if(totalLen + tmpLen > qBufSize) {
×
4843
            break;
×
4844
          }
4845
          (void)memcpy(POINTER_SHIFT(qBuf, totalLen), tmpBuf, tmpLen);
×
4846
          totalLen += tmpLen;
×
4847
        }
4848
        varDataSetLen(pBuf, totalLen);
32,162✔
4849
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
32,162✔
4850
      }
4851
      // update_time
4852
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
32,162✔
4853
        char updateTime[40] = {0};
32,162✔
4854
        (void)formatTimestampLocal(updateTime, tbPolicy->updateUs, TSDB_TIME_PRECISION_MICRO);
32,162✔
4855
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, updateTime, pShow->pMeta->pSchemas[cols].bytes);
32,162✔
4856
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
32,162✔
4857
      }
4858
      ++numOfRows;
32,162✔
4859
    }
4860
  }
4861
  *pNumOfRows = numOfRows;
127,820✔
4862
_exit:
127,820✔
4863
  TAOS_RETURN(code);
127,820✔
4864
}
4865

4866
static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
4,798✔
4867
  int32_t   code = 0, lino = 0;
4,798✔
4868
  SMnode   *pMnode = pReq->info.node;
4,798✔
4869
  SSdb     *pSdb = pMnode->pSdb;
4,798✔
4870
  int32_t   numOfRows = 0;
4,798✔
4871
  int32_t   cols = 0;
4,798✔
4872
  SUserObj *pObj = NULL;
4,798✔
4873
  char     *pBuf = NULL, *qBuf = NULL;
4,798✔
4874
  char     *sql = NULL;
4,798✔
4875
  char      roleName[TSDB_ROLE_LEN + VARSTR_HEADER_SIZE] = {0};
4,798✔
4876
  int32_t   bufSize = TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE;
4,798✔
4877

4878
  bool fetchNextInstance = pShow->restore ? false : true;
4,798✔
4879
  pShow->restore = false;
4,798✔
4880

4881
  while (numOfRows < rows) {
36,753✔
4882
    if (fetchNextInstance) {
36,753✔
4883
      pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pObj);
36,753✔
4884
      if (pShow->pIter == NULL) break;
36,753✔
4885
    } else {
4886
      fetchNextInstance = true;
×
4887
      void *pKey = taosHashGetKey(pShow->pIter, NULL);
×
4888
      if (!(pObj = sdbAcquire(pSdb, SDB_USER, pKey))) {
×
4889
        continue;
×
4890
      }
4891
    }
4892

4893
    int32_t nSysPrivileges = 0, nObjPrivileges = 0;
31,955✔
4894
    if (nSysPrivileges + nObjPrivileges >= rows) {
31,955✔
4895
      pShow->restore = true;
×
4896
      sdbRelease(pSdb, pObj);
×
4897
      break;
×
4898
    }
4899

4900
    if (!pBuf && !(pBuf = taosMemoryMalloc(bufSize))) {
31,955✔
4901
      sdbCancelFetch(pSdb, pShow->pIter);
×
4902
      sdbRelease(pSdb, pObj);
×
4903
      TAOS_CHECK_EXIT(terrno);
×
4904
    }
4905

4906
    cols = 0;
31,955✔
4907
    STR_WITH_MAXSIZE_TO_VARSTR(roleName, pObj->name, pShow->pMeta->pSchemas[cols].bytes);
31,955✔
4908

4909
    // system privileges
4910
    SPrivIter privIter = {0};
31,955✔
4911
    privIterInit(&privIter, &pObj->sysPrivs);
31,955✔
4912
    SPrivInfo *pPrivInfo = NULL;
31,955✔
4913
    while (privIterNext(&privIter, &pPrivInfo)) {
33,731✔
4914
      cols = 0;
1,776✔
4915
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
1,776✔
4916
      COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
1,776✔
4917

4918
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
1,776✔
4919
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, pPrivInfo->name, pShow->pMeta->pSchemas[cols].bytes);
1,776✔
4920
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
1,776✔
4921
      }
4922
      if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
1,776✔
4923
        STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privObjGetName(PRIV_OBJ_CLUSTER), pShow->pMeta->pSchemas[cols].bytes);
1,776✔
4924
        COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
1,776✔
4925
      }
4926
      // skip db, table, condition, notes, columns, update_time
4927
      COL_DATA_SET_EMPTY_VARCHAR(pBuf, 6);
12,432✔
4928
      numOfRows++;
1,776✔
4929
    }
4930

4931
    // object privileges
4932
    void *pIter = NULL;
31,955✔
4933
    while ((pIter = taosHashIterate(pObj->objPrivs, pIter))) {
50,289✔
4934
      SPrivObjPolicies *pPolices = (SPrivObjPolicies *)pIter;
18,334✔
4935

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

4946
      SPrivIter privIter = {0};
18,334✔
4947
      privIterInit(&privIter, &pPolices->policy);
18,334✔
4948
      SPrivInfo *pPrivInfo = NULL;
18,334✔
4949
      while (privIterNext(&privIter, &pPrivInfo)) {
101,530✔
4950
        cols = 0;
83,196✔
4951
        SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
83,196✔
4952
        COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
83,196✔
4953

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

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

4964
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
83,196✔
4965
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, dbName, pShow->pMeta->pSchemas[cols].bytes);
83,196✔
4966
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
83,196✔
4967
        }
4968

4969
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
83,196✔
4970
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, tblName, pShow->pMeta->pSchemas[cols].bytes);
83,196✔
4971
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
83,196✔
4972
        }
4973

4974
        // skip condition, notes, columns, update_time
4975
        COL_DATA_SET_EMPTY_VARCHAR(pBuf, 4);
415,980✔
4976

4977
        numOfRows++;
83,196✔
4978
      }
4979
    }
4980

4981
    // table level privileges
4982
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->selectTbs,
31,955✔
4983
                                           PRIV_TBL_SELECT, pBuf, bufSize, &numOfRows));
4984
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->insertTbs,
31,955✔
4985
                                           PRIV_TBL_INSERT, pBuf, bufSize, &numOfRows));
4986
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->updateTbs,
31,955✔
4987
                                           PRIV_TBL_UPDATE, pBuf, bufSize, &numOfRows));
4988
    TAOS_CHECK_EXIT(mndShowTablePrivileges(pReq, pShow, pBlock, rows - numOfRows, pObj, pObj->deleteTbs,
31,955✔
4989
                                           PRIV_TBL_DELETE, pBuf, bufSize, &numOfRows));
4990
#if 0
4991
    while ((pIter = taosHashIterate(pObj->selectTbs, pIter))) {
4992
      SPrivTblPolicies *pPolices = (SPrivTblPolicies *)pIter;
4993
      SArray           *tblPolicies = pPolices->policy;
4994

4995
      char   *key = taosHashGetKey(pPolices, NULL);
4996
      int32_t objType = PRIV_OBJ_UNKNOWN;
4997
      char    dbName[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
4998
      char    tblName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4999
      if ((code = privObjKeyParse(key, &objType, dbName, sizeof(dbName), tblName, sizeof(tblName), false))) {
5000
        sdbRelease(pSdb, pObj);
5001
        sdbCancelFetch(pSdb, pShow->pIter);
5002
        TAOS_CHECK_EXIT(code);
5003
      }
5004

5005
      int32_t nTbPolicies = taosArrayGetSize(tblPolicies);
5006
      for (int32_t i = 0; i < nTbPolicies; ++i) {
5007
        SPrivTblPolicy *tbPolicy = (SPrivTblPolicy *)TARRAY_GET_ELEM(tblPolicies, i);
5008
        cols = 0;
5009
        SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
5010
        COL_DATA_SET_VAL_GOTO((const char *)roleName, false, pObj, pShow->pIter, _exit);
5011

5012
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
5013
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privInfoGetName(PRIV_TBL_SELECT), pShow->pMeta->pSchemas[cols].bytes);
5014
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
5015
        }
5016

5017
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
5018
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, dbName, pShow->pMeta->pSchemas[cols].bytes);
5019
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
5020
        }
5021

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

5027
        // skip condition, notes, columns, update_time
5028
        COL_DATA_SET_EMPTY_VARCHAR(pBuf, 4);
5029

5030
        if ((pColInfo = taosArrayGet(pBlock->pDataBlock, ++cols))) {
5031
          STR_WITH_MAXSIZE_TO_VARSTR(pBuf, privObjGetName(objType), pShow->pMeta->pSchemas[cols].bytes);
5032
          COL_DATA_SET_VAL_GOTO((const char *)pBuf, false, pObj, pShow->pIter, _exit);
5033
        }
5034
        numOfRows++;
5035
      }
5036
    }
5037
#endif
5038
    sdbRelease(pSdb, pObj);
31,955✔
5039
  }
5040

5041
  pShow->numOfRows += numOfRows;
4,798✔
5042
_exit:
4,798✔
5043
  taosMemoryFreeClear(pBuf);
4,798✔
5044
  taosMemoryFreeClear(sql);
4,798✔
5045
  if (code < 0) {
4,798✔
5046
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
5047
    TAOS_RETURN(code);
×
5048
  }
5049
  return numOfRows;
4,798✔
5050
}
5051

5052
static void mndCancelGetNextPrivileges(SMnode *pMnode, void *pIter) {
×
5053
  SSdb *pSdb = pMnode->pSdb;
×
5054
  sdbCancelFetchByType(pSdb, pIter, SDB_USER);
×
5055
}
×
5056

5057
int32_t mndValidateUserAuthInfo(SMnode *pMnode, SUserAuthVersion *pUsers, int32_t numOfUses, void **ppRsp,
17,887,702✔
5058
                                int32_t *pRspLen, int64_t ipWhiteListVer) {
5059
  int32_t           code = 0;
17,887,702✔
5060
  int32_t           lino = 0;
17,887,702✔
5061
  int32_t           rspLen = 0;
17,887,702✔
5062
  void             *pRsp = NULL;
17,887,702✔
5063
  SUserAuthBatchRsp batchRsp = {0};
17,887,702✔
5064

5065
  batchRsp.pArray = taosArrayInit(numOfUses, sizeof(SGetUserAuthRsp));
17,887,702✔
5066
  if (batchRsp.pArray == NULL) {
17,887,702✔
5067
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
5068
  }
5069
  int64_t now = taosGetTimestampMs();
17,887,702✔
5070
  for (int32_t i = 0; i < numOfUses; ++i) {
35,827,124✔
5071
    SUserObj *pUser = NULL;
17,939,422✔
5072
    code = mndAcquireUser(pMnode, pUsers[i].user, &pUser);
17,939,422✔
5073
    if (pUser == NULL) {
17,939,422✔
5074
      if (TSDB_CODE_MND_USER_NOT_EXIST == code) {
320✔
5075
        SGetUserAuthRsp rsp = {.dropped = 1};
320✔
5076
        (void)memcpy(rsp.user, pUsers[i].user, TSDB_USER_LEN);
320✔
5077
        TSDB_CHECK_NULL(taosArrayPush(batchRsp.pArray, &rsp), code, lino, _OVER, TSDB_CODE_OUT_OF_MEMORY);
640✔
5078
      }
5079
      mError("user:%s, failed to auth user since %s", pUsers[i].user, tstrerror(code));
320✔
5080
      code = 0;
320✔
5081
      continue;
2,062✔
5082
    }
5083

5084
    pUsers[i].version = ntohl(pUsers[i].version);
17,939,102✔
5085
    if ((pUser->authVersion <= pUsers[i].version) && (ipWhiteListVer == pMnode->ipWhiteVer) &&
17,939,102✔
5086
        !mndNeedRetrieveRole(pUser)) {
17,233,123✔
5087
      mndReleaseUser(pMnode, pUser);
17,141,778✔
5088
      continue;
17,141,778✔
5089
    }
5090

5091
    SGetUserAuthRsp rsp = {0};
797,068✔
5092
    code = mndSetUserAuthRsp(pMnode, pUser, &rsp);
797,324✔
5093
    if (code) {
797,324✔
5094
      mndReleaseUser(pMnode, pUser);
×
5095
      tFreeSGetUserAuthRsp(&rsp);
×
5096
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
5097
    }
5098

5099
    if (!(taosArrayPush(batchRsp.pArray, &rsp))) {
1,594,648✔
5100
      code = terrno;
×
5101
      mndReleaseUser(pMnode, pUser);
×
5102
      tFreeSGetUserAuthRsp(&rsp);
×
5103
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
5104
    }
5105
    pUser->lastRoleRetrieve = now;  // update user's last retrieve time
797,324✔
5106
    mndReleaseUser(pMnode, pUser);
797,324✔
5107
  }
5108

5109
  if (taosArrayGetSize(batchRsp.pArray) <= 0) {
17,887,702✔
5110
    *ppRsp = NULL;
17,124,339✔
5111
    *pRspLen = 0;
17,124,339✔
5112

5113
    tFreeSUserAuthBatchRsp(&batchRsp);
17,124,339✔
5114
    return 0;
17,124,339✔
5115
  }
5116

5117
  rspLen = tSerializeSUserAuthBatchRsp(NULL, 0, &batchRsp);
763,363✔
5118
  if (rspLen < 0) {
763,026✔
5119
    TAOS_CHECK_GOTO(rspLen, &lino, _OVER);
×
5120
  }
5121
  pRsp = taosMemoryMalloc(rspLen);
763,026✔
5122
  if (pRsp == NULL) {
763,363✔
5123
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
5124
  }
5125
  rspLen = tSerializeSUserAuthBatchRsp(pRsp, rspLen, &batchRsp);
763,363✔
5126
  if (rspLen < 0) {
763,363✔
5127
    TAOS_CHECK_GOTO(rspLen, &lino, _OVER);
×
5128
  }
5129
_OVER:
763,363✔
5130
  tFreeSUserAuthBatchRsp(&batchRsp);
763,363✔
5131
  if (code < 0) {
763,363✔
5132
    for (int32_t i = 0; i < numOfUses; ++i) {
×
5133
      SUserObj *pUser = NULL;
×
5134
      if (mndAcquireUser(pMnode, pUsers[i].user, &pUser) != 0) {
×
5135
        continue;
×
5136
      }
5137
      pUser->lastRoleRetrieve = 0;  // reset last retrieve time on error
×
5138
      mndReleaseUser(pMnode, pUser);
×
5139
    }
5140
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
5141
    taosMemoryFreeClear(pRsp);
×
5142
    rspLen = 0;
×
5143
  }
5144
  *ppRsp = pRsp;
763,363✔
5145
  *pRspLen = rspLen;
763,363✔
5146

5147
  TAOS_RETURN(code);
763,108✔
5148
}
5149

5150
static int32_t mndRemoveDbPrivileges(SHashObj *pHash, const char *dbFName, int32_t dbFNameLen, int32_t *nRemoved) {
×
5151
  void *pVal = NULL;
×
5152
  while ((pVal = taosHashIterate(pHash, pVal))) {
×
5153
    size_t keyLen = 0;
×
5154
    char  *pKey = (char *)taosHashGetKey(pVal, &keyLen);
×
5155
    if (pKey == NULL || keyLen <= dbFNameLen) continue;
×
5156
    if ((*(pKey + dbFNameLen) == '.') && strncmp(pKey, dbFName, dbFNameLen) == 0) {
×
5157
      TAOS_CHECK_RETURN(taosHashRemove(pHash, pKey, keyLen));
×
5158
      if (nRemoved) ++(*nRemoved);
×
5159
    }
5160
  }
5161
  TAOS_RETURN(0);
×
5162
}
5163

5164
int32_t mndUserDropRole(SMnode *pMnode, STrans *pTrans, SRoleObj *pObj) {
×
5165
  int32_t   code = 0, lino = 0;
×
5166
  SSdb     *pSdb = pMnode->pSdb;
×
5167
  SUserObj *pUser = NULL;
×
5168
  void     *pIter = NULL;
×
5169

5170
  while ((pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser))) {
×
5171
    SHashObj *pRole = taosHashGet(pUser->roles, pObj->name, strlen(pObj->name) + 1);
×
5172
    if (!pRole) {
×
5173
      sdbRelease(pSdb, pUser);
×
5174
      pUser = NULL;
×
5175
      continue;
×
5176
    }
5177

5178
    SUserObj newUser = {0};
×
5179
    TAOS_CHECK_EXIT(mndUserDupObj(pUser, &newUser));
×
5180
    code = taosHashRemove(newUser.roles, pObj->name, strlen(pObj->name) + 1);
×
5181
    if (code == TSDB_CODE_NOT_FOUND) {
×
5182
      sdbRelease(pSdb, pUser);
×
5183
      pUser = NULL;
×
5184
      mndUserFreeObj(&newUser);
×
5185
      continue;
×
5186
    }
5187
    if (code != 0) {
×
5188
      mndUserFreeObj(&newUser);
×
5189
      TAOS_CHECK_EXIT(code);
×
5190
    }
5191
    SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
×
5192
    if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
×
5193
      mndUserFreeObj(&newUser);
×
5194
      TAOS_CHECK_EXIT(TSDB_CODE_OUT_OF_MEMORY);
×
5195
    }
5196
    if ((code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY))) {
×
5197
      mndUserFreeObj(&newUser);
×
5198
      TAOS_CHECK_EXIT(code);
×
5199
    }
5200
    sdbRelease(pSdb, pUser);
×
5201
    pUser = NULL;
×
5202
    mndUserFreeObj(&newUser);
×
5203
  }
5204
_exit:
×
5205
  if (pIter) sdbCancelFetch(pSdb, pIter);
×
5206
  if (pUser) sdbRelease(pSdb, pUser);
×
5207
  if (code < 0) {
×
5208
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
5209
  }
5210
  TAOS_RETURN(code);
×
5211
}
5212

5213
int32_t mndUserRemoveDb(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SSHashObj **ppUsers) {
583,135✔
5214
  int32_t    code = 0, lino = 0;
583,135✔
5215
  SSdb      *pSdb = pMnode->pSdb;
583,135✔
5216
  int32_t    dbLen = strlen(pDb->name);
583,135✔
5217
  void      *pIter = NULL;
583,135✔
5218
  SUserObj  *pUser = NULL;
583,135✔
5219
  SUserObj   newUser = {0};
583,135✔
5220
  SSHashObj *pUsers = ppUsers ? *ppUsers : NULL;
583,135✔
5221
  bool       output = (ppUsers != NULL);
583,135✔
5222
#ifdef PRIV_TODO
5223
  while (1) {
5224
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
5225
    if (pIter == NULL) break;
5226

5227
    bool update = false;
5228
    bool inReadDb = false; //(taosHashGet(pUser->readDbs, pDb->name, dbLen + 1) != NULL);
5229
    bool inWriteDb = false; //(taosHashGet(pUser->writeDbs, pDb->name, dbLen + 1) != NULL);
5230
    bool inUseDb = (taosHashGet(pUser->useDbs, pDb->name, dbLen + 1) != NULL);
5231
    bool inReadTbs = taosHashGetSize(pUser->selectTbs) > 0;
5232
    bool inWriteTbs = taosHashGetSize(pUser->insertTbs) > 0;
5233
    bool inAlterTbs = taosHashGetSize(pUser->alterTbs) > 0;
5234
    bool inReadViews = taosHashGetSize(pUser->readViews) > 0;
5235
    bool inWriteViews = taosHashGetSize(pUser->writeViews) > 0;
5236
    bool inAlterViews = taosHashGetSize(pUser->alterViews) > 0;
5237
    // no need remove pUser->topics since topics must be dropped ahead of db
5238
    if (!inReadDb && !inWriteDb && !inReadTbs && !inWriteTbs && !inAlterTbs && !inReadViews && !inWriteViews &&
5239
        !inAlterViews) {
5240
      sdbRelease(pSdb, pUser);
5241
      continue;
5242
    }
5243
    SUserObj *pTargetUser = &newUser;
5244
    if (output) {
5245
      if (!pUsers) {
5246
        TSDB_CHECK_NULL(pUsers = tSimpleHashInit(32, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY)), code, lino,
5247
                        _exit, TSDB_CODE_OUT_OF_MEMORY);
5248
        *ppUsers = pUsers;
5249
      }
5250
      void   *pVal = NULL;
5251
      int32_t userLen = strlen(pUser->user) + 1;
5252
      if ((pVal = tSimpleHashGet(pUsers, pUser->user, userLen)) != NULL) {
5253
        pTargetUser = (SUserObj *)pVal;
5254
      } else {
5255
        TAOS_CHECK_EXIT(mndUserDupObj(pUser, &newUser));
5256
        TAOS_CHECK_EXIT(tSimpleHashPut(pUsers, pUser->user, userLen, &newUser, sizeof(SUserObj)));
5257
        TSDB_CHECK_NULL((pVal = tSimpleHashGet(pUsers, pUser->user, userLen)), code, lino, _exit,
5258
                        TSDB_CODE_OUT_OF_MEMORY);
5259
        pTargetUser = (SUserObj *)pVal;
5260
      }
5261
    } else {
5262
      TAOS_CHECK_EXIT(mndUserDupObj(pUser, &newUser));
5263
    }
5264
    if (inReadDb) {
5265
      // TAOS_CHECK_EXIT(taosHashRemove(pTargetUser->readDbs, pDb->name, dbLen + 1));
5266
    }
5267
    if (inWriteDb) {
5268
      // TAOS_CHECK_EXIT(taosHashRemove(pTargetUser->writeDbs, pDb->name, dbLen + 1));
5269
    }
5270
    if (inUseDb) {
5271
      TAOS_CHECK_EXIT(taosHashRemove(pTargetUser->useDbs, pDb->name, dbLen + 1));
5272
    }
5273
    update = inReadDb || inWriteDb || inUseDb;
5274

5275
    int32_t nRemovedReadTbs = 0;
5276
    int32_t nRemovedWriteTbs = 0;
5277
    int32_t nRemovedAlterTbs = 0;
5278
    if (inReadTbs || inWriteTbs || inAlterTbs) {
5279
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->selectTbs, pDb->name, dbLen, &nRemovedReadTbs));
5280
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->insertTbs, pDb->name, dbLen, &nRemovedWriteTbs));
5281
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->alterTbs, pDb->name, dbLen, &nRemovedAlterTbs));
5282
      if (!update) update = nRemovedReadTbs > 0 || nRemovedWriteTbs > 0 || nRemovedAlterTbs > 0;
5283
    }
5284

5285
    int32_t nRemovedReadViews = 0;
5286
    int32_t nRemovedWriteViews = 0;
5287
    int32_t nRemovedAlterViews = 0;
5288
    if (inReadViews || inWriteViews || inAlterViews) {
5289
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->readViews, pDb->name, dbLen, &nRemovedReadViews));
5290
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->writeViews, pDb->name, dbLen, &nRemovedWriteViews));
5291
      TAOS_CHECK_EXIT(mndRemoveDbPrivileges(pTargetUser->alterViews, pDb->name, dbLen, &nRemovedAlterViews));
5292
      if (!update) update = nRemovedReadViews > 0 || nRemovedWriteViews > 0 || nRemovedAlterViews > 0;
5293
    }
5294

5295
    if (!output) {
5296
      if (update) {
5297
        SSdbRaw *pCommitRaw = mndUserActionEncode(pTargetUser);
5298
        if (pCommitRaw == NULL) {
5299
          TAOS_CHECK_EXIT(terrno);
5300
        }
5301
        TAOS_CHECK_EXIT(mndTransAppendCommitlog(pTrans, pCommitRaw));
5302
        TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
5303
      }
5304
      mndUserFreeObj(&newUser);
5305
    }
5306
    sdbRelease(pSdb, pUser);
5307
  }
5308
#endif
5309
_exit:
583,135✔
5310
  if (code < 0) {
583,135✔
5311
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
5312
    mndUserFreeObj(&newUser);
×
5313
  }
5314
  if (pUser != NULL) sdbRelease(pSdb, pUser);
583,135✔
5315
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
583,135✔
5316
  if (!output) mndUserFreeObj(&newUser);
583,135✔
5317
  TAOS_RETURN(code);
583,135✔
5318
}
5319

5320
int32_t mndUserRemoveStb(SMnode *pMnode, STrans *pTrans, char *stb) {
422,604✔
5321
  int32_t   code = 0;
422,604✔
5322
  SSdb     *pSdb = pMnode->pSdb;
422,604✔
5323
  int32_t   len = strlen(stb) + 1;
422,604✔
5324
  void     *pIter = NULL;
422,604✔
5325
  SUserObj *pUser = NULL;
422,604✔
5326
  SUserObj  newUser = {0};
422,604✔
5327
#ifdef PRIV_TODO
5328
  while (1) {
5329
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
5330
    if (pIter == NULL) break;
5331

5332
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
5333
      break;
5334
    }
5335

5336
    bool inRead = (taosHashGet(newUser.selectTbs, stb, len) != NULL);
5337
    bool inWrite = (taosHashGet(newUser.insertTbs, stb, len) != NULL);
5338
    bool inAlter = (taosHashGet(newUser.alterTbs, stb, len) != NULL);
5339
    if (inRead || inWrite || inAlter) {
5340
      code = taosHashRemove(newUser.selectTbs, stb, len);
5341
      if (code < 0) {
5342
        mError("failed to remove selectTbs:%s from user:%s", stb, pUser->user);
5343
      }
5344
      code = taosHashRemove(newUser.insertTbs, stb, len);
5345
      if (code < 0) {
5346
        mError("failed to remove insertTbs:%s from user:%s", stb, pUser->user);
5347
      }
5348
      code = taosHashRemove(newUser.alterTbs, stb, len);
5349
      if (code < 0) {
5350
        mError("failed to remove alterTbs:%s from user:%s", stb, pUser->user);
5351
      }
5352

5353
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
5354
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
5355
        code = TSDB_CODE_OUT_OF_MEMORY;
5356
        break;
5357
      }
5358
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
5359
      if (code != 0) {
5360
        mndUserFreeObj(&newUser);
5361
        sdbRelease(pSdb, pUser);
5362
        TAOS_RETURN(code);
5363
      }
5364
    }
5365

5366
    mndUserFreeObj(&newUser);
5367
    sdbRelease(pSdb, pUser);
5368
  }
5369
#endif
5370
  if (pUser != NULL) sdbRelease(pSdb, pUser);
422,604✔
5371
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
422,604✔
5372
  mndUserFreeObj(&newUser);
422,604✔
5373
  TAOS_RETURN(code);
422,604✔
5374
}
5375

5376
int32_t mndUserRemoveView(SMnode *pMnode, STrans *pTrans, char *view) {
×
5377
  int32_t   code = 0;
×
5378
  SSdb     *pSdb = pMnode->pSdb;
×
5379
  int32_t   len = strlen(view) + 1;
×
5380
  void     *pIter = NULL;
×
5381
  SUserObj *pUser = NULL;
×
5382
  SUserObj  newUser = {0};
×
5383
#ifdef PRIV_TODO
5384
  while (1) {
5385
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
5386
    if (pIter == NULL) break;
5387

5388
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
5389
      break;
5390
    }
5391

5392
    bool inRead = (taosHashGet(newUser.readViews, view, len) != NULL);
5393
    bool inWrite = (taosHashGet(newUser.writeViews, view, len) != NULL);
5394
    bool inAlter = (taosHashGet(newUser.alterViews, view, len) != NULL);
5395
    if (inRead || inWrite || inAlter) {
5396
      code = taosHashRemove(newUser.readViews, view, len);
5397
      if (code < 0) {
5398
        mError("failed to remove readViews:%s from user:%s", view, pUser->user);
5399
      }
5400
      code = taosHashRemove(newUser.writeViews, view, len);
5401
      if (code < 0) {
5402
        mError("failed to remove writeViews:%s from user:%s", view, pUser->user);
5403
      }
5404
      code = taosHashRemove(newUser.alterViews, view, len);
5405
      if (code < 0) {
5406
        mError("failed to remove alterViews:%s from user:%s", view, pUser->user);
5407
      }
5408

5409
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
5410
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
5411
        code = TSDB_CODE_OUT_OF_MEMORY;
5412
        break;
5413
      }
5414
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
5415
      if (code < 0) {
5416
        mndUserFreeObj(&newUser);
5417
        sdbRelease(pSdb, pUser);
5418
        TAOS_RETURN(code);
5419
      }
5420
    }
5421

5422
    mndUserFreeObj(&newUser);
5423
    sdbRelease(pSdb, pUser);
5424
  }
5425
#endif
5426
  if (pUser != NULL) sdbRelease(pSdb, pUser);
×
5427
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
×
5428
  mndUserFreeObj(&newUser);
×
5429
  TAOS_RETURN(code);
×
5430
}
5431

5432
int32_t mndUserRemoveTopic(SMnode *pMnode, STrans *pTrans, char *topic) {
93,643✔
5433
  int32_t   code = 0;
93,643✔
5434
  SSdb     *pSdb = pMnode->pSdb;
93,643✔
5435
  int32_t   len = strlen(topic) + 1;
93,643✔
5436
  void     *pIter = NULL;
93,643✔
5437
  SUserObj *pUser = NULL;
93,643✔
5438
  SUserObj  newUser = {0};
93,643✔
5439
#ifdef PRIV_TODO
5440
  while (1) {
5441
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
5442
    if (pIter == NULL) {
5443
      break;
5444
    }
5445

5446
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
5447
      break;
5448
    }
5449

5450
    bool inTopic = (taosHashGet(newUser.topics, topic, len) != NULL);
5451
    if (inTopic) {
5452
      code = taosHashRemove(newUser.topics, topic, len);
5453
      if (code < 0) {
5454
        mError("failed to remove topic:%s from user:%s", topic, pUser->user);
5455
      }
5456
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
5457
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
5458
        code = TSDB_CODE_OUT_OF_MEMORY;
5459
        break;
5460
      }
5461
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
5462
      if (code < 0) {
5463
        mndUserFreeObj(&newUser);
5464
        sdbRelease(pSdb, pUser);
5465
        TAOS_RETURN(code);
5466
      }
5467
    }
5468

5469
    mndUserFreeObj(&newUser);
5470
    sdbRelease(pSdb, pUser);
5471
  }
5472
#endif
5473
  if (pUser != NULL) sdbRelease(pSdb, pUser);
93,643✔
5474
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
93,643✔
5475
  mndUserFreeObj(&newUser);
93,643✔
5476
  TAOS_RETURN(code);
93,643✔
5477
}
5478

5479
int64_t mndGetUserIpWhiteListVer(SMnode *pMnode, SUserObj *pUser) {
×
5480
  // ver = 0, disable ip white list
5481
  // ver > 0, enable ip white list
5482
  return tsEnableWhiteList ? pUser->ipWhiteListVer : 0;
×
5483
}
5484

5485
int64_t mndGetUserTimeWhiteListVer(SMnode *pMnode, SUserObj *pUser) {
×
5486
  // ver = 0, disable datetime white list
5487
  // ver > 0, enable datetime white list
5488
  return tsEnableWhiteList ? pUser->timeWhiteListVer : 0;
×
5489
}
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