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

taosdata / TDengine / #4404

30 Jun 2025 02:45AM UTC coverage: 62.241% (-0.4%) from 62.635%
#4404

push

travis-ci

web-flow
Merge pull request #31480 from taosdata/docs/3.0/TD-34215

add stmt2 docs

153837 of 315978 branches covered (48.69%)

Branch coverage included in aggregate %.

238272 of 314005 relevant lines covered (75.88%)

6134648.6 hits per line

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

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

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

32
// clang-format on
33

34
#define USER_VER_NUMBER                      7
35
#define USER_VER_SUPPORT_WHITELIST           5
36
#define USER_VER_SUPPORT_WHITELIT_DUAL_STACK 7
37
#define USER_RESERVE_SIZE                    63
38

39
#define BIT_FLAG_MASK(n)              (1 << n)
40
#define BIT_FLAG_SET_MASK(val, mask)  ((val) |= (mask))
41
#define BIT_FLAG_TEST_MASK(val, mask) (((val) & (mask)) != 0)
42

43
#define PRIVILEGE_TYPE_ALL       BIT_FLAG_MASK(0)
44
#define PRIVILEGE_TYPE_READ      BIT_FLAG_MASK(1)
45
#define PRIVILEGE_TYPE_WRITE     BIT_FLAG_MASK(2)
46
#define PRIVILEGE_TYPE_SUBSCRIBE BIT_FLAG_MASK(3)
47
#define PRIVILEGE_TYPE_ALTER     BIT_FLAG_MASK(4)
48

49
#define ALTER_USER_ADD_PRIVS(_type) ((_type) == TSDB_ALTER_USER_ADD_PRIVILEGES)
50
#define ALTER_USER_DEL_PRIVS(_type) ((_type) == TSDB_ALTER_USER_DEL_PRIVILEGES)
51

52
#define ALTER_USER_ALL_PRIV(_priv) (BIT_FLAG_TEST_MASK((_priv), PRIVILEGE_TYPE_ALL))
53
#define ALTER_USER_READ_PRIV(_priv) \
54
  (BIT_FLAG_TEST_MASK((_priv), PRIVILEGE_TYPE_READ) || BIT_FLAG_TEST_MASK((_priv), PRIVILEGE_TYPE_ALL))
55
#define ALTER_USER_WRITE_PRIV(_priv) \
56
  (BIT_FLAG_TEST_MASK((_priv), PRIVILEGE_TYPE_WRITE) || BIT_FLAG_TEST_MASK((_priv), PRIVILEGE_TYPE_ALL))
57
#define ALTER_USER_ALTER_PRIV(_priv) \
58
  (BIT_FLAG_TEST_MASK((_priv), PRIVILEGE_TYPE_ALTER) || BIT_FLAG_TEST_MASK((_priv), PRIVILEGE_TYPE_ALL))
59
#define ALTER_USER_SUBSCRIBE_PRIV(_priv) (BIT_FLAG_TEST_MASK((_priv), PRIVILEGE_TYPE_SUBSCRIBE))
60

61
#define ALTER_USER_TARGET_DB(_tbname) (0 == (_tbname)[0])
62
#define ALTER_USER_TARGET_TB(_tbname) (0 != (_tbname)[0])
63

64
#define ALTER_USER_ADD_READ_DB_PRIV(_type, _priv, _tbname) \
65
  (ALTER_USER_ADD_PRIVS(_type) && ALTER_USER_READ_PRIV(_priv) && ALTER_USER_TARGET_DB(_tbname))
66
#define ALTER_USER_DEL_READ_DB_PRIV(_type, _priv, _tbname) \
67
  (ALTER_USER_DEL_PRIVS(_type) && ALTER_USER_READ_PRIV(_priv) && ALTER_USER_TARGET_DB(_tbname))
68
#define ALTER_USER_ADD_WRITE_DB_PRIV(_type, _priv, _tbname) \
69
  (ALTER_USER_ADD_PRIVS(_type) && ALTER_USER_WRITE_PRIV(_priv) && ALTER_USER_TARGET_DB(_tbname))
70
#define ALTER_USER_DEL_WRITE_DB_PRIV(_type, _priv, _tbname) \
71
  (ALTER_USER_DEL_PRIVS(_type) && ALTER_USER_WRITE_PRIV(_priv) && ALTER_USER_TARGET_DB(_tbname))
72
#define ALTER_USER_ADD_ALTER_DB_PRIV(_type, _priv, _tbname) \
73
  (ALTER_USER_ADD_PRIVS(_type) && ALTER_USER_ALTER_PRIV(_priv) && ALTER_USER_TARGET_DB(_tbname))
74
#define ALTER_USER_DEL_ALTER_DB_PRIV(_type, _priv, _tbname) \
75
  (ALTER_USER_DEL_PRIVS(_type) && ALTER_USER_ALTER_PRIV(_priv) && ALTER_USER_TARGET_DB(_tbname))
76
#define ALTER_USER_ADD_ALL_DB_PRIV(_type, _priv, _tbname) \
77
  (ALTER_USER_ADD_PRIVS(_type) && ALTER_USER_ALL_PRIV(_priv) && ALTER_USER_TARGET_DB(_tbname))
78
#define ALTER_USER_DEL_ALL_DB_PRIV(_type, _priv, _tbname) \
79
  (ALTER_USER_DEL_PRIVS(_type) && ALTER_USER_ALL_PRIV(_priv) && ALTER_USER_TARGET_DB(_tbname))
80

81
#define ALTER_USER_ADD_READ_TB_PRIV(_type, _priv, _tbname) \
82
  (ALTER_USER_ADD_PRIVS(_type) && ALTER_USER_READ_PRIV(_priv) && ALTER_USER_TARGET_TB(_tbname))
83
#define ALTER_USER_DEL_READ_TB_PRIV(_type, _priv, _tbname) \
84
  (ALTER_USER_DEL_PRIVS(_type) && ALTER_USER_READ_PRIV(_priv) && ALTER_USER_TARGET_TB(_tbname))
85
#define ALTER_USER_ADD_WRITE_TB_PRIV(_type, _priv, _tbname) \
86
  (ALTER_USER_ADD_PRIVS(_type) && ALTER_USER_WRITE_PRIV(_priv) && ALTER_USER_TARGET_TB(_tbname))
87
#define ALTER_USER_DEL_WRITE_TB_PRIV(_type, _priv, _tbname) \
88
  (ALTER_USER_DEL_PRIVS(_type) && ALTER_USER_WRITE_PRIV(_priv) && ALTER_USER_TARGET_TB(_tbname))
89
#define ALTER_USER_ADD_ALTER_TB_PRIV(_type, _priv, _tbname) \
90
  (ALTER_USER_ADD_PRIVS(_type) && ALTER_USER_ALTER_PRIV(_priv) && ALTER_USER_TARGET_TB(_tbname))
91
#define ALTER_USER_DEL_ALTER_TB_PRIV(_type, _priv, _tbname) \
92
  (ALTER_USER_DEL_PRIVS(_type) && ALTER_USER_ALTER_PRIV(_priv) && ALTER_USER_TARGET_TB(_tbname))
93
#define ALTER_USER_ADD_ALL_TB_PRIV(_type, _priv, _tbname) \
94
  (ALTER_USER_ADD_PRIVS(_type) && ALTER_USER_ALL_PRIV(_priv) && ALTER_USER_TARGET_TB(_tbname))
95
#define ALTER_USER_DEL_ALL_TB_PRIV(_type, _priv, _tbname) \
96
  (ALTER_USER_DEL_PRIVS(_type) && ALTER_USER_ALL_PRIV(_priv) && ALTER_USER_TARGET_TB(_tbname))
97

98
#define ALTER_USER_ADD_SUBSCRIBE_TOPIC_PRIV(_type, _priv) \
99
  (ALTER_USER_ADD_PRIVS(_type) && ALTER_USER_SUBSCRIBE_PRIV(_priv))
100
#define ALTER_USER_DEL_SUBSCRIBE_TOPIC_PRIV(_type, _priv) \
101
  (ALTER_USER_DEL_PRIVS(_type) && ALTER_USER_SUBSCRIBE_PRIV(_priv))
102

103
static int32_t createDefaultIpWhiteList(SIpWhiteListDual **ppWhiteList);
104
static int32_t createIpWhiteList(void *buf, int32_t len, SIpWhiteListDual **ppWhiteList);
105

106
static bool isIpWhiteListEqual(SIpWhiteListDual *a, SIpWhiteListDual *b);
107
static bool isIpRangeEqual(SIpRange *a, SIpRange *b);
108

109
void destroyIpWhiteTab(SHashObj *pIpWhiteTab);
110

111
#define MND_MAX_USE_HOST (TSDB_PRIVILEDGE_HOST_LEN / 24)
112

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

133
static int32_t ipWhiteMgtUpdateAll(SMnode *pMnode);
134
static int32_t ipWhiteMgtRemove(char *user);
135

136
static int32_t createIpWhiteListFromOldVer(void *buf, int32_t len, SIpWhiteList **ppList);
137
static int32_t tDerializeIpWhileListFromOldVer(void *buf, int32_t len, SIpWhiteList *pList);
138
typedef struct {
139
  SHashObj      *pIpWhiteTab;
140
  int64_t        ver;
141
  TdThreadRwlock rw;
142
} SIpWhiteMgt;
143

144
static SIpWhiteMgt ipWhiteMgt;
145

146
const static SIpV4Range defaultIpRange = {.ip = 16777343, .mask = 32};
147

148
static int32_t ipWhiteMgtInit() {
2,162✔
149
  ipWhiteMgt.pIpWhiteTab = taosHashInit(8, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), 1, HASH_ENTRY_LOCK);
2,162✔
150
  if (ipWhiteMgt.pIpWhiteTab == NULL) {
2,162!
151
    TAOS_RETURN(terrno);
×
152
  }
153
  ipWhiteMgt.ver = 0;
2,162✔
154
  (void)taosThreadRwlockInit(&ipWhiteMgt.rw, NULL);
2,162✔
155
  TAOS_RETURN(0);
2,162✔
156
}
157
void ipWhiteMgtCleanup() {
2,161✔
158
  destroyIpWhiteTab(ipWhiteMgt.pIpWhiteTab);
2,161✔
159
  (void)taosThreadRwlockDestroy(&ipWhiteMgt.rw);
2,161✔
160
}
2,161✔
161

162
int32_t ipWhiteMgtUpdate(SMnode *pMnode, char *user, SIpWhiteListDual *pNew) {
428✔
163
  int32_t code = 0;
428✔
164
  int32_t lino = 0;
428✔
165
  bool    update = true;
428✔
166
  SArray *fqdns = NULL;
428✔
167
  (void)taosThreadRwlockWrlock(&ipWhiteMgt.rw);
428✔
168
  SIpWhiteListDual **ppList = taosHashGet(ipWhiteMgt.pIpWhiteTab, user, strlen(user));
428✔
169

170
  if (ppList == NULL || *ppList == NULL) {
590!
171
    SIpWhiteListDual *p = cloneIpWhiteList(pNew);
162✔
172
    if (p == NULL) {
162!
173
      update = false;
×
174
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
175
    }
176
    if ((code = taosHashPut(ipWhiteMgt.pIpWhiteTab, user, strlen(user), &p, sizeof(void *))) != 0) {
162!
177
      update = false;
×
178
      taosMemoryFree(p);
×
179
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
180
    }
181
  } else {
182
    SIpWhiteListDual *pOld = *ppList;
266✔
183
    if (isIpWhiteListEqual(pOld, pNew)) {
266✔
184
      update = false;
241✔
185
    } else {
186
      taosMemoryFree(pOld);
25!
187
      SIpWhiteListDual *p = cloneIpWhiteList(pNew);
25✔
188
      if (p == NULL) {
25!
189
        update = false;
×
190
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
191
      }
192
      if ((code = taosHashPut(ipWhiteMgt.pIpWhiteTab, user, strlen(user), &p, sizeof(void *))) != 0) {
25!
193
        update = false;
×
194
        taosMemoryFree(p);
×
195
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
196
      }
197
    }
198
  }
199

200
  fqdns = mndGetAllDnodeFqdns(pMnode);  // TODO: update this line after refactor api
428✔
201
  if (fqdns == NULL) {
428!
202
    update = false;
×
203
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
204
  }
205

206
  for (int i = 0; i < taosArrayGetSize(fqdns); i++) {
1,063✔
207
    char *fqdn = taosArrayGetP(fqdns, i);
635✔
208
    bool  upd = false;
635✔
209
    TAOS_CHECK_GOTO(mndUpdateIpWhiteImpl(ipWhiteMgt.pIpWhiteTab, TSDB_DEFAULT_USER, fqdn, IP_WHITE_ADD, &upd), &lino,
635!
210
                    _OVER);
211
    update |= upd;
635✔
212
    TAOS_CHECK_GOTO(mndUpdateIpWhiteImpl(ipWhiteMgt.pIpWhiteTab, user, fqdn, IP_WHITE_ADD, &upd), &lino, _OVER);
635!
213
    update |= upd;
635✔
214
  }
215

216
  if (update) ipWhiteMgt.ver++;
428✔
217

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

241
  if (update) ipWhiteMgt.ver++;
59!
242
  (void)taosThreadRwlockUnlock(&ipWhiteMgt.rw);
59✔
243
  return 0;
59✔
244
}
245

246
bool isRangeInWhiteList(SIpWhiteListDual *pList, SIpRange *range) {
5,863✔
247
  for (int i = 0; i < pList->num; i++) {
9,031✔
248
    if (isIpRangeEqual(&pList->pIpRanges[i], range)) {
8,727✔
249
      return true;
5,559✔
250
    }
251
  }
252
  return false;
304✔
253
}
254

255
static int32_t ipWhiteMgtUpdateAll(SMnode *pMnode) {
2,472✔
256
  SHashObj *pNew = NULL;
2,472✔
257
  TAOS_CHECK_RETURN(mndFetchAllIpWhite(pMnode, &pNew));
2,472!
258

259
  SHashObj *pOld = ipWhiteMgt.pIpWhiteTab;
2,472✔
260

261
  ipWhiteMgt.pIpWhiteTab = pNew;
2,472✔
262
  ipWhiteMgt.ver++;
2,472✔
263

264
  destroyIpWhiteTab(pOld);
2,472✔
265
  TAOS_RETURN(0);
2,472✔
266
}
267

268
int64_t mndGetIpWhiteVer(SMnode *pMnode) {
88,359✔
269
  int64_t ver = 0;
88,359✔
270
  int32_t code = 0;
88,359✔
271
  (void)taosThreadRwlockWrlock(&ipWhiteMgt.rw);
88,359✔
272
  if (ipWhiteMgt.ver == 0) {
88,359!
273
    // get user and dnode ip white list
274
    if ((code = ipWhiteMgtUpdateAll(pMnode)) != 0) {
×
275
      (void)taosThreadRwlockUnlock(&ipWhiteMgt.rw);
×
276
      mError("%s failed to update ip white list since %s", __func__, tstrerror(code));
×
277
      return ver;
×
278
    }
279
    ipWhiteMgt.ver = taosGetTimestampMs();
×
280
  }
281
  ver = ipWhiteMgt.ver;
88,359✔
282
  (void)taosThreadRwlockUnlock(&ipWhiteMgt.rw);
88,359✔
283

284
  if (mndEnableIpWhiteList(pMnode) == 0 || tsEnableWhiteList == false) {
88,359!
285
    ver = 0;
88,351✔
286
  }
287
  mDebug("ip-white-list on mnode ver: %" PRId64, ver);
88,359✔
288
  return ver;
88,359✔
289
}
290

291
int32_t mndUpdateIpWhiteImpl(SHashObj *pIpWhiteTab, char *user, char *fqdn, int8_t type, bool *pUpdate) {
7,487✔
292
  int32_t lino = 0;
7,487✔
293
  bool    update = false;
7,487✔
294

295
  SIpRange range = {0};
7,487✔
296
  SIpAddr  addr = {0};
7,487✔
297
  int32_t  code = taosGetIpFromFqdn(tsEnableIpv6, fqdn, &addr);
7,487✔
298
  if (code) {
7,487!
299
    mError("failed to get ip from fqdn: %s at line %d since %s", fqdn, lino, tstrerror(code));
×
300
    TAOS_RETURN(TSDB_CODE_TSC_INVALID_FQDN);
×
301
  }
302

303
  code = tIpStrToUint(&addr, &range);
7,487✔
304
  if (code) {
7,487!
305
    TAOS_RETURN(code);
×
306
  }
307

308
  tIpRangeSetMask(&range, 32);
7,487✔
309

310
  mDebug("ip-white-list may update for user: %s, fqdn: %s", user, fqdn);
7,487✔
311
  SIpWhiteListDual **ppList = taosHashGet(pIpWhiteTab, user, strlen(user));
7,487✔
312
  SIpWhiteListDual  *pList = NULL;
7,487✔
313
  if (ppList != NULL && *ppList != NULL) {
7,487!
314
    pList = *ppList;
5,863✔
315
  }
316

317
  if (type == IP_WHITE_ADD) {
7,487!
318
    if (pList == NULL) {
7,487✔
319
      SIpWhiteListDual *pNewList = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + sizeof(SIpRange));
1,624!
320
      if (pNewList == NULL) {
1,624!
321
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
322
      }
323
      (void)memcpy(pNewList->pIpRanges, &range, sizeof(SIpRange));
1,624✔
324
      pNewList->num = 1;
1,624✔
325

326
      if ((code = taosHashPut(pIpWhiteTab, user, strlen(user), &pNewList, sizeof(void *))) != 0) {
1,624!
327
        taosMemoryFree(pNewList);
×
328
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
329
      }
330
      update = true;
1,624✔
331
    } else {
332
      if (!isRangeInWhiteList(pList, &range)) {
5,863✔
333
        int32_t           sz = sizeof(SIpWhiteListDual) + sizeof(SIpRange) * (pList->num + 1);
304✔
334
        SIpWhiteListDual *pNewList = taosMemoryCalloc(1, sz);
304!
335
        if (pNewList == NULL) {
304!
336
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
337
        }
338
        (void)memcpy(pNewList->pIpRanges, pList->pIpRanges, sizeof(SIpRange) * (pList->num));
304✔
339
        memcpy(&pNewList->pIpRanges[pList->num], &range, sizeof(SIpRange));
304✔
340

341
        pNewList->num = pList->num + 1;
304✔
342

343
        if ((code = taosHashPut(pIpWhiteTab, user, strlen(user), &pNewList, sizeof(void *))) != 0) {
304!
344
          taosMemoryFree(pNewList);
×
345
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
346
        }
347
        taosMemoryFree(pList);
304!
348
        update = true;
304✔
349
      }
350
    }
351
  } else if (type == IP_WHITE_DROP) {
×
352
    if (pList != NULL) {
×
353
      if (isRangeInWhiteList(pList, &range)) {
×
354
        if (pList->num == 1) {
×
355
          if (taosHashRemove(pIpWhiteTab, user, strlen(user)) < 0) {
×
356
            mError("failed to remove ip-white-list for user: %s at line %d", user, lino);
×
357
          }
358
          taosMemoryFree(pList);
×
359
        } else {
360
          int32_t           idx = 0;
×
361
          int32_t           sz = sizeof(SIpWhiteListDual) + sizeof(SIpRange) * (pList->num - 1);
×
362
          SIpWhiteListDual *pNewList = taosMemoryCalloc(1, sz);
×
363
          if (pNewList == NULL) {
×
364
            TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
365
          }
366
          for (int i = 0; i < pList->num; i++) {
×
367
            SIpRange *e = &pList->pIpRanges[i];
×
368
            if (!isIpRangeEqual(e, &range)) {
×
369
              memcpy(&pNewList->pIpRanges[idx], e, sizeof(SIpRange));
×
370
              idx++;
×
371
            }
372
          }
373
          pNewList->num = idx;
×
374
          if ((code = taosHashPut(pIpWhiteTab, user, strlen(user), &pNewList, sizeof(void *)) != 0)) {
×
375
            taosMemoryFree(pNewList);
×
376
            TAOS_CHECK_GOTO(code, &lino, _OVER);
×
377
          }
378
          taosMemoryFree(pList);
×
379
        }
380
        update = true;
×
381
      }
382
    }
383
  }
384
  if (update) {
7,487✔
385
    mDebug("ip-white-list update for user: %s, fqdn: %s", user, fqdn);
1,928✔
386
  }
387

388
_OVER:
5,613✔
389
  if (pUpdate) *pUpdate = update;
7,487✔
390
  if (code < 0) {
7,487!
391
    mError("failed to update ip-white-list for user: %s, fqdn: %s at line %d since %s", user, fqdn, lino,
×
392
           tstrerror(code));
393
  }
394
  TAOS_RETURN(code);
7,487✔
395
}
396

397
int32_t mndRefreshUserIpWhiteList(SMnode *pMnode) {
2,472✔
398
  int32_t code = 0;
2,472✔
399
  (void)taosThreadRwlockWrlock(&ipWhiteMgt.rw);
2,472✔
400

401
  if ((code = ipWhiteMgtUpdateAll(pMnode)) != 0) {
2,472!
402
    (void)taosThreadRwlockUnlock(&ipWhiteMgt.rw);
×
403
    TAOS_RETURN(code);
×
404
  }
405
  ipWhiteMgt.ver = taosGetTimestampMs();
2,472✔
406
  (void)taosThreadRwlockUnlock(&ipWhiteMgt.rw);
2,472✔
407

408
  TAOS_RETURN(code);
2,472✔
409
}
410

411
int32_t mndUpdateIpWhiteForAllUser(SMnode *pMnode, char *user, char *fqdn, int8_t type, int8_t lock) {
2,098✔
412
  int32_t code = 0;
2,098✔
413
  int32_t lino = 0;
2,098✔
414
  bool    update = false;
2,098✔
415

416
  if (lock) {
2,098!
417
    (void)taosThreadRwlockWrlock(&ipWhiteMgt.rw);
2,098✔
418
    if (ipWhiteMgt.ver == 0) {
2,098!
419
      TAOS_CHECK_GOTO(ipWhiteMgtUpdateAll(pMnode), &lino, _OVER);
×
420
      ipWhiteMgt.ver = taosGetTimestampMs();
×
421
      mInfo("update ip-white-list, user: %s, ver: %" PRId64, user, ipWhiteMgt.ver);
×
422
    }
423
  }
424

425
  TAOS_CHECK_GOTO(mndUpdateIpWhiteImpl(ipWhiteMgt.pIpWhiteTab, user, fqdn, type, &update), &lino, _OVER);
2,098!
426

427
  void *pIter = taosHashIterate(ipWhiteMgt.pIpWhiteTab, NULL);
2,098✔
428
  while (pIter) {
4,222✔
429
    size_t klen = 0;
2,124✔
430
    char  *key = taosHashGetKey(pIter, &klen);
2,124✔
431

432
    char *keyDup = taosMemoryCalloc(1, klen + 1);
2,124!
433
    if (keyDup == NULL) {
2,124!
434
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
435
    }
436
    (void)memcpy(keyDup, key, klen);
2,124✔
437
    bool upd = false;
2,124✔
438
    code = mndUpdateIpWhiteImpl(ipWhiteMgt.pIpWhiteTab, keyDup, fqdn, type, &upd);
2,124✔
439
    update |= upd;
2,124✔
440
    if (code < 0) {
2,124!
441
      taosMemoryFree(keyDup);
×
442
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
443
    }
444
    taosMemoryFree(keyDup);
2,124!
445

446
    pIter = taosHashIterate(ipWhiteMgt.pIpWhiteTab, pIter);
2,124✔
447
  }
448

449
_OVER:
2,098✔
450
  if (update) ipWhiteMgt.ver++;
2,098✔
451
  if (lock) (void)taosThreadRwlockUnlock(&ipWhiteMgt.rw);
2,098!
452
  if (code < 0) {
2,098!
453
    mError("failed to update ip-white-list for user: %s, fqdn: %s at line %d since %s", user, fqdn, lino,
×
454
           tstrerror(code));
455
  }
456

457
  TAOS_RETURN(code);
2,098✔
458
}
459

