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

taosdata / TDengine / #3558

17 Dec 2024 06:05AM UTC coverage: 59.778% (+1.6%) from 58.204%
#3558

push

travis-ci

web-flow
Merge pull request #29179 from taosdata/merge/mainto3.0

merge: form main to 3.0 branch

132787 of 287595 branches covered (46.17%)

Branch coverage included in aggregate %.

104 of 191 new or added lines in 5 files covered. (54.45%)

6085 existing lines in 168 files now uncovered.

209348 of 284746 relevant lines covered (73.52%)

8164844.48 hits per line

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

60.65
/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,516✔
140
  ipWhiteMgt.pIpWhiteTab = taosHashInit(8, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), 1, HASH_ENTRY_LOCK);
1,516✔
141
  if (ipWhiteMgt.pIpWhiteTab == NULL) {
1,516!
142
    TAOS_RETURN(terrno);
×
143
  }
144
  ipWhiteMgt.ver = 0;
1,516✔
145
  (void)taosThreadRwlockInit(&ipWhiteMgt.rw, NULL);
1,516✔
146
  TAOS_RETURN(0);
1,516✔
147
}
148
void ipWhiteMgtCleanup() {
1,515✔
149
  destroyIpWhiteTab(ipWhiteMgt.pIpWhiteTab);
1,515✔
150
  (void)taosThreadRwlockDestroy(&ipWhiteMgt.rw);
1,515✔
151
}
1,515✔
152

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

