fix some privilege and expr bugs
This commit is contained in:
@ -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 (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 {
|
||||
type.set_varchar();
|
||||
}
|
||||
OZ (aggregate_charsets_for_string_result(type,
|
||||
types,
|
||||
param_num,
|
||||
type_ctx.get_coll_type()));
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
@ -433,20 +433,7 @@ int ObShowResolver::resolve(const ParseNode &parse_tree)
|
||||
show_db_id,
|
||||
show_db_name))) {
|
||||
LOG_WARN("fail to resolve show database", K(ret), K(real_tenant_id));
|
||||
} else if (OB_FAIL(stmt_need_privs.need_privs_.init(2))) {
|
||||
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))) {
|
||||
} else if (OB_FAIL(schema_checker_->check_db_access(session_priv, show_db_name))) {
|
||||
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(),
|
||||
session_priv.host_name_.length(),session_priv.host_name_.ptr(),
|
||||
@ -454,8 +441,7 @@ int ObShowResolver::resolve(const ParseNode &parse_tree)
|
||||
} else {
|
||||
LOG_WARN("fail to check priv", K(ret));
|
||||
}
|
||||
} else {
|
||||
if (NULL != parse_tree.children_[0]) {
|
||||
} else if (NULL != parse_tree.children_[0]) {
|
||||
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);
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -813,29 +813,78 @@ int ObGrantResolver::resolve_col_names(
|
||||
1. username dup
|
||||
2. grant role can not with grant option
|
||||
3. grant role can not reference, index priv */
|
||||
int ObGrantResolver::check_user_dup_and_role_grant_option(
|
||||
int ObGrantResolver::check_user_dup(
|
||||
ObSchemaGetterGuard *guard,
|
||||
ObIArray<ObString> &user_name_array,
|
||||
const ObGrantStmt *grant_stmt,
|
||||
const ObString& user_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;
|
||||
CK (grant_stmt != NULL);
|
||||
|
||||
if (ObSchemaChecker::is_ora_priv_check()) {
|
||||
/* 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;
|
||||
LOG_WARN("user name dup", K(user_name), K(ret));
|
||||
} else if (grant_stmt->get_database_name() != user_name
|
||||
&& user_name == priv_user_name) {
|
||||
ret = OB_ERR_YOU_MAY_NOT_REVOKE_PRIVILEGES_FROM_YOURSELF;
|
||||
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 {
|
||||
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_index_priv = false;
|
||||
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,其次优先
|
||||
3. 不能grant index */
|
||||
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) {
|
||||
ret = OB_ERR_CANNOT_GRANT_TO_A_ROLE_WITH_GRANT_OPTION;
|
||||
} else if (has_ref_priv) {
|
||||
ObString str = "REFERENCES";
|
||||
ret = OB_ERR_CANNOT_GRANT_STRING_TO_A_ROLE;
|
||||
LOG_USER_ERROR(OB_ERR_CANNOT_GRANT_STRING_TO_A_ROLE,
|
||||
str.length(), str.ptr());
|
||||
LOG_USER_ERROR(OB_ERR_CANNOT_GRANT_STRING_TO_A_ROLE, str.length(), str.ptr());
|
||||
} else {
|
||||
CK (has_index_priv);
|
||||
ObString str = "INDEX";
|
||||
ret = OB_ERR_CANNOT_GRANT_STRING_TO_A_ROLE;
|
||||
LOG_USER_ERROR(OB_ERR_CANNOT_GRANT_STRING_TO_A_ROLE,
|
||||
str.length(), str.ptr());
|
||||
}
|
||||
}
|
||||
LOG_USER_ERROR(OB_ERR_CANNOT_GRANT_STRING_TO_A_ROLE, str.length(), str.ptr());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -999,6 +1035,8 @@ int ObGrantResolver::resolve_grant_obj_privileges(
|
||||
if (OB_SUCC(ret)) {
|
||||
// oracle 模式下 grant 时,如果用户不存在,不允许创建该用户;fix #17900015
|
||||
bool need_create_user = false;
|
||||
bool contain_role = false;
|
||||
bool is_all_role = true;
|
||||
CHECK_COMPATIBILITY_MODE(session_info_);
|
||||
if (!lib::is_oracle_mode()) {
|
||||
need_create_user = (0 == (params_.session_info_->get_sql_mode()
|
||||
@ -1086,13 +1124,17 @@ int ObGrantResolver::resolve_grant_obj_privileges(
|
||||
//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,
|
||||
grant_stmt,
|
||||
user_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
|
||||
|
||||
@ -1736,7 +1778,8 @@ bool ObGrantResolver::is_ora_obj_priv_type(
|
||||
int ObGrantResolver::build_table_priv_arary_for_all(
|
||||
ObGrantStmt *grant_stmt,
|
||||
share::ObRawObjPrivArray &table_priv_array,
|
||||
bool is_owner)
|
||||
bool is_owner,
|
||||
bool is_role)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
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_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_REFERENCES));
|
||||
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_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;
|
||||
}
|
||||
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_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_UPDATE));
|
||||
if (OB_SUCC(ret) && !is_role) {
|
||||
OZ (table_priv_array.push_back(OBJ_PRIV_ID_REFERENCES));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case share::schema::ObObjectType::DIRECTORY:
|
||||
@ -1913,9 +1960,7 @@ int ObGrantResolver::resolve_obj_priv_list_ora(
|
||||
} else if (OB_PRIV_TABLE_LEVEL == grant_level) {
|
||||
if (OB_PRIV_ALL == priv_type) {
|
||||
priv_set |= OB_PRIV_TABLE_ACC;
|
||||
OZ (build_table_priv_arary_for_all(grant_stmt,
|
||||
table_priv_array,
|
||||
is_owner));
|
||||
grant_stmt->set_grant_all_tab_priv(true);
|
||||
} else if (priv_type & (~(OB_PRIV_TABLE_ACC | OB_PRIV_GRANT)) &&
|
||||
is_ora_obj_priv_type(priv_type) == false) {
|
||||
ret = OB_ERR_MISSING_OR_INVALID_PRIVIEGE;
|
||||
|
||||
@ -102,13 +102,23 @@ public:
|
||||
share::schema::ObPrivLevel &grant_level,
|
||||
bool &is_directory,
|
||||
bool &explicit_db);
|
||||
int check_user_dup_and_role_grant_option(
|
||||
int check_user_dup(
|
||||
share::schema::ObSchemaGetterGuard *guard,
|
||||
ObIArray<ObString> &user_name_array,
|
||||
const ObGrantStmt *grant_stmt,
|
||||
const ObString& user_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,
|
||||
ObIArray<ObString> &role_name_array,
|
||||
share::ObRawPrivArray &sys_priv_array);
|
||||
@ -117,7 +127,8 @@ private:
|
||||
int build_table_priv_arary_for_all(
|
||||
ObGrantStmt *grant_stmt,
|
||||
share::ObRawObjPrivArray &table_priv_array,
|
||||
bool is_owner);
|
||||
bool is_owner,
|
||||
bool is_role);
|
||||
int check_obj_priv_valid(
|
||||
ObGrantStmt *grant_stmt,
|
||||
share::ObRawObjPriv ora_obj_priv);
|
||||
|
||||
@ -43,7 +43,8 @@ ObGrantStmt::ObGrantStmt(ObIAllocator *name_pool)
|
||||
ins_col_ids_(),
|
||||
upd_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_(),
|
||||
upd_col_ids_(),
|
||||
ref_col_ids_(),
|
||||
ref_query_(NULL)
|
||||
ref_query_(NULL),
|
||||
is_grant_all_tab_priv_(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@ -68,6 +68,7 @@ public:
|
||||
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; }
|
||||
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::ObRawObjPrivArray& get_obj_priv_array() const {return obj_priv_array_;}
|
||||
@ -78,6 +79,7 @@ public:
|
||||
ObPrivSet get_priv_set() const { return priv_set_; }
|
||||
uint64_t get_tenant_id() const { return tenant_id_; }
|
||||
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 obrpc::ObDDLArg &get_ddl_arg() { return grant_arg_; }
|
||||
@ -107,6 +109,7 @@ private:
|
||||
ObSEArray<uint64_t, 4> upd_col_ids_;
|
||||
ObSEArray<uint64_t, 4> ref_col_ids_;
|
||||
ObSelectStmt *ref_query_; // 用于grant 视图时,对视图依赖的table,view等做递归权限check.
|
||||
bool is_grant_all_tab_priv_;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObGrantStmt);
|
||||
|
||||
Reference in New Issue
Block a user