diff --git a/src/bin/gs_guc/cluster_guc.conf b/src/bin/gs_guc/cluster_guc.conf index 678d3925066daf434692d67828332efbfb773f9d..058b2ffa08a9164183b3099e9b8a8be35d0b8fe5 100755 --- a/src/bin/gs_guc/cluster_guc.conf +++ b/src/bin/gs_guc/cluster_guc.conf @@ -177,6 +177,7 @@ enable_analyze_check|bool|0,0|NULL|NULL| enable_bbox_dump|bool|0,0|NULL|NULL| enable_ffic_log|bool|0,0|NULL|NULL| enable_default_index_deduplication|bool|0,0|NULL|NULL| +enable_nonowner_remote_ddl|bool|0,0|NULL|NULL| enable_bitmapscan|bool|0,0|NULL|NULL| enable_ai_stats|bool|0,0|NULL|NULL| multi_stats_type|enum|bayesnet,mcv,all|NULL|NULL| diff --git a/src/common/backend/catalog/aclchk.cpp b/src/common/backend/catalog/aclchk.cpp index 4d5fe832f988390be51d00e159c17ef7346aaf67..d97ff19b5f0385bd6727dbce9262763cda58431a 100644 --- a/src/common/backend/catalog/aclchk.cpp +++ b/src/common/backend/catalog/aclchk.cpp @@ -273,6 +273,13 @@ static void dumpacl(Acl* acl) } \ } while (0) +/* Check if remote DDL operations are allowed for non-owners */ +#define IS_REMOTE_DDL_BLOCKED(mask, roleid, ownerId) \ + (!u_sess->attr.attr_common.enable_nonowner_remote_ddl && \ + (ACLMODE_FOR_DDL(mask) || (mask) & ACL_CREATE) && \ + !has_privs_of_role(roleid, ownerId) && \ + !IsLoopBackAddr(u_sess->proc_cxt.MyProcPort)) + /* * If is_grant is true, adds the given privileges for the list of * grantees to the existing old_acl. If is_grant is false, the @@ -4991,6 +4998,12 @@ AclMode pg_attribute_aclmask(Oid table_oid, AttrNumber attnum, Oid roleid, AclMo classForm = (Form_pg_class)GETSTRUCT(classTuple); ownerId = classForm->relowner; + if (IS_REMOTE_DDL_BLOCKED(mask, roleid, ownerId)) { + ReleaseSysCache(attTuple); + ReleaseSysCache(classTuple); + return ACL_NO_RIGHTS; + } + Oid namespaceId = classForm->relnamespace; ReleaseSysCache(classTuple); @@ -5223,6 +5236,10 @@ AclMode pg_class_aclmask(Oid table_oid, Oid roleid, AclMode mask, AclMaskHow how * Normal case: get the relation's ACL from pg_class */ ownerId = classForm->relowner; + if (IS_REMOTE_DDL_BLOCKED(mask, roleid, ownerId)) { + ReleaseSysCache(tuple); + return ACL_NO_RIGHTS; + } aclDatum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_relacl, &isNull); if (isNull) { @@ -5303,6 +5320,11 @@ AclMode pg_database_aclmask(Oid db_oid, Oid roleid, AclMode mask, AclMaskHow how errcause("System error."), erraction("Contact engineer to support."))); ownerId = ((Form_pg_database)GETSTRUCT(tuple))->datdba; + + if (IS_REMOTE_DDL_BLOCKED(mask, roleid, ownerId)) { + ReleaseSysCache(tuple); + return ACL_NO_RIGHTS; + } aclDatum = SysCacheGetAttr(DATABASEOID, tuple, Anum_pg_database_datacl, &isNull); if (isNull) { @@ -5355,6 +5377,11 @@ AclMode pg_directory_aclmask(Oid dir_oid, Oid roleid, AclMode mask, AclMaskHow h errcause("System error."), erraction("Contact engineer to support."))); ownerId = ((Form_pg_directory)GETSTRUCT(tuple))->owner; + + if (IS_REMOTE_DDL_BLOCKED(mask, roleid, ownerId)) { + ReleaseSysCache(tuple); + return ACL_NO_RIGHTS; + } aclDatum = SysCacheGetAttr(DIRECTORYOID, tuple, Anum_pg_directory_directory_acl, &isNull); if (isNull) { @@ -5405,6 +5432,12 @@ AclMode pg_proc_aclmask(Oid proc_oid, Oid roleid, AclMode mask, AclMaskHow how, errcause("System error."), erraction("Contact engineer to support."))); ownerId = ((Form_pg_proc)GETSTRUCT(tuple))->proowner; + + if (IS_REMOTE_DDL_BLOCKED(mask, roleid, ownerId)) { + ReleaseSysCache(tuple); + return ACL_NO_RIGHTS; + } + bool ispackage = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_package, &isNull); packageOidDatum = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_packageid, &isNull); /* packageid can be oid of object type */ @@ -5492,6 +5525,11 @@ AclMode pg_package_aclmask(Oid packageOid, Oid roleid, AclMode mask, AclMaskHow } ownerId = ((Form_gs_package)GETSTRUCT(tuple))->pkgowner; + if (IS_REMOTE_DDL_BLOCKED(mask, roleid, ownerId)) { + ReleaseSysCache(tuple); + return ACL_NO_RIGHTS; + } + pkgTuple = SearchSysCache1(PACKAGEOID, ObjectIdGetDatum(packageOid)); if (!HeapTupleIsValid(pkgTuple)) { ReleaseSysCache(pkgTuple); @@ -5554,6 +5592,11 @@ AclMode gs_sec_cmk_aclmask(Oid global_setting_oid, Oid roleid, AclMode mask, Acl ownerId = ((Form_gs_client_global_keys)GETSTRUCT(tuple))->key_owner; + if (IS_REMOTE_DDL_BLOCKED(mask, roleid, ownerId)) { + ReleaseSysCache(tuple); + return ACL_NO_RIGHTS; + } + aclDatum = SysCacheGetAttr(GLOBALSETTINGOID, tuple, Anum_gs_client_global_keys_key_acl, &isNull); if (isNull) { /* No ACL, so build default ACL */ @@ -5606,6 +5649,11 @@ AclMode pg_language_aclmask(Oid lang_oid, Oid roleid, AclMode mask, AclMaskHow h ownerId = ((Form_pg_language)GETSTRUCT(tuple))->lanowner; + if (IS_REMOTE_DDL_BLOCKED(mask, roleid, ownerId)) { + ReleaseSysCache(tuple); + return ACL_NO_RIGHTS; + } + aclDatum = SysCacheGetAttr(LANGOID, tuple, Anum_pg_language_lanacl, &isNull); if (isNull) { /* No ACL, so build default ACL */ @@ -5655,6 +5703,11 @@ AclMode gs_sec_cek_aclmask(Oid column_setting_oid, Oid roleid, AclMode mask, Acl ownerId = ((Form_gs_column_keys) GETSTRUCT(tuple))->key_owner; + if (IS_REMOTE_DDL_BLOCKED(mask, roleid, ownerId)) { + ReleaseSysCache(tuple); + return ACL_NO_RIGHTS; + } + aclDatum = SysCacheGetAttr(COLUMNSETTINGOID, tuple, Anum_gs_column_keys_key_acl, &isNull); if (isNull) { /* No ACL, so build default ACL */ @@ -5724,6 +5777,11 @@ AclMode pg_largeobject_aclmask_snapshot(Oid lobj_oid, Oid roleid, AclMode mask, ownerId = ((Form_pg_largeobject_metadata)GETSTRUCT(tuple))->lomowner; + if (IS_REMOTE_DDL_BLOCKED(mask, roleid, ownerId)) { + ReleaseSysCache(tuple); + return ACL_NO_RIGHTS; + } + aclDatum = heap_getattr(tuple, Anum_pg_largeobject_metadata_lomacl, RelationGetDescr(pg_lo_meta), &isNull); if (isNull) { @@ -5862,6 +5920,11 @@ AclMode pg_namespace_aclmask(Oid nsp_oid, Oid roleid, AclMode mask, AclMaskHow h ownerId = ((Form_pg_namespace)GETSTRUCT(tuple))->nspowner; + if (IS_REMOTE_DDL_BLOCKED(mask, roleid, ownerId)) { + ReleaseSysCache(tuple); + return ACL_NO_RIGHTS; + } + aclDatum = SysCacheGetAttr(NAMESPACEOID, tuple, Anum_pg_namespace_nspacl, &isNull); if (isNull) { /* No ACL, so build default ACL */ @@ -5939,6 +6002,11 @@ AclMode pg_nodegroup_aclmask(Oid group_oid, Oid roleid, AclMode mask, AclMaskHow ownerId = BOOTSTRAP_SUPERUSERID; + if (IS_REMOTE_DDL_BLOCKED(mask, roleid, ownerId)) { + ReleaseSysCache(tuple); + return ACL_NO_RIGHTS; + } + isNull = true; aclDatum = SysCacheGetAttr(PGXCGROUPOID, tuple, Anum_pgxc_group_group_acl, &isNull); @@ -5994,6 +6062,11 @@ AclMode pg_tablespace_aclmask(Oid spc_oid, Oid roleid, AclMode mask, AclMaskHow ownerId = ((Form_pg_tablespace)GETSTRUCT(tuple))->spcowner; + if (IS_REMOTE_DDL_BLOCKED(mask, roleid, ownerId)) { + ReleaseSysCache(tuple); + return ACL_NO_RIGHTS; + } + aclDatum = SysCacheGetAttr(TABLESPACEOID, tuple, Anum_pg_tablespace_spcacl, &isNull); if (isNull) { @@ -6050,6 +6123,11 @@ AclMode pg_foreign_data_wrapper_aclmask(Oid fdw_oid, Oid roleid, AclMode mask, A */ ownerId = fdwForm->fdwowner; + if (IS_REMOTE_DDL_BLOCKED(mask, roleid, ownerId)) { + ReleaseSysCache(tuple); + return ACL_NO_RIGHTS; + } + aclDatum = SysCacheGetAttr(FOREIGNDATAWRAPPEROID, tuple, Anum_pg_foreign_data_wrapper_fdwacl, &isNull); if (isNull) { /* No ACL, so build default ACL */ @@ -6105,6 +6183,11 @@ AclMode pg_foreign_server_aclmask(Oid srv_oid, Oid roleid, AclMode mask, AclMask */ ownerId = srvForm->srvowner; + if (IS_REMOTE_DDL_BLOCKED(mask, roleid, ownerId)) { + ReleaseSysCache(tuple); + return ACL_NO_RIGHTS; + } + aclDatum = SysCacheGetAttr(FOREIGNSERVEROID, tuple, Anum_pg_foreign_server_srvacl, &isNull); if (isNull) { /* No ACL, so build default ACL */ @@ -6161,6 +6244,12 @@ AclMode pg_extension_data_source_aclmask(Oid src_oid, Oid roleid, AclMode mask, /* Normal case: get the data source's ACL from pg_extension_data_source */ ownerId = srcForm->srcowner; + + if (IS_REMOTE_DDL_BLOCKED(mask, roleid, ownerId)) { + ReleaseSysCache(tuple); + return ACL_NO_RIGHTS; + } + aclDatum = SysCacheGetAttr(DATASOURCEOID, tuple, Anum_pg_extension_data_source_srcacl, &isNull); if (isNull) { /* No ACL, so build default ACL */ @@ -6233,6 +6322,12 @@ AclMode pg_type_aclmask(Oid type_oid, Oid roleid, AclMode mask, AclMaskHow how) * Now get the type's owner and ACL from the tuple */ ownerId = typeForm->typowner; + + if (IS_REMOTE_DDL_BLOCKED(mask, roleid, ownerId)) { + ReleaseSysCache(tuple); + return ACL_NO_RIGHTS; + } + aclDatum = SysCacheGetAttr(TYPEOID, tuple, Anum_pg_type_typacl, &isNull); if (isNull) { /* No ACL, so build default ACL */ @@ -6252,7 +6347,7 @@ AclMode pg_type_aclmask(Oid type_oid, Oid roleid, AclMode mask, AclMaskHow how) ReleaseSysCache(tuple); return result; } - bool is_ddl_privileges = ACLMODE_FOR_DDL(mask); + if (is_ddl_privileges) { if ((REMOVE_DDL_FLAG(mask) & ACL_ALTER) && !(result & ACL_ALTER)) { if (HasSpecAnyPriv(roleid, ALTER_ANY_TYPE, false)) { diff --git a/src/common/backend/utils/misc/guc.cpp b/src/common/backend/utils/misc/guc.cpp index 2993f4fa8d8833bdfb688288eec22c065059b3eb..1b4696bf767b6764f2e8b2f94386b519a7eda010 100755 --- a/src/common/backend/utils/misc/guc.cpp +++ b/src/common/backend/utils/misc/guc.cpp @@ -436,6 +436,7 @@ const char* sync_guc_variable_namelist[] = {"work_mem", "default_limit_rows", "sql_beta_feature", "enable_default_index_deduplication", + "enable_nonowner_remote_ddl", #ifndef ENABLE_MULTIPLE_NODES "plsql_show_all_error", "uppercase_attribute_name", @@ -1705,6 +1706,17 @@ static void InitConfigureNamesBool() NULL, NULL, NULL}, + {{"enable_nonowner_remote_ddl", + PGC_SIGHUP, + NODE_ALL, + DEVELOPER_OPTIONS, + gettext_noop("Enables remote DDL by non-owner"), + NULL}, + &u_sess->attr.attr_common.enable_nonowner_remote_ddl, + true, + NULL, + NULL, + NULL}, {{"enable_ffic_log", PGC_POSTMASTER, NODE_ALL, diff --git a/src/include/knl/knl_guc/knl_session_attr_common.h b/src/include/knl/knl_guc/knl_session_attr_common.h index 7ea52b11c445ca31699ae76402ef27bf24ebb185..35fa2f4ff45033243462c890a3a2d00e39069e4a 100644 --- a/src/include/knl/knl_guc/knl_session_attr_common.h +++ b/src/include/knl/knl_guc/knl_session_attr_common.h @@ -257,6 +257,7 @@ typedef struct knl_session_attr_common { bool enable_parallel_populate; #endif bool enable_aggr_coerce_type; + bool enable_nonowner_remote_ddl; } knl_session_attr_common; #endif /* SRC_INCLUDE_KNL_KNL_SESSION_ATTR_COMMON_H_ */ diff --git a/src/test/regress/input/forbid_ddl.source b/src/test/regress/input/forbid_ddl.source new file mode 100644 index 0000000000000000000000000000000000000000..7da513b3c6e877be1c4cb5cfafa6a1711d61af1e --- /dev/null +++ b/src/test/regress/input/forbid_ddl.source @@ -0,0 +1,71 @@ +\! @abs_bindir@/gs_guc set -D @abs_srcdir@/tmp_check/datanode1/ -c "listen_addresses='*'" > /dev/null 2>&1 +\! @abs_bindir@/gs_guc set -D @abs_srcdir@/tmp_check/datanode1/ -c "enable_nonowner_remote_ddl=off" > /dev/null 2>&1 +\! @abs_bindir@/gs_guc set -D @abs_srcdir@/tmp_check/datanode1/ -h "host all all `ip addr show | grep \"inet \" | grep -v 127.0.0.1 | awk '{print $2}' | cut -d \"/\" -f 1`/32 sha256" > /dev/null 2>&1 +\! @abs_bindir@/gs_ctl stop -D @abs_srcdir@/tmp_check/datanode1 > /dev/null 2>&1 +\! @abs_bindir@/gs_ctl start -D @abs_srcdir@/tmp_check/datanode1 > /dev/null 2>&1 +\! sleep 5 +-- forbin nonowner remote ddl +\! @abs_bindir@/gsql -p @portstring@ -d regression -c "create user grantee with password 'Asdf@1234';" +\! @abs_bindir@/gsql -p @portstring@ -d regression -c "grant all privileges on database regression to grantee;" +\! @abs_bindir@/gsql -p @portstring@ -d regression -c "grant all privileges on schema public to grantee;" + +-- database +\! @abs_bindir@/gsql -p @portstring@ -d regression -c "create database db_ddl;" +\! @abs_bindir@/gsql -p @portstring@ -d regression -c "grant all privileges on database db_ddl to grantee;" + +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d db_ddl -U "grantee" -W "Asdf@1234" -c "create schema test;" +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d db_ddl -U "grantee" -W "Asdf@1234" -c "alter database db_ddl reset all"; +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d db_ddl -U "grantee" -W "Asdf@1234" -c "comment on database db_ddl IS 'test'"; +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "drop database db_ddl"; + +-- tablespace +\! @abs_bindir@/gsql -p @portstring@ -d regression -c "create tablespace ts_ddl relative location 'ts_ddl';" +\! @abs_bindir@/gsql -p @portstring@ -d regression -c "grant all privileges on tablespace ts_ddl to grantee;" + +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "alter tablespace ts_ddl resize maxsize unlimited;" +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "create table test(id int) tablespace ts_ddl;" +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "comment on tablespace ts_ddl IS 'test';" +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "drop table test;" +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "drop tablespace ts_ddl;" + +-- namespace +\! @abs_bindir@/gsql -p @portstring@ -d regression -c "create schema ns_ddl;" +\! @abs_bindir@/gsql -p @portstring@ -d regression -c "grant all privileges on schema ns_ddl to grantee;" + +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "alter schema ns_ddl without blockchain;" +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "create table ns_ddl.test(id int);" +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "comment on schema ns_ddl IS 'test';" +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "drop schema ns_ddl cascade;" + +-- class +\! @abs_bindir@/gsql -p @portstring@ -d regression -c "create table tb_ddl(id int);" +\! @abs_bindir@/gsql -p @portstring@ -d regression -c "grant all privileges on table tb_ddl to grantee;" + +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "truncate table tb_ddl;" +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "alter table tb_ddl enable row level security;" +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "comment on table tb_ddl IS 'test';" +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "vacuum tb_ddl;" +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "create index on tb_ddl(id);" +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "drop table tb_ddl;" + +-- proc +\! @abs_bindir@/gsql -p @portstring@ -d regression -c "create function fn_ddl(id int) returns int as \$\$ begin return i; end; \$\$ language plpgsql;" +\! @abs_bindir@/gsql -p @portstring@ -d regression -c "grant all privileges on function fn_ddl(int) to grantee;" + +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "alter function fn_ddl(int) reset all;" +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "comment on function fn_ddl(int) IS 'test';" +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "drop function fn_ddl(int);" + +-- type +\! @abs_bindir@/gsql -p @portstring@ -d regression -c "create type tp_ddl as enum ('A', 'B');" +\! @abs_bindir@/gsql -p @portstring@ -d regression -c "grant all privileges on type tp_ddl to grantee;" + +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "alter type tp_ddl add value 'test';" +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "comment on type tp_ddl IS 'test';" +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "drop type tp_ddl;" + +-- attribute +\! @abs_bindir@/gsql -p @portstring@ -d regression -c "create table column_ddl(a int, b int);" +\! @abs_bindir@/gsql -p @portstring@ -d regression -c "grant all privileges (a) on column_ddl to grantee;" + +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "comment on column column_ddl.a is 'test';" \ No newline at end of file diff --git a/src/test/regress/output/forbid_ddl.source b/src/test/regress/output/forbid_ddl.source new file mode 100644 index 0000000000000000000000000000000000000000..fd15653b37470b47260b8e151c751f0cb3b8f0da --- /dev/null +++ b/src/test/regress/output/forbid_ddl.source @@ -0,0 +1,125 @@ +\! @abs_bindir@/gs_guc set -D @abs_srcdir@/tmp_check/datanode1/ -c "listen_addresses='*'" > /dev/null 2>&1 +\! @abs_bindir@/gs_guc set -D @abs_srcdir@/tmp_check/datanode1/ -c "enable_nonowner_remote_ddl=off" > /dev/null 2>&1 +\! @abs_bindir@/gs_guc set -D @abs_srcdir@/tmp_check/datanode1/ -h "host all all `ip addr show | grep \"inet \" | grep -v 127.0.0.1 | awk '{print $2}' | cut -d \"/\" -f 1`/32 sha256" > /dev/null 2>&1 +\! @abs_bindir@/gs_ctl stop -D @abs_srcdir@/tmp_check/datanode1 > /dev/null 2>&1 +\! @abs_bindir@/gs_ctl start -D @abs_srcdir@/tmp_check/datanode1 > /dev/null 2>&1 +\! sleep 5 +-- forbin nonowner remote ddl +\! @abs_bindir@/gsql -p @portstring@ -d regression -c "create user grantee with password 'Asdf@1234';" +CREATE ROLE +\! @abs_bindir@/gsql -p @portstring@ -d regression -c "grant all privileges on database regression to grantee;" +GRANT +\! @abs_bindir@/gsql -p @portstring@ -d regression -c "grant all privileges on schema public to grantee;" +GRANT +-- database +\! @abs_bindir@/gsql -p @portstring@ -d regression -c "create database db_ddl;" +CREATE DATABASE +\! @abs_bindir@/gsql -p @portstring@ -d regression -c "grant all privileges on database db_ddl to grantee;" +GRANT +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d db_ddl -U "grantee" -W "Asdf@1234" -c "create schema test;" +ERROR: permission denied for database db_ddl +DETAIL: N/A +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d db_ddl -U "grantee" -W "Asdf@1234" -c "alter database db_ddl reset all"; +ERROR: permission denied for database db_ddl +DETAIL: N/A +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d db_ddl -U "grantee" -W "Asdf@1234" -c "comment on database db_ddl IS 'test'"; +ERROR: permission denied for database db_ddl +DETAIL: N/A +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "drop database db_ddl"; +ERROR: permission denied for database db_ddl +DETAIL: N/A +-- tablespace +\! @abs_bindir@/gsql -p @portstring@ -d regression -c "create tablespace ts_ddl relative location 'ts_ddl';" +CREATE TABLESPACE +\! @abs_bindir@/gsql -p @portstring@ -d regression -c "grant all privileges on tablespace ts_ddl to grantee;" +GRANT +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "alter tablespace ts_ddl resize maxsize unlimited;" +ERROR: permission denied for tablespace ts_ddl +DETAIL: N/A +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "create table test(id int) tablespace ts_ddl;" +ERROR: permission denied for tablespace ts_ddl +DETAIL: N/A +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "comment on tablespace ts_ddl IS 'test';" +ERROR: permission denied for tablespace ts_ddl +DETAIL: N/A +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "drop table test;" +ERROR: table "test" does not exist +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "drop tablespace ts_ddl;" +ERROR: permission denied for tablespace ts_ddl +DETAIL: N/A +-- namespace +\! @abs_bindir@/gsql -p @portstring@ -d regression -c "create schema ns_ddl;" +CREATE SCHEMA +\! @abs_bindir@/gsql -p @portstring@ -d regression -c "grant all privileges on schema ns_ddl to grantee;" +GRANT +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "alter schema ns_ddl without blockchain;" +ERROR: permission denied for schema ns_ddl +DETAIL: N/A +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "create table ns_ddl.test(id int);" +ERROR: permission denied for schema ns_ddl +DETAIL: N/A +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "comment on schema ns_ddl IS 'test';" +ERROR: permission denied for schema ns_ddl +DETAIL: N/A +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "drop schema ns_ddl cascade;" +ERROR: permission denied for schema ns_ddl +DETAIL: N/A +-- class +\! @abs_bindir@/gsql -p @portstring@ -d regression -c "create table tb_ddl(id int);" +CREATE TABLE +\! @abs_bindir@/gsql -p @portstring@ -d regression -c "grant all privileges on table tb_ddl to grantee;" +GRANT +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "truncate table tb_ddl;" +ERROR: permission denied for relation tb_ddl +DETAIL: N/A +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "alter table tb_ddl enable row level security;" +ERROR: permission denied for relation tb_ddl +DETAIL: N/A +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "comment on table tb_ddl IS 'test';" +ERROR: permission denied for relation tb_ddl +DETAIL: N/A +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "vacuum tb_ddl;" +WARNING: skipping "tb_ddl" --- only table or database owner can vacuum it +VACUUM +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "create index on tb_ddl(id);" +ERROR: permission denied for relation tb_ddl +DETAIL: N/A +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "drop table tb_ddl;" +ERROR: permission denied for relation tb_ddl +DETAIL: N/A +-- proc +\! @abs_bindir@/gsql -p @portstring@ -d regression -c "create function fn_ddl(id int) returns int as \$\$ begin return i; end; \$\$ language plpgsql;" +CREATE FUNCTION +\! @abs_bindir@/gsql -p @portstring@ -d regression -c "grant all privileges on function fn_ddl(int) to grantee;" +GRANT +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "alter function fn_ddl(int) reset all;" +ERROR: permission denied for function fn_ddl +DETAIL: N/A +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "comment on function fn_ddl(int) IS 'test';" +ERROR: permission denied for function fn_ddl +DETAIL: N/A +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "drop function fn_ddl(int);" +ERROR: permission denied for function fn_ddl +DETAIL: N/A +-- type +\! @abs_bindir@/gsql -p @portstring@ -d regression -c "create type tp_ddl as enum ('A', 'B');" +CREATE TYPE +\! @abs_bindir@/gsql -p @portstring@ -d regression -c "grant all privileges on type tp_ddl to grantee;" +GRANT +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "alter type tp_ddl add value 'test';" +ERROR: permission denied for type tp_ddl +DETAIL: N/A +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "comment on type tp_ddl IS 'test';" +ERROR: permission denied for type tp_ddl +DETAIL: N/A +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "drop type tp_ddl;" +ERROR: permission denied for type tp_ddl +DETAIL: N/A +-- attribute +\! @abs_bindir@/gsql -p @portstring@ -d regression -c "create table column_ddl(a int, b int);" +CREATE TABLE +\! @abs_bindir@/gsql -p @portstring@ -d regression -c "grant all privileges (a) on column_ddl to grantee;" +GRANT +\! @abs_bindir@/gsql -p @portstring@ -h `ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1` -d regression -U "grantee" -W "Asdf@1234" -c "comment on column column_ddl.a is 'test';" +ERROR: permission denied for relation column_ddl +DETAIL: N/A diff --git a/src/test/regress/parallel_schedule0A b/src/test/regress/parallel_schedule0A index 4d0c7b70b7ed346292c01437bae22dd56f612f68..979a7d49967075deed582e229a70e7e4b18aab1a 100644 --- a/src/test/regress/parallel_schedule0A +++ b/src/test/regress/parallel_schedule0A @@ -491,6 +491,9 @@ test: accept_empty_str not_accept_empty_str pg_empty_str accept_empty_copy not_a test: lateral lateral_with_dop lateral_dump +# test for forbid remote DDL +test: forbid_ddl + #test: gin/cgin test: cgin_select ignore_keyword_list test: gin_select