fix bug that system privs create any table, drop any tableallowed to access table obj also

This commit is contained in:
jingtaoye35
2023-11-09 13:13:48 +00:00
committed by ob-robot
parent 0c24ef4988
commit a399421cc0
6 changed files with 114 additions and 47 deletions

View File

@ -1028,7 +1028,7 @@ int ObOraSysChecker::check_owner_or_p1_or_access(
ret = OB_SUCCESS; ret = OB_SUCCESS;
bool accessible = false; bool accessible = false;
OZ (check_access_to_obj(guard, tenant_id, user_id, OZ (check_access_to_obj(guard, tenant_id, user_id,
p1, obj_type, obj_id, role_id_array, accessible)); p1, obj_type, obj_id, database_name, role_id_array, accessible));
if (OB_SUCC(ret)) { if (OB_SUCC(ret)) {
if (accessible) { if (accessible) {
ret = OB_ERR_NO_PRIVILEGE; ret = OB_ERR_NO_PRIVILEGE;
@ -1055,6 +1055,7 @@ int ObOraSysChecker::check_access_to_obj(
const ObRawPriv p1, const ObRawPriv p1,
const uint64_t obj_type, const uint64_t obj_type,
const uint64_t obj_id, const uint64_t obj_id,
const ObString &database_name,
const ObIArray<uint64_t> &role_id_array, const ObIArray<uint64_t> &role_id_array,
bool &accessible) bool &accessible)
{ {
@ -1062,13 +1063,29 @@ int ObOraSysChecker::check_access_to_obj(
accessible = false; accessible = false;
ObRawPrivArray sys_priv_array; ObRawPrivArray sys_priv_array;
ObRawObjPrivArray obj_priv_array; ObRawObjPrivArray obj_priv_array;
bool is_owner = false;
// 1. 建立和p1相关的权限列表 // 1. 建立和p1相关的权限列表
OZ (build_related_sys_priv_array(p1, sys_priv_array), p1); OZ (build_related_sys_priv_array(p1, sys_priv_array), p1);
// 2. 检查user_id是否具有sys_priv_array中的系统权限一种 // 2. 检查user_id是否具有sys_priv_array中的系统权限一种
if (OB_SUCC(ret)) { if (OB_SUCC(ret)) {
const ObUserInfo *user_info = NULL;
if (database_name.empty()) {
is_owner = true;
} else if (OB_FAIL(guard.get_user_info(tenant_id, user_id, user_info))) {
LOG_WARN("failed to get user info", K(ret), K(tenant_id), K(user_id));
} else if (OB_ISNULL(user_info)) {
ret = OB_USER_NOT_EXIST;
LOG_USER_ERROR(OB_USER_NOT_EXIST, database_name.length(), database_name.ptr());
} else {
is_owner = ObOraPrivCheck::user_is_owner(user_info->get_user_name(), database_name);
}
}
if (OB_FAIL(ret)) {
} else if (is_owner) {
accessible = true;
} else {
if (sys_priv_array.count() > 0) { if (sys_priv_array.count() > 0) {
OZ (check_p1_or_plist(guard, tenant_id, user_id, OZ (check_p1_or_plist(guard, tenant_id, user_id, p1, NO_OPTION, sys_priv_array, role_id_array));
p1, NO_OPTION, sys_priv_array, role_id_array));
} else { } else {
OZ (check_p1(guard, tenant_id, user_id, p1, role_id_array)); OZ (check_p1(guard, tenant_id, user_id, p1, role_id_array));
} }
@ -1077,18 +1094,18 @@ int ObOraSysChecker::check_access_to_obj(
} else { } else {
ret = OB_SUCCESS; ret = OB_SUCCESS;
} }
} if (OB_SUCC(ret) && !accessible) {
if (OB_SUCC(ret) && !accessible) { // 3. 建立和p1,obj_type相关的对象权限列表
// 3. 建立和p1,obj_type相关的对象权限列表 OZ (build_related_obj_priv_array(p1, obj_type, obj_priv_array), p1, obj_type);
OZ (build_related_obj_priv_array(p1, obj_type, obj_priv_array), p1, obj_type); // 4. 检查user_id对于obj_id是否具有obj_priv_array权限中的一种
// 4. 检查user_id对于obj_id是否具有obj_priv_array权限中的一种 if (OB_SUCC(ret) && obj_priv_array.count() > 0) {
if (OB_SUCC(ret) && obj_priv_array.count() > 0) { OZ (check_obj_plist_or(guard, tenant_id, user_id, obj_type, obj_id,
OZ (check_obj_plist_or(guard, tenant_id, user_id, obj_type, obj_id, OBJ_LEVEL_FOR_TAB_PRIV, obj_priv_array, role_id_array));
OBJ_LEVEL_FOR_TAB_PRIV, obj_priv_array, role_id_array)); if (OB_SUCC(ret)) {
if (OB_SUCC(ret)) { accessible = true;
accessible = true; } else {
} else { ret = OB_SUCCESS;
ret = OB_SUCCESS; }
} }
} }
} }
@ -1102,6 +1119,7 @@ int ObOraSysChecker::check_access_to_obj(
const uint64_t user_id, const uint64_t user_id,
const uint64_t obj_type, const uint64_t obj_type,
const uint64_t obj_id, const uint64_t obj_id,
const ObString &database_name,
const ObIArray<uint64_t> &role_id_array, const ObIArray<uint64_t> &role_id_array,
bool &accessible) bool &accessible)
{ {
@ -1109,33 +1127,53 @@ int ObOraSysChecker::check_access_to_obj(
accessible = false; accessible = false;
ObRawPrivArray sys_priv_array; ObRawPrivArray sys_priv_array;
ObRawObjPrivArray obj_priv_array; ObRawObjPrivArray obj_priv_array;
bool is_owner = false;
// 1. 建立相关的sys权限列表 // 1. 建立相关的sys权限列表
OZ (build_related_sys_priv_array(obj_type, sys_priv_array)); OZ (build_related_sys_priv_array(obj_type, sys_priv_array));
// 2. 检查user_id是否具有 sys_priv 中的任意一个 // 2. 检查user_id是否具有 sys_priv 中的任意一个
if (OB_SUCC(ret) && sys_priv_array.count() > 0) { if (OB_SUCC(ret)) {
OZ (check_plist_or(guard, tenant_id, user_id, sys_priv_array, role_id_array)); const ObUserInfo *user_info = NULL;
if (OB_SUCC(ret)) { if (database_name.empty()) {
accessible = true; is_owner = true;
} else if (OB_ERR_NO_PRIVILEGE == ret || OB_ERR_EMPTY_QUERY == ret) { } else if (OB_FAIL(guard.get_user_info(tenant_id, user_id, user_info))) {
accessible = false; LOG_WARN("failed to get user info", K(ret), K(tenant_id), K(user_id));
ret = OB_SUCCESS; } else if (OB_ISNULL(user_info)) {
ret = OB_USER_NOT_EXIST;
LOG_USER_ERROR(OB_USER_NOT_EXIST, database_name.length(), database_name.ptr());
} else { } else {
accessible = false; is_owner = ObOraPrivCheck::user_is_owner(user_info->get_user_name(), database_name);
} }
} }
// 3. 建立相关的对象权限 if (OB_FAIL(ret)) {
OZ (build_related_obj_priv_array(obj_type, obj_priv_array)); } else if (is_owner) {
// 4. 检查user_id 是否具有 obj_priv_array中的一种 accessible = true;
if (OB_SUCC(ret) && obj_priv_array.count() > 0 && !accessible) { /* is_owner = true, means user can access obj */
OZ (check_obj_plist_or(guard, tenant_id, user_id, obj_type, obj_id, } else {
OBJ_LEVEL_FOR_TAB_PRIV, obj_priv_array, role_id_array)); if (sys_priv_array.count() > 0) {
if (OB_SUCC(ret)) { OZ (check_plist_or(guard, tenant_id, user_id, sys_priv_array, role_id_array));
accessible = true; if (OB_SUCC(ret)) {
} else if (OB_ERR_NO_PRIVILEGE == ret || OB_ERR_EMPTY_QUERY == ret) { accessible = true;
accessible = false; } else if (OB_ERR_NO_PRIVILEGE == ret || OB_ERR_EMPTY_QUERY == ret) {
ret = OB_SUCCESS; accessible = false;
} else { ret = OB_SUCCESS;
accessible = false; } else {
accessible = false;
}
}
// 3. 建立相关的对象权限
OZ (build_related_obj_priv_array(obj_type, obj_priv_array));
// 4. 检查user_id 是否具有 obj_priv_array中的一种
if (OB_SUCC(ret) && obj_priv_array.count() > 0 && !accessible) {
OZ (check_obj_plist_or(guard, tenant_id, user_id, obj_type, obj_id,
OBJ_LEVEL_FOR_TAB_PRIV, obj_priv_array, role_id_array));
if (OB_SUCC(ret)) {
accessible = true;
} else if (OB_ERR_NO_PRIVILEGE == ret || OB_ERR_EMPTY_QUERY == ret) {
accessible = false;
ret = OB_SUCCESS;
} else {
accessible = false;
}
} }
} }
return ret; return ret;
@ -1235,6 +1273,8 @@ int ObOraSysChecker::build_related_sys_priv_array(
OZ (sys_priv_array.push_back(PRIV_ID_CREATE_ANY_VIEW)); OZ (sys_priv_array.push_back(PRIV_ID_CREATE_ANY_VIEW));
break; break;
case static_cast<uint64_t>(PRIV_ID_CREATE_ANY_VIEW): case static_cast<uint64_t>(PRIV_ID_CREATE_ANY_VIEW):
OZ (sys_priv_array.push_back(PRIV_ID_CREATE_ANY_TABLE));
OZ (sys_priv_array.push_back(PRIV_ID_DROP_ANY_TABLE));
OZ (sys_priv_array.push_back(PRIV_ID_ALTER_ANY_TABLE)); OZ (sys_priv_array.push_back(PRIV_ID_ALTER_ANY_TABLE));
OZ (sys_priv_array.push_back(PRIV_ID_LOCK_ANY_TABLE)); OZ (sys_priv_array.push_back(PRIV_ID_LOCK_ANY_TABLE));
OZ (sys_priv_array.push_back(PRIV_ID_COMMENT_ANY_TABLE)); OZ (sys_priv_array.push_back(PRIV_ID_COMMENT_ANY_TABLE));
@ -1264,6 +1304,8 @@ int ObOraSysChecker::build_related_sys_priv_array(
sys_priv_array.reset(); sys_priv_array.reset();
switch (obj_type) { switch (obj_type) {
case static_cast<uint64_t>(ObObjectType::TABLE): { case static_cast<uint64_t>(ObObjectType::TABLE): {
OZ (sys_priv_array.push_back(PRIV_ID_CREATE_ANY_TABLE));
OZ (sys_priv_array.push_back(PRIV_ID_DROP_ANY_TABLE));
OZ (sys_priv_array.push_back(PRIV_ID_ALTER_ANY_TABLE)); OZ (sys_priv_array.push_back(PRIV_ID_ALTER_ANY_TABLE));
OZ (sys_priv_array.push_back(PRIV_ID_LOCK_ANY_TABLE)); OZ (sys_priv_array.push_back(PRIV_ID_LOCK_ANY_TABLE));
OZ (sys_priv_array.push_back(PRIV_ID_COMMENT_ANY_TABLE)); OZ (sys_priv_array.push_back(PRIV_ID_COMMENT_ANY_TABLE));
@ -1291,6 +1333,7 @@ int ObOraSysChecker::build_related_obj_priv_array(
obj_priv_array.reset(); obj_priv_array.reset();
switch (obj_type) { switch (obj_type) {
case static_cast<uint64_t>(ObObjectType::TABLE): { case static_cast<uint64_t>(ObObjectType::TABLE): {
OZ (obj_priv_array.push_back(OBJ_PRIV_ID_CREATE));
OZ (obj_priv_array.push_back(OBJ_PRIV_ID_ALTER)); OZ (obj_priv_array.push_back(OBJ_PRIV_ID_ALTER));
OZ (obj_priv_array.push_back(OBJ_PRIV_ID_DEBUG)); OZ (obj_priv_array.push_back(OBJ_PRIV_ID_DEBUG));
OZ (obj_priv_array.push_back(OBJ_PRIV_ID_DELETE)); OZ (obj_priv_array.push_back(OBJ_PRIV_ID_DELETE));
@ -1720,6 +1763,12 @@ int ObOraSysChecker::check_ora_obj_priv_for_create_view(
OZ (priv_list.push_back(PRIV_ID_INSERT_ANY_TABLE)); OZ (priv_list.push_back(PRIV_ID_INSERT_ANY_TABLE));
OZ (priv_list.push_back(PRIV_ID_UPDATE_ANY_TABLE)); OZ (priv_list.push_back(PRIV_ID_UPDATE_ANY_TABLE));
OZ (priv_list.push_back(PRIV_ID_DELETE_ANY_TABLE)); OZ (priv_list.push_back(PRIV_ID_DELETE_ANY_TABLE));
OZ (priv_list.push_back(PRIV_ID_CREATE_ANY_TABLE));
OZ (priv_list.push_back(PRIV_ID_DROP_ANY_TABLE));
OZ (priv_list.push_back(PRIV_ID_ALTER_ANY_TABLE));
OZ (priv_list.push_back(PRIV_ID_LOCK_ANY_TABLE));
OZ (priv_list.push_back(PRIV_ID_COMMENT_ANY_TABLE));
OZ (priv_list.push_back(PRIV_ID_FLASHBACK_ANY_TABLE));
} else { } else {
OZ (priv_list.push_back(PRIV_ID_SELECT_ANY_DICTIONARY)); OZ (priv_list.push_back(PRIV_ID_SELECT_ANY_DICTIONARY));
} }
@ -1733,7 +1782,12 @@ int ObOraSysChecker::check_ora_obj_priv_for_create_view(
OZ (obj_p_list.push_back(OBJ_PRIV_ID_INSERT)); OZ (obj_p_list.push_back(OBJ_PRIV_ID_INSERT));
OZ (obj_p_list.push_back(OBJ_PRIV_ID_UPDATE)); OZ (obj_p_list.push_back(OBJ_PRIV_ID_UPDATE));
OZ (obj_p_list.push_back(OBJ_PRIV_ID_DELETE)); OZ (obj_p_list.push_back(OBJ_PRIV_ID_DELETE));
OZ (obj_p_list.push_back(OBJ_PRIV_ID_CREATE));
OZ (obj_p_list.push_back(OBJ_PRIV_ID_ALTER));
OZ (obj_p_list.push_back(OBJ_PRIV_ID_DEBUG));
OZ (obj_p_list.push_back(OBJ_PRIV_ID_INDEX));
OZ (obj_p_list.push_back(OBJ_PRIV_ID_READ));
OZ (obj_p_list.push_back(OBJ_PRIV_ID_REFERENCES));
OZ (check_obj_plist_or_in_single(guard, tenant_id, user_id, obj_type, OZ (check_obj_plist_or_in_single(guard, tenant_id, user_id, obj_type,
obj_id, col_id, obj_p_list), obj_id, col_id, obj_p_list),
tenant_id, user_id, obj_type, obj_id, col_id, obj_p_list); tenant_id, user_id, obj_type, obj_id, col_id, obj_p_list);
@ -2571,7 +2625,7 @@ int ObOraSysChecker::check_ora_ddl_ref_priv(
if (ret == OB_ERR_NO_PRIVILEGE || ret == OB_ERR_EMPTY_QUERY) { if (ret == OB_ERR_NO_PRIVILEGE || ret == OB_ERR_EMPTY_QUERY) {
ret = OB_SUCCESS; ret = OB_SUCCESS;
bool accessible = false; bool accessible = false;
OZ (check_access_to_obj(guard, tenant_id, user_id, obj_type, obj_id, OZ (check_access_to_obj(guard, tenant_id, user_id, obj_type, obj_id, database_name,
role_id_array, accessible)); role_id_array, accessible));
OX (ret = accessible ? OB_ERR_NO_SYS_PRIVILEGE : OB_TABLE_NOT_EXIST); OX (ret = accessible ? OB_ERR_NO_SYS_PRIVILEGE : OB_TABLE_NOT_EXIST);
} }

View File

@ -496,6 +496,7 @@ public:
const share::ObRawPriv p1, const share::ObRawPriv p1,
const uint64_t obj_type, const uint64_t obj_type,
const uint64_t obj_id, const uint64_t obj_id,
const common::ObString &database_name,
const ObIArray<uint64_t> &role_id_array, const ObIArray<uint64_t> &role_id_array,
bool &exists); bool &exists);
@ -505,6 +506,7 @@ public:
const uint64_t user_id, const uint64_t user_id,
const uint64_t obj_type, const uint64_t obj_type,
const uint64_t obj_id, const uint64_t obj_id,
const common::ObString &database_name,
const ObIArray<uint64_t> &role_id_array, const ObIArray<uint64_t> &role_id_array,
bool &accessible); bool &accessible);

View File

@ -1590,6 +1590,7 @@ int ObShowResolver::check_desc_priv_if_ness(
OZ (schema_checker_->check_access_to_obj(real_tenant_id, OZ (schema_checker_->check_access_to_obj(real_tenant_id,
session_info_->get_priv_user_id(), session_info_->get_priv_user_id(),
table_schema->get_table_id(), table_schema->get_table_id(),
database_name,
stmt::T_SHOW_COLUMNS, stmt::T_SHOW_COLUMNS,
session_info_->get_enable_role_array(), session_info_->get_enable_role_array(),
accessible, accessible,

View File

@ -677,17 +677,18 @@ int ObCreateViewResolver::check_privilege_needed(ObCreateTableStmt &stmt,
const TableItem *table_item = select_stmt.get_table_item(i); const TableItem *table_item = select_stmt.get_table_item(i);
CK (OB_NOT_NULL(table_item)); CK (OB_NOT_NULL(table_item));
OZ (schema_checker_->check_access_to_obj(session_info_->get_effective_tenant_id(), OZ (schema_checker_->check_access_to_obj(session_info_->get_effective_tenant_id(),
session_info_->get_priv_user_id(), session_info_->get_priv_user_id(),
table_item->ref_id_, table_item->ref_id_,
stmt::T_CREATE_VIEW, table_item->database_name_,
session_info_->get_enable_role_array(), stmt::T_CREATE_VIEW,
accessible), session_info_->get_enable_role_array(),
accessible),
session_info_->get_effective_tenant_id(), session_info_->get_user_id(), session_info_->get_effective_tenant_id(), session_info_->get_user_id(),
stmt.get_database_name()); stmt.get_database_name());
if (!accessible) { if (OB_SUCC(ret) && !accessible) {
ret = OB_TABLE_NOT_EXIST; ret = OB_TABLE_NOT_EXIST;
LOG_USER_ERROR(OB_TABLE_NOT_EXIST, to_cstring(stmt.get_database_name()), LOG_USER_ERROR(OB_TABLE_NOT_EXIST, to_cstring(table_item->database_name_),
to_cstring(table_item->table_name_)); to_cstring(table_item->table_name_));
} }
} }
if (OB_SUCC(ret)) { if (OB_SUCC(ret)) {

View File

@ -2795,10 +2795,16 @@ int ObSchemaChecker::check_ora_ddl_priv(
} }
/**检查用户user_id是否能access到obj_id,会检查系统权限和对象权限*/ /**检查用户user_id是否能access到obj_id,会检查系统权限和对象权限*/
/*
*系统权限又分了两类:
* 1. 全局有效:create any table, create any view ....
* 2. user’s shema有效:create table,create view,create synonym, create index, ....
*/
int ObSchemaChecker::check_access_to_obj( int ObSchemaChecker::check_access_to_obj(
const uint64_t tenant_id, const uint64_t tenant_id,
const uint64_t user_id, const uint64_t user_id,
const uint64_t obj_id, const uint64_t obj_id,
const ObString &database_name,
const sql::stmt::StmtType stmt_type, const sql::stmt::StmtType stmt_type,
const ObIArray<uint64_t> &role_id_array, const ObIArray<uint64_t> &role_id_array,
bool &accessible, bool &accessible,
@ -2827,6 +2833,7 @@ int ObSchemaChecker::check_access_to_obj(
static_cast<uint64_t> static_cast<uint64_t>
(share::schema::ObObjectType::TABLE), (share::schema::ObObjectType::TABLE),
obj_id, obj_id,
database_name,
role_id_array, role_id_array,
accessible), accessible),
K(tenant_id), K(user_id), K(stmt_type), K(role_id_array)); K(tenant_id), K(user_id), K(stmt_type), K(role_id_array));
@ -2842,6 +2849,7 @@ int ObSchemaChecker::check_access_to_obj(
static_cast<uint64_t> static_cast<uint64_t>
(share::schema::ObObjectType::TABLE), (share::schema::ObObjectType::TABLE),
obj_id, obj_id,
database_name,
role_id_array, role_id_array,
accessible), accessible),
K(tenant_id), K(user_id), K(stmt_type), K(role_id_array)); K(tenant_id), K(user_id), K(stmt_type), K(role_id_array));

View File

@ -451,6 +451,7 @@ public:
int check_access_to_obj(const uint64_t tenant_id, int check_access_to_obj(const uint64_t tenant_id,
const uint64_t user_id, const uint64_t user_id,
const uint64_t obj_id, const uint64_t obj_id,
const common::ObString &database_name,
const sql::stmt::StmtType stmt_type, const sql::stmt::StmtType stmt_type,
const ObIArray<uint64_t> &role_id_array, const ObIArray<uint64_t> &role_id_array,
bool &accessible, bool &accessible,