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

S
slguan 已提交
16
#define _DEFAULT_SOURCE
17
#include "os.h"
S
slguan 已提交
18
#include "trpc.h"
S
slguan 已提交
19
#include "tutil.h"
S
slguan 已提交
20
#include "tglobal.h"
21
#include "tgrant.h"
H
hjxilinx 已提交
22
#include "tdataformat.h"
23
#include "tkey.h"
24
#include "mnode.h"
S
slguan 已提交
25
#include "dnode.h"
S
Shengliang Guan 已提交
26 27 28 29 30
#include "mnodeDef.h"
#include "mnodeInt.h"
#include "mnodeAcct.h"
#include "mnodeMnode.h"
#include "mnodeSdb.h"
31
#include "mnodeShow.h"
S
Shengliang Guan 已提交
32
#include "mnodeUser.h"
33 34
#include "mnodeWrite.h"
#include "mnodePeer.h"
S
slguan 已提交
35

36
static void *  tsUserSdb = NULL;
S
slguan 已提交
37
static int32_t tsUserUpdateSize = 0;
38 39 40 41 42 43 44 45
static int32_t mnodeGetUserMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn);
static int32_t mnodeRetrieveUsers(SShowObj *pShow, char *data, int32_t rows, void *pConn);
static int32_t mnodeProcessCreateUserMsg(SMnodeMsg *pMsg);
static int32_t mnodeProcessAlterUserMsg(SMnodeMsg *pMsg);
static int32_t mnodeProcessDropUserMsg(SMnodeMsg *pMsg);
static int32_t mnodeProcessAuthMsg(SMnodeMsg *pMsg);

static int32_t mnodeUserActionDestroy(SSdbOper *pOper) {
S
Shengliang Guan 已提交
46
  taosTFree(pOper->pObj);
S
slguan 已提交
47 48 49
  return TSDB_CODE_SUCCESS;
}

50
static int32_t mnodeUserActionInsert(SSdbOper *pOper) {
S
slguan 已提交
51
  SUserObj *pUser = pOper->pObj;
52
  SAcctObj *pAcct = mnodeGetAcct(pUser->acct);
53 54

  if (pAcct != NULL) {
55 56
    mnodeAddUserToAcct(pAcct, pUser);
    mnodeDecAcctRef(pAcct);
57
  } else {
58
    mError("user:%s, acct:%s info not exist in sdb", pUser->user, pUser->acct);
59
    return TSDB_CODE_MND_INVALID_ACCT;
60 61
  }

S
slguan 已提交
62 63 64
  return TSDB_CODE_SUCCESS;
}

65
static int32_t mnodeUserActionDelete(SSdbOper *pOper) {
S
slguan 已提交
66
  SUserObj *pUser = pOper->pObj;
67
  SAcctObj *pAcct = mnodeGetAcct(pUser->acct);
S
slguan 已提交
68

S
[TD-16]  
slguan 已提交
69
  if (pAcct != NULL) {
70 71
    mnodeDropUserFromAcct(pAcct, pUser);
    mnodeDecAcctRef(pAcct);
S
[TD-16]  
slguan 已提交
72
  }
S
slguan 已提交
73 74 75 76

  return TSDB_CODE_SUCCESS;
}

77
static int32_t mnodeUserActionUpdate(SSdbOper *pOper) {
S
slguan 已提交
78
  SUserObj *pUser = pOper->pObj;
79
  SUserObj *pSaved = mnodeGetUser(pUser->user);
S
slguan 已提交
80
  if (pUser != pSaved) {
S
slguan 已提交
81
    memcpy(pSaved, pUser, tsUserUpdateSize);
S
slguan 已提交
82 83
    free(pUser);
  }
84
  mnodeDecUserRef(pSaved);
S
slguan 已提交
85 86 87
  return TSDB_CODE_SUCCESS;
}

