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

taosdata / TDengine / #3630

06 Mar 2025 11:35AM UTC coverage: 63.629% (-0.06%) from 63.692%
#3630

push

travis-ci

web-flow
Merge pull request #30042 from taosdata/doc/internal

docs: format

149060 of 300532 branches covered (49.6%)

Branch coverage included in aggregate %.

233739 of 301077 relevant lines covered (77.63%)

17473135.72 hits per line

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

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

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

29
// clang-format on
30

31
#define USER_VER_NUMBER   6
32
#define USER_RESERVE_SIZE 64
33

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

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

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

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

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

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

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

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

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

104
void destroyIpWhiteTab(SHashObj *pIpWhiteTab);
105

106
#define MND_MAX_USE_HOST (TSDB_PRIVILEDGE_HOST_LEN / 24)
107

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

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

135
static SIpWhiteMgt ipWhiteMgt;
136

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

288
  destroyIpWhiteTab(ipWhiteMgt.pIpWhiteTab);
289

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

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

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

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

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

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

314
  ipWhiteMgtUpdateAll(pMnode);
315

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

761
  TAOS_CHECK_GOTO(tStartEncode(&encoder), &lino, _OVER);
5,161!
762
  TAOS_CHECK_GOTO(tEncodeI32(&encoder, pList->num), &lino, _OVER);
10,322!
763

764
  for (int i = 0; i < pList->num; i++) {
10,332✔
765
    SIpV4Range *pRange = &(pList->pIpRange[i]);
5,171✔
766
    TAOS_CHECK_GOTO(tEncodeU32(&encoder, pRange->ip), &lino, _OVER);
10,342!
767
    TAOS_CHECK_GOTO(tEncodeU32(&encoder, pRange->mask), &lino, _OVER);
10,342!
768
  }
769

770
  tEndEncode(&encoder);
5,161✔
771

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1173
  SDB_SET_INT32(pRaw, dataPos, len, _OVER);
5,161!
1174
  SDB_SET_BINARY(pRaw, dataPos, buf, len, _OVER);
5,161!
1175

1176
  SDB_SET_INT64(pRaw, dataPos, pUser->ipWhiteListVer, _OVER);
5,161!
1177

1178
  SDB_SET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
5,161!
1179
  SDB_SET_DATALEN(pRaw, dataPos, _OVER)
5,161!
1180

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1540
  return 0;
2,003✔
1541
}
1542

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

1551
  char *tb = taosHashIterate(pOld, NULL);
2,837,282✔
1552
  while (tb != NULL) {
2,838,209✔
1553
    size_t keyLen = 0;
930✔
1554
    char  *key = taosHashGetKey(tb, &keyLen);
930✔
1555

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

1565
  TAOS_RETURN(code);
2,837,279✔
1566
}
1567

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

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

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

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

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

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

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

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

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

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

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

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

1681
  return 0;
302✔
1682
}
1683

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

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

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

1704
static int32_t mndCreateUser(SMnode *pMnode, char *acct, SCreateUserReq *pCreate, SRpcMsg *pReq) {
149✔
1705
  int32_t  code = 0;
149✔
1706
  int32_t  lino = 0;
149✔
1707
  SUserObj userObj = {0};
149✔
1708

1709
  if (pCreate->passIsMd5 == 1) {
149!
1710
    memcpy(userObj.pass, pCreate->pass, TSDB_PASSWORD_LEN);
149✔
1711
  } else {
1712
    if (pCreate->isImport != 1) {
×
1713
      taosEncryptPass_c((uint8_t *)pCreate->pass, strlen(pCreate->pass), userObj.pass);
×
1714
    } else {
1715
      // mInfo("pCreate->pass:%s", pCreate->eass)
1716
      memcpy(userObj.pass, pCreate->pass, TSDB_PASSWORD_LEN);
×
1717
    }
1718
  }
1719

1720
  tstrncpy(userObj.user, pCreate->user, TSDB_USER_LEN);
149✔
1721
  tstrncpy(userObj.acct, acct, TSDB_USER_LEN);
149✔
1722
  userObj.createdTime = taosGetTimestampMs();
149✔
1723
  userObj.updateTime = userObj.createdTime;
149✔
1724
  userObj.superUser = 0;  // pCreate->superUser;
149✔
1725
  userObj.sysInfo = pCreate->sysInfo;
149✔
1726
  userObj.enable = pCreate->enable;
149✔
1727
  userObj.createdb = pCreate->createDb;
149✔
1728

1729
  if (pCreate->numIpRanges == 0) {
149✔
1730
    TAOS_CHECK_RETURN(createDefaultIpWhiteList(&userObj.pIpWhiteList));
146!
1731
  } else {
1732
    SHashObj *pUniqueTab = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
3✔
1733
    if (pUniqueTab == NULL) {
3!
1734
      TAOS_RETURN(terrno);
×
1735
    }
1736
    int32_t dummpy = 0;
3✔
1737
    for (int i = 0; i < pCreate->numIpRanges; i++) {
8✔
1738
      SIpV4Range range = {.ip = pCreate->pIpRanges[i].ip, .mask = pCreate->pIpRanges[i].mask};
5✔
1739
      if ((code = taosHashPut(pUniqueTab, &range, sizeof(range), &dummpy, sizeof(dummpy))) != 0) {
5!
1740
        taosHashCleanup(pUniqueTab);
×
1741
        TAOS_RETURN(code);
×
1742
      }
1743
    }
1744
    if ((code = taosHashPut(pUniqueTab, &defaultIpRange, sizeof(defaultIpRange), &dummpy, sizeof(dummpy))) != 0) {
3!
1745
      taosHashCleanup(pUniqueTab);
×
1746
      TAOS_RETURN(code);
×
1747
    }
1748

1749
    if (taosHashGetSize(pUniqueTab) > MND_MAX_USE_HOST) {
3!
1750
      taosHashCleanup(pUniqueTab);
×
1751
      TAOS_RETURN(TSDB_CODE_MND_TOO_MANY_USER_HOST);
×
1752
    }
1753

1754
    int32_t       numOfRanges = taosHashGetSize(pUniqueTab);
3✔
1755
    SIpWhiteList *p = taosMemoryCalloc(1, sizeof(SIpWhiteList) + numOfRanges * sizeof(SIpV4Range));
3!
1756
    if (p == NULL) {
3!
1757
      taosHashCleanup(pUniqueTab);
×
1758
      TAOS_RETURN(terrno);
×
1759
    }
1760
    void   *pIter = taosHashIterate(pUniqueTab, NULL);
3✔
1761
    int32_t i = 0;
3✔
1762
    while (pIter) {
9✔
1763
      size_t      len = 0;
6✔
1764
      SIpV4Range *key = taosHashGetKey(pIter, &len);
6✔
1765
      p->pIpRange[i].ip = key->ip;
6✔
1766
      p->pIpRange[i].mask = key->mask;
6✔
1767
      pIter = taosHashIterate(pUniqueTab, pIter);
6✔
1768

1769
      i++;
6✔
1770
    }
1771

1772
    taosHashCleanup(pUniqueTab);
3✔
1773
    p->num = numOfRanges;
3✔
1774
    userObj.pIpWhiteList = p;
3✔
1775
  }
1776

1777
  userObj.ipWhiteListVer = taosGetTimestampMs();
149✔
1778

1779
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "create-user");
149✔
1780
  if (pTrans == NULL) {
149!
1781
    mError("user:%s, failed to create since %s", pCreate->user, terrstr());
×
1782
    taosMemoryFree(userObj.pIpWhiteList);
×
1783
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1784
  }
1785
  mInfo("trans:%d, used to create user:%s", pTrans->id, pCreate->user);
149!
1786

1787
  SSdbRaw *pCommitRaw = mndUserActionEncode(&userObj);
149✔
1788
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
149!
1789
    mError("trans:%d, failed to commit redo log since %s", pTrans->id, terrstr());
×
1790
    mndTransDrop(pTrans);
×
1791
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
1792
  }
1793
  TAOS_CHECK_GOTO(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY), &lino, _OVER);
149!
1794

1795
  if (mndTransPrepare(pMnode, pTrans) != 0) {
149!
1796
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
1797
    mndTransDrop(pTrans);
×
1798
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1799
  }
1800
  if ((code = ipWhiteMgtUpdate(pMnode, userObj.user, userObj.pIpWhiteList)) != 0) {
149!
1801
    mndTransDrop(pTrans);
×
1802
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
1803
  }
1804

1805
  taosMemoryFree(userObj.pIpWhiteList);
149!
1806
  mndTransDrop(pTrans);
149✔
1807
  return 0;
149✔
1808
_OVER:
×
1809
  taosMemoryFree(userObj.pIpWhiteList);
×
1810

1811
  TAOS_RETURN(code);
×
1812
}
1813

1814
static int32_t mndCheckPasswordMinLen(const char *pwd, int32_t len) {
×
1815
  if (len < TSDB_PASSWORD_MIN_LEN) {
×
1816
    return -1;
×
1817
  }
1818
  return 0;
×
1819
}
1820

1821
static int32_t mndCheckPasswordMaxLen(const char *pwd, int32_t len) {
×
1822
  if (len > TSDB_PASSWORD_MAX_LEN) {
×
1823
    return -1;
×
1824
  }
1825
  return 0;
×
1826
}
1827

1828
static int32_t mndCheckPasswordFmt(const char *pwd, int32_t len) {
×
1829
  if (strcmp(pwd, "taosdata") == 0) {
×
1830
    return 0;
×
1831
  }
1832

1833
  bool charTypes[4] = {0};
×
1834
  for (int32_t i = 0; i < len; ++i) {
×
1835
    if (taosIsBigChar(pwd[i])) {
×
1836
      charTypes[0] = true;
×
1837
    } else if (taosIsSmallChar(pwd[i])) {
×
1838
      charTypes[1] = true;
×
1839
    } else if (taosIsNumberChar(pwd[i])) {
×
1840
      charTypes[2] = true;
×
1841
    } else if (taosIsSpecialChar(pwd[i])) {
×
1842
      charTypes[3] = true;
×
1843
    } else {
1844
      return -1;
×
1845
    }
1846
  }
1847

1848
  int32_t numOfTypes = 0;
×
1849
  for (int32_t i = 0; i < 4; ++i) {
×
1850
    numOfTypes += charTypes[i];
×
1851
  }
1852

1853
  if (numOfTypes < 3) {
×
1854
    return -1;
×
1855
  }
1856

1857
  return 0;
×
1858
}
1859

1860
static int32_t mndProcessCreateUserReq(SRpcMsg *pReq) {
149✔
1861
  SMnode        *pMnode = pReq->info.node;
149✔
1862
  int32_t        code = 0;
149✔
1863
  int32_t        lino = 0;
149✔
1864
  SUserObj      *pUser = NULL;
149✔
1865
  SUserObj      *pOperUser = NULL;
149✔
1866
  SCreateUserReq createReq = {0};
149✔
1867

1868
  if (tDeserializeSCreateUserReq(pReq->pCont, pReq->contLen, &createReq) != 0) {
149!
1869
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
1870
  }
1871

1872
  mInfo("user:%s, start to create, createdb:%d, is_import:%d", createReq.user, createReq.isImport, createReq.createDb);
149!
1873

1874
#ifndef TD_ENTERPRISE
1875
  if (createReq.isImport == 1) {
1876
    TAOS_CHECK_GOTO(TSDB_CODE_OPS_NOT_SUPPORT, &lino, _OVER);  // enterprise feature
1877
  }
1878
#endif
1879

1880
  if (createReq.isImport != 1) {
149!
1881
    TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CREATE_USER), &lino, _OVER);