460
static int64_t ipWhiteMgtFillMsg(SUpdateIpWhite *pUpdate) {
6✔
461
  int64_t ver = 0;
6✔
462
  (void)taosThreadRwlockWrlock(&ipWhiteMgt.rw);
6✔
463
  ver = ipWhiteMgt.ver;
6✔
464
  int32_t num = taosHashGetSize(ipWhiteMgt.pIpWhiteTab);
6✔
465

466
  pUpdate->pUserIpWhite = taosMemoryCalloc(1, num * sizeof(SUpdateUserIpWhite));
6!
467
  if (pUpdate->pUserIpWhite == NULL) {
6!
468
    (void)taosThreadRwlockUnlock(&ipWhiteMgt.rw);
×
469
    TAOS_RETURN(terrno);
×
470
  }
471

472
  void   *pIter = taosHashIterate(ipWhiteMgt.pIpWhiteTab, NULL);
6✔
473
  int32_t i = 0;
6✔
474
  while (pIter) {
12✔
475
    SUpdateUserIpWhite *pUser = &pUpdate->pUserIpWhite[i];
6✔
476
    SIpWhiteListDual   *list = *(SIpWhiteListDual **)pIter;
6✔
477

478
    size_t klen;
479
    char  *key = taosHashGetKey(pIter, &klen);
6✔
480
    if (list->num != 0) {
6!
481
      pUser->ver = ver;
6✔
482
      (void)memcpy(pUser->user, key, klen);
6✔
483
      pUser->numOfRange = list->num;
6✔
484
      pUser->pIpRanges = taosMemoryCalloc(1, list->num * sizeof(SIpRange));
6!
485
      if (pUser->pIpRanges == NULL) {
6!
486
        (void)taosThreadRwlockUnlock(&ipWhiteMgt.rw);
×
487
        TAOS_RETURN(terrno);
×
488
      }
489
      (void)memcpy(pUser->pIpRanges, list->pIpRanges, list->num * sizeof(SIpRange));
6✔
490
      i++;
6✔
491
    }
492
    pIter = taosHashIterate(ipWhiteMgt.pIpWhiteTab, pIter);
6✔
493
  }
494
  pUpdate->numOfUser = i;
6✔
495
  pUpdate->ver = ver;
6✔
496

497
  (void)taosThreadRwlockUnlock(&ipWhiteMgt.rw);
6✔
498
  TAOS_RETURN(0);
6✔
499
}
500

501
void destroyIpWhiteTab(SHashObj *pIpWhiteTab) {
4,633✔
502
  if (pIpWhiteTab == NULL) return;
4,633!
503

504
  void *pIter = taosHashIterate(pIpWhiteTab, NULL);
4,633✔
505
  while (pIter) {
7,112✔
506
    SIpWhiteListDual *list = *(SIpWhiteListDual **)pIter;
2,479✔
507
    taosMemoryFree(list);
2,479!
508
    pIter = taosHashIterate(pIpWhiteTab, pIter);
2,479✔
509
  }
510

511
  taosHashCleanup(pIpWhiteTab);
4,633✔
512
}
513
int32_t mndFetchAllIpWhite(SMnode *pMnode, SHashObj **ppIpWhiteTab) {
2,472✔
514
  int32_t   code = 0;
2,472✔
515
  int32_t   lino = 0;
2,472✔
516
  SSdb     *pSdb = pMnode->pSdb;
2,472✔
517
  void     *pIter = NULL;
2,472✔
518
  SHashObj *pIpWhiteTab = NULL;
2,472✔
519
  SArray   *pUserNames = NULL;
2,472✔
520
  SArray   *fqdns = NULL;
2,472✔
521

522
  pIpWhiteTab = taosHashInit(8, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), 1, HASH_ENTRY_LOCK);
2,472✔
523
  if (pIpWhiteTab == NULL) {
2,472!
524
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
525
  }
526
  pUserNames = taosArrayInit(8, sizeof(void *));
2,472✔
527
  if (pUserNames == NULL) {
2,472!
528
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
529
  }
530

531
  while (1) {
752✔
532
    SUserObj *pUser = NULL;
3,224✔
533
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
3,224✔
534
    if (pIter == NULL) break;
3,224✔
535

536
    SIpWhiteListDual *pWhiteList = cloneIpWhiteList(pUser->pIpWhiteListDual);
752✔
537
    if (pWhiteList == NULL) {
752!
538
      sdbRelease(pSdb, pUser);
×
539
      sdbCancelFetch(pSdb, pIter);
×
540
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
541
    }
542
    if ((code = taosHashPut(pIpWhiteTab, pUser->user, strlen(pUser->user), &pWhiteList, sizeof(void *))) != 0) {
752!
543
      taosMemoryFree(pWhiteList);
×
544
      sdbRelease(pSdb, pUser);
×
545
      sdbCancelFetch(pSdb, pIter);
×
546
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
547
    }
548

549
    char *name = taosStrdup(pUser->user);
752!
550
    if (name == NULL) {
752!
551
      sdbRelease(pSdb, pUser);
×
552
      sdbCancelFetch(pSdb, pIter);
×
553
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
554
    }
555
    if (taosArrayPush(pUserNames, &name) == NULL) {
752!
556
      taosMemoryFree(name);
×
557
      sdbRelease(pSdb, pUser);
×
558
      sdbCancelFetch(pSdb, pIter);
×
559
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
560
    }
561

562
    sdbRelease(pSdb, pUser);
752✔
563
  }
564

565
  bool found = false;
2,472✔
566
  for (int i = 0; i < taosArrayGetSize(pUserNames); i++) {
2,480✔
567
    char *name = taosArrayGetP(pUserNames, i);
750✔
568
    if (strlen(name) == strlen(TSDB_DEFAULT_USER) && strncmp(name, TSDB_DEFAULT_USER, strlen(TSDB_DEFAULT_USER)) == 0) {
750!
569
      found = true;
742✔
570
      break;
742✔
571
    }
572
  }
573
  if (found == false) {
2,472✔
574
    char *name = taosStrdup(TSDB_DEFAULT_USER);
1,730!
575
    if (name == NULL) {
1,730!
576
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
577
    }
578
    if (taosArrayPush(pUserNames, &name) == NULL) {
1,730!
579
      taosMemoryFree(name);
×
580
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
581
    }
582
  }
583

584
  fqdns = mndGetAllDnodeFqdns(pMnode);  // TODO: refactor this line after refactor api
2,472✔
585
  if (fqdns == NULL) {
2,472!
586
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
587
  }
588

589
  for (int i = 0; i < taosArrayGetSize(fqdns); i++) {
4,439✔
590
    char *fqdn = taosArrayGetP(fqdns, i);
1,967✔
591

592
    for (int j = 0; j < taosArrayGetSize(pUserNames); j++) {
3,962✔
593
      char *name = taosArrayGetP(pUserNames, j);
1,995✔
594
      TAOS_CHECK_GOTO(mndUpdateIpWhiteImpl(pIpWhiteTab, name, fqdn, IP_WHITE_ADD, NULL), &lino, _OVER);
1,995!
595
    }
596
  }
597

598
_OVER:
2,472✔
599
  taosArrayDestroyP(fqdns, NULL);
2,472✔
600
  taosArrayDestroyP(pUserNames, NULL);
2,472✔
601

602
  if (code < 0) {
2,472!
603
    mError("failed to fetch all ip white list at line %d since %s", lino, tstrerror(code));
×
604
    destroyIpWhiteTab(pIpWhiteTab);
×
605
    pIpWhiteTab = NULL;
×
606
  }
607
  *ppIpWhiteTab = pIpWhiteTab;
2,472✔
608
  TAOS_RETURN(code);
2,472✔
609
}
610

611
int32_t mndInitUser(SMnode *pMnode) {
2,162✔
612
  TAOS_CHECK_RETURN(ipWhiteMgtInit());
2,162!
613

614
  SSdbTable table = {
2,162✔
615
      .sdbType = SDB_USER,
616
      .keyType = SDB_KEY_BINARY,
617
      .deployFp = (SdbDeployFp)mndCreateDefaultUsers,
618
      .encodeFp = (SdbEncodeFp)mndUserActionEncode,
619
      .decodeFp = (SdbDecodeFp)mndUserActionDecode,
620
      .insertFp = (SdbInsertFp)mndUserActionInsert,
621
      .updateFp = (SdbUpdateFp)mndUserActionUpdate,
622
      .deleteFp = (SdbDeleteFp)mndUserActionDelete,
623
  };
624

625
  mndSetMsgHandle(pMnode, TDMT_MND_CREATE_USER, mndProcessCreateUserReq);
2,162✔
626
  mndSetMsgHandle(pMnode, TDMT_MND_ALTER_USER, mndProcessAlterUserReq);
2,162✔
627
  mndSetMsgHandle(pMnode, TDMT_MND_DROP_USER, mndProcessDropUserReq);
2,162✔
628
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_AUTH, mndProcessGetUserAuthReq);
2,162✔
629
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_WHITELIST, mndProcessGetUserWhiteListReq);
2,162✔
630
  mndSetMsgHandle(pMnode, TDMT_MND_GET_USER_WHITELIST_DUAL, mndProcessGetUserWhiteListReq);
2,162✔
631

632
  mndSetMsgHandle(pMnode, TDMT_MND_RETRIEVE_IP_WHITE, mndProcesSRetrieveIpWhiteReq);
2,162✔
633
  mndSetMsgHandle(pMnode, TDMT_MND_RETRIEVE_IP_WHITE_DUAL, mndProcesSRetrieveIpWhiteReq);
2,162✔
634

635
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_USER, mndRetrieveUsers);
2,162✔
636
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_USER, mndCancelGetNextUser);
2,162✔
637
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_USER_FULL, mndRetrieveUsersFull);
2,162✔
638
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_USER_FULL, mndCancelGetNextUser);
2,162✔
639
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_PRIVILEGES, mndRetrievePrivileges);
2,162✔
640
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_PRIVILEGES, mndCancelGetNextPrivileges);
2,162✔
641
  return sdbSetTable(pMnode->pSdb, table);
2,162✔
642
}
643

644
void mndCleanupUser(SMnode *pMnode) { ipWhiteMgtCleanup(); }
2,161✔
645

646
static bool isDefaultRange(SIpRange *pRange) {
2✔
647
  int32_t code = 0;
2✔
648
  int32_t lino = 0;
2✔
649

650
  SIpRange range4 = {0};
2✔
651
  SIpRange range6 = {0};
2✔
652

653
  code = createDefaultIp4Range(&range4);
2✔
654
  TSDB_CHECK_CODE(code, lino, _error);
2!
655

656
  code = createDefaultIp6Range(&range6);
2✔
657
  TSDB_CHECK_CODE(code, lino, _error);
2!
658

659
  if (isIpRangeEqual(pRange, &range4) || (isIpRangeEqual(pRange, &range6))) {
2!
660
    return true;
×
661
  }
662
_error:
2✔
663
  return false;
2✔
664
};
665

666
static int32_t ipRangeListToStr(SIpRange *range, int32_t num, char *buf, int64_t bufLen) {
126✔
667
  int32_t len = 0;
126✔
668
  for (int i = 0; i < num; i++) {
382✔
669
    SIpRange *pRange = &range[i];
256✔
670
    SIpAddr   addr = {0};
256✔
671
    tIpUintToStr(pRange, &addr);
256✔
672

673
    len += tsnprintf(buf + len, bufLen - len, "%s/%d,", IP_ADDR_STR(&addr), addr.mask);
256✔
674
  }
675
  if (len > 0) buf[len - 1] = 0;
126!
676
  return len;
126✔
677
}
678

679
static bool isIpRangeEqual(SIpRange *a, SIpRange *b) {
9,218✔
680
  // equal or not
681
  if (a->type != b->type) {
9,218✔
682
    return false;
1,586✔
683
  }
684
  if (a->type == 0) {
7,632✔
685
    SIpV4Range *aP4 = &a->ipV4;
7,391✔
686
    SIpV4Range *bP4 = &b->ipV4;
7,391✔
687
    if (aP4->ip != bP4->ip || aP4->mask != bP4->mask) {
7,391!
688
      return false;
1,591✔
689
    } else {
690
      return true;
5,800✔
691
    }
692
  } else {
693
    SIpV6Range *aP6 = &a->ipV6;
241✔
694
    SIpV6Range *bP6 = &b->ipV6;
241✔
695
    if (aP6->addr[0] != bP6->addr[0] || aP6->addr[1] != bP6->addr[1] || aP6->mask != bP6->mask) {
241!
696
      return false;
×
697
    } else {
698
      return true;
241✔
699
    }
700
  }
701

702
  return true;
703
}
704
static bool isRangeInIpWhiteList(SIpWhiteListDual *pList, SIpRange *tgt) {
1✔
705
  for (int i = 0; i < pList->num; i++) {
4✔
706
    if (isIpRangeEqual(&pList->pIpRanges[i], tgt)) return true;
3!
707
  }
708
  return false;
1✔
709
}
710
static bool isIpWhiteListEqual(SIpWhiteListDual *a, SIpWhiteListDual *b) {
266✔
711
  if (a->num != b->num) {
266✔
712
    return false;
25✔
713
  }
714
  for (int i = 0; i < a->num; i++) {
723✔
715
    if (!isIpRangeEqual(&a->pIpRanges[i], &b->pIpRanges[i])) {
482!
716
      return false;
×
717
    }
718
  }
719
  return true;
241✔
720
}
721
int32_t convertIpWhiteListToStr(SIpWhiteListDual *pList, char **buf) {
126✔
722
  if (pList->num == 0) {
126!
723
    *buf = NULL;
×
724
    return 0;
×
725
  }
726
  int64_t bufLen = pList->num * 256;
126✔
727
  *buf = taosMemoryCalloc(1, bufLen);
126!
728
  if (*buf == NULL) {
126!
729
    return 0;
×
730
  }
731

732
  int32_t len = ipRangeListToStr(pList->pIpRanges, pList->num, *buf, bufLen);
126✔
733
  if (len == 0) {
126!
734
    taosMemoryFreeClear(*buf);
×
735
    return 0;
×
736
  }
737
  return strlen(*buf);
126✔
738
}
739
int32_t tSerializeIpWhiteList(void *buf, int32_t len, SIpWhiteListDual *pList, uint32_t *pLen) {
6,197✔
740
  int32_t  code = 0;
6,197✔
741
  int32_t  lino = 0;
6,197✔
742
  int32_t  tlen = 0;
6,197✔
743
  SEncoder encoder = {0};
6,197✔
744
  tEncoderInit(&encoder, buf, len);
6,197✔
745

746
  TAOS_CHECK_GOTO(tStartEncode(&encoder), &lino, _OVER);
6,197!
747
  TAOS_CHECK_GOTO(tEncodeI32(&encoder, pList->num), &lino, _OVER);
12,394!
748

749
  for (int i = 0; i < pList->num; i++) {
18,596✔
750
    SIpRange *pRange = &(pList->pIpRanges[i]);
12,399✔
751
    TAOS_CHECK_GOTO(tSerializeIpRange(&encoder, pRange), &lino, _OVER);
12,399!
752
  }
753

754
  tEndEncode(&encoder);
6,197✔
755

756
  tlen = encoder.pos;
6,197✔
757
_OVER:
6,197✔
758
  tEncoderClear(&encoder);
6,197✔
759
  if (code < 0) {
6,197!
760
    mError("failed to serialize ip white list at line %d since %s", lino, tstrerror(code));
×
761
  }
762
  if (pLen) *pLen = tlen;
6,197!
763
  TAOS_RETURN(code);
6,197✔
764
}
765

766
int32_t tDerializeIpWhileList(void *buf, int32_t len, SIpWhiteListDual *pList) {
2,837✔
767
  int32_t  code = 0;
2,837✔
768
  int32_t  lino = 0;
2,837✔
769
  SDecoder decoder = {0};
2,837✔
770
  tDecoderInit(&decoder, buf, len);
2,837✔
771

772
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
2,837!
773
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &pList->num), &lino, _OVER);
5,674!
774

775
  for (int i = 0; i < pList->num; i++) {
8,534✔
776
    SIpRange *pRange = &(pList->pIpRanges[i]);
5,697✔
777
    TAOS_CHECK_GOTO(tDeserializeIpRange(&decoder, pRange), &lino, _OVER);
5,697!
778
  }
779

780
_OVER:
2,837✔
781
  tEndDecode(&decoder);
2,837✔
782
  tDecoderClear(&decoder);
2,837✔
783
  if (code < 0) {
2,837!
784
    mError("failed to deserialize ip white list at line %d since %s", lino, tstrerror(code));
×
785
  }
786
  TAOS_RETURN(code);
2,837✔
787
}
788

789
int32_t tDerializeIpWhileListFromOldVer(void *buf, int32_t len, SIpWhiteList *pList) {
×
790
  int32_t  code = 0;
×
791
  int32_t  lino = 0;
×
792
  SDecoder decoder = {0};
×
793
  tDecoderInit(&decoder, buf, len);
×
794

795
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
×
796
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &pList->num), &lino, _OVER);
×
797

798
  for (int i = 0; i < pList->num; i++) {
×
799
    SIpV4Range *pIp4 = &(pList->pIpRange[i]);
×
800
    TAOS_CHECK_GOTO(tDecodeU32(&decoder, &pIp4->ip), &lino, _OVER);
×
801
    TAOS_CHECK_GOTO(tDecodeU32(&decoder, &pIp4->mask), &lino, _OVER);
×
802
  }
803

804
_OVER:
×
805
  tEndDecode(&decoder);
×
806
  tDecoderClear(&decoder);
×
807
  if (code < 0) {
×
808
    mError("failed to deserialize ip white list at line %d since %s", lino, tstrerror(code));
×
809
  }
810
  TAOS_RETURN(code);
×
811
}
812

813
static int32_t createIpWhiteList(void *buf, int32_t len, SIpWhiteListDual **ppList) {
2,837✔
814
  int32_t           code = 0;
2,837✔
815
  int32_t           lino = 0;
2,837✔
816
  int32_t           num = 0;
2,837✔
817
  SIpWhiteListDual *p = NULL;
2,837✔
818
  SDecoder          decoder = {0};
2,837✔
819
  tDecoderInit(&decoder, buf, len);
2,837✔
820

821
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
2,837!
822
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &num), &lino, _OVER);
2,837!
823

824
  p = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + num * sizeof(SIpRange));
2,837!
825
  if (p == NULL) {
2,837!
826
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
827
  }
828
  TAOS_CHECK_GOTO(tDerializeIpWhileList(buf, len, p), &lino, _OVER);
2,837!
829

830
_OVER:
2,837✔
831
  tEndDecode(&decoder);
2,837✔
832
  tDecoderClear(&decoder);
2,837✔
833
  if (code < 0) {
2,837!
834
    taosMemoryFreeClear(p);
×
835
    mError("failed to create ip white list at line %d since %s", lino, tstrerror(code));
×
836
  }
837
  *ppList = p;
2,837✔
838
  TAOS_RETURN(code);
2,837✔
839
}
840

841
static int32_t createIpWhiteListFromOldVer(void *buf, int32_t len, SIpWhiteList **ppList) {
×
842
  int32_t       code = 0;
×
843
  int32_t       lino = 0;
×
844
  int32_t       num = 0;
×
845
  SIpWhiteList *p = NULL;
×
846
  SDecoder      decoder = {0};
×
847
  tDecoderInit(&decoder, buf, len);
×
848

849
  TAOS_CHECK_GOTO(tStartDecode(&decoder), &lino, _OVER);
×
850
  TAOS_CHECK_GOTO(tDecodeI32(&decoder, &num), &lino, _OVER);
×
851

852
  p = taosMemoryCalloc(1, sizeof(SIpWhiteList) + num * sizeof(SIpV4Range));
×
853
  if (p == NULL) {
×
854
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
855
  }
856
  TAOS_CHECK_GOTO(tDerializeIpWhileListFromOldVer(buf, len, p), &lino, _OVER);
×
857

858
_OVER:
×
859
  tEndDecode(&decoder);
×
860
  tDecoderClear(&decoder);
×
861
  if (code < 0) {
×
862
    taosMemoryFreeClear(p);
×
863
    mError("failed to create ip white list at line %d since %s", lino, tstrerror(code));
×
864
  }
865
  *ppList = p;
×
866
  TAOS_RETURN(code);
×
867
}
868

869
static int32_t createDefaultIpWhiteList(SIpWhiteListDual **ppWhiteList) {
1,783✔
870
  int32_t code = 0;
1,783✔
871
  int32_t lino = 0;
1,783✔
872
  *ppWhiteList = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + sizeof(SIpRange) * 2);
1,783!
873
  if (*ppWhiteList == NULL) {
1,783!
874
    TAOS_RETURN(terrno);
×
875
  }
876
  (*ppWhiteList)->num = 2;
1,783✔
877

878
  SIpRange v4 = {0};
1,783✔
879
  SIpRange v6 = {0};
1,783✔
880

881
#ifndef TD_ASTRA
882
  code = createDefaultIp4Range(&v4);
1,783✔
883
  TSDB_CHECK_CODE(code, lino, _error);
1,783!
884

885
  code = createDefaultIp6Range(&v6);
1,783✔
886
  TSDB_CHECK_CODE(code, lino, _error);
1,783!
887

888
#endif
889

890
_error:
1,783✔
891
  if (code != 0) {
1,783!
892
    taosMemoryFree(*ppWhiteList);
×
893
    *ppWhiteList = NULL;
×
894
    mError("failed to create default ip white list at line %d since %s", __LINE__, tstrerror(code));
×
895
  } else {
896
    memcpy(&(*ppWhiteList)->pIpRanges[0], &v4, sizeof(SIpRange));
1,783✔
897
    memcpy(&(*ppWhiteList)->pIpRanges[1], &v6, sizeof(SIpRange));
1,783✔
898
  }