88
static int32_t mnodeUserActionEncode(SSdbOper *pOper) {
S
slguan 已提交
89
  SUserObj *pUser = pOper->pObj;
S
slguan 已提交
90 91 92
  memcpy(pOper->rowData, pUser, tsUserUpdateSize);
  pOper->rowSize = tsUserUpdateSize;
  return TSDB_CODE_SUCCESS;
S
slguan 已提交
93 94
}

95
static int32_t mnodeUserActionDecode(SSdbOper *pOper) {
96
  SUserObj *pUser = (SUserObj *)calloc(1, sizeof(SUserObj));
97
  if (pUser == NULL) return TSDB_CODE_MND_OUT_OF_MEMORY;
S
slguan 已提交
98

S
slguan 已提交
99 100 101
  memcpy(pUser, pOper->rowData, tsUserUpdateSize);
  pOper->pObj = pUser;
  return TSDB_CODE_SUCCESS;
S
slguan 已提交
102
}
H
hzcheng 已提交
103

104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
static void mnodePrintUserAuth() {
  FILE *fp = fopen("auth.txt", "w");
  if (!fp) {
    mDebug("failed to auth.txt for write");
    return;
  }
  
  void *    pIter = NULL;
  SUserObj *pUser = NULL;

  while (1) {
    pIter = mnodeGetNextUser(pIter, &pUser);
    if (pUser == NULL) break;

    char *base64 = base64_encode((const unsigned char *)pUser->pass, TSDB_KEY_LEN * 2);
    fprintf(fp, "user:%24s auth:%s\n", pUser->user, base64);
    free(base64);

    mnodeDecUserRef(pUser);
  }

  fflush(fp);
  sdbFreeIter(pIter);
  fclose(fp);
}

130
static int32_t mnodeUserActionRestored() {
131 132
  int32_t numOfRows = sdbGetNumOfRows(tsUserSdb);
  if (numOfRows <= 0 && dnodeIsFirstDeploy()) {
133
    mInfo("dnode first deploy, create root user");
134 135
    SAcctObj *pAcct = mnodeGetAcct(TSDB_DEFAULT_USER);
    mnodeCreateUser(pAcct, TSDB_DEFAULT_USER, TSDB_DEFAULT_PASS, NULL);
136
    mnodeCreateUser(pAcct, "monitor", tsInternalPass, NULL);
137
    mnodeCreateUser(pAcct, "_"TSDB_DEFAULT_USER, tsInternalPass, NULL);
138
    mnodeDecAcctRef(pAcct);
S
slguan 已提交
139
  }
S
slguan 已提交
140

141 142 143 144 145
  if (tsPrintAuth != 0) {
    mInfo("print user auth, for -A parameter is set");
    mnodePrintUserAuth();
  }

146
  return TSDB_CODE_SUCCESS;
S
slguan 已提交
147 148
}