149!
1882
  } else {
1883
    if (strcmp(pReq->info.conn.user, "root") != 0) {
×
1884
      mError("The operation is not permitted, user:%s", pReq->info.conn.user);
×
1885
      TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_RIGHTS, &lino, _OVER);
×
1886
    }
1887
  }
1888

1889
  if (createReq.user[0] == 0) {
149!
1890
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
1891
  }
1892

1893
  if(createReq.passIsMd5 == 0){
149!
1894
    int32_t len = strlen(createReq.pass);
×
1895
    if (createReq.isImport != 1) {
×
1896
      if (mndCheckPasswordMinLen(createReq.pass, len) != 0) {
×
1897
        TAOS_CHECK_GOTO(TSDB_CODE_PAR_PASSWD_TOO_SHORT_OR_EMPTY, &lino, _OVER);
×
1898
      }
1899
      if (mndCheckPasswordMaxLen(createReq.pass, len) != 0) {
×
1900
        TAOS_CHECK_GOTO(TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG, &lino, _OVER);
×
1901
      }
1902
      if (mndCheckPasswordFmt(createReq.pass, len) != 0) {
×
1903
        TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_PASS_FORMAT, &lino, _OVER);
×
1904
      }
1905
    }
1906
  }
1907

1908
  code = mndAcquireUser(pMnode, createReq.user, &pUser);
149✔
1909
  if (pUser != NULL) {
149!
1910
    TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_ALREADY_EXIST, &lino, _OVER);
×
1911
  }
1912

1913
  code = mndAcquireUser(pMnode, pReq->info.conn.user, &pOperUser);
149✔
1914
  if (pOperUser == NULL) {
149!
1915
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_USER_FROM_CONN, &lino, _OVER);
×
1916
  }
1917

1918
  TAOS_CHECK_GOTO(grantCheck(TSDB_GRANT_USER), &lino, _OVER);
149!
1919

1920
  code = mndCreateUser(pMnode, pOperUser->acct, &createReq, pReq);
149✔
1921
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
149!
1922

1923
  char detail[1000] = {0};
149✔
1924
  (void)tsnprintf(detail, sizeof(detail), "enable:%d, superUser:%d, sysInfo:%d, password:xxx", createReq.enable,
149✔
1925
            createReq.superUser, createReq.sysInfo);
149✔
1926
  char operation[15] = {0};
149✔
1927
  if (createReq.isImport == 1) {
149!
1928
    tstrncpy(operation, "importUser", sizeof(operation));
×
1929
  } else {
1930
    tstrncpy(operation, "createUser", sizeof(operation));
149✔
1931
  }
1932

1933
  auditRecord(pReq, pMnode->clusterId, operation, "", createReq.user, detail, strlen(detail));
149✔
1934

1935
_OVER:
149✔
1936
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
149!
1937
    mError("user:%s, failed to create at line %d since %s", createReq.user, lino, tstrerror(code));
×
1938
  }
1939

1940
  mndReleaseUser(pMnode, pUser);
149✔
1941
  mndReleaseUser(pMnode, pOperUser);
149✔
1942
  tFreeSCreateUserReq(&createReq);
149✔
1943

1944
  TAOS_RETURN(code);
149✔
1945
}
1946

1947
int32_t mndProcessGetUserWhiteListReq(SRpcMsg *pReq) {
95✔
1948
  SMnode              *pMnode = pReq->info.node;
95✔
1949
  int32_t              code = 0;
95✔
1950
  int32_t              lino = 0;
95✔
1951
  int32_t              contLen = 0;
95✔
1952
  void                *pRsp = NULL;
95✔
1953
  SUserObj            *pUser = NULL;
95✔
1954
  SGetUserWhiteListReq wlReq = {0};
95✔
1955
  SGetUserWhiteListRsp wlRsp = {0};
95✔
1956

1957
  if (tDeserializeSGetUserWhiteListReq(pReq->pCont, pReq->contLen, &wlReq) != 0) {
95!
1958
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_MSG, &lino, _OVER);
×
1959
  }
1960
  mTrace("user: %s, start to get whitelist", wlReq.user);
95✔
1961

1962
  code = mndAcquireUser(pMnode, wlReq.user, &pUser);
95✔
1963
  if (pUser == NULL) {
95!
1964
    TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_NOT_EXIST, &lino, _OVER);
×
1965
  }
1966

1967
  TAOS_CHECK_GOTO(mndSetUserWhiteListRsp(pMnode, pUser, &wlRsp), &lino, _OVER);
95!
1968

1969
  contLen = tSerializeSGetUserWhiteListRsp(NULL, 0, &wlRsp);
95✔
1970
  if (contLen < 0) {
95!
1971
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
1972
  }
1973
  pRsp = rpcMallocCont(contLen);
95✔
1974
  if (pRsp == NULL) {
95!
1975
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
1976
  }
1977

1978
  contLen = tSerializeSGetUserWhiteListRsp(pRsp, contLen, &wlRsp);
95✔
1979
  if (contLen < 0) {
95!
1980
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
×
1981
  }
1982

1983
_OVER:
95✔
1984
  mndReleaseUser(pMnode, pUser);
95✔
1985
  tFreeSGetUserWhiteListRsp(&wlRsp);
95✔
1986
  if (code < 0) {
95!
1987
    mError("user:%s, failed to get whitelist at line %d since %s", wlReq.user, lino, tstrerror(code));
×
1988
    rpcFreeCont(pRsp);
×
1989
    pRsp = NULL;
×
1990
    contLen = 0;
×
1991
  }
1992
  pReq->code = code;
95✔
1993
  pReq->info.rsp = pRsp;
95✔
1994
  pReq->info.rspLen = contLen;
95✔
1995

1996
  TAOS_RETURN(code);
95✔
1997
}
1998

1999
int32_t mndProcesSRetrieveIpWhiteReq(SRpcMsg *pReq) {
6✔
2000
  int32_t        code = 0;
6✔
2001
  int32_t        lino = 0;
6✔
2002
  int32_t        len = 0;
6✔
2003
  void          *pRsp = NULL;
6✔
2004
  SUpdateIpWhite ipWhite = {0};
6✔
2005

2006
  // impl later
2007
  SRetrieveIpWhiteReq req = {0};
6✔
2008
  if (tDeserializeRetrieveIpWhite(pReq->pCont, pReq->contLen, &req) != 0) {
6!
2009
    code = TSDB_CODE_INVALID_MSG;
×
2010
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2011
  }
2012

2013
  TAOS_CHECK_GOTO(ipWhiteMgtFillMsg(&ipWhite), &lino, _OVER);
6!
2014

2015
  len = tSerializeSUpdateIpWhite(NULL, 0, &ipWhite);
6✔
2016
  if (len < 0) {
6!
2017
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
2018
  }
2019

2020
  pRsp = rpcMallocCont(len);
6✔
2021
  if (!pRsp) {
6!
2022
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2023
  }
2024
  len = tSerializeSUpdateIpWhite(pRsp, len, &ipWhite);
6✔
2025
  if (len < 0) {
6!
2026
    TAOS_CHECK_GOTO(len, &lino, _OVER);
×
2027
  }
2028

2029
_OVER:
6✔
2030
  if (code < 0) {
6!
2031
    mError("failed to process retrieve ip white request at line %d since %s", lino, tstrerror(code));
×
2032
    rpcFreeCont(pRsp);
×
2033
    pRsp = NULL;
×
2034
    len = 0;
×
2035
  }
2036
  pReq->code = code;
6✔
2037
  pReq->info.rsp = pRsp;
6✔
2038
  pReq->info.rspLen = len;
6✔
2039

2040
  tFreeSUpdateIpWhiteReq(&ipWhite);
6✔
2041
  TAOS_RETURN(code);
6✔
2042
}
2043

2044
static int32_t mndAlterUser(SMnode *pMnode, SUserObj *pOld, SUserObj *pNew, SRpcMsg *pReq) {
238✔
2045
  int32_t code = 0;
238✔
2046
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "alter-user");
238✔
2047
  if (pTrans == NULL) {
238!
2048
    mError("user:%s, failed to alter since %s", pOld->user, terrstr());
×
2049
    TAOS_RETURN(terrno);
×
2050
  }
2051
  mInfo("trans:%d, used to alter user:%s", pTrans->id, pOld->user);
238!
2052

2053
  SSdbRaw *pCommitRaw = mndUserActionEncode(pNew);
238✔
2054
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
238!
2055
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
2056
    mndTransDrop(pTrans);
×
2057
    TAOS_RETURN(terrno);
×
2058
  }
2059
  code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
238✔
2060
  if (code < 0) {
238!
2061
    mndTransDrop(pTrans);
×
2062
    TAOS_RETURN(code);
×
2063
  }
2064

2065
  if (mndTransPrepare(pMnode, pTrans) != 0) {
238!
2066
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
2067
    mndTransDrop(pTrans);
×
2068
    TAOS_RETURN(terrno);
×
2069
  }
2070
  if ((code = ipWhiteMgtUpdate(pMnode, pNew->user, pNew->pIpWhiteList)) != 0) {
238!
2071
    mndTransDrop(pTrans);
×
2072
    TAOS_RETURN(code);
×
2073
  }
2074
  mndTransDrop(pTrans);
238✔
2075
  return 0;
238✔
2076
}
2077

2078
static int32_t mndDupObjHash(SHashObj *pOld, int32_t dataLen, SHashObj **ppNew) {
815,538✔
2079
  int32_t code = 0;
815,538✔
2080

2081
  *ppNew =
815,538✔
2082
      taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
815,538✔
2083
  if (*ppNew == NULL) {
815,538!
2084
    code = terrno ? terrno : TSDB_CODE_OUT_OF_MEMORY;
×
2085
    TAOS_RETURN(code);
×
2086
  }
2087

2088
  char *db = taosHashIterate(pOld, NULL);
815,538✔
2089
  while (db != NULL) {
816,003✔
2090
    int32_t len = strlen(db) + 1;
466✔
2091
    if ((code = taosHashPut(*ppNew, db, len, db, dataLen)) != 0) {
466!
2092
      taosHashCancelIterate(pOld, db);
×
2093
      taosHashCleanup(*ppNew);
×
2094
      TAOS_RETURN(code);
×
2095
    }
2096
    db = taosHashIterate(pOld, db);
466✔
2097
  }
2098

2099
  TAOS_RETURN(code);
815,537✔
2100
}
2101

2102
int32_t mndDupDbHash(SHashObj *pOld, SHashObj **ppNew) { return mndDupObjHash(pOld, TSDB_DB_FNAME_LEN, ppNew); }
811,743✔
2103

2104
int32_t mndDupTopicHash(SHashObj *pOld, SHashObj **ppNew) { return mndDupObjHash(pOld, TSDB_TOPIC_FNAME_LEN, ppNew); }
3,795✔
2105