161
  if (ppList == NULL || *ppList == NULL) {
452!
162
    SIpWhiteList *p = cloneIpWhiteList(pNew);
126✔
163
    if (p == NULL) {
126!
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) {
126!
168
      update = false;
×
169
      taosMemoryFree(p);
×
170
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
171
    }
172
  } else {
173
    SIpWhiteList *pOld = *ppList;
200✔
174
    if (isIpWhiteListEqual(pOld, pNew)) {
200✔
175
      update = false;
178✔
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
326✔
192
  if (fqdns == NULL) {
326!
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++) {
858✔
198
    char *fqdn = taosArrayGetP(fqdns, i);
532✔
199
    bool  upd = false;
532✔
200
    TAOS_CHECK_GOTO(mndUpdateIpWhiteImpl(ipWhiteMgt.pIpWhiteTab, TSDB_DEFAULT_USER, fqdn, IP_WHITE_ADD, &upd), &lino,
532!
201
                    _OVER);
202
    update |= upd;
532✔
203
    TAOS_CHECK_GOTO(mndUpdateIpWhiteImpl(ipWhiteMgt.pIpWhiteTab, user, fqdn, IP_WHITE_ADD, &upd), &lino, _OVER);
532!
204
    update |= upd;
532✔
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++;
326✔
213

214
_OVER:
178✔
215
  (void)taosThreadRwlockUnlock(&ipWhiteMgt.rw);
326✔
216
  taosArrayDestroyP(fqdns, NULL);
326✔
217
  if (code < 0) {
326!
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);
326✔
221
}
222
int32_t ipWhiteMgtRemove(char *user) {
43✔
223
  bool    update = true;
43✔
224
  int32_t code = 0;
43✔
225
  (void)taosThreadRwlockWrlock(&ipWhiteMgt.rw);
43✔
226
  SIpWhiteList **ppList = taosHashGet(ipWhiteMgt.pIpWhiteTab, user, strlen(user));
43✔
227
  if (ppList == NULL || *ppList == NULL) {
43!
228
    update = false;
×
229
  } else {
230
    taosMemoryFree(*ppList);
43!
231
    code = taosHashRemove(ipWhiteMgt.pIpWhiteTab, user, strlen(user));
43✔
232
    if (code != 0) {
43!
233
      update = false;
×
234
    }
235
  }
236

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

242
bool isRangeInWhiteList(SIpWhiteList *pList, SIpV4Range *range) {
4,060✔
243
  for (int i = 0; i < pList->num; i++) {
5,109✔
244
    if (isIpRangeEqual(&pList->pIpRange[i], range)) {
4,899✔
245
      return true;
3,850✔
246
    }
247
  }
248
  return false;
210✔
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,539✔
298
  SHashObj *pNew = NULL;
1,539✔
299
  TAOS_CHECK_RETURN(mndFetchAllIpWhite(pMnode, &pNew));
1,539!
300

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

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

306
  destroyIpWhiteTab(pOld);
1,539✔
307
  TAOS_RETURN(0);
1,539✔
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) {
82,671✔
321
  int64_t ver = 0;
82,671✔
322
  int32_t code = 0;
82,671✔
323
  (void)taosThreadRwlockWrlock(&ipWhiteMgt.rw);
82,671✔
324
  if (ipWhiteMgt.ver == 0) {
82,675!
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;
82,675✔
334
  (void)taosThreadRwlockUnlock(&ipWhiteMgt.rw);
82,675✔
335

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

343
int32_t mndUpdateIpWhiteImpl(SHashObj *pIpWhiteTab, char *user, char *fqdn, int8_t type, bool *pUpdate) {
5,192✔
344
  int32_t    lino = 0;
5,192✔
345
  bool       update = false;
5,192✔
346
  SIpV4Range range = {.ip = 0, .mask = 32};
5,192✔
347
  int32_t    code = taosGetIpv4FromFqdn(fqdn, &range.ip);
5,192✔
348
  if (code) {
5,192!
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);
5,192✔
353
  SIpWhiteList **ppList = taosHashGet(pIpWhiteTab, user, strlen(user));
5,192✔
354
  SIpWhiteList  *pList = NULL;
5,192✔
355
  if (ppList != NULL && *ppList != NULL) {
5,192!
356
    pList = *ppList;
4,060✔
357
  }
358

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

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

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

386
        if ((code = taosHashPut(pIpWhiteTab, user, strlen(user), &pNewList, sizeof(void *))) != 0) {
210!
387
          taosMemoryFree(pNewList);
×
388
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
389
        }
390
        taosMemoryFree(pList);
210!
391
        update = true;
210✔
392
      }
393
    }
394
  } else if (type == IP_WHITE_DROP) {
20!
395
    if (pList != NULL) {
20✔
396
      if (isRangeInWhiteList(pList, &range)) {
18!
397
        if (pList->num == 1) {
18!
398
          if (taosHashRemove(pIpWhiteTab, user, strlen(user)) < 0) {
18!
399
            mError("failed to remove ip-white-list for user: %s at line %d", user, lino);
×
400
          }
401
          taosMemoryFree(pList);
18!
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;
18✔
425
      }
426
    }
427
  }
428
  if (update) {
5,192✔
429
    mDebug("ip-white-list update for user: %s, fqdn: %s", user, fqdn);
1,358✔
430
  }
431

432
_OVER:
3,903✔
433
  if (pUpdate) *pUpdate = update;
5,192✔
434
  if (code < 0) {
5,192!
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);
5,192✔
439
}
440

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

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

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

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

460
  if (lock) {
1,531!
461
    (void)taosThreadRwlockWrlock(&ipWhiteMgt.rw);
1,531✔
462
    if (ipWhiteMgt.ver == 0) {
1,531!
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,531!
470

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

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

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

493
_OVER:
1,531✔
494
  if (update) ipWhiteMgt.ver++;
1,531✔
495
  if (lock) (void)taosThreadRwlockUnlock(&ipWhiteMgt.rw);
1,531!
496
  if (code < 0) {
1,531!
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,531✔
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,054✔
546
  if (pIpWhiteTab == NULL) return;
3,054!
547

548
  void *pIter = taosHashIterate(pIpWhiteTab, NULL);
3,054✔
549
  while (pIter) {
4,599✔
550
    SIpWhiteList *list = *(SIpWhiteList **)pIter;
1,545✔
551
    taosMemoryFree(list);
1,545!
552
    pIter = taosHashIterate(pIpWhiteTab, pIter);
1,545✔
553
  }
554

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

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

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

580
    SIpWhiteList *pWhiteList = cloneIpWhiteList(pUser->pIpWhiteList);
350✔
581
    if (pWhiteList == NULL) {
350!
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) {
350!
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);
350!
594
    if (name == NULL) {
350!
595
      sdbRelease(pSdb, pUser);
×
596
      sdbCancelFetch(pSdb, pIter);
×
597
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
598
    }
599
    if (taosArrayPush(pUserNames, &name) == NULL) {
350!
600
      taosMemoryFree(name);
×
601
      sdbRelease(pSdb, pUser);
×
602
      sdbCancelFetch(pSdb, pIter);
×
603
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
604
    }
605

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

609
  bool found = false;
1,539✔
610
  for (int i = 0; i < taosArrayGetSize(pUserNames); i++) {
1,543✔
611
    char *name = taosArrayGetP(pUserNames, i);
349✔
612
    if (strlen(name) == strlen(TSDB_DEFAULT_USER) && strncmp(name, TSDB_DEFAULT_USER, strlen(TSDB_DEFAULT_USER)) == 0) {
349!
613
      found = true;
345✔
614
      break;
345✔
615
    }
616
  }
617
  if (found == false) {
1,539✔
618
    char *name = taosStrdup(TSDB_DEFAULT_USER);
1,194!
619
    if (name == NULL) {
1,194!
620
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
621
    }
622
    if (taosArrayPush(pUserNames, &name) == NULL) {
1,194!
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,539✔
629
  if (fqdns == NULL) {
1,539!
630
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
631
  }
632

633
  for (int i = 0; i < taosArrayGetSize(fqdns); i++) {
2,587✔
634
    char *fqdn = taosArrayGetP(fqdns, i);
1,048✔
635

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

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

646
  if (code < 0) {
1,539!
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,539✔
652
  TAOS_RETURN(code);
1,539✔
653
}
654

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

658
  SSdbTable table = {
1,516✔
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,516✔
670
  mndSetMsgHandle(pMnode, TDMT_MND_ALTER_USER, mndProcessAlterUserReq);
1,516✔
671
  mndSetMsgHandle(pMnode, TDMT_MND_DROP_USER, mndProcessDropUserReq);
1,516✔
672
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_AUTH, mndProcessGetUserAuthReq);
1,516✔
673
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_WHITELIST, mndProcessGetUserWhiteListReq);
1,516✔
674

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

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

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

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

692
  (void)uv_inet_ntop(AF_INET, &addr, buf, 32);
5,116✔
693
  if (range->mask != 32) {
5,132✔
694
    (void)tsnprintf(buf + strlen(buf), 36 - strlen(buf), "/%d", range->mask);
6✔
695
  }
696
  return;
5,132✔
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,108✔
703
  int32_t len = 0;
5,108✔
704
  for (int i = 0; i < num; i++) {
10,238✔
705
    char        tbuf[36] = {0};
5,116✔
706
    SIpV4Range *pRange = &range[i];
5,116✔
707

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

715
static bool isIpRangeEqual(SIpV4Range *a, SIpV4Range *b) {
5,082✔
716
  // equal or not
717
  return a->ip == b->ip && a->mask == b->mask;
5,082!
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) {
200✔
726
  if (a->num != b->num) {
200✔
727
    return false;
22✔
728
  }
729
  for (int i = 0; i < a->num; i++) {
356✔
730
    if (!isIpRangeEqual(&a->pIpRange[i], &b->pIpRange[i])) {
178!
731
      return false;
×
732
    }
733
  }
734
  return true;
178✔
735
}
736
int32_t convertIpWhiteListToStr(SIpWhiteList *pList, char **buf) {
5,108✔
737
  if (pList->num == 0) {
5,108!
738
    *buf = NULL;
×
739
    return 0;
×
740
  }
741
  int64_t bufLen = pList->num * 36;
5,108✔
742
  *buf = taosMemoryCalloc(1, bufLen);
5,108!
743
  if (*buf == NULL) {
5,119!
UNCOV
744
    return 0;
×
745
  }
746

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

761
  TAOS_CHECK_GOTO(tStartEncode(&encoder), &lino, _OVER);
4,243!
762
  TAOS_CHECK_GOTO(tEncodeI32(&encoder, pList->num), &lino, _OVER);
8,486!
763

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

956
  stb = taosHashIterate(pUser->alterTbs, NULL);
4,243✔
957
  while (stb != NULL) {
4,251✔
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,243✔
971
  while (stb != NULL) {
4,295✔
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,243✔
985
  while (stb != NULL) {
4,287✔
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,243✔
999
  while (stb != NULL) {
4,289✔
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,243✔
1013
  while (useDb != NULL) {
4,349✔
1014
    size_t keyLen = 0;
106✔
1015
    void  *key = taosHashGetKey(useDb, &keyLen);
106✔
1016
    size += sizeof(int32_t);
106✔
1017
    size += keyLen;
106✔
1018
    size += sizeof(int32_t);
106✔
1019
    useDb = taosHashIterate(pUser->useDbs, useDb);
106✔
1020
  }
1021

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

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

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

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

1055
  char *topic = taosHashIterate(pUser->topics, NULL);
4,243✔
1056
  while (topic != NULL) {
4,280✔
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,243!
1062
  SDB_SET_INT32(pRaw, dataPos, numOfWriteTbs, _OVER)
4,243!
1063
  SDB_SET_INT32(pRaw, dataPos, numOfAlterTbs, _OVER)
4,243!
1064
  SDB_SET_INT32(pRaw, dataPos, numOfReadViews, _OVER)
4,243!
1065
  SDB_SET_INT32(pRaw, dataPos, numOfWriteViews, _OVER)
4,243!
1066
  SDB_SET_INT32(pRaw, dataPos, numOfAlterViews, _OVER)
4,243!
1067
  SDB_SET_INT32(pRaw, dataPos, numOfUseDbs, _OVER)
4,243!
1068

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

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

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

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

1097
  stb = taosHashIterate(pUser->alterTbs, NULL);
4,243✔
1098
  while (stb != NULL) {
4,251✔
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,243✔
1112
  while (stb != NULL) {
4,295✔
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,243✔
1126
  while (stb != NULL) {
4,287✔
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,243✔
1140
  while (stb != NULL) {
4,289✔
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,243✔
1154
  while (useDb != NULL) {
4,349✔
1155
    size_t keyLen = 0;
106✔
1156
    void  *key = taosHashGetKey(useDb, &keyLen);
106✔
1157
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
106!
1158
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
106!
1159

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

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

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

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

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

1181
_OVER:
4,243✔
1182
  taosMemoryFree(buf);
4,243!
1183
  if (code < 0) {
4,243!
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);
×
UNCOV
1187
    pRaw = NULL;
×
UNCOV
1188
    terrno = code;
×
1189
  }
1190

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

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

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

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

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

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

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

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

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

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

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

1270
  if (sver >= 2) {
2,030!
1271
    for (int32_t i = 0; i < numOfTopics; ++i) {
2,064✔
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,030!
1280
    int32_t numOfReadTbs = 0;
2,030✔
1281
    int32_t numOfWriteTbs = 0;
2,030✔
1282
    int32_t numOfAlterTbs = 0;
2,030✔
1283
    int32_t numOfReadViews = 0;
2,030✔
1284
    int32_t numOfWriteViews = 0;
2,030✔
1285
    int32_t numOfAlterViews = 0;
2,030✔
1286
    int32_t numOfUseDbs = 0;
2,030✔
1287
    SDB_GET_INT32(pRaw, dataPos, &numOfReadTbs, _OVER)
2,030!
1288
    SDB_GET_INT32(pRaw, dataPos, &numOfWriteTbs, _OVER)
2,030!
1289
    if (sver >= 6) {
2,030!
1290
      SDB_GET_INT32(pRaw, dataPos, &numOfAlterTbs, _OVER)
2,030!
1291
      SDB_GET_INT32(pRaw, dataPos, &numOfReadViews, _OVER)
2,030!
1292
      SDB_GET_INT32(pRaw, dataPos, &numOfWriteViews, _OVER)
2,030!
1293
      SDB_GET_INT32(pRaw, dataPos, &numOfAlterViews, _OVER)
2,030!
1294
    }
1295
    SDB_GET_INT32(pRaw, dataPos, &numOfUseDbs, _OVER)
2,030!
1296

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

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

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

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

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

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

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

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

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

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

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

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

1365
    if (sver >= 6) {
2,030!
1366
      for (int32_t i = 0; i < numOfAlterTbs; ++i) {
2,038✔
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!
UNCOV
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!
UNCOV
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,082✔
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!
UNCOV
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!
UNCOV
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,074✔
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!
UNCOV
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!
UNCOV
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,076✔
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!
UNCOV
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!
UNCOV
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,118✔
1460
      int32_t keyLen = 0;
88✔
1461
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
88!
1462

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

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

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

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

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

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

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

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

1500
_OVER:
2,030✔
1501
  taosMemoryFree(key);
2,030!
1502
  taosMemoryFree(value);
2,030!
1503
  if (code < 0) {
2,030!
UNCOV
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);
×
UNCOV
1517
      taosHashCleanup(pUser->useDbs);
×
1518
      taosMemoryFreeClear(pUser->pIpWhiteList);
×
1519
    }
UNCOV
1520
    taosMemoryFreeClear(pRow);
×
UNCOV
1521
    return NULL;
×
1522
  }
1523

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

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

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

1540
  return 0;
1,689✔
1541
}
1542

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

1551
  char *tb = taosHashIterate(pOld, NULL);
966,671✔
1552
  while (tb != NULL) {
967,197✔
1553
    size_t keyLen = 0;
526✔
1554
    char  *key = taosHashGetKey(tb, &keyLen);
526✔
1555

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

1565
  TAOS_RETURN(code);
966,671✔
1566
}
1567

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

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

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

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

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

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

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

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

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

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

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

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

1681
  return 0;
258✔
1682
}
1683

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

1688
  *ppUser = sdbAcquire(pSdb, SDB_USER, userName);
549,107✔
1689
  if (*ppUser == NULL) {
549,144✔
1690
    if (terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
164!
1691
      code = TSDB_CODE_MND_USER_NOT_EXIST;
164✔
1692
    } else {
UNCOV
1693
      code = TSDB_CODE_MND_USER_NOT_AVAILABLE;
×
1694
    }
1695
  }
1696
  TAOS_RETURN(code);
549,144✔
1697
}
1698

1699
void mndReleaseUser(SMnode *pMnode, SUserObj *pUser) {
549,595✔
1700
  SSdb *pSdb = pMnode->pSdb;
549,595✔
1701
  sdbRelease(pSdb, pUser);
549,595✔
1702
}
549,717✔
1703

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

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

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

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

1763
      i++;
5✔
1764
    }
1765

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

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

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

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

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

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

UNCOV
1805
  TAOS_RETURN(code);
×
1806
}
1807

1808
static int32_t mndCheckPasswordFmt(const char *pwd) {
254✔
1809
  int32_t len = strlen(pwd);
254✔
1810
  if (len < TSDB_PASSWORD_MIN_LEN || len > TSDB_PASSWORD_MAX_LEN) {
254✔
1811
    return -1;
49✔
1812
  }
1813

1814
  if (strcmp(pwd, "taosdata") == 0) {
205✔
1815
    return 0;
40✔
1816
  }
1817

1818
  bool charTypes[4] = {0};
165✔
1819
  for (int32_t i = 0; i < len; ++i) {
1,773✔
1820
    if (taosIsBigChar(pwd[i])) {
1,610✔
1821
      charTypes[0] = true;
80✔
1822
    } else if (taosIsSmallChar(pwd[i])) {
1,530✔
1823
      charTypes[1] = true;
960✔
1824
    } else if (taosIsNumberChar(pwd[i])) {
570✔
1825
      charTypes[2] = true;
389✔
1826
    } else if (taosIsSpecialChar(pwd[i])) {
181✔
1827
      charTypes[3] = true;
179✔
1828
    } else {
1829
      return -1;
2✔
1830
    }
1831
  }
1832

1833
  int32_t numOfTypes = 0;
163✔
1834
  for (int32_t i = 0; i < 4; ++i) {
815✔
1835
    numOfTypes += charTypes[i];
652✔
1836
  }
1837

1838
  if (numOfTypes < 3) {
163✔
1839
    return -1;
42✔
1840
  }
1841

1842
  return 0;
121✔
1843
}
1844

1845
static int32_t mndProcessCreateUserReq(SRpcMsg *pReq) {
196✔
1846
  SMnode        *pMnode = pReq->info.node;
196✔
1847
  int32_t        code = 0;
196✔
1848
  int32_t        lino = 0;
196✔
1849
  SUserObj      *pUser = NULL;
196✔
1850
  SUserObj      *pOperUser = NULL;
196✔
1851
  SCreateUserReq createReq = {0};
196✔
1852

1853
  if (tDeserializeSCreateUserReq(pReq->pCont, pReq->contLen, &createReq) != 0) {
196!
UNCOV
1854
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
1855
  }
1856

1857
  mInfo("user:%s, start to create, createdb:%d, is_import:%d", createReq.user, createReq.isImport, createReq.createDb);
196!
1858

1859
#ifndef TD_ENTERPRISE
1860
  if (createReq.isImport == 1) {
1861
    TAOS_CHECK_GOTO(TSDB_CODE_OPS_NOT_SUPPORT, &lino, _OVER);  // enterprise feature
1862
  }
1863
#endif
1864

1865
  if (createReq.isImport != 1) {
196!
1866
    TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CREATE_USER), &lino, _OVER);
196✔
1867
  } else {
1868
    if (strcmp(pReq->info.conn.user, "root") != 0) {
×
UNCOV
1869
      mError("The operation is not permitted, user:%s", pReq->info.conn.user);
×
UNCOV
1870
      TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_RIGHTS, &lino, _OVER);
×
1871
    }
1872
  }
1873

1874
  if (createReq.user[0] == 0) {
191!
UNCOV
1875
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
1876
  }
1877

1878
  if (mndCheckPasswordFmt(createReq.pass) != 0) {
191✔
1879
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_PASS_FORMAT, &lino, _OVER);
65!
1880
  }
1881

1882
  if (createReq.isImport != 1) {
126!
1883
    if (strlen(createReq.pass) >= TSDB_PASSWORD_LEN) {
126!
UNCOV
1884
      TAOS_CHECK_GOTO(TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG, &lino, _OVER);
×
1885
    }
1886
  }
1887

1888
  code = mndAcquireUser(pMnode, createReq.user, &pUser);
126✔
1889
  if (pUser != NULL) {
126!
UNCOV
1890
    TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_ALREADY_EXIST, &lino, _OVER);
×
1891
  }
1892

1893
  code = mndAcquireUser(pMnode, pReq->info.conn.user, &pOperUser);
126✔
1894
  if (pOperUser == NULL) {
126!
UNCOV
1895
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_USER_FROM_CONN, &lino, _OVER);
×
1896
  }
1897

1898
  TAOS_CHECK_GOTO(grantCheck(TSDB_GRANT_USER), &lino, _OVER);
126!
1899

1900
  code = mndCreateUser(pMnode, pOperUser->acct, &createReq, pReq);
126✔
1901
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
126!
1902

1903
  char detail[1000] = {0};
126✔
1904
  (void)tsnprintf(detail, sizeof(detail), "enable:%d, superUser:%d, sysInfo:%d, password:xxx", createReq.enable,
126✔
1905
            createReq.superUser, createReq.sysInfo);
126✔
1906
  char operation[15] = {0};
126✔
1907
  if (createReq.isImport == 1) {
126!
UNCOV
1908
    tstrncpy(operation, "importUser", sizeof(operation));
×
1909
  } else {
1910
    tstrncpy(operation, "createUser", sizeof(operation));
126✔
1911
  }
1912

1913
  auditRecord(pReq, pMnode->clusterId, operation, "", createReq.user, detail, strlen(detail));
126✔
1914

1915
_OVER:
196✔
1916
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
196!
1917
    mError("user:%s, failed to create at line %d since %s", createReq.user, lino, tstrerror(code));
70!
1918
  }
1919

1920
  mndReleaseUser(pMnode, pUser);
196✔
1921
  mndReleaseUser(pMnode, pOperUser);
196✔
1922
  tFreeSCreateUserReq(&createReq);
196✔
1923

1924
  TAOS_RETURN(code);
196✔
1925
}
1926

1927
int32_t mndProcessGetUserWhiteListReq(SRpcMsg *pReq) {
20✔
1928
  SMnode              *pMnode = pReq->info.node;
20✔
1929
  int32_t              code = 0;
20✔
1930
  int32_t              lino = 0;
20✔
1931
  int32_t              contLen = 0;
20✔
1932
  void                *pRsp = NULL;
20✔
1933
  SUserObj            *pUser = NULL;
20✔
1934
  SGetUserWhiteListReq wlReq = {0};
20✔
1935
  SGetUserWhiteListRsp wlRsp = {0};
20✔
1936

1937
  if (tDeserializeSGetUserWhiteListReq(pReq->pCont, pReq->contLen, &wlReq) != 0) {
20!
UNCOV
1938
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
1939
  }
1940
  mTrace("user: %s, start to get whitelist", wlReq.user);
20✔
1941

1942
  code = mndAcquireUser(pMnode, wlReq.user, &pUser);
20✔
1943
  if (pUser == NULL) {
20!
UNCOV
1944
    TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_NOT_EXIST, &lino, _OVER);
×
1945
  }
1946

1947
  TAOS_CHECK_GOTO(mndSetUserWhiteListRsp(pMnode, pUser, &wlRsp), &lino, _OVER);
20!
1948

1949
  contLen = tSerializeSGetUserWhiteListRsp(NULL, 0, &wlRsp);
20✔
1950
  if (contLen < 0) {
20!
UNCOV
1951
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
1952
  }
1953
  pRsp = rpcMallocCont(contLen);
20✔
1954
  if (pRsp == NULL) {
20!
UNCOV
1955
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1956
  }
1957

1958
  contLen = tSerializeSGetUserWhiteListRsp(pRsp, contLen, &wlRsp);
20✔
1959
  if (contLen < 0) {
20!
UNCOV
1960
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
1961
  }
1962

1963
_OVER:
20✔
1964
  mndReleaseUser(pMnode, pUser);
20✔
1965
  tFreeSGetUserWhiteListRsp(&wlRsp);
20✔
1966
  if (code < 0) {
20!
1967
    mError("user:%s, failed to get whitelist at line %d since %s", wlReq.user, lino, tstrerror(code));
×
1968
    rpcFreeCont(pRsp);
×
UNCOV
1969
    pRsp = NULL;
×
UNCOV
1970
    contLen = 0;
×
1971
  }
1972
  pReq->code = code;
20✔
1973
  pReq->info.rsp = pRsp;
20✔
1974
  pReq->info.rspLen = contLen;
20✔
1975

1976
  TAOS_RETURN(code);
20✔
1977
}
1978

1979
int32_t mndProcesSRetrieveIpWhiteReq(SRpcMsg *pReq) {
6✔
1980
  int32_t        code = 0;
6✔
1981
  int32_t        lino = 0;
6✔
1982
  int32_t        len = 0;
6✔
1983
  void          *pRsp = NULL;
6✔
1984
  SUpdateIpWhite ipWhite = {0};
6✔
1985

1986
  // impl later
1987
  SRetrieveIpWhiteReq req = {0};
6✔
1988
  if (tDeserializeRetrieveIpWhite(pReq->pCont, pReq->contLen, &req) != 0) {
6!
UNCOV
1989
    code = TSDB_CODE_INVALID_MSG;
×
UNCOV
1990
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
1991
  }
1992

1993
  TAOS_CHECK_GOTO(ipWhiteMgtFillMsg(&ipWhite), &lino, _OVER);
6!
1994

1995
  len = tSerializeSUpdateIpWhite(NULL, 0, &ipWhite);
6✔
1996
  if (len < 0) {
6!
UNCOV
1997
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
1998
  }
1999

2000
  pRsp = rpcMallocCont(len);
6✔
2001
  if (!pRsp) {
6!
UNCOV
2002
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2003
  }
2004
  len = tSerializeSUpdateIpWhite(pRsp, len, &ipWhite);
6✔
2005
  if (len < 0) {
6!
UNCOV
2006
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
2007
  }
2008

2009
_OVER:
6✔
2010
  if (code < 0) {
6!
2011
    mError("failed to process retrieve ip white request at line %d since %s", lino, tstrerror(code));
×
2012
    rpcFreeCont(pRsp);
×
UNCOV
2013
    pRsp = NULL;
×
UNCOV
2014
    len = 0;
×
2015
  }
2016
  pReq->code = code;
6✔
2017
  pReq->info.rsp = pRsp;
6✔
2018
  pReq->info.rspLen = len;
6✔
2019

2020
  tFreeSUpdateIpWhiteReq(&ipWhite);
6✔
2021
  TAOS_RETURN(code);
6✔
2022
}
2023

2024
static int32_t mndAlterUser(SMnode *pMnode, SUserObj *pOld, SUserObj *pNew, SRpcMsg *pReq) {
200✔
2025
  int32_t code = 0;
200✔
2026
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "alter-user");
200✔
2027
  if (pTrans == NULL) {
200!
UNCOV
2028
    mError("user:%s, failed to alter since %s", pOld->user, terrstr());
×
UNCOV
2029
    TAOS_RETURN(terrno);
×
2030
  }
2031
  mInfo("trans:%d, used to alter user:%s", pTrans->id, pOld->user);
200!
2032

2033
  SSdbRaw *pCommitRaw = mndUserActionEncode(pNew);
200✔
2034
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
200!
2035
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
UNCOV
2036
    mndTransDrop(pTrans);
×
UNCOV
2037
    TAOS_RETURN(terrno);
×
2038
  }
2039
  code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
200✔
2040
  if (code < 0) {
200!
UNCOV
2041
    mndTransDrop(pTrans);
×
UNCOV
2042
    TAOS_RETURN(code);
×
2043
  }
2044

2045
  if (mndTransPrepare(pMnode, pTrans) != 0) {
200!
2046
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
UNCOV
2047
    mndTransDrop(pTrans);
×
UNCOV
2048
    TAOS_RETURN(terrno);
×
2049
  }
2050
  if ((code = ipWhiteMgtUpdate(pMnode, pNew->user, pNew->pIpWhiteList)) != 0) {
200!
UNCOV
2051
    mndTransDrop(pTrans);
×
UNCOV
2052
    TAOS_RETURN(code);
×
2053
  }
2054
  mndTransDrop(pTrans);
200✔
2055
  return 0;
200✔
2056
}
2057

2058
static int32_t mndDupObjHash(SHashObj *pOld, int32_t dataLen, SHashObj **ppNew) {
280,252✔
2059
  int32_t code = 0;
280,252✔
2060

2061
  *ppNew =
280,252✔
2062
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
280,252✔
2063
  if (*ppNew == NULL) {
280,252!
UNCOV
2064
    code = terrno ? terrno : TSDB_CODE_OUT_OF_MEMORY;
×
UNCOV
2065
    TAOS_RETURN(code);
×
2066
  }
2067

2068
  char *db = taosHashIterate(pOld, NULL);
280,252✔
2069
  while (db != NULL) {
280,581✔
2070
    int32_t len = strlen(db) + 1;
329✔
2071
    if ((code = taosHashPut(*ppNew, db, len, db, dataLen)) != 0) {
329!
2072
      taosHashCancelIterate(pOld, db);
×
UNCOV
2073
      taosHashCleanup(*ppNew);
×
UNCOV
2074
      TAOS_RETURN(code);
×
2075
    }
2076
    db = taosHashIterate(pOld, db);
329✔
2077
  }
2078

2079
  TAOS_RETURN(code);
280,252✔
2080
}
2081

2082
int32_t mndDupDbHash(SHashObj *pOld, SHashObj **ppNew) { return mndDupObjHash(pOld, TSDB_DB_FNAME_LEN, ppNew); }
277,094✔
2083

2084
int32_t mndDupTopicHash(SHashObj *pOld, SHashObj **ppNew) { return mndDupObjHash(pOld, TSDB_TOPIC_FNAME_LEN, ppNew); }
3,158✔
2085

2086
static int32_t mndTablePriviledge(SMnode *pMnode, SHashObj *hash, SHashObj *useDbHash, SAlterUserReq *alterReq,
59✔
2087
                                  SSdb *pSdb) {
2088
  void *pIter = NULL;
59✔
2089
  char  tbFName[TSDB_TABLE_FNAME_LEN] = {0};
59✔
2090

2091
  (void)snprintf(tbFName, sizeof(tbFName), "%s.%s", alterReq->objname, alterReq->tabName);
59✔
2092
  int32_t len = strlen(tbFName) + 1;
59✔
2093

2094
  if (alterReq->tagCond != NULL && alterReq->tagCondLen != 0) {
76!
2095
    char *value = taosHashGet(hash, tbFName, len);
17✔
2096
    if (value != NULL) {
17!
UNCOV
2097
      TAOS_RETURN(TSDB_CODE_MND_PRIVILEDGE_EXIST);
×
2098
    }
2099

2100
    int32_t condLen = alterReq->tagCondLen;
17✔
2101
    TAOS_CHECK_RETURN(taosHashPut(hash, tbFName, len, alterReq->tagCond, condLen));
17!
2102
  } else {
2103
    TAOS_CHECK_RETURN(taosHashPut(hash, tbFName, len, alterReq->isView ? "v" : "t", 2));
42!
2104
  }
2105

2106
  int32_t  dbKeyLen = strlen(alterReq->objname) + 1;
59✔
2107
  int32_t  ref = 1;
59✔
2108
  int32_t *currRef = taosHashGet(useDbHash, alterReq->objname, dbKeyLen);
59✔
2109
  if (NULL != currRef) {
59✔
2110
    ref = (*currRef) + 1;
20✔
2111
  }
2112
  TAOS_CHECK_RETURN(taosHashPut(useDbHash, alterReq->objname, dbKeyLen, &ref, sizeof(ref)));
59!
2113

2114
  TAOS_RETURN(0);
59✔
2115
}
2116

2117
static int32_t mndRemoveTablePriviledge(SMnode *pMnode, SHashObj *hash, SHashObj *useDbHash, SAlterUserReq *alterReq,
11✔
2118
                                        SSdb *pSdb) {
2119
  void *pIter = NULL;
11✔
2120
  char  tbFName[TSDB_TABLE_FNAME_LEN] = {0};
11✔
2121
  (void)snprintf(tbFName, sizeof(tbFName), "%s.%s", alterReq->objname, alterReq->tabName);
11✔
2122
  int32_t len = strlen(tbFName) + 1;
11✔
2123

2124
  if (taosHashRemove(hash, tbFName, len) != 0) {
11!
UNCOV
2125
    TAOS_RETURN(0);  // not found
×
2126
  }
2127

2128
  int32_t  dbKeyLen = strlen(alterReq->objname) + 1;
11✔
2129
  int32_t *currRef = taosHashGet(useDbHash, alterReq->objname, dbKeyLen);
11✔
2130
  if (NULL == currRef) {
11!
UNCOV
2131
    return 0;
×
2132
  }
2133

2134
  if (1 == *currRef) {
11!
2135
    if (taosHashRemove(useDbHash, alterReq->objname, dbKeyLen) != 0) {
11!
UNCOV
2136
      TAOS_RETURN(0);  // not found
×
2137
    }
2138
    return 0;
11✔
2139
  }
UNCOV
2140
  int32_t ref = (*currRef) - 1;
×
2141
  TAOS_CHECK_RETURN(taosHashPut(useDbHash, alterReq->objname, dbKeyLen, &ref, sizeof(ref)));
×
2142

UNCOV
2143
  return 0;
×
2144
}
2145

2146
static char *mndUserAuditTypeStr(int32_t type) {
34✔
2147
  if (type == TSDB_ALTER_USER_PASSWD) {
34!
2148
    return "changePassword";
34✔
2149
  }
UNCOV
2150
  if (type == TSDB_ALTER_USER_SUPERUSER) {
×
2151
    return "changeSuperUser";
×
2152
  }
UNCOV
2153
  if (type == TSDB_ALTER_USER_ENABLE) {
×
2154
    return "enableUser";
×
2155
  }
UNCOV
2156
  if (type == TSDB_ALTER_USER_SYSINFO) {
×
2157
    return "userSysInfo";
×
2158
  }
UNCOV
2159
  if (type == TSDB_ALTER_USER_CREATEDB) {
×
2160
    return "userCreateDB";
×
2161
  }
UNCOV
2162
  return "error";
×
2163
}
2164

2165
static int32_t mndProcessAlterUserPrivilegesReq(SAlterUserReq *pAlterReq, SMnode *pMnode, SUserObj *pNewUser) {
150✔
2166
  SSdb   *pSdb = pMnode->pSdb;
150✔
2167
  void   *pIter = NULL;
150✔
2168
  int32_t code = 0;
150✔
2169
  int32_t lino = 0;
150✔
2170

2171
  if (ALTER_USER_ADD_READ_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
150✔
2172
      ALTER_USER_ADD_ALL_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
114!
2173
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
36✔
2174
      int32_t len = strlen(pAlterReq->objname) + 1;
33✔
2175
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
33✔
2176
      if (pDb == NULL) {
33✔
2177
        mndReleaseDb(pMnode, pDb);
5✔
2178
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
5!
2179
      }
2180
      if ((code = taosHashPut(pNewUser->readDbs, pAlterReq->objname, len, pAlterReq->objname, TSDB_DB_FNAME_LEN)) !=
28!
2181
          0) {
UNCOV
2182
        mndReleaseDb(pMnode, pDb);
×
UNCOV
2183
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2184
      }
2185
      mndReleaseDb(pMnode, pDb);
28✔
2186
    } else {
2187
      while (1) {
9✔
2188
        SDbObj *pDb = NULL;
12✔
2189
        pIter = sdbFetch(pSdb, SDB_DB, pIter, (void **)&pDb);
12✔
2190
        if (pIter == NULL) break;
12✔
2191
        int32_t len = strlen(pDb->name) + 1;
9✔
2192
        if ((code = taosHashPut(pNewUser->readDbs, pDb->name, len, pDb->name, TSDB_DB_FNAME_LEN)) != 0) {
9!
2193
          sdbRelease(pSdb, pDb);
×
UNCOV
2194
          sdbCancelFetch(pSdb, pIter);
×
UNCOV
2195
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2196
        }
2197
        sdbRelease(pSdb, pDb);
9✔
2198
      }
2199
    }
2200
  }
2201

2202
  if (ALTER_USER_ADD_WRITE_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
145✔
2203
      ALTER_USER_ADD_ALL_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
114!
2204
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
31✔
2205
      int32_t len = strlen(pAlterReq->objname) + 1;
28✔
2206
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
28✔
2207
      if (pDb == NULL) {
28✔
2208
        mndReleaseDb(pMnode, pDb);
1✔
2209
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
1!
2210
      }
2211
      if ((code = taosHashPut(pNewUser->writeDbs, pAlterReq->objname, len, pAlterReq->objname, TSDB_DB_FNAME_LEN)) !=
27!
2212
          0) {
UNCOV
2213
        mndReleaseDb(pMnode, pDb);
×
UNCOV
2214
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2215
      }
2216
      mndReleaseDb(pMnode, pDb);
27✔
2217
    } else {
2218
      while (1) {
9✔
2219
        SDbObj *pDb = NULL;
12✔
2220
        pIter = sdbFetch(pSdb, SDB_DB, pIter, (void **)&pDb);
12✔
2221
        if (pIter == NULL) break;
12✔
2222
        int32_t len = strlen(pDb->name) + 1;
9✔
2223
        if ((code = taosHashPut(pNewUser->writeDbs, pDb->name, len, pDb->name, TSDB_DB_FNAME_LEN)) != 0) {
9!
2224
          sdbRelease(pSdb, pDb);
×
UNCOV
2225
          sdbCancelFetch(pSdb, pIter);
×
UNCOV
2226
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2227
        }
2228
        sdbRelease(pSdb, pDb);
9✔
2229
      }
2230
    }
2231
  }
2232

2233
  if (ALTER_USER_DEL_READ_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
144✔
2234
      ALTER_USER_DEL_ALL_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
124!
2235
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
20✔
2236
      int32_t len = strlen(pAlterReq->objname) + 1;
17✔
2237
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
17✔
2238
      if (pDb == NULL) {
17!
UNCOV
2239
        mndReleaseDb(pMnode, pDb);
×
UNCOV
2240
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
×
2241
      }
2242
      code = taosHashRemove(pNewUser->readDbs, pAlterReq->objname, len);
17✔
2243
      if (code < 0) {
17!
UNCOV
2244
        mError("read db:%s, failed to remove db:%s since %s", pNewUser->user, pAlterReq->objname, terrstr());
×
2245
      }
2246
      mndReleaseDb(pMnode, pDb);
17✔
2247
    } else {
2248
      taosHashClear(pNewUser->readDbs);
3✔
2249
    }
2250
  }
2251

2252
  if (ALTER_USER_DEL_WRITE_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
144✔
2253
      ALTER_USER_DEL_ALL_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
126!
2254
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
18✔
2255
      int32_t len = strlen(pAlterReq->objname) + 1;
15✔
2256
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
15✔
2257
      if (pDb == NULL) {
15!
UNCOV
2258
        mndReleaseDb(pMnode, pDb);
×
UNCOV
2259
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
×
2260
      }
2261
      code = taosHashRemove(pNewUser->writeDbs, pAlterReq->objname, len);
15✔
2262
      if (code < 0) {
15!
UNCOV
2263
        mError("user:%s, failed to remove db:%s since %s", pNewUser->user, pAlterReq->objname, terrstr());
×
2264
      }
2265
      mndReleaseDb(pMnode, pDb);
15✔
2266
    } else {
2267
      taosHashClear(pNewUser->writeDbs);
3✔
2268
    }
2269
  }
2270

2271
  SHashObj *pReadTbs = pNewUser->readTbs;
144✔
2272
  SHashObj *pWriteTbs = pNewUser->writeTbs;
144✔
2273
  SHashObj *pAlterTbs = pNewUser->alterTbs;
144✔
2274

2275
#ifdef TD_ENTERPRISE
2276
  if (pAlterReq->isView) {
144✔
2277
    pReadTbs = pNewUser->readViews;
12✔
2278
    pWriteTbs = pNewUser->writeViews;
12✔
2279
    pAlterTbs = pNewUser->alterViews;
12✔
2280
  }
2281
#endif
2282

2283
  if (ALTER_USER_ADD_READ_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
144✔
2284
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
120!
2285
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pReadTbs, pNewUser->useDbs, pAlterReq, pSdb), &lino, _OVER);
24!
2286
  }
2287

2288
  if (ALTER_USER_ADD_WRITE_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
144✔
2289
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
119!
2290
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pWriteTbs, pNewUser->useDbs, pAlterReq, pSdb), &lino, _OVER);
25!
2291
  }
