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

taosdata / TDengine / #3564

24 Dec 2024 05:40AM UTC coverage: 62.21% (+1.2%) from 61.045%
#3564

push

travis-ci

web-flow
Merge pull request #29289 from taosdata/fix/TD-33270-2

ci(stream):add stream unit test

138331 of 285924 branches covered (48.38%)

Branch coverage included in aggregate %.

215800 of 283329 relevant lines covered (76.17%)

19198660.97 hits per line

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

61.08
/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
#include <uv.h>
19
#include "mndUser.h"
20
#include "audit.h"
21
#include "mndDb.h"
22
#include "mndPrivilege.h"
23
#include "mndShow.h"
24
#include "mndStb.h"
25
#include "mndTopic.h"
26
#include "mndTrans.h"
27
#include "tbase64.h"
28

29
// clang-format on
30

31
#define USER_VER_NUMBER   6
32
#define USER_RESERVE_SIZE 64
33

34
#define BIT_FLAG_MASK(n)              (1 << n)
35
#define BIT_FLAG_SET_MASK(val, mask)  ((val) |= (mask))
36
#define BIT_FLAG_TEST_MASK(val, mask) (((val) & (mask)) != 0)
37

38
#define PRIVILEGE_TYPE_ALL       BIT_FLAG_MASK(0)
39
#define PRIVILEGE_TYPE_READ      BIT_FLAG_MASK(1)
40
#define PRIVILEGE_TYPE_WRITE     BIT_FLAG_MASK(2)
41
#define PRIVILEGE_TYPE_SUBSCRIBE BIT_FLAG_MASK(3)
42
#define PRIVILEGE_TYPE_ALTER     BIT_FLAG_MASK(4)
43

44
#define ALTER_USER_ADD_PRIVS(_type) ((_type) == TSDB_ALTER_USER_ADD_PRIVILEGES)
45
#define ALTER_USER_DEL_PRIVS(_type) ((_type) == TSDB_ALTER_USER_DEL_PRIVILEGES)
46

47
#define ALTER_USER_ALL_PRIV(_priv) (BIT_FLAG_TEST_MASK((_priv), PRIVILEGE_TYPE_ALL))
48
#define ALTER_USER_READ_PRIV(_priv) \
49
  (BIT_FLAG_TEST_MASK((_priv), PRIVILEGE_TYPE_READ) || BIT_FLAG_TEST_MASK((_priv), PRIVILEGE_TYPE_ALL))
50
#define ALTER_USER_WRITE_PRIV(_priv) \
51
  (BIT_FLAG_TEST_MASK((_priv), PRIVILEGE_TYPE_WRITE) || BIT_FLAG_TEST_MASK((_priv), PRIVILEGE_TYPE_ALL))
52
#define ALTER_USER_ALTER_PRIV(_priv) \
53
  (BIT_FLAG_TEST_MASK((_priv), PRIVILEGE_TYPE_ALTER) || BIT_FLAG_TEST_MASK((_priv), PRIVILEGE_TYPE_ALL))
54
#define ALTER_USER_SUBSCRIBE_PRIV(_priv) (BIT_FLAG_TEST_MASK((_priv), PRIVILEGE_TYPE_SUBSCRIBE))
55

56
#define ALTER_USER_TARGET_DB(_tbname) (0 == (_tbname)[0])
57
#define ALTER_USER_TARGET_TB(_tbname) (0 != (_tbname)[0])
58

59
#define ALTER_USER_ADD_READ_DB_PRIV(_type, _priv, _tbname) \
60
  (ALTER_USER_ADD_PRIVS(_type) && ALTER_USER_READ_PRIV(_priv) && ALTER_USER_TARGET_DB(_tbname))
61
#define ALTER_USER_DEL_READ_DB_PRIV(_type, _priv, _tbname) \
62
  (ALTER_USER_DEL_PRIVS(_type) && ALTER_USER_READ_PRIV(_priv) && ALTER_USER_TARGET_DB(_tbname))
63
#define ALTER_USER_ADD_WRITE_DB_PRIV(_type, _priv, _tbname) \
64
  (ALTER_USER_ADD_PRIVS(_type) && ALTER_USER_WRITE_PRIV(_priv) && ALTER_USER_TARGET_DB(_tbname))
65
#define ALTER_USER_DEL_WRITE_DB_PRIV(_type, _priv, _tbname) \
66
  (ALTER_USER_DEL_PRIVS(_type) && ALTER_USER_WRITE_PRIV(_priv) && ALTER_USER_TARGET_DB(_tbname))
67
#define ALTER_USER_ADD_ALTER_DB_PRIV(_type, _priv, _tbname) \
68
  (ALTER_USER_ADD_PRIVS(_type) && ALTER_USER_ALTER_PRIV(_priv) && ALTER_USER_TARGET_DB(_tbname))
69
#define ALTER_USER_DEL_ALTER_DB_PRIV(_type, _priv, _tbname) \
70
  (ALTER_USER_DEL_PRIVS(_type) && ALTER_USER_ALTER_PRIV(_priv) && ALTER_USER_TARGET_DB(_tbname))
71
#define ALTER_USER_ADD_ALL_DB_PRIV(_type, _priv, _tbname) \
72
  (ALTER_USER_ADD_PRIVS(_type) && ALTER_USER_ALL_PRIV(_priv) && ALTER_USER_TARGET_DB(_tbname))
73
#define ALTER_USER_DEL_ALL_DB_PRIV(_type, _priv, _tbname) \
74
  (ALTER_USER_DEL_PRIVS(_type) && ALTER_USER_ALL_PRIV(_priv) && ALTER_USER_TARGET_DB(_tbname))
75

76
#define ALTER_USER_ADD_READ_TB_PRIV(_type, _priv, _tbname) \
77
  (ALTER_USER_ADD_PRIVS(_type) && ALTER_USER_READ_PRIV(_priv) && ALTER_USER_TARGET_TB(_tbname))
78
#define ALTER_USER_DEL_READ_TB_PRIV(_type, _priv, _tbname) \
79
  (ALTER_USER_DEL_PRIVS(_type) && ALTER_USER_READ_PRIV(_priv) && ALTER_USER_TARGET_TB(_tbname))
80
#define ALTER_USER_ADD_WRITE_TB_PRIV(_type, _priv, _tbname) \
81
  (ALTER_USER_ADD_PRIVS(_type) && ALTER_USER_WRITE_PRIV(_priv) && ALTER_USER_TARGET_TB(_tbname))
82
#define ALTER_USER_DEL_WRITE_TB_PRIV(_type, _priv, _tbname) \
83
  (ALTER_USER_DEL_PRIVS(_type) && ALTER_USER_WRITE_PRIV(_priv) && ALTER_USER_TARGET_TB(_tbname))
84
#define ALTER_USER_ADD_ALTER_TB_PRIV(_type, _priv, _tbname) \
85
  (ALTER_USER_ADD_PRIVS(_type) && ALTER_USER_ALTER_PRIV(_priv) && ALTER_USER_TARGET_TB(_tbname))
86
#define ALTER_USER_DEL_ALTER_TB_PRIV(_type, _priv, _tbname) \
87
  (ALTER_USER_DEL_PRIVS(_type) && ALTER_USER_ALTER_PRIV(_priv) && ALTER_USER_TARGET_TB(_tbname))
88
#define ALTER_USER_ADD_ALL_TB_PRIV(_type, _priv, _tbname) \
89
  (ALTER_USER_ADD_PRIVS(_type) && ALTER_USER_ALL_PRIV(_priv) && ALTER_USER_TARGET_TB(_tbname))
90
#define ALTER_USER_DEL_ALL_TB_PRIV(_type, _priv, _tbname) \
91
  (ALTER_USER_DEL_PRIVS(_type) && ALTER_USER_ALL_PRIV(_priv) && ALTER_USER_TARGET_TB(_tbname))
92

93
#define ALTER_USER_ADD_SUBSCRIBE_TOPIC_PRIV(_type, _priv) \
94
  (ALTER_USER_ADD_PRIVS(_type) && ALTER_USER_SUBSCRIBE_PRIV(_priv))
95
#define ALTER_USER_DEL_SUBSCRIBE_TOPIC_PRIV(_type, _priv) \
96
  (ALTER_USER_DEL_PRIVS(_type) && ALTER_USER_SUBSCRIBE_PRIV(_priv))
97

98
static int32_t createDefaultIpWhiteList(SIpWhiteList **ppWhiteList);
99
static int32_t createIpWhiteList(void *buf, int32_t len, SIpWhiteList **ppWhiteList);
100
static bool    updateIpWhiteList(SIpWhiteList *pOld, SIpWhiteList *pNew);
101
static bool    isIpWhiteListEqual(SIpWhiteList *a, SIpWhiteList *b);
102
static bool    isIpRangeEqual(SIpV4Range *a, SIpV4Range *b);
103

104
void destroyIpWhiteTab(SHashObj *pIpWhiteTab);
105

106
#define MND_MAX_USE_HOST (TSDB_PRIVILEDGE_HOST_LEN / 24)
107

108
static int32_t  mndCreateDefaultUsers(SMnode *pMnode);
109
static SSdbRow *mndUserActionDecode(SSdbRaw *pRaw);
110
static int32_t  mndUserActionInsert(SSdb *pSdb, SUserObj *pUser);
111
static int32_t  mndUserActionDelete(SSdb *pSdb, SUserObj *pUser);
112
static int32_t  mndUserActionUpdate(SSdb *pSdb, SUserObj *pOld, SUserObj *pNew);
113
static int32_t  mndCreateUser(SMnode *pMnode, char *acct, SCreateUserReq *pCreate, SRpcMsg *pReq);
114
static int32_t  mndProcessCreateUserReq(SRpcMsg *pReq);
115
static int32_t  mndProcessAlterUserReq(SRpcMsg *pReq);
116
static int32_t  mndProcessDropUserReq(SRpcMsg *pReq);
117
static int32_t  mndProcessGetUserAuthReq(SRpcMsg *pReq);
118
static int32_t  mndProcessGetUserWhiteListReq(SRpcMsg *pReq);
119
static int32_t  mndRetrieveUsers(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
120
static int32_t  mndRetrieveUsersFull(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
121
static void     mndCancelGetNextUser(SMnode *pMnode, void *pIter);
122
static int32_t  mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
123
static void     mndCancelGetNextPrivileges(SMnode *pMnode, void *pIter);
124
static int32_t  mndFetchAllIpWhite(SMnode *pMnode, SHashObj **ppIpWhiteTab);
125
static int32_t  mndProcesSRetrieveIpWhiteReq(SRpcMsg *pReq);
126
static int32_t  mndUpdateIpWhiteImpl(SHashObj *pIpWhiteTab, char *user, char *fqdn, int8_t type, bool *pUpdate);
127

128
static int32_t ipWhiteMgtUpdateAll(SMnode *pMnode);
129
typedef struct {
130
  SHashObj      *pIpWhiteTab;
131
  int64_t        ver;
132
  TdThreadRwlock rw;
133
} SIpWhiteMgt;
134

135
static SIpWhiteMgt ipWhiteMgt;
136

137
const static SIpV4Range defaultIpRange = {.ip = 16777343, .mask = 32};
138

139
static int32_t ipWhiteMgtInit() {
1,774✔
140
  ipWhiteMgt.pIpWhiteTab = taosHashInit(8, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), 1, HASH_ENTRY_LOCK);
1,774✔
141
  if (ipWhiteMgt.pIpWhiteTab == NULL) {
1,774!
142
    TAOS_RETURN(terrno);
×
143
  }
144
  ipWhiteMgt.ver = 0;
1,774✔
145
  (void)taosThreadRwlockInit(&ipWhiteMgt.rw, NULL);
1,774✔
146
  TAOS_RETURN(0);
1,774✔
147
}
148
void ipWhiteMgtCleanup() {
1,773✔
149
  destroyIpWhiteTab(ipWhiteMgt.pIpWhiteTab);
1,773✔
150
  (void)taosThreadRwlockDestroy(&ipWhiteMgt.rw);
1,773✔
151
}
1,773✔
152

153
int32_t ipWhiteMgtUpdate(SMnode *pMnode, char *user, SIpWhiteList *pNew) {
366✔
154
  int32_t code = 0;
366✔
155
  int32_t lino = 0;
366✔
156
  bool    update = true;
366✔
157
  SArray *fqdns = NULL;
366✔
158
  (void)taosThreadRwlockWrlock(&ipWhiteMgt.rw);
366✔
159
  SIpWhiteList **ppList = taosHashGet(ipWhiteMgt.pIpWhiteTab, user, strlen(user));
366✔
160

161
  if (ppList == NULL || *ppList == NULL) {
511!
162
    SIpWhiteList *p = cloneIpWhiteList(pNew);
145✔
163
    if (p == NULL) {
145!
164
      update = false;
×
165
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
166
    }
167
    if ((code = taosHashPut(ipWhiteMgt.pIpWhiteTab, user, strlen(user), &p, sizeof(void *))) != 0) {
145!
168
      update = false;
×
169
      taosMemoryFree(p);
×
170
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
171
    }
172
  } else {
173
    SIpWhiteList *pOld = *ppList;
221✔
174
    if (isIpWhiteListEqual(pOld, pNew)) {
221✔
175
      update = false;
199✔
176
    } else {
177
      taosMemoryFree(pOld);
22!
178
      SIpWhiteList *p = cloneIpWhiteList(pNew);
22✔
179
      if (p == NULL) {
22!
180
        update = false;
×
181
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
182
      }
183
      if ((code = taosHashPut(ipWhiteMgt.pIpWhiteTab, user, strlen(user), &p, sizeof(void *))) != 0) {
22!
184
        update = false;
×
185
        taosMemoryFree(p);
×
186
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
187
      }
188
    }
189
  }
190

191
  fqdns = mndGetAllDnodeFqdns(pMnode);  // TODO: update this line after refactor api
366✔
192
  if (fqdns == NULL) {
366!
193
    update = false;
×
194
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
195
  }
196

197
  for (int i = 0; i < taosArrayGetSize(fqdns); i++) {
938✔
198
    char *fqdn = taosArrayGetP(fqdns, i);
572✔
199
    bool  upd = false;
572✔
200
    TAOS_CHECK_GOTO(mndUpdateIpWhiteImpl(ipWhiteMgt.pIpWhiteTab, TSDB_DEFAULT_USER, fqdn, IP_WHITE_ADD, &upd), &lino,
572!
201
                    _OVER);
202
    update |= upd;
572✔
203
    TAOS_CHECK_GOTO(mndUpdateIpWhiteImpl(ipWhiteMgt.pIpWhiteTab, user, fqdn, IP_WHITE_ADD, &upd), &lino, _OVER);
572!
204
    update |= upd;
572✔
205
  }
206

207
  // for (int i = 0; i < taosArrayGetSize(pUserNames); i++) {
208
  //   taosMemoryFree(taosArrayGetP(pUserNames, i));
209
  // }
210
  // taosArrayDestroy(pUserNames);
211

212
  if (update) ipWhiteMgt.ver++;
366✔
213

214
_OVER:
199✔
215
  (void)taosThreadRwlockUnlock(&ipWhiteMgt.rw);
366✔
216
  taosArrayDestroyP(fqdns, NULL);
366✔
217
  if (code < 0) {
366!
218
    mError("failed to update ip white list for user: %s at line %d since %s", user, lino, tstrerror(code));
×
219
  }
220
  TAOS_RETURN(code);
366✔
221
}
222
int32_t ipWhiteMgtRemove(char *user) {
44✔
223
  bool    update = true;
44✔
224
  int32_t code = 0;
44✔
225
  (void)taosThreadRwlockWrlock(&ipWhiteMgt.rw);
44✔
226
  SIpWhiteList **ppList = taosHashGet(ipWhiteMgt.pIpWhiteTab, user, strlen(user));
44✔
227
  if (ppList == NULL || *ppList == NULL) {
44!
228
    update = false;
×
229
  } else {
230
    taosMemoryFree(*ppList);
44!
231
    code = taosHashRemove(ipWhiteMgt.pIpWhiteTab, user, strlen(user));
44✔
232
    if (code != 0) {
44!
233
      update = false;
×
234
    }
235
  }
236

237
  if (update) ipWhiteMgt.ver++;
44!
238
  (void)taosThreadRwlockUnlock(&ipWhiteMgt.rw);
44✔
239
  return 0;
44✔
240
}
241

242
bool isRangeInWhiteList(SIpWhiteList *pList, SIpV4Range *range) {
4,732✔
243
  for (int i = 0; i < pList->num; i++) {
6,061✔
244
    if (isIpRangeEqual(&pList->pIpRange[i], range)) {
5,799✔
245
      return true;
4,470✔
246
    }
247
  }
248
  return false;
262✔
249
}
250
#if 0
251
int32_t ipWhiteUpdateForAllUser(SIpWhiteList *pList) {
252
  (void)taosThreadRwlockWrlock(&ipWhiteMgt.rw);
253

254
  SHashObj *pIpWhiteTab = taosHashInit(8, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), 1, HASH_ENTRY_LOCK);
255
  void     *pIter = taosHashIterate(ipWhiteMgt.pIpWhiteTab, NULL);
256

257
  while (pIter) {
258
    SIpWhiteList *p = *(SIpWhiteList **)pIter;
259
    SIpWhiteList *clone = cloneIpWhiteList(pList);
260
    int32_t       idx = 0;
261
    for (int i = 0; i < pList->num; i++) {
262
      SIpV4Range *e = &pList->pIpRange[i];
263
      if (!isRangeInWhiteList(p, e)) {
264
        clone->pIpRange[idx] = *e;
265
        idx++;
266
      }
267
    }
268
    clone->num = idx;
269

270
    SIpWhiteList *val = NULL;
271
    if (clone->num != 0) {
272
      int32_t sz = clone->num + p->num;
273
      val = taosMemoryCalloc(1, sizeof(SIpWhiteList) + sz * sizeof(SIpV4Range));
274
      (void)memcpy(val->pIpRange, p->pIpRange, sizeof(SIpV4Range) * p->num);
275
      (void)memcpy(((char *)val->pIpRange) + sizeof(SIpV4Range) * p->num, (char *)clone->pIpRange,
276
             sizeof(SIpV4Range) * clone->num);
277

278
    } else {
279
      val = cloneIpWhiteList(p);
280
    }
281
    taosMemoryFree(clone);
282

283
    size_t klen;
284
    void  *key = taosHashGetKey(pIter, &klen);
285
    taosHashPut(pIpWhiteTab, key, klen, val, sizeof(void *));
286
  }
287

288
  destroyIpWhiteTab(ipWhiteMgt.pIpWhiteTab);
289

290
  ipWhiteMgt.pIpWhiteTab = pIpWhiteTab;
291
  ipWhiteMgt.ver++;
292
  (void)taosThreadRwlockUnlock(&ipWhiteMgt.rw);
293
  return 0;
294
}
295
#endif
296

297
static int32_t ipWhiteMgtUpdateAll(SMnode *pMnode) {
1,791✔
298
  SHashObj *pNew = NULL;
1,791✔
299
  TAOS_CHECK_RETURN(mndFetchAllIpWhite(pMnode, &pNew));
1,791!
300

301
  SHashObj *pOld = ipWhiteMgt.pIpWhiteTab;
1,791✔
302

303
  ipWhiteMgt.pIpWhiteTab = pNew;
1,791✔
304
  ipWhiteMgt.ver++;
1,791✔
305

306
  destroyIpWhiteTab(pOld);
1,791✔
307
  TAOS_RETURN(0);
1,791✔
308
}
309

310
#if 0
311
void ipWhiteMgtUpdate2(SMnode *pMnode) {
312
  (void)taosThreadRwlockWrlock(&ipWhiteMgt.rw);
313

314
  ipWhiteMgtUpdateAll(pMnode);
315

316
  (void)taosThreadRwlockUnlock(&ipWhiteMgt.rw);
317
}
318
#endif
319

320
int64_t mndGetIpWhiteVer(SMnode *pMnode) {
100,851✔
321
  int64_t ver = 0;
100,851✔
322
  int32_t code = 0;
100,851✔
323
  (void)taosThreadRwlockWrlock(&ipWhiteMgt.rw);
100,851✔
324
  if (ipWhiteMgt.ver == 0) {
100,853!
325
    // get user and dnode ip white list
326
    if ((code = ipWhiteMgtUpdateAll(pMnode)) != 0) {
×
327
      (void)taosThreadRwlockUnlock(&ipWhiteMgt.rw);
×
328
      mError("%s failed to update ip white list since %s", __func__, tstrerror(code));
×
329
      return ver;
×
330
    }
331
    ipWhiteMgt.ver = taosGetTimestampMs();
×
332
  }
333
  ver = ipWhiteMgt.ver;
100,853✔
334
  (void)taosThreadRwlockUnlock(&ipWhiteMgt.rw);
100,853✔
335

336
  if (mndEnableIpWhiteList(pMnode) == 0 || tsEnableWhiteList == false) {
100,852!
337
    ver = 0;
100,835✔
338
  }
339
  mDebug("ip-white-list on mnode ver: %" PRId64 "", ver);
100,852✔
340
  return ver;
100,852✔
341
}
342