2106
static int32_t mndTablePriviledge(SMnode *pMnode, SHashObj *hash, SHashObj *useDbHash, SAlterUserReq *alterReq,
86✔
2107
                                  SSdb *pSdb) {
2108
  void *pIter = NULL;
86✔
2109
  char  tbFName[TSDB_TABLE_FNAME_LEN] = {0};
86✔
2110

2111
  (void)snprintf(tbFName, sizeof(tbFName), "%s.%s", alterReq->objname, alterReq->tabName);
86✔
2112
  int32_t len = strlen(tbFName) + 1;
86✔
2113

2114
  if (alterReq->tagCond != NULL && alterReq->tagCondLen != 0) {
109!
2115
    char *value = taosHashGet(hash, tbFName, len);
23✔
2116
    if (value != NULL) {
23!
2117
      TAOS_RETURN(TSDB_CODE_MND_PRIVILEDGE_EXIST);
×
2118
    }
2119

2120
    int32_t condLen = alterReq->tagCondLen;
23✔
2121
    TAOS_CHECK_RETURN(taosHashPut(hash, tbFName, len, alterReq->tagCond, condLen));
23!
2122
  } else {
2123
    TAOS_CHECK_RETURN(taosHashPut(hash, tbFName, len, alterReq->isView ? "v" : "t", 2));
63!
2124
  }
2125

2126
  int32_t  dbKeyLen = strlen(alterReq->objname) + 1;
86✔
2127
  int32_t  ref = 1;
86✔
2128
  int32_t *currRef = taosHashGet(useDbHash, alterReq->objname, dbKeyLen);
86✔
2129
  if (NULL != currRef) {
86✔
2130
    ref = (*currRef) + 1;
30✔
2131
  }
2132
  TAOS_CHECK_RETURN(taosHashPut(useDbHash, alterReq->objname, dbKeyLen, &ref, sizeof(ref)));
86!
2133

2134
  TAOS_RETURN(0);
86✔
2135
}
2136

2137
static int32_t mndRemoveTablePriviledge(SMnode *pMnode, SHashObj *hash, SHashObj *useDbHash, SAlterUserReq *alterReq,
11✔
2138
                                        SSdb *pSdb) {
2139
  void *pIter = NULL;
11✔
2140
  char  tbFName[TSDB_TABLE_FNAME_LEN] = {0};
11✔
2141
  (void)snprintf(tbFName, sizeof(tbFName), "%s.%s", alterReq->objname, alterReq->tabName);
11✔
2142
  int32_t len = strlen(tbFName) + 1;
11✔
2143

2144
  if (taosHashRemove(hash, tbFName, len) != 0) {
11!
2145
    TAOS_RETURN(0);  // not found
×
2146
  }
2147

2148
  int32_t  dbKeyLen = strlen(alterReq->objname) + 1;
11✔
2149
  int32_t *currRef = taosHashGet(useDbHash, alterReq->objname, dbKeyLen);
11✔
2150
  if (NULL == currRef) {
11!
2151
    return 0;
×
2152
  }
2153

2154
  if (1 == *currRef) {
11!
2155
    if (taosHashRemove(useDbHash, alterReq->objname, dbKeyLen) != 0) {
11!
2156
      TAOS_RETURN(0);  // not found
×
2157
    }
2158
    return 0;
11✔
2159
  }
2160
  int32_t ref = (*currRef) - 1;
×
2161
  TAOS_CHECK_RETURN(taosHashPut(useDbHash, alterReq->objname, dbKeyLen, &ref, sizeof(ref)));
×
2162

2163
  return 0;
×
2164
}
2165

2166
static char *mndUserAuditTypeStr(int32_t type) {
35✔
2167
  if (type == TSDB_ALTER_USER_PASSWD) {
35!
2168
    return "changePassword";
35✔
2169
  }
2170
  if (type == TSDB_ALTER_USER_SUPERUSER) {
×
2171
    return "changeSuperUser";
×
2172
  }
2173
  if (type == TSDB_ALTER_USER_ENABLE) {
×
2174
    return "enableUser";
×
2175
  }
2176
  if (type == TSDB_ALTER_USER_SYSINFO) {
×
2177
    return "userSysInfo";
×
2178
  }
2179
  if (type == TSDB_ALTER_USER_CREATEDB) {
×
2180
    return "userCreateDB";
×
2181
  }
2182
  return "error";
×
2183
}
2184

2185
static int32_t mndProcessAlterUserPrivilegesReq(SAlterUserReq *pAlterReq, SMnode *pMnode, SUserObj *pNewUser) {
186✔
2186
  SSdb   *pSdb = pMnode->pSdb;
186✔
2187
  void   *pIter = NULL;
186✔
2188
  int32_t code = 0;
186✔
2189
  int32_t lino = 0;
186✔
2190

2191
  if (ALTER_USER_ADD_READ_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
186✔
2192
      ALTER_USER_ADD_ALL_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
140!
2193
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
46✔
2194
      int32_t len = strlen(pAlterReq->objname) + 1;
43✔
2195
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
43✔
2196
      if (pDb == NULL) {
43✔
2197
        mndReleaseDb(pMnode, pDb);
6✔
2198
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
6!
2199
      }
2200
      if ((code = taosHashPut(pNewUser->readDbs, pAlterReq->objname, len, pAlterReq->objname, TSDB_DB_FNAME_LEN)) !=
37!
2201
          0) {
2202
        mndReleaseDb(pMnode, pDb);
×
2203
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2204
      }
2205
      mndReleaseDb(pMnode, pDb);
37✔
2206
    } else {
2207
      while (1) {
9✔
2208
        SDbObj *pDb = NULL;
12✔
2209
        pIter = sdbFetch(pSdb, SDB_DB, pIter, (void **)&pDb);
12✔
2210
        if (pIter == NULL) break;
12✔
2211
        int32_t len = strlen(pDb->name) + 1;
9✔
2212
        if ((code = taosHashPut(pNewUser->readDbs, pDb->name, len, pDb->name, TSDB_DB_FNAME_LEN)) != 0) {
9!
2213
          sdbRelease(pSdb, pDb);
×
2214
          sdbCancelFetch(pSdb, pIter);
×
2215
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2216
        }
2217
        sdbRelease(pSdb, pDb);
9✔
2218
      }
2219
    }
2220
  }
2221

2222
  if (ALTER_USER_ADD_WRITE_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
180✔
2223
      ALTER_USER_ADD_ALL_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
140!
2224
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
40✔
2225
      int32_t len = strlen(pAlterReq->objname) + 1;
37✔
2226
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
37✔
2227
      if (pDb == NULL) {
37✔
2228
        mndReleaseDb(pMnode, pDb);
1✔
2229
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
1!
2230
      }
2231
      if ((code = taosHashPut(pNewUser->writeDbs, pAlterReq->objname, len, pAlterReq->objname, TSDB_DB_FNAME_LEN)) !=
36!
2232
          0) {
2233
        mndReleaseDb(pMnode, pDb);
×
2234
        TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2235
      }
2236
      mndReleaseDb(pMnode, pDb);
36✔
2237
    } else {
2238
      while (1) {
9✔
2239
        SDbObj *pDb = NULL;
12✔
2240
        pIter = sdbFetch(pSdb, SDB_DB, pIter, (void **)&pDb);
12✔
2241
        if (pIter == NULL) break;
12✔
2242
        int32_t len = strlen(pDb->name) + 1;
9✔
2243
        if ((code = taosHashPut(pNewUser->writeDbs, pDb->name, len, pDb->name, TSDB_DB_FNAME_LEN)) != 0) {
9!
2244
          sdbRelease(pSdb, pDb);
×
2245
          sdbCancelFetch(pSdb, pIter);
×
2246
          TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2247
        }
2248
        sdbRelease(pSdb, pDb);
9✔
2249
      }
2250
    }
2251
  }
2252

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

2272
  if (ALTER_USER_DEL_WRITE_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
179✔
2273
      ALTER_USER_DEL_ALL_DB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
157!
2274
    if (strcmp(pAlterReq->objname, "1.*") != 0) {
22✔
2275
      int32_t len = strlen(pAlterReq->objname) + 1;
19✔
2276
      SDbObj *pDb = mndAcquireDb(pMnode, pAlterReq->objname);
19✔
2277
      if (pDb == NULL) {
19!
2278
        mndReleaseDb(pMnode, pDb);
×
2279
        TAOS_CHECK_GOTO(terrno, &lino, _OVER);  // TODO: refactor the terrno to code
×
2280
      }
2281
      code = taosHashRemove(pNewUser->writeDbs, pAlterReq->objname, len);
19✔
2282
      if (code < 0) {
19!
2283
        mError("user:%s, failed to remove db:%s since %s", pNewUser->user, pAlterReq->objname, terrstr());
×
2284
      }
2285
      mndReleaseDb(pMnode, pDb);
19✔
2286
    } else {
2287
      taosHashClear(pNewUser->writeDbs);
3✔
2288
    }
2289
  }
2290

2291
  SHashObj *pReadTbs = pNewUser->readTbs;
179✔
2292
  SHashObj *pWriteTbs = pNewUser->writeTbs;
179✔
2293
  SHashObj *pAlterTbs = pNewUser->alterTbs;
179✔
2294

2295
#ifdef TD_ENTERPRISE
2296
  if (pAlterReq->isView) {
179✔
2297
    pReadTbs = pNewUser->readViews;
18✔
2298
    pWriteTbs = pNewUser->writeViews;
18✔
2299
    pAlterTbs = pNewUser->alterViews;
18✔
2300
  }
2301
#endif
2302

2303
  if (ALTER_USER_ADD_READ_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
179✔
2304
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
143!
2305
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pReadTbs, pNewUser->useDbs, pAlterReq, pSdb), &lino, _OVER);
36!
2306
  }
2307

2308
  if (ALTER_USER_ADD_WRITE_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
179✔
2309
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
144!
2310
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pWriteTbs, pNewUser->useDbs, pAlterReq, pSdb), &lino, _OVER);
35!
2311
  }
2312

2313
  if (ALTER_USER_ADD_ALTER_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
179✔
2314
      ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
164!
2315
    TAOS_CHECK_GOTO(mndTablePriviledge(pMnode, pAlterTbs, pNewUser->useDbs, pAlterReq, pSdb), &lino, _OVER);
15!
2316
  }
2317

2318
  if (ALTER_USER_DEL_READ_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
179✔
2319
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
173!
2320
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pReadTbs, pNewUser->useDbs, pAlterReq, pSdb), &lino, _OVER);
6!
2321
  }
2322

2323
  if (ALTER_USER_DEL_WRITE_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
179✔
2324
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
174!
2325
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pWriteTbs, pNewUser->useDbs, pAlterReq, pSdb), &lino, _OVER);
5!
2326
  }
2327

2328
  if (ALTER_USER_DEL_ALTER_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) ||
179!
2329
      ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) {
179!
2330
    TAOS_CHECK_GOTO(mndRemoveTablePriviledge(pMnode, pAlterTbs, pNewUser->useDbs, pAlterReq, pSdb), &lino, _OVER);
×
2331
  }
2332

2333
  if (ALTER_USER_ADD_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, pAlterReq->privileges)) {
179✔
2334
    int32_t      len = strlen(pAlterReq->objname) + 1;
15✔
2335
    SMqTopicObj *pTopic = NULL;
15✔
2336
    if ((code = mndAcquireTopic(pMnode, pAlterReq->objname, &pTopic)) != 0) {
15!
2337
      mndReleaseTopic(pMnode, pTopic);
×
2338
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2339
    }
2340
    if ((code = taosHashPut(pNewUser->topics, pTopic->name, len, pTopic->name, TSDB_TOPIC_FNAME_LEN)) != 0) {
15!
2341
      mndReleaseTopic(pMnode, pTopic);
×
2342
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
2343
    }
2344
    mndReleaseTopic(pMnode, pTopic);
15✔
2345
  }
2346