2292

2293
  if (ALTER_USER_ADD_ALTER_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
144✔
2294
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
134!
2295
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pAlterTbs, pNewUser->useDbs, pAlterReq, pSdb), &lino, _OVER);
10!
2296
  }
2297

2298
  if (ALTER_USER_DEL_READ_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
144✔
2299
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
138!
2300
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pReadTbs, pNewUser->useDbs, pAlterReq, pSdb), &lino, _OVER);
6!
2301
  }
2302

2303
  if (ALTER_USER_DEL_WRITE_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
144✔
2304
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
139!
2305
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pWriteTbs, pNewUser->useDbs, pAlterReq, pSdb), &lino, _OVER);
5!
2306
  }
2307

2308
  if (ALTER_USER_DEL_ALTER_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
144!
2309
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
144!
UNCOV
2310
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pAlterTbs, pNewUser->useDbs, pAlterReq, pSdb), &lino, _OVER);
×
2311
  }
2312

2313
  if (ALTER_USER_ADD_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, pAlterReq->privileges)) {
144✔
2314
    int32_t      len = strlen(pAlterReq->objname) + 1;
15✔
2315
    SMqTopicObj *pTopic = NULL;
15✔
2316
    if ((code = mndAcquireTopic(pMnode, pAlterReq->objname, &pTopic)) != 0) {
15!
UNCOV
2317
      mndReleaseTopic(pMnode, pTopic);
×
UNCOV
2318
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2319
    }
2320
    if ((code = taosHashPut(pNewUser->topics, pTopic->name, len, pTopic->name, TSDB_TOPIC_FNAME_LEN)) != 0) {
15!
UNCOV
2321
      mndReleaseTopic(pMnode, pTopic);
×
UNCOV
2322
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2323
    }
2324
    mndReleaseTopic(pMnode, pTopic);
15✔
2325
  }