343
int32_t mndUpdateIpWhiteImpl(SHashObj *pIpWhiteTab, char *user, char *fqdn, int8_t type, bool *pUpdate) {
6,024✔
344
  int32_t    lino = 0;
6,024✔
345
  bool       update = false;
6,024✔
346
  SIpV4Range range = {.ip = 0, .mask = 32};
6,024✔
347
  int32_t    code = taosGetIpv4FromFqdn(fqdn, &range.ip);
6,024✔
348
  if (code) {
6,024!
349
    mError("failed to get ip from fqdn: %s at line %d since %s", fqdn, lino, tstrerror(code));
×
350
    TAOS_RETURN(TSDB_CODE_TSC_INVALID_FQDN);
×
351
  }
352
  mDebug("ip-white-list may update for user: %s, fqdn: %s", user, fqdn);
6,024✔
353
  SIpWhiteList **ppList = taosHashGet(pIpWhiteTab, user, strlen(user));
6,024✔
354
  SIpWhiteList  *pList = NULL;
6,024✔
355
  if (ppList != NULL && *ppList != NULL) {
6,024!
356
    pList = *ppList;
4,732✔
357
  }
358

359
  if (type == IP_WHITE_ADD) {
6,024✔
360
    if (pList == NULL) {
6,003✔
361
      SIpWhiteList *pNewList = taosMemoryCalloc(1, sizeof(SIpWhiteList) + sizeof(SIpV4Range));
1,290!
362
      if (pNewList == NULL) {
1,290!
363
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
364
      }
365
      (void)memcpy(pNewList->pIpRange, &range, sizeof(SIpV4Range));
1,290✔
366
      pNewList->num = 1;
1,290✔
367

368
      if ((code = taosHashPut(pIpWhiteTab, user, strlen(user), &pNewList, sizeof(void *))) != 0) {
1,290!
369
        taosMemoryFree(pNewList);
×
370
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
371
      }
372
      update = true;
1,290✔
373
    } else {
374
      if (!isRangeInWhiteList(pList, &range)) {
4,713✔
375
        int32_t       sz = sizeof(SIpWhiteList) + sizeof(SIpV4Range) * (pList->num + 1);
262✔
376
        SIpWhiteList *pNewList = taosMemoryCalloc(1, sz);
262!
377
        if (pNewList == NULL) {
262!
378
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
379
        }
380
        (void)memcpy(pNewList->pIpRange, pList->pIpRange, sizeof(SIpV4Range) * (pList->num));
262✔
381
        pNewList->pIpRange[pList->num].ip = range.ip;
262✔
382
        pNewList->pIpRange[pList->num].mask = range.mask;
262✔
383

384
        pNewList->num = pList->num + 1;
262✔
385

386
        if ((code = taosHashPut(pIpWhiteTab, user, strlen(user), &pNewList, sizeof(void *))) != 0) {
262!
387
          taosMemoryFree(pNewList);
×
388
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
389
        }
390
        taosMemoryFree(pList);
262!
391
        update = true;
262✔
392
      }
393
    }
394
  } else if (type == IP_WHITE_DROP) {
21!
395
    if (pList != NULL) {
21✔
396
      if (isRangeInWhiteList(pList, &range)) {
19!
397
        if (pList->num == 1) {
19!
398
          if (taosHashRemove(pIpWhiteTab, user, strlen(user)) < 0) {
19!
399
            mError("failed to remove ip-white-list for user: %s at line %d", user, lino);
×
400
          }
401
          taosMemoryFree(pList);
19!
402
        } else {
403
          int32_t       idx = 0;
×
404
          int32_t       sz = sizeof(SIpWhiteList) + sizeof(SIpV4Range) * (pList->num - 1);
×
405
          SIpWhiteList *pNewList = taosMemoryCalloc(1, sz);
×
406
          if (pNewList == NULL) {
×
407
            TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
408
          }
409
          for (int i = 0; i < pList->num; i++) {
×
410
            SIpV4Range *e = &pList->pIpRange[i];
×
411
            if (!isIpRangeEqual(e, &range)) {
×
412
              pNewList->pIpRange[idx].ip = e->ip;
×
413
              pNewList->pIpRange[idx].mask = e->mask;
×
414
              idx++;
×
415
            }
416
          }
417
          pNewList->num = idx;
×
418
          if ((code = taosHashPut(pIpWhiteTab, user, strlen(user), &pNewList, sizeof(void *)) != 0)) {
×
419
            taosMemoryFree(pNewList);
×
420
            TAOS_CHECK_GOTO(code, &lino, _OVER);
×
421
          }
422
          taosMemoryFree(pList);
×
423
        }
424
        update = true;
19✔
425
      }
426
    }
427
  }
428
  if (update) {
6,024✔
429
    mDebug("ip-white-list update for user: %s, fqdn: %s", user, fqdn);
1,571✔
430
  }
431

432
_OVER:
4,529✔
433
  if (pUpdate) *pUpdate = update;
6,024✔
434
  if (code < 0) {
6,024!
435
    mError("failed to update ip-white-list for user: %s, fqdn: %s at line %d since %s", user, fqdn, lino,
×
436
           tstrerror(code));
437
  }
438
  TAOS_RETURN(code);
6,024✔
439
}
440

441
int32_t mndRefreshUserIpWhiteList(SMnode *pMnode) {
1,791✔
442
  int32_t code = 0;
1,791✔
443
  (void)taosThreadRwlockWrlock(&ipWhiteMgt.rw);
1,791✔
444

445
  if ((code = ipWhiteMgtUpdateAll(pMnode)) != 0) {
1,791!
446
    (void)taosThreadRwlockUnlock(&ipWhiteMgt.rw);
×
447
    TAOS_RETURN(code);
×
448
  }
449
  ipWhiteMgt.ver = taosGetTimestampMs();
1,791✔
450
  (void)taosThreadRwlockUnlock(&ipWhiteMgt.rw);
1,791✔
451

452
  TAOS_RETURN(code);
1,791✔
453
}
454

455
int32_t mndUpdateIpWhiteForAllUser(SMnode *pMnode, char *user, char *fqdn, int8_t type, int8_t lock) {
1,762✔
456
  int32_t code = 0;
1,762✔
457
  int32_t lino = 0;
1,762✔
458
  bool    update = false;
1,762✔
459

460
  if (lock) {
1,762!
461
    (void)taosThreadRwlockWrlock(&ipWhiteMgt.rw);
1,762✔
462
    if (ipWhiteMgt.ver == 0) {
1,762!
463
      TAOS_CHECK_GOTO(ipWhiteMgtUpdateAll(pMnode), &lino, _OVER);
×
464
      ipWhiteMgt.ver = taosGetTimestampMs();
×
465
      mInfo("update ip-white-list, user: %s, ver: %" PRId64, user, ipWhiteMgt.ver);
×
466
    }
467
  }
468

469
  TAOS_CHECK_GOTO(mndUpdateIpWhiteImpl(ipWhiteMgt.pIpWhiteTab, user, fqdn, type, &update), &lino, _OVER);
1,762!
470

471
  void *pIter = taosHashIterate(ipWhiteMgt.pIpWhiteTab, NULL);
1,762✔
472
  while (pIter) {
3,529✔
473
    size_t klen = 0;
1,767✔
474
    char  *key = taosHashGetKey(pIter, &klen);
1,767✔
475

476
    char *keyDup = taosMemoryCalloc(1, klen + 1);
1,767!
477
    if (keyDup == NULL) {
1,767!
478
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
479
    }
480
    (void)memcpy(keyDup, key, klen);
1,767✔
481
    bool upd = false;
1,767✔
482
    code = mndUpdateIpWhiteImpl(ipWhiteMgt.pIpWhiteTab, keyDup, fqdn, type, &upd);
1,767✔
483
    update |= upd;
1,767✔
484
    if (code < 0) {
1,767!
485
      taosMemoryFree(keyDup);
×
486
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
487
    }
488
    taosMemoryFree(keyDup);
1,767!
489

490
    pIter = taosHashIterate(ipWhiteMgt.pIpWhiteTab, pIter);
1,767✔
491
  }
492

493
_OVER:
1,762✔
494
  if (update) ipWhiteMgt.ver++;
1,762✔
495
  if (lock) (void)taosThreadRwlockUnlock(&ipWhiteMgt.rw);
1,762!
496
  if (code < 0) {
1,762!
497
    mError("failed to update ip-white-list for user: %s, fqdn: %s at line %d since %s", user, fqdn, lino,
×
498
           tstrerror(code));
499
  }
500

501
  TAOS_RETURN(code);
1,762✔
502
}
503

504
static int64_t ipWhiteMgtFillMsg(SUpdateIpWhite *pUpdate) {
6✔
505
  int64_t ver = 0;
6✔
506
  (void)taosThreadRwlockWrlock(&ipWhiteMgt.rw);
6✔
507
  ver = ipWhiteMgt.ver;
6✔
508
  int32_t num = taosHashGetSize(ipWhiteMgt.pIpWhiteTab);
6✔
509

510
  pUpdate->pUserIpWhite = taosMemoryCalloc(1, num * sizeof(SUpdateUserIpWhite));
6!
511
  if (pUpdate->pUserIpWhite == NULL) {
6!
512
    (void)taosThreadRwlockUnlock(&ipWhiteMgt.rw);
×
513
    TAOS_RETURN(terrno);
×
514
  }
515

516
  void   *pIter = taosHashIterate(ipWhiteMgt.pIpWhiteTab, NULL);
6✔
517
  int32_t i = 0;
6✔
518
  while (pIter) {
12✔
519
    SUpdateUserIpWhite *pUser = &pUpdate->pUserIpWhite[i];
6✔
520
    SIpWhiteList       *list = *(SIpWhiteList **)pIter;
6✔
521

522
    size_t klen;
523
    char  *key = taosHashGetKey(pIter, &klen);
6✔
524
    if (list->num != 0) {
6!
525
      pUser->ver = ver;
6✔
526
      (void)memcpy(pUser->user, key, klen);
6✔
527
      pUser->numOfRange = list->num;
6✔
528
      pUser->pIpRanges = taosMemoryCalloc(1, list->num * sizeof(SIpV4Range));
6!
529
      if (pUser->pIpRanges == NULL) {
6!
530
        (void)taosThreadRwlockUnlock(&ipWhiteMgt.rw);
×
531
        TAOS_RETURN(terrno);
×
532
      }
533
      (void)memcpy(pUser->pIpRanges, list->pIpRange, list->num * sizeof(SIpV4Range));
6✔
534
      i++;
6✔
535
    }
536
    pIter = taosHashIterate(ipWhiteMgt.pIpWhiteTab, pIter);
6✔
537
  }
538
  pUpdate->numOfUser = i;
6✔
539
  pUpdate->ver = ver;
6✔
540

541
  (void)taosThreadRwlockUnlock(&ipWhiteMgt.rw);
6✔
542
  TAOS_RETURN(0);
6✔
543
}
544

545
void destroyIpWhiteTab(SHashObj *pIpWhiteTab) {
3,564✔
546
  if (pIpWhiteTab == NULL) return;
3,564!
547

548
  void *pIter = taosHashIterate(pIpWhiteTab, NULL);
3,564✔
549
  while (pIter) {
5,352✔
550
    SIpWhiteList *list = *(SIpWhiteList **)pIter;
1,788✔
551
    taosMemoryFree(list);
1,788!
552
    pIter = taosHashIterate(pIpWhiteTab, pIter);
1,788✔
553
  }
554

555
  taosHashCleanup(pIpWhiteTab);
3,564✔
556
}
557
int32_t mndFetchAllIpWhite(SMnode *pMnode, SHashObj **ppIpWhiteTab) {
1,791✔
558
  int32_t   code = 0;
1,791✔
559
  int32_t   lino = 0;
1,791✔
560
  SSdb     *pSdb = pMnode->pSdb;
1,791✔
561
  void     *pIter = NULL;
1,791✔
562
  SHashObj *pIpWhiteTab = NULL;
1,791✔
563
  SArray   *pUserNames = NULL;
1,791✔
564
  SArray   *fqdns = NULL;
1,791✔
565

566
  pIpWhiteTab = taosHashInit(8, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), 1, HASH_ENTRY_LOCK);
1,791✔
567
  if (pIpWhiteTab == NULL) {
1,791!
568
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
569
  }
570
  pUserNames = taosArrayInit(8, sizeof(void *));
1,791✔
571
  if (pUserNames == NULL) {
1,791!
572
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
573
  }
574

575
  while (1) {
416✔
576
    SUserObj *pUser = NULL;
2,207✔
577
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
2,207✔
578
    if (pIter == NULL) break;
2,207✔
579

580
    SIpWhiteList *pWhiteList = cloneIpWhiteList(pUser->pIpWhiteList);
416✔
581
    if (pWhiteList == NULL) {
416!
582
      sdbRelease(pSdb, pUser);
×
583
      sdbCancelFetch(pSdb, pIter);
×
584
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
585
    }
586
    if ((code = taosHashPut(pIpWhiteTab, pUser->user, strlen(pUser->user), &pWhiteList, sizeof(void *))) != 0) {
416!
587
      taosMemoryFree(pWhiteList);
×
588
      sdbRelease(pSdb, pUser);
×
589
      sdbCancelFetch(pSdb, pIter);
×
590
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
591
    }
592

593
    char *name = taosStrdup(pUser->user);
416!
594
    if (name == NULL) {
416!
595
      sdbRelease(pSdb, pUser);
×
596
      sdbCancelFetch(pSdb, pIter);
×
597
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
598
    }
599
    if (taosArrayPush(pUserNames, &name) == NULL) {
416!
600
      taosMemoryFree(name);
×
601
      sdbRelease(pSdb, pUser);
×
602
      sdbCancelFetch(pSdb, pIter);
×
603
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
604
    }
605

606
    sdbRelease(pSdb, pUser);
416✔
607
  }
608

609
  bool found = false;
1,791✔
610
  for (int i = 0; i < taosArrayGetSize(pUserNames); i++) {
1,795✔
611
    char *name = taosArrayGetP(pUserNames, i);
415✔
612
    if (strlen(name) == strlen(TSDB_DEFAULT_USER) && strncmp(name, TSDB_DEFAULT_USER, strlen(TSDB_DEFAULT_USER)) == 0) {
415!
613
      found = true;
411✔
614
      break;
411✔
615
    }
616
  }
617
  if (found == false) {
1,791✔
618
    char *name = taosStrdup(TSDB_DEFAULT_USER);
1,380!
619
    if (name == NULL) {
1,380!
620
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
621
    }
622
    if (taosArrayPush(pUserNames, &name) == NULL) {
1,380!
623
      taosMemoryFree(name);
×
624
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
625
    }
626
  }
627

628
  fqdns = mndGetAllDnodeFqdns(pMnode);  // TODO: refactor this line after refactor api
1,791✔
629
  if (fqdns == NULL) {
1,791!
630
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
631
  }
632

633
  for (int i = 0; i < taosArrayGetSize(fqdns); i++) {
3,130✔
634
    char *fqdn = taosArrayGetP(fqdns, i);
1,339✔
635

636
    for (int j = 0; j < taosArrayGetSize(pUserNames); j++) {
2,690✔
637
      char *name = taosArrayGetP(pUserNames, j);
1,351✔
638
      TAOS_CHECK_GOTO(mndUpdateIpWhiteImpl(pIpWhiteTab, name, fqdn, IP_WHITE_ADD, NULL), &lino, _OVER);
1,351!
639
    }
640
  }
641

642
_OVER:
1,791✔
643
  taosArrayDestroyP(fqdns, NULL);
1,791✔
644
  taosArrayDestroyP(pUserNames, NULL);
1,791✔
645

646
  if (code < 0) {
1,791!
647
    mError("failed to fetch all ip white list at line %d since %s", lino, tstrerror(code));
×
648
    destroyIpWhiteTab(pIpWhiteTab);
×
649
    pIpWhiteTab = NULL;
×
650
  }
651
  *ppIpWhiteTab = pIpWhiteTab;
1,791✔
652
  TAOS_RETURN(code);
1,791✔
653
}
654

655
int32_t mndInitUser(SMnode *pMnode) {
1,774✔
656
  TAOS_CHECK_RETURN(ipWhiteMgtInit());
1,774!
657

658
  SSdbTable table = {
1,774✔
659
      .sdbType = SDB_USER,
660
      .keyType = SDB_KEY_BINARY,
661
      .deployFp = (SdbDeployFp)mndCreateDefaultUsers,
662
      .encodeFp = (SdbEncodeFp)mndUserActionEncode,
663
      .decodeFp = (SdbDecodeFp)mndUserActionDecode,
664
      .insertFp = (SdbInsertFp)mndUserActionInsert,
665
      .updateFp = (SdbUpdateFp)mndUserActionUpdate,
666
      .deleteFp = (SdbDeleteFp)mndUserActionDelete,
667
  };
668

669
  mndSetMsgHandle(pMnode, TDMT_MND_CREATE_USER, mndProcessCreateUserReq);
1,774✔
670
  mndSetMsgHandle(pMnode, TDMT_MND_ALTER_USER, mndProcessAlterUserReq);
1,774✔
671
  mndSetMsgHandle(pMnode, TDMT_MND_DROP_USER, mndProcessDropUserReq);
1,774✔
672
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_AUTH, mndProcessGetUserAuthReq);
1,774✔
673
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_WHITELIST, mndProcessGetUserWhiteListReq);
1,774✔
674

675
  mndSetMsgHandle(pMnode, TDMT_MND_RETRIEVE_IP_WHITE, mndProcesSRetrieveIpWhiteReq);
1,774✔
676

677
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_USER, mndRetrieveUsers);
1,774✔
678
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_USER, mndCancelGetNextUser);
1,774✔
679
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_USER_FULL, mndRetrieveUsersFull);
1,774✔
680
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_USER_FULL, mndCancelGetNextUser);
1,774✔
681
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_PRIVILEGES, mndRetrievePrivileges);
1,774✔
682
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_PRIVILEGES, mndCancelGetNextPrivileges);
1,774✔
683
  return sdbSetTable(pMnode->pSdb, table);
1,774✔
684
}
685

686
void mndCleanupUser(SMnode *pMnode) { ipWhiteMgtCleanup(); }
1,773✔
687

688
static void ipRangeToStr(SIpV4Range *range, char *buf) {
5,123✔
689
  struct in_addr addr;
690
  addr.s_addr = range->ip;
5,123✔
691

692
  (void)uv_inet_ntop(AF_INET, &addr, buf, 32);
5,123✔
693
  if (range->mask != 32) {
5,133✔
694
    (void)tsnprintf(buf + strlen(buf), 36 - strlen(buf), "/%d", range->mask);
6✔
695
  }
696
  return;
5,136✔
697
}
698
static bool isDefaultRange(SIpV4Range *pRange) {
2✔
699
  static SIpV4Range val = {.ip = 16777343, .mask = 32};
700
  return pRange->ip == val.ip && pRange->mask == val.mask;
2!
701
}
702
static int32_t ipRangeListToStr(SIpV4Range *range, int32_t num, char *buf, int64_t bufLen) {
5,117✔
703
  int32_t len = 0;
5,117✔
704
  for (int i = 0; i < num; i++) {
10,258✔
705
    char        tbuf[36] = {0};
5,127✔
706
    SIpV4Range *pRange = &range[i];
5,127✔
707

708
    ipRangeToStr(&range[i], tbuf);
5,127✔
709
    len += tsnprintf(buf + len, bufLen - len, "%s,", tbuf);
5,137✔
710
  }
711
  if (len > 0) buf[len - 1] = 0;
5,131✔
712
  return len;
5,131✔
713
}
714

715
static bool isIpRangeEqual(SIpV4Range *a, SIpV4Range *b) {
6,003✔
716
  // equal or not
717
  return a->ip == b->ip && a->mask == b->mask;
6,003!
718
}
719
static bool isRangeInIpWhiteList(SIpWhiteList *pList, SIpV4Range *tgt) {
1✔
720
  for (int i = 0; i < pList->num; i++) {
4✔
721
    if (isIpRangeEqual(&pList->pIpRange[i], tgt)) return true;
3!
722
  }
723
  return false;
1✔
724
}
725
static bool isIpWhiteListEqual(SIpWhiteList *a, SIpWhiteList *b) {
221✔
726
  if (a->num != b->num) {
221✔
727
    return false;
22✔
728
  }
729
  for (int i = 0; i < a->num; i++) {
398✔
730
    if (!isIpRangeEqual(&a->pIpRange[i], &b->pIpRange[i])) {
199!
731
      return false;
×
732
    }
733
  }
734
  return true;
199✔
735
}
736
int32_t convertIpWhiteListToStr(SIpWhiteList *pList, char **buf) {
5,113✔
737
  if (pList->num == 0) {
5,113!
738
    *buf = NULL;
×
739
    return 0;
×
740
  }
741
  int64_t bufLen = pList->num * 36;
5,113✔
742
  *buf = taosMemoryCalloc(1, bufLen);
5,113!
743
  if (*buf == NULL) {
5,129!
744
    return 0;
×
745
  }
746

747
  int32_t len = ipRangeListToStr(pList->pIpRange, pList->num, *buf, bufLen);
5,129✔
748
  if (len == 0) {
5,128!
749
    taosMemoryFreeClear(*buf);
×
750
    return 0;
×
751
  }
752
  return strlen(*buf);
5,128✔
753
}
754
int32_t tSerializeIpWhiteList(void *buf, int32_t len, SIpWhiteList *pList, uint32_t *pLen) {
4,923✔
755
  int32_t  code = 0;
4,923✔
756
  int32_t  lino = 0;
4,923✔
757
  int32_t  tlen = 0;
4,923✔
758
  SEncoder encoder = {0};
4,923✔
759
  tEncoderInit(&encoder, buf, len);
4,923✔
760

761
  TAOS_CHECK_GOTO(tStartEncode(&encoder), &lino, _OVER);
4,923!
762
  TAOS_CHECK_GOTO(tEncodeI32(&encoder, pList->num), &lino, _OVER);
9,846!
763

764
  for (int i = 0; i < pList->num; i++) {
9,856✔
765
    SIpV4Range *pRange = &(pList->pIpRange[i]);
4,933✔
766
    TAOS_CHECK_GOTO(tEncodeU32(&encoder, pRange->ip), &lino, _OVER);
9,866!
767
    TAOS_CHECK_GOTO(tEncodeU32(&encoder, pRange->mask), &lino, _OVER);
9,866!
768
  }
769

770
  tEndEncode(&encoder);
4,923✔
771

772
  tlen = encoder.pos;
4,923✔
773
_OVER:
4,923✔
774
  tEncoderClear(&encoder);
4,923✔
775
  if (code < 0) {
4,923!
776
    mError("failed to serialize ip white list at line %d since %s", lino, tstrerror(code));
×
777
  }
778
  if (pLen) *pLen = tlen;
4,923!
779
  TAOS_RETURN(code);
4,923✔
780
}
781

782
int32_t tDerializeIpWhileList(void *buf, int32_t len, SIpWhiteList *pList) {
2,378✔
783
  int32_t  code = 0;
2,378✔
784
  int32_t  lino = 0;
2,378✔
785
  SDecoder decoder = {0};
2,378✔
786
  tDecoderInit(&decoder, buf, len);
2,378✔
787

788
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
2,378!
789
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &pList->num), &lino, _OVER);
4,756!
790

791
  for (int i = 0; i < pList->num; i++) {
4,782✔
792
    SIpV4Range *pRange = &(pList->pIpRange[i]);
2,404✔
793
    TAOS_CHECK_GOTO(tDecodeU32(&decoder, &pRange->ip), &lino, _OVER);
4,808!
794
    TAOS_CHECK_GOTO(tDecodeU32(&decoder, &pRange->mask), &lino, _OVER);
4,808!
795
  }