899
  return 0;
1,783✔
900
}
901

902
static int32_t mndCreateDefaultUser(SMnode *pMnode, char *acct, char *user, char *pass) {
1,624✔
903
  int32_t  code = 0;
1,624✔
904
  int32_t  lino = 0;
1,624✔
905
  SUserObj userObj = {0};
1,624✔
906
  taosEncryptPass_c((uint8_t *)pass, strlen(pass), userObj.pass);
1,624✔
907
  tstrncpy(userObj.user, user, TSDB_USER_LEN);
1,624✔
908
  tstrncpy(userObj.acct, acct, TSDB_USER_LEN);
1,624✔
909
  userObj.createdTime = taosGetTimestampMs();
1,624✔
910
  userObj.updateTime = userObj.createdTime;
1,624✔
911
  userObj.sysInfo = 1;
1,624✔
912
  userObj.enable = 1;
1,624✔
913
  userObj.ipWhiteListVer = taosGetTimestampMs();
1,624✔
914
  TAOS_CHECK_RETURN(createDefaultIpWhiteList(&userObj.pIpWhiteListDual));
1,624!
915
  if (strcmp(user, TSDB_DEFAULT_USER) == 0) {
1,624!
916
    userObj.superUser = 1;
1,624✔
917
    userObj.createdb = 1;
1,624✔
918
  }
919

920
  SSdbRaw *pRaw = mndUserActionEncode(&userObj);
1,624✔
921
  if (pRaw == NULL) goto _ERROR;
1,624!
922
  TAOS_CHECK_GOTO(sdbSetRawStatus(pRaw, SDB_STATUS_READY), &lino, _ERROR);
1,624!
923

924
  mInfo("user:%s, will be created when deploying, raw:%p", userObj.user, pRaw);
1,624!
925

926
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, NULL, "create-user");
1,624✔
927
  if (pTrans == NULL) {
1,624!
928
    sdbFreeRaw(pRaw);
×
929
    mError("user:%s, failed to create since %s", userObj.user, terrstr());
×
930
    goto _ERROR;
×
931
  }
932
  mInfo("trans:%d, used to create user:%s", pTrans->id, userObj.user);
1,624!
933

934
  if (mndTransAppendCommitlog(pTrans, pRaw) != 0) {
1,624!
935
    mError("trans:%d, failed to commit redo log since %s", pTrans->id, terrstr());
×
936
    mndTransDrop(pTrans);
×
937
    goto _ERROR;
×
938
  }
939
  TAOS_CHECK_GOTO(sdbSetRawStatus(pRaw, SDB_STATUS_READY), &lino, _ERROR);
1,624!
940

941
  if (mndTransPrepare(pMnode, pTrans) != 0) {
1,624!
942
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
943
    mndTransDrop(pTrans);
×
944
    goto _ERROR;
×
945
  }
946

947
  mndTransDrop(pTrans);
1,624✔
948
  taosMemoryFree(userObj.pIpWhiteListDual);
1,624!
949
  return 0;
1,624✔
950
_ERROR:
×
951
  taosMemoryFree(userObj.pIpWhiteListDual);
×
952
  TAOS_RETURN(terrno ? terrno : TSDB_CODE_APP_ERROR);
×
953
}
954

955
static int32_t mndCreateDefaultUsers(SMnode *pMnode) {
1,624✔
956
  return mndCreateDefaultUser(pMnode, TSDB_DEFAULT_USER, TSDB_DEFAULT_USER, TSDB_DEFAULT_PASS);
1,624✔
957
}
958

959
SSdbRaw *mndUserActionEncode(SUserObj *pUser) {
6,197✔
960
  int32_t code = 0;
6,197✔
961
  int32_t lino = 0;
6,197✔
962
  int32_t ipWhiteReserve =
×
963
      pUser->pIpWhiteListDual ? (sizeof(SIpRange) * pUser->pIpWhiteListDual->num + sizeof(SIpWhiteListDual) + 4) : 16;
6,197!
964
  int32_t numOfReadDbs = taosHashGetSize(pUser->readDbs);
6,197✔
965
  int32_t numOfWriteDbs = taosHashGetSize(pUser->writeDbs);
6,197✔
966
  int32_t numOfReadTbs = taosHashGetSize(pUser->readTbs);
6,197✔
967
  int32_t numOfWriteTbs = taosHashGetSize(pUser->writeTbs);
6,197✔
968
  int32_t numOfAlterTbs = taosHashGetSize(pUser->alterTbs);
6,197✔
969
  int32_t numOfReadViews = taosHashGetSize(pUser->readViews);
6,197✔
970
  int32_t numOfWriteViews = taosHashGetSize(pUser->writeViews);
6,197✔
971
  int32_t numOfAlterViews = taosHashGetSize(pUser->alterViews);
6,197✔
972
  int32_t numOfTopics = taosHashGetSize(pUser->topics);
6,197✔
973
  int32_t numOfUseDbs = taosHashGetSize(pUser->useDbs);
6,197✔
974
  int32_t size = sizeof(SUserObj) + USER_RESERVE_SIZE + (numOfReadDbs + numOfWriteDbs) * TSDB_DB_FNAME_LEN +
6,197✔
975
                 numOfTopics * TSDB_TOPIC_FNAME_LEN + ipWhiteReserve;
6,197✔
976
  char    *buf = NULL;
6,197✔
977
  SSdbRaw *pRaw = NULL;
6,197✔
978

979
  char *stb = taosHashIterate(pUser->readTbs, NULL);
6,197✔
980
  while (stb != NULL) {
6,254✔
981
    size_t keyLen = 0;
57✔
982
    void  *key = taosHashGetKey(stb, &keyLen);
57✔
983
    size += sizeof(int32_t);
57✔
984
    size += keyLen;
57✔
985

986
    size_t valueLen = 0;
57✔
987
    valueLen = strlen(stb) + 1;
57✔
988
    size += sizeof(int32_t);
57✔
989
    size += valueLen;
57✔
990
    stb = taosHashIterate(pUser->readTbs, stb);
57✔
991
  }
992

993
  stb = taosHashIterate(pUser->writeTbs, NULL);
6,197✔
994
  while (stb != NULL) {
6,266✔
995
    size_t keyLen = 0;
69✔
996
    void  *key = taosHashGetKey(stb, &keyLen);
69✔
997
    size += sizeof(int32_t);
69✔
998
    size += keyLen;
69✔
999

1000
    size_t valueLen = 0;
69✔
1001
    valueLen = strlen(stb) + 1;
69✔
1002
    size += sizeof(int32_t);
69✔
1003
    size += valueLen;
69✔
1004
    stb = taosHashIterate(pUser->writeTbs, stb);
69✔
1005
  }
1006

1007
  stb = taosHashIterate(pUser->alterTbs, NULL);
6,197✔
1008
  while (stb != NULL) {
6,214✔
1009
    size_t keyLen = 0;
17✔
1010
    void  *key = taosHashGetKey(stb, &keyLen);
17✔
1011
    size += sizeof(int32_t);
17✔
1012
    size += keyLen;
17✔
1013

1014
    size_t valueLen = 0;
17✔
1015
    valueLen = strlen(stb) + 1;
17✔
1016
    size += sizeof(int32_t);
17✔
1017
    size += valueLen;
17✔
1018
    stb = taosHashIterate(pUser->alterTbs, stb);
17✔
1019
  }
1020

1021
  stb = taosHashIterate(pUser->readViews, NULL);
6,197✔
1022
  while (stb != NULL) {
6,304✔
1023
    size_t keyLen = 0;
107✔
1024
    void  *key = taosHashGetKey(stb, &keyLen);
107✔
1025
    size += sizeof(int32_t);
107✔
1026
    size += keyLen;
107✔
1027

1028
    size_t valueLen = 0;
107✔
1029
    valueLen = strlen(stb) + 1;
107✔
1030
    size += sizeof(int32_t);
107✔
1031
    size += valueLen;
107✔
1032
    stb = taosHashIterate(pUser->readViews, stb);
107✔
1033
  }
1034

1035
  stb = taosHashIterate(pUser->writeViews, NULL);
6,197✔
1036
  while (stb != NULL) {
6,288✔
1037
    size_t keyLen = 0;
91✔
1038
    void  *key = taosHashGetKey(stb, &keyLen);
91✔
1039
    size += sizeof(int32_t);
91✔
1040
    size += keyLen;
91✔
1041

1042
    size_t valueLen = 0;
91✔
1043
    valueLen = strlen(stb) + 1;
91✔
1044
    size += sizeof(int32_t);
91✔
1045
    size += valueLen;
91✔
1046
    stb = taosHashIterate(pUser->writeViews, stb);
91✔
1047
  }
1048

1049
  stb = taosHashIterate(pUser->alterViews, NULL);
6,197✔
1050
  while (stb != NULL) {
6,292✔
1051
    size_t keyLen = 0;
95✔
1052
    void  *key = taosHashGetKey(stb, &keyLen);
95✔
1053
    size += sizeof(int32_t);
95✔
1054
    size += keyLen;
95✔
1055

1056
    size_t valueLen = 0;
95✔
1057
    valueLen = strlen(stb) + 1;
95✔
1058
    size += sizeof(int32_t);
95✔
1059
    size += valueLen;
95✔
1060
    stb = taosHashIterate(pUser->alterViews, stb);
95✔
1061
  }
1062

1063
  int32_t *useDb = taosHashIterate(pUser->useDbs, NULL);
6,197✔
1064
  while (useDb != NULL) {
6,408✔
1065
    size_t keyLen = 0;
211✔
1066
    void  *key = taosHashGetKey(useDb, &keyLen);
211✔
1067
    size += sizeof(int32_t);
211✔
1068
    size += keyLen;
211✔
1069
    size += sizeof(int32_t);
211✔
1070
    useDb = taosHashIterate(pUser->useDbs, useDb);
211✔
1071
  }
1072

1073
  pRaw = sdbAllocRaw(SDB_USER, USER_VER_NUMBER, size);
6,197✔
1074
  if (pRaw == NULL) {
6,197!
1075
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1076
  }
1077

1078
  int32_t dataPos = 0;
6,197✔
1079
  SDB_SET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN, _OVER)
6,197!
1080
  SDB_SET_BINARY(pRaw, dataPos, pUser->pass, TSDB_PASSWORD_LEN, _OVER)
6,197!
1081
  SDB_SET_BINARY(pRaw, dataPos, pUser->acct, TSDB_USER_LEN, _OVER)
6,197!
1082
  SDB_SET_INT64(pRaw, dataPos, pUser->createdTime, _OVER)
6,197!
1083
  SDB_SET_INT64(pRaw, dataPos, pUser->updateTime, _OVER)
6,197!
1084
  SDB_SET_INT8(pRaw, dataPos, pUser->superUser, _OVER)
6,197!
1085
  SDB_SET_INT8(pRaw, dataPos, pUser->sysInfo, _OVER)
6,197!
1086
  SDB_SET_INT8(pRaw, dataPos, pUser->enable, _OVER)
6,197!
1087
  SDB_SET_UINT8(pRaw, dataPos, pUser->flag, _OVER)
6,197!
1088
  SDB_SET_INT32(pRaw, dataPos, pUser->authVersion, _OVER)
6,197!
1089
  SDB_SET_INT32(pRaw, dataPos, pUser->passVersion, _OVER)
6,197!
1090
  SDB_SET_INT32(pRaw, dataPos, numOfReadDbs, _OVER)
6,197!
1091
  SDB_SET_INT32(pRaw, dataPos, numOfWriteDbs, _OVER)
6,197!
1092
  SDB_SET_INT32(pRaw, dataPos, numOfTopics, _OVER)
6,197!
1093

1094
  char *db = taosHashIterate(pUser->readDbs, NULL);
6,197✔
1095
  while (db != NULL) {
6,336✔
1096
    SDB_SET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER);
139!
1097
    db = taosHashIterate(pUser->readDbs, db);
139✔
1098
  }
1099

1100
  db = taosHashIterate(pUser->writeDbs, NULL);
6,197✔
1101
  while (db != NULL) {
6,330✔
1102
    SDB_SET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER);
133!
1103
    db = taosHashIterate(pUser->writeDbs, db);
133✔
1104
  }
1105

1106
  char *topic = taosHashIterate(pUser->topics, NULL);
6,197✔
1107
  while (topic != NULL) {
6,234✔
1108
    SDB_SET_BINARY(pRaw, dataPos, topic, TSDB_TOPIC_FNAME_LEN, _OVER);
37!
1109
    topic = taosHashIterate(pUser->topics, topic);
37✔
1110
  }
1111

1112
  SDB_SET_INT32(pRaw, dataPos, numOfReadTbs, _OVER)
6,197!
1113
  SDB_SET_INT32(pRaw, dataPos, numOfWriteTbs, _OVER)
6,197!
1114
  SDB_SET_INT32(pRaw, dataPos, numOfAlterTbs, _OVER)
6,197!
1115
  SDB_SET_INT32(pRaw, dataPos, numOfReadViews, _OVER)
6,197!
1116
  SDB_SET_INT32(pRaw, dataPos, numOfWriteViews, _OVER)
6,197!
1117
  SDB_SET_INT32(pRaw, dataPos, numOfAlterViews, _OVER)
6,197!
1118
  SDB_SET_INT32(pRaw, dataPos, numOfUseDbs, _OVER)
6,197!
1119

1120
  stb = taosHashIterate(pUser->readTbs, NULL);
6,197✔
1121
  while (stb != NULL) {
6,254✔
1122
    size_t keyLen = 0;
57✔
1123
    void  *key = taosHashGetKey(stb, &keyLen);
57✔
1124
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
57!
1125
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
57!
1126

1127
    size_t valueLen = 0;
57✔
1128
    valueLen = strlen(stb) + 1;
57✔
1129
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
57!
1130
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
57!
1131
    stb = taosHashIterate(pUser->readTbs, stb);
57✔
1132
  }
1133

1134
  stb = taosHashIterate(pUser->writeTbs, NULL);
6,197✔
1135
  while (stb != NULL) {
6,266✔
1136
    size_t keyLen = 0;
69✔
1137
    void  *key = taosHashGetKey(stb, &keyLen);
69✔
1138
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
69!
1139
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
69!
1140

1141
    size_t valueLen = 0;
69✔
1142
    valueLen = strlen(stb) + 1;
69✔
1143
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
69!
1144
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
69!
1145
    stb = taosHashIterate(pUser->writeTbs, stb);
69✔
1146
  }
1147

1148
  stb = taosHashIterate(pUser->alterTbs, NULL);
6,197✔
1149
  while (stb != NULL) {
6,214✔
1150
    size_t keyLen = 0;
17✔
1151
    void  *key = taosHashGetKey(stb, &keyLen);
17✔
1152
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
17!
1153
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
17!
1154

1155
    size_t valueLen = 0;
17✔
1156
    valueLen = strlen(stb) + 1;
17✔
1157
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
17!
1158
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
17!
1159
    stb = taosHashIterate(pUser->alterTbs, stb);
17✔
1160
  }
1161

1162
  stb = taosHashIterate(pUser->readViews, NULL);
6,197✔
1163
  while (stb != NULL) {
6,304✔
1164
    size_t keyLen = 0;
107✔
1165
    void  *key = taosHashGetKey(stb, &keyLen);
107✔
1166
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
107!
1167
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
107!
1168

1169
    size_t valueLen = 0;
107✔
1170
    valueLen = strlen(stb) + 1;
107✔
1171
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
107!
1172
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
107!
1173
    stb = taosHashIterate(pUser->readViews, stb);
107✔
1174
  }
1175

1176
  stb = taosHashIterate(pUser->writeViews, NULL);
6,197✔
1177
  while (stb != NULL) {
6,288✔
1178
    size_t keyLen = 0;
91✔
1179
    void  *key = taosHashGetKey(stb, &keyLen);
91✔
1180
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
91!
1181
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
91!
1182

1183
    size_t valueLen = 0;
91✔
1184
    valueLen = strlen(stb) + 1;
91✔
1185
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
91!
1186
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
91!
1187
    stb = taosHashIterate(pUser->writeViews, stb);
91✔
1188
  }
1189

1190
  stb = taosHashIterate(pUser->alterViews, NULL);
6,197✔
1191
  while (stb != NULL) {
6,292✔
1192
    size_t keyLen = 0;
95✔
1193
    void  *key = taosHashGetKey(stb, &keyLen);
95✔
1194
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
95!
1195
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
95!
1196

1197
    size_t valueLen = 0;
95✔
1198
    valueLen = strlen(stb) + 1;
95✔
1199
    SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER)
95!
1200
    SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER);
95!
1201
    stb = taosHashIterate(pUser->alterViews, stb);
95✔
1202
  }
1203

1204
  useDb = taosHashIterate(pUser->useDbs, NULL);
6,197✔
1205
  while (useDb != NULL) {
6,408✔
1206
    size_t keyLen = 0;
211✔
1207
    void  *key = taosHashGetKey(useDb, &keyLen);
211✔
1208
    SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER)
211!
1209
    SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
211!
1210

1211
    SDB_SET_INT32(pRaw, dataPos, *useDb, _OVER)
211!
1212
    useDb = taosHashIterate(pUser->useDbs, useDb);
211✔
1213
  }
1214

1215
  // save white list
1216
  int32_t num = pUser->pIpWhiteListDual->num;
6,197✔
1217
  int32_t tlen = sizeof(SIpWhiteListDual) + num * sizeof(SIpRange) + 4;
6,197✔
1218
  if ((buf = taosMemoryCalloc(1, tlen)) == NULL) {
6,197!
1219
    TAOS_CHECK_GOTO(terrno, NULL, _OVER);
×
1220
  }
1221
  int32_t len = 0;
6,197✔
1222
  TAOS_CHECK_GOTO(tSerializeIpWhiteList(buf, tlen, pUser->pIpWhiteListDual, &len), &lino, _OVER);
6,197!
1223

1224
  SDB_SET_INT32(pRaw, dataPos, len, _OVER);
6,197!
1225
  SDB_SET_BINARY(pRaw, dataPos, buf, len, _OVER);
6,197!
1226

1227
  SDB_SET_INT64(pRaw, dataPos, pUser->ipWhiteListVer, _OVER);
6,197!
1228
  SDB_SET_INT8(pRaw, dataPos, pUser->passEncryptAlgorithm, _OVER);
6,197!
1229

1230
  SDB_SET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
6,197!
1231
  SDB_SET_DATALEN(pRaw, dataPos, _OVER)
6,197!
1232

1233
_OVER:
6,197✔
1234
  taosMemoryFree(buf);
6,197!
1235
  if (code < 0) {
6,197!
1236
    mError("user:%s, failed to encode user action to raw:%p at line %d since %s", pUser->user, pRaw, lino,
×
1237
           tstrerror(code));
1238
    sdbFreeRaw(pRaw);
×
1239
    pRaw = NULL;
×
1240
    terrno = code;
×
1241
  }
1242

1243
  mTrace("user:%s, encode user action to raw:%p, row:%p", pUser->user, pRaw, pUser);
6,197✔
1244
  return pRaw;
6,197✔
1245
}
1246

1247
static SSdbRow *mndUserActionDecode(SSdbRaw *pRaw) {
2,837✔
1248
  int32_t   code = 0;
2,837✔
1249
  int32_t   lino = 0;
2,837✔
1250
  SSdbRow  *pRow = NULL;
2,837✔
1251
  SUserObj *pUser = NULL;
2,837✔
1252
  char     *key = NULL;
2,837✔
1253
  char     *value = NULL;
2,837✔
1254

1255
  int8_t sver = 0;
2,837✔
1256
  if (sdbGetRawSoftVer(pRaw, &sver) != 0) {
2,837!
1257
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_PTR, &lino, _OVER);
×
1258
  }
1259

1260
  if (sver < 1 || sver > USER_VER_NUMBER) {
2,837!
1261
    TAOS_CHECK_GOTO(TSDB_CODE_SDB_INVALID_DATA_VER, &lino, _OVER);
×
1262
  }
1263

1264
  pRow = sdbAllocRow(sizeof(SUserObj));
2,837✔
1265
  if (pRow == NULL) {
2,837!
1266
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1267
  }
1268

1269
  pUser = sdbGetRowObj(pRow);
2,837✔
1270
  if (pUser == NULL) {
2,837!
1271
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1272
  }
1273

1274
  int32_t dataPos = 0;
2,837✔
1275
  SDB_GET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN, _OVER)
2,837!
1276
  SDB_GET_BINARY(pRaw, dataPos, pUser->pass, TSDB_PASSWORD_LEN, _OVER)
2,837!
1277
  SDB_GET_BINARY(pRaw, dataPos, pUser->acct, TSDB_USER_LEN, _OVER)
2,837!
1278
  SDB_GET_INT64(pRaw, dataPos, &pUser->createdTime, _OVER)
2,837!
1279
  SDB_GET_INT64(pRaw, dataPos, &pUser->updateTime, _OVER)
2,837!
1280
  SDB_GET_INT8(pRaw, dataPos, &pUser->superUser, _OVER)
2,837!
1281
  SDB_GET_INT8(pRaw, dataPos, &pUser->sysInfo, _OVER)
2,837!
1282
  SDB_GET_INT8(pRaw, dataPos, &pUser->enable, _OVER)
2,837!
1283
  SDB_GET_UINT8(pRaw, dataPos, &pUser->flag, _OVER)
2,837!
1284
  if (pUser->superUser) pUser->createdb = 1;
2,837✔
1285
  SDB_GET_INT32(pRaw, dataPos, &pUser->authVersion, _OVER)
2,837!
1286
  if (sver >= 4) {
2,837!
1287
    SDB_GET_INT32(pRaw, dataPos, &pUser->passVersion, _OVER)
2,837!
1288
  }
1289

1290
  int32_t numOfReadDbs = 0;
2,837✔
1291
  int32_t numOfWriteDbs = 0;
2,837✔
1292
  int32_t numOfTopics = 0;
2,837✔
1293
  SDB_GET_INT32(pRaw, dataPos, &numOfReadDbs, _OVER)
2,837!
1294
  SDB_GET_INT32(pRaw, dataPos, &numOfWriteDbs, _OVER)
2,837!
1295
  if (sver >= 2) {
2,837!
1296
    SDB_GET_INT32(pRaw, dataPos, &numOfTopics, _OVER)
2,837!
1297
  }
1298