149
int32_t mnodeInitUsers() {
S
slguan 已提交
150
  SUserObj tObj;
S
slguan 已提交
151
  tsUserUpdateSize = (int8_t *)tObj.updateEnd - (int8_t *)&tObj;
S
slguan 已提交
152

S
slguan 已提交
153
  SSdbTableDesc tableDesc = {
S
slguan 已提交
154
    .tableId      = SDB_TABLE_USER,
S
slguan 已提交
155
    .tableName    = "users",
S
Shengliang Guan 已提交
156
    .hashSessions = TSDB_DEFAULT_USERS_HASH_SIZE,
S
slguan 已提交
157
    .maxRowSize   = tsUserUpdateSize,
S
slguan 已提交
158
    .refCountPos  = (int8_t *)(&tObj.refCount) - (int8_t *)&tObj,
S
slguan 已提交
159
    .keyType      = SDB_KEY_STRING,
160 161 162 163 164 165 166
    .insertFp     = mnodeUserActionInsert,
    .deleteFp     = mnodeUserActionDelete,
    .updateFp     = mnodeUserActionUpdate,
    .encodeFp     = mnodeUserActionEncode,
    .decodeFp     = mnodeUserActionDecode,
    .destroyFp    = mnodeUserActionDestroy,
    .restoredFp   = mnodeUserActionRestored
S
slguan 已提交
167 168 169
  };

  tsUserSdb = sdbOpenTable(&tableDesc);
170
  if (tsUserSdb == NULL) {
171
    mError("table:%s, failed to create hash", tableDesc.tableName);
H
hzcheng 已提交
172 173 174
    return -1;
  }

175 176 177 178 179 180
  mnodeAddWriteMsgHandle(TSDB_MSG_TYPE_CM_CREATE_USER, mnodeProcessCreateUserMsg);
  mnodeAddWriteMsgHandle(TSDB_MSG_TYPE_CM_ALTER_USER, mnodeProcessAlterUserMsg);
  mnodeAddWriteMsgHandle(TSDB_MSG_TYPE_CM_DROP_USER, mnodeProcessDropUserMsg);
  mnodeAddShowMetaHandle(TSDB_MGMT_TABLE_USER, mnodeGetUserMeta);
  mnodeAddShowRetrieveHandle(TSDB_MGMT_TABLE_USER, mnodeRetrieveUsers);
  mnodeAddPeerMsgHandle(TSDB_MSG_TYPE_DM_AUTH, mnodeProcessAuthMsg);
S
Shengliang Guan 已提交
181
   
182
  mDebug("table:%s, hash is created", tableDesc.tableName);
H
hzcheng 已提交
183 184 185
  return 0;
}

186
void mnodeCleanupUsers() {
S
slguan 已提交
187
  sdbCloseTable(tsUserSdb);
188
  tsUserSdb = NULL;
S
slguan 已提交
189 190
}

191
SUserObj *mnodeGetUser(char *name) {
192 193
  return (SUserObj *)sdbGetRow(tsUserSdb, name);
}
H
hzcheng 已提交
194

195
void *mnodeGetNextUser(void *pIter, SUserObj **pUser) { 
S
Shengliang Guan 已提交
196
  return sdbFetchRow(tsUserSdb, pIter, (void **)pUser); 
197 198
}

199
void mnodeIncUserRef(SUserObj *pUser) { 
S
slguan 已提交
200 201 202
  return sdbIncRef(tsUserSdb, pUser); 
}

203
void mnodeDecUserRef(SUserObj *pUser) { 
S
slguan 已提交
204 205 206
  return sdbDecRef(tsUserSdb, pUser); 
}

207
static int32_t mnodeUpdateUser(SUserObj *pUser, void *pMsg) {
S
slguan 已提交
208
  SSdbOper oper = {
209
    .type  = SDB_OPER_GLOBAL,
S
slguan 已提交
210
    .table = tsUserSdb,
211 212
    .pObj  = pUser,
    .pMsg  = pMsg
S
slguan 已提交
213 214 215
  };

  int32_t code = sdbUpdateRow(&oper);
S
Shengliang Guan 已提交
216 217 218
  if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) {
    mError("user:%s, failed to alter by %s, reason:%s", pUser->user, mnodeGetUserFromMsg(pMsg), tstrerror(code));
  } else {
219
    mLInfo("user:%s, is altered by %s", pUser->user, mnodeGetUserFromMsg(pMsg));
S
slguan 已提交
220
  }
221 222

  return code;
223
}
H
hzcheng 已提交
224