2326

2327
  if (ALTER_USER_DEL_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, pAlterReq->privileges)) {
144✔
2328
    int32_t      len = strlen(pAlterReq->objname) + 1;
11✔
2329
    SMqTopicObj *pTopic = NULL;
11✔
2330
    if ((code = mndAcquireTopic(pMnode, pAlterReq->objname, &pTopic)) != 0) {
11✔
2331
      mndReleaseTopic(pMnode, pTopic);
1✔
2332
      TAOS_CHECK_GOTO(code, &lino, _OVER);
1!
2333
    }
2334
    code = taosHashRemove(pNewUser->topics, pAlterReq->objname, len);
10✔
2335
    if (code < 0) {
10!
UNCOV
2336
      mError("user:%s, failed to remove topic:%s since %s", pNewUser->user, pAlterReq->objname, tstrerror(code));
×
2337
    }
2338
    mndReleaseTopic(pMnode, pTopic);
10✔
2339
  }
2340

2341
_OVER:
133✔
2342
  if (code < 0) {
150✔
2343
    mError("user:%s, failed to alter user privileges at line %d since %s", pAlterReq->user, lino, tstrerror(code));
7!
2344
  }
2345
  TAOS_RETURN(code);
150✔
2346
}
2347

2348
static int32_t mndProcessAlterUserReq(SRpcMsg *pReq) {
301✔
2349
  SMnode       *pMnode = pReq->info.node;
301✔
2350
  SSdb         *pSdb = pMnode->pSdb;
301✔
2351
  void         *pIter = NULL;
301✔
2352
  int32_t       code = 0;
301✔
2353
  int32_t       lino = 0;
301✔
2354
  SUserObj     *pUser = NULL;
301✔
2355
  SUserObj     *pOperUser = NULL;
301✔
2356
  SUserObj      newUser = {0};
301✔
2357
  SAlterUserReq alterReq = {0};
301✔
2358

2359
  TAOS_CHECK_GOTO(tDeserializeSAlterUserReq(pReq->pCont, pReq->contLen, &alterReq), &lino, _OVER);
301!
2360

2361
  mInfo("user:%s, start to alter", alterReq.user);
301!
2362

2363
  if (alterReq.user[0] == 0) {
301!
UNCOV
2364
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
2365
  }
2366

2367
  if (TSDB_ALTER_USER_PASSWD == alterReq.alterType && mndCheckPasswordFmt(alterReq.pass) != 0) {
301✔
2368
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_PASS_FORMAT, &lino, _OVER);
28!
2369
  }
2370

2371
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, alterReq.user, &pUser), &lino, _OVER);
273✔
2372

2373
  (void)mndAcquireUser(pMnode, pReq->info.conn.user, &pOperUser);
252✔
2374
  if (pOperUser == NULL) {
252!
UNCOV
2375
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_USER_FROM_CONN, &lino, _OVER);
×
2376
  }
2377

2378
  TAOS_CHECK_GOTO(mndCheckAlterUserPrivilege(pOperUser, pUser, &alterReq), &lino, _OVER);
252✔
2379

2380
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
208!
2381

2382
  if (alterReq.alterType == TSDB_ALTER_USER_PASSWD) {
208✔
2383
    char pass[TSDB_PASSWORD_LEN + 1] = {0};
34✔
2384
    taosEncryptPass_c((uint8_t *)alterReq.pass, strlen(alterReq.pass), pass);
34✔
2385
    (void)memcpy(newUser.pass, pass, TSDB_PASSWORD_LEN);
34✔
2386
    if (0 != strncmp(pUser->pass, pass, TSDB_PASSWORD_LEN)) {
34✔
2387
      ++newUser.passVersion;
31✔
2388
    }
2389
  }
2390

2391
  if (alterReq.alterType == TSDB_ALTER_USER_SUPERUSER) {
208!
UNCOV
2392
    newUser.superUser = alterReq.superUser;
×
2393
  }
2394

2395
  if (alterReq.alterType == TSDB_ALTER_USER_ENABLE) {
208✔
2396
    newUser.enable = alterReq.enable;
4✔
2397
  }
2398

2399
  if (alterReq.alterType == TSDB_ALTER_USER_SYSINFO) {
208✔
2400
    newUser.sysInfo = alterReq.sysInfo;
13✔
2401
  }
2402

2403
  if (alterReq.alterType == TSDB_ALTER_USER_CREATEDB) {
208✔
2404
    newUser.createdb = alterReq.createdb;
5✔
2405
  }
2406

2407
  if (ALTER_USER_ADD_PRIVS(alterReq.alterType) || ALTER_USER_DEL_PRIVS(alterReq.alterType)) {
208✔
2408
    TAOS_CHECK_GOTO(mndProcessAlterUserPrivilegesReq(&alterReq, pMnode, &newUser), &lino, _OVER);
150✔
2409
  }
2410

2411
  if (alterReq.alterType == TSDB_ALTER_USER_ADD_WHITE_LIST) {
201✔
2412
    taosMemoryFreeClear(newUser.pIpWhiteList);
1!
2413

2414
    int32_t       num = pUser->pIpWhiteList->num + alterReq.numIpRanges;
1✔
2415
    int32_t       idx = pUser->pIpWhiteList->num;
1✔
2416
    SIpWhiteList *pNew = taosMemoryCalloc(1, sizeof(SIpWhiteList) + sizeof(SIpV4Range) * num);
1!
2417

2418
    if (pNew == NULL) {
1!
UNCOV
2419
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2420
    }
2421

2422
    bool exist = false;
1✔
2423
    (void)memcpy(pNew->pIpRange, pUser->pIpWhiteList->pIpRange, sizeof(SIpV4Range) * idx);
1✔
2424
    for (int i = 0; i < alterReq.numIpRanges; i++) {
2✔
2425
      SIpV4Range *range = &(alterReq.pIpRanges[i]);
1✔
2426
      if (!isRangeInIpWhiteList(pUser->pIpWhiteList, range)) {
1!
2427
        // already exist, just ignore;
2428
        (void)memcpy(&pNew->pIpRange[idx], range, sizeof(SIpV4Range));
1✔
2429
        idx++;
1✔
2430
        continue;
1✔
2431
      } else {
UNCOV
2432
        exist = true;
×
2433
      }
2434
    }
2435
    if (exist) {
1!
UNCOV
2436
      taosMemoryFree(pNew);
×
UNCOV
2437
      TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_HOST_EXIST, &lino, _OVER);
×
2438
    }