796

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

804
  TAOS_RETURN(code);
2,378✔
805
}
806

807
static int32_t createIpWhiteList(void *buf, int32_t len, SIpWhiteList **ppList) {
2,378✔
808
  int32_t       code = 0;
2,378✔
809
  int32_t       lino = 0;
2,378✔
810
  int32_t       num = 0;
2,378✔
811
  SIpWhiteList *p = NULL;
2,378✔
812
  SDecoder      decoder = {0};
2,378✔
813
  tDecoderInit(&decoder, buf, len);
2,378✔
814

815
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
2,378!
816
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &num), &lino, _OVER);
2,378!
817

818
  p = taosMemoryCalloc(1, sizeof(SIpWhiteList) + num * sizeof(SIpV4Range));
2,378!
819
  if (p == NULL) {
2,378!
820
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
821
  }
822
  TAOS_CHECK_GOTO(tDerializeIpWhileList(buf, len, p), &lino, _OVER);
2,378!
823

824
_OVER:
2,378✔
825
  tEndDecode(&decoder);
2,378✔
826
  tDecoderClear(&decoder);
2,378✔
827
  if (code < 0) {
2,378!
828
    taosMemoryFreeClear(p);
×
829
    mError("failed to create ip white list at line %d since %s", lino, tstrerror(code));
×
830
  }
831
  *ppList = p;
2,378✔
832
  TAOS_RETURN(code);
2,378✔
833
}
834

835
static int32_t createDefaultIpWhiteList(SIpWhiteList **ppWhiteList) {
1,424✔
836
  *ppWhiteList = taosMemoryCalloc(1, sizeof(SIpWhiteList) + sizeof(SIpV4Range) * 1);
1,424!
837
  if (*ppWhiteList == NULL) {
1,424!
838
    TAOS_RETURN(terrno);
×
839
  }
840
  (*ppWhiteList)->num = 1;
1,424✔
841
  SIpV4Range *range = &((*ppWhiteList)->pIpRange[0]);
1,424✔
842

843
  struct in_addr addr;
844
  if (uv_inet_pton(AF_INET, "127.0.0.1", &addr) == 0) {
1,424!
845
    range->ip = addr.s_addr;
1,424✔
846
    range->mask = 32;
1,424✔
847
  }
848
  return 0;
1,424✔
849
}
850

851
static int32_t mndCreateDefaultUser(SMnode *pMnode, char *acct, char *user, char *pass) {
1,284✔
852
  int32_t  code = 0;
1,284✔
853
  int32_t  lino = 0;
1,284✔
854
  SUserObj userObj = {0};
1,284✔
855
  taosEncryptPass_c((uint8_t *)pass, strlen(pass), userObj.pass);
1,284✔
856
  tstrncpy(userObj.user, user, TSDB_USER_LEN);
1,284✔
857
  tstrncpy(userObj.acct, acct, TSDB_USER_LEN);
1,284✔
858
  userObj.createdTime = taosGetTimestampMs();
1,284✔
859
  userObj.updateTime = userObj.createdTime;
1,284✔
860
  userObj.sysInfo = 1;
1,284✔
861
  userObj.enable = 1;
1,284✔
862
  userObj.ipWhiteListVer = taosGetTimestampMs();
1,284✔
863
  TAOS_CHECK_RETURN(createDefaultIpWhiteList(&userObj.pIpWhiteList));
1,284!
864
  if (strcmp(user, TSDB_DEFAULT_USER) == 0) {
1,284!
865
    userObj.superUser = 1;
1,284✔
866
    userObj.createdb = 1;
1,284✔
867
  }
868

869
  SSdbRaw *pRaw = mndUserActionEncode(&userObj);
1,284✔
870
  if (pRaw == NULL) goto _ERROR;
1,284!
871
  TAOS_CHECK_GOTO(sdbSetRawStatus(pRaw, SDB_STATUS_READY), &lino, _ERROR);
1,284!
872

873
  mInfo("user:%s, will be created when deploying, raw:%p", userObj.user, pRaw);
1,284!
874

875
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, NULL, "create-user");
1,284✔
876
  if (pTrans == NULL) {
1,284!
877
    sdbFreeRaw(pRaw);
×
878
    mError("user:%s, failed to create since %s", userObj.user, terrstr());
×
879
    goto _ERROR;
×
880
  }
881
  mInfo("trans:%d, used to create user:%s", pTrans->id, userObj.user);
1,284!
882

883
  if (mndTransAppendCommitlog(pTrans, pRaw) != 0) {
1,284!
884
    mError("trans:%d, failed to commit redo log since %s", pTrans->id, terrstr());
×
885
    mndTransDrop(pTrans);
×
886
    goto _ERROR;
×
887
  }
888
  TAOS_CHECK_GOTO(sdbSetRawStatus(pRaw, SDB_STATUS_READY), &lino, _ERROR);
1,284!
889

890
  if (mndTransPrepare(pMnode, pTrans) != 0) {
1,284!
891
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
892
    mndTransDrop(pTrans);
×
893
    goto _ERROR;
×
894
  }
895

896
  mndTransDrop(pTrans);
1,284✔
897
  taosMemoryFree(userObj.pIpWhiteList);
1,284!
898
  return 0;
1,284✔
899
_ERROR:
×
900
  taosMemoryFree(userObj.pIpWhiteList);
×
901
  TAOS_RETURN(terrno ? terrno : TSDB_CODE_APP_ERROR);
×
902
}
903

904
static int32_t mndCreateDefaultUsers(SMnode *pMnode) {
1,284✔
905
  return mndCreateDefaultUser(pMnode, TSDB_DEFAULT_USER, TSDB_DEFAULT_USER, TSDB_DEFAULT_PASS);
1,284✔
906
}
907

908
SSdbRaw *mndUserActionEncode(SUserObj *pUser) {
4,923✔
909
  int32_t code = 0;
4,923✔
910
  int32_t lino = 0;
4,923✔
911
  int32_t ipWhiteReserve =
×
912
      pUser->pIpWhiteList ? (sizeof(SIpV4Range) * pUser->pIpWhiteList->num + sizeof(SIpWhiteList) + 4) : 16;
4,923!
913
  int32_t numOfReadDbs = taosHashGetSize(pUser->readDbs);
4,923✔
914
  int32_t numOfWriteDbs = taosHashGetSize(pUser->writeDbs);
4,923✔
915
  int32_t numOfReadTbs = taosHashGetSize(pUser->readTbs);
4,923✔
916
  int32_t numOfWriteTbs = taosHashGetSize(pUser->writeTbs);
4,923✔
917
  int32_t numOfAlterTbs = taosHashGetSize(pUser->alterTbs);
4,923✔
918
  int32_t numOfReadViews = taosHashGetSize(pUser->readViews);
4,923✔
919
  int32_t numOfWriteViews = taosHashGetSize(pUser->writeViews);
4,923✔
920
  int32_t numOfAlterViews = taosHashGetSize(pUser->alterViews);
4,923✔
921
  int32_t numOfTopics = taosHashGetSize(pUser->topics);
4,923✔
922
  int32_t numOfUseDbs = taosHashGetSize(pUser->useDbs);
4,923✔
923
  int32_t size = sizeof(SUserObj) + USER_RESERVE_SIZE + (numOfReadDbs + numOfWriteDbs) * TSDB_DB_FNAME_LEN +
4,923✔
924
                 numOfTopics * TSDB_TOPIC_FNAME_LEN + ipWhiteReserve;
4,923✔
925
  char    *buf = NULL;
4,923✔
926
  SSdbRaw *pRaw = NULL;
4,923✔
927

928
  char *stb = taosHashIterate(pUser->readTbs, NULL);
4,923✔
929
  while (stb != NULL) {
4,961✔
930
    size_t keyLen = 0;
38✔
931
    void  *key = taosHashGetKey(stb, &keyLen);
38✔
932
    size += sizeof(int32_t);
38✔
933
    size += keyLen;
38✔
934

935
    size_t valueLen = 0;
38✔
936
    valueLen = strlen(stb) + 1;
38✔
937
    size += sizeof(int32_t);
38✔
938
    size += valueLen;
38✔
939
    stb = taosHashIterate(pUser->readTbs, stb);
38✔
940
  }
941

942
  stb = taosHashIterate(pUser->writeTbs, NULL);
4,923✔
943
  while (stb != NULL) {
4,973✔
944
    size_t keyLen = 0;
50✔
945
    void  *key = taosHashGetKey(stb, &keyLen);
50✔
946
    size += sizeof(int32_t);
50✔
947
    size += keyLen;
50✔
948

949
    size_t valueLen = 0;
50✔
950
    valueLen = strlen(stb) + 1;
50✔
951
    size += sizeof(int32_t);
50✔
952
    size += valueLen;
50✔
953
    stb = taosHashIterate(pUser->writeTbs, stb);
50✔
954
  }
955

956
  stb = taosHashIterate(pUser->alterTbs, NULL);
4,923✔
957
  while (stb != NULL) {
4,931✔
958
    size_t keyLen = 0;
8✔
959
    void  *key = taosHashGetKey(stb, &keyLen);
8✔
960
    size += sizeof(int32_t);
8✔
961
    size += keyLen;
8✔
962

963
    size_t valueLen = 0;
8✔
964
    valueLen = strlen(stb) + 1;
8✔
965
    size += sizeof(int32_t);
8✔
966
    size += valueLen;
8✔
967
    stb = taosHashIterate(pUser->alterTbs, stb);
8✔
968
  }
969

970
  stb = taosHashIterate(pUser->readViews, NULL);
4,923✔
971
  while (stb != NULL) {
4,975✔
972
    size_t keyLen = 0;
52✔
973
    void  *key = taosHashGetKey(stb, &keyLen);
52✔
974
    size += sizeof(int32_t);
52✔
975
    size += keyLen;
52✔
976

977
    size_t valueLen = 0;
52✔
978
    valueLen = strlen(stb) + 1;
52✔
979
    size += sizeof(int32_t);
52✔
980
    size += valueLen;
52✔
981
    stb = taosHashIterate(pUser->readViews, stb);
52✔
982
  }
983

984
  stb = taosHashIterate(pUser->writeViews, NULL);
4,923✔
985
  while (stb != NULL) {
4,967✔
986
    size_t keyLen = 0;
44✔
987
    void  *key = taosHashGetKey(stb, &keyLen);
44✔
988
    size += sizeof(int32_t);
44✔
989
    size += keyLen;
44✔
990

991
    size_t valueLen = 0;
44✔
992
    valueLen = strlen(stb) + 1;
44✔
993
    size += sizeof(int32_t);
44✔
994
    size += valueLen;
44✔
995
    stb = taosHashIterate(pUser->writeViews, stb);
44✔
996
  }
997

998
  stb = taosHashIterate(pUser->alterViews, NULL);
4,923✔
999
  while (stb != NULL) {
4,969✔
1000
    size_t keyLen = 0;
46✔
1001
    void  *key = taosHashGetKey(stb, &keyLen);
46✔
1002
    size += sizeof(int32_t);
46✔
1003
    size += keyLen;
46✔
1004

1005
    size_t valueLen = 0;
46✔
1006
    valueLen = strlen(stb) + 1;
46✔
1007
    size += sizeof(int32_t);
46✔
1008
    size += valueLen;
46✔
1009
    stb = taosHashIterate(pUser->alterViews, stb);
46✔
1010
  }
1011

1012
  int32_t *useDb = taosHashIterate(pUser->useDbs, NULL);
4,923✔
1013
  while (useDb != NULL) {
5,053✔
1014
    size_t keyLen = 0;
130✔
1015
    void  *key = taosHashGetKey(useDb, &keyLen);
130✔
1016
    size += sizeof(int32_t);
130✔
1017
    size += keyLen;
130✔
1018
    size += sizeof(int32_t);
130✔
1019
    useDb = taosHashIterate(pUser->useDbs, useDb);
130✔
1020
  }
1021

1022
  pRaw = sdbAllocRaw(SDB_USER, USER_VER_NUMBER, size);
4,923✔
1023
  if (pRaw == NULL) {
4,923!
1024
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1025
  }
1026

1027
  int32_t dataPos = 0;
4,923✔
1028
  SDB_SET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN, _OVER)
4,923!
1029
  SDB_SET_BINARY(pRaw, dataPos, pUser->pass, TSDB_PASSWORD_LEN, _OVER)
4,923!
1030
  SDB_SET_BINARY(pRaw, dataPos, pUser->acct, TSDB_USER_LEN, _OVER)
4,923!
1031
  SDB_SET_INT64(pRaw, dataPos, pUser->createdTime, _OVER)
4,923!
1032
  SDB_SET_INT64(pRaw, dataPos, pUser->updateTime, _OVER)
4,923!
1033
  SDB_SET_INT8(pRaw, dataPos, pUser->superUser, _OVER)
4,923!
1034
  SDB_SET_INT8(pRaw, dataPos, pUser->sysInfo, _OVER)
4,923!
1035
  SDB_SET_INT8(pRaw, dataPos, pUser->enable, _OVER)
4,923!
1036
  SDB_SET_UINT8(pRaw, dataPos, pUser->flag, _OVER)
4,923!
1037
  SDB_SET_INT32(pRaw, dataPos, pUser->authVersion, _OVER)
4,923!
1038
  SDB_SET_INT32(pRaw, dataPos, pUser->passVersion, _OVER)
4,923!
1039
  SDB_SET_INT32(pRaw, dataPos, numOfReadDbs, _OVER)
4,923!
1040
  SDB_SET_INT32(pRaw, dataPos, numOfWriteDbs, _OVER)
4,923!
1041
  SDB_SET_INT32(pRaw, dataPos, numOfTopics, _OVER)
4,923!
1042

1043
  char *db = taosHashIterate(pUser->readDbs, NULL);
4,923✔
1044
  while (db != NULL) {
5,028✔
1045
    SDB_SET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER);
105!
1046
    db = taosHashIterate(pUser->readDbs, db);
105✔
1047
  }
1048

1049
  db = taosHashIterate(pUser->writeDbs, NULL);
4,923✔
1050
  while (db != NULL) {
5,022✔
1051
    SDB_SET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER);
99!
1052
    db = taosHashIterate(pUser->writeDbs, db);
99✔
1053
  }
1054

1055
  char *topic = taosHashIterate(pUser->topics, NULL);
4,923✔
1056
  while (topic != NULL) {
4,960✔
1057
    SDB_SET_BINARY(pRaw, dataPos, topic, TSDB_TOPIC_FNAME_LEN, _OVER);
37!
1058
    topic = taosHashIterate(pUser->topics, topic);
37✔
1059
  }
1060

1061
  SDB_SET_INT32(pRaw, dataPos, numOfReadTbs, _OVER)
4,923!
1062
  SDB_SET_INT32(pRaw, dataPos, numOfWriteTbs, _OVER)
4,923!
1063
  SDB_SET_INT32(pRaw, dataPos, numOfAlterTbs, _OVER)
4,923!
1064
  SDB_SET_INT32(pRaw, dataPos, numOfReadViews, _OVER)
4,923!
1065
  SDB_SET_INT32(pRaw, dataPos, numOfWriteViews, _OVER)
4,923!
1066
  SDB_SET_INT32(pRaw, dataPos, numOfAlterViews, _OVER)
4,923!
1067
  SDB_SET_INT32(pRaw, dataPos, numOfUseDbs, _OVER)
4,923!
1068

1069
  stb = taosHashIterate(pUser->readTbs, NULL);
4,923✔
1070
  while (stb != NULL) {
4,961✔
1071
    size_t keyLen = 0;
38✔
1072
    void  *key = taosHashGetKey(stb, &keyLen);
38✔
1073
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
38!
1074
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
38!
1075

1076
    size_t valueLen = 0;
38✔
1077
    valueLen = strlen(stb) + 1;
38✔
1078
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
38!
1079
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
38!
1080
    stb = taosHashIterate(pUser->readTbs, stb);
38✔
1081
  }
1082

1083
  stb = taosHashIterate(pUser->writeTbs, NULL);
4,923✔
1084
  while (stb != NULL) {
4,973✔
1085
    size_t keyLen = 0;
50✔
1086
    void  *key = taosHashGetKey(stb, &keyLen);
50✔
1087
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
50!
1088
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
50!
1089

1090
    size_t valueLen = 0;
50✔
1091
    valueLen = strlen(stb) + 1;
50✔
1092
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
50!
1093
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
50!
1094
    stb = taosHashIterate(pUser->writeTbs, stb);
50✔
1095
  }
1096

1097
  stb = taosHashIterate(pUser->alterTbs, NULL);
4,923✔
1098
  while (stb != NULL) {
4,931✔
1099
    size_t keyLen = 0;
8✔
1100
    void  *key = taosHashGetKey(stb, &keyLen);
8✔
1101
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
8!
1102
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
8!
1103

1104
    size_t valueLen = 0;
8✔
1105
    valueLen = strlen(stb) + 1;
8✔
1106
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
8!
1107
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
8!
1108
    stb = taosHashIterate(pUser->alterTbs, stb);
8✔
1109
  }
1110

1111
  stb = taosHashIterate(pUser->readViews, NULL);
4,923✔
1112
  while (stb != NULL) {
4,975✔
1113
    size_t keyLen = 0;
52✔
1114
    void  *key = taosHashGetKey(stb, &keyLen);
52✔
1115
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
52!
1116
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
52!
1117

1118
    size_t valueLen = 0;
52✔
1119
    valueLen = strlen(stb) + 1;
52✔
1120
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
52!
1121
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
52!
1122
    stb = taosHashIterate(pUser->readViews, stb);
52✔
1123
  }
1124

1125
  stb = taosHashIterate(pUser->writeViews, NULL);
4,923✔
1126
  while (stb != NULL) {
4,967✔
1127
    size_t keyLen = 0;
44✔
1128
    void  *key = taosHashGetKey(stb, &keyLen);
44✔
1129
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
44!
1130
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
44!
1131

1132
    size_t valueLen = 0;
44✔
1133
    valueLen = strlen(stb) + 1;
44✔
1134
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
44!
1135
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
44!
1136
    stb = taosHashIterate(pUser->writeViews, stb);
44✔
1137
  }
1138

1139
  stb = taosHashIterate(pUser->alterViews, NULL);
4,923✔
1140
  while (stb != NULL) {
4,969✔
1141
    size_t keyLen = 0;
46✔
1142
    void  *key = taosHashGetKey(stb, &keyLen);
46✔
1143
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
46!
1144
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
46!
1145

1146
    size_t valueLen = 0;
46✔
1147
    valueLen = strlen(stb) + 1;
46✔
1148
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
46!
1149
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
46!
1150
    stb = taosHashIterate(pUser->alterViews, stb);
46✔
1151
  }
1152

1153
  useDb = taosHashIterate(pUser->useDbs, NULL);
4,923✔
1154
  while (useDb != NULL) {
5,053✔
1155
    size_t keyLen = 0;
130✔
1156
    void  *key = taosHashGetKey(useDb, &keyLen);
130✔
1157
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
130!
1158
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
130!
1159

1160
    SDB_SET_INT32(pRaw, dataPos, *useDb, _OVER)
130!
1161
    useDb = taosHashIterate(pUser->useDbs, useDb);
130✔
1162
  }
1163

1164
  // save white list
1165
  int32_t num = pUser->pIpWhiteList->num;
4,923✔
1166
  int32_t tlen = sizeof(SIpWhiteList) + num * sizeof(SIpV4Range) + 4;
4,923✔
1167
  if ((buf = taosMemoryCalloc(1, tlen)) == NULL) {
4,923!
1168
    TAOS_CHECK_GOTO(terrno, NULL, _OVER);
×
1169
  }
1170
  int32_t len = 0;
4,923✔
1171
  TAOS_CHECK_GOTO(tSerializeIpWhiteList(buf, tlen, pUser->pIpWhiteList, &len), &lino, _OVER);
4,923!
1172

1173
  SDB_SET_INT32(pRaw, dataPos, len, _OVER);
4,923!
1174
  SDB_SET_BINARY(pRaw, dataPos, buf, len, _OVER);
4,923!
1175

1176
  SDB_SET_INT64(pRaw, dataPos, pUser->ipWhiteListVer, _OVER);
4,923!
1177

1178
  SDB_SET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
4,923!
1179
  SDB_SET_DATALEN(pRaw, dataPos, _OVER)
4,923!
1180

1181
_OVER:
4,923✔
1182
  taosMemoryFree(buf);
4,923!
1183
  if (code < 0) {
4,923!
1184
    mError("user:%s, failed to encode user action to raw:%p at line %d since %s", pUser->user, pRaw, lino,
×
1185
           tstrerror(code));
1186
    sdbFreeRaw(pRaw);
×
1187
    pRaw = NULL;
×
1188
    terrno = code;
×
1189
  }
1190

1191
  mTrace("user:%s, encode user action to raw:%p, row:%p", pUser->user, pRaw, pUser);
4,923✔
1192
  return pRaw;
4,923✔
1193
}
1194

1195
static SSdbRow *mndUserActionDecode(SSdbRaw *pRaw) {
2,378✔
1196
  int32_t   code = 0;
2,378✔
1197
  int32_t   lino = 0;
2,378✔
1198
  SSdbRow  *pRow = NULL;
2,378✔
1199
  SUserObj *pUser = NULL;
2,378✔
1200
  char     *key = NULL;
2,378✔
1201
  char     *value = NULL;
2,378✔
1202

1203
  int8_t sver = 0;
2,378✔
1204
  if (sdbGetRawSoftVer(pRaw, &sver) != 0) {
2,378!
1205
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_PTR, &lino, _OVER);
×
1206
  }
1207

1208
  if (sver < 1 || sver > USER_VER_NUMBER) {
2,378!
1209
    TAOS_CHECK_GOTO(TSDB_CODE_SDB_INVALID_DATA_VER, &lino, _OVER);
×
1210
  }
1211

1212
  pRow = sdbAllocRow(sizeof(SUserObj));
2,378✔
1213
  if (pRow == NULL) {
2,378!
1214
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1215
  }
1216

1217
  pUser = sdbGetRowObj(pRow);
2,378✔
1218
  if (pUser == NULL) {
2,378!
1219
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1220
  }
1221

1222
  int32_t dataPos = 0;
2,378✔
1223
  SDB_GET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN, _OVER)
2,378!
1224
  SDB_GET_BINARY(pRaw, dataPos, pUser->pass, TSDB_PASSWORD_LEN, _OVER)