225
int32_t mnodeCreateUser(SAcctObj *pAcct, char *name, char *pass, void *pMsg) {
S
slguan 已提交
226
  int32_t code = acctCheck(pAcct, ACCT_GRANT_USER);
227
  if (code != TSDB_CODE_SUCCESS) {
S
slguan 已提交
228
    return code;
H
hzcheng 已提交
229 230
  }

231
  if (name[0] == 0) {
232
    return TSDB_CODE_MND_INVALID_USER_FORMAT;
233 234 235
  }

  if (pass[0] == 0) {
236
    return TSDB_CODE_MND_INVALID_PASS_FORMAT;
S
slguan 已提交
237 238
  }

239
  SUserObj *pUser = mnodeGetUser(name);
H
hzcheng 已提交
240
  if (pUser != NULL) {
241
    mDebug("user:%s, is already there", name);
242
    mnodeDecUserRef(pUser);
243
    return TSDB_CODE_MND_USER_ALREADY_EXIST;
H
hzcheng 已提交
244 245
  }

246 247
  code = grantCheck(TSDB_GRANT_USER);
  if (code != TSDB_CODE_SUCCESS) {
S
slguan 已提交
248 249 250
    return code;
  }

S
slguan 已提交
251
  pUser = calloc(1, sizeof(SUserObj));
S
Shengliang Guan 已提交
252
  tstrncpy(pUser->user, name, TSDB_USER_LEN);
S
slguan 已提交
253
  taosEncryptPass((uint8_t*) pass, strlen(pass), pUser->pass);
H
hzcheng 已提交
254 255 256 257
  strcpy(pUser->acct, pAcct->user);
  pUser->createdTime = taosGetTimestampMs();
  pUser->superAuth = 0;
  pUser->writeAuth = 1;
258
  if (strcmp(pUser->user, TSDB_DEFAULT_USER) == 0 || strcmp(pUser->user, pUser->acct) == 0) {
H
hzcheng 已提交
259 260 261
    pUser->superAuth = 1;
  }

S
slguan 已提交
262
  SSdbOper oper = {
263 264 265
    .type    = SDB_OPER_GLOBAL,
    .table   = tsUserSdb,
    .pObj    = pUser,
266
    .rowSize = sizeof(SUserObj),
267
    .pMsg    = pMsg
S
slguan 已提交
268 269 270
  };

  code = sdbInsertRow(&oper);
S
Shengliang Guan 已提交
271 272
  if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) {
    mError("user:%s, failed to create by %s, reason:%s", pUser->user, mnodeGetUserFromMsg(pMsg), tstrerror(code));
S
Shengliang Guan 已提交
273
    taosTFree(pUser);
274
  } else {
275
    mLInfo("user:%s, is created by %s", pUser->user, mnodeGetUserFromMsg(pMsg));
H
hzcheng 已提交
276
  }
277 278

  return code;
H
hzcheng 已提交
279 280
}

281
static int32_t mnodeDropUser(SUserObj *pUser, void *pMsg) {
S
slguan 已提交
282
  SSdbOper oper = {
283
    .type  = SDB_OPER_GLOBAL,
S
slguan 已提交
284
    .table = tsUserSdb,
285 286
    .pObj  = pUser,
    .pMsg  = pMsg
S
slguan 已提交
287
  };
H
hzcheng 已提交
288

S
slguan 已提交
289
  int32_t code = sdbDeleteRow(&oper);
S
Shengliang Guan 已提交
290 291 292
  if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) {
    mError("user:%s, failed to drop by %s, reason:%s", pUser->user, mnodeGetUserFromMsg(pMsg), tstrerror(code));
  } else {
293
    mLInfo("user:%s, is dropped by %s", pUser->user, mnodeGetUserFromMsg(pMsg));
S
slguan 已提交
294
  }
295 296

  return code;
H
hzcheng 已提交
297 298
}