1299
  pUser->readDbs = taosHashInit(numOfReadDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
2,837✔
1300
  pUser->writeDbs =
2,837✔
1301
      taosHashInit(numOfWriteDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
2,837✔
1302
  pUser->topics = taosHashInit(numOfTopics, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
2,837✔
1303
  if (pUser->readDbs == NULL || pUser->writeDbs == NULL || pUser->topics == NULL) {
2,837!
1304
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1305
    goto _OVER;
×
1306
  }
1307

1308
  for (int32_t i = 0; i < numOfReadDbs; ++i) {
2,958✔
1309
    char db[TSDB_DB_FNAME_LEN] = {0};
121✔
1310
    SDB_GET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER)
121!
1311
    int32_t len = strlen(db) + 1;
121✔
1312
    TAOS_CHECK_GOTO(taosHashPut(pUser->readDbs, db, len, db, TSDB_DB_FNAME_LEN), &lino, _OVER);
121!
1313
  }
1314

1315
  for (int32_t i = 0; i < numOfWriteDbs; ++i) {
2,951✔
1316
    char db[TSDB_DB_FNAME_LEN] = {0};
114✔
1317
    SDB_GET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER)
114!
1318
    int32_t len = strlen(db) + 1;
114✔
1319
    TAOS_CHECK_GOTO(taosHashPut(pUser->writeDbs, db, len, db, TSDB_DB_FNAME_LEN), &lino, _OVER);
114!
1320
  }
1321

1322
  if (sver >= 2) {
2,837!
1323
    for (int32_t i = 0; i < numOfTopics; ++i) {
2,871✔
1324
      char topic[TSDB_TOPIC_FNAME_LEN] = {0};
34✔
1325
      SDB_GET_BINARY(pRaw, dataPos, topic, TSDB_TOPIC_FNAME_LEN, _OVER)
34!
1326
      int32_t len = strlen(topic) + 1;
34✔
1327
      TAOS_CHECK_GOTO(taosHashPut(pUser->topics, topic, len, topic, TSDB_TOPIC_FNAME_LEN), &lino, _OVER);
34!
1328
    }
1329
  }
1330

1331
  if (sver >= 3) {
2,837!
1332
    int32_t numOfReadTbs = 0;
2,837✔
1333
    int32_t numOfWriteTbs = 0;
2,837✔
1334
    int32_t numOfAlterTbs = 0;
2,837✔
1335
    int32_t numOfReadViews = 0;
2,837✔
1336
    int32_t numOfWriteViews = 0;
2,837✔
1337
    int32_t numOfAlterViews = 0;
2,837✔
1338
    int32_t numOfUseDbs = 0;
2,837✔
1339
    SDB_GET_INT32(pRaw, dataPos, &numOfReadTbs, _OVER)
2,837!
1340
    SDB_GET_INT32(pRaw, dataPos, &numOfWriteTbs, _OVER)
2,837!
1341
    if (sver >= 6) {
2,837!
1342
      SDB_GET_INT32(pRaw, dataPos, &numOfAlterTbs, _OVER)
2,837!
1343
      SDB_GET_INT32(pRaw, dataPos, &numOfReadViews, _OVER)
2,837!
1344
      SDB_GET_INT32(pRaw, dataPos, &numOfWriteViews, _OVER)
2,837!
1345
      SDB_GET_INT32(pRaw, dataPos, &numOfAlterViews, _OVER)
2,837!
1346
    }
1347
    SDB_GET_INT32(pRaw, dataPos, &numOfUseDbs, _OVER)
2,837!
1348

1349
    pUser->readTbs =
2,837✔
1350
        taosHashInit(numOfReadTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
2,837✔
1351
    pUser->writeTbs =
2,837✔
1352
        taosHashInit(numOfWriteTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
2,837✔
1353
    pUser->alterTbs =
2,837✔
1354
        taosHashInit(numOfAlterTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
2,837✔
1355

1356
    pUser->readViews =
2,837✔
1357
        taosHashInit(numOfReadViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
2,837✔
1358
    pUser->writeViews =
2,837✔
1359
        taosHashInit(numOfWriteViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
2,837✔
1360
    pUser->alterViews =
2,837✔
1361
        taosHashInit(numOfAlterViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
2,837✔
1362

1363
    pUser->useDbs = taosHashInit(numOfUseDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
2,837✔
1364

1365
    if (pUser->readTbs == NULL || pUser->writeTbs == NULL || pUser->alterTbs == NULL || pUser->readViews == NULL ||
2,837!
1366
        pUser->writeViews == NULL || pUser->alterViews == NULL || pUser->useDbs == NULL) {
2,837!
1367
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1368
      goto _OVER;
×
1369
    }
1370

1371
    for (int32_t i = 0; i < numOfReadTbs; ++i) {
2,871✔
1372
      int32_t keyLen = 0;
34✔
1373
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
34!
1374

1375
      TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
34!
1376
      if (key == NULL) {
34!
1377
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1378
      }
1379
      (void)memset(key, 0, keyLen);
34✔
1380
      SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
34!
1381

1382
      int32_t valuelen = 0;
34✔
1383
      SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
34!
1384
      TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
34!
1385
      if (value == NULL) {
34!
1386
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1387
      }
1388
      (void)memset(value, 0, valuelen);
34✔
1389
      SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
34!
1390

1391
      TAOS_CHECK_GOTO(taosHashPut(pUser->readTbs, key, keyLen, value, valuelen), &lino, _OVER);
34!
1392
    }
1393

1394
    for (int32_t i = 0; i < numOfWriteTbs; ++i) {
2,877✔
1395
      int32_t keyLen = 0;
40✔
1396
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
40!
1397

1398
      TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
40!
1399
      if (key == NULL) {
40!
1400
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1401
      }
1402
      (void)memset(key, 0, keyLen);
40✔
1403
      SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
40!
1404

1405
      int32_t valuelen = 0;
40✔
1406
      SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
40!
1407
      TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
40!
1408
      if (value == NULL) {
40!
1409
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1410
      }
1411
      (void)memset(value, 0, valuelen);
40✔
1412
      SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
40!
1413

1414
      TAOS_CHECK_GOTO(taosHashPut(pUser->writeTbs, key, keyLen, value, valuelen), &lino, _OVER);
40!
1415
    }
1416

1417
    if (sver >= 6) {
2,837!
1418
      for (int32_t i = 0; i < numOfAlterTbs; ++i) {
2,853✔
1419
        int32_t keyLen = 0;
16✔
1420
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
16!
1421

1422
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
16!
1423
        if (key == NULL) {
16!
1424
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1425
        }
1426
        (void)memset(key, 0, keyLen);
16✔
1427
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
16!
1428

1429
        int32_t valuelen = 0;
16✔
1430
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
16!
1431
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
16!
1432
        if (value == NULL) {
16!
1433
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1434
        }
1435
        (void)memset(value, 0, valuelen);
16✔
1436
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
16!
1437

1438
        TAOS_CHECK_GOTO(taosHashPut(pUser->alterTbs, key, keyLen, value, valuelen), &lino, _OVER);
16!
1439
      }
1440

1441
      for (int32_t i = 0; i < numOfReadViews; ++i) {
2,941✔
1442
        int32_t keyLen = 0;
104✔
1443
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
104!
1444

1445
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
104!
1446
        if (key == NULL) {
104!
1447
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1448
        }
1449
        (void)memset(key, 0, keyLen);
104✔
1450
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
104!
1451

1452
        int32_t valuelen = 0;
104✔
1453
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
104!
1454
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
104!
1455
        if (value == NULL) {
104!
1456
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1457
        }
1458
        (void)memset(value, 0, valuelen);
104✔
1459
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
104!
1460

1461
        TAOS_CHECK_GOTO(taosHashPut(pUser->readViews, key, keyLen, value, valuelen), &lino, _OVER);
104!
1462
      }
1463

1464
      for (int32_t i = 0; i < numOfWriteViews; ++i) {
2,925✔
1465
        int32_t keyLen = 0;
88✔
1466
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
88!
1467

1468
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
88!
1469
        if (key == NULL) {
88!
1470
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1471
        }
1472
        (void)memset(key, 0, keyLen);
88✔
1473
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
88!
1474

1475
        int32_t valuelen = 0;
88✔
1476
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
88!
1477
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
88!
1478
        if (value == NULL) {
88!
1479
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1480
        }
1481
        (void)memset(value, 0, valuelen);
88✔
1482
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
88!
1483

1484
        TAOS_CHECK_GOTO(taosHashPut(pUser->writeViews, key, keyLen, value, valuelen), &lino, _OVER);
88!
1485
      }
1486

1487
      for (int32_t i = 0; i < numOfAlterViews; ++i) {
2,929✔
1488
        int32_t keyLen = 0;
92✔
1489
        SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
92!
1490

1491
        TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
92!
1492
        if (key == NULL) {
92!
1493
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1494
        }
1495
        (void)memset(key, 0, keyLen);
92✔
1496
        SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
92!
1497

1498
        int32_t valuelen = 0;
92✔
1499
        SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER);
92!
1500
        TAOS_MEMORY_REALLOC(value, valuelen * sizeof(char));
92!
1501
        if (value == NULL) {
92!
1502
          TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1503
        }
1504
        (void)memset(value, 0, valuelen);
92✔
1505
        SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER)
92!
1506

1507
        TAOS_CHECK_GOTO(taosHashPut(pUser->alterViews, key, keyLen, value, valuelen), &lino, _OVER);
92!
1508
      }
1509
    }
1510

1511
    for (int32_t i = 0; i < numOfUseDbs; ++i) {
2,995✔
1512
      int32_t keyLen = 0;
158✔
1513
      SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER);
158!
1514

1515
      TAOS_MEMORY_REALLOC(key, keyLen * sizeof(char));
158!
1516
      if (key == NULL) {
158!
1517
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1518
      }
1519
      (void)memset(key, 0, keyLen);
158✔
1520
      SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
158!
1521

1522
      int32_t ref = 0;
158✔
1523
      SDB_GET_INT32(pRaw, dataPos, &ref, _OVER);
158!
1524

1525
      TAOS_CHECK_GOTO(taosHashPut(pUser->useDbs, key, keyLen, &ref, sizeof(ref)), &lino, _OVER);
158!
1526
    }
1527
  }
1528
  // decoder white list
1529
  if (sver >= USER_VER_SUPPORT_WHITELIST) {
2,837!
1530
    if (sver < USER_VER_SUPPORT_WHITELIT_DUAL_STACK) {
2,837!
1531
      int32_t len = 0;
×
1532
      SDB_GET_INT32(pRaw, dataPos, &len, _OVER);
×
1533

1534
      TAOS_MEMORY_REALLOC(key, len);
×
1535
      if (key == NULL) {
×
1536
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1537
      }
1538
      SDB_GET_BINARY(pRaw, dataPos, key, len, _OVER);
×
1539

1540
      SIpWhiteList *pIpWhiteList = NULL;
×
1541
      TAOS_CHECK_GOTO(createIpWhiteListFromOldVer(key, len, &pIpWhiteList), &lino, _OVER);
×
1542

1543
      SDB_GET_INT64(pRaw, dataPos, &pUser->ipWhiteListVer, _OVER);
×
1544

1545
      code = cvtIpWhiteListToDual(pIpWhiteList, &pUser->pIpWhiteListDual);
×
1546
      if (code != 0) {
×
1547
        taosMemoryFreeClear(pIpWhiteList);
×
1548
      }
1549
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
1550

1551
      taosMemoryFreeClear(pIpWhiteList);
×
1552

1553
    } else if (sver >= USER_VER_SUPPORT_WHITELIT_DUAL_STACK) {
2,837!
1554
      int32_t len = 0;
2,837✔
1555
      SDB_GET_INT32(pRaw, dataPos, &len, _OVER);
2,837!
1556

1557
      TAOS_MEMORY_REALLOC(key, len);
2,837!
1558
      if (key == NULL) {
2,837!
1559
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1560
      }
1561
      SDB_GET_BINARY(pRaw, dataPos, key, len, _OVER);
2,837!
1562

1563
      TAOS_CHECK_GOTO(createIpWhiteList(key, len, &pUser->pIpWhiteListDual), &lino, _OVER);
2,837!
1564
      SDB_GET_INT64(pRaw, dataPos, &pUser->ipWhiteListVer, _OVER);
2,837!
1565
    }
1566
  }
1567

1568
  if (pUser->pIpWhiteListDual == NULL) {
2,837!
1569
    TAOS_CHECK_GOTO(createDefaultIpWhiteList(&pUser->pIpWhiteListDual), &lino, _OVER);
×
1570
    pUser->ipWhiteListVer = taosGetTimestampMs();
×
1571
  }
1572

1573
  SDB_GET_INT8(pRaw, dataPos, &pUser->passEncryptAlgorithm, _OVER);
2,837!
1574

1575
  SDB_GET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
2,837!
1576
  taosInitRWLatch(&pUser->lock);
2,837✔
1577

1578
_OVER:
2,837✔
1579
  taosMemoryFree(key);
2,837!
1580
  taosMemoryFree(value);
2,837!
1581
  if (code < 0) {
2,837!
1582
    terrno = code;
×
1583
    mError("user:%s, failed to decode at line %d from raw:%p since %s", pUser == NULL ? "null" : pUser->user, lino,
×
1584
           pRaw, tstrerror(code));
1585
    if (pUser != NULL) {
×
1586
      taosHashCleanup(pUser->readDbs);
×
1587
      taosHashCleanup(pUser->writeDbs);
×
1588
      taosHashCleanup(pUser->topics);
×
1589
      taosHashCleanup(pUser->readTbs);
×
1590
      taosHashCleanup(pUser->writeTbs);
×
1591
      taosHashCleanup(pUser->alterTbs);
×
1592
      taosHashCleanup(pUser->readViews);
×
1593
      taosHashCleanup(pUser->writeViews);
×
1594
      taosHashCleanup(pUser->alterViews);
×
1595
      taosHashCleanup(pUser->useDbs);
×
1596
      taosMemoryFreeClear(pUser->pIpWhiteListDual);
×
1597
    }
1598
    taosMemoryFreeClear(pRow);
×
1599
    return NULL;
×
1600
  }
1601

1602
  mTrace("user:%s, decode from raw:%p, row:%p", pUser->user, pRaw, pUser);
2,837✔
1603
  return pRow;
2,837✔
1604
}
1605

1606
static int32_t mndUserActionInsert(SSdb *pSdb, SUserObj *pUser) {
2,384✔
1607
  mTrace("user:%s, perform insert action, row:%p", pUser->user, pUser);
2,384✔
1608

1609
  SAcctObj *pAcct = sdbAcquire(pSdb, SDB_ACCT, pUser->acct);
2,384✔
1610
  if (pAcct == NULL) {
2,384!
1611
    terrno = TSDB_CODE_MND_ACCT_NOT_EXIST;
×
1612
    mError("user:%s, failed to perform insert action since %s", pUser->user, terrstr());
×
1613
    TAOS_RETURN(terrno);
×
1614
  }
1615
  pUser->acctId = pAcct->acctId;
2,384✔
1616
  sdbRelease(pSdb, pAcct);
2,384✔
1617

1618
  return 0;
2,384✔
1619
}
1620

1621
int32_t mndDupTableHash(SHashObj *pOld, SHashObj **ppNew) {
212,590✔
1622
  int32_t code = 0;
212,590✔
1623
  *ppNew =
212,590✔
1624
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
212,590✔
1625
  if (*ppNew == NULL) {
212,590!
1626
    TAOS_RETURN(terrno);
×
1627
  }
1628

1629
  char *tb = taosHashIterate(pOld, NULL);
212,590✔
1630
  while (tb != NULL) {
213,813✔
1631
    size_t keyLen = 0;
1,223✔
1632
    char  *key = taosHashGetKey(tb, &keyLen);
1,223✔
1633

1634
    int32_t valueLen = strlen(tb) + 1;
1,223✔
1635
    if ((code = taosHashPut(*ppNew, key, keyLen, tb, valueLen)) != 0) {
1,223!
1636
      taosHashCancelIterate(pOld, tb);
×
1637
      taosHashCleanup(*ppNew);
×
1638
      TAOS_RETURN(code);
×
1639
    }
1640
    tb = taosHashIterate(pOld, tb);
1,223✔
1641
  }
1642

1643
  TAOS_RETURN(code);
212,590✔
1644
}
1645

1646
int32_t mndDupUseDbHash(SHashObj *pOld, SHashObj **ppNew) {
6,370✔
1647
  int32_t code = 0;
6,370✔
1648
  *ppNew =
6,370✔
1649
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
6,370✔
1650
  if (*ppNew == NULL) {
6,370!
1651
    TAOS_RETURN(terrno);
×
1652
  }
1653

1654
  int32_t *db = taosHashIterate(pOld, NULL);
6,370✔
1655
  while (db != NULL) {
6,730✔
1656
    size_t keyLen = 0;
360✔
1657
    char  *key = taosHashGetKey(db, &keyLen);
360✔
1658

1659
    if ((code = taosHashPut(*ppNew, key, keyLen, db, sizeof(*db))) != 0) {
360!
1660
      taosHashCancelIterate(pOld, db);
×
1661
      taosHashCleanup(*ppNew);
×
1662
      TAOS_RETURN(code);
×
1663
    }
1664
    db = taosHashIterate(pOld, db);
360✔
1665
  }
1666

1667
  TAOS_RETURN(code);
6,370✔
1668
}
1669

1670
int32_t mndUserDupObj(SUserObj *pUser, SUserObj *pNew) {
6,370✔
1671
  int32_t code = 0;
6,370✔
1672
  (void)memcpy(pNew, pUser, sizeof(SUserObj));
6,370✔
1673
  pNew->authVersion++;
6,370✔
1674
  pNew->updateTime = taosGetTimestampMs();
6,370✔
1675

1676
  taosRLockLatch(&pUser->lock);
6,370✔
1677
  TAOS_CHECK_GOTO(mndDupDbHash(pUser->readDbs, &pNew->readDbs), NULL, _OVER);
6,370!
1678
  TAOS_CHECK_GOTO(mndDupDbHash(pUser->writeDbs, &pNew->writeDbs), NULL, _OVER);
6,370!
1679
  TAOS_CHECK_GOTO(mndDupTableHash(pUser->readTbs, &pNew->readTbs), NULL, _OVER);
6,370!
1680
  TAOS_CHECK_GOTO(mndDupTableHash(pUser->writeTbs, &pNew->writeTbs), NULL, _OVER);
6,370!
1681
  TAOS_CHECK_GOTO(mndDupTableHash(pUser->alterTbs, &pNew->alterTbs), NULL, _OVER);
6,370!
1682
  TAOS_CHECK_GOTO(mndDupTableHash(pUser->readViews, &pNew->readViews), NULL, _OVER);
6,370!
1683
  TAOS_CHECK_GOTO(mndDupTableHash(pUser->writeViews, &pNew->writeViews), NULL, _OVER);
6,370!
1684
  TAOS_CHECK_GOTO(mndDupTableHash(pUser->alterViews, &pNew->alterViews), NULL, _OVER);
6,370!
1685
  TAOS_CHECK_GOTO(mndDupTopicHash(pUser->topics, &pNew->topics), NULL, _OVER);
6,370!
1686
  TAOS_CHECK_GOTO(mndDupUseDbHash(pUser->useDbs, &pNew->useDbs), NULL, _OVER);
6,370!
1687
  pNew->pIpWhiteListDual = cloneIpWhiteList(pUser->pIpWhiteListDual);
6,370✔
1688
  if (pNew->pIpWhiteListDual == NULL) {
6,370!
1689
    code = TSDB_CODE_OUT_OF_MEMORY;
×
1690
  }
1691

1692
_OVER:
6,370✔
1693
  taosRUnLockLatch(&pUser->lock);
6,370✔
1694
  TAOS_RETURN(code);
6,370✔
1695
}
1696

1697
void mndUserFreeObj(SUserObj *pUser) {
19,538✔
1698
  taosHashCleanup(pUser->readDbs);
19,538✔
1699
  taosHashCleanup(pUser->writeDbs);
19,538✔
1700
  taosHashCleanup(pUser->topics);
19,538✔
1701
  taosHashCleanup(pUser->readTbs);
19,538✔
1702
  taosHashCleanup(pUser->writeTbs);
19,538✔
1703
  taosHashCleanup(pUser->alterTbs);
19,538✔
1704
  taosHashCleanup(pUser->readViews);
19,538✔
1705
  taosHashCleanup(pUser->writeViews);
19,538✔
1706
  taosHashCleanup(pUser->alterViews);
19,538✔
1707
  taosHashCleanup(pUser->useDbs);
19,538✔
1708
  taosMemoryFreeClear(pUser->pIpWhiteListDual);
19,538!
1709
  pUser->readDbs = NULL;
19,538✔
1710
  pUser->writeDbs = NULL;
19,538✔
1711
  pUser->topics = NULL;
19,538✔
1712
  pUser->readTbs = NULL;
19,538✔
1713
  pUser->writeTbs = NULL;
19,538✔
1714
  pUser->alterTbs = NULL;
19,538✔
1715
  pUser->readViews = NULL;
19,538✔
1716
  pUser->writeViews = NULL;
19,538✔
1717
  pUser->alterViews = NULL;
19,538✔
1718
  pUser->useDbs = NULL;
19,538✔
1719
}
19,538✔
1720

1721
static int32_t mndUserActionDelete(SSdb *pSdb, SUserObj *pUser) {
2,836✔
1722
  mTrace("user:%s, perform delete action, row:%p", pUser->user, pUser);
2,836✔
1723
  mndUserFreeObj(pUser);
2,836✔
1724
  return 0;
2,836✔
1725
}
1726

1727
static int32_t mndUserActionUpdate(SSdb *pSdb, SUserObj *pOld, SUserObj *pNew) {
344✔
1728
  mTrace("user:%s, perform update action, old row:%p new row:%p", pOld->user, pOld, pNew);
344!
1729
  taosWLockLatch(&pOld->lock);
344✔
1730
  pOld->updateTime = pNew->updateTime;
344✔
1731
  pOld->authVersion = pNew->authVersion;
344✔
1732
  pOld->passVersion = pNew->passVersion;
344✔
1733
  pOld->sysInfo = pNew->sysInfo;
344✔
1734
  pOld->enable = pNew->enable;
344✔
1735
  pOld->flag = pNew->flag;
344✔
1736
  (void)memcpy(pOld->pass, pNew->pass, TSDB_PASSWORD_LEN);
344✔
1737
  TSWAP(pOld->readDbs, pNew->readDbs);
344✔
1738
  TSWAP(pOld->writeDbs, pNew->writeDbs);
344✔
1739
  TSWAP(pOld->topics, pNew->topics);
344✔
1740
  TSWAP(pOld->readTbs, pNew->readTbs);
344✔
1741
  TSWAP(pOld->writeTbs, pNew->writeTbs);
344✔
1742
  TSWAP(pOld->alterTbs, pNew->alterTbs);
344✔
1743
  TSWAP(pOld->readViews, pNew->readViews);
344✔
1744
  TSWAP(pOld->writeViews, pNew->writeViews);
344✔
1745
  TSWAP(pOld->alterViews, pNew->alterViews);
344✔
1746
  TSWAP(pOld->useDbs, pNew->useDbs);
344✔
1747

1748
  int32_t sz = sizeof(SIpWhiteListDual) + pNew->pIpWhiteListDual->num * sizeof(SIpRange);
344✔
1749
  TAOS_MEMORY_REALLOC(pOld->pIpWhiteListDual, sz);
344!
1750
  if (pOld->pIpWhiteListDual == NULL) {
344!
1751
    taosWUnLockLatch(&pOld->lock);
×
1752
    return terrno;
×
1753
  }
1754
  (void)memcpy(pOld->pIpWhiteListDual, pNew->pIpWhiteListDual, sz);
344✔
1755
  pOld->ipWhiteListVer = pNew->ipWhiteListVer;
344✔
1756

1757
  taosWUnLockLatch(&pOld->lock);
344✔
1758

1759
  return 0;
344✔
1760
}
1761

1762
int32_t mndAcquireUser(SMnode *pMnode, const char *userName, SUserObj **ppUser) {
303,418✔
1763
  int32_t code = 0;
303,418✔
1764
  SSdb   *pSdb = pMnode->pSdb;
303,418✔
1765

1766
  *ppUser = sdbAcquire(pSdb, SDB_USER, userName);
303,418✔
1767
  if (*ppUser == NULL) {
303,424✔
1768
    if (terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
218!
1769
      code = TSDB_CODE_MND_USER_NOT_EXIST;
218✔
1770
    } else {
1771
      code = TSDB_CODE_MND_USER_NOT_AVAILABLE;
×
1772
    }
1773
  }
1774
  TAOS_RETURN(code);
303,424✔
1775
}
1776

1777
void mndReleaseUser(SMnode *pMnode, SUserObj *pUser) {
303,925✔
1778
  SSdb *pSdb = pMnode->pSdb;
303,925✔
1779
  sdbRelease(pSdb, pUser);
303,925✔
1780
}
303,927✔
1781

1782
int32_t mndEncryptPass(char *pass, int8_t *algo) {
198✔
1783
  int32_t code = 0;
198✔
1784
  if (tsiEncryptPassAlgorithm == DND_CA_SM4) {
198!
1785
    if (strlen(tsEncryptKey) == 0) {
×
1786
      code = TSDB_CODE_DNODE_INVALID_ENCRYPTKEY;
×
1787
      goto _OVER;
×
1788
    }
1789
    unsigned char packetData[TSDB_PASSWORD_LEN] = {0};
×
1790
    int           newLen = 0;
×
1791

1792
    SCryptOpts opts = {0};
×
1793
    opts.len = TSDB_PASSWORD_LEN;
×
1794
    opts.source = pass;
×
1795
    opts.result = packetData;
×
1796
    opts.unitLen = TSDB_PASSWORD_LEN;
×
1797
    tstrncpy(opts.key, tsEncryptKey, ENCRYPT_KEY_LEN + 1);
×
1798

1799
    newLen = CBC_Encrypt(&opts);
×
1800

1801
    memcpy(pass, packetData, newLen);
×
1802

1803
    if (algo != NULL) *algo = DND_CA_SM4;
×
1804
  }
1805
_OVER:
198✔
1806
  return code;
198✔
1807
}
1808

1809
static int32_t addDefaultIpToTable(int8_t enableIpv6, SHashObj *pUniqueTab) {
3✔
1810
  int32_t code = 0;
3✔
1811
  int32_t lino = 0;
3✔
1812
  int32_t dummpy = 0;
3✔
1813

1814
  SIpRange ipv4 = {0}, ipv6 = {0};
3✔
1815
  code = createDefaultIp4Range(&ipv4);
3✔
1816
  TSDB_CHECK_CODE(code, lino, _error);
3!
1817

1818
  code = taosHashPut(pUniqueTab, &ipv4, sizeof(ipv4), &dummpy, sizeof(dummpy));
3✔
1819
  TSDB_CHECK_CODE(code, lino, _error);
3!
1820

1821
  if (enableIpv6) {
3!
1822
    code = createDefaultIp6Range(&ipv6);
×
1823
    TSDB_CHECK_CODE(code, lino, _error);
×
1824

1825
    code = taosHashPut(pUniqueTab, &ipv6, sizeof(ipv6), &dummpy, sizeof(dummpy));
×
1826
    TSDB_CHECK_CODE(code, lino, _error);
×
1827
  }
1828
_error:
3✔
1829
  if (code != 0) {
3!
1830
    mError("failed to add default ip range to table since %s", tstrerror(code));
×
1831
  }
1832
  return code;
3✔
1833
}
1834

1835
static int32_t mndCreateUser(SMnode *pMnode, char *acct, SCreateUserReq *pCreate, SRpcMsg *pReq) {
162✔
1836
  int32_t  code = 0;
162✔
1837
  int32_t  lino = 0;
162✔
1838
  SUserObj userObj = {0};
162✔
1839

1840
  if (pCreate->passIsMd5 == 1) {
162!
1841
    memcpy(userObj.pass, pCreate->pass, TSDB_PASSWORD_LEN - 1);
162✔
1842
    TAOS_CHECK_RETURN(mndEncryptPass(userObj.pass, &userObj.passEncryptAlgorithm));
162!
1843
  } else {
1844
    if (pCreate->isImport != 1) {
×
1845
      taosEncryptPass_c((uint8_t *)pCreate->pass, strlen(pCreate->pass), userObj.pass);
×
1846
      userObj.pass[TSDB_PASSWORD_LEN - 1] = 0;
×
1847
      TAOS_CHECK_RETURN(mndEncryptPass(userObj.pass, &userObj.passEncryptAlgorithm));
×
1848
    } else {
1849
      memcpy(userObj.pass, pCreate->pass, TSDB_PASSWORD_LEN);
×
1850
    }
1851
  }
1852

1853
  tstrncpy(userObj.user, pCreate->user, TSDB_USER_LEN);
162✔
1854
  tstrncpy(userObj.acct, acct, TSDB_USER_LEN);
162✔
1855
  userObj.createdTime = taosGetTimestampMs();
162✔
1856
  userObj.updateTime = userObj.createdTime;
162✔
1857
  userObj.superUser = 0;  // pCreate->superUser;
162✔
1858
  userObj.sysInfo = pCreate->sysInfo;
162✔
1859
  userObj.enable = pCreate->enable;
162✔
1860
  userObj.createdb = pCreate->createDb;
162✔
1861

1862
  if (pCreate->numIpRanges == 0) {
162✔
1863
    TAOS_CHECK_RETURN(createDefaultIpWhiteList(&userObj.pIpWhiteListDual));
159!
1864
  } else {
1865
    SHashObj *pUniqueTab = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
3✔
1866
    if (pUniqueTab == NULL) {
3!
1867
      TAOS_RETURN(terrno);
×
1868
    }
1869
    int32_t dummpy = 0;
3✔
1870
    for (int i = 0; i < pCreate->numIpRanges; i++) {
8✔
1871
      SIpRange range = {0};
5✔
1872
      if (pCreate->pIpDualRanges == NULL) {
5!
1873
        range.type = 0;
×
1874
        memcpy(&range.ipV4, &(pCreate->pIpRanges[i]), sizeof(SIpV4Range));
×
1875
      } else {
1876
        memcpy(&range, pCreate->pIpDualRanges + i, sizeof(SIpRange));
5✔
1877
      }
1878

1879
      if ((code = taosHashPut(pUniqueTab, &range, sizeof(range), &dummpy, sizeof(dummpy))) != 0) {
5!
1880
        taosHashCleanup(pUniqueTab);
×
1881
        TAOS_RETURN(code);
×
1882
      }
1883
    }
1884
    code = addDefaultIpToTable(tsEnableIpv6, pUniqueTab);
3✔
1885
    if (code != 0) {
3!
1886
      taosHashCleanup(pUniqueTab);
×
1887
      TAOS_RETURN(code);
×
1888
    }
1889

1890
    if (taosHashGetSize(pUniqueTab) > MND_MAX_USE_HOST) {
3!
1891
      taosHashCleanup(pUniqueTab);
×
1892
      TAOS_RETURN(TSDB_CODE_MND_TOO_MANY_USER_HOST);
×
1893
    }
1894

1895
    int32_t           numOfRanges = taosHashGetSize(pUniqueTab);
3✔
1896
    SIpWhiteListDual *p = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + numOfRanges * sizeof(SIpRange));
3!
1897
    if (p == NULL) {
3!
1898
      taosHashCleanup(pUniqueTab);
×
1899
      TAOS_RETURN(terrno);
×
1900
    }
1901
    void   *pIter = taosHashIterate(pUniqueTab, NULL);
3✔
1902
    int32_t i = 0;
3✔
1903
    while (pIter) {
10✔
1904
      size_t    len = 0;
7✔
1905
      SIpRange *key = taosHashGetKey(pIter, &len);
7✔
1906
      memcpy(p->pIpRanges + i, key, sizeof(SIpRange));
7✔
1907
      pIter = taosHashIterate(pUniqueTab, pIter);
7✔
1908
      i++;
7✔
1909
    }
1910

1911
    taosHashCleanup(pUniqueTab);
3✔
1912
    p->num = numOfRanges;
3✔
1913
    userObj.pIpWhiteListDual = p;
3✔
1914
  }
1915

1916
  userObj.ipWhiteListVer = taosGetTimestampMs();
162✔
1917

1918
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "create-user");
162✔
1919
  if (pTrans == NULL) {
162!
1920
    mError("user:%s, failed to create since %s", pCreate->user, terrstr());
×
1921
    taosMemoryFree(userObj.pIpWhiteListDual);
×
1922
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1923
  }
1924
  mInfo("trans:%d, used to create user:%s", pTrans->id, pCreate->user);
162!
1925

1926
  SSdbRaw *pCommitRaw = mndUserActionEncode(&userObj);
162✔
1927
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
162!
1928
    mError("trans:%d, failed to commit redo log since %s", pTrans->id, terrstr());
×
1929
    mndTransDrop(pTrans);
×
1930
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
1931
  }
1932
  TAOS_CHECK_GOTO(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY), &lino, _OVER);
162!
1933

1934
  if (mndTransPrepare(pMnode, pTrans) != 0) {
162!
1935
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
1936
    mndTransDrop(pTrans);
×
1937
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1938
  }
1939
  if ((code = ipWhiteMgtUpdate(pMnode, userObj.user, userObj.pIpWhiteListDual)) != 0) {
162!
1940
    mndTransDrop(pTrans);
×
1941
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
1942
  }
1943

1944
  taosMemoryFree(userObj.pIpWhiteListDual);
162!
1945
  mndTransDrop(pTrans);
162✔
1946
  return 0;
162✔
1947
_OVER:
×
1948
  taosMemoryFree(userObj.pIpWhiteListDual);
×
1949

1950
  TAOS_RETURN(code);
×
1951
}
1952