2439
    pNew->num = idx;
1✔
2440
    newUser.pIpWhiteList = pNew;
1✔
2441
    newUser.ipWhiteListVer = pUser->ipWhiteListVer + 1;
1✔
2442

2443
    if (pNew->num > MND_MAX_USE_HOST) {
1!
UNCOV
2444
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_HOST, &lino, _OVER);
×
2445
    }
2446
  }
2447
  if (alterReq.alterType == TSDB_ALTER_USER_DROP_WHITE_LIST) {
201✔
2448
    taosMemoryFreeClear(newUser.pIpWhiteList);
1!
2449

2450
    int32_t       num = pUser->pIpWhiteList->num;
1✔
2451
    bool          noexist = true;
1✔
2452
    bool          localHost = false;
1✔
2453
    SIpWhiteList *pNew = taosMemoryCalloc(1, sizeof(SIpWhiteList) + sizeof(SIpV4Range) * num);
1!
2454

2455
    if (pNew == NULL) {
1!
UNCOV
2456
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2457
    }
2458

2459
    if (pUser->pIpWhiteList->num > 0) {
1!
2460
      int idx = 0;
1✔
2461
      for (int i = 0; i < pUser->pIpWhiteList->num; i++) {
3✔
2462
        SIpV4Range *oldRange = &pUser->pIpWhiteList->pIpRange[i];
2✔
2463
        bool        found = false;
2✔
2464
        for (int j = 0; j < alterReq.numIpRanges; j++) {
4✔
2465
          SIpV4Range *range = &alterReq.pIpRanges[j];
2✔
2466
          if (isDefaultRange(range)) {
2!
UNCOV
2467
            localHost = true;
×
UNCOV
2468
            break;
×
2469
          }
2470
          if (isIpRangeEqual(oldRange, range)) {
2!
UNCOV
2471
            found = true;
×
UNCOV
2472
            break;
×
2473
          }
2474
        }
2475
        if (localHost) break;
2!
2476

2477
        if (found == false) {
2!
2478
          (void)memcpy(&pNew->pIpRange[idx], oldRange, sizeof(SIpV4Range));
2✔
2479
          idx++;
2✔
2480
        } else {
UNCOV
2481
          noexist = false;
×
2482
        }
2483
      }
2484
      pNew->num = idx;
1✔
2485
      newUser.pIpWhiteList = pNew;
1✔
2486
      newUser.ipWhiteListVer = pUser->ipWhiteListVer + 1;
1✔
2487

2488
    } else {
2489
      pNew->num = 0;
×
UNCOV
2490
      newUser.pIpWhiteList = pNew;
×
UNCOV
2491
      newUser.ipWhiteListVer = pUser->ipWhiteListVer + 1;
×
2492
    }
2493

2494
    if (localHost) {
1!
UNCOV
2495
      TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_LOCAL_HOST_NOT_DROP, &lino, _OVER);
×
2496
    }
2497
    if (noexist) {
1!
2498
      TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_HOST_NOT_EXIST, &lino, _OVER);
1!
2499
    }
2500
  }
2501

2502
  code = mndAlterUser(pMnode, pUser, &newUser, pReq);
200✔
2503
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
200!
2504

2505
  if (alterReq.alterType == TSDB_ALTER_USER_PASSWD) {
200✔
2506
    char detail[1000] = {0};
34✔
2507
    (void)tsnprintf(detail, sizeof(detail),
34✔
2508
              "alterType:%s, enable:%d, superUser:%d, sysInfo:%d, createdb:%d, tabName:%s, password:xxx",
2509
              mndUserAuditTypeStr(alterReq.alterType), alterReq.enable, alterReq.superUser, alterReq.sysInfo,
34✔
2510
              alterReq.createdb ? 1 : 0, alterReq.tabName);
34✔
2511
    auditRecord(pReq, pMnode->clusterId, "alterUser", "", alterReq.user, detail, strlen(detail));
34✔
2512
  } else if (alterReq.alterType == TSDB_ALTER_USER_SUPERUSER || alterReq.alterType == TSDB_ALTER_USER_ENABLE ||
166!
2513
             alterReq.alterType == TSDB_ALTER_USER_SYSINFO || alterReq.alterType == TSDB_ALTER_USER_CREATEDB) {
162✔
2514
    auditRecord(pReq, pMnode->clusterId, "alterUser", "", alterReq.user, alterReq.sql, alterReq.sqlLen);
22✔
2515
  } else if (ALTER_USER_ADD_READ_DB_PRIV(alterReq.alterType, alterReq.privileges, alterReq.tabName) ||
144✔
2516
             ALTER_USER_ADD_WRITE_DB_PRIV(alterReq.alterType, alterReq.privileges, alterReq.tabName) ||
113✔
2517
             ALTER_USER_ADD_ALL_DB_PRIV(alterReq.alterType, alterReq.privileges, alterReq.tabName) ||
103!
2518
             ALTER_USER_ADD_READ_TB_PRIV(alterReq.alterType, alterReq.privileges, alterReq.tabName) ||
103!
2519
             ALTER_USER_ADD_WRITE_TB_PRIV(alterReq.alterType, alterReq.privileges, alterReq.tabName) ||
79!
2520
             ALTER_USER_ADD_ALL_TB_PRIV(alterReq.alterType, alterReq.privileges, alterReq.tabName)) {
62!
2521
    if (strcmp(alterReq.objname, "1.*") != 0) {
82✔
2522
      SName name = {0};
78✔
2523
      TAOS_CHECK_GOTO(tNameFromString(&name, alterReq.objname, T_NAME_ACCT | T_NAME_DB), &lino, _OVER);
78!
2524
      auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", name.dbname, alterReq.user, alterReq.sql,
78✔
2525
                  alterReq.sqlLen);
2526
    } else {
2527
      auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", "", alterReq.user, alterReq.sql, alterReq.sqlLen);
4✔
2528
    }
2529
  } else if (ALTER_USER_ADD_SUBSCRIBE_TOPIC_PRIV(alterReq.alterType, alterReq.privileges)) {
62✔
2530
    auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", alterReq.objname, alterReq.user, alterReq.sql,
15✔
2531
                alterReq.sqlLen);
2532
  } else if (ALTER_USER_DEL_SUBSCRIBE_TOPIC_PRIV(alterReq.alterType, alterReq.privileges)) {
47✔
2533
    auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", alterReq.objname, alterReq.user, alterReq.sql,
10✔
2534
                alterReq.sqlLen);
2535
  } else {
2536
    if (strcmp(alterReq.objname, "1.*") != 0) {
37✔
2537
      SName name = {0};
33✔
2538
      TAOS_CHECK_GOTO(tNameFromString(&name, alterReq.objname, T_NAME_ACCT | T_NAME_DB), &lino, _OVER);
33✔
2539
      auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", name.dbname, alterReq.user, alterReq.sql,
32✔
2540
                  alterReq.sqlLen);
2541
    } else {
2542
      auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", "", alterReq.user, alterReq.sql, alterReq.sqlLen);
4✔
2543
    }
2544
  }
2545

2546
_OVER:
301✔
2547
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
301✔
2548
    mError("user:%s, failed to alter at line %d since %s", alterReq.user, lino, tstrerror(code));
102!
2549
  }
2550

2551
  tFreeSAlterUserReq(&alterReq);
301✔
2552
  mndReleaseUser(pMnode, pOperUser);
301✔
2553
  mndReleaseUser(pMnode, pUser);
301✔
2554
  mndUserFreeObj(&newUser);
301✔
2555

2556
  TAOS_RETURN(code);
301✔
2557
}
2558

2559
static int32_t mndDropUser(SMnode *pMnode, SRpcMsg *pReq, SUserObj *pUser) {
43✔
2560
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "drop-user");
43✔
2561
  if (pTrans == NULL) {
43!
UNCOV
2562
    mError("user:%s, failed to drop since %s", pUser->user, terrstr());
×
UNCOV
2563
    TAOS_RETURN(terrno);
×
2564
  }
2565
  mInfo("trans:%d, used to drop user:%s", pTrans->id, pUser->user);
43!
2566

2567
  SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
43✔
2568
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
43!
2569
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
UNCOV
2570
    mndTransDrop(pTrans);
×
UNCOV
2571
    TAOS_RETURN(terrno);
×
2572
  }
2573
  if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED) < 0) {
43!
UNCOV
2574
    mndTransDrop(pTrans);
×
UNCOV
2575
    TAOS_RETURN(terrno);
×
2576
  }
2577

2578
  if (mndTransPrepare(pMnode, pTrans) != 0) {
43!
2579
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
UNCOV
2580
    mndTransDrop(pTrans);
×
UNCOV
2581
    TAOS_RETURN(terrno);
×
2582
  }
2583
  (void)ipWhiteMgtRemove(pUser->user);
43✔
2584

2585
  mndTransDrop(pTrans);
43✔
2586
  TAOS_RETURN(0);
43✔
2587
}
2588

2589
static int32_t mndProcessDropUserReq(SRpcMsg *pReq) {
43✔
2590
  SMnode      *pMnode = pReq->info.node;
43✔
2591
  int32_t      code = 0;
43✔
2592
  int32_t      lino = 0;
43✔
2593
  SUserObj    *pUser = NULL;
43✔
2594
  SDropUserReq dropReq = {0};
43✔
2595

2596
  TAOS_CHECK_GOTO(tDeserializeSDropUserReq(pReq->pCont, pReq->contLen, &dropReq), &lino, _OVER);
43!
2597

2598
  mInfo("user:%s, start to drop", dropReq.user);
43!
2599
  TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_DROP_USER), &lino, _OVER);
43!
2600

2601
  if (dropReq.user[0] == 0) {
43!
UNCOV
2602
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
2603
  }
2604

2605
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, dropReq.user, &pUser), &lino, _OVER);
43!
2606

2607
  TAOS_CHECK_GOTO(mndDropUser(pMnode, pReq, pUser), &lino, _OVER);
43!
2608
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
43!
2609

2610
  auditRecord(pReq, pMnode->clusterId, "dropUser", "", dropReq.user, dropReq.sql, dropReq.sqlLen);
43✔
2611

2612
_OVER:
43✔
2613
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
43!
UNCOV
2614
    mError("user:%s, failed to drop at line %d since %s", dropReq.user, lino, tstrerror(code));
×
2615
  }
2616

2617
  mndReleaseUser(pMnode, pUser);
43✔
2618
  tFreeSDropUserReq(&dropReq);
43✔
2619
  TAOS_RETURN(code);
43✔
2620
}
2621

2622
static int32_t mndProcessGetUserAuthReq(SRpcMsg *pReq) {
133,245✔
2623
  SMnode         *pMnode = pReq->info.node;
133,245✔
2624
  int32_t         code = 0;
133,245✔
2625
  int32_t         lino = 0;
133,245✔
2626
  int32_t         contLen = 0;
133,245✔
2627
  void           *pRsp = NULL;
133,245✔
2628
  SUserObj       *pUser = NULL;
133,245✔
2629
  SGetUserAuthReq authReq = {0};
133,245✔
2630
  SGetUserAuthRsp authRsp = {0};
133,245✔
2631

2632
  TAOS_CHECK_EXIT(tDeserializeSGetUserAuthReq(pReq->pCont, pReq->contLen, &authReq));
133,245!
2633
  mTrace("user:%s, start to get auth", authReq.user);
133,245✔
2634

2635
  TAOS_CHECK_EXIT(mndAcquireUser(pMnode, authReq.user, &pUser));
133,245✔
2636

2637
  TAOS_CHECK_EXIT(mndSetUserAuthRsp(pMnode, pUser, &authRsp));
133,243!
2638

2639
  contLen = tSerializeSGetUserAuthRsp(NULL, 0, &authRsp);
133,243✔
2640
  if (contLen < 0) {
133,243!
UNCOV
2641
    TAOS_CHECK_EXIT(contLen);
×
2642
  }
2643
  pRsp = rpcMallocCont(contLen);
133,243✔
2644
  if (pRsp == NULL) {
133,243!
UNCOV
2645
    TAOS_CHECK_EXIT(terrno);
×
2646
  }
2647

2648
  contLen = tSerializeSGetUserAuthRsp(pRsp, contLen, &authRsp);
133,243✔
2649
  if (contLen < 0) {
133,243!
UNCOV
2650
    TAOS_CHECK_EXIT(contLen);
×
2651
  }
2652

2653
_exit:
133,243✔
2654
  mndReleaseUser(pMnode, pUser);
133,245✔
2655
  tFreeSGetUserAuthRsp(&authRsp);
133,245✔
2656
  if (code < 0) {
133,245✔
2657
    mError("user:%s, failed to get auth at line %d since %s", authReq.user, lino, tstrerror(code));
2!
2658
    rpcFreeCont(pRsp);
2✔
2659
    pRsp = NULL;
2✔
2660
    contLen = 0;
2✔
2661
  }
2662
  pReq->info.rsp = pRsp;
133,245✔
2663
  pReq->info.rspLen = contLen;
133,245✔
2664
  pReq->code = code;
133,245✔
2665

2666
  TAOS_RETURN(code);
133,245✔
2667
}
2668