2347
  if (ALTER_USER_DEL_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, pAlterReq->privileges)) {
179✔
2348
    int32_t      len = strlen(pAlterReq->objname) + 1;
11✔
2349
    SMqTopicObj *pTopic = NULL;
11✔
2350
    if ((code = mndAcquireTopic(pMnode, pAlterReq->objname, &pTopic)) != 0) {
11✔
2351
      mndReleaseTopic(pMnode, pTopic);
1✔
2352
      TAOS_CHECK_GOTO(code, &lino, _OVER);
1!
2353
    }
2354
    code = taosHashRemove(pNewUser->topics, pAlterReq->objname, len);
10✔
2355
    if (code < 0) {
10!
2356
      mError("user:%s, failed to remove topic:%s since %s", pNewUser->user, pAlterReq->objname, tstrerror(code));
×
2357
    }
2358
    mndReleaseTopic(pMnode, pTopic);
10✔
2359
  }
2360

2361
_OVER:
168✔
2362
  if (code < 0) {
186✔
2363
    mError("user:%s, failed to alter user privileges at line %d since %s", pAlterReq->user, lino, tstrerror(code));
8!
2364
  }
2365
  TAOS_RETURN(code);
186✔
2366
}
2367

2368
static int32_t mndProcessAlterUserReq(SRpcMsg *pReq) {
317✔
2369
  SMnode       *pMnode = pReq->info.node;
317✔
2370
  SSdb         *pSdb = pMnode->pSdb;
317✔
2371
  void         *pIter = NULL;
317✔
2372
  int32_t       code = 0;
317✔
2373
  int32_t       lino = 0;
317✔
2374
  SUserObj     *pUser = NULL;
317✔
2375
  SUserObj     *pOperUser = NULL;
317✔
2376
  SUserObj      newUser = {0};
317✔
2377
  SAlterUserReq alterReq = {0};
317✔
2378

2379
  TAOS_CHECK_GOTO(tDeserializeSAlterUserReq(pReq->pCont, pReq->contLen, &alterReq), &lino, _OVER);
317!
2380

2381
  mInfo("user:%s, start to alter", alterReq.user);
317!
2382

2383
  if (alterReq.user[0] == 0) {
317!
2384
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
2385
  }
2386
  if(alterReq.passIsMd5 == 0){
317✔
2387
    if (TSDB_ALTER_USER_PASSWD == alterReq.alterType) {
281!
2388
      int32_t len = strlen(alterReq.pass);
×
2389
      if (mndCheckPasswordMinLen(alterReq.pass, len) != 0) {
×
2390
        TAOS_CHECK_GOTO(TSDB_CODE_PAR_PASSWD_TOO_SHORT_OR_EMPTY, &lino, _OVER);
×
2391
      }
2392
      if (mndCheckPasswordMaxLen(alterReq.pass, len) != 0) {
×
2393
        TAOS_CHECK_GOTO(TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG, &lino, _OVER);
×
2394
      }
2395
      if (mndCheckPasswordFmt(alterReq.pass, len) != 0) {
×
2396
        TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_PASS_FORMAT, &lino, _OVER);
×
2397
      }
2398
    }
2399
  }
2400

2401
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, alterReq.user, &pUser), &lino, _OVER);
317✔
2402

2403
  (void)mndAcquireUser(pMnode, pReq->info.conn.user, &pOperUser);
295✔
2404
  if (pOperUser == NULL) {
295!
2405
    TAOS_CHECK_GOTO(TSDB_CODE_MND_NO_USER_FROM_CONN, &lino, _OVER);
×
2406
  }
2407

2408
  TAOS_CHECK_GOTO(mndCheckAlterUserPrivilege(pOperUser, pUser, &alterReq), &lino, _OVER);
295✔
2409

2410
  TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER);
247!
2411

2412
  if (alterReq.alterType == TSDB_ALTER_USER_PASSWD) {
247✔
2413
    if (alterReq.passIsMd5 == 1) {
35!
2414
      (void)memcpy(newUser.pass, alterReq.pass, TSDB_PASSWORD_LEN);
35✔
2415
    } else {
2416
      taosEncryptPass_c((uint8_t *)alterReq.pass, strlen(alterReq.pass), newUser.pass);
×
2417
    }
2418

2419
    if (0 != strncmp(pUser->pass, newUser.pass, TSDB_PASSWORD_LEN)) {
35✔
2420
      ++newUser.passVersion;
31✔
2421
    }
2422
  }
2423

2424
  if (alterReq.alterType == TSDB_ALTER_USER_SUPERUSER) {
247!
2425
    newUser.superUser = alterReq.superUser;
×
2426
  }
2427

2428
  if (alterReq.alterType == TSDB_ALTER_USER_ENABLE) {
247✔
2429
    newUser.enable = alterReq.enable;
5✔
2430
  }
2431

2432
  if (alterReq.alterType == TSDB_ALTER_USER_SYSINFO) {
247✔
2433
    newUser.sysInfo = alterReq.sysInfo;
14✔
2434
  }
2435

2436
  if (alterReq.alterType == TSDB_ALTER_USER_CREATEDB) {
247✔
2437
    newUser.createdb = alterReq.createdb;
5✔
2438
  }
2439

2440
  if (ALTER_USER_ADD_PRIVS(alterReq.alterType) || ALTER_USER_DEL_PRIVS(alterReq.alterType)) {
247✔
2441
    TAOS_CHECK_GOTO(mndProcessAlterUserPrivilegesReq(&alterReq, pMnode, &newUser), &lino, _OVER);
186✔
2442
  }
2443

2444
  if (alterReq.alterType == TSDB_ALTER_USER_ADD_WHITE_LIST) {
239✔
2445
    taosMemoryFreeClear(newUser.pIpWhiteList);
1!
2446

2447
    int32_t       num = pUser->pIpWhiteList->num + alterReq.numIpRanges;
1✔
2448
    int32_t       idx = pUser->pIpWhiteList->num;
1✔
2449
    SIpWhiteList *pNew = taosMemoryCalloc(1, sizeof(SIpWhiteList) + sizeof(SIpV4Range) * num);
1!
2450

2451
    if (pNew == NULL) {
1!
2452
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2453
    }
2454

2455
    bool exist = false;
1✔
2456
    (void)memcpy(pNew->pIpRange, pUser->pIpWhiteList->pIpRange, sizeof(SIpV4Range) * idx);
1✔
2457
    for (int i = 0; i < alterReq.numIpRanges; i++) {
2✔
2458
      SIpV4Range *range = &(alterReq.pIpRanges[i]);
1✔
2459
      if (!isRangeInIpWhiteList(pUser->pIpWhiteList, range)) {
1!
2460
        // already exist, just ignore;
2461
        (void)memcpy(&pNew->pIpRange[idx], range, sizeof(SIpV4Range));
1✔
2462
        idx++;
1✔
2463
        continue;
1✔
2464
      } else {
2465
        exist = true;
×
2466
      }
2467
    }
2468
    if (exist) {
1!
2469
      taosMemoryFree(pNew);
×
2470
      TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_HOST_EXIST, &lino, _OVER);
×
2471
    }
2472
    pNew->num = idx;
1✔
2473
    newUser.pIpWhiteList = pNew;
1✔
2474
    newUser.ipWhiteListVer = pUser->ipWhiteListVer + 1;
1✔
2475

2476
    if (pNew->num > MND_MAX_USE_HOST) {
1!
2477
      TAOS_CHECK_GOTO(TSDB_CODE_MND_TOO_MANY_USER_HOST, &lino, _OVER);
×
2478
    }
2479
  }
2480
  if (alterReq.alterType == TSDB_ALTER_USER_DROP_WHITE_LIST) {
239✔
2481
    taosMemoryFreeClear(newUser.pIpWhiteList);
1!
2482

2483
    int32_t       num = pUser->pIpWhiteList->num;
1✔
2484
    bool          noexist = true;
1✔
2485
    bool          localHost = false;
1✔
2486
    SIpWhiteList *pNew = taosMemoryCalloc(1, sizeof(SIpWhiteList) + sizeof(SIpV4Range) * num);
1!
2487

2488
    if (pNew == NULL) {
1!
2489
      TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
2490
    }
2491

2492
    if (pUser->pIpWhiteList->num > 0) {
1!
2493
      int idx = 0;
1✔
2494
      for (int i = 0; i < pUser->pIpWhiteList->num; i++) {
3✔
2495
        SIpV4Range *oldRange = &pUser->pIpWhiteList->pIpRange[i];
2✔
2496
        bool        found = false;
2✔
2497
        for (int j = 0; j < alterReq.numIpRanges; j++) {
4✔
2498
          SIpV4Range *range = &alterReq.pIpRanges[j];
2✔
2499
          if (isDefaultRange(range)) {
2!
2500
            localHost = true;
×
2501
            break;
×
2502
          }
2503
          if (isIpRangeEqual(oldRange, range)) {
2!
2504
            found = true;
×
2505
            break;
×
2506
          }
2507
        }
2508
        if (localHost) break;
2!
2509

2510
        if (found == false) {
2!
2511
          (void)memcpy(&pNew->pIpRange[idx], oldRange, sizeof(SIpV4Range));
2✔
2512
          idx++;
2✔
2513
        } else {
2514
          noexist = false;
×
2515
        }
2516
      }
2517
      pNew->num = idx;
1✔
2518
      newUser.pIpWhiteList = pNew;
1✔
2519
      newUser.ipWhiteListVer = pUser->ipWhiteListVer + 1;
1✔
2520

2521
    } else {
2522
      pNew->num = 0;
×
2523
      newUser.pIpWhiteList = pNew;
×
2524
      newUser.ipWhiteListVer = pUser->ipWhiteListVer + 1;
×
2525
    }
2526

2527
    if (localHost) {
1!
2528
      TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_LOCAL_HOST_NOT_DROP, &lino, _OVER);
×
2529
    }
2530
    if (noexist) {
1!
2531
      TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_HOST_NOT_EXIST, &lino, _OVER);
1!
2532
    }
2533
  }
2534

2535
  code = mndAlterUser(pMnode, pUser, &newUser, pReq);
238✔
2536
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
238!
2537

2538
  if (alterReq.alterType == TSDB_ALTER_USER_PASSWD) {
238✔
2539
    char detail[1000] = {0};
35✔
2540
    (void)tsnprintf(detail, sizeof(detail),
35✔
2541
              "alterType:%s, enable:%d, superUser:%d, sysInfo:%d, createdb:%d, tabName:%s, password:xxx",
2542
              mndUserAuditTypeStr(alterReq.alterType), alterReq.enable, alterReq.superUser, alterReq.sysInfo,
35✔
2543
              alterReq.createdb ? 1 : 0, alterReq.tabName);
35✔
2544
    auditRecord(pReq, pMnode->clusterId, "alterUser", "", alterReq.user, detail, strlen(detail));
35✔
2545
  } else if (alterReq.alterType == TSDB_ALTER_USER_SUPERUSER || alterReq.alterType == TSDB_ALTER_USER_ENABLE ||
203!
2546
             alterReq.alterType == TSDB_ALTER_USER_SYSINFO || alterReq.alterType == TSDB_ALTER_USER_CREATEDB) {
198✔
2547
    auditRecord(pReq, pMnode->clusterId, "alterUser", "", alterReq.user, alterReq.sql, alterReq.sqlLen);
24✔
2548
  } else if (ALTER_USER_ADD_READ_DB_PRIV(alterReq.alterType, alterReq.privileges, alterReq.tabName) ||
179✔
2549
             ALTER_USER_ADD_WRITE_DB_PRIV(alterReq.alterType, alterReq.privileges, alterReq.tabName) ||
139✔
2550
             ALTER_USER_ADD_ALL_DB_PRIV(alterReq.alterType, alterReq.privileges, alterReq.tabName) ||
126!
2551
             ALTER_USER_ADD_READ_TB_PRIV(alterReq.alterType, alterReq.privileges, alterReq.tabName) ||
126!
2552
             ALTER_USER_ADD_WRITE_TB_PRIV(alterReq.alterType, alterReq.privileges, alterReq.tabName) ||
90!
2553
             ALTER_USER_ADD_ALL_TB_PRIV(alterReq.alterType, alterReq.privileges, alterReq.tabName)) {
67!
2554
    if (strcmp(alterReq.objname, "1.*") != 0) {
112✔
2555
      SName name = {0};
108✔
2556
      TAOS_CHECK_GOTO(tNameFromString(&name, alterReq.objname, T_NAME_ACCT | T_NAME_DB), &lino, _OVER);
108!
2557
      auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", name.dbname, alterReq.user, alterReq.sql,
108✔
2558
                  alterReq.sqlLen);
2559
    } else {
2560
      auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", "", alterReq.user, alterReq.sql, alterReq.sqlLen);
4✔
2561
    }