299 300
static int32_t mnodeGetUserMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) {
  SUserObj *pUser = mnodeGetUserFromConn(pConn);
S
slguan 已提交
301
  if (pUser == NULL) {
302
    return TSDB_CODE_MND_NO_USER_FROM_CONN;
S
slguan 已提交
303 304
  }

305
  int32_t cols = 0;
H
hjxilinx 已提交
306
  SSchema *pSchema = pMeta->schema;
S
slguan 已提交
307

H
hjxilinx 已提交
308
  pShow->bytes[cols] = TSDB_USER_LEN + VARSTR_HEADER_SIZE;
S
slguan 已提交
309 310 311 312 313
  pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
  strcpy(pSchema[cols].name, "name");
  pSchema[cols].bytes = htons(pShow->bytes[cols]);
  cols++;

H
hjxilinx 已提交
314
  pShow->bytes[cols] = 8 + VARSTR_HEADER_SIZE;
S
slguan 已提交
315 316 317 318 319 320 321
  pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
  strcpy(pSchema[cols].name, "privilege");
  pSchema[cols].bytes = htons(pShow->bytes[cols]);
  cols++;

  pShow->bytes[cols] = 8;
  pSchema[cols].type = TSDB_DATA_TYPE_TIMESTAMP;
H
hjxilinx 已提交
322
  strcpy(pSchema[cols].name, "create_time");
S
slguan 已提交
323 324 325
  pSchema[cols].bytes = htons(pShow->bytes[cols]);
  cols++;

326 327 328 329 330 331
  pShow->bytes[cols] = TSDB_USER_LEN + VARSTR_HEADER_SIZE;
  pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
  strcpy(pSchema[cols].name, "account");
  pSchema[cols].bytes = htons(pShow->bytes[cols]);
  cols++;

S
slguan 已提交
332 333 334 335 336 337 338 339 340 341 342
  pMeta->numOfColumns = htons(cols);
  strcpy(pMeta->tableId, "show users");
  pShow->numOfColumns = cols;

  pShow->offset[0] = 0;
  for (int32_t i = 1; i < cols; ++i) {
    pShow->offset[i] = pShow->offset[i - 1] + pShow->bytes[i - 1];
  }

  pShow->numOfRows = pUser->pAcct->acctInfo.numOfUsers;
  pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1];
H
hzcheng 已提交
343

344
  mnodeDecUserRef(pUser);
H
hzcheng 已提交
345 346 347
  return 0;
}

348
static int32_t mnodeRetrieveUsers(SShowObj *pShow, char *data, int32_t rows, void *pConn) {
S
slguan 已提交
349 350 351 352 353 354
  int32_t  numOfRows = 0;
  SUserObj *pUser    = NULL;
  int32_t  cols      = 0;
  char     *pWrite;

  while (numOfRows < rows) {
355
    pShow->pIter = mnodeGetNextUser(pShow->pIter, &pUser);
S
slguan 已提交
356
    if (pUser == NULL) break;
S
slguan 已提交
357
    
S
slguan 已提交
358 359 360
    cols = 0;

    pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
H
Hui Li 已提交
361
    STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pUser->user, pShow->bytes[cols]);
S
slguan 已提交
362 363 364 365
    cols++;

    pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
    if (pUser->superAuth) {
sangshuduo's avatar
sangshuduo 已提交
366 367
      const char *src = "super";
      STR_WITH_SIZE_TO_VARSTR(pWrite, src, strlen(src));
S
slguan 已提交
368
    } else if (pUser->writeAuth) {
sangshuduo's avatar
sangshuduo 已提交
369 370
      const char *src = "writable";
      STR_WITH_SIZE_TO_VARSTR(pWrite, src, strlen(src));
S
slguan 已提交
371
    } else {
sangshuduo's avatar
sangshuduo 已提交
372 373
      const char *src = "readable";
      STR_WITH_SIZE_TO_VARSTR(pWrite, src, strlen(src));
S
slguan 已提交
374 375 376 377 378 379 380
    }
    cols++;

    pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
    *(int64_t *)pWrite = pUser->createdTime;
    cols++;

381
    pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
H
Hui Li 已提交
382
    STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pUser->acct, pShow->bytes[cols]);
383 384
    cols++;

S
slguan 已提交
385
    numOfRows++;
386
    mnodeDecUserRef(pUser);
S
slguan 已提交
387
  }
388

S
slguan 已提交
389
  pShow->numOfReads += numOfRows;