2669
static int32_t mndRetrieveUsers(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
5,067✔
2670
  SMnode   *pMnode = pReq->info.node;
5,067✔
2671
  SSdb     *pSdb = pMnode->pSdb;
5,067✔
2672
  int32_t   code = 0;
5,067✔
2673
  int32_t   lino = 0;
5,067✔
2674
  int32_t   numOfRows = 0;
5,067✔
2675
  SUserObj *pUser = NULL;
5,067✔
2676
  int32_t   cols = 0;
5,067✔
2677
  int8_t    flag = 0;
5,067✔
2678
  char     *pWrite = NULL;
5,067✔
2679
  char     *buf = NULL;
5,067✔
2680
  char     *varstr = NULL;
5,067✔
2681

2682
  while (numOfRows < rows) {
10,193!
2683
    pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
10,193✔
2684
    if (pShow->pIter == NULL) break;
10,198✔
2685

2686
    cols = 0;
5,126✔
2687
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
5,126✔
2688
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
5,126✔
2689
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
5,126✔
2690
    COL_DATA_SET_VAL_GOTO((const char *)name, false, pUser, _exit);
5,126!
2691

2692
    cols++;
5,121✔
2693
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
5,121✔
2694
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->superUser, false, pUser, _exit);
5,121!
2695

2696
    cols++;
5,124✔
2697
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
5,124✔
2698
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->enable, false, pUser, _exit);
5,125!
2699

2700
    cols++;
5,126✔
2701
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
5,126✔
2702
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sysInfo, false, pUser, _exit);
5,126!
2703

2704
    cols++;
5,126✔
2705
    flag = pUser->createdb ? 1 : 0;
5,126✔
2706
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
5,126✔
2707
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, _exit);
5,126!
2708

2709
    cols++;
5,123✔
2710
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
5,123✔
2711
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->createdTime, false, pUser, _exit);
5,125!
2712

2713
    cols++;
5,125✔
2714

2715
    int32_t tlen = convertIpWhiteListToStr(pUser->pIpWhiteList, &buf);
5,125✔
2716
    // int32_t tlen = mndFetchIpWhiteList(pUser->pIpWhiteList, &buf);
2717
    if (tlen != 0) {
5,113!
2718
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
5,122!
2719
      if (varstr == NULL) {
5,124!
UNCOV
2720
        sdbRelease(pSdb, pUser);
×
UNCOV
2721
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
2722
      }
2723
      varDataSetLen(varstr, tlen);
5,124✔
2724
      (void)memcpy(varDataVal(varstr), buf, tlen);
5,124✔
2725

2726
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
5,124✔
2727
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, _exit);
5,118!
2728

2729
      taosMemoryFreeClear(buf);
5,125!
2730
    } else {
UNCOV
2731
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
2732
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, _exit);
×
2733
    }
2734

2735
    numOfRows++;
5,120✔
2736
    sdbRelease(pSdb, pUser);
5,120✔
2737
  }
2738

2739
  pShow->numOfRows += numOfRows;
5,072✔
2740
_exit:
5,072✔
2741
  taosMemoryFreeClear(buf);
5,072!
2742
  taosMemoryFreeClear(varstr);
5,072!
2743
  if (code < 0) {
5,072!
UNCOV
2744
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
UNCOV
2745
    TAOS_RETURN(code);
×
2746
  }
2747
  return numOfRows;
5,072✔
2748
}
2749

UNCOV
2750
static int32_t mndRetrieveUsersFull(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
×
2751
  int32_t numOfRows = 0;
×
2752
#ifdef TD_ENTERPRISE
2753
  SMnode   *pMnode = pReq->info.node;
×
2754
  SSdb     *pSdb = pMnode->pSdb;
×
2755
  SUserObj *pUser = NULL;
×
2756
  int32_t   code = 0;
×
2757
  int32_t   lino = 0;
×
2758
  int32_t   cols = 0;
×
2759
  int8_t    flag = 0;
×
2760
  char     *pWrite = NULL;
×
UNCOV
2761
  char     *buf = NULL;
×
2762
  char     *varstr = NULL;
×
2763

2764
  while (numOfRows < rows) {
×
UNCOV
2765
    pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
×
2766
    if (pShow->pIter == NULL) break;
×
2767

2768
    cols = 0;
×
2769
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
2770
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
×
UNCOV
2771
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
×
2772
    COL_DATA_SET_VAL_GOTO((const char *)name, false, pUser, _exit);
×
2773

2774
    cols++;
×
UNCOV
2775
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
2776
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->superUser, false, pUser, _exit);
×
2777

2778
    cols++;
×
UNCOV
2779
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
2780
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->enable, false, pUser, _exit);
×
2781

2782
    cols++;
×
UNCOV
2783
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
2784
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sysInfo, false, pUser, _exit);
×
2785

2786
    cols++;
×
2787
    flag = pUser->createdb ? 1 : 0;
×
UNCOV
2788
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
2789
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, _exit);
×
2790

2791
    // mInfo("pUser->pass:%s", pUser->pass);
2792
    cols++;
×
2793
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
2794
    char pass[TSDB_PASSWORD_LEN + VARSTR_HEADER_SIZE] = {0};
×
UNCOV
2795
    STR_WITH_MAXSIZE_TO_VARSTR(pass, pUser->pass, pShow->pMeta->pSchemas[cols].bytes);
×
2796
    COL_DATA_SET_VAL_GOTO((const char *)pass, false, pUser, _exit);
×
2797

2798
    cols++;
×
2799

2800
    int32_t tlen = convertIpWhiteListToStr(pUser->pIpWhiteList, &buf);
×
2801
    // int32_t tlen = mndFetchIpWhiteList(pUser->pIpWhiteList, &buf);
2802
    if (tlen != 0) {
×
2803
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
×
2804
      if (varstr == NULL) {
×
UNCOV
2805
        sdbRelease(pSdb, pUser);
×
2806
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
2807
      }
UNCOV
2808
      varDataSetLen(varstr, tlen);
×
2809
      (void)memcpy(varDataVal(varstr), buf, tlen);
×
2810

UNCOV
2811
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
2812
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, _exit);
×
2813

2814
      taosMemoryFreeClear(buf);
×
2815
    } else {
UNCOV
2816
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
UNCOV
2817
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, _exit);
×
2818
    }
2819

UNCOV
2820
    numOfRows++;
×
UNCOV
2821
    sdbRelease(pSdb, pUser);
×
2822
  }
2823

2824
  pShow->numOfRows += numOfRows;
×
2825
_exit:
×
2826
  taosMemoryFreeClear(buf);
×
2827
  taosMemoryFreeClear(varstr);
×
2828
  if (code < 0) {
×
UNCOV
2829
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
UNCOV
2830
    TAOS_RETURN(code);
×
2831
  }
2832
#endif
UNCOV
2833
  return numOfRows;
×
2834
}
2835

2836
static void mndCancelGetNextUser(SMnode *pMnode, void *pIter) {
×
2837
  SSdb *pSdb = pMnode->pSdb;
×
UNCOV
2838
  sdbCancelFetchByType(pSdb, pIter, SDB_USER);
×
UNCOV
2839
}
×
2840

2841
static int32_t mndLoopHash(SHashObj *hash, char *priType, SSDataBlock *pBlock, int32_t *pNumOfRows, SSdb *pSdb,
26,323✔
2842
                           SUserObj *pUser, SShowObj *pShow, char **condition, char **sql) {
2843
  char   *value = taosHashIterate(hash, NULL);
26,323✔
2844
  char   *user = pUser->user;
26,352✔
2845
  int32_t code = 0;
26,352✔
2846
  int32_t lino = 0;
26,352✔
2847
  int32_t cols = 0;
26,352✔
2848
  int32_t numOfRows = *pNumOfRows;
26,352✔
2849

2850
  while (value != NULL) {
26,354✔
2851
    cols = 0;
2✔
2852
    char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
2✔
2853
    STR_WITH_MAXSIZE_TO_VARSTR(userName, user, pShow->pMeta->pSchemas[cols].bytes);
2✔
2854
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2✔
2855
    COL_DATA_SET_VAL_GOTO((const char *)userName, false, NULL, _exit);
2!
2856

2857
    char privilege[20] = {0};
2✔
2858
    STR_WITH_MAXSIZE_TO_VARSTR(privilege, priType, pShow->pMeta->pSchemas[cols].bytes);
2✔
2859
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2✔
2860
    COL_DATA_SET_VAL_GOTO((const char *)privilege, false, NULL, _exit);
2!
2861

2862
    size_t keyLen = 0;
2✔
2863
    void  *key = taosHashGetKey(value, &keyLen);
2✔
2864

2865
    char dbName[TSDB_DB_NAME_LEN] = {0};
2✔
2866
    (void)mndExtractShortDbNameFromStbFullName(key, dbName);
2✔
2867
    char dbNameContent[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
2✔
2868
    STR_WITH_MAXSIZE_TO_VARSTR(dbNameContent, dbName, pShow->pMeta->pSchemas[cols].bytes);
2✔
2869
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2✔
2870
    COL_DATA_SET_VAL_GOTO((const char *)dbNameContent, false, NULL, _exit);
2!
2871

2872
    char tableName[TSDB_TABLE_NAME_LEN] = {0};
2✔
2873
    mndExtractTbNameFromStbFullName(key, tableName, TSDB_TABLE_NAME_LEN);
2✔
2874
    char tableNameContent[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
2✔
2875
    STR_WITH_MAXSIZE_TO_VARSTR(tableNameContent, tableName, pShow->pMeta->pSchemas[cols].bytes);
2✔
2876
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2✔
2877
    COL_DATA_SET_VAL_GOTO((const char *)tableNameContent, false, NULL, _exit);
2!
2878

2879
    if (strcmp("t", value) != 0 && strcmp("v", value) != 0) {
2!
2880
      SNode  *pAst = NULL;
×
2881
      int32_t sqlLen = 0;
×
2882
      size_t  bufSz = strlen(value) + 1;
×
2883
      if (bufSz < 6) bufSz = 6;
×
2884
      TAOS_MEMORY_REALLOC(*sql, bufSz);
×
2885
      if (*sql == NULL) {
×
UNCOV
2886
        code = terrno;
×
2887
        goto _exit;
×
2888
      }
2889
      TAOS_MEMORY_REALLOC(*condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
×
2890
      if ((*condition) == NULL) {
×
UNCOV
2891
        code = terrno;
×
UNCOV
2892
        goto _exit;
×
2893
      }
2894

2895
      if (nodesStringToNode(value, &pAst) == 0) {
×
2896
        if (nodesNodeToSQL(pAst, *sql, bufSz, &sqlLen) != 0) {
×
UNCOV
2897
          sqlLen = 5;
×
2898
          (void)tsnprintf(*sql, bufSz, "error");
×
2899
        }
2900
        nodesDestroyNode(pAst);
×
2901
      } else {
UNCOV
2902
        sqlLen = 5;
×
UNCOV
2903
        (void)tsnprintf(*sql, bufSz, "error");
×
2904
      }
2905

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

UNCOV
2908
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
2909
      COL_DATA_SET_VAL_GOTO((const char *)(*condition), false, NULL, _exit);
×
2910

2911
      char notes[2] = {0};
×
2912
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
×
UNCOV
2913
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
UNCOV
2914
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, NULL, _exit);
×
2915
    } else {
2916
      TAOS_MEMORY_REALLOC(*condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
2!
2917
      if ((*condition) == NULL) {
2!
UNCOV
2918
        code = terrno;
×
UNCOV
2919
        goto _exit;
×
2920
      }
2921
      STR_WITH_MAXSIZE_TO_VARSTR((*condition), "", pShow->pMeta->pSchemas[cols].bytes);
2✔
2922
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2✔
2923
      COL_DATA_SET_VAL_GOTO((const char *)(*condition), false, NULL, _exit);
2!
2924

2925
      char notes[64 + VARSTR_HEADER_SIZE] = {0};
2✔
2926
      STR_WITH_MAXSIZE_TO_VARSTR(notes, value[0] == 'v' ? "view" : "", sizeof(notes));
2!
2927
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2✔
2928
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, NULL, _exit);
2!
2929
    }
2930

2931
    numOfRows++;
2✔
2932
    value = taosHashIterate(hash, value);
2✔
2933
  }
2934
  *pNumOfRows = numOfRows;
26,352✔
2935
_exit:
26,352✔
2936
  if (code < 0) {
26,352!
UNCOV
2937
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
UNCOV
2938
    sdbRelease(pSdb, pUser);
×
2939
  }
2940
  TAOS_RETURN(code);
26,352✔
2941
}
2942

2943
static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
4,336✔
2944
  int32_t   code = 0;
4,336✔
2945
  int32_t   lino = 0;
4,336✔
2946
  SMnode   *pMnode = pReq->info.node;
4,336✔
2947
  SSdb     *pSdb = pMnode->pSdb;
4,336✔
2948
  int32_t   numOfRows = 0;
4,336✔
2949
  SUserObj *pUser = NULL;
4,336✔
2950
  int32_t   cols = 0;
4,336✔
2951
  char     *pWrite = NULL;
4,336✔
2952
  char     *condition = NULL;
4,336✔
2953
  char     *sql = NULL;
4,336✔
2954

2955
  bool fetchNextUser = pShow->restore ? false : true;
4,336✔
2956
  pShow->restore = false;
4,336✔
2957

2958
  while (numOfRows < rows) {
8,733!
2959
    if (fetchNextUser) {
8,733!
2960
      pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
8,733✔
2961
      if (pShow->pIter == NULL) break;
8,738✔
2962
    } else {
2963
      fetchNextUser = true;
×
2964
      void *pKey = taosHashGetKey(pShow->pIter, NULL);
×
2965
      pUser = sdbAcquire(pSdb, SDB_USER, pKey);
×
UNCOV
2966
      if (!pUser) {
×
UNCOV
2967
        continue;
×
2968
      }
2969
    }
2970

2971
    int32_t numOfReadDbs = taosHashGetSize(pUser->readDbs);
4,399✔
2972
    int32_t numOfWriteDbs = taosHashGetSize(pUser->writeDbs);
4,386✔
2973
    int32_t numOfTopics = taosHashGetSize(pUser->topics);
4,397✔
2974
    int32_t numOfReadTbs = taosHashGetSize(pUser->readTbs);
4,398✔
2975
    int32_t numOfWriteTbs = taosHashGetSize(pUser->writeTbs);
4,395✔
2976
    int32_t numOfAlterTbs = taosHashGetSize(pUser->alterTbs);
4,395✔
2977
    int32_t numOfReadViews = taosHashGetSize(pUser->readViews);
4,395✔
2978
    int32_t numOfWriteViews = taosHashGetSize(pUser->writeViews);
4,396✔
2979
    int32_t numOfAlterViews = taosHashGetSize(pUser->alterViews);
4,394✔
2980
    if (numOfRows + numOfReadDbs + numOfWriteDbs + numOfTopics + numOfReadTbs + numOfWriteTbs + numOfAlterTbs +
4,396✔
2981
            numOfReadViews + numOfWriteViews + numOfAlterViews >=
4,396!
2982
        rows) {
UNCOV
2983
      mInfo(
×
2984
          "will restore. current num of rows: %d, read dbs %d, write dbs %d, topics %d, read tables %d, write tables "
2985
          "%d, alter tables %d, read views %d, write views %d, alter views %d",
2986
          numOfRows, numOfReadDbs, numOfWriteDbs, numOfTopics, numOfReadTbs, numOfWriteTbs, numOfAlterTbs,
2987
          numOfReadViews, numOfWriteViews, numOfAlterViews);
2988
      pShow->restore = true;
×
UNCOV
2989
      sdbRelease(pSdb, pUser);
×
UNCOV
2990
      break;
×
2991
    }
2992

2993
    if (pUser->superUser) {
4,396✔
2994
      cols = 0;
4,327✔
2995
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
4,327✔
2996
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
4,327✔
2997
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4,327✔
2998
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, _exit);
4,326!
2999

3000
      char privilege[20] = {0};
4,334✔
3001
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "all", pShow->pMeta->pSchemas[cols].bytes);
4,334✔
3002
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4,334✔
3003
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, _exit);
4,336!
3004

3005
      char objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4,333✔
3006
      STR_WITH_MAXSIZE_TO_VARSTR(objName, "all", pShow->pMeta->pSchemas[cols].bytes);
4,333✔
3007
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4,333✔
3008
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, _exit);
4,339!
3009

