parAuthenticator.c 4.0 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/*
 * 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/>.
 */

#include "catalog.h"
X
Xiaoyu Wang 已提交
17
#include "cmdnodes.h"
18 19 20
#include "parInt.h"

typedef struct SAuthCxt {
21 22 23
  SParseContext*   pParseCxt;
  SParseMetaCache* pMetaCache;
  int32_t          errCode;
24 25 26 27
} SAuthCxt;

static int32_t authQuery(SAuthCxt* pCxt, SNode* pStmt);

28 29 30
static int32_t checkAuth(SAuthCxt* pCxt, const char* pDbName, AUTH_TYPE type) {
  SParseContext* pParseCxt = pCxt->pParseCxt;
  if (pParseCxt->isSuperUser) {
31 32
    return TSDB_CODE_SUCCESS;
  }
33
  SName name;
34
  tNameSetDbName(&name, pParseCxt->acctId, pDbName, strlen(pDbName));
35 36
  char dbFname[TSDB_DB_FNAME_LEN] = {0};
  tNameGetFullDbName(&name, dbFname);
37
  int32_t code = TSDB_CODE_SUCCESS;
38
  bool    pass = false;
39 40 41
  if (NULL != pCxt->pMetaCache) {
    code = getUserAuthFromCache(pCxt->pMetaCache, pParseCxt->pUser, dbFname, type, &pass);
  } else {
D
dapan1121 已提交
42 43 44 45 46 47
    SRequestConnInfo conn = {.pTrans = pParseCxt->pTransporter, 
                             .requestId = pParseCxt->requestId,
                             .requestObjRefId = pParseCxt->requestRid,
                             .mgmtEps = pParseCxt->mgmtEpSet};

    code = catalogChkAuth(pParseCxt->pCatalog, &conn, pParseCxt->pUser, dbFname, type, &pass);
48
  }
49 50 51 52 53 54 55 56 57 58
  return TSDB_CODE_SUCCESS == code ? (pass ? TSDB_CODE_SUCCESS : TSDB_CODE_PAR_PERMISSION_DENIED) : code;
}

static EDealRes authSubquery(SAuthCxt* pCxt, SNode* pStmt) {
  return TSDB_CODE_SUCCESS == authQuery(pCxt, pStmt) ? DEAL_RES_CONTINUE : DEAL_RES_ERROR;
}

static EDealRes authSelectImpl(SNode* pNode, void* pContext) {
  SAuthCxt* pCxt = pContext;
  if (QUERY_NODE_REAL_TABLE == nodeType(pNode)) {
59
    pCxt->errCode = checkAuth(pCxt, ((SRealTableNode*)pNode)->table.dbName, AUTH_TYPE_READ);
60 61 62 63 64 65 66 67 68 69 70 71
    return TSDB_CODE_SUCCESS == pCxt->errCode ? DEAL_RES_CONTINUE : DEAL_RES_ERROR;
  } else if (QUERY_NODE_TEMP_TABLE == nodeType(pNode)) {
    return authSubquery(pCxt, ((STempTableNode*)pNode)->pSubquery);
  }
  return DEAL_RES_CONTINUE;
}

static int32_t authSelect(SAuthCxt* pCxt, SSelectStmt* pSelect) {
  nodesWalkSelectStmt(pSelect, SQL_CLAUSE_FROM, authSelectImpl, pCxt);
  return pCxt->errCode;
}

72 73 74 75 76 77 78 79
static int32_t authSetOperator(SAuthCxt* pCxt, SSetOperator* pSetOper) {
  int32_t code = authQuery(pCxt, pSetOper->pLeft);
  if (TSDB_CODE_SUCCESS == code) {
    code = authQuery(pCxt, pSetOper->pRight);
  }
  return code;
}

X
Xiaoyu Wang 已提交
80 81
static int32_t authDropUser(SAuthCxt* pCxt, SDropUserStmt* pStmt) {
  if (!pCxt->pParseCxt->isSuperUser || 0 == strcmp(pStmt->useName, TSDB_DEFAULT_USER)) {
82 83 84 85 86
    return TSDB_CODE_PAR_PERMISSION_DENIED;
  }
  return TSDB_CODE_SUCCESS;
}

X
Xiaoyu Wang 已提交
87 88 89 90
static int32_t authDelete(SAuthCxt* pCxt, SDeleteStmt* pDelete) {
  return checkAuth(pCxt, ((SRealTableNode*)pDelete->pFromTable)->table.dbName, AUTH_TYPE_WRITE);
}

91 92 93
static int32_t authQuery(SAuthCxt* pCxt, SNode* pStmt) {
  switch (nodeType(pStmt)) {
    case QUERY_NODE_SET_OPERATOR:
94
      return authSetOperator(pCxt, (SSetOperator*)pStmt);
95 96
    case QUERY_NODE_SELECT_STMT:
      return authSelect(pCxt, (SSelectStmt*)pStmt);
97
    case QUERY_NODE_DROP_USER_STMT:
X
Xiaoyu Wang 已提交
98
      return authDropUser(pCxt, (SDropUserStmt*)pStmt);
X
Xiaoyu Wang 已提交
99 100
    case QUERY_NODE_DELETE_STMT:
      return authDelete(pCxt, (SDeleteStmt*)pStmt);
101 102 103 104 105 106 107
    default:
      break;
  }

  return TSDB_CODE_SUCCESS;
}

108 109
int32_t authenticate(SParseContext* pParseCxt, SQuery* pQuery, SParseMetaCache* pMetaCache) {
  SAuthCxt cxt = {.pParseCxt = pParseCxt, .pMetaCache = pMetaCache, .errCode = TSDB_CODE_SUCCESS};
110 111
  return authQuery(&cxt, pQuery->pRoot);
}