H
hzcheng 已提交
390 391 392
  return numOfRows;
}

393
SUserObj *mnodeGetUserFromConn(void *pConn) {
394
  SRpcConnInfo connInfo = {0};
395
  if (rpcGetConnInfo(pConn, &connInfo) == 0) {
396
    return mnodeGetUser(connInfo.user);
397 398 399
  } else {
    mError("can not get user from conn:%p", pConn);
    return NULL;
400
  }
S
slguan 已提交
401
}
S
slguan 已提交
402

403 404
char *mnodeGetUserFromMsg(void *pMsg) {
  SMnodeMsg *pMnodeMsg = pMsg;
S
Shengliang Guan 已提交
405
  if (pMnodeMsg != NULL && pMnodeMsg->pUser != NULL) {
406 407 408 409 410 411
    return pMnodeMsg->pUser->user;
  } else {
    return "system";
  }
}

412
static int32_t mnodeProcessCreateUserMsg(SMnodeMsg *pMsg) {
413
  SUserObj *pOperUser = pMsg->pUser;
414
  
415
  if (pOperUser->superAuth) {
S
Shengliang Guan 已提交
416
    SCMCreateUserMsg *pCreate = pMsg->rpcMsg.pCont;
417
    return mnodeCreateUser(pOperUser->pAcct, pCreate->user, pCreate->pass, pMsg);
S
slguan 已提交
418
  } else {
S
slguan 已提交
419
    mError("user:%s, no rights to create user", pOperUser->user);
420
    return TSDB_CODE_MND_NO_RIGHTS;
S
slguan 已提交
421 422 423
  }
}

424
static int32_t mnodeProcessAlterUserMsg(SMnodeMsg *pMsg) {
425 426 427
  int32_t code;
  SUserObj *pOperUser = pMsg->pUser;
  
S
Shengliang Guan 已提交
428
  SCMAlterUserMsg *pAlter = pMsg->rpcMsg.pCont;
429
  SUserObj *pUser = mnodeGetUser(pAlter->user);
S
slguan 已提交
430
  if (pUser == NULL) {
431
    return TSDB_CODE_MND_INVALID_USER;
S
slguan 已提交
432 433 434
  }

  if (strcmp(pUser->user, "monitor") == 0 || (strcmp(pUser->user + 1, pUser->acct) == 0 && pUser->user[0] == '_')) {
435
    mnodeDecUserRef(pUser);
436
    return TSDB_CODE_MND_NO_RIGHTS;
S
slguan 已提交
437 438 439 440
  }

  if ((pAlter->flag & TSDB_ALTER_USER_PASSWD) != 0) {
    bool hasRight = false;
441
    if (strcmp(pOperUser->user, TSDB_DEFAULT_USER) == 0) {
S
slguan 已提交
442 443 444 445
      hasRight = true;
    } else if (strcmp(pUser->user, pOperUser->user) == 0) {
      hasRight = true;
    } else if (pOperUser->superAuth) {
446
      if (strcmp(pUser->user, TSDB_DEFAULT_USER) == 0) {
S
slguan 已提交
447 448 449 450 451 452 453 454 455 456 457
        hasRight = false;
      } else if (strcmp(pOperUser->acct, pUser->acct) != 0) {
        hasRight = false;
      } else {
        hasRight = true;
      }
    }

    if (hasRight) {
      memset(pUser->pass, 0, sizeof(pUser->pass));
      taosEncryptPass((uint8_t*)pAlter->pass, strlen(pAlter->pass), pUser->pass);
458
      code = mnodeUpdateUser(pUser, pMsg);
S
slguan 已提交
459
    } else {
C
chang 已提交
460
      mError("user:%s, no rights to alter user", pOperUser->user);
461
      code = TSDB_CODE_MND_NO_RIGHTS;
S
slguan 已提交
462
    }
S
slguan 已提交
463
  } else if ((pAlter->flag & TSDB_ALTER_USER_PRIVILEGES) != 0) {
S
slguan 已提交
464 465
    bool hasRight = false;

466
    if (strcmp(pUser->user, TSDB_DEFAULT_USER) == 0) {
S
slguan 已提交
467 468 469
      hasRight = false;
    } else if (strcmp(pUser->user, pUser->acct) == 0) {
      hasRight = false;
470
    } else if (strcmp(pOperUser->user, TSDB_DEFAULT_USER) == 0) {
S
slguan 已提交
471 472 473 474
      hasRight = true;
    } else if (strcmp(pUser->user, pOperUser->user) == 0) {
      hasRight = false;
    } else if (pOperUser->superAuth) {
475
      if (strcmp(pUser->user, TSDB_DEFAULT_USER) == 0) {
S
slguan 已提交
476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497
        hasRight = false;
      } else if (strcmp(pOperUser->acct, pUser->acct) != 0) {
        hasRight = false;
      } else {
        hasRight = true;
      }
    }

    if (pAlter->privilege == 1) { // super
      hasRight = false;
    }

    if (hasRight) {
      if (pAlter->privilege == 2) {  // read
        pUser->superAuth = 0;
        pUser->writeAuth = 0;
      }
      if (pAlter->privilege == 3) {  // write
        pUser->superAuth = 0;
        pUser->writeAuth = 1;
      }

498
      code = mnodeUpdateUser(pUser, pMsg);
S
slguan 已提交
499
    } else {
C
chang 已提交
500
      mError("user:%s, no rights to alter user", pOperUser->user);
501
      code = TSDB_CODE_MND_NO_RIGHTS;
S
slguan 已提交
502
    }
S
slguan 已提交
503
  } else {
C
chang 已提交
504
    mError("user:%s, no rights to alter user", pOperUser->user);
505
    code = TSDB_CODE_MND_NO_RIGHTS;
S
slguan 已提交
506 507
  }

508 509
  mnodeDecUserRef(pUser);
  return code;
S
slguan 已提交
510 511
}