1953
static int32_t mndCheckPasswordMinLen(const char *pwd, int32_t len) {
×
1954
  if (len < TSDB_PASSWORD_MIN_LEN) {
×
1955
    return -1;
×
1956
  }
1957
  return 0;
×
1958
}
1959

1960
static int32_t mndCheckPasswordMaxLen(const char *pwd, int32_t len) {
×
1961
  if (len > TSDB_PASSWORD_MAX_LEN) {
×
1962
    return -1;
×
1963
  }
1964
  return 0;
×
1965
}
1966

1967
static int32_t mndCheckPasswordFmt(const char *pwd, int32_t len) {
×
1968
  if (strcmp(pwd, "taosdata") == 0) {
×
1969
    return 0;
×
1970
  }
1971

1972
  bool charTypes[4] = {0};
×
1973
  for (int32_t i = 0; i < len; ++i) {
×
1974
    if (taosIsBigChar(pwd[i])) {
×
1975
      charTypes[0] = true;
×
1976
    } else if (taosIsSmallChar(pwd[i])) {
×
1977
      charTypes[1] = true;
×
1978
    } else if (taosIsNumberChar(pwd[i])) {
×
1979
      charTypes[2] = true;
×
1980
    } else if (taosIsSpecialChar(pwd[i])) {
×
1981
      charTypes[3] = true;
×
1982
    } else {
1983
      return -1;
×
1984
    }
1985
  }
1986

1987
  int32_t numOfTypes = 0;
×
1988
  for (int32_t i = 0; i < 4; ++i) {
×
1989
    numOfTypes += charTypes[i];
×
1990
  }
1991

1992
  if (numOfTypes < 3) {
×
1993
    return -1;
×
1994
  }
1995

1996
  return 0;
×
1997
}
1998

1999
static int32_t mndProcessCreateUserReq(SRpcMsg *pReq) {
162✔
2000
  SMnode        *pMnode = pReq->info.node;
162✔
2001
  int32_t        code = 0;
162✔
2002
  int32_t        lino = 0;
162✔
2003
  SUserObj      *pUser = NULL;
162✔
2004
  SUserObj      *pOperUser = NULL;
162✔
2005
  SCreateUserReq createReq = {0};
162✔
2006

2007
  if (tDeserializeSCreateUserReq(pReq->pCont, pReq->contLen, &createReq) != 0) {
162!
2008
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
2009
  }
2010

2011
  mInfo("user:%s, start to create, createdb:%d, is_import:%d", createReq.user, createReq.createDb, createReq.isImport);
162!
2012

2013
#ifndef TD_ENTERPRISE
2014
  if (createReq.isImport == 1) {
2015
    TAOS_CHECK_GOTO(TSDB_CODE_OPS_NOT_SUPPORT, &lino, _OVER);  // enterprise feature
2016
  }
2017
#endif
2018

2019
  if (createReq.isImport != 1) {
162✔
2020
    TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CREATE_USER), &lino, _OVER);
161!
2021
  } else {
2022
    if (strcmp(pReq->info.conn.user, "root") != 0) {
1!
2023
      mError("The operation is not permitted, user:%s", pReq->info.conn.user);
×
2024
      TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_RIGHTS, &lino, _OVER);
×
2025
    }
2026
  }
2027

2028
  if (createReq.user[0] == 0) {
162!
2029
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
2030
  }
2031

2032
  if (createReq.passIsMd5 == 0) {
162!
2033
    int32_t len = strlen(createReq.pass);
×
2034
    if (createReq.isImport != 1) {
×
2035
      if (mndCheckPasswordMinLen(createReq.pass, len) != 0) {
×
2036
        TAOS_CHECK_GOTO(TSDB_CODE_PAR_PASSWD_TOO_SHORT_OR_EMPTY, &lino, _OVER);
×
2037
      }
2038
      if (mndCheckPasswordMaxLen(createReq.pass, len) != 0) {
×
2039
        TAOS_CHECK_GOTO(TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG, &lino, _OVER);
×
2040
      }
2041
      if (mndCheckPasswordFmt(createReq.pass, len) != 0) {
×
2042
        TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_PASS_FORMAT, &lino, _OVER);
×
2043
      }
2044
    }
2045
  }
2046

2047
  code = mndAcquireUser(pMnode, createReq.user, &pUser);
162✔
2048
  if (pUser != NULL) {
162!
2049
    TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_ALREADY_EXIST, &lino, _OVER);
×
2050
  }
2051

2052
  code = mndAcquireUser(pMnode, pReq->info.conn.user, &pOperUser);
162✔
2053
  if (pOperUser == NULL) {
162!
2054
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_USER_FROM_CONN, &lino, _OVER);
×
2055
  }
2056

2057
  TAOS_CHECK_GOTO(grantCheck(TSDB_GRANT_USER), &lino, _OVER);
162!
2058

2059
  code = mndCreateUser(pMnode, pOperUser->acct, &createReq, pReq);
162✔
2060
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
162!
2061

2062
  char detail[1000] = {0};
162✔
2063
  (void)tsnprintf(detail, sizeof(detail), "enable:%d, superUser:%d, sysInfo:%d, password:xxx", createReq.enable,
162✔
2064
                  createReq.superUser, createReq.sysInfo);
162✔
2065
  char operation[15] = {0};
162✔
2066
  if (createReq.isImport == 1) {
162✔
2067
    tstrncpy(operation, "importUser", sizeof(operation));
1✔
2068
  } else {
2069
    tstrncpy(operation, "createUser", sizeof(operation));
161✔
2070
  }
2071

2072
  auditRecord(pReq, pMnode->clusterId, operation, "", createReq.user, detail, strlen(detail));
162✔
2073

2074
_OVER:
162✔
2075
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
162!
2076
    mError("user:%s, failed to create at line %d since %s", createReq.user, lino, tstrerror(code));
×
2077
  }
2078

2079
  mndReleaseUser(pMnode, pUser);
162✔
2080
  mndReleaseUser(pMnode, pOperUser);
162✔
2081
  tFreeSCreateUserReq(&createReq);
162✔
2082

2083
  TAOS_RETURN(code);
162✔
2084
}
2085

2086
int32_t mndProcessGetUserWhiteListReq(SRpcMsg *pReq) {
229✔
2087
  SMnode              *pMnode = pReq->info.node;
229✔
2088
  int32_t              code = 0;
229✔
2089
  int32_t              lino = 0;
229✔
2090
  int32_t              contLen = 0;
229✔
2091
  void                *pRsp = NULL;
229✔
2092
  SUserObj            *pUser = NULL;
229✔
2093
  SGetUserWhiteListReq wlReq = {0};
229✔
2094
  SGetUserWhiteListRsp wlRsp = {0};
229✔
2095

2096
  int32_t (*serialFn)(void *, int32_t, SGetUserWhiteListRsp *) = NULL;
229✔
2097
  int32_t (*setRspFn)(SMnode * pMnode, SUserObj * pUser, SGetUserWhiteListRsp * pRsp) = NULL;
229✔
2098

2099
  if (pReq->msgType == TDMT_MND_GET_USER_WHITELIST_DUAL) {
229!
2100
    serialFn = tSerializeSGetUserWhiteListDualRsp;
×
2101
    setRspFn = mndSetUserWhiteListDualRsp;
×
2102
  } else {
2103
    serialFn = tSerializeSGetUserWhiteListRsp;
229✔
2104
    setRspFn = mndSetUserWhiteListRsp;
229✔
2105
  }
2106
  if (tDeserializeSGetUserWhiteListReq(pReq->pCont, pReq->contLen, &wlReq) != 0) {
229!
2107
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
2108
  }
2109
  mTrace("user: %s, start to get whitelist", wlReq.user);
229✔
2110

2111
  code = mndAcquireUser(pMnode, wlReq.user, &pUser);
229✔
2112
  if (pUser == NULL) {
229!
2113
    TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_NOT_EXIST, &lino, _OVER);
×
2114
  }
2115

2116
  TAOS_CHECK_GOTO(setRspFn(pMnode, pUser, &wlRsp), &lino, _OVER);
229!
2117
  contLen = serialFn(NULL, 0, &wlRsp);
229✔
2118
  if (contLen < 0) {
229!
2119
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2120
  }
2121
  pRsp = rpcMallocCont(contLen);
229✔
2122
  if (pRsp == NULL) {
229!
2123
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2124
  }
2125

2126
  contLen = serialFn(pRsp, contLen, &wlRsp);
229✔
2127
  if (contLen < 0) {
229!
2128
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
2129
  }
2130

2131
_OVER:
229✔
2132
  mndReleaseUser(pMnode, pUser);
229✔
2133
  tFreeSGetUserWhiteListDualRsp(&wlRsp);
229✔
2134
  if (code < 0) {
229!
2135
    mError("user:%s, failed to get whitelist at line %d since %s", wlReq.user, lino, tstrerror(code));
×
2136
    rpcFreeCont(pRsp);
×
2137
    pRsp = NULL;
×
2138
    contLen = 0;
×
2139
  }
2140
  pReq->code = code;
229✔
2141
  pReq->info.rsp = pRsp;
229✔
2142
  pReq->info.rspLen = contLen;
229✔
2143

2144
  TAOS_RETURN(code);
229✔
2145
}
2146

2147
int32_t mndProcesSRetrieveIpWhiteReq(SRpcMsg *pReq) {
6✔
2148
  int32_t        code = 0;
6✔
2149
  int32_t        lino = 0;
6✔
2150
  int32_t        len = 0;
6✔
2151
  void          *pRsp = NULL;
6✔
2152
  SUpdateIpWhite ipWhite = {0};
6✔
2153

2154
  // impl later
2155
  SRetrieveIpWhiteReq req = {0};
6✔
2156
  if (tDeserializeRetrieveIpWhite(pReq->pCont, pReq->contLen, &req) != 0) {
6!
2157
    code = TSDB_CODE_INVALID_MSG;
×
2158
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2159
  }
2160

2161
  int32_t (*fn)(void *, int32_t, SUpdateIpWhite *) = NULL;
6✔
2162
  if (pReq->msgType == TDMT_MND_RETRIEVE_IP_WHITE) {
6!
2163
    fn = tSerializeSUpdateIpWhite;
×
2164
  } else if (pReq->msgType == TDMT_MND_RETRIEVE_IP_WHITE_DUAL) {
6!
2165
    fn = tSerializeSUpdateIpWhiteDual;
6✔
2166
  }
2167

2168
  TAOS_CHECK_GOTO(ipWhiteMgtFillMsg(&ipWhite), &lino, _OVER);
6!
2169

2170
  len = fn(NULL, 0, &ipWhite);
6✔
2171
  if (len < 0) {
6!
2172
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
2173
  }
2174

2175
  pRsp = rpcMallocCont(len);
6✔
2176
  if (!pRsp) {
6!
2177
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2178
  }
2179
  len = fn(pRsp, len, &ipWhite);
6✔
2180
  if (len < 0) {
6!
2181
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
2182
  }
2183

2184
_OVER:
6✔
2185
  if (code < 0) {
6!
2186
    mError("failed to process retrieve ip white request at line %d since %s", lino, tstrerror(code));
×
2187
    rpcFreeCont(pRsp);
×
2188
    pRsp = NULL;
×
2189
    len = 0;
×
2190
  }
2191
  pReq->code = code;
6✔
2192
  pReq->info.rsp = pRsp;
6✔
2193
  pReq->info.rspLen = len;
6✔
2194

2195
  tFreeSUpdateIpWhiteReq(&ipWhite);
6✔
2196
  TAOS_RETURN(code);
6✔
2197
}
2198

2199
static int32_t mndAlterUser(SMnode *pMnode, SUserObj *pOld, SUserObj *pNew, SRpcMsg *pReq) {
266✔
2200
  int32_t code = 0;
266✔
2201
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "alter-user");
266✔
2202
  if (pTrans == NULL) {
266!
2203
    mError("user:%s, failed to alter since %s", pOld->user, terrstr());
×
2204
    TAOS_RETURN(terrno);
×
2205
  }
2206
  mInfo("trans:%d, used to alter user:%s", pTrans->id, pOld->user);
266!
2207

2208
  SSdbRaw *pCommitRaw = mndUserActionEncode(pNew);
266✔
2209
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
266!
2210
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
2211
    mndTransDrop(pTrans);
×
2212
    TAOS_RETURN(terrno);
×
2213
  }
2214
  code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
266✔
2215
  if (code < 0) {
266!
2216
    mndTransDrop(pTrans);
×
2217
    TAOS_RETURN(code);
×
2218
  }
2219