3010
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4,338✔
3011
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
4,338✔
3012
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4,338✔
3013
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, _exit);
4,324!
3014

3015
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
4,337!
3016
      if (condition == NULL) {
4,339!
UNCOV
3017
        sdbRelease(pSdb, pUser);
×
UNCOV
3018
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
3019
      }
3020
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
4,339✔
3021
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4,339✔
3022
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, _exit);
4,338!
3023

3024
      char notes[2] = {0};
4,337✔
3025
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
4,337✔
3026
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4,337✔
3027
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, _exit);
4,332!
3028

3029
      numOfRows++;
4,337✔
3030
    }
3031

3032
    char *db = taosHashIterate(pUser->readDbs, NULL);
4,406✔
3033
    while (db != NULL) {
4,416✔
3034
      cols = 0;
19✔
3035
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
19✔
3036
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
19✔
3037
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3038
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, _exit);
19!
3039

3040
      char privilege[20] = {0};
19✔
3041
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "read", pShow->pMeta->pSchemas[cols].bytes);
19✔
3042
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3043
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, _exit);
19!
3044

3045
      SName name = {0};
19✔
3046
      char  objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
19✔
3047
      code = tNameFromString(&name, db, T_NAME_ACCT | T_NAME_DB);
19✔
3048
      if (code < 0) {
19!
UNCOV
3049
        sdbRelease(pSdb, pUser);
×
UNCOV
3050
        TAOS_CHECK_GOTO(code, &lino, _exit);
×
3051
      }
3052
      (void)tNameGetDbName(&name, varDataVal(objName));
19✔
3053
      varDataSetLen(objName, strlen(varDataVal(objName)));
19✔
3054
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3055
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, _exit);
19!
3056

3057
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
19✔
3058
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
19✔
3059
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3060
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, _exit);
19!
3061

3062
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
19!
3063
      if (condition == NULL) {
19!
UNCOV
3064
        sdbRelease(pSdb, pUser);
×
UNCOV
3065
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
3066
      }
3067
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
19✔
3068
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3069
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, _exit);
19!
3070

3071
      char notes[2] = {0};
19✔
3072
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
19✔
3073
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3074
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, _exit);
19!
3075

3076
      numOfRows++;
19✔
3077
      db = taosHashIterate(pUser->readDbs, db);
19✔
3078
    }
3079

3080
    db = taosHashIterate(pUser->writeDbs, NULL);
4,397✔
3081
    while (db != NULL) {
4,399✔
3082
      cols = 0;
19✔
3083
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
19✔
3084
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
19✔
3085
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3086
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, _exit);
19!
3087

3088
      char privilege[20] = {0};
19✔
3089
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "write", pShow->pMeta->pSchemas[cols].bytes);
19✔
3090
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3091
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, _exit);
19!
3092

3093
      SName name = {0};
19✔
3094
      char  objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
19✔
3095
      code = tNameFromString(&name, db, T_NAME_ACCT | T_NAME_DB);
19✔
3096
      if (code < 0) {
19!
UNCOV
3097
        sdbRelease(pSdb, pUser);
×
UNCOV
3098
        TAOS_CHECK_GOTO(code, &lino, _exit);
×
3099
      }
3100
      (void)tNameGetDbName(&name, varDataVal(objName));
19✔
3101
      varDataSetLen(objName, strlen(varDataVal(objName)));
19✔
3102
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3103
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, _exit);
19!
3104

3105
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
19✔
3106
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
19✔
3107
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3108
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, _exit);
19!
3109

3110
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
19!
3111
      if (condition == NULL) {
19!
UNCOV
3112
        sdbRelease(pSdb, pUser);
×
UNCOV
3113
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
3114
      }
3115
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
19✔
3116
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3117
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, _exit);
19!
3118

3119
      char notes[2] = {0};
19✔
3120
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
19✔
3121
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3122
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, _exit);
19!
3123

3124
      numOfRows++;
19✔
3125
      db = taosHashIterate(pUser->writeDbs, db);
19✔
3126
    }
3127