2,378!
1225
  SDB_GET_BINARY(pRaw, dataPos, pUser->acct, TSDB_USER_LEN, _OVER)
2,378!
1226
  SDB_GET_INT64(pRaw, dataPos, &pUser->createdTime, _OVER)
2,378!
1227
  SDB_GET_INT64(pRaw, dataPos, &pUser->updateTime, _OVER)
2,378!
1228
  SDB_GET_INT8(pRaw, dataPos, &pUser->superUser, _OVER)
2,378!
1229
  SDB_GET_INT8(pRaw, dataPos, &pUser->sysInfo, _OVER)
2,378!
1230
  SDB_GET_INT8(pRaw, dataPos, &pUser->enable, _OVER)
2,378!
1231
  SDB_GET_UINT8(pRaw, dataPos, &pUser->flag, _OVER)
2,378!
1232
  if (pUser->superUser) pUser->createdb = 1;
2,378✔
1233
  SDB_GET_INT32(pRaw, dataPos, &pUser->authVersion, _OVER)
2,378!
1234
  if (sver >= 4) {
2,378!
1235
    SDB_GET_INT32(pRaw, dataPos, &pUser->passVersion, _OVER)
2,378!
1236
  }
1237

1238
  int32_t numOfReadDbs = 0;
2,378✔
1239
  int32_t numOfWriteDbs = 0;
2,378✔
1240
  int32_t numOfTopics = 0;
2,378✔
1241
  SDB_GET_INT32(pRaw, dataPos, &numOfReadDbs, _OVER)
2,378!
1242
  SDB_GET_INT32(pRaw, dataPos, &numOfWriteDbs, _OVER)
2,378!
1243
  if (sver >= 2) {
2,378!
1244
    SDB_GET_INT32(pRaw, dataPos, &numOfTopics, _OVER)
2,378!
1245
  }
1246

1247
  pUser->readDbs = taosHashInit(numOfReadDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
2,378✔
1248
  pUser->writeDbs =
2,378✔
1249
      taosHashInit(numOfWriteDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
2,378✔
1250
  pUser->topics = taosHashInit(numOfTopics, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
2,378✔
1251
  if (pUser->readDbs == NULL || pUser->writeDbs == NULL || pUser->topics == NULL) {
2,378!
1252
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1253
    goto _OVER;
×
1254
  }
1255

1256
  for (int32_t i = 0; i < numOfReadDbs; ++i) {
2,471✔
1257
    char db[TSDB_DB_FNAME_LEN] = {0};
93✔
1258
    SDB_GET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER)
93!
1259
    int32_t len = strlen(db) + 1;
93✔
1260
    TAOS_CHECK_GOTO(taosHashPut(pUser->readDbs, db, len, db, TSDB_DB_FNAME_LEN), &lino, _OVER);
93!
1261
  }
1262

1263
  for (int32_t i = 0; i < numOfWriteDbs; ++i) {
2,464✔
1264
    char db[TSDB_DB_FNAME_LEN] = {0};
86✔
1265
    SDB_GET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER)
86!
1266
    int32_t len = strlen(db) + 1;
86✔
1267
    TAOS_CHECK_GOTO(taosHashPut(pUser->writeDbs, db, len, db, TSDB_DB_FNAME_LEN), &lino, _OVER);
86!
1268
  }
1269

1270
  if (sver >= 2) {
2,378!
1271
    for (int32_t i = 0; i < numOfTopics; ++i) {
2,412✔
1272
      char topic[TSDB_TOPIC_FNAME_LEN] = {0};
34✔
1273
      SDB_GET_BINARY(pRaw, dataPos, topic, TSDB_TOPIC_FNAME_LEN, _OVER)
34!
1274
      int32_t len = strlen(topic) + 1;
34✔
1275
      TAOS_CHECK_GOTO(taosHashPut(pUser->topics, topic, len, topic, TSDB_TOPIC_FNAME_LEN), &lino, _OVER);
34!
1276
    }
1277
  }
1278

1279
  if (sver >= 3) {
2,378!
1280
    int32_t numOfReadTbs = 0;
2,378✔
1281
    int32_t numOfWriteTbs = 0;
2,378✔
1282
    int32_t numOfAlterTbs = 0;
2,378✔
1283
    int32_t numOfReadViews = 0;
2,378✔
1284
    int32_t numOfWriteViews = 0;
2,378✔
1285
    int32_t numOfAlterViews = 0;
2,378✔
1286
    int32_t numOfUseDbs = 0;
2,378✔
1287
    SDB_GET_INT32(pRaw, dataPos, &numOfReadTbs, _OVER)
2,378!
1288
    SDB_GET_INT32(pRaw, dataPos, &numOfWriteTbs, _OVER)
2,378!
1289
    if (sver >= 6) {
2,378!
1290
      SDB_GET_INT32(pRaw, dataPos, &numOfAlterTbs, _OVER)
2,378!
1291
      SDB_GET_INT32(pRaw, dataPos, &numOfReadViews, _OVER)
2,378!
1292
      SDB_GET_INT32(pRaw, dataPos, &numOfWriteViews, _OVER)
2,378!
1293
      SDB_GET_INT32(pRaw, dataPos, &numOfAlterViews, _OVER)
2,378!
1294
    }
1295
    SDB_GET_INT32(pRaw, dataPos, &numOfUseDbs, _OVER)
2,378!
1296

1297
    pUser->readTbs =
2,378✔
1298
        taosHashInit(numOfReadTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
2,378✔
1299
    pUser->writeTbs =
2,378✔
1300
        taosHashInit(numOfWriteTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
2,378✔
1301
    pUser->alterTbs =
2,378✔
1302
        taosHashInit(numOfAlterTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
2,378✔
1303

1304
    pUser->readViews =
2,378✔
1305
        taosHashInit(numOfReadViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
2,378✔
1306
    pUser->writeViews =
2,378✔
1307
        taosHashInit(numOfWriteViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
2,378✔
1308
    pUser->alterViews =
2,378✔
1309
        taosHashInit(numOfAlterViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
2,378✔
1310

1311
    pUser->useDbs = taosHashInit(numOfUseDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
2,378✔
1312

1313
    if (pUser->readTbs == NULL || pUser->writeTbs == NULL || pUser->alterTbs == NULL || pUser->readViews == NULL ||
2,378!
1314
        pUser->writeViews == NULL || pUser->alterViews == NULL || pUser->useDbs == NULL) {
2,378!
1315
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1316
      goto _OVER;
×
1317
    }
1318

1319
    for (int32_t i = 0; i < numOfReadTbs; ++i) {
2,404✔
1320
      int32_t keyLen = 0;
26✔
1321
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
26!
1322

1323
      TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
26!
1324
      if (key == NULL) {
26!
1325
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1326
      }
1327
      (void)memset(key, 0, keyLen);
26✔
1328
      SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
26!
1329

1330
      int32_t valuelen = 0;
26✔
1331
      SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
26!
1332
      TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
26!
1333
      if (value == NULL) {
26!
1334
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1335
      }
1336
      (void)memset(value, 0, valuelen);
26✔
1337
      SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
26!
1338

1339
      TAOS_CHECK_GOTO(taosHashPut(pUser->readTbs, key, keyLen, value, valuelen), &lino, _OVER);
26!
1340
    }
1341

1342
    for (int32_t i = 0; i < numOfWriteTbs; ++i) {
2,410✔
1343
      int32_t keyLen = 0;
32✔
1344
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
32!
1345

1346
      TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
32!
1347
      if (key == NULL) {
32!
1348
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1349
      }
1350
      (void)memset(key, 0, keyLen);
32✔
1351
      SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
32!
1352

1353
      int32_t valuelen = 0;
32✔
1354
      SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
32!
1355
      TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
32!
1356
      if (value == NULL) {
32!
1357
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1358
      }
1359
      (void)memset(value, 0, valuelen);
32✔
1360
      SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
32!
1361

1362
      TAOS_CHECK_GOTO(taosHashPut(pUser->writeTbs, key, keyLen, value, valuelen), &lino, _OVER);
32!
1363
    }
1364

1365
    if (sver >= 6) {
2,378!
1366
      for (int32_t i = 0; i < numOfAlterTbs; ++i) {
2,386✔
1367
        int32_t keyLen = 0;
8✔
1368
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
8!
1369

1370
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
8!
1371
        if (key == NULL) {
8!
1372
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1373
        }
1374
        (void)memset(key, 0, keyLen);
8✔
1375
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
8!
1376

1377
        int32_t valuelen = 0;
8✔
1378
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
8!
1379
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
8!
1380
        if (value == NULL) {
8!
1381
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1382
        }
1383
        (void)memset(value, 0, valuelen);
8✔
1384
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
8!
1385

1386
        TAOS_CHECK_GOTO(taosHashPut(pUser->alterTbs, key, keyLen, value, valuelen), &lino, _OVER);
8!
1387
      }
1388

1389
      for (int32_t i = 0; i < numOfReadViews; ++i) {
2,430✔
1390
        int32_t keyLen = 0;
52✔
1391
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
52!
1392

1393
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
52!
1394
        if (key == NULL) {
52!
1395
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1396
        }
1397
        (void)memset(key, 0, keyLen);
52✔
1398
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
52!
1399

1400
        int32_t valuelen = 0;
52✔
1401
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
52!
1402
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
52!
1403
        if (value == NULL) {
52!
1404
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1405
        }
1406
        (void)memset(value, 0, valuelen);
52✔
1407
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
52!
1408

1409
        TAOS_CHECK_GOTO(taosHashPut(pUser->readViews, key, keyLen, value, valuelen), &lino, _OVER);
52!
1410
      }
1411

1412
      for (int32_t i = 0; i < numOfWriteViews; ++i) {
2,422✔
1413
        int32_t keyLen = 0;
44✔
1414
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
44!
1415

1416
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
44!
1417
        if (key == NULL) {
44!
1418
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1419
        }
1420
        (void)memset(key, 0, keyLen);
44✔
1421
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
44!
1422

1423
        int32_t valuelen = 0;
44✔
1424
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
44!
1425
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
44!
1426
        if (value == NULL) {
44!
1427
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1428
        }
1429
        (void)memset(value, 0, valuelen);
44✔
1430
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
44!
1431

1432
        TAOS_CHECK_GOTO(taosHashPut(pUser->writeViews, key, keyLen, value, valuelen), &lino, _OVER);
44!
1433
      }
1434

1435
      for (int32_t i = 0; i < numOfAlterViews; ++i) {
2,424✔
1436
        int32_t keyLen = 0;
46✔
1437
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
46!
1438

1439
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
46!
1440
        if (key == NULL) {
46!
1441
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1442
        }
1443
        (void)memset(key, 0, keyLen);
46✔
1444
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
46!
1445

1446
        int32_t valuelen = 0;
46✔
1447
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
46!
1448
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
46!
1449
        if (value == NULL) {
46!
1450
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1451
        }
1452
        (void)memset(value, 0, valuelen);
46✔
1453
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
46!
1454

1455
        TAOS_CHECK_GOTO(taosHashPut(pUser->alterViews, key, keyLen, value, valuelen), &lino, _OVER);
46!
1456
      }
1457
    }
1458

1459
    for (int32_t i = 0; i < numOfUseDbs; ++i) {
2,478✔
1460
      int32_t keyLen = 0;
100✔
1461
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
100!
1462

1463
      TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
100!
1464
      if (key == NULL) {
100!
1465
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1466
      }
1467
      (void)memset(key, 0, keyLen);
100✔
1468
      SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
100!
1469

1470
      int32_t ref = 0;
100✔
1471
      SDB_GET_INT32(pRaw, dataPos, &ref, _OVER);
100!
1472

1473
      TAOS_CHECK_GOTO(taosHashPut(pUser->useDbs, key, keyLen, &ref, sizeof(ref)), &lino, _OVER);
100!
1474
    }
1475
  }
1476
  // decoder white list
1477
  if (sver >= 5) {
2,378!
1478
    int32_t len = 0;
2,378✔
1479
    SDB_GET_INT32(pRaw, dataPos, &len, _OVER);
2,378!
1480

1481
    TAOS_MEMORY_REALLOC(key, len);
2,378!
1482
    if (key == NULL) {
2,378!
1483
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1484
    }
1485
    SDB_GET_BINARY(pRaw, dataPos, key, len, _OVER);
2,378!
1486

1487
    TAOS_CHECK_GOTO(createIpWhiteList(key, len, &pUser->pIpWhiteList), &lino, _OVER);
2,378!
1488

1489
    SDB_GET_INT64(pRaw, dataPos, &pUser->ipWhiteListVer, _OVER);
2,378!
1490
  }
1491

1492
  if (pUser->pIpWhiteList == NULL) {
2,378!
1493
    TAOS_CHECK_GOTO(createDefaultIpWhiteList(&pUser->pIpWhiteList), &lino, _OVER);
×
1494
    pUser->ipWhiteListVer = taosGetTimestampMs();
×
1495
  }
1496

1497
  SDB_GET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
2,378!
1498
  taosInitRWLatch(&pUser->lock);
2,378✔
1499

1500
_OVER:
2,378✔
1501
  taosMemoryFree(key);
2,378!
1502
  taosMemoryFree(value);
2,378!
1503
  if (code < 0) {
2,378!
1504
    terrno = code;
×
1505
    mError("user:%s, failed to decode at line %d from raw:%p since %s", pUser == NULL ? "null" : pUser->user, lino,
×
1506
           pRaw, tstrerror(code));
1507
    if (pUser != NULL) {
×
1508
      taosHashCleanup(pUser->readDbs);
×
1509
      taosHashCleanup(pUser->writeDbs);
×
1510
      taosHashCleanup(pUser->topics);
×
1511
      taosHashCleanup(pUser->readTbs);
×
1512
      taosHashCleanup(pUser->writeTbs);
×
1513
      taosHashCleanup(pUser->alterTbs);
×
1514
      taosHashCleanup(pUser->readViews);
×
1515
      taosHashCleanup(pUser->writeViews);
×
1516
      taosHashCleanup(pUser->alterViews);
×
1517
      taosHashCleanup(pUser->useDbs);
×
1518
      taosMemoryFreeClear(pUser->pIpWhiteList);
×
1519
    }
1520
    taosMemoryFreeClear(pRow);
×
1521
    return NULL;
×
1522
  }
1523

1524
  mTrace("user:%s, decode from raw:%p, row:%p", pUser->user, pRaw, pUser);
2,378✔
1525
  return pRow;
2,378✔
1526
}
1527

1528
static int32_t mndUserActionInsert(SSdb *pSdb, SUserObj *pUser) {
1,985✔
1529
  mTrace("user:%s, perform insert action, row:%p", pUser->user, pUser);
1,985✔
1530

1531
  SAcctObj *pAcct = sdbAcquire(pSdb, SDB_ACCT, pUser->acct);
1,985✔
1532
  if (pAcct == NULL) {
1,985!
1533
    terrno = TSDB_CODE_MND_ACCT_NOT_EXIST;
×
1534
    mError("user:%s, failed to perform insert action since %s", pUser->user, terrstr());
×
1535
    TAOS_RETURN(terrno);
×
1536
  }
1537
  pUser->acctId = pAcct->acctId;
1,985✔
1538
  sdbRelease(pSdb, pAcct);
1,985✔
1539

1540
  return 0;
1,985✔
1541
}
1542

1543
int32_t mndDupTableHash(SHashObj *pOld, SHashObj **ppNew) {
2,783,845✔
1544
  int32_t code = 0;
2,783,845✔
1545
  *ppNew =
2,783,842✔
1546
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
2,783,845✔
1547
  if (*ppNew == NULL) {
2,783,842!
1548
    TAOS_RETURN(terrno);
×
1549
  }
1550

1551
  char *tb = taosHashIterate(pOld, NULL);
2,783,842✔
1552
  while (tb != NULL) {
2,784,588✔
1553
    size_t keyLen = 0;
742✔
1554
    char  *key = taosHashGetKey(tb, &keyLen);
742✔
1555

1556
    int32_t valueLen = strlen(tb) + 1;
742✔
1557
    if ((code = taosHashPut(*ppNew, key, keyLen, tb, valueLen)) != 0) {
742!
1558
      taosHashCancelIterate(pOld, tb);
×
1559
      taosHashCleanup(*ppNew);
×
1560
      TAOS_RETURN(code);
×
1561
    }
1562
    tb = taosHashIterate(pOld, tb);
742✔
1563
  }
1564

1565
  TAOS_RETURN(code);
2,783,846✔
1566
}
1567

1568
int32_t mndDupUseDbHash(SHashObj *pOld, SHashObj **ppNew) {
3,690✔
1569
  int32_t code = 0;
3,690✔
1570
  *ppNew =
3,690✔
1571
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
3,690✔
1572
  if (*ppNew == NULL) {
3,690!
1573
    TAOS_RETURN(terrno);
×
1574
  }
1575

1576
  int32_t *db = taosHashIterate(pOld, NULL);
3,690✔
1577
  while (db != NULL) {
3,876✔
1578
    size_t keyLen = 0;
186✔
1579
    char  *key = taosHashGetKey(db, &keyLen);
186✔
1580

1581
    if ((code = taosHashPut(*ppNew, key, keyLen, db, sizeof(*db))) != 0) {
186!
1582
      taosHashCancelIterate(pOld, db);
×
1583
      taosHashCleanup(*ppNew);
×
1584
      TAOS_RETURN(code);
×
1585
    }
1586
    db = taosHashIterate(pOld, db);
186✔
1587
  }
1588

1589
  TAOS_RETURN(code);
3,690✔
1590
}
1591

1592
int32_t mndUserDupObj(SUserObj *pUser, SUserObj *pNew) {
3,690✔
1593
  int32_t code = 0;
3,690✔
1594
  (void)memcpy(pNew, pUser, sizeof(SUserObj));
3,690✔
1595
  pNew->authVersion++;
3,690✔
1596
  pNew->updateTime = taosGetTimestampMs();
3,690✔
1597

1598
  taosRLockLatch(&pUser->lock);
3,690✔
1599
  TAOS_CHECK_GOTO(mndDupDbHash(pUser->readDbs, &pNew->readDbs), NULL, _OVER);
3,690!
1600
  TAOS_CHECK_GOTO(mndDupDbHash(pUser->writeDbs, &pNew->writeDbs), NULL, _OVER);
3,690!
1601
  TAOS_CHECK_GOTO(mndDupTableHash(pUser->readTbs, &pNew->readTbs), NULL, _OVER);
3,690!
1602
  TAOS_CHECK_GOTO(mndDupTableHash(pUser->writeTbs, &pNew->writeTbs), NULL, _OVER);
3,690!
1603
  TAOS_CHECK_GOTO(mndDupTableHash(pUser->alterTbs, &pNew->alterTbs), NULL, _OVER);
3,690!
1604
  TAOS_CHECK_GOTO(mndDupTableHash(pUser->readViews, &pNew->readViews), NULL, _OVER);
3,690!
1605
  TAOS_CHECK_GOTO(mndDupTableHash(pUser->writeViews, &pNew->writeViews), NULL, _OVER);
3,690!
1606
  TAOS_CHECK_GOTO(mndDupTableHash(pUser->alterViews, &pNew->alterViews), NULL, _OVER);
3,690!
1607
  TAOS_CHECK_GOTO(mndDupTopicHash(pUser->topics, &pNew->topics), NULL, _OVER);
3,690!
1608
  TAOS_CHECK_GOTO(mndDupUseDbHash(pUser->useDbs, &pNew->useDbs), NULL, _OVER);
3,690!
1609
  pNew->pIpWhiteList = cloneIpWhiteList(pUser->pIpWhiteList);
3,690✔
1610
  if (pNew->pIpWhiteList == NULL) {
3,690!
1611
    code = TSDB_CODE_OUT_OF_MEMORY;
×
1612
  }
1613

1614
_OVER:
3,690✔
1615
  taosRUnLockLatch(&pUser->lock);
3,690✔
1616
  TAOS_RETURN(code);
3,690✔
1617
}
1618

1619
void mndUserFreeObj(SUserObj *pUser) {
13,427✔
1620
  taosHashCleanup(pUser->readDbs);
13,427✔
1621
  taosHashCleanup(pUser->writeDbs);
13,427✔
1622
  taosHashCleanup(pUser->topics);
13,427✔
1623
  taosHashCleanup(pUser->readTbs);
13,427✔
1624
  taosHashCleanup(pUser->writeTbs);
13,427✔
1625
  taosHashCleanup(pUser->alterTbs);
13,427✔
1626
  taosHashCleanup(pUser->readViews);
13,427✔
1627
  taosHashCleanup(pUser->writeViews);
13,427✔
1628
  taosHashCleanup(pUser->alterViews);
13,427✔
1629
  taosHashCleanup(pUser->useDbs);
13,427✔
1630
  taosMemoryFreeClear(pUser->pIpWhiteList);
13,427!
1631
  pUser->readDbs = NULL;
13,427✔
1632
  pUser->writeDbs = NULL;
13,427✔
1633
  pUser->topics = NULL;
13,427✔
1634
  pUser->readTbs = NULL;
13,427✔
1635
  pUser->writeTbs = NULL;
13,427✔
1636
  pUser->alterTbs = NULL;
13,427✔
1637
  pUser->readViews = NULL;
13,427✔
1638
  pUser->writeViews = NULL;
13,427✔
1639
  pUser->alterViews = NULL;
13,427✔
1640
  pUser->useDbs = NULL;
13,427✔
1641
}
13,427✔
1642

1643
static int32_t mndUserActionDelete(SSdb *pSdb, SUserObj *pUser) {
2,377✔
1644
  mTrace("user:%s, perform delete action, row:%p", pUser->user, pUser);
2,377✔
1645
  mndUserFreeObj(pUser);
2,377✔
1646
  return 0;
2,377✔
1647
}
1648

1649
static int32_t mndUserActionUpdate(SSdb *pSdb, SUserObj *pOld, SUserObj *pNew) {
290✔
1650
  mTrace("user:%s, perform update action, old row:%p new row:%p", pOld->user, pOld, pNew);
290!
1651
  taosWLockLatch(&pOld->lock);
290✔
1652
  pOld->updateTime = pNew->updateTime;
290✔
1653
  pOld->authVersion = pNew->authVersion;
290✔
1654
  pOld->passVersion = pNew->passVersion;
290✔
1655
  pOld->sysInfo = pNew->sysInfo;
290✔
1656
  pOld->enable = pNew->enable;
290✔
1657
  pOld->flag = pNew->flag;
290✔
1658
  (void)memcpy(pOld->pass, pNew->pass, TSDB_PASSWORD_LEN);
290✔
1659
  TSWAP(pOld->readDbs, pNew->readDbs);
290✔
1660
  TSWAP(pOld->writeDbs, pNew->writeDbs);
290✔
1661
  TSWAP(pOld->topics, pNew->topics);
290✔
1662
  TSWAP(pOld->readTbs, pNew->readTbs);
290✔
1663
  TSWAP(pOld->writeTbs, pNew->writeTbs);
290✔
1664
  TSWAP(pOld->alterTbs, pNew->alterTbs);
290✔
1665
  TSWAP(pOld->readViews, pNew->readViews);
290✔
1666
  TSWAP(pOld->writeViews, pNew->writeViews);
290✔
1667
  TSWAP(pOld->alterViews, pNew->alterViews);
290✔
1668
  TSWAP(pOld->useDbs, pNew->useDbs);
290✔
1669

1670
  int32_t sz = sizeof(SIpWhiteList) + pNew->pIpWhiteList->num * sizeof(SIpV4Range);
290✔
1671
  TAOS_MEMORY_REALLOC(pOld->pIpWhiteList, sz);
290!
1672
  if (pOld->pIpWhiteList == NULL) {
290!
1673
    taosWUnLockLatch(&pOld->lock);
×
1674
    return terrno;
×
1675
  }
1676
  (void)memcpy(pOld->pIpWhiteList, pNew->pIpWhiteList, sz);
290✔
1677
  pOld->ipWhiteListVer = pNew->ipWhiteListVer;
290✔
1678

1679
  taosWUnLockLatch(&pOld->lock);
290✔
1680

1681
  return 0;
290✔
1682
}
1683

1684
int32_t mndAcquireUser(SMnode *pMnode, const char *userName, SUserObj **ppUser) {
4,975,052✔
1685
  int32_t code = 0;
4,975,052✔
1686
  SSdb   *pSdb = pMnode->pSdb;
4,975,052✔
1687

1688
  *ppUser = sdbAcquire(pSdb, SDB_USER, userName);
4,975,052✔
1689
  if (*ppUser == NULL) {
4,975,127✔
1690
    if (terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
188!
1691
      code = TSDB_CODE_MND_USER_NOT_EXIST;
188✔
1692
    } else {
1693
      code = TSDB_CODE_MND_USER_NOT_AVAILABLE;
×
1694
    }
1695
  }
1696
  TAOS_RETURN(code);
4,975,127✔
1697
}
1698

1699
void mndReleaseUser(SMnode *pMnode, SUserObj *pUser) {
4,975,606✔
1700
  SSdb *pSdb = pMnode->pSdb;
4,975,606✔
1701
  sdbRelease(pSdb, pUser);
4,975,606✔
1702
}
4,975,946✔
1703

1704
static int32_t mndCreateUser(SMnode *pMnode, char *acct, SCreateUserReq *pCreate, SRpcMsg *pReq) {
145✔
1705
  int32_t  code = 0;
145✔
1706
  int32_t  lino = 0;
145✔
1707
  SUserObj userObj = {0};
145✔
1708
  if (pCreate->isImport != 1) {
145✔
1709
    taosEncryptPass_c((uint8_t *)pCreate->pass, strlen(pCreate->pass), userObj.pass);
142✔
1710
  } else {
1711
    // mInfo("pCreate->pass:%s", pCreate->eass)
1712
    memcpy(userObj.pass, pCreate->pass, TSDB_PASSWORD_LEN);
3✔
1713
  }
1714
  tstrncpy(userObj.user, pCreate->user, TSDB_USER_LEN);
145✔
1715
  tstrncpy(userObj.acct, acct, TSDB_USER_LEN);
145✔
1716
  userObj.createdTime = taosGetTimestampMs();
145✔
1717
  userObj.updateTime = userObj.createdTime;
145✔
1718
  userObj.superUser = 0;  // pCreate->superUser;
145✔
1719
  userObj.sysInfo = pCreate->sysInfo;
145✔
1720
  userObj.enable = pCreate->enable;
145✔
1721
  userObj.createdb = pCreate->createDb;
145✔
1722

1723
  if (pCreate->numIpRanges == 0) {
145✔
1724
    TAOS_CHECK_RETURN(createDefaultIpWhiteList(&userObj.pIpWhiteList));
140!
1725
  } else {
1726
    SHashObj *pUniqueTab = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
5✔
1727
    if (pUniqueTab == NULL) {
5!
1728
      TAOS_RETURN(terrno);
×
1729
    }
1730
    int32_t dummpy = 0;
5✔
1731
    for (int i = 0; i < pCreate->numIpRanges; i++) {
12✔
1732
      SIpV4Range range = {.ip = pCreate->pIpRanges[i].ip, .mask = pCreate->pIpRanges[i].mask};
7✔
1733
      if ((code = taosHashPut(pUniqueTab, &range, sizeof(range), &dummpy, sizeof(dummpy))) != 0) {
7!
1734
        taosHashCleanup(pUniqueTab);
×
1735
        TAOS_RETURN(code);
×
1736
      }
1737
    }
1738
    if ((code = taosHashPut(pUniqueTab, &defaultIpRange, sizeof(defaultIpRange), &dummpy, sizeof(dummpy))) != 0) {
5!
1739
      taosHashCleanup(pUniqueTab);
×
1740
      TAOS_RETURN(code);
×
1741
    }
1742

1743
    if (taosHashGetSize(pUniqueTab) > MND_MAX_USE_HOST) {
5!
1744
      taosHashCleanup(pUniqueTab);
×
1745
      TAOS_RETURN(TSDB_CODE_MND_TOO_MANY_USER_HOST);
×
1746
    }
1747

1748
    int32_t       numOfRanges = taosHashGetSize(pUniqueTab);
5✔
1749
    SIpWhiteList *p = taosMemoryCalloc(1, sizeof(SIpWhiteList) + numOfRanges * sizeof(SIpV4Range));
5!
1750
    if (p == NULL) {
5!
1751
      taosHashCleanup(pUniqueTab);
×
1752
      TAOS_RETURN(terrno);
×
1753
    }
1754
    void   *pIter = taosHashIterate(pUniqueTab, NULL);
5✔
1755
    int32_t i = 0;
5✔
1756
    while (pIter) {
13✔
1757
      size_t      len = 0;
8✔
1758
      SIpV4Range *key = taosHashGetKey(pIter, &len);
8✔
1759
      p->pIpRange[i].ip = key->ip;
8✔
1760
      p->pIpRange[i].mask = key->mask;
8✔
1761
      pIter = taosHashIterate(pUniqueTab, pIter);
8✔
1762

1763
      i++;
8✔
1764
    }
1765

1766
    taosHashCleanup(pUniqueTab);
5✔
1767
    p->num = numOfRanges;
5✔
1768
    userObj.pIpWhiteList = p;
5✔
1769
  }
1770

1771
  userObj.ipWhiteListVer = taosGetTimestampMs();
145✔
1772

1773
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "create-user");
145✔
1774
  if (pTrans == NULL) {
145!
1775
    mError("user:%s, failed to create since %s", pCreate->user, terrstr());
×
1776
    taosMemoryFree(userObj.pIpWhiteList);
×
1777
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1778
  }
1779
  mInfo("trans:%d, used to create user:%s", pTrans->id, pCreate->user);
145!
1780

1781
  SSdbRaw *pCommitRaw = mndUserActionEncode(&userObj);
145✔
1782
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
145!
1783
    mError("trans:%d, failed to commit redo log since %s", pTrans->id, terrstr());
×
1784
    mndTransDrop(pTrans);
×
1785
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
1786
  }
1787
  TAOS_CHECK_GOTO(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY), &lino, _OVER);
145!
1788

1789
  if (mndTransPrepare(pMnode, pTrans) != 0) {
145!
1790
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
1791
    mndTransDrop(pTrans);
×
1792
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1793
  }
1794
  if ((code = ipWhiteMgtUpdate(pMnode, userObj.user, userObj.pIpWhiteList)) != 0) {
145!
1795
    mndTransDrop(pTrans);
×
1796
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
1797
  }
1798

1799
  taosMemoryFree(userObj.pIpWhiteList);
145!
1800
  mndTransDrop(pTrans);
145✔
1801
  return 0;
145✔
1802
_OVER:
×
1803
  taosMemoryFree(userObj.pIpWhiteList);
×
1804

1805
  TAOS_RETURN(code);
×
1806
}
1807

1808
static int32_t mndCheckPasswordMinLen(const char *pwd, int32_t len) {
277✔
1809
  if (len < TSDB_PASSWORD_MIN_LEN) {
277✔
1810
    return -1;
50✔
1811
  }
1812
  return 0;
227✔
1813
}
1814

1815
static int32_t mndCheckPasswordMaxLen(const char *pwd, int32_t len) {
227✔
1816
  if (len > TSDB_PASSWORD_MAX_LEN) {
227✔
1817
    return -1;
3✔
1818
  }
1819
  return 0;
224✔
1820
}
1821

1822
static int32_t mndCheckPasswordFmt(const char *pwd, int32_t len) {
224✔
1823
  if (strcmp(pwd, "taosdata") == 0) {
224✔
1824
    return 0;
42✔
1825
  }
1826

1827
  bool charTypes[4] = {0};
182✔
1828
  for (int32_t i = 0; i < len; ++i) {
1,926✔
1829
    if (taosIsBigChar(pwd[i])) {
1,746✔
1830
      charTypes[0] = true;
80✔
1831
    } else if (taosIsSmallChar(pwd[i])) {
1,666✔
1832
      charTypes[1] = true;
1,022✔
1833
    } else if (taosIsNumberChar(pwd[i])) {
644✔
1834
      charTypes[2] = true;
448✔
1835
    } else if (taosIsSpecialChar(pwd[i])) {
196✔
1836
      charTypes[3] = true;
194✔
1837
    } else {
1838
      return -1;
2✔
1839
    }
1840
  }
1841

1842
  int32_t numOfTypes = 0;
180✔
1843
  for (int32_t i = 0; i < 4; ++i) {
900✔
1844
    numOfTypes += charTypes[i];
720✔
1845
  }
1846

1847
  if (numOfTypes < 3) {
180✔
1848
    return -1;
44✔
1849
  }
1850

1851
  return 0;
136✔
1852
}
1853

1854
static int32_t mndProcessCreateUserReq(SRpcMsg *pReq) {
218✔
1855
  SMnode        *pMnode = pReq->info.node;
218✔
1856
  int32_t        code = 0;
218✔
1857
  int32_t        lino = 0;
218✔
1858
  SUserObj      *pUser = NULL;
218✔
1859
  SUserObj      *pOperUser = NULL;
218✔
1860
  SCreateUserReq createReq = {0};
218✔
1861

1862
  if (tDeserializeSCreateUserReq(pReq->pCont, pReq->contLen, &createReq) != 0) {
218!
1863
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
1864
  }
1865

1866
  mInfo("user:%s, start to create, createdb:%d, is_import:%d", createReq.user, createReq.isImport, createReq.createDb);
218!
1867

1868
#ifndef TD_ENTERPRISE
1869
  if (createReq.isImport == 1) {
1870
    TAOS_CHECK_GOTO(TSDB_CODE_OPS_NOT_SUPPORT, &lino, _OVER);  // enterprise feature
1871
  }
1872
#endif
1873

1874
  if (createReq.isImport != 1) {
218✔
1875
    TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CREATE_USER), &lino, _OVER);
215✔
1876
  } else {
1877
    if (strcmp(pReq->info.conn.user, "root") != 0) {
3!
1878
      mError("The operation is not permitted, user:%s", pReq->info.conn.user);
×
1879
      TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_RIGHTS, &lino, _OVER);
×
1880
    }
1881
  }
1882

1883
  if (createReq.user[0] == 0) {
213!
1884
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
1885
  }
1886

1887
  int32_t len = strlen(createReq.pass);
213✔
1888
  if (createReq.isImport != 1) {
213✔
1889
    if (mndCheckPasswordMinLen(createReq.pass, len) != 0) {
210✔
1890
      TAOS_CHECK_GOTO(TSDB_CODE_PAR_PASSWD_TOO_SHORT_OR_EMPTY, &lino, _OVER);
44!
1891
    }
1892
    if (mndCheckPasswordMaxLen(createReq.pass, len) != 0) {
166✔
1893
      TAOS_CHECK_GOTO(TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG, &lino, _OVER);
2!
1894
    }
1895
    if (mndCheckPasswordFmt(createReq.pass, len) != 0) {
164✔
1896
      TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_PASS_FORMAT, &lino, _OVER);
22!
1897
    }
1898
  }
1899

1900
  code = mndAcquireUser(pMnode, createReq.user, &pUser);
145✔
1901
  if (pUser != NULL) {
145!
1902
    TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_ALREADY_EXIST, &lino, _OVER);
×
1903
  }