2220
  if (mndTransPrepare(pMnode, pTrans) != 0) {
266!
2221
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
2222
    mndTransDrop(pTrans);
×
2223
    TAOS_RETURN(terrno);
×
2224
  }
2225
  if ((code = ipWhiteMgtUpdate(pMnode, pNew->user, pNew->pIpWhiteListDual)) != 0) {
266!
2226
    mndTransDrop(pTrans);
×
2227
    TAOS_RETURN(code);
×
2228
  }
2229
  mndTransDrop(pTrans);
266✔
2230
  return 0;
266✔
2231
}
2232

2233
static int32_t mndDupObjHash(SHashObj *pOld, int32_t dataLen, SHashObj **ppNew) {
68,930✔
2234
  int32_t code = 0;
68,930✔
2235

2236
  *ppNew =
68,930✔
2237
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
68,930✔
2238
  if (*ppNew == NULL) {
68,930!
2239
    code = terrno ? terrno : TSDB_CODE_OUT_OF_MEMORY;
×
2240
    TAOS_RETURN(code);
×
2241
  }
2242

2243
  char *db = taosHashIterate(pOld, NULL);
68,930✔
2244
  while (db != NULL) {
69,521✔
2245
    int32_t len = strlen(db) + 1;
591✔
2246
    if ((code = taosHashPut(*ppNew, db, len, db, dataLen)) != 0) {
591!
2247
      taosHashCancelIterate(pOld, db);
×
2248
      taosHashCleanup(*ppNew);
×
2249
      TAOS_RETURN(code);
×
2250
    }
2251
    db = taosHashIterate(pOld, db);
591✔
2252
  }
2253

2254
  TAOS_RETURN(code);
68,930✔
2255
}
2256

2257
int32_t mndDupDbHash(SHashObj *pOld, SHashObj **ppNew) { return mndDupObjHash(pOld, TSDB_DB_FNAME_LEN, ppNew); }
62,560✔
2258

2259
int32_t mndDupTopicHash(SHashObj *pOld, SHashObj **ppNew) { return mndDupObjHash(pOld, TSDB_TOPIC_FNAME_LEN, ppNew); }
6,370✔
2260

2261
static int32_t mndTablePriviledge(SMnode *pMnode, SHashObj *hash, SHashObj *useDbHash, SAlterUserReq *alterReq,
101✔
2262
                                  SSdb *pSdb) {
2263
  void *pIter = NULL;
101✔
2264
  char  tbFName[TSDB_TABLE_FNAME_LEN] = {0};
101✔
2265

2266
  (void)snprintf(tbFName, sizeof(tbFName), "%s.%s", alterReq->objname, alterReq->tabName);
101✔
2267
  int32_t len = strlen(tbFName) + 1;
101✔
2268

2269
  if (alterReq->tagCond != NULL && alterReq->tagCondLen != 0) {
124!
2270
    char *value = taosHashGet(hash, tbFName, len);
23✔
2271
    if (value != NULL) {
23!
2272
      TAOS_RETURN(TSDB_CODE_MND_PRIVILEDGE_EXIST);
×
2273
    }
2274

2275
    int32_t condLen = alterReq->tagCondLen;
23✔
2276
    TAOS_CHECK_RETURN(taosHashPut(hash, tbFName, len, alterReq->tagCond, condLen));
23!
2277
  } else {
2278
    TAOS_CHECK_RETURN(taosHashPut(hash, tbFName, len, alterReq->isView ? "v" : "t", 2));
78!
2279
  }
2280

2281
  int32_t  dbKeyLen = strlen(alterReq->objname) + 1;
101✔
2282
  int32_t  ref = 1;
101✔
2283
  int32_t *currRef = taosHashGet(useDbHash, alterReq->objname, dbKeyLen);
101✔
2284
  if (NULL != currRef) {
101✔
2285
    ref = (*currRef) + 1;
40✔
2286
  }
2287
  TAOS_CHECK_RETURN(taosHashPut(useDbHash, alterReq->objname, dbKeyLen, &ref, sizeof(ref)));
101!
2288

2289
  TAOS_RETURN(0);
101✔
2290
}
2291

2292
static int32_t mndRemoveTablePriviledge(SMnode *pMnode, SHashObj *hash, SHashObj *useDbHash, SAlterUserReq *alterReq,
11✔
2293
                                        SSdb *pSdb) {
2294
  void *pIter = NULL;
11✔
2295
  char  tbFName[TSDB_TABLE_FNAME_LEN] = {0};
11✔
2296
  (void)snprintf(tbFName, sizeof(tbFName), "%s.%s", alterReq->objname, alterReq->tabName);
11✔
2297
  int32_t len = strlen(tbFName) + 1;
11✔
2298

2299
  if (taosHashRemove(hash, tbFName, len) != 0) {
11!
2300
    TAOS_RETURN(0);  // not found
×
2301
  }
2302

2303
  int32_t  dbKeyLen = strlen(alterReq->objname) + 1;
11✔
2304
  int32_t *currRef = taosHashGet(useDbHash, alterReq->objname, dbKeyLen);
11✔
2305
  if (NULL == currRef) {
11!
2306
    return 0;
×
2307
  }
2308

2309
  if (1 == *currRef) {
11!
2310
    if (taosHashRemove(useDbHash, alterReq->objname, dbKeyLen) != 0) {
11!
2311
      TAOS_RETURN(0);  // not found
×
2312
    }
2313
    return 0;
11✔
2314
  }
2315
  int32_t ref = (*currRef) - 1;
×
2316
  TAOS_CHECK_RETURN(taosHashPut(useDbHash, alterReq->objname, dbKeyLen, &ref, sizeof(ref)));
×
2317

2318
  return 0;
×
2319
}
2320

2321
static char *mndUserAuditTypeStr(int32_t type) {
36✔
2322
  if (type == TSDB_ALTER_USER_PASSWD) {
36!
2323
    return "changePassword";
36✔
2324
  }
2325
  if (type == TSDB_ALTER_USER_SUPERUSER) {
×
2326
    return "changeSuperUser";
×
2327
  }
2328
  if (type == TSDB_ALTER_USER_ENABLE) {
×
2329
    return "enableUser";
×
2330
  }
2331
  if (type == TSDB_ALTER_USER_SYSINFO) {
×
2332
    return "userSysInfo";
×
2333
  }
2334
  if (type == TSDB_ALTER_USER_CREATEDB) {
×
2335
    return "userCreateDB";
×
2336
  }
2337
  return "error";
×
2338
}
2339

2340
static int32_t mndProcessAlterUserPrivilegesReq(SAlterUserReq *pAlterReq, SMnode *pMnode, SUserObj *pNewUser) {
204✔
2341
  SSdb   *pSdb = pMnode->pSdb;
204✔
2342
  void   *pIter = NULL;
204✔
2343
  int32_t code = 0;
204✔
2344
  int32_t lino = 0;
204✔
2345

2346
  if (ALTER_USER_ADD_READ_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
204✔
2347
      ALTER_USER_ADD_ALL_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
151!
2348
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
53✔
2349
      int32_t len = strlen(pAlterReq->objname) + 1;
50✔
2350
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
50✔
2351
      if (pDb == NULL) {
50✔
2352
        mndReleaseDb(pMnode, pDb);
7✔
2353
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
7!
2354
      }
2355
      if ((code = taosHashPut(pNewUser->readDbs, pAlterReq->objname, len, pAlterReq->objname, TSDB_DB_FNAME_LEN)) !=
43!
2356
          0) {
2357
        mndReleaseDb(pMnode, pDb);
×
2358
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2359
      }
2360
      mndReleaseDb(pMnode, pDb);
43✔
2361
    } else {
2362
      while (1) {
9✔
2363
        SDbObj *pDb = NULL;
12✔
2364
        pIter = sdbFetch(pSdb, SDB_DB, pIter, (void **)&pDb);
12✔
2365
        if (pIter == NULL) break;
12✔
2366
        int32_t len = strlen(pDb->name) + 1;
9✔
2367
        if ((code = taosHashPut(pNewUser->readDbs, pDb->name, len, pDb->name, TSDB_DB_FNAME_LEN)) != 0) {
9!
2368
          sdbRelease(pSdb, pDb);
×
2369
          sdbCancelFetch(pSdb, pIter);
×
2370
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2371
        }
2372
        sdbRelease(pSdb, pDb);
9✔
2373
      }
2374
    }
2375
  }
2376

2377
  if (ALTER_USER_ADD_WRITE_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
197✔
2378
      ALTER_USER_ADD_ALL_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
151!
2379
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
46✔
2380
      int32_t len = strlen(pAlterReq->objname) + 1;
43✔
2381
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
43✔
2382
      if (pDb == NULL) {
43✔
2383
        mndReleaseDb(pMnode, pDb);
1✔
2384
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
1!
2385
      }
2386
      if ((code = taosHashPut(pNewUser->writeDbs, pAlterReq->objname, len, pAlterReq->objname, TSDB_DB_FNAME_LEN)) !=
42!
2387
          0) {
2388
        mndReleaseDb(pMnode, pDb);
×
2389
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2390
      }
2391
      mndReleaseDb(pMnode, pDb);
42✔
2392
    } else {
2393
      while (1) {
9✔
2394
        SDbObj *pDb = NULL;
12✔
2395
        pIter = sdbFetch(pSdb, SDB_DB, pIter, (void **)&pDb);
12✔
2396
        if (pIter == NULL) break;
12✔
2397
        int32_t len = strlen(pDb->name) + 1;
9✔
2398
        if ((code = taosHashPut(pNewUser->writeDbs, pDb->name, len, pDb->name, TSDB_DB_FNAME_LEN)) != 0) {
9!
2399
          sdbRelease(pSdb, pDb);
×
2400
          sdbCancelFetch(pSdb, pIter);
×
2401
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2402
        }
2403
        sdbRelease(pSdb, pDb);
9✔
2404
      }
2405
    }
2406
  }
2407

2408
  if (ALTER_USER_DEL_READ_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
196✔
2409
      ALTER_USER_DEL_ALL_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
168!
2410
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
28✔
2411
      int32_t len = strlen(pAlterReq->objname) + 1;
25✔
2412
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
25✔
2413
      if (pDb == NULL) {
25!
2414
        mndReleaseDb(pMnode, pDb);
×
2415
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
×
2416
      }
2417
      code = taosHashRemove(pNewUser->readDbs, pAlterReq->objname, len);
25✔
2418
      if (code < 0) {
25!
2419
        mError("read db:%s, failed to remove db:%s since %s", pNewUser->user, pAlterReq->objname, terrstr());
×
2420
      }
2421
      mndReleaseDb(pMnode, pDb);
25✔
2422
    } else {
2423
      taosHashClear(pNewUser->readDbs);
3✔
2424
    }
2425
  }
2426

2427
  if (ALTER_USER_DEL_WRITE_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
196✔
2428
      ALTER_USER_DEL_ALL_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
170!
2429
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
26✔
2430
      int32_t len = strlen(pAlterReq->objname) + 1;
23✔
2431
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
23✔
2432
      if (pDb == NULL) {
23!
2433
        mndReleaseDb(pMnode, pDb);
×
2434
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
×
2435
      }
2436
      code = taosHashRemove(pNewUser->writeDbs, pAlterReq->objname, len);
23✔
2437
      if (code < 0) {
23!
2438
        mError("user:%s, failed to remove db:%s since %s", pNewUser->user, pAlterReq->objname, terrstr());
×
2439
      }
2440
      mndReleaseDb(pMnode, pDb);
23✔
2441
    } else {
2442
      taosHashClear(pNewUser->writeDbs);
3✔
2443
    }
2444
  }
2445

2446
  SHashObj *pReadTbs = pNewUser->readTbs;
196✔
2447
  SHashObj *pWriteTbs = pNewUser->writeTbs;
196✔
2448
  SHashObj *pAlterTbs = pNewUser->alterTbs;
196✔
2449

2450
#ifdef TD_ENTERPRISE
2451
  if (pAlterReq->isView) {
196✔
2452
    pReadTbs = pNewUser->readViews;
24✔
2453
    pWriteTbs = pNewUser->writeViews;
24✔
2454
    pAlterTbs = pNewUser->alterViews;
24✔
2455
  }
2456
#endif
2457

2458
  if (ALTER_USER_ADD_READ_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
196✔
2459
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
154!
2460
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pReadTbs, pNewUser->useDbs, pAlterReq, pSdb), &lino, _OVER);
42!
2461
  }
2462

2463
  if (ALTER_USER_ADD_WRITE_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
196✔
2464
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
157!
2465
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pWriteTbs, pNewUser->useDbs, pAlterReq, pSdb), &lino, _OVER);
39!
2466
  }
2467

2468
  if (ALTER_USER_ADD_ALTER_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
196✔
2469
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
176!
2470
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pAlterTbs, pNewUser->useDbs, pAlterReq, pSdb), &lino, _OVER);
20!
2471
  }
2472

2473
  if (ALTER_USER_DEL_READ_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
196✔
2474
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
190!
2475
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pReadTbs, pNewUser->useDbs, pAlterReq, pSdb), &lino, _OVER);
6!
2476
  }
2477

2478
  if (ALTER_USER_DEL_WRITE_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
196✔
2479
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
191!
2480
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pWriteTbs, pNewUser->useDbs, pAlterReq, pSdb), &lino, _OVER);
5!
2481
  }
2482

2483
  if (ALTER_USER_DEL_ALTER_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
196!
2484
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
196!
2485
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pAlterTbs, pNewUser->useDbs, pAlterReq, pSdb), &lino, _OVER);
×
2486
  }
2487

2488
#ifdef USE_TOPIC
2489
  if (ALTER_USER_ADD_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, pAlterReq->privileges)) {
196✔
2490
    int32_t      len = strlen(pAlterReq->objname) + 1;
15✔
2491
    SMqTopicObj *pTopic = NULL;
15✔
2492
    if ((code = mndAcquireTopic(pMnode, pAlterReq->objname, &pTopic)) != 0) {
15!
2493
      mndReleaseTopic(pMnode, pTopic);
×
2494
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2495
    }
2496
    if ((code = taosHashPut(pNewUser->topics, pTopic->name, len, pTopic->name, TSDB_TOPIC_FNAME_LEN)) != 0) {
15!
2497
      mndReleaseTopic(pMnode, pTopic);
×
2498
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2499
    }
2500
    mndReleaseTopic(pMnode, pTopic);
15✔
2501
  }
2502

2503
  if (ALTER_USER_DEL_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, pAlterReq->privileges)) {
196✔
2504
    int32_t      len = strlen(pAlterReq->objname) + 1;
11✔
2505
    SMqTopicObj *pTopic = NULL;
11✔
2506
    if ((code = mndAcquireTopic(pMnode, pAlterReq->objname, &pTopic)) != 0) {
11✔
2507
      mndReleaseTopic(pMnode, pTopic);
1✔
2508
      TAOS_CHECK_GOTO(code, &lino, _OVER);
1!
2509
    }
2510
    code = taosHashRemove(pNewUser->topics, pAlterReq->objname, len);
10✔
2511
    if (code < 0) {
10!
2512
      mError("user:%s, failed to remove topic:%s since %s", pNewUser->user, pAlterReq->objname, tstrerror(code));
×
2513
    }
2514
    mndReleaseTopic(pMnode, pTopic);
10✔
2515
  }
2516
#endif
2517
_OVER:
185✔
2518
  if (code < 0) {
204✔
2519
    mError("user:%s, failed to alter user privileges at line %d since %s", pAlterReq->user, lino, tstrerror(code));
9!
2520
  }
2521
  TAOS_RETURN(code);
204✔
2522
}
2523

2524
static int32_t mndProcessAlterUserReq(SRpcMsg *pReq) {
369✔
2525
  SMnode       *pMnode = pReq->info.node;
369✔
2526
  SSdb         *pSdb = pMnode->pSdb;
369✔
2527
  void         *pIter = NULL;
369✔
2528
  int32_t       code = 0;
369✔
2529
  int32_t       lino = 0;
369✔
2530
  SUserObj     *pUser = NULL;
369✔
2531
  SUserObj     *pOperUser = NULL;
369✔
2532
  SUserObj      newUser = {0};
369✔
2533
  SAlterUserReq alterReq = {0};
369✔
2534

2535
  TAOS_CHECK_GOTO(tDeserializeSAlterUserReq(pReq->pCont, pReq->contLen, &alterReq), &lino, _OVER);
369!
2536

2537
  mInfo("user:%s, start to alter", alterReq.user);
369!
2538

2539
  if (alterReq.user[0] == 0) {
369!
2540
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
2541
  }
2542
  if (alterReq.passIsMd5 == 0) {
369✔
2543
    if (TSDB_ALTER_USER_PASSWD == alterReq.alterType) {
332!
2544
      int32_t len = strlen(alterReq.pass);
×
2545
      if (mndCheckPasswordMinLen(alterReq.pass, len) != 0) {
×
2546
        TAOS_CHECK_GOTO(TSDB_CODE_PAR_PASSWD_TOO_SHORT_OR_EMPTY, &lino, _OVER);
×
2547
      }
2548
      if (mndCheckPasswordMaxLen(alterReq.pass, len) != 0) {
×
2549
        TAOS_CHECK_GOTO(TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG, &lino, _OVER);
×
2550
      }
2551
      if (mndCheckPasswordFmt(alterReq.pass, len) != 0) {
×
2552
        TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_PASS_FORMAT, &lino, _OVER);
×
2553
      }
2554
    }
2555
  }
2556

2557
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, alterReq.user, &pUser), &lino, _OVER);
369✔
2558

2559
  (void)mndAcquireUser(pMnode, pReq->info.conn.user, &pOperUser);
347✔
2560
  if (pOperUser == NULL) {
347!
2561
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_USER_FROM_CONN, &lino, _OVER);
×
2562
  }
2563

2564
  TAOS_CHECK_GOTO(mndCheckAlterUserPrivilege(pOperUser, pUser, &alterReq), &lino, _OVER);
347✔
2565

2566
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
276!
2567

2568
  if (alterReq.alterType == TSDB_ALTER_USER_PASSWD) {
276✔
2569
    if (alterReq.passIsMd5 == 1) {
36!
2570
      (void)memcpy(newUser.pass, alterReq.pass, TSDB_PASSWORD_LEN);
36✔
2571
    } else {
2572
      taosEncryptPass_c((uint8_t *)alterReq.pass, strlen(alterReq.pass), newUser.pass);
×
2573
    }
2574

2575
    TAOS_CHECK_GOTO(mndEncryptPass(newUser.pass, &newUser.passEncryptAlgorithm), &lino, _OVER);
36!
2576

2577
    if (0 != strncmp(pUser->pass, newUser.pass, TSDB_PASSWORD_LEN)) {
36✔
2578
      ++newUser.passVersion;
32✔
2579
    }
2580
  }
2581

2582
  if (alterReq.alterType == TSDB_ALTER_USER_SUPERUSER) {
276!
2583
    newUser.superUser = alterReq.superUser;
×
2584
  }
2585

2586
  if (alterReq.alterType == TSDB_ALTER_USER_ENABLE) {
276✔
2587
    newUser.enable = alterReq.enable;
9✔
2588
  }
2589

2590
  if (alterReq.alterType == TSDB_ALTER_USER_SYSINFO) {
276✔
2591
    newUser.sysInfo = alterReq.sysInfo;
18✔
2592
  }
2593

2594
  if (alterReq.alterType == TSDB_ALTER_USER_CREATEDB) {
276✔
2595
    newUser.createdb = alterReq.createdb;
7✔
2596
  }
2597

2598
  if (ALTER_USER_ADD_PRIVS(alterReq.alterType) || ALTER_USER_DEL_PRIVS(alterReq.alterType)) {
276✔
2599
    TAOS_CHECK_GOTO(mndProcessAlterUserPrivilegesReq(&alterReq, pMnode, &newUser), &lino, _OVER);
204✔
2600
  }
2601

2602
  if (alterReq.alterType == TSDB_ALTER_USER_ADD_WHITE_LIST) {
267✔
2603
    taosMemoryFreeClear(newUser.pIpWhiteListDual);
1!
2604

2605
    int32_t           num = pUser->pIpWhiteListDual->num + alterReq.numIpRanges;
1✔
2606
    int32_t           idx = pUser->pIpWhiteListDual->num;
1✔
2607
    SIpWhiteListDual *pNew = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + sizeof(SIpRange) * num);
1!
2608

2609
    if (pNew == NULL) {
1!
2610
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2611
    }
2612

2613
    bool exist = false;
1✔
2614
    (void)memcpy(pNew->pIpRanges, pUser->pIpWhiteListDual->pIpRanges, sizeof(SIpRange) * idx);
1✔
2615
    for (int i = 0; i < alterReq.numIpRanges; i++) {
2✔
2616
      SIpRange range = {0};
1✔
2617
      if (alterReq.pIpDualRanges == NULL) {
1!
2618
        range.type = 0;
×
2619
        memcpy(&range.ipV4, &alterReq.pIpRanges[i], sizeof(SIpV4Range));
×
2620
      } else {
2621
        memcpy(&range, &alterReq.pIpDualRanges[i], sizeof(SIpRange));
1✔
2622
        range = alterReq.pIpDualRanges[i];
1✔
2623
      }
2624
      if (!isRangeInIpWhiteList(pUser->pIpWhiteListDual, &range)) {
1!
2625
        // already exist, just ignore;
2626
        (void)memcpy(&pNew->pIpRanges[idx], &range, sizeof(SIpRange));
1✔
2627
        idx++;
1✔
2628
        continue;
1✔
2629
      } else {
2630
        exist = true;
×
2631
      }
2632
    }
2633
    if (exist) {
1!
2634
      taosMemoryFree(pNew);
×
2635
      TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_HOST_EXIST, &lino, _OVER);
×
2636
    }
2637
    pNew->num = idx;
1✔
2638
    newUser.pIpWhiteListDual = pNew;
1✔
2639
    newUser.ipWhiteListVer = pUser->ipWhiteListVer + 1;
1✔
2640

2641
    if (pNew->num > MND_MAX_USE_HOST) {
1!
2642
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_HOST, &lino, _OVER);
×
2643
    }
2644
  }
