fix some privilege and expr bugs

This commit is contained in:
yinyj17
2023-08-02 10:24:12 +00:00
committed by ob-robot
parent aefb0e9afc
commit bb7ce82bd2
6 changed files with 131 additions and 76 deletions

View File

@ -217,14 +217,24 @@ int ObExprConcat::calc_result_typeN(ObExprResType &type,
} }
OZ (aggregate_string_type_and_charset_oracle(*type_ctx.get_session(), params, type)); OZ (aggregate_string_type_and_charset_oracle(*type_ctx.get_session(), params, type));
OZ (deduce_string_param_calc_type_and_charset(*type_ctx.get_session(), type, params)); OZ (deduce_string_param_calc_type_and_charset(*type_ctx.get_session(), type, params));
} else {
bool has_text = false;
for (int64_t i = 0; !has_text && i < param_num; ++i) {
if (ObTinyTextType != types[i].get_type() && types[i].is_text()) {
has_text = true;
}
}
if (has_text) {
type.set_type(ObLongTextType);
} else { } else {
type.set_varchar(); type.set_varchar();
}
OZ (aggregate_charsets_for_string_result(type, OZ (aggregate_charsets_for_string_result(type,
types, types,
param_num, param_num,
type_ctx.get_coll_type())); type_ctx.get_coll_type()));
for (int64_t i = 0; i < param_num; ++i) { for (int64_t i = 0; i < param_num; ++i) {
types[i].set_calc_type(ObVarcharType); types[i].set_calc_type(type.get_type());
types[i].set_calc_collation_type(type.get_collation_type()); types[i].set_calc_collation_type(type.get_collation_type());
} }
} }

View File

@ -433,20 +433,7 @@ int ObShowResolver::resolve(const ParseNode &parse_tree)
show_db_id, show_db_id,
show_db_name))) { show_db_name))) {
LOG_WARN("fail to resolve show database", K(ret), K(real_tenant_id)); LOG_WARN("fail to resolve show database", K(ret), K(real_tenant_id));
} else if (OB_FAIL(stmt_need_privs.need_privs_.init(2))) { } else if (OB_FAIL(schema_checker_->check_db_access(session_priv, show_db_name))) {
LOG_WARN("fail to init need privs array", K(ret));
} else {
ObNeedPriv need_priv;
need_priv.priv_level_ = OB_PRIV_USER_LEVEL;
need_priv.priv_set_ = OB_PRIV_DB_ACC;
stmt_need_privs.need_privs_.push_back(need_priv);
need_priv.priv_level_ = OB_PRIV_DB_LEVEL;
need_priv.priv_set_ = OB_PRIV_DB_ACC;
need_priv.db_ = show_db_name;
stmt_need_privs.need_privs_.push_back(need_priv);
if (OB_FAIL(schema_checker_->check_priv_or(session_priv, stmt_need_privs))) {
if (OB_ERR_NO_DB_PRIVILEGE == ret) { if (OB_ERR_NO_DB_PRIVILEGE == ret) {
LOG_USER_ERROR(OB_ERR_NO_DB_PRIVILEGE, session_priv.user_name_.length(), session_priv.user_name_.ptr(), LOG_USER_ERROR(OB_ERR_NO_DB_PRIVILEGE, session_priv.user_name_.length(), session_priv.user_name_.ptr(),
session_priv.host_name_.length(),session_priv.host_name_.ptr(), session_priv.host_name_.length(),session_priv.host_name_.ptr(),
@ -454,8 +441,7 @@ int ObShowResolver::resolve(const ParseNode &parse_tree)
} else { } else {
LOG_WARN("fail to check priv", K(ret)); LOG_WARN("fail to check priv", K(ret));
} }
} else { } else if (NULL != parse_tree.children_[0]) {
if (NULL != parse_tree.children_[0]) {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_CREATE_DATABASE_EXISTS); GEN_SQL_STEP_1(ObShowSqlSet::SHOW_CREATE_DATABASE_EXISTS);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_CREATE_DATABASE_EXISTS, OB_SYS_DATABASE_NAME, OB_TENANT_VIRTUAL_SHOW_CREATE_DATABASE_TNAME, show_db_id); GEN_SQL_STEP_2(ObShowSqlSet::SHOW_CREATE_DATABASE_EXISTS, OB_SYS_DATABASE_NAME, OB_TENANT_VIRTUAL_SHOW_CREATE_DATABASE_TNAME, show_db_id);
} else { } else {
@ -463,8 +449,6 @@ int ObShowResolver::resolve(const ParseNode &parse_tree)
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_CREATE_DATABASE, OB_SYS_DATABASE_NAME, OB_TENANT_VIRTUAL_SHOW_CREATE_DATABASE_TNAME, show_db_id); GEN_SQL_STEP_2(ObShowSqlSet::SHOW_CREATE_DATABASE, OB_SYS_DATABASE_NAME, OB_TENANT_VIRTUAL_SHOW_CREATE_DATABASE_TNAME, show_db_id);
} }
} }
}
}
}(); }();
break; break;
} }