1904

1905
  code = mndAcquireUser(pMnode, pReq->info.conn.user, &pOperUser);
145✔
1906
  if (pOperUser == NULL) {
145!
1907
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_USER_FROM_CONN, &lino, _OVER);
×
1908
  }
1909

1910
  TAOS_CHECK_GOTO(grantCheck(TSDB_GRANT_USER), &lino, _OVER);
145!
1911

1912
  code = mndCreateUser(pMnode, pOperUser->acct, &createReq, pReq);
145✔
1913
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
145!
1914

1915
  char detail[1000] = {0};
145✔
1916
  (void)tsnprintf(detail, sizeof(detail), "enable:%d, superUser:%d, sysInfo:%d, password:xxx", createReq.enable,
145✔
1917
            createReq.superUser, createReq.sysInfo);
145✔
1918
  char operation[15] = {0};
145✔
1919
  if (createReq.isImport == 1) {
145✔
1920
    tstrncpy(operation, "importUser", sizeof(operation));
3✔
1921
  } else {
1922
    tstrncpy(operation, "createUser", sizeof(operation));
142✔
1923
  }
1924

1925
  auditRecord(pReq, pMnode->clusterId, operation, "", createReq.user, detail, strlen(detail));
145✔
1926

1927
_OVER:
218✔
1928
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
218!
1929
    mError("user:%s, failed to create at line %d since %s", createReq.user, lino, tstrerror(code));
73!
1930
  }
1931

1932
  mndReleaseUser(pMnode, pUser);
218✔
1933
  mndReleaseUser(pMnode, pOperUser);
218✔
1934
  tFreeSCreateUserReq(&createReq);
218✔
1935

1936
  TAOS_RETURN(code);
218✔
1937
}
1938

1939
int32_t mndProcessGetUserWhiteListReq(SRpcMsg *pReq) {
82✔
1940
  SMnode              *pMnode = pReq->info.node;
82✔
1941
  int32_t              code = 0;
82✔
1942
  int32_t              lino = 0;
82✔
1943
  int32_t              contLen = 0;
82✔
1944
  void                *pRsp = NULL;
82✔
1945
  SUserObj            *pUser = NULL;
82✔
1946
  SGetUserWhiteListReq wlReq = {0};
82✔
1947
  SGetUserWhiteListRsp wlRsp = {0};
82✔
1948

1949
  if (tDeserializeSGetUserWhiteListReq(pReq->pCont, pReq->contLen, &wlReq) != 0) {
82!
1950
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
1951
  }
1952
  mTrace("user: %s, start to get whitelist", wlReq.user);
82✔
1953

1954
  code = mndAcquireUser(pMnode, wlReq.user, &pUser);
82✔
1955
  if (pUser == NULL) {
82!
1956
    TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_NOT_EXIST, &lino, _OVER);
×
1957
  }
1958

1959
  TAOS_CHECK_GOTO(mndSetUserWhiteListRsp(pMnode, pUser, &wlRsp), &lino, _OVER);
82!
1960

1961
  contLen = tSerializeSGetUserWhiteListRsp(NULL, 0, &wlRsp);
82✔
1962
  if (contLen < 0) {
82!
1963
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
1964
  }
1965
  pRsp = rpcMallocCont(contLen);
82✔
1966
  if (pRsp == NULL) {
82!
1967
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1968
  }
1969

1970
  contLen = tSerializeSGetUserWhiteListRsp(pRsp, contLen, &wlRsp);
82✔
1971
  if (contLen < 0) {
82!
1972
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
1973
  }
1974

1975
_OVER:
82✔
1976
  mndReleaseUser(pMnode, pUser);
82✔
1977
  tFreeSGetUserWhiteListRsp(&wlRsp);
82✔
1978
  if (code < 0) {
82!
1979
    mError("user:%s, failed to get whitelist at line %d since %s", wlReq.user, lino, tstrerror(code));
×
1980
    rpcFreeCont(pRsp);
×
1981
    pRsp = NULL;
×
1982
    contLen = 0;
×
1983
  }
1984
  pReq->code = code;
82✔
1985
  pReq->info.rsp = pRsp;
82✔
1986
  pReq->info.rspLen = contLen;
82✔
1987

1988
  TAOS_RETURN(code);
82✔
1989
}
1990

1991
int32_t mndProcesSRetrieveIpWhiteReq(SRpcMsg *pReq) {
6✔
1992
  int32_t        code = 0;
6✔
1993
  int32_t        lino = 0;
6✔
1994
  int32_t        len = 0;
6✔
1995
  void          *pRsp = NULL;
6✔
1996
  SUpdateIpWhite ipWhite = {0};
6✔
1997

1998
  // impl later
1999
  SRetrieveIpWhiteReq req = {0};
6✔
2000
  if (tDeserializeRetrieveIpWhite(pReq->pCont, pReq->contLen, &req) != 0) {
6!
2001
    code = TSDB_CODE_INVALID_MSG;
×
2002
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2003
  }
2004

2005
  TAOS_CHECK_GOTO(ipWhiteMgtFillMsg(&ipWhite), &lino, _OVER);
6!
2006

2007
  len = tSerializeSUpdateIpWhite(NULL, 0, &ipWhite);
6✔
2008
  if (len < 0) {
6!
2009
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
2010
  }
2011

2012
  pRsp = rpcMallocCont(len);
6✔
2013
  if (!pRsp) {
6!
2014
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2015
  }
2016
  len = tSerializeSUpdateIpWhite(pRsp, len, &ipWhite);
6✔
2017
  if (len < 0) {
6!
2018
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
2019
  }
2020

2021
_OVER:
6✔
2022
  if (code < 0) {
6!
2023
    mError("failed to process retrieve ip white request at line %d since %s", lino, tstrerror(code));
×
2024
    rpcFreeCont(pRsp);
×
2025
    pRsp = NULL;
×
2026
    len = 0;
×
2027
  }
2028
  pReq->code = code;
6✔
2029
  pReq->info.rsp = pRsp;
6✔
2030
  pReq->info.rspLen = len;
6✔
2031

2032
  tFreeSUpdateIpWhiteReq(&ipWhite);
6✔
2033
  TAOS_RETURN(code);
6✔
2034
}
2035

2036
static int32_t mndAlterUser(SMnode *pMnode, SUserObj *pOld, SUserObj *pNew, SRpcMsg *pReq) {
221✔
2037
  int32_t code = 0;
221✔
2038
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "alter-user");
221✔
2039
  if (pTrans == NULL) {
221!
2040
    mError("user:%s, failed to alter since %s", pOld->user, terrstr());
×
2041
    TAOS_RETURN(terrno);
×
2042
  }
2043
  mInfo("trans:%d, used to alter user:%s", pTrans->id, pOld->user);
221!
2044

2045
  SSdbRaw *pCommitRaw = mndUserActionEncode(pNew);
221✔
2046
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
221!
2047
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
2048
    mndTransDrop(pTrans);
×
2049
    TAOS_RETURN(terrno);
×
2050
  }
2051
  code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
221✔
2052
  if (code < 0) {
221!
2053
    mndTransDrop(pTrans);
×
2054
    TAOS_RETURN(code);
×
2055
  }
2056

2057
  if (mndTransPrepare(pMnode, pTrans) != 0) {
221!
2058
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
2059
    mndTransDrop(pTrans);
×
2060
    TAOS_RETURN(terrno);
×
2061
  }
2062
  if ((code = ipWhiteMgtUpdate(pMnode, pNew->user, pNew->pIpWhiteList)) != 0) {
221!
2063
    mndTransDrop(pTrans);
×
2064
    TAOS_RETURN(code);
×
2065
  }
2066
  mndTransDrop(pTrans);
221✔
2067
  return 0;
221✔
2068
}
2069

2070
static int32_t mndDupObjHash(SHashObj *pOld, int32_t dataLen, SHashObj **ppNew) {
800,136✔
2071
  int32_t code = 0;
800,136✔
2072

2073
  *ppNew =
800,134✔
2074
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
800,136✔
2075
  if (*ppNew == NULL) {
800,134!
2076
    code = terrno ? terrno : TSDB_CODE_OUT_OF_MEMORY;
×
2077
    TAOS_RETURN(code);
×
2078
  }
2079

2080
  char *db = taosHashIterate(pOld, NULL);
800,134✔
2081
  while (db != NULL) {
800,539✔
2082
    int32_t len = strlen(db) + 1;
406✔
2083
    if ((code = taosHashPut(*ppNew, db, len, db, dataLen)) != 0) {
406!
2084
      taosHashCancelIterate(pOld, db);
×
2085
      taosHashCleanup(*ppNew);
×
2086
      TAOS_RETURN(code);
×
2087
    }
2088
    db = taosHashIterate(pOld, db);
406✔
2089
  }
2090

2091
  TAOS_RETURN(code);
800,133✔
2092
}
2093

2094
int32_t mndDupDbHash(SHashObj *pOld, SHashObj **ppNew) { return mndDupObjHash(pOld, TSDB_DB_FNAME_LEN, ppNew); }
796,446✔
2095

2096
int32_t mndDupTopicHash(SHashObj *pOld, SHashObj **ppNew) { return mndDupObjHash(pOld, TSDB_TOPIC_FNAME_LEN, ppNew); }
3,690✔
2097