2645
  if (alterReq.alterType == TSDB_ALTER_USER_DROP_WHITE_LIST) {
267✔
2646
    taosMemoryFreeClear(newUser.pIpWhiteListDual);
1!
2647

2648
    int32_t           num = pUser->pIpWhiteListDual->num;
1✔
2649
    bool              noexist = true;
1✔
2650
    bool              localHost = false;
1✔
2651
    SIpWhiteListDual *pNew = taosMemoryCalloc(1, sizeof(SIpWhiteListDual) + sizeof(SIpRange) * num);
1!
2652

2653
    if (pNew == NULL) {
1!
2654
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2655
    }
2656

2657
    if (pUser->pIpWhiteListDual->num > 0) {
1!
2658
      int idx = 0;
1✔
2659
      for (int i = 0; i < pUser->pIpWhiteListDual->num; i++) {
3✔
2660
        SIpRange *oldRange = &pUser->pIpWhiteListDual->pIpRanges[i];
2✔
2661

2662
        bool found = false;
2✔
2663
        for (int j = 0; j < alterReq.numIpRanges; j++) {
4✔
2664
          SIpRange range = {0};
2✔
2665
          if (alterReq.pIpDualRanges == NULL) {
2!
2666
            SIpV4Range *trange = &alterReq.pIpRanges[j];
×
2667
            memcpy(&range.ipV4, trange, sizeof(SIpV4Range));
×
2668
          } else {
2669
            memcpy(&range, &alterReq.pIpDualRanges[j], sizeof(SIpRange));
2✔
2670
          }
2671

2672
          if (isDefaultRange(&range)) {
2!
2673
            localHost = true;
×
2674
            break;
×
2675
          }
2676
          if (isIpRangeEqual(oldRange, &range)) {
2!
2677
            found = true;
×
2678
            break;
×
2679
          }
2680
        }
2681
        if (localHost) break;
2!
2682

2683
        if (found == false) {
2!
2684
          (void)memcpy(&pNew->pIpRanges[idx], oldRange, sizeof(SIpRange));
2✔
2685
          idx++;
2✔
2686
        } else {
2687
          noexist = false;
×
2688
        }
2689
      }
2690
      pNew->num = idx;
1✔
2691
      newUser.pIpWhiteListDual = pNew;
1✔
2692
      newUser.ipWhiteListVer = pUser->ipWhiteListVer + 1;
1✔
2693

2694
    } else {
2695
      pNew->num = 0;
×
2696
      newUser.pIpWhiteListDual = pNew;
×
2697
      newUser.ipWhiteListVer = pUser->ipWhiteListVer + 1;
×
2698
    }
2699

2700
    if (localHost) {
1!
2701
      TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_LOCAL_HOST_NOT_DROP, &lino, _OVER);
×
2702
    }
2703
    if (noexist) {
1!
2704
      TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_HOST_NOT_EXIST, &lino, _OVER);
1!
2705
    }
2706
  }
2707

2708
  code = mndAlterUser(pMnode, pUser, &newUser, pReq);
266✔
2709
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
266!
2710

2711
  if (alterReq.alterType == TSDB_ALTER_USER_PASSWD) {
266✔
2712
    char detail[1000] = {0};
36✔
2713
    (void)tsnprintf(detail, sizeof(detail),
36✔
2714
                    "alterType:%s, enable:%d, superUser:%d, sysInfo:%d, createdb:%d, tabName:%s, password:xxx",
2715
                    mndUserAuditTypeStr(alterReq.alterType), alterReq.enable, alterReq.superUser, alterReq.sysInfo,
36✔
2716
                    alterReq.createdb ? 1 : 0, alterReq.tabName);
36✔
2717
    auditRecord(pReq, pMnode->clusterId, "alterUser", "", alterReq.user, detail, strlen(detail));
36✔
2718
  } else if (alterReq.alterType == TSDB_ALTER_USER_SUPERUSER || alterReq.alterType == TSDB_ALTER_USER_ENABLE ||
230!
2719
             alterReq.alterType == TSDB_ALTER_USER_SYSINFO || alterReq.alterType == TSDB_ALTER_USER_CREATEDB) {
221✔
2720
    auditRecord(pReq, pMnode->clusterId, "alterUser", "", alterReq.user, alterReq.sql, alterReq.sqlLen);
34✔
2721
  } else if (ALTER_USER_ADD_READ_DB_PRIV(alterReq.alterType, alterReq.privileges, alterReq.tabName) ||
196✔
2722
             ALTER_USER_ADD_WRITE_DB_PRIV(alterReq.alterType, alterReq.privileges, alterReq.tabName) ||
150✔
2723
             ALTER_USER_ADD_ALL_DB_PRIV(alterReq.alterType, alterReq.privileges, alterReq.tabName) ||
137!
2724
             ALTER_USER_ADD_READ_TB_PRIV(alterReq.alterType, alterReq.privileges, alterReq.tabName) ||
137!
2725
             ALTER_USER_ADD_WRITE_TB_PRIV(alterReq.alterType, alterReq.privileges, alterReq.tabName) ||
95!
2726
             ALTER_USER_ADD_ALL_TB_PRIV(alterReq.alterType, alterReq.privileges, alterReq.tabName)) {
72!
2727
    if (strcmp(alterReq.objname, "1.*") != 0) {
124✔
2728
      SName name = {0};
120✔
2729
      TAOS_CHECK_GOTO(tNameFromString(&name, alterReq.objname, T_NAME_ACCT | T_NAME_DB), &lino, _OVER);
120!
2730
      auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", name.dbname, alterReq.user, alterReq.sql,
120✔
2731
                  alterReq.sqlLen);
2732
    } else {
2733
      auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", "", alterReq.user, alterReq.sql, alterReq.sqlLen);
4✔
2734
    }
2735
  } else if (ALTER_USER_ADD_SUBSCRIBE_TOPIC_PRIV(alterReq.alterType, alterReq.privileges)) {
72✔
2736
    auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", alterReq.objname, alterReq.user, alterReq.sql,
15✔
2737
                alterReq.sqlLen);
2738
  } else if (ALTER_USER_DEL_SUBSCRIBE_TOPIC_PRIV(alterReq.alterType, alterReq.privileges)) {
57✔
2739
    auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", alterReq.objname, alterReq.user, alterReq.sql,
10✔
2740
                alterReq.sqlLen);
2741
  } else {
2742
    if (strcmp(alterReq.objname, "1.*") != 0) {
47✔
2743
      SName name = {0};
43✔
2744
      TAOS_CHECK_GOTO(tNameFromString(&name, alterReq.objname, T_NAME_ACCT | T_NAME_DB), &lino, _OVER);
43✔
2745
      auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", name.dbname, alterReq.user, alterReq.sql,
42✔
2746
                  alterReq.sqlLen);
2747
    } else {
2748
      auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", "", alterReq.user, alterReq.sql, alterReq.sqlLen);
4✔
2749
    }
2750
  }
2751

2752
_OVER:
369✔
2753
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
369✔
2754
    mError("user:%s, failed to alter at line %d since %s", alterReq.user, lino, tstrerror(code));
104!
2755
  }
2756

2757
  tFreeSAlterUserReq(&alterReq);
369✔
2758
  mndReleaseUser(pMnode, pOperUser);
369✔
2759
  mndReleaseUser(pMnode, pUser);
369✔
2760
  mndUserFreeObj(&newUser);
369✔
2761

2762
  TAOS_RETURN(code);
369✔
2763
}
2764

2765
static int32_t mndDropUser(SMnode *pMnode, SRpcMsg *pReq, SUserObj *pUser) {
59✔
2766
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "drop-user");
59✔
2767
  if (pTrans == NULL) {
59!
2768
    mError("user:%s, failed to drop since %s", pUser->user, terrstr());
×
2769
    TAOS_RETURN(terrno);
×
2770
  }
2771
  mInfo("trans:%d, used to drop user:%s", pTrans->id, pUser->user);
59!
2772

2773
  SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
59✔
2774
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
59!
2775
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
2776
    mndTransDrop(pTrans);
×
2777
    TAOS_RETURN(terrno);
×
2778
  }
2779
  if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED) < 0) {
59!
2780
    mndTransDrop(pTrans);
×
2781
    TAOS_RETURN(terrno);
×
2782
  }
2783

2784
  if (mndTransPrepare(pMnode, pTrans) != 0) {
59!
2785
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
2786
    mndTransDrop(pTrans);
×
2787
    TAOS_RETURN(terrno);
×
2788
  }
2789
  (void)ipWhiteMgtRemove(pUser->user);
59✔
2790

2791
  mndTransDrop(pTrans);
59✔
2792
  TAOS_RETURN(0);
59✔
2793
}
2794

2795
static int32_t mndProcessDropUserReq(SRpcMsg *pReq) {
59✔
2796
  SMnode      *pMnode = pReq->info.node;
59✔
2797
  int32_t      code = 0;
59✔
2798
  int32_t      lino = 0;
59✔
2799
  SUserObj    *pUser = NULL;
59✔
2800
  SDropUserReq dropReq = {0};
59✔
2801

2802
  TAOS_CHECK_GOTO(tDeserializeSDropUserReq(pReq->pCont, pReq->contLen, &dropReq), &lino, _OVER);
59!
2803

2804
  mInfo("user:%s, start to drop", dropReq.user);
59!
2805
  TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_DROP_USER), &lino, _OVER);
59!
2806

2807
  if (dropReq.user[0] == 0) {
59!
2808
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
2809
  }
2810

2811
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, dropReq.user, &pUser), &lino, _OVER);
59!
2812

2813
  TAOS_CHECK_GOTO(mndDropUser(pMnode, pReq, pUser), &lino, _OVER);
59!
2814
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
59!
2815

2816
  auditRecord(pReq, pMnode->clusterId, "dropUser", "", dropReq.user, dropReq.sql, dropReq.sqlLen);
59✔
2817

2818
_OVER:
59✔
2819
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
59!
2820
    mError("user:%s, failed to drop at line %d since %s", dropReq.user, lino, tstrerror(code));
×
2821
  }
2822

2823
  mndReleaseUser(pMnode, pUser);
59✔
2824
  tFreeSDropUserReq(&dropReq);
59✔
2825
  TAOS_RETURN(code);
59✔
2826
}
2827

2828
static int32_t mndProcessGetUserAuthReq(SRpcMsg *pReq) {
21,890✔
2829
  SMnode         *pMnode = pReq->info.node;
21,890✔
2830
  int32_t         code = 0;
21,890✔
2831
  int32_t         lino = 0;
21,890✔
2832
  int32_t         contLen = 0;
21,890✔
2833
  void           *pRsp = NULL;
21,890✔
2834
  SUserObj       *pUser = NULL;
21,890✔
2835
  SGetUserAuthReq authReq = {0};
21,890✔
2836
  SGetUserAuthRsp authRsp = {0};
21,890✔
2837

2838
  TAOS_CHECK_EXIT(tDeserializeSGetUserAuthReq(pReq->pCont, pReq->contLen, &authReq));
21,890!
2839
  mTrace("user:%s, start to get auth", authReq.user);
21,890✔
2840

2841
  TAOS_CHECK_EXIT(mndAcquireUser(pMnode, authReq.user, &pUser));
21,890✔
2842

2843
  TAOS_CHECK_EXIT(mndSetUserAuthRsp(pMnode, pUser, &authRsp));
21,886!
2844

2845
  contLen = tSerializeSGetUserAuthRsp(NULL, 0, &authRsp);
21,886✔
2846
  if (contLen < 0) {
21,886!
2847
    TAOS_CHECK_EXIT(contLen);
×
2848
  }
2849
  pRsp = rpcMallocCont(contLen);
21,886✔
2850
  if (pRsp == NULL) {
21,886!
2851
    TAOS_CHECK_EXIT(terrno);
×
2852
  }
2853

2854
  contLen = tSerializeSGetUserAuthRsp(pRsp, contLen, &authRsp);
21,886✔
2855
  if (contLen < 0) {
21,886!
2856
    TAOS_CHECK_EXIT(contLen);
×
2857
  }
2858

2859
_exit:
21,886✔
2860
  mndReleaseUser(pMnode, pUser);
21,890✔
2861
  tFreeSGetUserAuthRsp(&authRsp);
21,890✔
2862
  if (code < 0) {
21,890✔
2863
    mError("user:%s, failed to get auth at line %d since %s", authReq.user, lino, tstrerror(code));
4!
2864
    rpcFreeCont(pRsp);
4✔
2865
    pRsp = NULL;
4✔
2866
    contLen = 0;
4✔
2867
  }
2868
  pReq->info.rsp = pRsp;
21,890✔
2869
  pReq->info.rspLen = contLen;
21,890✔
2870
  pReq->code = code;
21,890✔
2871

2872
  TAOS_RETURN(code);
21,890✔
2873
}
2874

2875
static int32_t mndRetrieveUsers(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
55✔
2876
  SMnode   *pMnode = pReq->info.node;
55✔
2877
  SSdb     *pSdb = pMnode->pSdb;
55✔
2878
  int32_t   code = 0;
55✔
2879
  int32_t   lino = 0;
55✔
2880
  int32_t   numOfRows = 0;
55✔
2881
  SUserObj *pUser = NULL;
55✔
2882
  int32_t   cols = 0;
55✔
2883
  int8_t    flag = 0;
55✔
2884
  char     *pWrite = NULL;
55✔
2885
  char     *buf = NULL;
55✔
2886
  char     *varstr = NULL;
55✔
2887

2888
  while (numOfRows < rows) {
181!
2889
    pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
181✔
2890
    if (pShow->pIter == NULL) break;
181✔
2891

2892
    cols = 0;
126✔
2893
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
126✔
2894
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
126✔
2895
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
126✔
2896
    COL_DATA_SET_VAL_GOTO((const char *)name, false, pUser, _exit);
126!
2897

2898
    cols++;
126✔
2899
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
126✔
2900
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->superUser, false, pUser, _exit);
126!
2901

2902
    cols++;
126✔
2903
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
126✔
2904
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->enable, false, pUser, _exit);
126!
2905

2906
    cols++;
126✔
2907
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
126✔
2908
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sysInfo, false, pUser, _exit);
126!
2909

2910
    cols++;
126✔
2911
    flag = pUser->createdb ? 1 : 0;
126✔
2912
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
126✔
2913
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, _exit);
126!
2914

2915
    cols++;
126✔
2916
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
126✔
2917
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->createdTime, false, pUser, _exit);
126!
2918

2919
    cols++;
126✔
2920

2921
    int32_t tlen = convertIpWhiteListToStr(pUser->pIpWhiteListDual, &buf);
126✔
2922
    if (tlen != 0) {
126!
2923
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
126!
2924
      if (varstr == NULL) {
126!
2925
        sdbRelease(pSdb, pUser);
×
2926
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
2927
      }
2928
      varDataSetLen(varstr, tlen);
126✔
2929
      (void)memcpy(varDataVal(varstr), buf, tlen);
126✔
2930

2931
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
126✔
2932
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, _exit);
126!
2933

2934
      taosMemoryFreeClear(buf);
126!
2935
    } else {
2936
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
2937
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, _exit);
×
2938
    }
2939

2940
    numOfRows++;
126✔
2941
    sdbRelease(pSdb, pUser);
126✔
2942
  }
2943

2944
  pShow->numOfRows += numOfRows;
55✔
2945
_exit:
55✔
2946
  taosMemoryFreeClear(buf);
55!
2947
  taosMemoryFreeClear(varstr);
55!
2948
  if (code < 0) {
55!
2949
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
2950
    TAOS_RETURN(code);
×
2951
  }
2952
  return numOfRows;
55✔
2953
}
2954

2955
static int32_t mndRetrieveUsersFull(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
×
2956
  int32_t numOfRows = 0;
×
2957
#ifdef TD_ENTERPRISE
2958
  SMnode   *pMnode = pReq->info.node;
×
2959
  SSdb     *pSdb = pMnode->pSdb;
×
2960
  SUserObj *pUser = NULL;
×
2961
  int32_t   code = 0;
×
2962
  int32_t   lino = 0;
×
2963
  int32_t   cols = 0;
×
2964
  int8_t    flag = 0;
×
2965
  char     *pWrite = NULL;
×
2966
  char     *buf = NULL;
×
2967
  char     *varstr = NULL;
×
2968

2969
  while (numOfRows < rows) {
×
2970
    pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
×
2971
    if (pShow->pIter == NULL) break;
×
2972

2973
    cols = 0;
×
2974
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
2975
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
×
2976
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
×
2977
    COL_DATA_SET_VAL_GOTO((const char *)name, false, pUser, _exit);
×
2978

2979
    cols++;
×
2980
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
2981
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->superUser, false, pUser, _exit);
×
2982

2983
    cols++;
×
2984
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
2985
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->enable, false, pUser, _exit);
×
2986

2987
    cols++;
×
2988
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
2989
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sysInfo, false, pUser, _exit);
×
2990

2991
    cols++;
×
2992
    flag = pUser->createdb ? 1 : 0;
×
2993
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
2994
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, _exit);
×
2995

2996
    // mInfo("pUser->pass:%s", pUser->pass);
2997
    cols++;
×
2998
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
2999
    char pass[TSDB_PASSWORD_LEN + VARSTR_HEADER_SIZE] = {0};
×
3000
    STR_WITH_MAXSIZE_TO_VARSTR(pass, pUser->pass, pShow->pMeta->pSchemas[cols].bytes);
×
3001
    COL_DATA_SET_VAL_GOTO((const char *)pass, false, pUser, _exit);
×
3002

3003
    cols++;
×
3004

3005
    int32_t tlen = convertIpWhiteListToStr(pUser->pIpWhiteListDual, &buf);
×
3006
    if (tlen != 0) {
×
3007
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
×
3008
      if (varstr == NULL) {
×
3009
        sdbRelease(pSdb, pUser);
×
3010
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
3011
      }
3012
      varDataSetLen(varstr, tlen);
×
3013
      (void)memcpy(varDataVal(varstr), buf, tlen);
×
3014

3015
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3016
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, _exit);
×
3017

3018
      taosMemoryFreeClear(buf);
×
3019
    } else {
3020
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
3021
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, _exit);
×
3022
    }
3023

3024
    numOfRows++;
×
3025
    sdbRelease(pSdb, pUser);
×
3026
  }
3027

3028
  pShow->numOfRows += numOfRows;
×
3029
_exit:
×
3030
  taosMemoryFreeClear(buf);
×
3031
  taosMemoryFreeClear(varstr);
×
3032
  if (code < 0) {
×
3033
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
3034
    TAOS_RETURN(code);
×
3035
  }
3036
#endif
3037
  return numOfRows;
×
3038
}
3039

3040
static void mndCancelGetNextUser(SMnode *pMnode, void *pIter) {
×
3041
  SSdb *pSdb = pMnode->pSdb;
×
3042
  sdbCancelFetchByType(pSdb, pIter, SDB_USER);
×
3043
}
×
3044

3045
static int32_t mndLoopHash(SHashObj *hash, char *priType, SSDataBlock *pBlock, int32_t *pNumOfRows, SSdb *pSdb,
570✔
3046
                           SUserObj *pUser, SShowObj *pShow, char **condition, char **sql) {
3047
  char   *value = taosHashIterate(hash, NULL);
570✔
3048
  char   *user = pUser->user;
570✔
3049
  int32_t code = 0;
570✔
3050
  int32_t lino = 0;
570✔
3051
  int32_t cols = 0;
570✔
3052
  int32_t numOfRows = *pNumOfRows;
570✔
3053

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

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

3066
    size_t keyLen = 0;
4✔
3067
    void  *key = taosHashGetKey(value, &keyLen);
4✔
3068

3069
    char dbName[TSDB_DB_NAME_LEN] = {0};
4✔
3070
    (void)mndExtractShortDbNameFromStbFullName(key, dbName);
4✔
3071
    char dbNameContent[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4✔
3072
    STR_WITH_MAXSIZE_TO_VARSTR(dbNameContent, dbName, pShow->pMeta->pSchemas[cols].bytes);
4✔
3073
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4✔
3074
    COL_DATA_SET_VAL_GOTO((const char *)dbNameContent, false, NULL, _exit);
4!
3075

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

3083
    if (strcmp("t", value) != 0 && strcmp("v", value) != 0) {
4!
3084
      SNode  *pAst = NULL;
×
3085
      int32_t sqlLen = 0;
×
3086
      size_t  bufSz = strlen(value) + 1;
×
3087
      if (bufSz < 6) bufSz = 6;
×
3088
      TAOS_MEMORY_REALLOC(*sql, bufSz);
×
3089
      if (*sql == NULL) {
×
3090
        code = terrno;
×
3091
        goto _exit;
×
3092
      }
3093
      TAOS_MEMORY_REALLOC(*condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
×
3094
      if ((*condition) == NULL) {
×
3095
        code = terrno;
×
3096
        goto _exit;
×
3097
      }
3098

3099
      if (nodesStringToNode(value, &pAst) == 0) {
×
3100
        if (nodesNodeToSQLFormat(pAst, *sql, bufSz, &sqlLen, true) != 0) {
×
3101
          sqlLen = tsnprintf(*sql, bufSz, "error");
×
3102
        }
3103
        nodesDestroyNode(pAst);
×
3104
      }
3105

3106
      if (sqlLen == 0) {
×
3107
        sqlLen = tsnprintf(*sql, bufSz, "error");
×
3108
      }
3109

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

3112
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
3113
      COL_DATA_SET_VAL_GOTO((const char *)(*condition), false, NULL, _exit);
×
3114

3115
      char notes[2] = {0};
×
3116
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
×
3117
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
3118
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, NULL, _exit);
×
3119
    } else {
3120
      TAOS_MEMORY_REALLOC(*condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
4!
3121
      if ((*condition) == NULL) {
4!
3122
        code = terrno;
×
3123
        goto _exit;
×
3124
      }
3125
      STR_WITH_MAXSIZE_TO_VARSTR((*condition), "", pShow->pMeta->pSchemas[cols].bytes);
4✔
3126
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4✔
3127
      COL_DATA_SET_VAL_GOTO((const char *)(*condition), false, NULL, _exit);
4!
3128

3129
      char notes[64 + VARSTR_HEADER_SIZE] = {0};
4✔
3130
      STR_WITH_MAXSIZE_TO_VARSTR(notes, value[0] == 'v' ? "view" : "", sizeof(notes));
4!
3131
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4✔
3132
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, NULL, _exit);
4!
3133
    }
3134

3135
    numOfRows++;
4✔
3136
    value = taosHashIterate(hash, value);
4✔
3137
  }
3138
  *pNumOfRows = numOfRows;
570✔
3139
_exit:
570✔
3140
  if (code < 0) {
570!
3141
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
3142
    sdbRelease(pSdb, pUser);
×
3143
  }
3144
  TAOS_RETURN(code);
570✔
3145
}
3146

3147
static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
23✔
3148
  int32_t   code = 0;
23✔
3149
  int32_t   lino = 0;
23✔
3150
  SMnode   *pMnode = pReq->info.node;
23✔
3151
  SSdb     *pSdb = pMnode->pSdb;
23✔
3152
  int32_t   numOfRows = 0;
23✔
3153
  SUserObj *pUser = NULL;
23✔
3154
  int32_t   cols = 0;
23✔
3155
  char     *pWrite = NULL;
23✔
3156
  char     *condition = NULL;
23✔
3157
  char     *sql = NULL;
23✔
3158

3159
  bool fetchNextUser = pShow->restore ? false : true;
23✔
3160
  pShow->restore = false;
23✔
3161