2562
  } else if (ALTER_USER_ADD_SUBSCRIBE_TOPIC_PRIV(alterReq.alterType, alterReq.privileges)) {
67✔
2563
    auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", alterReq.objname, alterReq.user, alterReq.sql,
15✔
2564
                alterReq.sqlLen);
2565
  } else if (ALTER_USER_DEL_SUBSCRIBE_TOPIC_PRIV(alterReq.alterType, alterReq.privileges)) {
52✔
2566
    auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", alterReq.objname, alterReq.user, alterReq.sql,
10✔
2567
                alterReq.sqlLen);
2568
  } else {
2569
    if (strcmp(alterReq.objname, "1.*") != 0) {
42✔
2570
      SName name = {0};
38✔
2571
      TAOS_CHECK_GOTO(tNameFromString(&name, alterReq.objname, T_NAME_ACCT | T_NAME_DB), &lino, _OVER);
38✔
2572
      auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", name.dbname, alterReq.user, alterReq.sql,
37✔
2573
                  alterReq.sqlLen);
2574
    } else {
2575
      auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", "", alterReq.user, alterReq.sql, alterReq.sqlLen);
4✔
2576
    }
2577
  }
2578

2579
_OVER:
317✔
2580
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
317✔
2581
    mError("user:%s, failed to alter at line %d since %s", alterReq.user, lino, tstrerror(code));
80!
2582
  }
2583

2584
  tFreeSAlterUserReq(&alterReq);
317✔
2585
  mndReleaseUser(pMnode, pOperUser);
317✔
2586
  mndReleaseUser(pMnode, pUser);
317✔
2587
  mndUserFreeObj(&newUser);
317✔
2588

2589
  TAOS_RETURN(code);
317✔
2590
}
2591

2592
static int32_t mndDropUser(SMnode *pMnode, SRpcMsg *pReq, SUserObj *pUser) {
50✔
2593
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "drop-user");
50✔
2594
  if (pTrans == NULL) {
50!
2595
    mError("user:%s, failed to drop since %s", pUser->user, terrstr());
×
2596
    TAOS_RETURN(terrno);
×
2597
  }
2598
  mInfo("trans:%d, used to drop user:%s", pTrans->id, pUser->user);
50!
2599

2600
  SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
50✔
2601
  if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
50!
2602
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
2603
    mndTransDrop(pTrans);
×
2604
    TAOS_RETURN(terrno);
×
2605
  }
2606
  if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED) < 0) {
50!
2607
    mndTransDrop(pTrans);
×
2608
    TAOS_RETURN(terrno);
×
2609
  }
2610

2611
  if (mndTransPrepare(pMnode, pTrans) != 0) {
50!
2612
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
2613
    mndTransDrop(pTrans);
×
2614
    TAOS_RETURN(terrno);
×
2615
  }
2616
  (void)ipWhiteMgtRemove(pUser->user);
50✔
2617

2618
  mndTransDrop(pTrans);
50✔
2619
  TAOS_RETURN(0);
50✔
2620
}
2621

2622
static int32_t mndProcessDropUserReq(SRpcMsg *pReq) {
50✔
2623
  SMnode      *pMnode = pReq->info.node;
50✔
2624
  int32_t      code = 0;
50✔
2625
  int32_t      lino = 0;
50✔
2626
  SUserObj    *pUser = NULL;
50✔
2627
  SDropUserReq dropReq = {0};
50✔
2628

2629
  TAOS_CHECK_GOTO(tDeserializeSDropUserReq(pReq->pCont, pReq->contLen, &dropReq), &lino, _OVER);
50!
2630

2631
  mInfo("user:%s, start to drop", dropReq.user);
50!
2632
  TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_DROP_USER), &lino, _OVER);
50!
2633

2634
  if (dropReq.user[0] == 0) {
50!
2635
    TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
×
2636
  }
2637

2638
  TAOS_CHECK_GOTO(mndAcquireUser(pMnode, dropReq.user, &pUser), &lino, _OVER);
50!
2639

2640
  TAOS_CHECK_GOTO(mndDropUser(pMnode, pReq, pUser), &lino, _OVER);
50!
2641
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
50!
2642

2643
  auditRecord(pReq, pMnode->clusterId, "dropUser", "", dropReq.user, dropReq.sql, dropReq.sqlLen);
50✔
2644

2645
_OVER:
50✔
2646
  if (code < 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
50!
2647
    mError("user:%s, failed to drop at line %d since %s", dropReq.user, lino, tstrerror(code));
×
2648
  }
2649

2650
  mndReleaseUser(pMnode, pUser);
50✔
2651
  tFreeSDropUserReq(&dropReq);
50✔
2652
  TAOS_RETURN(code);
50✔
2653
}
2654

2655
static int32_t mndProcessGetUserAuthReq(SRpcMsg *pReq) {
387,092✔
2656
  SMnode         *pMnode = pReq->info.node;
387,092✔
2657
  int32_t         code = 0;
387,092✔
2658
  int32_t         lino = 0;
387,092✔
2659
  int32_t         contLen = 0;
387,092✔
2660
  void           *pRsp = NULL;
387,092✔
2661
  SUserObj       *pUser = NULL;
387,092✔
2662
  SGetUserAuthReq authReq = {0};
387,092✔
2663
  SGetUserAuthRsp authRsp = {0};
387,092✔
2664

2665
  TAOS_CHECK_EXIT(tDeserializeSGetUserAuthReq(pReq->pCont, pReq->contLen, &authReq));
387,092!
2666
  mTrace("user:%s, start to get auth", authReq.user);
387,097✔
2667

2668
  TAOS_CHECK_EXIT(mndAcquireUser(pMnode, authReq.user, &pUser));
387,097✔
2669

2670
  TAOS_CHECK_EXIT(mndSetUserAuthRsp(pMnode, pUser, &authRsp));
387,093!
2671

2672
  contLen = tSerializeSGetUserAuthRsp(NULL, 0, &authRsp);
387,094✔
2673
  if (contLen < 0) {
387,082!
2674
    TAOS_CHECK_EXIT(contLen);
×
2675
  }
2676
  pRsp = rpcMallocCont(contLen);
387,082✔
2677
  if (pRsp == NULL) {
387,085!
2678
    TAOS_CHECK_EXIT(terrno);
×
2679
  }
2680

2681
  contLen = tSerializeSGetUserAuthRsp(pRsp, contLen, &authRsp);
387,085✔
2682
  if (contLen < 0) {
387,087!
2683
    TAOS_CHECK_EXIT(contLen);
×
2684
  }
2685

2686
_exit:
387,087✔
2687
  mndReleaseUser(pMnode, pUser);
387,090✔
2688
  tFreeSGetUserAuthRsp(&authRsp);
387,097✔
2689
  if (code < 0) {
387,097✔
2690
    mError("user:%s, failed to get auth at line %d since %s", authReq.user, lino, tstrerror(code));
3!
2691
    rpcFreeCont(pRsp);
3✔
2692
    pRsp = NULL;
3✔
2693
    contLen = 0;
3✔
2694
  }
2695
  pReq->info.rsp = pRsp;
387,097✔
2696
  pReq->info.rspLen = contLen;
387,097✔
2697
  pReq->code = code;
387,097✔
2698

2699
  TAOS_RETURN(code);
387,097✔
2700
}
2701

2702
static int32_t mndRetrieveUsers(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
5,059✔
2703
  SMnode   *pMnode = pReq->info.node;
5,059✔
2704
  SSdb     *pSdb = pMnode->pSdb;
5,059✔
2705
  int32_t   code = 0;
5,059✔
2706
  int32_t   lino = 0;
5,059✔
2707
  int32_t   numOfRows = 0;
5,059✔
2708
  SUserObj *pUser = NULL;
5,059✔
2709
  int32_t   cols = 0;
5,059✔
2710
  int8_t    flag = 0;
5,059✔
2711
  char     *pWrite = NULL;
5,059✔
2712
  char     *buf = NULL;
5,059✔
2713
  char     *varstr = NULL;
5,059✔
2714

2715
  while (numOfRows < rows) {
10,189!
2716
    pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
10,192✔
2717
    if (pShow->pIter == NULL) break;
10,206✔
2718

2719
    cols = 0;
5,131✔
2720
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
5,131✔
2721
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
5,122✔
2722
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
5,122✔
2723
    COL_DATA_SET_VAL_GOTO((const char *)name, false, pUser, _exit);
5,122!
2724

2725
    cols++;
5,111✔
2726
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
5,111✔
2727
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->superUser, false, pUser, _exit);
5,101!
2728

2729
    cols++;
5,112✔
2730
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
5,112✔
2731
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->enable, false, pUser, _exit);
5,101!
2732

2733
    cols++;
5,111✔
2734
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
5,111✔
2735
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sysInfo, false, pUser, _exit);
5,106!
2736

2737
    cols++;
5,105✔
2738
    flag = pUser->createdb ? 1 : 0;
5,105✔
2739
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
5,105✔
2740
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, _exit);
5,100!
2741

2742
    cols++;
5,103✔
2743
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
5,103✔
2744
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->createdTime, false, pUser, _exit);
5,099!
2745

2746
    cols++;
5,104✔
2747

2748
    int32_t tlen = convertIpWhiteListToStr(pUser->pIpWhiteList, &buf);
5,104✔
2749
    // int32_t tlen = mndFetchIpWhiteList(pUser->pIpWhiteList, &buf);
2750
    if (tlen != 0) {
5,122✔
2751
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
5,121!
2752
      if (varstr == NULL) {
5,128!
2753
        sdbRelease(pSdb, pUser);
×
2754
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
2755
      }
2756
      varDataSetLen(varstr, tlen);
5,128✔
2757
      (void)memcpy(varDataVal(varstr), buf, tlen);
5,128✔
2758

2759
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
5,128✔
2760
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, _exit);
5,116!
2761

2762
      taosMemoryFreeClear(buf);
5,119!
2763
    } else {
2764
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
1✔
2765
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, _exit);
×
2766
    }
2767

2768
    numOfRows++;
5,131✔
2769
    sdbRelease(pSdb, pUser);
5,131✔
2770
  }
2771

2772
  pShow->numOfRows += numOfRows;
5,072✔
2773
_exit:
5,072✔
2774
  taosMemoryFreeClear(buf);
5,072!
2775
  taosMemoryFreeClear(varstr);
5,072!
2776
  if (code < 0) {
5,067!
2777
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
2778
    TAOS_RETURN(code);
×
2779
  }
2780
  return numOfRows;
5,067✔
2781
}
2782