2098
static int32_t mndTablePriviledge(SMnode *pMnode, SHashObj *hash, SHashObj *useDbHash, SAlterUserReq *alterReq,
71✔
2099
                                  SSdb *pSdb) {
2100
  void *pIter = NULL;
71✔
2101
  char  tbFName[TSDB_TABLE_FNAME_LEN] = {0};
71✔
2102

2103
  (void)snprintf(tbFName, sizeof(tbFName), "%s.%s", alterReq->objname, alterReq->tabName);
71✔
2104
  int32_t len = strlen(tbFName) + 1;
71✔
2105

2106
  if (alterReq->tagCond != NULL && alterReq->tagCondLen != 0) {
94!
2107
    char *value = taosHashGet(hash, tbFName, len);
23✔
2108
    if (value != NULL) {
23!
2109
      TAOS_RETURN(TSDB_CODE_MND_PRIVILEDGE_EXIST);
×
2110
    }
2111

2112
    int32_t condLen = alterReq->tagCondLen;
23✔
2113
    TAOS_CHECK_RETURN(taosHashPut(hash, tbFName, len, alterReq->tagCond, condLen));
23!
2114
  } else {
2115
    TAOS_CHECK_RETURN(taosHashPut(hash, tbFName, len, alterReq->isView ? "v" : "t", 2));
48!
2116
  }
2117

2118
  int32_t  dbKeyLen = strlen(alterReq->objname) + 1;
71✔
2119
  int32_t  ref = 1;
71✔
2120
  int32_t *currRef = taosHashGet(useDbHash, alterReq->objname, dbKeyLen);
71✔
2121
  if (NULL != currRef) {
71✔
2122
    ref = (*currRef) + 1;
20✔
2123
  }
2124
  TAOS_CHECK_RETURN(taosHashPut(useDbHash, alterReq->objname, dbKeyLen, &ref, sizeof(ref)));
71!
2125

2126
  TAOS_RETURN(0);
71✔
2127
}
2128

2129
static int32_t mndRemoveTablePriviledge(SMnode *pMnode, SHashObj *hash, SHashObj *useDbHash, SAlterUserReq *alterReq,
11✔
2130
                                        SSdb *pSdb) {
2131
  void *pIter = NULL;
11✔
2132
  char  tbFName[TSDB_TABLE_FNAME_LEN] = {0};
11✔
2133
  (void)snprintf(tbFName, sizeof(tbFName), "%s.%s", alterReq->objname, alterReq->tabName);
11✔
2134
  int32_t len = strlen(tbFName) + 1;
11✔
2135

2136
  if (taosHashRemove(hash, tbFName, len) != 0) {
11!
2137
    TAOS_RETURN(0);  // not found
×
2138
  }
2139

2140
  int32_t  dbKeyLen = strlen(alterReq->objname) + 1;
11✔
2141
  int32_t *currRef = taosHashGet(useDbHash, alterReq->objname, dbKeyLen);
11✔
2142
  if (NULL == currRef) {
11!
2143
    return 0;
×
2144
  }
2145

2146
  if (1 == *currRef) {
11!
2147
    if (taosHashRemove(useDbHash, alterReq->objname, dbKeyLen) != 0) {
11!
2148
      TAOS_RETURN(0);  // not found
×
2149
    }
2150
    return 0;
11✔
2151
  }
2152
  int32_t ref = (*currRef) - 1;
×
2153
  TAOS_CHECK_RETURN(taosHashPut(useDbHash, alterReq->objname, dbKeyLen, &ref, sizeof(ref)));
×
2154

2155
  return 0;
×
2156
}
2157

2158
static char *mndUserAuditTypeStr(int32_t type) {
35✔
2159
  if (type == TSDB_ALTER_USER_PASSWD) {
35!
2160
    return "changePassword";
35✔
2161
  }
2162
  if (type == TSDB_ALTER_USER_SUPERUSER) {
×
2163
    return "changeSuperUser";
×
2164
  }
2165
  if (type == TSDB_ALTER_USER_ENABLE) {
×
2166
    return "enableUser";
×
2167
  }
2168
  if (type == TSDB_ALTER_USER_SYSINFO) {
×
2169
    return "userSysInfo";
×
2170
  }
2171
  if (type == TSDB_ALTER_USER_CREATEDB) {
×
2172
    return "userCreateDB";
×
2173
  }
2174
  return "error";
×
2175
}
2176

2177
static int32_t mndProcessAlterUserPrivilegesReq(SAlterUserReq *pAlterReq, SMnode *pMnode, SUserObj *pNewUser) {
168✔
2178
  SSdb   *pSdb = pMnode->pSdb;
168✔
2179
  void   *pIter = NULL;
168✔
2180
  int32_t code = 0;
168✔
2181
  int32_t lino = 0;
168✔
2182

2183
  if (ALTER_USER_ADD_READ_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
168✔
2184
      ALTER_USER_ADD_ALL_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
129!
2185
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
39✔
2186
      int32_t len = strlen(pAlterReq->objname) + 1;
36✔
2187
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
36✔
2188
      if (pDb == NULL) {
36✔
2189
        mndReleaseDb(pMnode, pDb);
5✔
2190
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
5!
2191
      }
2192
      if ((code = taosHashPut(pNewUser->readDbs, pAlterReq->objname, len, pAlterReq->objname, TSDB_DB_FNAME_LEN)) !=
31!
2193
          0) {
2194
        mndReleaseDb(pMnode, pDb);
×
2195
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2196
      }
2197
      mndReleaseDb(pMnode, pDb);
31✔
2198
    } else {
2199
      while (1) {
9✔
2200
        SDbObj *pDb = NULL;
12✔
2201
        pIter = sdbFetch(pSdb, SDB_DB, pIter, (void **)&pDb);
12✔
2202
        if (pIter == NULL) break;
12✔
2203
        int32_t len = strlen(pDb->name) + 1;
9✔
2204
        if ((code = taosHashPut(pNewUser->readDbs, pDb->name, len, pDb->name, TSDB_DB_FNAME_LEN)) != 0) {
9!
2205
          sdbRelease(pSdb, pDb);
×
2206
          sdbCancelFetch(pSdb, pIter);
×
2207
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2208
        }
2209
        sdbRelease(pSdb, pDb);
9✔
2210
      }
2211
    }
2212
  }
2213

2214
  if (ALTER_USER_ADD_WRITE_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
163✔
2215
      ALTER_USER_ADD_ALL_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
129!
2216
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
34✔
2217
      int32_t len = strlen(pAlterReq->objname) + 1;
31✔
2218
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
31✔
2219
      if (pDb == NULL) {
31✔
2220
        mndReleaseDb(pMnode, pDb);
1✔
2221
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
1!
2222
      }
2223
      if ((code = taosHashPut(pNewUser->writeDbs, pAlterReq->objname, len, pAlterReq->objname, TSDB_DB_FNAME_LEN)) !=
30!
2224
          0) {
2225
        mndReleaseDb(pMnode, pDb);
×
2226
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2227
      }
2228
      mndReleaseDb(pMnode, pDb);
30✔
2229
    } else {
2230
      while (1) {
9✔
2231
        SDbObj *pDb = NULL;
12✔
2232
        pIter = sdbFetch(pSdb, SDB_DB, pIter, (void **)&pDb);
12✔
2233
        if (pIter == NULL) break;
12✔
2234
        int32_t len = strlen(pDb->name) + 1;
9✔
2235
        if ((code = taosHashPut(pNewUser->writeDbs, pDb->name, len, pDb->name, TSDB_DB_FNAME_LEN)) != 0) {
9!
2236
          sdbRelease(pSdb, pDb);
×
2237
          sdbCancelFetch(pSdb, pIter);
×
2238
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2239
        }
2240
        sdbRelease(pSdb, pDb);
9✔
2241
      }
2242
    }
2243
  }
2244

2245
  if (ALTER_USER_DEL_READ_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
162✔
2246
      ALTER_USER_DEL_ALL_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
142!
2247
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
20✔
2248
      int32_t len = strlen(pAlterReq->objname) + 1;
17✔
2249
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
17✔
2250
      if (pDb == NULL) {
17!
2251
        mndReleaseDb(pMnode, pDb);
×
2252
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
×
2253
      }
2254
      code = taosHashRemove(pNewUser->readDbs, pAlterReq->objname, len);
17✔
2255
      if (code < 0) {
17!
2256
        mError("read db:%s, failed to remove db:%s since %s", pNewUser->user, pAlterReq->objname, terrstr());
×
2257
      }
2258
      mndReleaseDb(pMnode, pDb);
17✔
2259
    } else {
2260
      taosHashClear(pNewUser->readDbs);
3✔
2261
    }
2262
  }
2263

2264
  if (ALTER_USER_DEL_WRITE_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
162✔
2265
      ALTER_USER_DEL_ALL_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
144!
2266
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
18✔
2267
      int32_t len = strlen(pAlterReq->objname) + 1;
15✔
2268
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
15✔
2269
      if (pDb == NULL) {
15!
2270
        mndReleaseDb(pMnode, pDb);
×
2271
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
×
2272
      }
2273
      code = taosHashRemove(pNewUser->writeDbs, pAlterReq->objname, len);
15✔
2274
      if (code < 0) {
15!
2275
        mError("user:%s, failed to remove db:%s since %s", pNewUser->user, pAlterReq->objname, terrstr());
×
2276
      }
2277
      mndReleaseDb(pMnode, pDb);
15✔
2278
    } else {
2279
      taosHashClear(pNewUser->writeDbs);
3✔
2280
    }
2281
  }
2282

2283
  SHashObj *pReadTbs = pNewUser->readTbs;
162✔
2284
  SHashObj *pWriteTbs = pNewUser->writeTbs;
162✔
2285
  SHashObj *pAlterTbs = pNewUser->alterTbs;
162✔
2286

2287
#ifdef TD_ENTERPRISE
2288
  if (pAlterReq->isView) {
162✔
2289
    pReadTbs = pNewUser->readViews;
12✔
2290
    pWriteTbs = pNewUser->writeViews;
12✔
2291
    pAlterTbs = pNewUser->alterViews;
12✔
2292
  }
2293
#endif
2294

2295
  if (ALTER_USER_ADD_READ_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
162✔
2296
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
132!
2297
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pReadTbs, pNewUser->useDbs, pAlterReq, pSdb), &lino, _OVER);
30!
2298
  }
2299

2300
  if (ALTER_USER_ADD_WRITE_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
162✔
2301
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
131!
2302
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pWriteTbs, pNewUser->useDbs, pAlterReq, pSdb), &lino, _OVER);
31!
2303
  }
2304

2305
  if (ALTER_USER_ADD_ALTER_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
162✔
2306
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
152!
2307
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pAlterTbs, pNewUser->useDbs, pAlterReq, pSdb), &lino, _OVER);
10!
2308
  }
2309

2310
  if (ALTER_USER_DEL_READ_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
162✔
2311
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
156!
2312
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pReadTbs, pNewUser->useDbs, pAlterReq, pSdb), &lino, _OVER);
6!
2313
  }
2314

2315
  if (ALTER_USER_DEL_WRITE_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
162✔
2316
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
157!
2317
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pWriteTbs, pNewUser->useDbs, pAlterReq, pSdb), &lino, _OVER);
5!
2318
  }
2319

2320
  if (ALTER_USER_DEL_ALTER_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
162!
2321
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
162!
2322
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pAlterTbs, pNewUser->useDbs, pAlterReq, pSdb), &lino, _OVER);
×
2323
  }
2324

2325
  if (ALTER_USER_ADD_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, pAlterReq->privileges)) {
162✔
2326
    int32_t      len = strlen(pAlterReq->objname) + 1;
15✔
2327
    SMqTopicObj *pTopic = NULL;
15✔
2328
    if ((code = mndAcquireTopic(pMnode, pAlterReq->objname, &pTopic)) != 0) {
15!
2329
      mndReleaseTopic(pMnode, pTopic);
×
2330
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2331
    }
2332
    if ((code = taosHashPut(pNewUser->topics, pTopic->name, len, pTopic->name, TSDB_TOPIC_FNAME_LEN)) != 0) {
15!
2333
      mndReleaseTopic(pMnode, pTopic);
×
2334
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2335
    }
2336
    mndReleaseTopic(pMnode, pTopic);
15✔
2337
  }
2338

2339
  if (ALTER_USER_DEL_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, pAlterReq->privileges)) {
162✔
2340
    int32_t      len = strlen(pAlterReq->objname) + 1;
11✔
2341
    SMqTopicObj *pTopic = NULL;
11✔
2342
    if ((code = mndAcquireTopic(pMnode, pAlterReq->objname, &pTopic)) != 0) {
11✔
2343
      mndReleaseTopic(pMnode, pTopic);
1✔
2344
      TAOS_CHECK_GOTO(code, &lino, _OVER);
1!
2345
    }
2346
    code = taosHashRemove(pNewUser->topics, pAlterReq->objname, len);
10✔
2347
    if (code < 0) {
10!
2348
      mError("user:%s, failed to remove topic:%s since %s", pNewUser->user, pAlterReq->objname, tstrerror(code));
×
2349
    }
2350
    mndReleaseTopic(pMnode, pTopic);
10✔
2351
  }
2352

2353
_OVER:
151✔
2354
  if (code < 0) {
168✔
2355
    mError("user:%s, failed to alter user privileges at line %d since %s", pAlterReq->user, lino, tstrerror(code));
7!
2356
  }
2357
  TAOS_RETURN(code);
168✔
2358
}
2359

2360
static int32_t mndProcessAlterUserReq(SRpcMsg *pReq) {
326✔
2361
  SMnode       *pMnode = pReq->info.node;
326✔
2362
  SSdb         *pSdb = pMnode->pSdb;
326✔
2363
  void         *pIter = NULL;
326✔
2364
  int32_t       code = 0;
326✔
2365
  int32_t       lino = 0;
326✔
2366
  SUserObj     *pUser = NULL;
326✔
2367
  SUserObj     *pOperUser = NULL;
326✔
2368
  SUserObj      newUser = {0};
326✔
2369
  SAlterUserReq alterReq = {0};
326✔
2370

2371
  TAOS_CHECK_GOTO(tDeserializeSAlterUserReq(pReq->pCont, pReq->contLen, &alterReq), &lino, _OVER);
326!
2372

2373
  mInfo("user:%s, start to alter", alterReq.user);
326!
2374

2375
  if (alterReq.user[0] == 0) {
326!
2376
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
2377
  }
2378

2379
  if (TSDB_ALTER_USER_PASSWD == alterReq.alterType) {
326✔
2380
    int32_t len = strlen(alterReq.pass);
67✔
2381
    if (mndCheckPasswordMinLen(alterReq.pass, len) != 0) {
67✔
2382
      TAOS_CHECK_GOTO(TSDB_CODE_PAR_PASSWD_TOO_SHORT_OR_EMPTY, &lino, _OVER);
6!
2383
    }
2384
    if (mndCheckPasswordMaxLen(alterReq.pass, len) != 0) {
61✔
2385
      TAOS_CHECK_GOTO(TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG, &lino, _OVER);
1!
2386
    }
2387
    if (mndCheckPasswordFmt(alterReq.pass, len) != 0) {
60✔
2388
      TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_PASS_FORMAT, &lino, _OVER);
24!
2389
    }
2390
  }
2391

2392
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, alterReq.user, &pUser), &lino, _OVER);
295✔
2393

2394
  (void)mndAcquireUser(pMnode, pReq->info.conn.user, &pOperUser);
273✔
2395
  if (pOperUser == NULL) {
273!
2396
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_USER_FROM_CONN, &lino, _OVER);
×
2397
  }
2398

2399
  TAOS_CHECK_GOTO(mndCheckAlterUserPrivilege(pOperUser, pUser, &alterReq), &lino, _OVER);
273✔
2400

2401
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
229!
2402

2403
  if (alterReq.alterType == TSDB_ALTER_USER_PASSWD) {
229✔
2404
    char pass[TSDB_PASSWORD_LEN + 1] = {0};
35✔
2405
    taosEncryptPass_c((uint8_t *)alterReq.pass, strlen(alterReq.pass), pass);
35✔
2406
    (void)memcpy(newUser.pass, pass, TSDB_PASSWORD_LEN);
35✔
2407
    if (0 != strncmp(pUser->pass, pass, TSDB_PASSWORD_LEN)) {
35✔
2408
      ++newUser.passVersion;
31✔
2409
    }
2410
  }
2411

2412
  if (alterReq.alterType == TSDB_ALTER_USER_SUPERUSER) {
229!
2413
    newUser.superUser = alterReq.superUser;
×
2414
  }
2415

2416
  if (alterReq.alterType == TSDB_ALTER_USER_ENABLE) {
229✔
2417
    newUser.enable = alterReq.enable;
5✔
2418
  }
2419

2420
  if (alterReq.alterType == TSDB_ALTER_USER_SYSINFO) {
229✔
2421
    newUser.sysInfo = alterReq.sysInfo;
14✔
2422
  }
2423

2424
  if (alterReq.alterType == TSDB_ALTER_USER_CREATEDB) {
229✔
2425
    newUser.createdb = alterReq.createdb;
5✔
2426
  }
2427

2428
  if (ALTER_USER_ADD_PRIVS(alterReq.alterType) || ALTER_USER_DEL_PRIVS(alterReq.alterType)) {
229✔
2429
    TAOS_CHECK_GOTO(mndProcessAlterUserPrivilegesReq(&alterReq, pMnode, &newUser), &lino, _OVER);
168✔
2430
  }
2431

2432
  if (alterReq.alterType == TSDB_ALTER_USER_ADD_WHITE_LIST) {
222✔
2433
    taosMemoryFreeClear(newUser.pIpWhiteList);
1!
2434

2435
    int32_t       num = pUser->pIpWhiteList->num + alterReq.numIpRanges;
1✔
2436
    int32_t       idx = pUser->pIpWhiteList->num;
1✔
2437
    SIpWhiteList *pNew = taosMemoryCalloc(1, sizeof(SIpWhiteList) + sizeof(SIpV4Range) * num);
1!
2438

2439
    if (pNew == NULL) {
1!
2440
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2441
    }
2442

2443
    bool exist = false;
1✔
2444
    (void)memcpy(pNew->pIpRange, pUser->pIpWhiteList->pIpRange, sizeof(SIpV4Range) * idx);
1✔
2445
    for (int i = 0; i < alterReq.numIpRanges; i++) {
2✔
2446
      SIpV4Range *range = &(alterReq.pIpRanges[i]);
1✔
2447
      if (!isRangeInIpWhiteList(pUser->pIpWhiteList, range)) {
1!
2448
        // already exist, just ignore;
2449
        (void)memcpy(&pNew->pIpRange[idx], range, sizeof(SIpV4Range));
1✔
2450
        idx++;
1✔
2451
        continue;
1✔
2452
      } else {
2453
        exist = true;
×
2454
      }
2455
    }
2456
    if (exist) {
1!
2457
      taosMemoryFree(pNew);
×
2458
      TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_HOST_EXIST, &lino, _OVER);
×
2459
    }
2460
    pNew->num = idx;
1✔
2461
    newUser.pIpWhiteList = pNew;
1✔
2462
    newUser.ipWhiteListVer = pUser->ipWhiteListVer + 1;
1✔
2463

2464
    if (pNew->num > MND_MAX_USE_HOST) {
1!
2465
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_HOST, &lino, _OVER);
×
2466
    }
2467
  }
2468
  if (alterReq.alterType == TSDB_ALTER_USER_DROP_WHITE_LIST) {
222✔
2469
    taosMemoryFreeClear(newUser.pIpWhiteList);
1!
2470

2471
    int32_t       num = pUser->pIpWhiteList->num;
1✔
2472
    bool          noexist = true;
1✔
2473
    bool          localHost = false;
1✔
2474
    SIpWhiteList *pNew = taosMemoryCalloc(1, sizeof(SIpWhiteList) + sizeof(SIpV4Range) * num);
1!
2475

2476
    if (pNew == NULL) {
1!
2477
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2478
    }
2479

2480
    if (pUser->pIpWhiteList->num > 0) {
1!
2481
      int idx = 0;
1✔
2482
      for (int i = 0; i < pUser->pIpWhiteList->num; i++) {
3✔
2483
        SIpV4Range *oldRange = &pUser->pIpWhiteList->pIpRange[i];
2✔
2484
        bool        found = false;
2✔
2485
        for (int j = 0; j < alterReq.numIpRanges; j++) {
4✔
2486
          SIpV4Range *range = &alterReq.pIpRanges[j];
2✔
2487
          if (isDefaultRange(range)) {
2!
2488
            localHost = true;
×
2489
            break;
×
2490
          }
2491
          if (isIpRangeEqual(oldRange, range)) {
2!
2492
            found = true;
×
2493
            break;
×
2494
          }
2495
        }
2496
        if (localHost) break;
2!
2497

2498
        if (found == false) {
2!
2499
          (void)memcpy(&pNew->pIpRange[idx], oldRange, sizeof(SIpV4Range));
2✔
2500
          idx++;
2✔
2501
        } else {
2502
          noexist = false;
×
2503
        }
2504
      }
2505
      pNew->num = idx;
1✔
2506
      newUser.pIpWhiteList = pNew;
1✔
2507
      newUser.ipWhiteListVer = pUser->ipWhiteListVer + 1;
1✔
2508

2509
    } else {
2510
      pNew->num = 0;
×
2511
      newUser.pIpWhiteList = pNew;
×
2512
      newUser.ipWhiteListVer = pUser->ipWhiteListVer + 1;
×
2513
    }
2514

2515
    if (localHost) {
1!
2516
      TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_LOCAL_HOST_NOT_DROP, &lino, _OVER);
×
2517
    }
2518
    if (noexist) {
1!
2519
      TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_HOST_NOT_EXIST, &lino, _OVER);
1!
2520
    }
2521
  }
2522

2523
  code = mndAlterUser(pMnode, pUser, &newUser, pReq);
221✔
2524
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
221!
2525