3162
  while (numOfRows < rows) {
118!
3163
    if (fetchNextUser) {
118!
3164
      pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
118✔
3165
      if (pShow->pIter == NULL) break;
118✔
3166
    } else {
3167
      fetchNextUser = true;
×
3168
      void *pKey = taosHashGetKey(pShow->pIter, NULL);
×
3169
      pUser = sdbAcquire(pSdb, SDB_USER, pKey);
×
3170
      if (!pUser) {
×
3171
        continue;
×
3172
      }
3173
    }
3174

3175
    int32_t numOfReadDbs = taosHashGetSize(pUser->readDbs);
95✔
3176
    int32_t numOfWriteDbs = taosHashGetSize(pUser->writeDbs);
95✔
3177
    int32_t numOfTopics = taosHashGetSize(pUser->topics);
95✔
3178
    int32_t numOfReadTbs = taosHashGetSize(pUser->readTbs);
95✔
3179
    int32_t numOfWriteTbs = taosHashGetSize(pUser->writeTbs);
95✔
3180
    int32_t numOfAlterTbs = taosHashGetSize(pUser->alterTbs);
95✔
3181
    int32_t numOfReadViews = taosHashGetSize(pUser->readViews);
95✔
3182
    int32_t numOfWriteViews = taosHashGetSize(pUser->writeViews);
95✔
3183
    int32_t numOfAlterViews = taosHashGetSize(pUser->alterViews);
95✔
3184
    if (numOfRows + numOfReadDbs + numOfWriteDbs + numOfTopics + numOfReadTbs + numOfWriteTbs + numOfAlterTbs +
95✔
3185
            numOfReadViews + numOfWriteViews + numOfAlterViews >=
95!
3186
        rows) {
3187
      mInfo(
×
3188
          "will restore. current num of rows: %d, read dbs %d, write dbs %d, topics %d, read tables %d, write tables "
3189
          "%d, alter tables %d, read views %d, write views %d, alter views %d",
3190
          numOfRows, numOfReadDbs, numOfWriteDbs, numOfTopics, numOfReadTbs, numOfWriteTbs, numOfAlterTbs,
3191
          numOfReadViews, numOfWriteViews, numOfAlterViews);
3192
      pShow->restore = true;
×
3193
      sdbRelease(pSdb, pUser);
×
3194
      break;
×
3195
    }
3196

3197
    if (pUser->superUser) {
95✔
3198
      cols = 0;
23✔
3199
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
23✔
3200
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
23✔
3201
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
23✔
3202
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, _exit);
23!
3203

3204
      char privilege[20] = {0};
23✔
3205
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "all", pShow->pMeta->pSchemas[cols].bytes);
23✔
3206
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
23✔
3207
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, _exit);
23!
3208

3209
      char objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
23✔
3210
      STR_WITH_MAXSIZE_TO_VARSTR(objName, "all", pShow->pMeta->pSchemas[cols].bytes);
23✔
3211
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
23✔
3212
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, _exit);
23!
3213

3214
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
23✔
3215
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
23✔
3216
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
23✔
3217
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, _exit);
23!
3218

3219
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
23!
3220
      if (condition == NULL) {
23!
3221
        sdbRelease(pSdb, pUser);
×
3222
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
3223
      }
3224
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
23✔
3225
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
23✔
3226
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, _exit);
23!
3227

3228
      char notes[2] = {0};
23✔
3229
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
23✔
3230
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
23✔
3231
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, _exit);
23!
3232

3233
      numOfRows++;
23✔
3234
    }
3235

3236
    char *db = taosHashIterate(pUser->readDbs, NULL);
95✔
3237
    while (db != NULL) {
114✔
3238
      cols = 0;
19✔
3239
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
19✔
3240
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
19✔
3241
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3242
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, _exit);
19!
3243

3244
      char privilege[20] = {0};
19✔
3245
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "read", pShow->pMeta->pSchemas[cols].bytes);
19✔
3246
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3247
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, _exit);
19!
3248

3249
      SName name = {0};
19✔
3250
      char  objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
19✔
3251
      code = tNameFromString(&name, db, T_NAME_ACCT | T_NAME_DB);
19✔
3252
      if (code < 0) {
19!
3253
        sdbRelease(pSdb, pUser);
×
3254
        TAOS_CHECK_GOTO(code, &lino, _exit);
×
3255
      }
3256
      (void)tNameGetDbName(&name, varDataVal(objName));
19✔
3257
      varDataSetLen(objName, strlen(varDataVal(objName)));
19✔
3258
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3259
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, _exit);
19!
3260

3261
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
19✔
3262
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
19✔
3263
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3264
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, _exit);
19!
3265

3266
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
19!
3267
      if (condition == NULL) {
19!
3268
        sdbRelease(pSdb, pUser);
×
3269
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
3270
      }
3271
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
19✔
3272
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3273
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, _exit);
19!
3274

3275
      char notes[2] = {0};
19✔
3276
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
19✔
3277
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3278
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, _exit);
19!
3279

3280
      numOfRows++;
19✔
3281
      db = taosHashIterate(pUser->readDbs, db);
19✔
3282
    }
3283

3284
    db = taosHashIterate(pUser->writeDbs, NULL);
95✔
3285
    while (db != NULL) {
114✔
3286
      cols = 0;
19✔
3287
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
19✔
3288
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
19✔
3289
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3290
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, _exit);
19!
3291

3292
      char privilege[20] = {0};
19✔
3293
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "write", pShow->pMeta->pSchemas[cols].bytes);
19✔
3294
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3295
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, _exit);
19!
3296

3297
      SName name = {0};
19✔
3298
      char  objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
19✔
3299
      code = tNameFromString(&name, db, T_NAME_ACCT | T_NAME_DB);
19✔
3300
      if (code < 0) {
19!
3301
        sdbRelease(pSdb, pUser);
×
3302
        TAOS_CHECK_GOTO(code, &lino, _exit);
×
3303
      }
3304
      (void)tNameGetDbName(&name, varDataVal(objName));
19✔
3305
      varDataSetLen(objName, strlen(varDataVal(objName)));
19✔
3306
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3307
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, _exit);
19!
3308

3309
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
19✔
3310
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
19✔
3311
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3312
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, _exit);
19!
3313

3314
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
19!
3315
      if (condition == NULL) {
19!
3316
        sdbRelease(pSdb, pUser);
×
3317
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
3318
      }
3319
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
19✔
3320
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3321
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, _exit);
19!
3322

3323
      char notes[2] = {0};
19✔
3324
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
19✔
3325
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3326
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, _exit);
19!
3327

3328
      numOfRows++;
19✔
3329
      db = taosHashIterate(pUser->writeDbs, db);
19✔
3330
    }
3331

3332
    TAOS_CHECK_EXIT(mndLoopHash(pUser->readTbs, "read", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
95!
3333

3334
    TAOS_CHECK_EXIT(mndLoopHash(pUser->writeTbs, "write", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
95!
3335

3336
    TAOS_CHECK_EXIT(mndLoopHash(pUser->alterTbs, "alter", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
95!
3337

3338
    TAOS_CHECK_EXIT(mndLoopHash(pUser->readViews, "read", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
95!
3339

3340
    TAOS_CHECK_EXIT(mndLoopHash(pUser->writeViews, "write", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
95!
3341

3342
    TAOS_CHECK_EXIT(mndLoopHash(pUser->alterViews, "alter", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
95!
3343

3344
    char *topic = taosHashIterate(pUser->topics, NULL);
95✔
3345
    while (topic != NULL) {
103✔
3346
      cols = 0;
8✔
3347
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
8✔
3348
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
8✔
3349
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
8✔
3350
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, _exit);
8!
3351

3352
      char privilege[20] = {0};
8✔
3353
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "subscribe", pShow->pMeta->pSchemas[cols].bytes);
8✔
3354
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
8✔
3355
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, _exit);
8!
3356

3357
      char topicName[TSDB_TOPIC_NAME_LEN + VARSTR_HEADER_SIZE + 5] = {0};
8✔
3358
      tstrncpy(varDataVal(topicName), mndGetDbStr(topic), TSDB_TOPIC_NAME_LEN - 2);
8✔
3359
      varDataSetLen(topicName, strlen(varDataVal(topicName)));
8✔
3360
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
8✔
3361
      COL_DATA_SET_VAL_GOTO((const char *)topicName, false, pUser, _exit);
8!
3362

3363
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
8✔
3364
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
8✔
3365
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
8✔
3366
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, _exit);
8!
3367

3368
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
8!
3369
      if (condition == NULL) {
8!
3370
        sdbRelease(pSdb, pUser);
×
3371
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
3372
      }
3373
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
8✔
3374
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
8✔
3375
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, _exit);
8!
3376

3377
      char notes[2] = {0};
8✔
3378
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
8✔
3379
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
8✔
3380
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, _exit);
8!
3381

3382
      numOfRows++;
8✔
3383
      topic = taosHashIterate(pUser->topics, topic);
8✔
3384
    }
3385

3386
    sdbRelease(pSdb, pUser);
95✔
3387
  }
3388

3389
  pShow->numOfRows += numOfRows;
23✔
3390
_exit:
23✔
3391
  taosMemoryFreeClear(condition);
23!
3392
  taosMemoryFreeClear(sql);
23!
3393
  if (code < 0) {
23!
3394
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
3395
    TAOS_RETURN(code);
×
3396
  }
3397
  return numOfRows;
23✔
3398
}
3399

3400
static void mndCancelGetNextPrivileges(SMnode *pMnode, void *pIter) {
×
3401
  SSdb *pSdb = pMnode->pSdb;
×
3402
  sdbCancelFetchByType(pSdb, pIter, SDB_USER);
×
3403
}
×
3404

3405
int32_t mndValidateUserAuthInfo(SMnode *pMnode, SUserAuthVersion *pUsers, int32_t numOfUses, void **ppRsp,
34,466✔
3406
                                int32_t *pRspLen, int64_t ipWhiteListVer) {
3407
  int32_t           code = 0;
34,466✔
3408
  int32_t           lino = 0;
34,466✔
3409
  int32_t           rspLen = 0;
34,466✔
3410
  void             *pRsp = NULL;
34,466✔
3411
  SUserAuthBatchRsp batchRsp = {0};
34,466✔
3412

3413
  batchRsp.pArray = taosArrayInit(numOfUses, sizeof(SGetUserAuthRsp));
34,466✔
3414
  if (batchRsp.pArray == NULL) {
34,466!
3415
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3416
  }
3417

3418
  for (int32_t i = 0; i < numOfUses; ++i) {
69,171✔
3419
    SUserObj *pUser = NULL;
34,705✔
3420
    code = mndAcquireUser(pMnode, pUsers[i].user, &pUser);
34,705✔
3421
    if (pUser == NULL) {
34,705✔
3422
      if (TSDB_CODE_MND_USER_NOT_EXIST == code) {
29!
3423
        SGetUserAuthRsp rsp = {.dropped = 1};
29✔
3424
        (void)memcpy(rsp.user, pUsers[i].user, TSDB_USER_LEN);
29✔
3425
        TSDB_CHECK_NULL(taosArrayPush(batchRsp.pArray, &rsp), code, lino, _OVER, TSDB_CODE_OUT_OF_MEMORY);
58!
3426
      }
3427
      mError("user:%s, failed to auth user since %s", pUsers[i].user, tstrerror(code));
29!
3428
      code = 0;
29✔
3429
      continue;
31,681✔
3430
    }
3431

3432
    pUsers[i].version = ntohl(pUsers[i].version);
34,676✔
3433
    if (pUser->authVersion <= pUsers[i].version && ipWhiteListVer == pMnode->ipWhiteVer) {
34,676✔
3434
      mndReleaseUser(pMnode, pUser);
31,652✔
3435
      continue;
31,652✔
3436
    }
3437

3438
    SGetUserAuthRsp rsp = {0};
3,024✔
3439
    code = mndSetUserAuthRsp(pMnode, pUser, &rsp);
3,024✔
3440
    if (code) {
3,024!
3441
      mndReleaseUser(pMnode, pUser);
×
3442
      tFreeSGetUserAuthRsp(&rsp);
×
3443
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3444
    }
3445

3446
    if (!(taosArrayPush(batchRsp.pArray, &rsp))) {
6,048!
3447
      code = terrno;
×
3448
      mndReleaseUser(pMnode, pUser);
×
3449
      tFreeSGetUserAuthRsp(&rsp);
×
3450
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3451
    }
3452
    mndReleaseUser(pMnode, pUser);
3,024✔
3453
  }
3454

3455
  if (taosArrayGetSize(batchRsp.pArray) <= 0) {
34,466✔
3456
    *ppRsp = NULL;
31,619✔
3457
    *pRspLen = 0;
31,619✔
3458

3459
    tFreeSUserAuthBatchRsp(&batchRsp);
31,619✔
3460
    return 0;
31,619✔
3461
  }
3462

3463
  rspLen = tSerializeSUserAuthBatchRsp(NULL, 0, &batchRsp);
2,847✔
3464
  if (rspLen < 0) {
2,847!
3465
    TAOS_CHECK_GOTO(rspLen, &lino, _OVER);
×
3466
  }
3467
  pRsp = taosMemoryMalloc(rspLen);
2,847!
3468
  if (pRsp == NULL) {
2,847!
3469
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3470
  }
3471
  rspLen = tSerializeSUserAuthBatchRsp(pRsp, rspLen, &batchRsp);
2,847✔
3472
  if (rspLen < 0) {
2,847!
3473
    TAOS_CHECK_GOTO(rspLen, &lino, _OVER);
×
3474
  }
3475
_OVER:
2,847✔
3476
  tFreeSUserAuthBatchRsp(&batchRsp);
2,847✔
3477
  if (code < 0) {
2,847!
3478
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
3479
    taosMemoryFreeClear(pRsp);
×
3480
    rspLen = 0;
×
3481
  }
3482
  *ppRsp = pRsp;
2,847✔
3483
  *pRspLen = rspLen;
2,847✔
3484

3485
  TAOS_RETURN(code);
2,847✔
3486
}
3487

3488
int32_t mndUserRemoveDb(SMnode *pMnode, STrans *pTrans, char *db) {
1,839✔
3489
  int32_t   code = 0;
1,839✔
3490
  int32_t   lino = 0;
1,839✔
3491
  SSdb     *pSdb = pMnode->pSdb;
1,839✔
3492
  int32_t   len = strlen(db) + 1;
1,839✔
3493
  void     *pIter = NULL;
1,839✔
3494
  SUserObj *pUser = NULL;
1,839✔
3495
  SUserObj  newUser = {0};
1,839✔
3496

3497
  while (1) {
2,032✔
3498
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
3,871✔
3499
    if (pIter == NULL) break;
3,871✔
3500

3501
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
2,032!
3502
      break;
×
3503
    }
3504

3505
    bool inRead = (taosHashGet(newUser.readDbs, db, len) != NULL);
2,032✔
3506
    bool inWrite = (taosHashGet(newUser.writeDbs, db, len) != NULL);
2,032✔
3507
    if (inRead || inWrite) {
2,032!
3508
      code = taosHashRemove(newUser.readDbs, db, len);
2✔
3509
      if (code < 0) {
2!
3510
        mError("failed to remove readDbs:%s from user:%s", db, pUser->user);
×
3511
      }
3512
      code = taosHashRemove(newUser.writeDbs, db, len);
2✔
3513
      if (code < 0) {
2!
3514
        mError("failed to remove writeDbs:%s from user:%s", db, pUser->user);
×
3515
      }
3516

3517
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
2✔
3518
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
2!
3519
        code = TSDB_CODE_OUT_OF_MEMORY;
×
3520
        break;
×
3521
      }
3522
      TAOS_CHECK_GOTO(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY), &lino, _OVER);
2!
3523
    }
3524

3525
    mndUserFreeObj(&newUser);
2,032✔
3526
    sdbRelease(pSdb, pUser);
2,032✔
3527
  }
3528

3529
_OVER:
1,839✔
3530
  if (pUser != NULL) sdbRelease(pSdb, pUser);
1,839!
3531
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
1,839!
3532
  mndUserFreeObj(&newUser);
1,839✔
3533
  TAOS_RETURN(code);
1,839✔
3534
}
3535

3536
int32_t mndUserRemoveStb(SMnode *pMnode, STrans *pTrans, char *stb) {
3,285✔
3537
  int32_t   code = 0;
3,285✔
3538
  SSdb     *pSdb = pMnode->pSdb;
3,285✔
3539
  int32_t   len = strlen(stb) + 1;
3,285✔
3540
  void     *pIter = NULL;
3,285✔
3541
  SUserObj *pUser = NULL;
3,285✔
3542
  SUserObj  newUser = {0};
3,285✔
3543

3544
  while (1) {
3,472✔
3545
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
6,757✔
3546
    if (pIter == NULL) break;
6,757✔
3547

3548
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
3,472!
3549
      break;
×
3550
    }
3551

3552
    bool inRead = (taosHashGet(newUser.readTbs, stb, len) != NULL);
3,472✔
3553
    bool inWrite = (taosHashGet(newUser.writeTbs, stb, len) != NULL);
3,472✔
3554
    bool inAlter = (taosHashGet(newUser.alterTbs, stb, len) != NULL);
3,472✔
3555
    if (inRead || inWrite || inAlter) {
3,472!
3556
      code = taosHashRemove(newUser.readTbs, stb, len);
×
3557
      if (code < 0) {
×
3558
        mError("failed to remove readTbs:%s from user:%s", stb, pUser->user);
×
3559
      }
3560
      code = taosHashRemove(newUser.writeTbs, stb, len);
×
3561
      if (code < 0) {
×
3562
        mError("failed to remove writeTbs:%s from user:%s", stb, pUser->user);
×
3563
      }
3564
      code = taosHashRemove(newUser.alterTbs, stb, len);
×
3565
      if (code < 0) {
×
3566
        mError("failed to remove alterTbs:%s from user:%s", stb, pUser->user);
×
3567
      }
3568

3569
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
×
3570
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
×
3571
        code = TSDB_CODE_OUT_OF_MEMORY;
×
3572
        break;
×
3573
      }
3574
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
×
3575
      if (code != 0) {
×
3576
        mndUserFreeObj(&newUser);
×
3577
        sdbRelease(pSdb, pUser);
×
3578
        TAOS_RETURN(code);
×
3579
      }
3580
    }
3581

3582
    mndUserFreeObj(&newUser);
3,472✔
3583
    sdbRelease(pSdb, pUser);
3,472✔
3584
  }
3585

3586
  if (pUser != NULL) sdbRelease(pSdb, pUser);
3,285!
3587
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
3,285!
3588
  mndUserFreeObj(&newUser);
3,285✔
3589
  TAOS_RETURN(code);
3,285✔
3590
}
3591

3592
int32_t mndUserRemoveView(SMnode *pMnode, STrans *pTrans, char *view) {
229✔
3593
  int32_t   code = 0;
229✔
3594
  SSdb     *pSdb = pMnode->pSdb;
229✔
3595
  int32_t   len = strlen(view) + 1;
229✔
3596
  void     *pIter = NULL;
229✔
3597
  SUserObj *pUser = NULL;
229✔
3598
  SUserObj  newUser = {0};
229✔
3599

3600
  while (1) {
241✔
3601
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
470✔
3602
    if (pIter == NULL) break;
470✔
3603

3604
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
241!
3605
      break;
×
3606
    }
3607

3608
    bool inRead = (taosHashGet(newUser.readViews, view, len) != NULL);
241✔
3609
    bool inWrite = (taosHashGet(newUser.writeViews, view, len) != NULL);
241✔
3610
    bool inAlter = (taosHashGet(newUser.alterViews, view, len) != NULL);
241✔
3611
    if (inRead || inWrite || inAlter) {
241!
3612
      code = taosHashRemove(newUser.readViews, view, len);
4✔
3613
      if (code < 0) {
4!
3614
        mError("failed to remove readViews:%s from user:%s", view, pUser->user);
×
3615
      }
3616
      code = taosHashRemove(newUser.writeViews, view, len);
4✔
3617
      if (code < 0) {
4!
3618
        mError("failed to remove writeViews:%s from user:%s", view, pUser->user);
4!
3619
      }
3620
      code = taosHashRemove(newUser.alterViews, view, len);
4✔
3621
      if (code < 0) {
4!
3622
        mError("failed to remove alterViews:%s from user:%s", view, pUser->user);
4!
3623
      }
3624

3625
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
4✔
3626
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
4!
3627
        code = TSDB_CODE_OUT_OF_MEMORY;
×
3628
        break;
×
3629
      }
3630
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
4✔
3631
      if (code < 0) {
4!
3632
        mndUserFreeObj(&newUser);
×
3633
        sdbRelease(pSdb, pUser);
×
3634
        TAOS_RETURN(code);
×
3635
      }
3636
    }
3637

3638
    mndUserFreeObj(&newUser);
241✔
3639
    sdbRelease(pSdb, pUser);
241✔
3640
  }
3641

3642
  if (pUser != NULL) sdbRelease(pSdb, pUser);
229!
3643
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
229!
3644
  mndUserFreeObj(&newUser);
229✔
3645
  TAOS_RETURN(code);
229✔
3646
}
3647

3648
int32_t mndUserRemoveTopic(SMnode *pMnode, STrans *pTrans, char *topic) {
322✔
3649
  int32_t   code = 0;
322✔
3650
  SSdb     *pSdb = pMnode->pSdb;
322✔
3651
  int32_t   len = strlen(topic) + 1;
322✔
3652
  void     *pIter = NULL;
322✔
3653
  SUserObj *pUser = NULL;
322✔
3654
  SUserObj  newUser = {0};
322✔
3655

3656
  while (1) {
325✔
3657
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
647✔
3658
    if (pIter == NULL) {
647✔
3659
      break;
322✔
3660
    }
3661

3662
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
325!
3663
      break;
×
3664
    }
3665

3666
    bool inTopic = (taosHashGet(newUser.topics, topic, len) != NULL);
325✔
3667
    if (inTopic) {
325!
3668
      code = taosHashRemove(newUser.topics, topic, len);
×
3669
      if (code < 0) {
×
3670
        mError("failed to remove topic:%s from user:%s", topic, pUser->user);
×
3671
      }
3672
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
×
3673
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
×
3674
        code = TSDB_CODE_OUT_OF_MEMORY;
×
3675
        break;
×
3676
      }
3677
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
×
3678
      if (code < 0) {
×
3679
        mndUserFreeObj(&newUser);
×
3680
        sdbRelease(pSdb, pUser);
×
3681
        TAOS_RETURN(code);
×
3682
      }
3683
    }
3684

3685
    mndUserFreeObj(&newUser);
325✔
3686
    sdbRelease(pSdb, pUser);
325✔
3687
  }
3688

3689
  if (pUser != NULL) sdbRelease(pSdb, pUser);
322!
3690
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
322!
3691
  mndUserFreeObj(&newUser);
322✔
3692
  TAOS_RETURN(code);
322✔
3693
}
3694

3695
int64_t mndGetUserIpWhiteListVer(SMnode *pMnode, SUserObj *pUser) {
×
3696
  // ver = 0, disable ip white list
3697
  // ver > 0, enable ip white list
3698
  return tsEnableWhiteList ? pUser->ipWhiteListVer : 0;
×
3699
}
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