View File

@ -813,29 +813,78 @@ int ObGrantResolver::resolve_col_names(
1. username dup 1. username dup
2. grant role can not with grant option 2. grant role can not with grant option
3. grant role can not reference, index priv */ 3. grant role can not reference, index priv */
int ObGrantResolver::check_user_dup_and_role_grant_option( int ObGrantResolver::check_user_dup(
ObSchemaGetterGuard *guard, ObSchemaGetterGuard *guard,
ObIArray<ObString> &user_name_array, ObIArray<ObString> &user_name_array,
const ObGrantStmt *grant_stmt, const ObGrantStmt *grant_stmt,
const ObString& user_name, const ObString& user_name,
const ObString& host_name, const ObString& host_name,
const ObString& priv_user_name) const ObString& priv_user_name,
bool &contain_role,
bool &is_all_role)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
CK (grant_stmt != NULL); CK (grant_stmt != NULL);
if (ObSchemaChecker::is_ora_priv_check()) { if (ObSchemaChecker::is_ora_priv_check()) {
/* 1. check user dup */ /* 1. check user dup */
if (has_exist_in_array(user_name_array, user_name)) { const ObUserInfo *user_info = NULL;
uint64_t tenant_id = OB_INVALID_ID;
if (OB_ISNULL(params_.session_info_) || OB_ISNULL(guard)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected null", K(ret));
} else if (has_exist_in_array(user_name_array, user_name)) {
ret = OB_ERR_DUPLICATE_USERNAME_IN_LIST; ret = OB_ERR_DUPLICATE_USERNAME_IN_LIST;
LOG_WARN("user name dup", K(user_name), K(ret)); LOG_WARN("user name dup", K(user_name), K(ret));
} else if (grant_stmt->get_database_name() != user_name } else if (grant_stmt->get_database_name() != user_name
&& user_name == priv_user_name) { && user_name == priv_user_name) {
ret = OB_ERR_YOU_MAY_NOT_REVOKE_PRIVILEGES_FROM_YOURSELF; ret = OB_ERR_YOU_MAY_NOT_REVOKE_PRIVILEGES_FROM_YOURSELF;
LOG_WARN("grant to self", K(user_name), K(ret)); LOG_WARN("grant to self", K(user_name), K(ret));
} else if (OB_FAIL(user_name_array.push_back(user_name))) {
LOG_WARN("failed to push back user name", K(ret), K(user_name));
} else if (FALSE_IT(tenant_id = params_.session_info_->get_effective_tenant_id())) {
// do nothing
} else if (OB_FAIL(guard->get_user_info(tenant_id, user_name, host_name, user_info))) {
LOG_WARN("failed to get user info", K(ret), K(tenant_id), K(user_name), K(host_name));
} else if (OB_ISNULL(user_info)) {
ret = OB_USER_NOT_EXIST;
LOG_WARN("user is not exist", K(ret), K(tenant_id), K(user_name), K(host_name));
} else { } else {
OZ (user_name_array.push_back(user_name)); contain_role |= user_info->is_role();
is_all_role &= user_info->is_role();
} }
}
return ret;
}
int ObGrantResolver::rebuild_table_priv(
ObGrantStmt *grant_stmt,
bool is_owner,
const bool is_all_role)
{
int ret = OB_SUCCESS;
if (OB_ISNULL(grant_stmt)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected null stmt", K(ret));
} else if (grant_stmt->is_grant_all_tab_priv()) {
share::ObRawObjPrivArray table_priv_array;
OZ (build_table_priv_arary_for_all(grant_stmt,
table_priv_array,
is_owner,
is_all_role));
OZ (grant_stmt->set_obj_priv_array(table_priv_array));
}
return ret;
}
int ObGrantResolver::check_role_grant_option(
const ObGrantStmt *grant_stmt,
const bool contain_role) {
int ret = OB_SUCCESS;
if (OB_ISNULL(grant_stmt)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected null stmt", K(ret));
} else if (ObSchemaChecker::is_ora_priv_check() && contain_role) {
bool has_ref_priv = false; bool has_ref_priv = false;
bool has_index_priv = false; bool has_index_priv = false;
if (has_exist_in_array(grant_stmt->get_obj_priv_array(), if (has_exist_in_array(grant_stmt->get_obj_priv_array(),
@ -851,30 +900,17 @@ int ObGrantResolver::check_user_dup_and_role_grant_option(
2. 不能grant reference,其次优先 2. 不能grant reference,其次优先
3. 不能grant index */ 3. 不能grant index */
if (grant_stmt->get_option() == GRANT_OPTION || has_ref_priv || has_index_priv) { if (grant_stmt->get_option() == GRANT_OPTION || has_ref_priv || has_index_priv) {
const ObUserInfo *user_info = NULL;
CK (params_.session_info_ != NULL);
uint64_t tenant_id = params_.session_info_->get_effective_tenant_id();
CK (guard != NULL);
OZ (guard->get_user_info(tenant_id, user_name, host_name, user_info));
if (OB_SUCC(ret)) {
if (NULL == user_info) {
ret = OB_USER_NOT_EXIST;
} else if (user_info->is_role()) {
if (grant_stmt->get_option() == GRANT_OPTION) { if (grant_stmt->get_option() == GRANT_OPTION) {
ret = OB_ERR_CANNOT_GRANT_TO_A_ROLE_WITH_GRANT_OPTION; ret = OB_ERR_CANNOT_GRANT_TO_A_ROLE_WITH_GRANT_OPTION;
} else if (has_ref_priv) { } else if (has_ref_priv) {
ObString str = "REFERENCES"; ObString str = "REFERENCES";
ret = OB_ERR_CANNOT_GRANT_STRING_TO_A_ROLE; ret = OB_ERR_CANNOT_GRANT_STRING_TO_A_ROLE;
LOG_USER_ERROR(OB_ERR_CANNOT_GRANT_STRING_TO_A_ROLE, LOG_USER_ERROR(OB_ERR_CANNOT_GRANT_STRING_TO_A_ROLE, str.length(), str.ptr());
str.length(), str.ptr());
} else { } else {
CK (has_index_priv); CK (has_index_priv);
ObString str = "INDEX"; ObString str = "INDEX";
ret = OB_ERR_CANNOT_GRANT_STRING_TO_A_ROLE; ret = OB_ERR_CANNOT_GRANT_STRING_TO_A_ROLE;
LOG_USER_ERROR(OB_ERR_CANNOT_GRANT_STRING_TO_A_ROLE, LOG_USER_ERROR(OB_ERR_CANNOT_GRANT_STRING_TO_A_ROLE, str.length(), str.ptr());
str.length(), str.ptr());
}
}
} }
} }
} }
@ -999,6 +1035,8 @@ int ObGrantResolver::resolve_grant_obj_privileges(
if (OB_SUCC(ret)) { if (OB_SUCC(ret)) {
// oracle 模式下 grant 时,如果用户不存在,不允许创建该用户;fix #17900015 // oracle 模式下 grant 时,如果用户不存在,不允许创建该用户;fix #17900015
bool need_create_user = false; bool need_create_user = false;
bool contain_role = false;
bool is_all_role = true;
CHECK_COMPATIBILITY_MODE(session_info_); CHECK_COMPATIBILITY_MODE(session_info_);
if (!lib::is_oracle_mode()) { if (!lib::is_oracle_mode()) {
need_create_user = (0 == (params_.session_info_->get_sql_mode() need_create_user = (0 == (params_.session_info_->get_sql_mode()
@ -1086,13 +1124,17 @@ int ObGrantResolver::resolve_grant_obj_privileges(
//do nothing //do nothing
} }
} }
OZ (check_user_dup_and_role_grant_option(params_.schema_checker_->get_schema_guard(), OZ (check_user_dup(params_.schema_checker_->get_schema_guard(),
user_name_array, user_name_array,
grant_stmt, grant_stmt,
user_name, user_name,
host_name, host_name,
priv_user_name)); priv_user_name,
contain_role,
is_all_role));
} }
OZ (rebuild_table_priv(grant_stmt, is_owner, is_all_role));
OZ (check_role_grant_option(grant_stmt, contain_role));
} }
}//end of resolve users }//end of resolve users
@ -1736,7 +1778,8 @@ bool ObGrantResolver::is_ora_obj_priv_type(
int ObGrantResolver::build_table_priv_arary_for_all( int ObGrantResolver::build_table_priv_arary_for_all(
ObGrantStmt *grant_stmt, ObGrantStmt *grant_stmt,
share::ObRawObjPrivArray &table_priv_array, share::ObRawObjPrivArray &table_priv_array,
bool is_owner) bool is_owner,
bool is_role)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
CK (grant_stmt != NULL); CK (grant_stmt != NULL);
@ -1773,12 +1816,14 @@ int ObGrantResolver::build_table_priv_arary_for_all(
{ {
OZ (table_priv_array.push_back(OBJ_PRIV_ID_ALTER)); OZ (table_priv_array.push_back(OBJ_PRIV_ID_ALTER));
OZ (table_priv_array.push_back(OBJ_PRIV_ID_DELETE)); OZ (table_priv_array.push_back(OBJ_PRIV_ID_DELETE));
OZ (table_priv_array.push_back(OBJ_PRIV_ID_INDEX));
OZ (table_priv_array.push_back(OBJ_PRIV_ID_INSERT)); OZ (table_priv_array.push_back(OBJ_PRIV_ID_INSERT));
OZ (table_priv_array.push_back(OBJ_PRIV_ID_REFERENCES));
OZ (table_priv_array.push_back(OBJ_PRIV_ID_SELECT)); OZ (table_priv_array.push_back(OBJ_PRIV_ID_SELECT));
OZ (table_priv_array.push_back(OBJ_PRIV_ID_UPDATE)); OZ (table_priv_array.push_back(OBJ_PRIV_ID_UPDATE));
OZ (table_priv_array.push_back(OBJ_PRIV_ID_FLASHBACK)); OZ (table_priv_array.push_back(OBJ_PRIV_ID_FLASHBACK));
if (OB_SUCC(ret) && !is_role) {
OZ (table_priv_array.push_back(OBJ_PRIV_ID_INDEX));
OZ (table_priv_array.push_back(OBJ_PRIV_ID_REFERENCES));
}
break; break;
} }
case share::schema::ObObjectType::SEQUENCE: case share::schema::ObObjectType::SEQUENCE:
@ -1803,9 +1848,11 @@ int ObGrantResolver::build_table_priv_arary_for_all(
{ {
OZ (table_priv_array.push_back(OBJ_PRIV_ID_DELETE)); OZ (table_priv_array.push_back(OBJ_PRIV_ID_DELETE));
OZ (table_priv_array.push_back(OBJ_PRIV_ID_INSERT)); OZ (table_priv_array.push_back(OBJ_PRIV_ID_INSERT));
OZ (table_priv_array.push_back(OBJ_PRIV_ID_REFERENCES));
OZ (table_priv_array.push_back(OBJ_PRIV_ID_SELECT)); OZ (table_priv_array.push_back(OBJ_PRIV_ID_SELECT));
OZ (table_priv_array.push_back(OBJ_PRIV_ID_UPDATE)); OZ (table_priv_array.push_back(OBJ_PRIV_ID_UPDATE));
if (OB_SUCC(ret) && !is_role) {
OZ (table_priv_array.push_back(OBJ_PRIV_ID_REFERENCES));
}
break; break;
} }
case share::schema::ObObjectType::DIRECTORY: case share::schema::ObObjectType::DIRECTORY:
@ -1913,9 +1960,7 @@ int ObGrantResolver::resolve_obj_priv_list_ora(
} else if (OB_PRIV_TABLE_LEVEL == grant_level) { } else if (OB_PRIV_TABLE_LEVEL == grant_level) {
if (OB_PRIV_ALL == priv_type) { if (OB_PRIV_ALL == priv_type) {
priv_set |= OB_PRIV_TABLE_ACC; priv_set |= OB_PRIV_TABLE_ACC;
OZ (build_table_priv_arary_for_all(grant_stmt, grant_stmt->set_grant_all_tab_priv(true);
table_priv_array,
is_owner));
} else if (priv_type & (~(OB_PRIV_TABLE_ACC | OB_PRIV_GRANT)) && } else if (priv_type & (~(OB_PRIV_TABLE_ACC | OB_PRIV_GRANT)) &&
is_ora_obj_priv_type(priv_type) == false) { is_ora_obj_priv_type(priv_type) == false) {
ret = OB_ERR_MISSING_OR_INVALID_PRIVIEGE; ret = OB_ERR_MISSING_OR_INVALID_PRIVIEGE;

View File

@ -102,13 +102,23 @@ public:
share::schema::ObPrivLevel &grant_level, share::schema::ObPrivLevel &grant_level,
bool &is_directory, bool &is_directory,
bool &explicit_db); bool &explicit_db);
int check_user_dup_and_role_grant_option( int check_user_dup(
share::schema::ObSchemaGetterGuard *guard, share::schema::ObSchemaGetterGuard *guard,
ObIArray<ObString> &user_name_array, ObIArray<ObString> &user_name_array,
const ObGrantStmt *grant_stmt, const ObGrantStmt *grant_stmt,
const ObString& user_name, const ObString& user_name,
const ObString& host_name, const ObString& host_name,
const ObString& priv_user_name); const ObString& priv_user_name,
bool &contain_role,
bool &is_all_role);
int rebuild_table_priv(
ObGrantStmt *grant_stmt,
bool is_owner,
const bool is_all_role);
int check_role_grant_option(
const ObGrantStmt *grant_stmt,
const bool contain_role);
static int resolve_role_sys_obj_all_col_priv_list(const ParseNode *role_sys_list, static int resolve_role_sys_obj_all_col_priv_list(const ParseNode *role_sys_list,
ObIArray<ObString> &role_name_array, ObIArray<ObString> &role_name_array,
share::ObRawPrivArray &sys_priv_array); share::ObRawPrivArray &sys_priv_array);
@ -117,7 +127,8 @@ private:
int build_table_priv_arary_for_all( int build_table_priv_arary_for_all(
ObGrantStmt *grant_stmt, ObGrantStmt *grant_stmt,
share::ObRawObjPrivArray &table_priv_array, share::ObRawObjPrivArray &table_priv_array,
bool is_owner); bool is_owner,
bool is_role);
int check_obj_priv_valid( int check_obj_priv_valid(
ObGrantStmt *grant_stmt, ObGrantStmt *grant_stmt,
share::ObRawObjPriv ora_obj_priv); share::ObRawObjPriv ora_obj_priv);

View File

@ -43,7 +43,8 @@ ObGrantStmt::ObGrantStmt(ObIAllocator *name_pool)
ins_col_ids_(), ins_col_ids_(),
upd_col_ids_(), upd_col_ids_(),
ref_col_ids_(), ref_col_ids_(),
ref_query_(NULL) ref_query_(NULL),
is_grant_all_tab_priv_(false)
{ {
} }
@ -68,7 +69,8 @@ ObGrantStmt::ObGrantStmt()
ins_col_ids_(), ins_col_ids_(),
upd_col_ids_(), upd_col_ids_(),
ref_col_ids_(), ref_col_ids_(),
ref_query_(NULL) ref_query_(NULL),
is_grant_all_tab_priv_(false)
{ {
} }

View File

@ -68,6 +68,7 @@ public:
int set_ref_col_ids(ObSEArray<uint64_t, 4> &col_ids) { return ref_col_ids_.assign(col_ids); } int set_ref_col_ids(ObSEArray<uint64_t, 4> &col_ids) { return ref_col_ids_.assign(col_ids); }
void set_ref_query(ObSelectStmt* ref_query) { ref_query_ = ref_query; } void set_ref_query(ObSelectStmt* ref_query) { ref_query_ = ref_query; }
int add_grantee(const common::ObString &grantee); int add_grantee(const common::ObString &grantee);
void set_grant_all_tab_priv(bool is_grant_all) { is_grant_all_tab_priv_ = is_grant_all; }
const share::ObRawPrivArray& get_priv_array() const {return sys_priv_array_;} const share::ObRawPrivArray& get_priv_array() const {return sys_priv_array_;}
const share::ObRawObjPrivArray& get_obj_priv_array() const {return obj_priv_array_;} const share::ObRawObjPrivArray& get_obj_priv_array() const {return obj_priv_array_;}
@ -78,6 +79,7 @@ public:
ObPrivSet get_priv_set() const { return priv_set_; } ObPrivSet get_priv_set() const { return priv_set_; }
uint64_t get_tenant_id() const { return tenant_id_; } uint64_t get_tenant_id() const { return tenant_id_; }
const common::ObStrings& get_grantees() const { return grantees_; } const common::ObStrings& get_grantees() const { return grantees_; }
bool is_grant_all_tab_priv() const { return is_grant_all_tab_priv_; }
virtual bool cause_implicit_commit() const { return true; } virtual bool cause_implicit_commit() const { return true; }
virtual obrpc::ObDDLArg &get_ddl_arg() { return grant_arg_; } virtual obrpc::ObDDLArg &get_ddl_arg() { return grant_arg_; }
@ -107,6 +109,7 @@ private:
ObSEArray<uint64_t, 4> upd_col_ids_; ObSEArray<uint64_t, 4> upd_col_ids_;
ObSEArray<uint64_t, 4> ref_col_ids_; ObSEArray<uint64_t, 4> ref_col_ids_;
ObSelectStmt *ref_query_; // 用于grant 视图时,对视图依赖的table,view等做递归权限check. ObSelectStmt *ref_query_; // 用于grant 视图时,对视图依赖的table,view等做递归权限check.
bool is_grant_all_tab_priv_;
private: private:
DISALLOW_COPY_AND_ASSIGN(ObGrantStmt); DISALLOW_COPY_AND_ASSIGN(ObGrantStmt);