512
static int32_t mnodeProcessDropUserMsg(SMnodeMsg *pMsg) {
513 514
  int32_t code;
  SUserObj *pOperUser = pMsg->pUser;
S
slguan 已提交
515

S
Shengliang Guan 已提交
516
  SCMDropUserMsg *pDrop = pMsg->rpcMsg.pCont;
517
  SUserObj *pUser = mnodeGetUser(pDrop->user);
S
slguan 已提交
518
  if (pUser == NULL) {
519
    return TSDB_CODE_MND_INVALID_USER;
S
slguan 已提交
520 521
  }

S
[TD-16]  
slguan 已提交
522 523
  if (strcmp(pUser->user, "monitor") == 0 || strcmp(pUser->user, pUser->acct) == 0 ||
    (strcmp(pUser->user + 1, pUser->acct) == 0 && pUser->user[0] == '_')) {
524
    mnodeDecUserRef(pUser);
525
    return TSDB_CODE_MND_NO_RIGHTS;
S
slguan 已提交
526 527 528
  }

  bool hasRight = false;
529
  if (strcmp(pUser->user, TSDB_DEFAULT_USER) == 0) {
S
slguan 已提交
530
    hasRight = false;
531
  } else if (strcmp(pOperUser->user, TSDB_DEFAULT_USER) == 0) {
S
slguan 已提交
532 533 534 535
    hasRight = true;
  } else if (strcmp(pUser->user, pOperUser->user) == 0) {
    hasRight = false;
  } else if (pOperUser->superAuth) {
S
slguan 已提交
536
    if (strcmp(pOperUser->acct, pUser->acct) != 0) {
S
slguan 已提交
537 538 539 540 541 542 543
      hasRight = false;
    } else {
      hasRight = true;
    }
  }

  if (hasRight) {
544
    code = mnodeDropUser(pUser, pMsg);
S
slguan 已提交
545
  } else {
546
    code = TSDB_CODE_MND_NO_RIGHTS;
S
slguan 已提交
547 548
  }

549 550
  mnodeDecUserRef(pUser);
  return code;
S
slguan 已提交
551
}
S
[TD-61]  
slguan 已提交
552