2526
  if (alterReq.alterType == TSDB_ALTER_USER_PASSWD) {
221✔
2527
    char detail[1000] = {0};
35✔
2528
    (void)tsnprintf(detail, sizeof(detail),
35✔
2529
              "alterType:%s, enable:%d, superUser:%d, sysInfo:%d, createdb:%d, tabName:%s, password:xxx",
2530
              mndUserAuditTypeStr(alterReq.alterType), alterReq.enable, alterReq.superUser, alterReq.sysInfo,
35✔
2531
              alterReq.createdb ? 1 : 0, alterReq.tabName);
35✔
2532
    auditRecord(pReq, pMnode->clusterId, "alterUser", "", alterReq.user, detail, strlen(detail));
35✔
2533
  } else if (alterReq.alterType == TSDB_ALTER_USER_SUPERUSER || alterReq.alterType == TSDB_ALTER_USER_ENABLE ||
186!
2534
             alterReq.alterType == TSDB_ALTER_USER_SYSINFO || alterReq.alterType == TSDB_ALTER_USER_CREATEDB) {
181✔
2535
    auditRecord(pReq, pMnode->clusterId, "alterUser", "", alterReq.user, alterReq.sql, alterReq.sqlLen);
24✔
2536
  } else if (ALTER_USER_ADD_READ_DB_PRIV(alterReq.alterType, alterReq.privileges, alterReq.tabName) ||
162✔
2537
             ALTER_USER_ADD_WRITE_DB_PRIV(alterReq.alterType, alterReq.privileges, alterReq.tabName) ||
128✔
2538
             ALTER_USER_ADD_ALL_DB_PRIV(alterReq.alterType, alterReq.privileges, alterReq.tabName) ||
115!
2539
             ALTER_USER_ADD_READ_TB_PRIV(alterReq.alterType, alterReq.privileges, alterReq.tabName) ||
115!
2540
             ALTER_USER_ADD_WRITE_TB_PRIV(alterReq.alterType, alterReq.privileges, alterReq.tabName) ||
85!
2541
             ALTER_USER_ADD_ALL_TB_PRIV(alterReq.alterType, alterReq.privileges, alterReq.tabName)) {
62!
2542
    if (strcmp(alterReq.objname, "1.*") != 0) {
100✔
2543
      SName name = {0};
96✔
2544
      TAOS_CHECK_GOTO(tNameFromString(&name, alterReq.objname, T_NAME_ACCT | T_NAME_DB), &lino, _OVER);
96!
2545
      auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", name.dbname, alterReq.user, alterReq.sql,
96✔
2546
                  alterReq.sqlLen);
2547
    } else {
2548
      auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", "", alterReq.user, alterReq.sql, alterReq.sqlLen);
4✔
2549
    }
2550
  } else if (ALTER_USER_ADD_SUBSCRIBE_TOPIC_PRIV(alterReq.alterType, alterReq.privileges)) {
62✔
2551
    auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", alterReq.objname, alterReq.user, alterReq.sql,
15✔
2552
                alterReq.sqlLen);
2553
  } else if (ALTER_USER_DEL_SUBSCRIBE_TOPIC_PRIV(alterReq.alterType, alterReq.privileges)) {
47✔
2554
    auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", alterReq.objname, alterReq.user, alterReq.sql,
10✔
2555
                alterReq.sqlLen);
2556
  } else {
2557
    if (strcmp(alterReq.objname, "1.*") != 0) {
37✔
2558
      SName name = {0};
33✔
2559
      TAOS_CHECK_GOTO(tNameFromString(&name, alterReq.objname, T_NAME_ACCT | T_NAME_DB), &lino, _OVER);
33✔
2560
      auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", name.dbname, alterReq.user, alterReq.sql,
32✔
2561
                  alterReq.sqlLen);
2562
    } else {
2563
      auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", "", alterReq.user, alterReq.sql, alterReq.sqlLen);
4✔
2564
    }
2565
  }
2566

2567
_OVER:
326✔
2568
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
326✔
2569
    mError("user:%s, failed to alter at line %d since %s", alterReq.user, lino, tstrerror(code));
106!
2570
  }
2571

2572
  tFreeSAlterUserReq(&alterReq);
326✔
2573
  mndReleaseUser(pMnode, pOperUser);
326✔
2574
  mndReleaseUser(pMnode, pUser);
326✔
2575
  mndUserFreeObj(&newUser);
326✔
2576

2577
  TAOS_RETURN(code);
326✔
2578
}
2579

2580
static int32_t mndDropUser(SMnode *pMnode, SRpcMsg *pReq, SUserObj *pUser) {
44✔
2581
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "drop-user");
44✔
2582
  if (pTrans == NULL) {
44!
2583
    mError("user:%s, failed to drop since %s", pUser->user, terrstr());
×
2584
    TAOS_RETURN(terrno);
×
2585
  }
2586
  mInfo("trans:%d, used to drop user:%s", pTrans->id, pUser->user);
44!
2587

2588
  SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
44✔
2589
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
44!
2590
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
2591
    mndTransDrop(pTrans);
×
2592
    TAOS_RETURN(terrno);
×
2593
  }
2594
  if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED) < 0) {
44!
2595
    mndTransDrop(pTrans);
×
2596
    TAOS_RETURN(terrno);
×
2597
  }
2598

2599
  if (mndTransPrepare(pMnode, pTrans) != 0) {
44!
2600
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
2601
    mndTransDrop(pTrans);
×
2602
    TAOS_RETURN(terrno);
×
2603
  }
2604
  (void)ipWhiteMgtRemove(pUser->user);
44✔
2605

2606
  mndTransDrop(pTrans);
44✔
2607
  TAOS_RETURN(0);
44✔
2608
}
2609

2610
static int32_t mndProcessDropUserReq(SRpcMsg *pReq) {
44✔
2611
  SMnode      *pMnode = pReq->info.node;
44✔
2612
  int32_t      code = 0;
44✔
2613
  int32_t      lino = 0;
44✔
2614
  SUserObj    *pUser = NULL;
44✔
2615
  SDropUserReq dropReq = {0};
44✔
2616

2617
  TAOS_CHECK_GOTO(tDeserializeSDropUserReq(pReq->pCont, pReq->contLen, &dropReq), &lino, _OVER);
44!
2618

2619
  mInfo("user:%s, start to drop", dropReq.user);
44!
2620
  TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_DROP_USER), &lino, _OVER);
44!
2621

2622
  if (dropReq.user[0] == 0) {
44!
2623
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
2624
  }
2625

2626
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, dropReq.user, &pUser), &lino, _OVER);
44!
2627

2628
  TAOS_CHECK_GOTO(mndDropUser(pMnode, pReq, pUser), &lino, _OVER);
44!
2629
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
44!
2630

2631
  auditRecord(pReq, pMnode->clusterId, "dropUser", "", dropReq.user, dropReq.sql, dropReq.sqlLen);
44✔
2632

2633
_OVER:
44✔
2634
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
44!
2635
    mError("user:%s, failed to drop at line %d since %s", dropReq.user, lino, tstrerror(code));
×
2636
  }
2637

2638
  mndReleaseUser(pMnode, pUser);
44✔
2639
  tFreeSDropUserReq(&dropReq);
44✔
2640
  TAOS_RETURN(code);
44✔
2641
}
2642

2643
static int32_t mndProcessGetUserAuthReq(SRpcMsg *pReq) {
379,719✔
2644
  SMnode         *pMnode = pReq->info.node;
379,719✔
2645
  int32_t         code = 0;
379,719✔
2646
  int32_t         lino = 0;
379,719✔
2647
  int32_t         contLen = 0;
379,719✔
2648
  void           *pRsp = NULL;
379,719✔
2649
  SUserObj       *pUser = NULL;
379,719✔
2650
  SGetUserAuthReq authReq = {0};
379,719✔
2651
  SGetUserAuthRsp authRsp = {0};
379,719✔
2652

2653
  TAOS_CHECK_EXIT(tDeserializeSGetUserAuthReq(pReq->pCont, pReq->contLen, &authReq));
379,719!
2654
  mTrace("user:%s, start to get auth", authReq.user);
379,721✔
2655

2656
  TAOS_CHECK_EXIT(mndAcquireUser(pMnode, authReq.user, &pUser));
379,721✔
2657

2658
  TAOS_CHECK_EXIT(mndSetUserAuthRsp(pMnode, pUser, &authRsp));
379,719!
2659

2660
  contLen = tSerializeSGetUserAuthRsp(NULL, 0, &authRsp);
379,718✔
2661
  if (contLen < 0) {
379,704!
2662
    TAOS_CHECK_EXIT(contLen);
×
2663
  }
2664
  pRsp = rpcMallocCont(contLen);
379,704✔
2665
  if (pRsp == NULL) {
379,707!
2666
    TAOS_CHECK_EXIT(terrno);
×
2667
  }
2668

2669
  contLen = tSerializeSGetUserAuthRsp(pRsp, contLen, &authRsp);
379,707✔
2670
  if (contLen < 0) {
379,708!
2671
    TAOS_CHECK_EXIT(contLen);
×
2672
  }
2673

2674
_exit:
379,708✔
2675
  mndReleaseUser(pMnode, pUser);
379,710✔
2676
  tFreeSGetUserAuthRsp(&authRsp);
379,721✔
2677
  if (code < 0) {
379,721✔
2678
    mError("user:%s, failed to get auth at line %d since %s", authReq.user, lino, tstrerror(code));
2!
2679
    rpcFreeCont(pRsp);
2✔
2680
    pRsp = NULL;
2✔
2681
    contLen = 0;
2✔
2682
  }
2683
  pReq->info.rsp = pRsp;
379,721✔
2684
  pReq->info.rspLen = contLen;
379,721✔
2685
  pReq->code = code;
379,721✔
2686

2687
  TAOS_RETURN(code);
379,721✔
2688
}
2689

2690
static int32_t mndRetrieveUsers(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
5,072✔
2691
  SMnode   *pMnode = pReq->info.node;
5,072✔
2692
  SSdb     *pSdb = pMnode->pSdb;
5,072✔
2693
  int32_t   code = 0;
5,072✔
2694
  int32_t   lino = 0;
5,072✔
2695
  int32_t   numOfRows = 0;
5,072✔
2696
  SUserObj *pUser = NULL;
5,072✔
2697
  int32_t   cols = 0;
5,072✔
2698
  int8_t    flag = 0;
5,072✔
2699
  char     *pWrite = NULL;
5,072✔
2700
  char     *buf = NULL;
5,072✔
2701
  char     *varstr = NULL;
5,072✔
2702

2703
  while (numOfRows < rows) {
10,206✔
2704
    pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
10,204✔
2705
    if (pShow->pIter == NULL) break;
10,212✔
2706

2707
    cols = 0;
5,133✔
2708
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
5,133✔
2709
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
5,130✔
2710
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
5,130✔
2711
    COL_DATA_SET_VAL_GOTO((const char *)name, false, pUser, _exit);
5,130!
2712

2713
    cols++;
5,124✔
2714
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
5,124✔
2715
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->superUser, false, pUser, _exit);
5,123!
2716

2717
    cols++;
5,123✔
2718
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
5,123✔
2719
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->enable, false, pUser, _exit);
5,115!
2720

2721
    cols++;
5,123✔
2722
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
5,123✔
2723
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sysInfo, false, pUser, _exit);
5,121!
2724

2725
    cols++;
5,121✔
2726
    flag = pUser->createdb ? 1 : 0;
5,121✔
2727
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
5,121✔
2728
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, _exit);
5,122!
2729

2730
    cols++;
5,124✔
2731
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
5,124✔
2732
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->createdTime, false, pUser, _exit);
5,121!
2733

2734
    cols++;
5,123✔
2735

2736
    int32_t tlen = convertIpWhiteListToStr(pUser->pIpWhiteList, &buf);
5,123✔
2737
    // int32_t tlen = mndFetchIpWhiteList(pUser->pIpWhiteList, &buf);
2738
    if (tlen != 0) {
5,126!
2739
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
5,132!
2740
      if (varstr == NULL) {
5,134!
2741
        sdbRelease(pSdb, pUser);
×
2742
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
2743
      }
2744
      varDataSetLen(varstr, tlen);
5,134✔
2745
      (void)memcpy(varDataVal(varstr), buf, tlen);
5,134✔
2746

2747
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
5,134✔
2748
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, _exit);
5,129!
2749

2750
      taosMemoryFreeClear(buf);
5,124!
2751
    } else {
2752
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
2753
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, _exit);
×
2754
    }
2755

2756
    numOfRows++;
5,133✔
2757
    sdbRelease(pSdb, pUser);
5,133✔
2758
  }
2759

2760
  pShow->numOfRows += numOfRows;
5,081✔
2761
_exit:
5,081✔
2762
  taosMemoryFreeClear(buf);
5,081!
2763
  taosMemoryFreeClear(varstr);
5,081!
2764
  if (code < 0) {
5,083!
2765
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
2766
    TAOS_RETURN(code);
×
2767
  }
2768
  return numOfRows;
5,083✔
2769
}
2770

2771
static int32_t mndRetrieveUsersFull(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
×
2772
  int32_t numOfRows = 0;
×
2773
#ifdef TD_ENTERPRISE
2774
  SMnode   *pMnode = pReq->info.node;
×
2775
  SSdb     *pSdb = pMnode->pSdb;
×
2776
  SUserObj *pUser = NULL;
×
2777
  int32_t   code = 0;
×
2778
  int32_t   lino = 0;
×
2779
  int32_t   cols = 0;
×
2780
  int8_t    flag = 0;
×
2781
  char     *pWrite = NULL;
×
2782
  char     *buf = NULL;
×
2783
  char     *varstr = NULL;
×
2784

2785
  while (numOfRows < rows) {
×
2786
    pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
×
2787
    if (pShow->pIter == NULL) break;
×
2788

2789
    cols = 0;
×
2790
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
2791
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
×
2792
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
×
2793
    COL_DATA_SET_VAL_GOTO((const char *)name, false, pUser, _exit);
×
2794

2795
    cols++;
×
2796
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
2797
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->superUser, false, pUser, _exit);
×
2798

2799
    cols++;
×
2800
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
2801
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->enable, false, pUser, _exit);
×
2802

2803
    cols++;
×
2804
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
2805
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sysInfo, false, pUser, _exit);
×
2806

2807
    cols++;
×
2808
    flag = pUser->createdb ? 1 : 0;
×
2809
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
2810
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, _exit);
×
2811

2812
    // mInfo("pUser->pass:%s", pUser->pass);
2813
    cols++;
×
2814
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
2815
    char pass[TSDB_PASSWORD_LEN + VARSTR_HEADER_SIZE] = {0};
×
2816
    STR_WITH_MAXSIZE_TO_VARSTR(pass, pUser->pass, pShow->pMeta->pSchemas[cols].bytes);
×
2817
    COL_DATA_SET_VAL_GOTO((const char *)pass, false, pUser, _exit);
×
2818

2819
    cols++;
×
2820

2821
    int32_t tlen = convertIpWhiteListToStr(pUser->pIpWhiteList, &buf);
×
2822
    // int32_t tlen = mndFetchIpWhiteList(pUser->pIpWhiteList, &buf);
2823
    if (tlen != 0) {
×
2824
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
×
2825
      if (varstr == NULL) {
×
2826
        sdbRelease(pSdb, pUser);
×
2827
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
2828
      }
2829
      varDataSetLen(varstr, tlen);
×
2830
      (void)memcpy(varDataVal(varstr), buf, tlen);
×
2831

2832
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
2833
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, _exit);
×
2834

2835
      taosMemoryFreeClear(buf);
×
2836
    } else {
2837
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
2838
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, _exit);
×
2839
    }
2840

2841
    numOfRows++;
×
2842
    sdbRelease(pSdb, pUser);
×
2843
  }
2844

2845
  pShow->numOfRows += numOfRows;
×
2846
_exit:
×
2847
  taosMemoryFreeClear(buf);
×
2848
  taosMemoryFreeClear(varstr);
×
2849
  if (code < 0) {
×
2850
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
2851
    TAOS_RETURN(code);
×
2852
  }
2853
#endif
2854
  return numOfRows;
×
2855
}
2856

2857
static void mndCancelGetNextUser(SMnode *pMnode, void *pIter) {
×
2858
  SSdb *pSdb = pMnode->pSdb;
×
2859
  sdbCancelFetchByType(pSdb, pIter, SDB_USER);
×
2860
}
×
2861

2862
static int32_t mndLoopHash(SHashObj *hash, char *priType, SSDataBlock *pBlock, int32_t *pNumOfRows, SSdb *pSdb,
26,296✔
2863
                           SUserObj *pUser, SShowObj *pShow, char **condition, char **sql) {
2864
  char   *value = taosHashIterate(hash, NULL);
26,296✔
2865
  char   *user = pUser->user;
26,312✔
2866
  int32_t code = 0;
26,312✔
2867
  int32_t lino = 0;
26,312✔
2868
  int32_t cols = 0;
26,312✔
2869
  int32_t numOfRows = *pNumOfRows;
26,312✔
2870

2871
  while (value != NULL) {
26,314✔
2872
    cols = 0;
2✔
2873
    char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
2✔
2874
    STR_WITH_MAXSIZE_TO_VARSTR(userName, user, pShow->pMeta->pSchemas[cols].bytes);
2✔
2875
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2✔
2876
    COL_DATA_SET_VAL_GOTO((const char *)userName, false, NULL, _exit);
2!
2877

2878
    char privilege[20] = {0};
2✔
2879
    STR_WITH_MAXSIZE_TO_VARSTR(privilege, priType, pShow->pMeta->pSchemas[cols].bytes);
2✔
2880
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2✔
2881
    COL_DATA_SET_VAL_GOTO((const char *)privilege, false, NULL, _exit);
2!
2882

2883
    size_t keyLen = 0;
2✔
2884
    void  *key = taosHashGetKey(value, &keyLen);
2✔
2885

2886
    char dbName[TSDB_DB_NAME_LEN] = {0};
2✔
2887
    (void)mndExtractShortDbNameFromStbFullName(key, dbName);
2✔
2888
    char dbNameContent[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
2✔
2889
    STR_WITH_MAXSIZE_TO_VARSTR(dbNameContent, dbName, pShow->pMeta->pSchemas[cols].bytes);
2✔
2890
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2✔
2891
    COL_DATA_SET_VAL_GOTO((const char *)dbNameContent, false, NULL, _exit);
2!
2892

2893
    char tableName[TSDB_TABLE_NAME_LEN] = {0};
2✔
2894
    mndExtractTbNameFromStbFullName(key, tableName, TSDB_TABLE_NAME_LEN);
2✔
2895
    char tableNameContent[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
2✔
2896
    STR_WITH_MAXSIZE_TO_VARSTR(tableNameContent, tableName, pShow->pMeta->pSchemas[cols].bytes);
2✔
2897
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2✔
2898
    COL_DATA_SET_VAL_GOTO((const char *)tableNameContent, false, NULL, _exit);
2!
2899

2900
    if (strcmp("t", value) != 0 && strcmp("v", value) != 0) {
2!
2901
      SNode  *pAst = NULL;
×
2902
      int32_t sqlLen = 0;
×
2903
      size_t  bufSz = strlen(value) + 1;
×
2904
      if (bufSz < 6) bufSz = 6;
×
2905
      TAOS_MEMORY_REALLOC(*sql, bufSz);
×
2906
      if (*sql == NULL) {
×
2907
        code = terrno;
×
2908
        goto _exit;
×
2909
      }
2910
      TAOS_MEMORY_REALLOC(*condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
×
2911
      if ((*condition) == NULL) {
×
2912
        code = terrno;
×
2913
        goto _exit;
×
2914
      }
2915

2916
      if (nodesStringToNode(value, &pAst) == 0) {
×
2917
        if (nodesNodeToSQL(pAst, *sql, bufSz, &sqlLen) != 0) {
×
2918
          sqlLen = 5;
×
2919
          (void)tsnprintf(*sql, bufSz, "error");
×
2920
        }
2921
        nodesDestroyNode(pAst);
×
2922
      } else {
2923
        sqlLen = 5;
×
2924
        (void)tsnprintf(*sql, bufSz, "error");
×
2925
      }
2926

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

2929
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
2930
      COL_DATA_SET_VAL_GOTO((const char *)(*condition), false, NULL, _exit);
×
2931

2932
      char notes[2] = {0};
×
2933
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
×
2934
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
2935
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, NULL, _exit);
×
2936
    } else {
2937
      TAOS_MEMORY_REALLOC(*condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
2!
2938
      if ((*condition) == NULL) {
2!
2939
        code = terrno;
×
2940
        goto _exit;
×
2941
      }
2942
      STR_WITH_MAXSIZE_TO_VARSTR((*condition), "", pShow->pMeta->pSchemas[cols].bytes);
2✔
2943
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2✔
2944
      COL_DATA_SET_VAL_GOTO((const char *)(*condition), false, NULL, _exit);
2!
2945

2946
      char notes[64 + VARSTR_HEADER_SIZE] = {0};
2✔
2947
      STR_WITH_MAXSIZE_TO_VARSTR(notes, value[0] == 'v' ? "view" : "", sizeof(notes));
2!
2948
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2✔
2949
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, NULL, _exit);
2!
2950
    }
2951

2952
    numOfRows++;
2✔
2953
    value = taosHashIterate(hash, value);
2✔
2954
  }
2955
  *pNumOfRows = numOfRows;
26,312✔
2956
_exit:
26,312✔
2957
  if (code < 0) {
26,312!
2958
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
2959
    sdbRelease(pSdb, pUser);
×
2960
  }
2961
  TAOS_RETURN(code);
26,312✔
2962
}
2963

2964
static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
4,334✔
2965
  int32_t   code = 0;
4,334✔
2966
  int32_t   lino = 0;
4,334✔
2967
  SMnode   *pMnode = pReq->info.node;
4,334✔
2968
  SSdb     *pSdb = pMnode->pSdb;
4,334✔
2969
  int32_t   numOfRows = 0;
4,334✔
2970
  SUserObj *pUser = NULL;
4,334✔
2971
  int32_t   cols = 0;
4,334✔
2972
  char     *pWrite = NULL;
4,334✔
2973
  char     *condition = NULL;
4,334✔
2974
  char     *sql = NULL;
4,334✔
2975

2976
  bool fetchNextUser = pShow->restore ? false : true;
4,334✔
2977
  pShow->restore = false;
4,334✔
2978

2979
  while (numOfRows < rows) {
8,733!
2980
    if (fetchNextUser) {
8,733!
2981
      pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
8,733✔
2982
      if (pShow->pIter == NULL) break;
8,737✔
2983
    } else {
2984
      fetchNextUser = true;
×
2985
      void *pKey = taosHashGetKey(pShow->pIter, NULL);
×
2986
      pUser = sdbAcquire(pSdb, SDB_USER, pKey);
×
2987
      if (!pUser) {
×
2988
        continue;
×
2989
      }
2990
    }
2991

2992
    int32_t numOfReadDbs = taosHashGetSize(pUser->readDbs);
4,398✔
2993
    int32_t numOfWriteDbs = taosHashGetSize(pUser->writeDbs);
4,395✔
2994
    int32_t numOfTopics = taosHashGetSize(pUser->topics);
4,396✔
2995
    int32_t numOfReadTbs = taosHashGetSize(pUser->readTbs);
4,396✔
2996
    int32_t numOfWriteTbs = taosHashGetSize(pUser->writeTbs);
4,396✔
2997
    int32_t numOfAlterTbs = taosHashGetSize(pUser->alterTbs);
4,394✔
2998
    int32_t numOfReadViews = taosHashGetSize(pUser->readViews);
4,393✔
2999
    int32_t numOfWriteViews = taosHashGetSize(pUser->writeViews);
4,392✔
3000
    int32_t numOfAlterViews = taosHashGetSize(pUser->alterViews);
4,394✔
3001
    if (numOfRows + numOfReadDbs + numOfWriteDbs + numOfTopics + numOfReadTbs + numOfWriteTbs + numOfAlterTbs +
4,392✔
3002
            numOfReadViews + numOfWriteViews + numOfAlterViews >=
4,392!
3003
        rows) {
3004
      mInfo(
×
3005
          "will restore. current num of rows: %d, read dbs %d, write dbs %d, topics %d, read tables %d, write tables "
3006
          "%d, alter tables %d, read views %d, write views %d, alter views %d",
3007
          numOfRows, numOfReadDbs, numOfWriteDbs, numOfTopics, numOfReadTbs, numOfWriteTbs, numOfAlterTbs,
3008
          numOfReadViews, numOfWriteViews, numOfAlterViews);
3009
      pShow->restore = true;
×
3010
      sdbRelease(pSdb, pUser);
×
3011
      break;
×
3012
    }
3013

3014
    if (pUser->superUser) {
4,392✔
3015
      cols = 0;
4,332✔
3016
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
4,332✔
3017
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
4,332✔
3018
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4,332✔
3019
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, _exit);
4,321!
3020

3021
      char privilege[20] = {0};
4,323✔
3022
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "all", pShow->pMeta->pSchemas[cols].bytes);
4,323✔
3023
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4,323✔
3024
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, _exit);
4,322!
3025

3026
      char objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4,330✔
3027
      STR_WITH_MAXSIZE_TO_VARSTR(objName, "all", pShow->pMeta->pSchemas[cols].bytes);
4,330✔
3028
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4,330✔
3029
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, _exit);
4,327!
3030

