Files
oceanbase/src/share/ob_priv_common.cpp
wangzelin.wzl 93a1074b0c patch 4.0
2022-10-24 17:57:12 +08:00

602 lines
18 KiB
C++

/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#define USING_LOG_PREFIX SHARE_SCHEMA
#include "share/ob_priv_common.h"
#include "ob_define.h"
#include "lib/charset/ob_charset.h"
#include "lib/oblog/ob_log_module.h"
namespace oceanbase
{
using namespace common;
namespace share
{
#define N_PIRVS_PER_GROUP 30
/* 300个权限*/
int group_id_arr[] =
{
0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
};
/* 300个权限 */
int th_in_group_arr[] =
{
0,
0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, /* 1- 15 */
30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, /* 16-30 */
0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, /* 31-45 */
30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, /* 46-60 */
0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, /* 61-75 */
30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, /* 76-90 */
0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, /* 91-105 */
30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, /* 106-120 */
0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, /* 121-135 */
30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, /* 136-150 */
0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, /* 151-165 */
30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, /* 166-180 */
0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, /* 181-195 */
30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, /* 196-210 */
0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, /* 211-225 */
30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, /* 226-240 */
0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, /* 241-255 */
30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, /* 256-270 */
0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, /* 271-285 */
30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, /* 286-300 */
};
#define NTHID_TO_PACKED(i) (1LL << i)
int ObPrivPacker::init_packed_array(
ObPackedPrivArray &array)
{
int ret = OB_SUCCESS;
array.reset();
OZ (array.push_back(0));
OZ (array.push_back(0));
OZ (array.push_back(0));
return ret;
}
int ObPrivPacker::raw_priv_to_packed_info(
const uint64_t option,
const ObRawPriv priv,
int &group_id,
ObPrivSet &packed_priv)
{
int ret = OB_SUCCESS;
CK (priv > 0 && priv < PRIV_ID_MAX);
group_id = group_id_arr[priv];
packed_priv = NTHID_TO_PACKED(th_in_group_arr[priv]);
CK (option == NO_OPTION || option == ADMIN_OPTION);
if (option == ADMIN_OPTION) {
packed_priv |= packed_priv << 1;
}
return ret;
}
int ObPrivPacker::raw_obj_priv_to_packed_info(
const uint64_t option,
const ObRawObjPriv priv,
ObPackedObjPriv &packed_priv)
{
int ret = OB_SUCCESS;
CK (priv >= 0 && priv <= OBJ_PRIV_ID_MAX);
packed_priv = NTHID_TO_PACKED(th_in_group_arr[priv]);
CK (option == NO_OPTION || option == GRANT_OPTION);
if (option == GRANT_OPTION) {
packed_priv |= packed_priv << 1;
}
return ret;
}
/* 判断一个相对的priv id是否在privset里面,同时输出option信息 */
int ObPrivPacker::has_raw_priv(
const ObRawPriv raw_priv,
const ObPrivSet priv_set,
bool &exists,
uint64_t &option)
{
int ret = OB_SUCCESS;
ObPrivSet packed_priv;
exists = false;
CK (raw_priv >= 0 && raw_priv <= PRIV_ID_MAX);
if (OB_SUCC(ret)) {
packed_priv = NTHID_TO_PACKED(th_in_group_arr[raw_priv]);
if (packed_priv & priv_set) {
exists = true;
if ((packed_priv << 1) & priv_set) {
option = 1;
}
}
}
return ret;
}
/* 将相对raw priv和group idx,还原到raw priv,根据option,push back到相应的链表 */
int ObPrivPacker::push_back_raw_priv_array(
ObRawPriv raw_priv,
bool exists,
uint64_t option,
ObRawPrivArray &raw_priv_array,
ObRawPrivArray &raw_priv_array_with_option)
{
int ret = OB_SUCCESS;
if (exists) {
if (option) {
OZ (raw_priv_array_with_option.push_back(raw_priv));
}
else {
OZ (raw_priv_array.push_back(raw_priv));
}
}
return ret;
}
/* 解析packed_array到raw privs array,根据是否有option,输出两个链表 */
int ObPrivPacker::packed_array_to_raw_privs(
const ObPackedPrivArray &packed_array, /* in: packed info from sys priv schema */
ObRawPrivArray &raw_priv_array, /* out: raw privs array */
ObRawPrivArray &raw_priv_array_with_option) /* out: raw privs with option array */
{
int ret = OB_SUCCESS;
ObPrivSet priv_set;
ObRawPriv raw_priv;
// unused
// ObRawPriv related_raw_priv;
bool stop = false;
int i = 0;
bool exists = false;
uint64_t option;
ARRAY_FOREACH(packed_array, group_idx) {
priv_set = packed_array.at(group_idx);
if (priv_set > 0) {
raw_priv = group_idx * N_PIRVS_PER_GROUP + 1;
for (i = 0; OB_SUCC(ret) && !stop && i < N_PIRVS_PER_GROUP; i ++) {
OZ (has_raw_priv(raw_priv, priv_set, exists, option));
OZ (push_back_raw_priv_array(raw_priv,
exists,
option,
raw_priv_array,
raw_priv_array_with_option));
OX (raw_priv ++);
if (raw_priv >= PRIV_ID_MAX) {
stop = true;
}
}
}
}
return ret;
}
bool ObOraPrivCheck::user_is_owner(
const ObString &user_name,
const ObString &db_name)
{
return ObCharset::case_sensitive_equal(user_name, db_name);
}
int ObPrivPacker::pack_raw_priv(
const uint64_t option,
const ObRawPriv priv,
ObPackedPrivArray &packed_array)
{
int group_id;
ObPrivSet packed_priv;
int ret = OB_SUCCESS;
OZ (raw_priv_to_packed_info(option, priv, group_id, packed_priv));
if (OB_SUCC(ret)) {
if (packed_array.count() > 0) {
if (group_id >= packed_array.count()) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("group id error", K(ret));
} else {
packed_array[group_id] |= packed_priv;
}
} else {
LOG_WARN("packed_array has no space reserved");
}
}
return ret;
}
int ObPrivPacker::pack_raw_priv_list(
const uint64_t option,
const ObRawPrivArray &priv_list,
ObPackedPrivArray &packed_array)
{
int group_id;
ObPrivSet packed_priv;
ObRawPriv priv;
int ret = OB_SUCCESS;
OZ (ObPrivPacker::init_packed_array(packed_array));
for (int i = 0; OB_SUCC(ret) && i < priv_list.count(); i++) {
priv = priv_list.at(i);
OZ (raw_priv_to_packed_info(option, priv, group_id, packed_priv));
if (OB_SUCC(ret)) {
if (packed_array.count() > 0) {
if (group_id >= packed_array.count()) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("group id error", K(ret));
} else {
packed_array[group_id] |= packed_priv;
}
} else {
LOG_WARN("packed_array has no space reserved");
}
}
}
return ret;
}
int ObPrivPacker::pack_raw_obj_priv(
const uint64_t option,
const ObRawPriv priv,
ObPackedObjPriv &packed_obj_priv)
{
int ret = OB_SUCCESS;
OZ (raw_obj_priv_to_packed_info(option, priv, packed_obj_priv),
option, priv);
return ret;
}
int ObPrivPacker::pack_raw_obj_priv_list(
const uint64_t option,
const ObRawObjPrivArray priv_list,
ObPackedObjPriv &packed_obj_priv)
{
int ret = OB_SUCCESS;
packed_obj_priv = 0;
for (int i = 0; OB_SUCC(ret) && i < priv_list.count(); i++) {
const ObRawObjPriv priv = priv_list.at(i);
OZ (append_raw_obj_priv(option, priv, packed_obj_priv),
option, priv);
}
return ret;
}
int ObPrivPacker::append_raw_obj_priv(
const uint64_t option,
const ObRawObjPriv priv,
ObPackedObjPriv &packed_obj_privs)
{
int ret = OB_SUCCESS;
ObPackedObjPriv tmp_packed_priv;
OZ (raw_obj_priv_to_packed_info(option, priv, tmp_packed_priv));
OX (packed_obj_privs |= tmp_packed_priv);
return ret;
}
int ObPrivPacker::raw_obj_priv_from_pack(
const ObPackedObjPriv &packed_obj_privs,
ObRawObjPrivArray &raw_priv_array)
{
int ret = OB_SUCCESS;
ObRawObjPriv raw_priv;
bool exists;
raw_priv_array.reset();
if (packed_obj_privs > 0) {
CK (OBJ_PRIV_ID_MAX <= N_PIRVS_PER_GROUP);
for (raw_priv = 1; OB_SUCC(ret) && raw_priv <= OBJ_PRIV_ID_MAX; raw_priv ++) {
OZ (ObOraPrivCheck::raw_obj_priv_exists(raw_priv, packed_obj_privs, exists));
if (OB_SUCC(ret) && exists) {
OZ (raw_priv_array.push_back(raw_priv));
}
}
}
return ret;
}
int ObPrivPacker::raw_option_obj_priv_from_pack(
const ObPackedObjPriv &packed_obj_privs,
ObRawObjPrivArray &raw_priv_array)
{
int ret = OB_SUCCESS;
ObRawObjPriv raw_priv;
bool exists;
raw_priv_array.reset();
if (packed_obj_privs > 0) {
CK (OBJ_PRIV_ID_MAX <= N_PIRVS_PER_GROUP);
for (raw_priv = 1; OB_SUCC(ret) && raw_priv <= OBJ_PRIV_ID_MAX; raw_priv ++) {
OZ (ObOraPrivCheck::raw_obj_priv_exists(raw_priv, GRANT_OPTION, packed_obj_privs, exists));
if (OB_SUCC(ret) && exists) {
OZ (raw_priv_array.push_back(raw_priv));
}
}
}
return ret;
}
int ObPrivPacker::raw_no_option_obj_priv_from_pack(
const ObPackedObjPriv &packed_obj_privs,
ObRawObjPrivArray &raw_priv_array)
{
int ret = OB_SUCCESS;
ObRawObjPriv raw_priv;
bool exists_grant;
bool exists;
raw_priv_array.reset();
if (packed_obj_privs > 0) {
CK (OBJ_PRIV_ID_MAX <= N_PIRVS_PER_GROUP);
for (raw_priv = 1; OB_SUCC(ret) && raw_priv <= OBJ_PRIV_ID_MAX; raw_priv ++) {
OZ (ObOraPrivCheck::raw_obj_priv_exists(raw_priv, packed_obj_privs, exists));
OZ (ObOraPrivCheck::raw_obj_priv_exists(raw_priv, GRANT_OPTION,
packed_obj_privs, exists_grant));
if (OB_SUCC(ret) && exists && !exists_grant) {
OZ (raw_priv_array.push_back(raw_priv));
}
}
}
return ret;
}
int ObPrivPacker::merge_two_packed_array(
ObPackedPrivArray &packed_array_1,
const ObPackedPrivArray &packed_array_2)
{
int ret = OB_SUCCESS;
int i;
if (packed_array_1.count() == 0) {
packed_array_1 = packed_array_2;
} else if (packed_array_2.count() > 0) {
CK (packed_array_1.count() == packed_array_2.count());
for (i = 0; i < packed_array_1.count() && OB_SUCC(ret); i++) {
packed_array_1[i] |= packed_array_2[i];
}
}
return ret;
}
int ObOraPrivCheck::raw_sys_priv_exists(
const uint64_t option,
const ObRawPriv priv,
const ObPackedPrivArray &packed_array,
bool &exists)
{
int ret = OB_SUCCESS;
int group_id;
ObPrivSet packed_priv;
exists = false;
if (packed_array.count() > 0) {
if (priv == OBJ_PRIV_ID_NONE) {
exists = FALSE;
} else {
OZ (ObPrivPacker::raw_priv_to_packed_info(option, priv, group_id, packed_priv));
if (OB_SUCC(ret)) {
if (group_id >= packed_array.count()) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("group id error", K(option), K(priv), K(packed_array), K(group_id), K(ret));
} else if (OB_TEST_PRIVS(packed_array.at(group_id), packed_priv)) {
exists = true;
}
}
}
}
return ret;
}
int ObOraPrivCheck::raw_sys_priv_exists(
const ObRawPriv priv,
const ObPackedPrivArray &packed_array,
bool &exists)
{
int ret = OB_SUCCESS;
int group_id;
ObPrivSet packed_priv;
exists = false;
if (priv > 0 && packed_array.count() > 0) {
OZ (ObPrivPacker::raw_priv_to_packed_info(NO_OPTION, priv, group_id, packed_priv), priv);
if (OB_SUCC(ret)) {
if (group_id >= packed_array.count()) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("group id error", K(priv), K(packed_array), K(group_id), K(ret));
} else if (OB_TEST_PRIVS(packed_array.at(group_id), packed_priv)) {
exists = true;
}
}
}
return ret;
}
int ObOraPrivCheck::packed_sys_priv_list_or_exists(
const ObPackedPrivArray &plist_to_be_checked,
const ObPackedPrivArray &packed_array,
bool &exists)
{
int ret = OB_SUCCESS;
int group_id;
exists = false;
for (group_id = 0; !exists && group_id < plist_to_be_checked.count(); group_id++) {
if (plist_to_be_checked.at(group_id) != 0
&& group_id < packed_array.count()
&& (OB_PRIV_HAS_ANY(plist_to_be_checked.at(group_id), packed_array.at(group_id))))
exists = true;
}
return ret;
}
int ObOraPrivCheck::packed_sys_priv_list_and_exists(
const ObPackedPrivArray &plist_to_be_checked,
const ObPackedPrivArray &packed_array,
bool &exists)
{
int ret = OB_SUCCESS;
int group_id;
exists = true;
for (group_id = 0; exists && group_id < plist_to_be_checked.count(); group_id++) {
if (plist_to_be_checked.at(group_id) != 0) {
if (group_id >= packed_array.count()) {
exists = false;
} else {
if (OB_TEST_PRIVS(packed_array.at(group_id), plist_to_be_checked.at(group_id))) {
} else {
exists = false;
}
}
}
}
return ret;
}
int ObOraPrivCheck::raw_obj_priv_exists(
const ObRawObjPriv priv,
const ObPackedObjPriv &obj_privs,
bool &exists)
{
int ret = OB_SUCCESS;
exists = false;
if (priv > 0) {
ObPrivSet packed_priv;
OZ (ObPrivPacker::raw_obj_priv_to_packed_info(NO_OPTION, priv, packed_priv));
OX (exists = OB_TEST_PRIVS(obj_privs, packed_priv));
}
return ret;
}
int ObOraPrivCheck::raw_obj_priv_exists_with_info(
const ObRawObjPriv priv,
const ObPackedObjPriv &obj_privs,
bool &exists,
uint64_t &option)
{
int ret = OB_SUCCESS;
exists = false;
option = NO_OPTION;
if (priv > 0) {
ObPrivSet packed_priv;
OZ (ObPrivPacker::raw_obj_priv_to_packed_info(NO_OPTION, priv, packed_priv));
OX (exists = OB_TEST_PRIVS(obj_privs, packed_priv));
if (OB_SUCC(ret) && exists) {
bool tmp_exist = false;
OZ (ObPrivPacker::raw_obj_priv_to_packed_info(GRANT_OPTION, priv, packed_priv));
OX (tmp_exist = OB_TEST_PRIVS(obj_privs, packed_priv));
OX (option = tmp_exist ? GRANT_OPTION: NO_OPTION);
}
}
return ret;
}
int ObOraPrivCheck::raw_obj_priv_exists(
const ObRawObjPriv priv,
const uint64_t option,
const ObPackedObjPriv &obj_privs,
bool &exists)
{
int ret = OB_SUCCESS;
exists = false;
if (priv > 0) {
ObPrivSet packed_priv;
OZ (ObPrivPacker::raw_obj_priv_to_packed_info(option, priv, packed_priv));
OX (exists = OB_TEST_PRIVS(obj_privs, packed_priv));
}
return ret;
}
int ObOraPrivCheck::packed_obj_priv_list_or_exists(
const ObPackedObjPriv &priv_list_to_be_checked,
const ObPackedObjPriv &obj_privs,
bool &exists)
{
int ret = OB_SUCCESS;
exists = OB_PRIV_HAS_ANY(obj_privs, priv_list_to_be_checked);
return ret;
}
int ObOraPrivCheck::p1_or_cond_p2_exists(
const ObRawPriv priv1,
bool cond,
const ObRawPriv priv2,
const ObPackedPrivArray &packed_array,
bool &exists)
{
int ret = OB_SUCCESS;
OZ (raw_sys_priv_exists(priv1, packed_array, exists));
if (OB_SUCC(ret) && !exists && cond) {
CK (priv1 != priv2);
OZ (raw_sys_priv_exists(priv2, packed_array, exists));
}
return ret;
}
bool ObOraPrivCheck::raw_priv_can_be_granted_to_column(const ObRawObjPriv priv)
{
return (OBJ_PRIV_ID_INSERT == priv
|| OBJ_PRIV_ID_UPDATE == priv
|| OBJ_PRIV_ID_REFERENCES == priv);
}
int ObPrivPacker::get_total_privs(
const ObPackedPrivArray &packed_array,
int &n_cnt)
{
int ret = OB_SUCCESS;
int i;
int j;
ObRawPriv raw_priv;
n_cnt = 0;
for (i = 0; i < packed_array.count() && OB_SUCC(ret); i++) {
const ObPrivSet &item = packed_array[i];
if (item > 0) {
raw_priv = N_PIRVS_PER_GROUP * i + 1;
for (j = 0; j < N_PIRVS_PER_GROUP && OB_SUCC(ret); j++) {
if ((item & NTHID_TO_PACKED(th_in_group_arr[raw_priv])) != 0)
n_cnt ++;
OX (raw_priv ++);
}
}
}
return ret;
}
int ObPrivPacker::get_total_obj_privs(
const ObPackedObjPriv &packed_obj_privs,
int &n_cnt)
{
int ret = OB_SUCCESS;
ObRawObjPriv raw_priv;
bool exists;
n_cnt = 0;
if (packed_obj_privs > 0) {
CK (OBJ_PRIV_ID_MAX <= N_PIRVS_PER_GROUP);
for (raw_priv = 1; OB_SUCC(ret) && raw_priv <= OBJ_PRIV_ID_MAX; raw_priv ++) {
OZ (ObOraPrivCheck::raw_obj_priv_exists(raw_priv, packed_obj_privs, exists));
if (OB_SUCC(ret) && exists) {
n_cnt ++;
}
}
}
return ret;
}
}//end namespace share
}//end namespace oceanbase