2783
static int32_t mndRetrieveUsersFull(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
×
2784
  int32_t numOfRows = 0;
×
2785
#ifdef TD_ENTERPRISE
2786
  SMnode   *pMnode = pReq->info.node;
×
2787
  SSdb     *pSdb = pMnode->pSdb;
×
2788
  SUserObj *pUser = NULL;
×
2789
  int32_t   code = 0;
×
2790
  int32_t   lino = 0;
×
2791
  int32_t   cols = 0;
×
2792
  int8_t    flag = 0;
×
2793
  char     *pWrite = NULL;
×
2794
  char     *buf = NULL;
×
2795
  char     *varstr = NULL;
×
2796

2797
  while (numOfRows < rows) {
×
2798
    pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
×
2799
    if (pShow->pIter == NULL) break;
×
2800

2801
    cols = 0;
×
2802
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
2803
    char             name[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
×
2804
    STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
×
2805
    COL_DATA_SET_VAL_GOTO((const char *)name, false, pUser, _exit);
×
2806

2807
    cols++;
×
2808
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
2809
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->superUser, false, pUser, _exit);
×
2810

2811
    cols++;
×
2812
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
2813
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->enable, false, pUser, _exit);
×
2814

2815
    cols++;
×
2816
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
2817
    COL_DATA_SET_VAL_GOTO((const char *)&pUser->sysInfo, false, pUser, _exit);
×
2818

2819
    cols++;
×
2820
    flag = pUser->createdb ? 1 : 0;
×
2821
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
2822
    COL_DATA_SET_VAL_GOTO((const char *)&flag, false, pUser, _exit);
×
2823

2824
    // mInfo("pUser->pass:%s", pUser->pass);
2825
    cols++;
×
2826
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
2827
    char pass[TSDB_PASSWORD_LEN + VARSTR_HEADER_SIZE] = {0};
×
2828
    STR_WITH_MAXSIZE_TO_VARSTR(pass, pUser->pass, pShow->pMeta->pSchemas[cols].bytes);
×
2829
    COL_DATA_SET_VAL_GOTO((const char *)pass, false, pUser, _exit);
×
2830

2831
    cols++;
×
2832

2833
    int32_t tlen = convertIpWhiteListToStr(pUser->pIpWhiteList, &buf);
×
2834
    // int32_t tlen = mndFetchIpWhiteList(pUser->pIpWhiteList, &buf);
2835
    if (tlen != 0) {
×
2836
      TAOS_MEMORY_REALLOC(varstr, VARSTR_HEADER_SIZE + tlen);
×
2837
      if (varstr == NULL) {
×
2838
        sdbRelease(pSdb, pUser);
×
2839
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
2840
      }
2841
      varDataSetLen(varstr, tlen);
×
2842
      (void)memcpy(varDataVal(varstr), buf, tlen);
×
2843

2844
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
2845
      COL_DATA_SET_VAL_GOTO((const char *)varstr, false, pUser, _exit);
×
2846

2847
      taosMemoryFreeClear(buf);
×
2848
    } else {
2849
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
×
2850
      COL_DATA_SET_VAL_GOTO((const char *)NULL, true, pUser, _exit);
×
2851
    }
2852

2853
    numOfRows++;
×
2854
    sdbRelease(pSdb, pUser);
×
2855
  }
2856

2857
  pShow->numOfRows += numOfRows;
×
2858
_exit:
×
2859
  taosMemoryFreeClear(buf);
×
2860
  taosMemoryFreeClear(varstr);
×
2861
  if (code < 0) {
×
2862
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
2863
    TAOS_RETURN(code);
×
2864
  }
2865
#endif
2866
  return numOfRows;
×
2867
}
2868

2869
static void mndCancelGetNextUser(SMnode *pMnode, void *pIter) {
×
2870
  SSdb *pSdb = pMnode->pSdb;
×
2871
  sdbCancelFetchByType(pSdb, pIter, SDB_USER);
×
2872
}
×
2873

2874
static int32_t mndLoopHash(SHashObj *hash, char *priType, SSDataBlock *pBlock, int32_t *pNumOfRows, SSdb *pSdb,
26,354✔
2875
                           SUserObj *pUser, SShowObj *pShow, char **condition, char **sql) {
2876
  char   *value = taosHashIterate(hash, NULL);
26,354✔
2877
  char   *user = pUser->user;
26,373✔
2878
  int32_t code = 0;
26,373✔
2879
  int32_t lino = 0;
26,373✔
2880
  int32_t cols = 0;
26,373✔
2881
  int32_t numOfRows = *pNumOfRows;
26,373✔
2882

2883
  while (value != NULL) {
26,376✔
2884
    cols = 0;
3✔
2885
    char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
3✔
2886
    STR_WITH_MAXSIZE_TO_VARSTR(userName, user, pShow->pMeta->pSchemas[cols].bytes);
3✔
2887
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
3✔
2888
    COL_DATA_SET_VAL_GOTO((const char *)userName, false, NULL, _exit);
3!
2889

2890
    char privilege[20] = {0};
3✔
2891
    STR_WITH_MAXSIZE_TO_VARSTR(privilege, priType, pShow->pMeta->pSchemas[cols].bytes);
3✔
2892
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
3✔
2893
    COL_DATA_SET_VAL_GOTO((const char *)privilege, false, NULL, _exit);
3!
2894

2895
    size_t keyLen = 0;
3✔
2896
    void  *key = taosHashGetKey(value, &keyLen);
3✔
2897

2898
    char dbName[TSDB_DB_NAME_LEN] = {0};
3✔
2899
    (void)mndExtractShortDbNameFromStbFullName(key, dbName);
3✔
2900
    char dbNameContent[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
3✔
2901
    STR_WITH_MAXSIZE_TO_VARSTR(dbNameContent, dbName, pShow->pMeta->pSchemas[cols].bytes);
3✔
2902
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
3✔
2903
    COL_DATA_SET_VAL_GOTO((const char *)dbNameContent, false, NULL, _exit);
3!
2904

2905
    char tableName[TSDB_TABLE_NAME_LEN] = {0};
3✔
2906
    mndExtractTbNameFromStbFullName(key, tableName, TSDB_TABLE_NAME_LEN);
3✔
2907
    char tableNameContent[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
3✔
2908
    STR_WITH_MAXSIZE_TO_VARSTR(tableNameContent, tableName, pShow->pMeta->pSchemas[cols].bytes);
3✔
2909
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
3✔
2910
    COL_DATA_SET_VAL_GOTO((const char *)tableNameContent, false, NULL, _exit);
3!
2911

2912
    if (strcmp("t", value) != 0 && strcmp("v", value) != 0) {
3!
2913
      SNode  *pAst = NULL;
×
2914
      int32_t sqlLen = 0;
×
2915
      size_t  bufSz = strlen(value) + 1;
×
2916
      if (bufSz < 6) bufSz = 6;
×
2917
      TAOS_MEMORY_REALLOC(*sql, bufSz);
×
2918
      if (*sql == NULL) {
×
2919
        code = terrno;
×
2920
        goto _exit;
×
2921
      }
2922
      TAOS_MEMORY_REALLOC(*condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
×
2923
      if ((*condition) == NULL) {
×
2924
        code = terrno;
×
2925
        goto _exit;
×
2926
      }
2927

2928
      if (nodesStringToNode(value, &pAst) == 0) {
×
2929
        if (nodesNodeToSQL(pAst, *sql, bufSz, &sqlLen) != 0) {
×
2930
          sqlLen = 5;
×
2931
          (void)tsnprintf(*sql, bufSz, "error");
×
2932
        }
2933
        nodesDestroyNode(pAst);
×
2934
      } else {
2935
        sqlLen = 5;
×
2936
        (void)tsnprintf(*sql, bufSz, "error");
×
2937
      }
2938

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

2941
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
2942
      COL_DATA_SET_VAL_GOTO((const char *)(*condition), false, NULL, _exit);
×
2943

2944
      char notes[2] = {0};
×
2945
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
×
2946
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
2947
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, NULL, _exit);
×
2948
    } else {
2949
      TAOS_MEMORY_REALLOC(*condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
3!
2950
      if ((*condition) == NULL) {
3!
2951
        code = terrno;
×
2952
        goto _exit;
×
2953
      }
2954
      STR_WITH_MAXSIZE_TO_VARSTR((*condition), "", pShow->pMeta->pSchemas[cols].bytes);
3✔
2955
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
3✔
2956
      COL_DATA_SET_VAL_GOTO((const char *)(*condition), false, NULL, _exit);
3!
2957

2958
      char notes[64 + VARSTR_HEADER_SIZE] = {0};
3✔
2959
      STR_WITH_MAXSIZE_TO_VARSTR(notes, value[0] == 'v' ? "view" : "", sizeof(notes));
3!
2960
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
3✔
2961
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, NULL, _exit);
3!
2962
    }
2963

2964
    numOfRows++;
3✔
2965
    value = taosHashIterate(hash, value);
3✔
2966
  }
2967
  *pNumOfRows = numOfRows;
26,373✔
2968
_exit:
26,373✔
2969
  if (code < 0) {
26,373!
2970
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
2971
    sdbRelease(pSdb, pUser);
×
2972
  }
2973
  TAOS_RETURN(code);
26,373✔
2974
}
2975

2976
static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
4,338✔
2977
  int32_t   code = 0;
4,338✔
2978
  int32_t   lino = 0;
4,338✔
2979
  SMnode   *pMnode = pReq->info.node;
4,338✔
2980
  SSdb     *pSdb = pMnode->pSdb;
4,338✔
2981
  int32_t   numOfRows = 0;
4,338✔
2982
  SUserObj *pUser = NULL;
4,338✔
2983
  int32_t   cols = 0;
4,338✔
2984
  char     *pWrite = NULL;
4,338✔
2985
  char     *condition = NULL;
4,338✔
2986
  char     *sql = NULL;
4,338✔
2987

2988
  bool fetchNextUser = pShow->restore ? false : true;
4,338✔
2989
  pShow->restore = false;
4,338✔
2990

2991
  while (numOfRows < rows) {
8,743!
2992
    if (fetchNextUser) {
8,743!
2993
      pShow->pIter = sdbFetch(pSdb, SDB_USER, pShow->pIter, (void **)&pUser);
8,743✔
2994
      if (pShow->pIter == NULL) break;
8,748✔
2995
    } else {
2996
      fetchNextUser = true;
×
2997
      void *pKey = taosHashGetKey(pShow->pIter, NULL);
×
2998
      pUser = sdbAcquire(pSdb, SDB_USER, pKey);
×
2999
      if (!pUser) {
×
3000
        continue;
×
3001
      }
3002
    }
3003

3004
    int32_t numOfReadDbs = taosHashGetSize(pUser->readDbs);
4,407✔
3005
    int32_t numOfWriteDbs = taosHashGetSize(pUser->writeDbs);
4,402✔
3006
    int32_t numOfTopics = taosHashGetSize(pUser->topics);
4,404✔
3007
    int32_t numOfReadTbs = taosHashGetSize(pUser->readTbs);
4,405✔
3008
    int32_t numOfWriteTbs = taosHashGetSize(pUser->writeTbs);
4,404✔
3009
    int32_t numOfAlterTbs = taosHashGetSize(pUser->alterTbs);
4,405✔
3010
    int32_t numOfReadViews = taosHashGetSize(pUser->readViews);
4,405✔
3011
    int32_t numOfWriteViews = taosHashGetSize(pUser->writeViews);
4,406✔
3012
    int32_t numOfAlterViews = taosHashGetSize(pUser->alterViews);
4,406✔
3013
    if (numOfRows + numOfReadDbs + numOfWriteDbs + numOfTopics + numOfReadTbs + numOfWriteTbs + numOfAlterTbs +
4,402✔
3014
            numOfReadViews + numOfWriteViews + numOfAlterViews >=
4,402!
3015
        rows) {
3016
      mInfo(
×
3017
          "will restore. current num of rows: %d, read dbs %d, write dbs %d, topics %d, read tables %d, write tables "
3018
          "%d, alter tables %d, read views %d, write views %d, alter views %d",
3019
          numOfRows, numOfReadDbs, numOfWriteDbs, numOfTopics, numOfReadTbs, numOfWriteTbs, numOfAlterTbs,
3020
          numOfReadViews, numOfWriteViews, numOfAlterViews);
3021
      pShow->restore = true;
×
3022
      sdbRelease(pSdb, pUser);
×
3023
      break;
×
3024
    }
3025

3026
    if (pUser->superUser) {
4,402✔
3027
      cols = 0;
4,338✔
3028
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
4,338✔
3029
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
4,338✔
3030
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4,338✔
3031
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, _exit);
4,326!
3032

3033
      char privilege[20] = {0};
4,330✔
3034
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "all", pShow->pMeta->pSchemas[cols].bytes);
4,330✔
3035
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4,330✔
3036
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, _exit);
4,330!
3037

3038
      char objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4,325✔
3039
      STR_WITH_MAXSIZE_TO_VARSTR(objName, "all", pShow->pMeta->pSchemas[cols].bytes);
4,325✔
3040
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4,325✔
3041
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, _exit);
4,324!
3042

