fix privilege bug: disable normal user using dcl on inner users.

This commit is contained in:
jingtaoye35 2023-04-10 07:50:37 +00:00 committed by ob-robot
parent 23da06c6dd
commit 7fc53bfe13
12 changed files with 201 additions and 16 deletions

View File

@ -1400,3 +1400,6 @@ DEF_STR(_load_tde_encrypt_engine, OB_CLUSTER_PARAMETER, "NONE",
DEF_INT(_pipelined_table_function_memory_limit, OB_TENANT_PARAMETER, "524288000", "[1024,18446744073709551615]",
"pipeline table function result set memory size limit. default 524288000 (500M), Range: [1024,18446744073709551615]",
ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE));
DEF_BOOL(_enable_reserved_user_dcl_restriction, OB_CLUSTER_PARAMETER, "False",
"specifies whether to forbid non-reserved user to modify reserved users",
ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE));

View File

@ -51,8 +51,17 @@ int ObAlterUserPrimaryZoneResolver::resolve(const ParseNode &parse_tree)
LOG_WARN("unexpected null user or null primary zone", K(primary_zone_node), K(user_node), K(ret));
} else {
ObString user_name;
ObString host_name;
user_name.assign_ptr(user_node->children_[0]->str_value_,
static_cast<int32_t>(user_node->children_[0]->str_len_));
host_name.assign_ptr(OB_DEFAULT_HOST_NAME, static_cast<int32_t>(STRLEN(OB_DEFAULT_HOST_NAME)));
if (OB_FAIL(check_dcl_on_inner_user(parse_tree.type_,
params_.session_info_->get_priv_user_id(),
user_name,
host_name))) {
LOG_WARN("failed to check dcl on inner-user or unsupport to modify reserved user", K(ret),
K(params_.session_info_->get_user_name()), K(user_name));
}
OZ(ObDatabaseResolver<ObAlterUserPrimaryZoneStmt>::resolve_primary_zone(
stmt, primary_zone_node));
stmt->set_tenant_id(params_.session_info_->get_effective_tenant_id());

View File

@ -321,16 +321,16 @@ int ObAlterUserProfileResolver::resolve_default_role(const ParseNode &parse_tree
}
OZ (params_.schema_checker_->get_user_info(tenant_id, user_name, host_name, user_info),
tenant_id, user_name, host_name);
if (ret == OB_USER_NOT_EXIST) {
if (ret == OB_USER_NOT_EXIST || OB_ISNULL(user_info)) {
ret = OB_USER_NOT_EXIST;
LOG_USER_ERROR(OB_USER_NOT_EXIST, user_name.length(), user_name.ptr());
}
if (OB_SUCC(ret)) {
if (user_info == NULL) {
ret = OB_USER_NOT_EXIST;
LOG_USER_ERROR(OB_USER_NOT_EXIST, user_name.length(), user_name.ptr());
} else {
arg.user_id_ = user_info->get_user_id();
}
} else if (OB_FAIL(check_dcl_on_inner_user(parse_tree.type_,
session_info_->get_priv_user_id(),
user_info->get_user_id()))) {
LOG_WARN("failed to check dcl on inner-user or unsupport to modify reserved user", K(ret),
K(session_info_->get_user_name()), K(user_name));
} else {
arg.user_id_ = user_info->get_user_id();
}
/* 2. resolve default role */
@ -403,8 +403,14 @@ int ObAlterUserProfileResolver::resolve(const ParseNode &parse_tree)
arg.profile_name_ = ObString(profile_name->str_len_, profile_name->str_value_);
}
arg.tenant_id_ = params_.session_info_->get_effective_tenant_id();
if (OB_FAIL(check_dcl_on_inner_user(parse_tree.type_,
session_info_->get_priv_user_id(),
arg.user_name_,
arg.host_name_))) {
LOG_WARN("failed to check dcl on inner-user or unsupport to modify reserved user", K(ret),
K(params_.session_info_->get_user_name()), K(arg.user_name_));
}
}
if (OB_SUCC(ret) && T_SET_ROLE != parse_tree.type_
&& ObSchemaChecker::is_ora_priv_check()) {
OZ (schema_checker_->check_ora_ddl_priv(

View File

@ -361,3 +361,104 @@ int ObDCLResolver::mask_password_for_passwd_node(ObIAllocator *allocator,
LOG_DEBUG("finish mask_password_for_passwd_node", K(src), K(masked_sql));
return ret;
}
int ObDCLResolver::check_dcl_on_inner_user(const ObItemType &type,
const uint64_t &session_user_id,
const ObString &user_name,
const ObString &host_name) {
int ret = OB_SUCCESS;
uint64_t user_id = OB_INVALID_ID;
bool is_valid = true;
if (GCONF._enable_reserved_user_dcl_restriction) {
if (T_ALTER_USER_DEFAULT_ROLE == type ||
T_ALTER_USER_PRIMARY_ZONE == type ||
T_ALTER_USER_PROFILE == type ||
T_DROP_USER == type ||
T_GRANT == type ||
T_LOCK_USER == type ||
T_RENAME_USER == type ||
T_REVOKE == type ||
T_REVOKE_ALL == type ||
T_REVOKE_ROLE == type ||
T_SET_PASSWORD == type ||
T_SET_ROLE == type ||
T_SYSTEM_REVOKE == type) {
if (user_name.empty() || session_user_id == OB_INVALID_ID) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("failed. get empty user name or invalid session user id", K(ret), K(user_name),
K(session_user_id));
} else if (OB_ISNULL(schema_checker_) || OB_ISNULL(params_.session_info_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("failed. get NULL ptr", K(ret), K(schema_checker_), K(params_.session_info_));
} else if (OB_FAIL(schema_checker_->get_user_id(
params_.session_info_->get_effective_tenant_id(),
user_name,
host_name,
user_id))) {
if (OB_USER_NOT_EXIST == ret) {
ret = OB_ERR_USER_OR_ROLE_DOES_NOT_EXIST;
LOG_USER_ERROR(OB_ERR_USER_OR_ROLE_DOES_NOT_EXIST, user_name.length(), user_name.ptr());
}
LOG_WARN("failed to get user id", K(ret), K(user_name));
}
if (OB_SUCC(ret)) {
if (OB_SYS_USER_ID == user_id ||
OB_ORA_SYS_USER_ID == user_id ||
OB_ORA_AUDITOR_USER_ID == user_id ||
OB_ORA_LBACSYS_USER_ID == user_id) {
if (session_user_id != user_id &&
OB_SYS_USER_ID != session_user_id &&
OB_ORA_SYS_USER_ID != session_user_id) {
is_valid = false;
}
}
}
}
}
if (OB_SUCC(ret) && !is_valid) {
ret = OB_NOT_SUPPORTED;
LOG_USER_ERROR(OB_NOT_SUPPORTED, "modify on reserved user");
}
return ret;
}
int ObDCLResolver::check_dcl_on_inner_user(const ObItemType &type,
const uint64_t &session_user_id,
const uint64_t &user_id) {
int ret = OB_SUCCESS;
bool is_valid = true;
if (GCONF._enable_reserved_user_dcl_restriction) {
if (T_ALTER_USER_DEFAULT_ROLE == type ||
T_ALTER_USER_PRIMARY_ZONE == type ||
T_ALTER_USER_PROFILE == type ||
T_DROP_USER == type ||
T_GRANT == type ||
T_LOCK_USER == type ||
T_RENAME_USER == type ||
T_REVOKE == type ||
T_REVOKE_ALL == type ||
T_REVOKE_ROLE == type ||
T_SET_PASSWORD == type ||
T_SET_ROLE == type ||
T_SYSTEM_REVOKE == type) {
if (OB_INVALID_ID == user_id || OB_INVALID_ID == session_user_id) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("failed.invalid session user id/user id", K(ret), K(user_id), K(session_user_id));
} else if (OB_SYS_USER_ID == user_id ||
OB_ORA_SYS_USER_ID == user_id ||
OB_ORA_AUDITOR_USER_ID == user_id ||
OB_ORA_LBACSYS_USER_ID == user_id) {
if (session_user_id != user_id &&
OB_SYS_USER_ID != session_user_id &&
OB_ORA_SYS_USER_ID != session_user_id) {
is_valid = false;
}
}
}
}
if (OB_SUCC(ret) && !is_valid) {
ret = OB_NOT_SUPPORTED;
LOG_USER_ERROR(OB_NOT_SUPPORTED, "modify on reserved user");
}
return ret;
}

View File

@ -40,6 +40,13 @@ protected:
int64_t profile_id,
common::ObString &password,
common::ObString &user_name);
int check_dcl_on_inner_user(const ObItemType &type,
const uint64_t &session_user_id,
const ObString &user_name,
const ObString &host_name);
int check_dcl_on_inner_user(const ObItemType &type,
const uint64_t &session_user_id,
const uint64_t &user_id);
static int mask_password_for_single_user(ObIAllocator *allocator,
const common::ObString &src,
const ParseNode *user_node,

View File

@ -127,8 +127,12 @@ int ObDropUserResolver::resolve(const ParseNode &parse_tree)
} else if (is_inner_user_or_role(user_info->get_user_id())) {
ret = OB_ERR_NO_PRIVILEGE;
SQL_RESV_LOG(WARN, "Can not drop internal user", K(ret));
} else if (OB_FAIL(check_dcl_on_inner_user(top_node->type_,
params_.session_info_->get_priv_user_id(),
user_info->get_user_id()))) {
LOG_WARN("failed to check dcl on inner-user or unsupport to modify reserved user",
K(ret), K(params_.session_info_->get_user_name()), K(user_name));
}
if (OB_SUCC(ret)) {
if (OB_FAIL(drop_user_stmt->add_user(user_name, host_name))) {
LOG_WARN("Add user error", K(user_name), K(ret));

View File

@ -1072,6 +1072,12 @@ int ObGrantResolver::resolve_grant_obj_privileges(
if (user_name.length() > OB_MAX_USER_NAME_LENGTH) {
ret = OB_WRONG_USER_NAME_LENGTH;
LOG_USER_ERROR(OB_WRONG_USER_NAME_LENGTH, user_name.length(), user_name.ptr());
} else if (OB_FAIL(check_dcl_on_inner_user(node->type_,
session_info_->get_priv_user_id(),
user_name,
host_name))) {
LOG_WARN("failed to check dcl on inner-user or unsupport to modify reserved user",
K(ret), K(session_info_->get_user_name()), K(user_name));
} else if (OB_FAIL(grant_stmt->add_grantee(user_name))) {
LOG_WARN("Add grantee error", K(user_name), K(ret));
} else if (OB_FAIL(grant_stmt->add_user(user_name, host_name, pwd, need_enc))) {
@ -1307,6 +1313,12 @@ int ObGrantResolver::resolve_mysql(const ParseNode &parse_tree)
if (user_name.length() > OB_MAX_USER_NAME_LENGTH) {
ret = OB_WRONG_USER_NAME_LENGTH;
LOG_USER_ERROR(OB_WRONG_USER_NAME_LENGTH, user_name.length(), user_name.ptr());
} else if (OB_FAIL(check_dcl_on_inner_user(node->type_,
session_info_->get_priv_user_id(),
user_name,
host_name))) {
LOG_WARN("failed to check dcl on inner-user or unsupport to modify reserved user",
K(ret), K(session_info_->get_user_name()), K(user_name));
} else if (OB_FAIL(grant_stmt->add_grantee(user_name))) {
LOG_WARN("Add grantee error", K(user_name), K(ret));
} else if (OB_FAIL(grant_stmt->add_user(user_name, host_name, pwd, need_enc))) {

View File

@ -95,10 +95,14 @@ int ObLockUserResolver::resolve(const ParseNode &parse_tree)
host_name.assign_ptr(user_hostname_node->children_[1]->str_value_,
static_cast<int32_t>(user_hostname_node->children_[1]->str_len_));
}
if (OB_FAIL(lock_user_stmt->add_user(user_name, host_name))) {
if (OB_FAIL(check_dcl_on_inner_user(node->type_,
session_info_->get_priv_user_id(),
user_name,
host_name))) {
LOG_WARN("failed to check dcl on inner-user or unsupport to modify reserved user",
K(ret), K(params_.session_info_->get_user_name()), K(user_name));
} else if (OB_FAIL(lock_user_stmt->add_user(user_name, host_name))) {
SQL_RESV_LOG(WARN, "Add user error", K(user_name), K(host_name), K(ret));
} else {
//do nothing
}
}
}

View File

@ -65,7 +65,6 @@ int ObRenameUserResolver::resolve(const ParseNode &parse_tree)
to_host.assign_ptr(rename_info->children_[3]->str_value_,
static_cast<int32_t>(rename_info->children_[3]->str_len_));
}
if ((0 == to_user.case_compare(OB_RESTORE_USER_NAME)) || (0 == from_user.case_compare(OB_RESTORE_USER_NAME))) {
ret = OB_ERR_NO_PRIVILEGE;
LOG_WARN("__oceanbase_inner_restore_user is reserved", K(ret));
@ -73,6 +72,12 @@ int ObRenameUserResolver::resolve(const ParseNode &parse_tree)
LOG_USER_ERROR(OB_WRONG_USER_NAME_LENGTH, from_user.length(), from_user.ptr());
} else if (to_user.length() > OB_MAX_USER_NAME_LENGTH) {
LOG_USER_ERROR(OB_WRONG_USER_NAME_LENGTH, to_user.length(), to_user.ptr());
} else if (OB_FAIL(check_dcl_on_inner_user(node->type_,
session_info_->get_priv_user_id(),
from_user,
from_host))) {
LOG_WARN("failed to check dcl on inner-user or unsupport to modify reserved user",
K(ret), K(session_info_->get_user_name()), K(from_user));
} else if (OB_FAIL(rename_user_stmt->add_rename_info(from_user, from_host, to_user, to_host))) {
LOG_WARN("Failed to add user to ObRenameUserStmt", K(ret));
} else {

View File

@ -107,6 +107,11 @@ int ObRevokeResolver::resolve_revoke_role_inner(
LOG_USER_ERROR(OB_ERR_USER_OR_ROLE_DOES_NOT_EXIST, user_name.length(), user_name.ptr());
}
LOG_WARN("fail to get user id", K(ret), K(user_name), K(host_name));
} else if (OB_FAIL(check_dcl_on_inner_user(revoke_role->type_,
params_.session_info_->get_priv_user_id(),
user_id))) {
LOG_WARN("failed to check dcl on inner-user or unsupport to modify reserved user", K(ret),
K(session_info_->get_priv_user_id()), K(user_name));
}
OZ (revoke_stmt->add_grantee(user_name));
OZ (params_.schema_checker_->get_user_info(tenant_id, user_id, user_info), user_id);
@ -193,6 +198,11 @@ int ObRevokeResolver::resolve_revoke_sysprivs_inner(
LOG_USER_ERROR(OB_ERR_USER_OR_ROLE_DOES_NOT_EXIST, user_name.length(), user_name.ptr());
}
LOG_WARN("fail to get user id", K(ret), K(user_name), K(host_name));
} else if (OB_FAIL(check_dcl_on_inner_user(revoke_role->type_,
params_.session_info_->get_priv_user_id(),
user_id))) {
LOG_WARN("failed to check dcl on inner-user or unsupport to modify reserved user", K(ret),
K(session_info_->get_priv_user_id()), K(user_name));
}
OZ (params_.schema_checker_->get_user_info(
revoke_stmt->get_tenant_id(), user_id, user_info), user_id);
@ -363,6 +373,11 @@ int ObRevokeResolver::resolve_mysql(const ParseNode &parse_tree)
ret = OB_NOT_SUPPORTED;
LOG_WARN("Revoke privilege from root at global level is not supported", K(ret));
LOG_USER_ERROR(OB_NOT_SUPPORTED, "Revoke privilege from root at global level");
} else if (OB_FAIL(check_dcl_on_inner_user(node->type_,
params_.session_info_->get_priv_user_id(),
user_id))) {
LOG_WARN("failed to check dcl on inner-user or unsupport to modify reserved user",
K(ret), K(session_info_->get_priv_user_id()), K(user_name));
} else if (OB_FAIL(revoke_stmt->add_user(user_id))) {
LOG_WARN("Add user to grant_stmt error", K(ret), K(user_id));
} else {
@ -608,6 +623,11 @@ int ObRevokeResolver::resolve_revoke_role_and_sysprivs_inner(const ParseNode *no
LOG_USER_ERROR(OB_ERR_USER_OR_ROLE_DOES_NOT_EXIST, user_name.length(), user_name.ptr());
}
LOG_WARN("fail to get user id", K(ret), K(user_name), K(host_name));
} else if (OB_FAIL(check_dcl_on_inner_user(node->type_,
params_.session_info_->get_priv_user_id(),
user_id))) {
LOG_WARN("failed to check dcl on inner-user or unsupport to modify reserved user", K(ret),
K(session_info_->get_priv_user_id()), K(user_id));
}
OZ (revoke_stmt->add_grantee(user_name));
OZ (params_.schema_checker_->get_user_info(tenant_id, user_id, user_info), user_id);
@ -784,6 +804,11 @@ int ObRevokeResolver::resolve_revoke_obj_priv_inner(const ParseNode *node,
ret = OB_NOT_SUPPORTED;
LOG_WARN("Revoke privilege from root at global level is not supported", K(ret));
LOG_USER_ERROR(OB_NOT_SUPPORTED, "Revoke privilege from root at global level");
} else if (OB_FAIL(check_dcl_on_inner_user(node->type_,
params_.session_info_->get_priv_user_id(),
user_id))) {
LOG_WARN("failed to check dcl on inner-user or unsupport to modify reserved user",
K(ret), K(params_.session_info_->get_priv_user_id()), K(user_id));
} else if (OB_FAIL(revoke_stmt->add_user(user_id))) {
LOG_WARN("Add user to grant_stmt error", K(ret), K(user_id));
} else {

View File

@ -108,7 +108,15 @@ int ObSetPasswordResolver::resolve(const ParseNode &parse_tree)
host_name = session_host_name;
set_pwd_stmt->set_for_current_user(true);
}
if (OB_SUCC(ret)) {
if (OB_FAIL(check_dcl_on_inner_user(node->type_,
params_.session_info_->get_priv_user_id(),
user_name,
host_name))) {
LOG_WARN("failed to check dcl on inner-user or unsupport to modify reserved user", K(ret),
K(params_.session_info_->get_priv_user_id()), K(user_name));
}
}
if (OB_SUCC(ret)) {
// replace password to *** in query_string for audit
ObString masked_sql;

View File

@ -262,6 +262,7 @@ _enable_protocol_diagnose
_enable_px_batch_rescan
_enable_px_bloom_filter_sync
_enable_px_ordered_coord
_enable_reserved_user_dcl_restriction
_enable_resource_limit_spec
_enable_tenant_sql_net_thread
_enable_trace_session_leak