3128
    TAOS_CHECK_EXIT(mndLoopHash(pUser->readTbs, "read", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
4,380!
3129

3130
    TAOS_CHECK_EXIT(mndLoopHash(pUser->writeTbs, "write", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
4,389!
3131

3132
    TAOS_CHECK_EXIT(mndLoopHash(pUser->alterTbs, "alter", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
4,389!
3133

3134
    TAOS_CHECK_EXIT(mndLoopHash(pUser->readViews, "read", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
4,395!
3135

3136
    TAOS_CHECK_EXIT(mndLoopHash(pUser->writeViews, "write", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
4,396!
3137

3138
    TAOS_CHECK_EXIT(mndLoopHash(pUser->alterViews, "alter", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
4,396!
3139

3140
    char *topic = taosHashIterate(pUser->topics, NULL);
4,388✔
3141
    while (topic != NULL) {
4,400✔
3142
      cols = 0;
8✔
3143
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
8✔
3144
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
8✔
3145
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
8✔
3146
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, _exit);
8!
3147

3148
      char privilege[20] = {0};
8✔
3149
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "subscribe", pShow->pMeta->pSchemas[cols].bytes);
8✔
3150
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
8✔
3151
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, _exit);
8!
3152

3153
      char topicName[TSDB_TOPIC_NAME_LEN + VARSTR_HEADER_SIZE + 5] = {0};
8✔
3154
      tstrncpy(varDataVal(topicName), mndGetDbStr(topic), TSDB_TOPIC_NAME_LEN - 2);
8✔
3155
      varDataSetLen(topicName, strlen(varDataVal(topicName)));
8✔
3156
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
8✔
3157
      COL_DATA_SET_VAL_GOTO((const char *)topicName, false, pUser, _exit);
8!
3158

3159
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
8✔
3160
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
8✔
3161
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
8✔
3162
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, _exit);
8!
3163

3164
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
8!
3165
      if (condition == NULL) {
8!
UNCOV
3166
        sdbRelease(pSdb, pUser);
×
UNCOV
3167
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
3168
      }
3169
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
8✔
3170
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
8✔
3171
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, _exit);
8!
3172

3173
      char notes[2] = {0};
8✔
3174
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
8✔
3175
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
8✔
3176
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, _exit);
8!
3177

3178
      numOfRows++;
8✔
3179
      topic = taosHashIterate(pUser->topics, topic);
8✔
3180
    }
3181

3182
    sdbRelease(pSdb, pUser);
4,392✔
3183
  }
3184

3185
  pShow->numOfRows += numOfRows;
4,339✔
3186
_exit:
4,339✔
3187
  taosMemoryFreeClear(condition);
4,339!
3188
  taosMemoryFreeClear(sql);
4,339!
3189
  if (code < 0) {
4,339!
UNCOV
3190
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
UNCOV
3191
    TAOS_RETURN(code);
×
3192
  }
3193
  return numOfRows;
4,339✔
3194
}
3195

3196
static void mndCancelGetNextPrivileges(SMnode *pMnode, void *pIter) {
×
3197
  SSdb *pSdb = pMnode->pSdb;
×
UNCOV
3198
  sdbCancelFetchByType(pSdb, pIter, SDB_USER);
×
UNCOV
3199
}
×
3200

3201
int32_t mndValidateUserAuthInfo(SMnode *pMnode, SUserAuthVersion *pUsers, int32_t numOfUses, void **ppRsp,
33,120✔
3202
                                int32_t *pRspLen, int64_t ipWhiteListVer) {
3203
  int32_t           code = 0;
33,120✔
3204
  int32_t           lino = 0;
33,120✔
3205
  int32_t           rspLen = 0;
33,120✔
3206
  void             *pRsp = NULL;
33,120✔
3207
  SUserAuthBatchRsp batchRsp = {0};
33,120✔
3208

3209
  batchRsp.pArray = taosArrayInit(numOfUses, sizeof(SGetUserAuthRsp));
33,120✔
3210
  if (batchRsp.pArray == NULL) {
33,120!
UNCOV
3211
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3212
  }
3213

3214
  for (int32_t i = 0; i < numOfUses; ++i) {
66,341✔
3215
    SUserObj *pUser = NULL;
33,221✔
3216
    code = mndAcquireUser(pMnode, pUsers[i].user, &pUser);
33,221✔
3217
    if (pUser == NULL) {
33,221✔
3218
      if (TSDB_CODE_MND_USER_NOT_EXIST == code) {
14!
3219
        SGetUserAuthRsp rsp = {.dropped = 1};
14✔
3220
        (void)memcpy(rsp.user, pUsers[i].user, TSDB_USER_LEN);
14✔
3221
        TSDB_CHECK_NULL(taosArrayPush(batchRsp.pArray, &rsp), code, lino, _OVER, TSDB_CODE_OUT_OF_MEMORY);
28!
3222
      }
3223
      mError("user:%s, failed to auth user since %s", pUsers[i].user, tstrerror(code));
14!
3224
      code = 0;
14✔
3225
      continue;
31,075✔
3226
    }
3227

3228
    pUsers[i].version = ntohl(pUsers[i].version);
33,207✔
3229
    if (pUser->authVersion <= pUsers[i].version && ipWhiteListVer == pMnode->ipWhiteVer) {
33,207✔
3230
      mndReleaseUser(pMnode, pUser);
31,061✔
3231
      continue;
31,061✔
3232
    }
3233

3234
    SGetUserAuthRsp rsp = {0};
2,146✔
3235
    code = mndSetUserAuthRsp(pMnode, pUser, &rsp);
2,146✔
3236
    if (code) {
2,146!
3237
      mndReleaseUser(pMnode, pUser);
×
UNCOV
3238
      tFreeSGetUserAuthRsp(&rsp);
×
UNCOV
3239
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3240
    }
3241

3242
    if (!(taosArrayPush(batchRsp.pArray, &rsp))) {
4,292!
3243
      code = terrno;
×
3244
      mndReleaseUser(pMnode, pUser);
×
UNCOV
3245
      tFreeSGetUserAuthRsp(&rsp);
×
UNCOV
3246
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3247
    }
3248
    mndReleaseUser(pMnode, pUser);
2,146✔
3249
  }
3250

3251
  if (taosArrayGetSize(batchRsp.pArray) <= 0) {
33,120✔
3252
    *ppRsp = NULL;
31,040✔
3253
    *pRspLen = 0;
31,040✔
3254

3255
    tFreeSUserAuthBatchRsp(&batchRsp);
31,040✔
3256
    return 0;
31,040✔
3257
  }
3258

3259
  rspLen = tSerializeSUserAuthBatchRsp(NULL, 0, &batchRsp);
2,080✔
3260
  if (rspLen < 0) {
2,080!
UNCOV
3261
    TAOS_CHECK_GOTO(rspLen, &lino, _OVER);
×
3262
  }
3263
  pRsp = taosMemoryMalloc(rspLen);
2,080!
3264
  if (pRsp == NULL) {
2,080!
UNCOV
3265
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3266
  }
3267
  rspLen = tSerializeSUserAuthBatchRsp(pRsp, rspLen, &batchRsp);
2,080✔
3268
  if (rspLen < 0) {
2,080!
UNCOV
3269
    TAOS_CHECK_GOTO(rspLen, &lino, _OVER);
×
3270
  }
3271
_OVER:
2,080✔
3272
  tFreeSUserAuthBatchRsp(&batchRsp);
2,080✔
3273
  if (code < 0) {
2,080!
3274
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
UNCOV
3275
    taosMemoryFreeClear(pRsp);
×
UNCOV
3276
    rspLen = 0;
×
3277
  }
3278
  *ppRsp = pRsp;
2,080✔
3279
  *pRspLen = rspLen;
2,080✔
3280

3281
  TAOS_RETURN(code);
2,080✔
3282
}
3283

3284
int32_t mndUserRemoveDb(SMnode *pMnode, STrans *pTrans, char *db) {
1,576✔
3285
  int32_t   code = 0;
1,576✔
3286
  int32_t   lino = 0;
1,576✔
3287
  SSdb     *pSdb = pMnode->pSdb;
1,576✔
3288
  int32_t   len = strlen(db) + 1;
1,576✔
3289
  void     *pIter = NULL;
1,576✔
3290
  SUserObj *pUser = NULL;
1,576✔
3291
  SUserObj  newUser = {0};
1,576✔
3292

3293
  while (1) {
1,675✔
3294
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
3,251✔
3295
    if (pIter == NULL) break;
3,251✔
3296

3297
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
1,675!
UNCOV
3298
      break;
×
3299
    }
3300

3301
    bool inRead = (taosHashGet(newUser.readDbs, db, len) != NULL);
1,675✔
3302
    bool inWrite = (taosHashGet(newUser.writeDbs, db, len) != NULL);
1,675✔
3303
    if (inRead || inWrite) {
1,675!
3304
      code = taosHashRemove(newUser.readDbs, db, len);
2✔
3305
      if (code < 0) {
2!
UNCOV
3306
        mError("failed to remove readDbs:%s from user:%s", db, pUser->user);
×
3307
      }
3308
      code = taosHashRemove(newUser.writeDbs, db, len);
2✔
3309
      if (code < 0) {
2!
UNCOV
3310
        mError("failed to remove writeDbs:%s from user:%s", db, pUser->user);
×
3311
      }
3312

3313
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
2✔
3314
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
2!
UNCOV
3315
        code = TSDB_CODE_OUT_OF_MEMORY;
×
UNCOV
3316
        break;
×
3317
      }
3318
      TAOS_CHECK_GOTO(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY), &lino, _OVER);
2!
3319
    }
3320

3321
    mndUserFreeObj(&newUser);
1,675✔
3322
    sdbRelease(pSdb, pUser);
1,675✔
3323
  }
3324

3325
_OVER:
1,576✔
3326
  if (pUser != NULL) sdbRelease(pSdb, pUser);
1,576!
3327
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
1,576!
3328
  mndUserFreeObj(&newUser);
1,576✔
3329
  TAOS_RETURN(code);
1,576✔
3330
}
3331

3332
int32_t mndUserRemoveStb(SMnode *pMnode, STrans *pTrans, char *stb) {
836✔
3333
  int32_t   code = 0;
836✔
3334
  SSdb     *pSdb = pMnode->pSdb;
836✔
3335
  int32_t   len = strlen(stb) + 1;
836✔
3336
  void     *pIter = NULL;
836✔
3337
  SUserObj *pUser = NULL;
836✔
3338
  SUserObj  newUser = {0};
836✔
3339

3340
  while (1) {
836✔
3341
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
1,672✔
3342
    if (pIter == NULL) break;
1,672✔
3343

3344
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
836!
UNCOV
3345
      break;
×
3346
    }
3347

3348
    bool inRead = (taosHashGet(newUser.readTbs, stb, len) != NULL);
836✔
3349
    bool inWrite = (taosHashGet(newUser.writeTbs, stb, len) != NULL);
836✔
3350
    bool inAlter = (taosHashGet(newUser.alterTbs, stb, len) != NULL);
836✔
3351
    if (inRead || inWrite || inAlter) {
836!
3352
      code = taosHashRemove(newUser.readTbs, stb, len);
×
UNCOV
3353
      if (code < 0) {
×
3354
        mError("failed to remove readTbs:%s from user:%s", stb, pUser->user);
×
3355
      }
3356
      code = taosHashRemove(newUser.writeTbs, stb, len);
×
UNCOV
3357
      if (code < 0) {
×
3358
        mError("failed to remove writeTbs:%s from user:%s", stb, pUser->user);
×
3359
      }
3360
      code = taosHashRemove(newUser.alterTbs, stb, len);
×
UNCOV
3361
      if (code < 0) {
×
UNCOV
3362
        mError("failed to remove alterTbs:%s from user:%s", stb, pUser->user);
×
3363
      }
3364

3365
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
×
3366
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
×
UNCOV
3367
        code = TSDB_CODE_OUT_OF_MEMORY;
×
3368
        break;
×
3369
      }
3370
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
×
3371
      if (code != 0) {
×
3372
        mndUserFreeObj(&newUser);
×
UNCOV
3373
        sdbRelease(pSdb, pUser);
×
UNCOV
3374
        TAOS_RETURN(code);
×
3375
      }
3376
    }
3377

3378
    mndUserFreeObj(&newUser);
836✔
3379
    sdbRelease(pSdb, pUser);
836✔
3380
  }
3381

3382
  if (pUser != NULL) sdbRelease(pSdb, pUser);
836!
3383
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
836!
3384
  mndUserFreeObj(&newUser);
836✔
3385
  TAOS_RETURN(code);
836✔
3386
}
3387

3388
int32_t mndUserRemoveView(SMnode *pMnode, STrans *pTrans, char *view) {
107✔
3389
  int32_t   code = 0;
107✔
3390
  SSdb     *pSdb = pMnode->pSdb;
107✔
3391
  int32_t   len = strlen(view) + 1;
107✔
3392
  void     *pIter = NULL;
107✔
3393
  SUserObj *pUser = NULL;
107✔
3394
  SUserObj  newUser = {0};
107✔
3395

3396
  while (1) {
113✔
3397
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
220✔
3398
    if (pIter == NULL) break;
220✔
3399

3400
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
113!
UNCOV
3401
      break;
×
3402
    }
3403

3404
    bool inRead = (taosHashGet(newUser.readViews, view, len) != NULL);
113✔
3405
    bool inWrite = (taosHashGet(newUser.writeViews, view, len) != NULL);
113✔
3406
    bool inAlter = (taosHashGet(newUser.alterViews, view, len) != NULL);
113✔
3407
    if (inRead || inWrite || inAlter) {
113!
3408
      code = taosHashRemove(newUser.readViews, view, len);
2✔
3409
      if (code < 0) {
2!
UNCOV
3410
        mError("failed to remove readViews:%s from user:%s", view, pUser->user);
×
3411
      }
3412
      code = taosHashRemove(newUser.writeViews, view, len);
2✔
3413
      if (code < 0) {
2!
3414
        mError("failed to remove writeViews:%s from user:%s", view, pUser->user);
2!
3415
      }
3416
      code = taosHashRemove(newUser.alterViews, view, len);
2✔
3417
      if (code < 0) {
2!
3418
        mError("failed to remove alterViews:%s from user:%s", view, pUser->user);
2!
3419
      }
3420

3421
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
2✔
3422
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
2!
UNCOV
3423
        code = TSDB_CODE_OUT_OF_MEMORY;
×
UNCOV
3424
        break;
×
3425
      }
3426
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
2✔
3427
      if (code < 0) {
2!
3428
        mndUserFreeObj(&newUser);
×
UNCOV
3429
        sdbRelease(pSdb, pUser);
×
UNCOV
3430
        TAOS_RETURN(code);
×
3431
      }
3432
    }
3433

3434
    mndUserFreeObj(&newUser);
113✔
3435
    sdbRelease(pSdb, pUser);
113✔
3436
  }
3437

3438
  if (pUser != NULL) sdbRelease(pSdb, pUser);
107!
3439
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
107!
3440
  mndUserFreeObj(&newUser);
107✔
3441
  TAOS_RETURN(code);
107✔
3442
}
3443

3444
int32_t mndUserRemoveTopic(SMnode *pMnode, STrans *pTrans, char *topic) {
309✔
3445
  int32_t   code = 0;
309✔
3446
  SSdb     *pSdb = pMnode->pSdb;
309✔
3447
  int32_t   len = strlen(topic) + 1;
309✔
3448
  void     *pIter = NULL;
309✔
3449
  SUserObj *pUser = NULL;
309✔
3450
  SUserObj  newUser = {0};
309✔
3451

3452
  while (1) {
312✔
3453
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
621✔
3454
    if (pIter == NULL) {
621✔
3455
      break;
309✔
3456
    }
3457

3458
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
312!
UNCOV
3459
      break;
×
3460
    }
3461

3462
    bool inTopic = (taosHashGet(newUser.topics, topic, len) != NULL);
312✔
3463
    if (inTopic) {
312!
3464
      code = taosHashRemove(newUser.topics, topic, len);
×
UNCOV
3465
      if (code < 0) {
×
3466
        mError("failed to remove topic:%s from user:%s", topic, pUser->user);
×
3467
      }
3468
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
×
3469
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
×
UNCOV
3470
        code = TSDB_CODE_OUT_OF_MEMORY;
×
3471
        break;
×
3472
      }
3473
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
×
3474
      if (code < 0) {
×
3475
        mndUserFreeObj(&newUser);
×
UNCOV
3476
        sdbRelease(pSdb, pUser);
×
UNCOV
3477
        TAOS_RETURN(code);
×
3478
      }
3479
    }
3480

3481
    mndUserFreeObj(&newUser);
312✔
3482
    sdbRelease(pSdb, pUser);
312✔
3483
  }
3484

3485
  if (pUser != NULL) sdbRelease(pSdb, pUser);
309!
3486
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
309!
3487
  mndUserFreeObj(&newUser);
309✔
3488
  TAOS_RETURN(code);
309✔
3489
}
3490

UNCOV
3491
int64_t mndGetUserIpWhiteListVer(SMnode *pMnode, SUserObj *pUser) {
×
3492
  // ver = 0, disable ip white list
3493
  // ver > 0, enable ip white list
UNCOV
3494
  return tsEnableWhiteList ? pUser->ipWhiteListVer : 0;
×
3495
}
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