3043
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
4,325✔
3044
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
4,325✔
3045
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4,325✔
3046
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, _exit);
4,334!
3047

3048
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
4,329!
3049
      if (condition == NULL) {
4,339!
3050
        sdbRelease(pSdb, pUser);
×
3051
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
3052
      }
3053
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
4,339✔
3054
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4,339✔
3055
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, _exit);
4,336!
3056

3057
      char notes[2] = {0};
4,335✔
3058
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
4,335✔
3059
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4,335✔
3060
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, _exit);
4,331!
3061

3062
      numOfRows++;
4,331✔
3063
    }
3064

3065
    char *db = taosHashIterate(pUser->readDbs, NULL);
4,395✔
3066
    while (db != NULL) {
4,418✔
3067
      cols = 0;
19✔
3068
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
19✔
3069
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
19✔
3070
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3071
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, _exit);
19!
3072

3073
      char privilege[20] = {0};
19✔
3074
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "read", pShow->pMeta->pSchemas[cols].bytes);
19✔
3075
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3076
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, _exit);
19!
3077

3078
      SName name = {0};
19✔
3079
      char  objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
19✔
3080
      code = tNameFromString(&name, db, T_NAME_ACCT | T_NAME_DB);
19✔
3081
      if (code < 0) {
19!
3082
        sdbRelease(pSdb, pUser);
×
3083
        TAOS_CHECK_GOTO(code, &lino, _exit);
×
3084
      }
3085
      (void)tNameGetDbName(&name, varDataVal(objName));
19✔
3086
      varDataSetLen(objName, strlen(varDataVal(objName)));
19✔
3087
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3088
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, _exit);
19!
3089

3090
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
19✔
3091
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
19✔
3092
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3093
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, _exit);
19!
3094

3095
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
19!
3096
      if (condition == NULL) {
19!
3097
        sdbRelease(pSdb, pUser);
×
3098
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
3099
      }
3100
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
19✔
3101
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3102
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, _exit);
19!
3103

3104
      char notes[2] = {0};
19✔
3105
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
19✔
3106
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3107
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, _exit);
19!
3108

3109
      numOfRows++;
19✔
3110
      db = taosHashIterate(pUser->readDbs, db);
19✔
3111
    }
3112

3113
    db = taosHashIterate(pUser->writeDbs, NULL);
4,399✔
3114
    while (db != NULL) {
4,416✔
3115
      cols = 0;
19✔
3116
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
19✔
3117
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
19✔
3118
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3119
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, _exit);
19!
3120

3121
      char privilege[20] = {0};
19✔
3122
      STR_WITH_MAXSIZE_TO_VARSTR(privilege, "write", pShow->pMeta->pSchemas[cols].bytes);
19✔
3123
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3124
      COL_DATA_SET_VAL_GOTO((const char *)privilege, false, pUser, _exit);
19!
3125

3126
      SName name = {0};
19✔
3127
      char  objName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
19✔
3128
      code = tNameFromString(&name, db, T_NAME_ACCT | T_NAME_DB);
19✔
3129
      if (code < 0) {
19!
3130
        sdbRelease(pSdb, pUser);
×
3131
        TAOS_CHECK_GOTO(code, &lino, _exit);
×
3132
      }
3133
      (void)tNameGetDbName(&name, varDataVal(objName));
19✔
3134
      varDataSetLen(objName, strlen(varDataVal(objName)));
19✔
3135
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3136
      COL_DATA_SET_VAL_GOTO((const char *)objName, false, pUser, _exit);
19!
3137

3138
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
19✔
3139
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
19✔
3140
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3141
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, _exit);
19!
3142

3143
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
19!
3144
      if (condition == NULL) {
19!
3145
        sdbRelease(pSdb, pUser);
×
3146
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
3147
      }
3148
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
19✔
3149
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3150
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, _exit);
19!
3151

3152
      char notes[2] = {0};
19✔
3153
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
19✔
3154
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
19✔
3155
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, _exit);
19!
3156

3157
      numOfRows++;
19✔
3158
      db = taosHashIterate(pUser->writeDbs, db);
19✔
3159
    }
3160

3161
    TAOS_CHECK_EXIT(mndLoopHash(pUser->readTbs, "read", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
4,397!
3162

3163
    TAOS_CHECK_EXIT(mndLoopHash(pUser->writeTbs, "write", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
4,397!
3164

3165
    TAOS_CHECK_EXIT(mndLoopHash(pUser->alterTbs, "alter", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
4,405!
3166

3167
    TAOS_CHECK_EXIT(mndLoopHash(pUser->readViews, "read", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
4,406!
3168

3169
    TAOS_CHECK_EXIT(mndLoopHash(pUser->writeViews, "write", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
4,403!
3170

3171
    TAOS_CHECK_EXIT(mndLoopHash(pUser->alterViews, "alter", pBlock, &numOfRows, pSdb, pUser, pShow, &condition, &sql));
4,401!
3172

3173
    char *topic = taosHashIterate(pUser->topics, NULL);
4,402✔
3174
    while (topic != NULL) {
4,408✔
3175
      cols = 0;
8✔
3176
      char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0};
8✔
3177
      STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes);
8✔
3178
      SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
8✔
3179
      COL_DATA_SET_VAL_GOTO((const char *)userName, false, pUser, _exit);
8!
3180

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

3186
      char topicName[TSDB_TOPIC_NAME_LEN + VARSTR_HEADER_SIZE + 5] = {0};
8✔
3187
      tstrncpy(varDataVal(topicName), mndGetDbStr(topic), TSDB_TOPIC_NAME_LEN - 2);
8✔
3188
      varDataSetLen(topicName, strlen(varDataVal(topicName)));
8✔
3189
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
8✔
3190
      COL_DATA_SET_VAL_GOTO((const char *)topicName, false, pUser, _exit);
8!
3191

3192
      char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
8✔
3193
      STR_WITH_MAXSIZE_TO_VARSTR(tableName, "", pShow->pMeta->pSchemas[cols].bytes);
8✔
3194
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
8✔
3195
      COL_DATA_SET_VAL_GOTO((const char *)tableName, false, pUser, _exit);
8!
3196

3197
      TAOS_MEMORY_REALLOC(condition, TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE);
8!
3198
      if (condition == NULL) {
8!
3199
        sdbRelease(pSdb, pUser);
×
3200
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
3201
      }
3202
      STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes);
8✔
3203
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
8✔
3204
      COL_DATA_SET_VAL_GOTO((const char *)condition, false, pUser, _exit);
8!
3205

3206
      char notes[2] = {0};
8✔
3207
      STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes));
8✔
3208
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
8✔
3209
      COL_DATA_SET_VAL_GOTO((const char *)notes, false, pUser, _exit);
8!
3210

3211
      numOfRows++;
8✔
3212
      topic = taosHashIterate(pUser->topics, topic);
8✔
3213
    }
3214

3215
    sdbRelease(pSdb, pUser);
4,400✔
3216
  }
3217

3218
  pShow->numOfRows += numOfRows;
4,341✔
3219
_exit:
4,341✔
3220
  taosMemoryFreeClear(condition);
4,341!
3221
  taosMemoryFreeClear(sql);
4,341!
3222
  if (code < 0) {
4,341!
3223
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
3224
    TAOS_RETURN(code);
×
3225
  }
3226
  return numOfRows;
4,341✔
3227
}
3228

3229
static void mndCancelGetNextPrivileges(SMnode *pMnode, void *pIter) {
×
3230
  SSdb *pSdb = pMnode->pSdb;
×
3231
  sdbCancelFetchByType(pSdb, pIter, SDB_USER);
×
3232
}
×
3233

3234
int32_t mndValidateUserAuthInfo(SMnode *pMnode, SUserAuthVersion *pUsers, int32_t numOfUses, void **ppRsp,
219,264✔
3235
                                int32_t *pRspLen, int64_t ipWhiteListVer) {
3236
  int32_t           code = 0;
219,264✔
3237
  int32_t           lino = 0;
219,264✔
3238
  int32_t           rspLen = 0;
219,264✔
3239
  void             *pRsp = NULL;
219,264✔
3240
  SUserAuthBatchRsp batchRsp = {0};
219,264✔
3241

3242
  batchRsp.pArray = taosArrayInit(numOfUses, sizeof(SGetUserAuthRsp));
219,264✔
3243
  if (batchRsp.pArray == NULL) {
219,260!
3244
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3245
  }
3246

3247
  for (int32_t i = 0; i < numOfUses; ++i) {
438,740✔
3248
    SUserObj *pUser = NULL;
219,469✔
3249
    code = mndAcquireUser(pMnode, pUsers[i].user, &pUser);
219,469✔
3250
    if (pUser == NULL) {
219,473✔
3251
      if (TSDB_CODE_MND_USER_NOT_EXIST == code) {
17!
3252
        SGetUserAuthRsp rsp = {.dropped = 1};
17✔
3253
        (void)memcpy(rsp.user, pUsers[i].user, TSDB_USER_LEN);
17✔
3254
        TSDB_CHECK_NULL(taosArrayPush(batchRsp.pArray, &rsp), code, lino, _OVER, TSDB_CODE_OUT_OF_MEMORY);
34!
3255
      }
3256
      mError("user:%s, failed to auth user since %s", pUsers[i].user, tstrerror(code));
17!
3257
      code = 0;
17✔
3258
      continue;
204,496✔
3259
    }
3260

3261
    pUsers[i].version = ntohl(pUsers[i].version);
219,456✔
3262
    if (pUser->authVersion <= pUsers[i].version && ipWhiteListVer == pMnode->ipWhiteVer) {
219,456✔
3263
      mndReleaseUser(pMnode, pUser);
204,479✔
3264
      continue;
204,479✔
3265
    }
3266

3267
    SGetUserAuthRsp rsp = {0};
14,977✔
3268
    code = mndSetUserAuthRsp(pMnode, pUser, &rsp);
14,977✔
3269
    if (code) {
14,984!
3270
      mndReleaseUser(pMnode, pUser);
×
3271
      tFreeSGetUserAuthRsp(&rsp);
×
3272
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3273
    }
3274

3275
    if (!(taosArrayPush(batchRsp.pArray, &rsp))) {
29,968!
3276
      code = terrno;
×
3277
      mndReleaseUser(pMnode, pUser);
×
3278
      tFreeSGetUserAuthRsp(&rsp);
×
3279
      TAOS_CHECK_GOTO(code, &lino, _OVER);
×
3280
    }
3281
    mndReleaseUser(pMnode, pUser);
14,984✔
3282
  }
3283

3284
  if (taosArrayGetSize(batchRsp.pArray) <= 0) {
219,271✔
3285
    *ppRsp = NULL;
204,461✔
3286
    *pRspLen = 0;
204,461✔
3287

3288
    tFreeSUserAuthBatchRsp(&batchRsp);
204,461✔
3289
    return 0;
204,461✔
3290
  }
3291

3292
  rspLen = tSerializeSUserAuthBatchRsp(NULL, 0, &batchRsp);
14,810✔
3293
  if (rspLen < 0) {
14,810!
3294
    TAOS_CHECK_GOTO(rspLen, &lino, _OVER);
×
3295
  }
3296
  pRsp = taosMemoryMalloc(rspLen);
14,810!
3297
  if (pRsp == NULL) {
14,810!
3298
    TAOS_CHECK_GOTO(terrno, &lino, _OVER);
×
3299
  }
3300
  rspLen = tSerializeSUserAuthBatchRsp(pRsp, rspLen, &batchRsp);
14,810✔
3301
  if (rspLen < 0) {
14,810!
3302
    TAOS_CHECK_GOTO(rspLen, &lino, _OVER);
×
3303
  }
3304
_OVER:
14,810✔
3305
  tFreeSUserAuthBatchRsp(&batchRsp);
14,810✔
3306
  if (code < 0) {
14,810!
3307
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
3308
    taosMemoryFreeClear(pRsp);
×
3309
    rspLen = 0;
×
3310
  }
3311
  *ppRsp = pRsp;
14,810✔
3312
  *pRspLen = rspLen;
14,810✔
3313

3314
  TAOS_RETURN(code);
14,810✔
3315
}
3316

3317
int32_t mndUserRemoveDb(SMnode *pMnode, STrans *pTrans, char *db) {
1,866✔
3318
  int32_t   code = 0;
1,866✔
3319
  int32_t   lino = 0;
1,866✔
3320
  SSdb     *pSdb = pMnode->pSdb;
1,866✔
3321
  int32_t   len = strlen(db) + 1;
1,866✔
3322
  void     *pIter = NULL;
1,866✔
3323
  SUserObj *pUser = NULL;
1,866✔
3324
  SUserObj  newUser = {0};
1,866✔
3325

3326
  while (1) {
2,055✔
3327
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
3,921✔
3328
    if (pIter == NULL) break;
3,921✔
3329

3330
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
2,055!
3331
      break;
×
3332
    }
3333

3334
    bool inRead = (taosHashGet(newUser.readDbs, db, len) != NULL);
2,055✔
3335
    bool inWrite = (taosHashGet(newUser.writeDbs, db, len) != NULL);
2,055✔
3336
    if (inRead || inWrite) {
2,055!
3337
      code = taosHashRemove(newUser.readDbs, db, len);
2✔
3338
      if (code < 0) {
2!
3339
        mError("failed to remove readDbs:%s from user:%s", db, pUser->user);
×
3340
      }
3341
      code = taosHashRemove(newUser.writeDbs, db, len);
2✔
3342
      if (code < 0) {
2!
3343
        mError("failed to remove writeDbs:%s from user:%s", db, pUser->user);
×
3344
      }
3345

3346
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
2✔
3347
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
2!
3348
        code = TSDB_CODE_OUT_OF_MEMORY;
×
3349
        break;
×
3350
      }
3351
      TAOS_CHECK_GOTO(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY), &lino, _OVER);
2!
3352
    }
3353

3354
    mndUserFreeObj(&newUser);
2,055✔
3355
    sdbRelease(pSdb, pUser);
2,055✔
3356
  }
3357

3358
_OVER:
1,866✔
3359
  if (pUser != NULL) sdbRelease(pSdb, pUser);
1,866!
3360
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
1,866!
3361
  mndUserFreeObj(&newUser);
1,866✔
3362
  TAOS_RETURN(code);
1,866✔
3363
}
3364