3031
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4,327✔
3032
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
4,327✔
3033
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4,327✔
3034
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, _exit);
4,324!
3035

3036
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
4,327!
3037
      if (condition == NULL) {
4,337!
3038
        sdbRelease(pSdb, pUser);
×
3039
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
3040
      }
3041
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
4,337✔
3042
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4,337✔
3043
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, _exit);
4,322!
3044

3045
      char notes[2] = {0};
4,327✔
3046
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
4,327✔
3047
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4,327✔
3048
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, _exit);
4,321!
3049

3050
      numOfRows++;
4,328✔
3051
    }
3052

3053
    char *db = taosHashIterate(pUser->readDbs, NULL);
4,388✔
3054
    while (db != NULL) {
4,406✔
3055
      cols = 0;
19✔
3056
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
19✔
3057
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
19✔
3058
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3059
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, _exit);
19!
3060

3061
      char privilege[20] = {0};
19✔
3062
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "read", pShow->pMeta->pSchemas[cols].bytes);
19✔
3063
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3064
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, _exit);
19!
3065

3066
      SName name = {0};
19✔
3067
      char  objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
19✔
3068
      code = tNameFromString(&name, db, T_NAME_ACCT | T_NAME_DB);
19✔
3069
      if (code < 0) {
19!
3070
        sdbRelease(pSdb, pUser);
×
3071
        TAOS_CHECK_GOTO(code, &lino, _exit);
×
3072
      }
3073
      (void)tNameGetDbName(&name, varDataVal(objName));
19✔
3074
      varDataSetLen(objName, strlen(varDataVal(objName)));
19✔
3075
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3076
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, _exit);
19!
3077

3078
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
19✔
3079
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
19✔
3080
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3081
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, _exit);
19!
3082

3083
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
19!
3084
      if (condition == NULL) {
19!
3085
        sdbRelease(pSdb, pUser);
×
3086
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
3087
      }
3088
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
19✔
3089
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3090
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, _exit);
19!
3091

3092
      char notes[2] = {0};
19✔
3093
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
19✔
3094
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3095
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, _exit);
19!
3096

3097
      numOfRows++;
19✔
3098
      db = taosHashIterate(pUser->readDbs, db);
19✔
3099
    }
3100

3101
    db = taosHashIterate(pUser->writeDbs, NULL);
4,387✔
3102
    while (db != NULL) {
4,405✔
3103
      cols = 0;
19✔
3104
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
19✔
3105
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
19✔
3106
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3107
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, _exit);
19!
3108

3109
      char privilege[20] = {0};
19✔
3110
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "write", pShow->pMeta->pSchemas[cols].bytes);
19✔
3111
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3112
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, _exit);
19!
3113

3114
      SName name = {0};
19✔
3115
      char  objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
19✔
3116
      code = tNameFromString(&name, db, T_NAME_ACCT | T_NAME_DB);
19✔
3117
      if (code < 0) {
19!
3118
        sdbRelease(pSdb, pUser);
×
3119
        TAOS_CHECK_GOTO(code, &lino, _exit);
×
3120
      }
3121
      (void)tNameGetDbName(&name, varDataVal(objName));
19✔
3122
      varDataSetLen(objName, strlen(varDataVal(objName)));
19✔
3123
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3124
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, _exit);
19!
3125

3126
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
19✔
3127
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
19✔
3128
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3129
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, _exit);
19!
3130

3131
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
19!
3132
      if (condition == NULL) {
19!
3133
        sdbRelease(pSdb, pUser);
×
3134
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
3135
      }
3136
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
19✔
3137
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3138
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, _exit);
19!
3139

3140
      char notes[2] = {0};
19✔
3141
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
19✔
3142
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3143
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, _exit);
19!
3144

3145
      numOfRows++;
19✔
3146
      db = taosHashIterate(pUser->writeDbs, db);
19✔
3147
    }
3148

3149
    TAOS_CHECK_EXIT(mndLoopHash(pUser->readTbs, "read", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
4,386!
3150

3151
    TAOS_CHECK_EXIT(mndLoopHash(pUser->writeTbs, "write", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
4,391!
3152

3153
    TAOS_CHECK_EXIT(mndLoopHash(pUser->alterTbs, "alter", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
4,397!
3154

3155
    TAOS_CHECK_EXIT(mndLoopHash(pUser->readViews, "read", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
4,397!
3156

3157
    TAOS_CHECK_EXIT(mndLoopHash(pUser->writeViews, "write", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
4,394!
3158

3159
    TAOS_CHECK_EXIT(mndLoopHash(pUser->alterViews, "alter", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
4,397!
3160

3161
    char *topic = taosHashIterate(pUser->topics, NULL);
4,396✔
3162
    while (topic != NULL) {
4,404✔
3163
      cols = 0;
8✔
3164
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
8✔
3165
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
8✔
3166
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
8✔
3167
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, _exit);
8!
3168

3169
      char privilege[20] = {0};
8✔
3170
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "subscribe", pShow->pMeta->pSchemas[cols].bytes);
8✔
3171
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
8✔
3172
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, _exit);
8!
3173

3174
      char topicName[TSDB_TOPIC_NAME_LEN + VARSTR_HEADER_SIZE + 5] = {0};
8✔
3175
      tstrncpy(varDataVal(topicName), mndGetDbStr(topic), TSDB_TOPIC_NAME_LEN - 2);
8✔
3176
      varDataSetLen(topicName, strlen(varDataVal(topicName)));
8✔
3177
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
8✔
3178
      COL_DATA_SET_VAL_GOTO((const char *)topicName, false, pUser, _exit);
8!
3179

3180
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
8✔
3181
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
8✔
3182
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
8✔
3183
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, _exit);
8!
3184

3185
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
8!
3186
      if (condition == NULL) {
8!
3187
        sdbRelease(pSdb, pUser);
×
3188
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
3189
      }
3190
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
8✔
3191
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
8✔
3192
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, _exit);
8!
3193

3194
      char notes[2] = {0};
8✔
3195
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
8✔
3196
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
8✔
3197
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, _exit);
8!
3198

3199
      numOfRows++;
8✔
3200
      topic = taosHashIterate(pUser->topics, topic);
8✔
3201
    }
3202

3203
    sdbRelease(pSdb, pUser);
4,396✔
3204
  }
3205

3206
  pShow->numOfRows += numOfRows;
4,339✔
3207
_exit:
4,339✔
3208
  taosMemoryFreeClear(condition);
4,339!
3209
  taosMemoryFreeClear(sql);
4,339!
3210
  if (code < 0) {
4,339!
3211
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
3212
    TAOS_RETURN(code);
×
3213
  }
3214
  return numOfRows;
4,339✔
3215
}
3216

3217
static void mndCancelGetNextPrivileges(SMnode *pMnode, void *pIter) {
×
3218
  SSdb *pSdb = pMnode->pSdb;
×
3219
  sdbCancelFetchByType(pSdb, pIter, SDB_USER);
×
3220
}
×
3221

3222
int32_t mndValidateUserAuthInfo(SMnode *pMnode, SUserAuthVersion *pUsers, int32_t numOfUses, void **ppRsp,
226,591✔
3223
                                int32_t *pRspLen, int64_t ipWhiteListVer) {
3224
  int32_t           code = 0;
226,591✔
3225
  int32_t           lino = 0;
226,591✔
3226
  int32_t           rspLen = 0;
226,591✔
3227
  void             *pRsp = NULL;
226,591✔
3228
  SUserAuthBatchRsp batchRsp = {0};
226,591✔
3229

3230
  batchRsp.pArray = taosArrayInit(numOfUses, sizeof(SGetUserAuthRsp));
226,591✔
3231
  if (batchRsp.pArray == NULL) {
226,589!
3232
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3233
  }
3234

3235
  for (int32_t i = 0; i < numOfUses; ++i) {
453,368✔
3236
    SUserObj *pUser = NULL;
226,766✔
3237
    code = mndAcquireUser(pMnode, pUsers[i].user, &pUser);
226,766✔
3238
    if (pUser == NULL) {
226,771✔
3239
      if (TSDB_CODE_MND_USER_NOT_EXIST == code) {
18!
3240
        SGetUserAuthRsp rsp = {.dropped = 1};
18✔
3241
        (void)memcpy(rsp.user, pUsers[i].user, TSDB_USER_LEN);
18✔
3242
        TSDB_CHECK_NULL(taosArrayPush(batchRsp.pArray, &rsp), code, lino, _OVER, TSDB_CODE_OUT_OF_MEMORY);
36!
3243
      }
3244
      mError("user:%s, failed to auth user since %s", pUsers[i].user, tstrerror(code));
18!
3245
      code = 0;
18✔
3246
      continue;
211,964✔
3247
    }
3248

3249
    pUsers[i].version = ntohl(pUsers[i].version);
226,753✔
3250
    if (pUser->authVersion <= pUsers[i].version && ipWhiteListVer == pMnode->ipWhiteVer) {
226,753✔
3251
      mndReleaseUser(pMnode, pUser);
211,943✔
3252
      continue;
211,946✔
3253
    }
3254

3255
    SGetUserAuthRsp rsp = {0};
14,810✔
3256
    code = mndSetUserAuthRsp(pMnode, pUser, &rsp);
14,810✔
3257
    if (code) {
14,815!
3258
      mndReleaseUser(pMnode, pUser);
×
3259
      tFreeSGetUserAuthRsp(&rsp);
×
3260
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3261
    }
3262

3263
    if (!(taosArrayPush(batchRsp.pArray, &rsp))) {
29,630!
3264
      code = terrno;
×
3265
      mndReleaseUser(pMnode, pUser);
×
3266
      tFreeSGetUserAuthRsp(&rsp);
×
3267
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3268
    }
3269
    mndReleaseUser(pMnode, pUser);
14,815✔
3270
  }
3271

3272
  if (taosArrayGetSize(batchRsp.pArray) <= 0) {
226,602✔
3273
    *ppRsp = NULL;
211,922✔
3274
    *pRspLen = 0;
211,922✔
3275

3276
    tFreeSUserAuthBatchRsp(&batchRsp);
211,922✔
3277
    return 0;
211,922✔
3278
  }
3279

3280
  rspLen = tSerializeSUserAuthBatchRsp(NULL, 0, &batchRsp);
14,677✔
3281
  if (rspLen < 0) {
14,677!
3282
    TAOS_CHECK_GOTO(rspLen, &lino, _OVER);
×
3283
  }
3284
  pRsp = taosMemoryMalloc(rspLen);
14,677!
3285
  if (pRsp == NULL) {
14,677!
3286
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3287
  }
3288
  rspLen = tSerializeSUserAuthBatchRsp(pRsp, rspLen, &batchRsp);
14,677✔
3289
  if (rspLen < 0) {
14,677!
3290
    TAOS_CHECK_GOTO(rspLen, &lino, _OVER);
×
3291
  }
3292
_OVER:
14,677✔
3293
  tFreeSUserAuthBatchRsp(&batchRsp);
14,677✔
3294
  if (code < 0) {
14,677!
3295
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
3296
    taosMemoryFreeClear(pRsp);
×
3297
    rspLen = 0;
×
3298
  }
3299
  *ppRsp = pRsp;
14,677✔
3300
  *pRspLen = rspLen;
14,677✔
3301

3302
  TAOS_RETURN(code);
14,677✔
3303
}
3304

3305
int32_t mndUserRemoveDb(SMnode *pMnode, STrans *pTrans, char *db) {
1,865✔
3306
  int32_t   code = 0;
1,865✔
3307
  int32_t   lino = 0;
1,865✔
3308
  SSdb     *pSdb = pMnode->pSdb;
1,865✔
3309
  int32_t   len = strlen(db) + 1;
1,865✔
3310
  void     *pIter = NULL;
1,865✔
3311
  SUserObj *pUser = NULL;
1,865✔
3312
  SUserObj  newUser = {0};
1,865✔
3313

3314
  while (1) {
2,054✔
3315
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
3,919✔
3316
    if (pIter == NULL) break;
3,919✔
3317

3318
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
2,054!
3319
      break;
×
3320
    }
3321

3322
    bool inRead = (taosHashGet(newUser.readDbs, db, len) != NULL);
2,054✔
3323
    bool inWrite = (taosHashGet(newUser.writeDbs, db, len) != NULL);
2,054✔
3324
    if (inRead || inWrite) {
2,054!
3325
      code = taosHashRemove(newUser.readDbs, db, len);
2✔
3326
      if (code < 0) {
2!
3327
        mError("failed to remove readDbs:%s from user:%s", db, pUser->user);
×
3328
      }
3329
      code = taosHashRemove(newUser.writeDbs, db, len);
2✔
3330
      if (code < 0) {
2!
3331
        mError("failed to remove writeDbs:%s from user:%s", db, pUser->user);
×
3332
      }
3333

3334
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
2✔
3335
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
2!
3336
        code = TSDB_CODE_OUT_OF_MEMORY;
×
3337
        break;
×
3338
      }
3339
      TAOS_CHECK_GOTO(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY), &lino, _OVER);
2!
3340
    }
3341

3342
    mndUserFreeObj(&newUser);
2,054✔
3343
    sdbRelease(pSdb, pUser);
2,054✔
3344
  }
3345

3346
_OVER:
1,865✔
3347
  if (pUser != NULL) sdbRelease(pSdb, pUser);
1,865!
3348
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
1,865!
3349
  mndUserFreeObj(&newUser);
1,865✔
3350
  TAOS_RETURN(code);
1,865✔
3351
}
3352

3353
int32_t mndUserRemoveStb(SMnode *pMnode, STrans *pTrans, char *stb) {
955✔
3354
  int32_t   code = 0;
955✔
3355
  SSdb     *pSdb = pMnode->pSdb;
955✔
3356
  int32_t   len = strlen(stb) + 1;
955✔
3357
  void     *pIter = NULL;
955✔
3358
  SUserObj *pUser = NULL;
955✔
3359
  SUserObj  newUser = {0};
955✔
3360

3361
  while (1) {
955✔
3362
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
1,910✔
3363
    if (pIter == NULL) break;
1,910✔
3364

3365
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
955!
3366
      break;
×
3367
    }
3368

3369
    bool inRead = (taosHashGet(newUser.readTbs, stb, len) != NULL);
955✔
3370
    bool inWrite = (taosHashGet(newUser.writeTbs, stb, len) != NULL);
955✔
3371
    bool inAlter = (taosHashGet(newUser.alterTbs, stb, len) != NULL);
955✔
3372
    if (inRead || inWrite || inAlter) {
955!
3373
      code = taosHashRemove(newUser.readTbs, stb, len);
×
3374
      if (code < 0) {
×
3375
        mError("failed to remove readTbs:%s from user:%s", stb, pUser->user);
×
3376
      }
3377
      code = taosHashRemove(newUser.writeTbs, stb, len);
×
3378
      if (code < 0) {
×
3379
        mError("failed to remove writeTbs:%s from user:%s", stb, pUser->user);
×
3380
      }
3381
      code = taosHashRemove(newUser.alterTbs, stb, len);
×
3382
      if (code < 0) {
×
3383
        mError("failed to remove alterTbs:%s from user:%s", stb, pUser->user);
×
3384
      }
3385

3386
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
×
3387
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
×
3388
        code = TSDB_CODE_OUT_OF_MEMORY;
×
3389
        break;
×
3390
      }
3391
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
×
3392
      if (code != 0) {
×
3393
        mndUserFreeObj(&newUser);
×
3394
        sdbRelease(pSdb, pUser);
×
3395
        TAOS_RETURN(code);
×
3396
      }
3397
    }
3398

3399
    mndUserFreeObj(&newUser);
955✔
3400
    sdbRelease(pSdb, pUser);
955✔
3401
  }
3402

3403
  if (pUser != NULL) sdbRelease(pSdb, pUser);
955!
3404
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
955!
3405
  mndUserFreeObj(&newUser);
955✔
3406
  TAOS_RETURN(code);
955✔
3407
}
3408

3409
int32_t mndUserRemoveView(SMnode *pMnode, STrans *pTrans, char *view) {
107✔
3410
  int32_t   code = 0;
107✔
3411
  SSdb     *pSdb = pMnode->pSdb;
107✔
3412
  int32_t   len = strlen(view) + 1;
107✔
3413
  void     *pIter = NULL;
107✔
3414
  SUserObj *pUser = NULL;
107✔
3415
  SUserObj  newUser = {0};
107✔
3416

3417
  while (1) {
113✔
3418
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
220✔
3419
    if (pIter == NULL) break;
220✔
3420

3421
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
113!
3422
      break;
×
3423
    }
3424

3425
    bool inRead = (taosHashGet(newUser.readViews, view, len) != NULL);
113✔
3426
    bool inWrite = (taosHashGet(newUser.writeViews, view, len) != NULL);
113✔
3427
    bool inAlter = (taosHashGet(newUser.alterViews, view, len) != NULL);
113✔
3428
    if (inRead || inWrite || inAlter) {
113!
3429
      code = taosHashRemove(newUser.readViews, view, len);
2✔
3430
      if (code < 0) {
2!
3431
        mError("failed to remove readViews:%s from user:%s", view, pUser->user);
×
3432
      }
3433
      code = taosHashRemove(newUser.writeViews, view, len);
2✔
3434
      if (code < 0) {
2!
3435
        mError("failed to remove writeViews:%s from user:%s", view, pUser->user);
2!
3436
      }
3437
      code = taosHashRemove(newUser.alterViews, view, len);
2✔
3438
      if (code < 0) {
2!
3439
        mError("failed to remove alterViews:%s from user:%s", view, pUser->user);
2!
3440
      }
3441

3442
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
2✔
3443
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
2!
3444
        code = TSDB_CODE_OUT_OF_MEMORY;
×
3445
        break;
×
3446
      }
3447
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
2✔
3448
      if (code < 0) {
2!
3449
        mndUserFreeObj(&newUser);
×
3450
        sdbRelease(pSdb, pUser);
×
3451
        TAOS_RETURN(code);
×
3452
      }
3453
    }
3454

3455
    mndUserFreeObj(&newUser);
113✔
3456
    sdbRelease(pSdb, pUser);
113✔
3457
  }
3458

3459
  if (pUser != NULL) sdbRelease(pSdb, pUser);
107!
3460
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
107!
3461
  mndUserFreeObj(&newUser);
107✔
3462
  TAOS_RETURN(code);
107✔
3463
}
3464

3465
int32_t mndUserRemoveTopic(SMnode *pMnode, STrans *pTrans, char *topic) {
322✔
3466
  int32_t   code = 0;
322✔
3467
  SSdb     *pSdb = pMnode->pSdb;
322✔
3468
  int32_t   len = strlen(topic) + 1;
322✔
3469
  void     *pIter = NULL;
322✔
3470
  SUserObj *pUser = NULL;
322✔
3471
  SUserObj  newUser = {0};
322✔
3472

3473
  while (1) {
325✔
3474
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
647✔
3475
    if (pIter == NULL) {
647✔
3476
      break;
322✔
3477
    }
3478

3479
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
325!
3480
      break;
×
3481
    }
3482

3483
    bool inTopic = (taosHashGet(newUser.topics, topic, len) != NULL);
325✔
3484
    if (inTopic) {
325!
3485
      code = taosHashRemove(newUser.topics, topic, len);
×
3486
      if (code < 0) {
×
3487
        mError("failed to remove topic:%s from user:%s", topic, pUser->user);
×
3488
      }
3489
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
×
3490
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
×
3491
        code = TSDB_CODE_OUT_OF_MEMORY;
×
3492
        break;
×
3493
      }
3494
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
×
3495
      if (code < 0) {
×
3496
        mndUserFreeObj(&newUser);
×
3497
        sdbRelease(pSdb, pUser);
×
3498
        TAOS_RETURN(code);
×
3499
      }
3500
    }
3501

3502
    mndUserFreeObj(&newUser);
325✔
3503
    sdbRelease(pSdb, pUser);
325✔
3504
  }
3505

3506
  if (pUser != NULL) sdbRelease(pSdb, pUser);
322!
3507
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
322!
3508
  mndUserFreeObj(&newUser);
322✔
3509
  TAOS_RETURN(code);
322✔
3510
}
3511

3512
int64_t mndGetUserIpWhiteListVer(SMnode *pMnode, SUserObj *pUser) {
×
3513
  // ver = 0, disable ip white list
3514
  // ver > 0, enable ip white list
3515
  return tsEnableWhiteList ? pUser->ipWhiteListVer : 0;
×
3516
}
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