553
void mnodeDropAllUsers(SAcctObj *pAcct)  {
S
Shengliang Guan 已提交
554
  void *    pIter = NULL;
S
slguan 已提交
555 556
  int32_t   numOfUsers = 0;
  int32_t   acctNameLen = strlen(pAcct->user);
S
[TD-61]  
slguan 已提交
557 558 559
  SUserObj *pUser = NULL;

  while (1) {
560
    pIter = mnodeGetNextUser(pIter, &pUser);
S
[TD-61]  
slguan 已提交
561 562 563
    if (pUser == NULL) break;

    if (strncmp(pUser->acct, pAcct->user, acctNameLen) == 0) {
S
slguan 已提交
564
      SSdbOper oper = {
S
slguan 已提交
565
        .type = SDB_OPER_LOCAL,
S
[TD-61]  
slguan 已提交
566 567 568 569 570 571
        .table = tsUserSdb,
        .pObj = pUser,
      };
      sdbDeleteRow(&oper);
      numOfUsers++;
    }
S
slguan 已提交
572

573
    mnodeDecUserRef(pUser);
S
[TD-61]  
slguan 已提交
574 575
  }

S
Shengliang Guan 已提交
576 577
  sdbFreeIter(pIter);

578
  mDebug("acct:%s, all users:%d is dropped from sdb", pAcct->user, numOfUsers);
sangshuduo's avatar
sangshuduo 已提交
579
}
S
Shengliang Guan 已提交
580

581
int32_t mnodeRetriveAuth(char *user, char *spi, char *encrypt, char *secret, char *ckey) {
S
Shengliang Guan 已提交
582 583
  if (!sdbIsMaster()) {
    *secret = 0;
S
Shengliang Guan 已提交
584 585
    mDebug("user:%s, failed to auth user, reason:%s", user, tstrerror(TSDB_CODE_APP_NOT_READY));
    return TSDB_CODE_APP_NOT_READY;
S
Shengliang Guan 已提交
586 587
  }

588
  SUserObj *pUser = mnodeGetUser(user);
S
Shengliang Guan 已提交
589 590
  if (pUser == NULL) {
    *secret = 0;
591 592
    mError("user:%s, failed to auth user, reason:%s", user, tstrerror(TSDB_CODE_MND_INVALID_USER));
    return TSDB_CODE_MND_INVALID_USER;
S
Shengliang Guan 已提交
593 594 595 596 597 598
  } else {
    *spi = 1;
    *encrypt = 0;
    *ckey = 0;

    memcpy(secret, pUser->pass, TSDB_KEY_LEN);
599
    mnodeDecUserRef(pUser);
600
    mDebug("user:%s, auth info is returned", user);
S
Shengliang Guan 已提交
601 602 603 604
    return TSDB_CODE_SUCCESS;
  }
}

605
static int32_t mnodeProcessAuthMsg(SMnodeMsg *pMsg) {
S
Shengliang Guan 已提交
606
  SDMAuthMsg *pAuthMsg = pMsg->rpcMsg.pCont;
S
Shengliang Guan 已提交
607 608
  SDMAuthRsp *pAuthRsp = rpcMallocCont(sizeof(SDMAuthRsp));
  
609 610
  pMsg->rpcRsp.rsp = pAuthRsp;
  pMsg->rpcRsp.len = sizeof(SDMAuthRsp);
S
Shengliang Guan 已提交
611
  
612
  return mnodeRetriveAuth(pAuthMsg->user, &pAuthRsp->spi, &pAuthRsp->encrypt, pAuthRsp->secret, pAuthRsp->ckey);
S
Shengliang Guan 已提交
613
}