3365
int32_t mndUserRemoveStb(SMnode *pMnode, STrans *pTrans, char *stb) {
969✔
3366
  int32_t   code = 0;
969✔
3367
  SSdb     *pSdb = pMnode->pSdb;
969✔
3368
  int32_t   len = strlen(stb) + 1;
969✔
3369
  void     *pIter = NULL;
969✔
3370
  SUserObj *pUser = NULL;
969✔
3371
  SUserObj  newUser = {0};
969✔
3372

3373
  while (1) {
969✔
3374
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
1,938✔
3375
    if (pIter == NULL) break;
1,938✔
3376

3377
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
969!
3378
      break;
×
3379
    }
3380

3381
    bool inRead = (taosHashGet(newUser.readTbs, stb, len) != NULL);
969✔
3382
    bool inWrite = (taosHashGet(newUser.writeTbs, stb, len) != NULL);
969✔
3383
    bool inAlter = (taosHashGet(newUser.alterTbs, stb, len) != NULL);
969✔
3384
    if (inRead || inWrite || inAlter) {
969!
3385
      code = taosHashRemove(newUser.readTbs, stb, len);
×
3386
      if (code < 0) {
×
3387
        mError("failed to remove readTbs:%s from user:%s", stb, pUser->user);
×
3388
      }
3389
      code = taosHashRemove(newUser.writeTbs, stb, len);
×
3390
      if (code < 0) {
×
3391
        mError("failed to remove writeTbs:%s from user:%s", stb, pUser->user);
×
3392
      }
3393
      code = taosHashRemove(newUser.alterTbs, stb, len);
×
3394
      if (code < 0) {
×
3395
        mError("failed to remove alterTbs:%s from user:%s", stb, pUser->user);
×
3396
      }
3397

3398
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
×
3399
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
×
3400
        code = TSDB_CODE_OUT_OF_MEMORY;
×
3401
        break;
×
3402
      }
3403
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
×
3404
      if (code != 0) {
×
3405
        mndUserFreeObj(&newUser);
×
3406
        sdbRelease(pSdb, pUser);
×
3407
        TAOS_RETURN(code);
×
3408
      }
3409
    }
3410

3411
    mndUserFreeObj(&newUser);
969✔
3412
    sdbRelease(pSdb, pUser);
969✔
3413
  }
3414

3415
  if (pUser != NULL) sdbRelease(pSdb, pUser);
969!
3416
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
969!
3417
  mndUserFreeObj(&newUser);
969✔
3418
  TAOS_RETURN(code);
969✔
3419
}
3420

3421
int32_t mndUserRemoveView(SMnode *pMnode, STrans *pTrans, char *view) {
172✔
3422
  int32_t   code = 0;
172✔
3423
  SSdb     *pSdb = pMnode->pSdb;
172✔
3424
  int32_t   len = strlen(view) + 1;
172✔
3425
  void     *pIter = NULL;
172✔
3426
  SUserObj *pUser = NULL;
172✔
3427
  SUserObj  newUser = {0};
172✔
3428

3429
  while (1) {
181✔
3430
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
353✔
3431
    if (pIter == NULL) break;
353✔
3432

3433
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
181!
3434
      break;
×
3435
    }
3436

3437
    bool inRead = (taosHashGet(newUser.readViews, view, len) != NULL);
181✔
3438
    bool inWrite = (taosHashGet(newUser.writeViews, view, len) != NULL);
181✔
3439
    bool inAlter = (taosHashGet(newUser.alterViews, view, len) != NULL);
181✔
3440
    if (inRead || inWrite || inAlter) {
181!
3441
      code = taosHashRemove(newUser.readViews, view, len);
3✔
3442
      if (code < 0) {
3!
3443
        mError("failed to remove readViews:%s from user:%s", view, pUser->user);
×
3444
      }
3445
      code = taosHashRemove(newUser.writeViews, view, len);
3✔
3446
      if (code < 0) {
3!
3447
        mError("failed to remove writeViews:%s from user:%s", view, pUser->user);
3!
3448
      }
3449
      code = taosHashRemove(newUser.alterViews, view, len);
3✔
3450
      if (code < 0) {
3!
3451
        mError("failed to remove alterViews:%s from user:%s", view, pUser->user);
3!
3452
      }
3453

3454
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
3✔
3455
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
3!
3456
        code = TSDB_CODE_OUT_OF_MEMORY;
×
3457
        break;
×
3458
      }
3459
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
3✔
3460
      if (code < 0) {
3!
3461
        mndUserFreeObj(&newUser);
×
3462
        sdbRelease(pSdb, pUser);
×
3463
        TAOS_RETURN(code);
×
3464
      }
3465
    }
3466

3467
    mndUserFreeObj(&newUser);
181✔
3468
    sdbRelease(pSdb, pUser);
181✔
3469
  }
3470

3471
  if (pUser != NULL) sdbRelease(pSdb, pUser);
172!
3472
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
172!
3473
  mndUserFreeObj(&newUser);
172✔
3474
  TAOS_RETURN(code);
172✔
3475
}
3476

3477
int32_t mndUserRemoveTopic(SMnode *pMnode, STrans *pTrans, char *topic) {
321✔
3478
  int32_t   code = 0;
321✔
3479
  SSdb     *pSdb = pMnode->pSdb;
321✔
3480
  int32_t   len = strlen(topic) + 1;
321✔
3481
  void     *pIter = NULL;
321✔
3482
  SUserObj *pUser = NULL;
321✔
3483
  SUserObj  newUser = {0};
321✔
3484

3485
  while (1) {
324✔
3486
    pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pUser);
645✔
3487
    if (pIter == NULL) {
645✔
3488
      break;
321✔
3489
    }
3490

3491
    if ((code = mndUserDupObj(pUser, &newUser)) != 0) {
324!
3492
      break;
×
3493
    }
3494

3495
    bool inTopic = (taosHashGet(newUser.topics, topic, len) != NULL);
324✔
3496
    if (inTopic) {
324!
3497
      code = taosHashRemove(newUser.topics, topic, len);
×
3498
      if (code < 0) {
×
3499
        mError("failed to remove topic:%s from user:%s", topic, pUser->user);
×
3500
      }
3501
      SSdbRaw *pCommitRaw = mndUserActionEncode(&newUser);
×
3502
      if (pCommitRaw == NULL || (code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
×
3503
        code = TSDB_CODE_OUT_OF_MEMORY;
×
3504
        break;
×
3505
      }
3506
      code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
×
3507
      if (code < 0) {
×
3508
        mndUserFreeObj(&newUser);
×
3509
        sdbRelease(pSdb, pUser);
×
3510
        TAOS_RETURN(code);
×
3511
      }
3512
    }
3513

3514
    mndUserFreeObj(&newUser);
324✔
3515
    sdbRelease(pSdb, pUser);
324✔
3516
  }
3517

3518
  if (pUser != NULL) sdbRelease(pSdb, pUser);
321!
3519
  if (pIter != NULL) sdbCancelFetch(pSdb, pIter);
321!
3520
  mndUserFreeObj(&newUser);
321✔
3521
  TAOS_RETURN(code);
321✔
3522
}
3523

3524
int64_t mndGetUserIpWhiteListVer(SMnode *pMnode, SUserObj *pUser) {
×
3525
  // ver = 0, disable ip white list
3526
  // ver > 0, enable ip white list
3527
  return tsEnableWhiteList ? pUser->ipWhiteListVer : 0;
×
3528
}
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