!3262 修复view definer在权限相关的一些bug

Merge pull request !3262 from Cross-罗/definer_bugfix
This commit is contained in:
zhangxubo
2023-03-29 07:50:18 +00:00
committed by Gitee
7 changed files with 83 additions and 62 deletions

View File

@ -18543,13 +18543,7 @@ static void dumpViewSchema(
appendPQExpBuffer(q, "%s CASCADE;\n", fmtId(tbinfo->dobj.name));
}
/* set definer for CREATE VIEW statement */
appendPQExpBuffer(q, "CREATE ");
if ((gdatcompatibility != NULL) && strcmp(gdatcompatibility, B_FORMAT) == 0 &&
tbinfo->rolname != NULL && strlen(tbinfo->rolname) > 0) {
appendPQExpBuffer(q, " DEFINER = \"%s\" ", tbinfo->rolname);
}
appendPQExpBuffer(q, " VIEW %s(%s)", fmtId(tbinfo->dobj.name), schemainfo);
appendPQExpBuffer(q, "CREATE VIEW %s(%s)", fmtId(tbinfo->dobj.name), schemainfo);
if ((tbinfo->reloptions != NULL) && strlen(tbinfo->reloptions) > 0)
appendPQExpBuffer(q, " WITH (%s)", tbinfo->reloptions);
appendPQExpBuffer(q, " AS\n ");

View File

@ -222,6 +222,28 @@ static ObjectAddress DefineVirtualRelation(RangeVar* relation, List* tlist, bool
* set definer by AlterTameCmd
*/
if (definer != NULL) {
/* Get owner to check the permissions. */
Oid ownerOid = get_role_oid(definer, false);
bool isOwnerChange = false;
if (!OidIsValid(ownerOid)) {
ownerOid = GetUserId();
} else if (ownerOid != GetUserId()) {
isOwnerChange = true;
}
if (isOwnerChange && !is_alter) {
/* Check namespace permissions. */
AclResult aclresult;
Oid namespaceId = RangeVarGetAndCheckCreationNamespace(relation, NoLock, NULL, relkind);
aclresult = pg_namespace_aclcheck(namespaceId, ownerOid, ACL_CREATE);
bool anyResult = false;
if (aclresult != ACLCHECK_OK && !IsSysSchema(namespaceId)) {
anyResult = CheckRelationCreateAnyPrivilege(ownerOid, relkind);
}
if (aclresult != ACLCHECK_OK && !anyResult) {
aclcheck_error(aclresult, ACL_KIND_NAMESPACE, get_namespace_name(namespaceId));
}
}
atcmd = makeNode(AlterTableCmd);
atcmd->subtype = AT_ChangeOwner;
atcmd->name = definer;

View File

@ -0,0 +1,15 @@
create database db1 dbcompatibility='B';
\c db1;
create user use_1136631 password 'Aa123456';
create table tab_1136631(id int unique,a1 varchar(20));
NOTICE: CREATE TABLE / UNIQUE will create implicit index "tab_1136631_id_key" for table "tab_1136631"
create view v_1136631 as select * from tab_1136631;
create definer=use_1136631 view v_1136631 as select * from tab_1136631;
ERROR: permission denied for schema public
DETAIL: N/A
create or replace definer=use_1136631 view v_1136631 as select * from tab_1136631;
ERROR: permission denied for schema public
DETAIL: N/A
\c postgres
drop database db1;
drop user use_1136631 cascade;

View File

@ -33,21 +33,12 @@ end;
SELECT c.relname as view_name, u.usename as rolname FROM pg_class c, pg_user u WHERE u.usesysid = c.relowner AND relname like '%definer_test_view%' order by view_name;
-- dump all views
\! @abs_bindir@/gs_dump test_db -p @portstring@ --include-depend-objs --exclude-self | grep -vE '^SET|^REVOKE|^GRANT|^--|^gs_dump|^COMMENT|^ALTER|^DROP'| tr -s '\n' > @abs_bindir@/definer_view_dump.sql 2>&1
\! @abs_bindir@/gs_dump test_db -p @portstring@ --include-depend-objs --exclude-self | grep -vE '^SET|^REVOKE|^GRANT|^--|^gs_dump|^COMMENT|^DROP'| tr -s '\n' > @abs_bindir@/definer_view_dump.sql 2>&1
\! cat @abs_bindir@/definer_view_dump.sql
\! @abs_bindir@/gs_dump test_db -p @portstring@ -F c -f @abs_bindir@/definer_view_dump.dmp
CREATE DATABASE target DBCOMPATIBILITY 'B';
DROP VIEW definer_test_view1;
DROP VIEW definer_test_view2;
DROP VIEW definer_test_view3;
DROP FUNCTION pro_1107262(n int);
DROP TABLE tab_1107262;
DROP SCHEMA "Test_User";
DROP SCHEMA test_user2;
GRANT ALL PRIVILEGES TO test_user2;
\i @abs_bindir@/definer_view_dump.sql
\! @abs_bindir@/gs_restore -d target -p @portstring@ @abs_bindir@/definer_view_dump.dmp
SELECT * FROM definer_test_view1;
SELECT * FROM definer_test_view2;
@ -72,6 +63,7 @@ create database test_2;
drop database test_db;
drop database test_1;
drop database test_2;
drop database target;
DROP USER "Test_User";
DROP USER test_user2;
DROP USER "Root_Test" CASCADE;

View File

@ -58,11 +58,13 @@ SELECT c.relname as view_name, u.usename as rolname FROM pg_class c, pg_user u W
(3 rows)
-- dump all views
\! @abs_bindir@/gs_dump test_db -p @portstring@ --include-depend-objs --exclude-self | grep -vE '^SET|^REVOKE|^GRANT|^--|^gs_dump|^COMMENT|^ALTER|^DROP'| tr -s '\n' > @abs_bindir@/definer_view_dump.sql 2>&1
\! @abs_bindir@/gs_dump test_db -p @portstring@ --include-depend-objs --exclude-self | grep -vE '^SET|^REVOKE|^GRANT|^--|^gs_dump|^COMMENT|^DROP'| tr -s '\n' > @abs_bindir@/definer_view_dump.sql 2>&1
\! cat @abs_bindir@/definer_view_dump.sql
CREATE SCHEMA "Test_User";
ALTER SCHEMA "Test_User" OWNER TO "Test_User";
CREATE SCHEMA test_user2;
ALTER SCHEMA test_user2 OWNER TO test_user2;
CREATE DEFINER = "Root_Test" PROCEDURE pro_1107262(n int) NOT SHIPPABLE
AS DECLARE
begin
@ -72,53 +74,38 @@ n:=n+1;
until n>10 end repeat;
end;
/
CREATE DEFINER = "Root_Test" VIEW definer_test_view1(log) AS
ALTER PROCEDURE public.pro_1107262(n integer) OWNER TO "Root_Test";
CREATE VIEW definer_test_view1(log) AS
SELECT log((10)::numeric, (1000)::numeric) AS log;
CREATE DEFINER = "test_user2" VIEW definer_test_view2(log) AS
ALTER VIEW public.definer_test_view1 OWNER TO "Root_Test";
CREATE VIEW definer_test_view2(log) AS
SELECT log((10)::numeric, (100)::numeric) AS log;
CREATE DEFINER = "Test_User" VIEW definer_test_view3(log) AS
ALTER VIEW public.definer_test_view2 OWNER TO test_user2;
CREATE VIEW definer_test_view3(log) AS
SELECT log((10)::numeric, (100)::numeric) AS log;
ALTER VIEW public.definer_test_view3 OWNER TO "Test_User";
CREATE TABLE tab_1107262 (
id integer,
c1 integer
)
WITH (orientation=row, compression=no);
ALTER TABLE public.tab_1107262 OWNER TO "Root_Test";
COPY tab_1107262 (id, c1) FROM stdin;
\.
;
DROP VIEW definer_test_view1;
DROP VIEW definer_test_view2;
DROP VIEW definer_test_view3;
DROP FUNCTION pro_1107262(n int);
DROP TABLE tab_1107262;
DROP SCHEMA "Test_User";
DROP SCHEMA test_user2;
GRANT ALL PRIVILEGES TO test_user2;
\i @abs_bindir@/definer_view_dump.sql
CREATE SCHEMA "Test_User";
CREATE SCHEMA test_user2;
CREATE DEFINER = "Root_Test" PROCEDURE pro_1107262(n int) NOT SHIPPABLE
AS DECLARE
begin
repeat
insert into tab_1107262 values(n,n*2);
n:=n+1;
until n>10 end repeat;
end;
/
CREATE DEFINER = "Root_Test" VIEW definer_test_view1(log) AS
SELECT log((10)::numeric, (1000)::numeric) AS log;
CREATE DEFINER = "test_user2" VIEW definer_test_view2(log) AS
SELECT log((10)::numeric, (100)::numeric) AS log;
CREATE DEFINER = "Test_User" VIEW definer_test_view3(log) AS
SELECT log((10)::numeric, (100)::numeric) AS log;
CREATE TABLE tab_1107262 (
id integer,
c1 integer
)
WITH (orientation=row, compression=no);
COPY tab_1107262 (id, c1) FROM stdin;
;
\! @abs_bindir@/gs_dump test_db -p @portstring@ -F c -f @abs_bindir@/definer_view_dump.dmp
--?gs_dump[port='@portstring@'][test_db].*
--?gs_dump[port='@portstring@'][test_db].*
--?gs_dump[port='@portstring@'][test_db].*
--?gs_dump[port='@portstring@'][test_db].*
CREATE DATABASE target DBCOMPATIBILITY 'B';
\! @abs_bindir@/gs_restore -d target -p @portstring@ @abs_bindir@/definer_view_dump.dmp
start restore operation ...
table tab_1107262 complete data imported !
Finish reading 12 SQL statements!
end restore operation ...
restore operation successful
--?.*
SELECT * FROM definer_test_view1;
log
--------------------
@ -151,10 +138,10 @@ create database test_1;
create table startwith_t(id int, level int, connect_by_isleaf int, connect_by_iscycle int);
create view startwith_v as select id, connect_by_isleaf as level, level as connect_by_isleaf from startwith_t;
\! @abs_bindir@/gs_dump test_1 -p @portstring@ -f @abs_bindir@/dump_postgres.sql
--?.*
--?.*
--?.*
--?.*
--?gs_dump[port='@portstring@'][test_1].*
--?gs_dump[port='@portstring@'][test_1].*
--?gs_dump[port='@portstring@'][test_1].*
--?gs_dump[port='@portstring@'][test_1].*
drop database if exists test_2;
NOTICE: database "test_2" does not exist, skipping
create database test_2;
@ -187,6 +174,7 @@ GRANT
drop database test_db;
drop database test_1;
drop database test_2;
drop database target;
DROP USER "Test_User";
DROP USER test_user2;
DROP USER "Root_Test" CASCADE;

View File

@ -66,7 +66,7 @@ test: pl_debugger_server pl_debugger_client
test: update_for_wait_s1 update_for_wait_s2
test: plan_hint plan_hint_set plan_hint_no_expand plan_hint_iud null_test_opt deserialize_func
test: large_sequence int16 gs_dump_sequence
test: gs_dump_tableof view_definer_test
test: gs_dump_tableof view_definer_test view_definer_permission_test
test: analyze_commands
#test: single_node_job
test: single_node_ddl

View File

@ -0,0 +1,10 @@
create database db1 dbcompatibility='B';
\c db1;
create user use_1136631 password 'Aa123456';
create table tab_1136631(id int unique,a1 varchar(20));
create view v_1136631 as select * from tab_1136631;
create definer=use_1136631 view v_1136631 as select * from tab_1136631;
create or replace definer=use_1136631 view v_1136631 as select * from tab_1136631;
\c postgres
drop database db1;
drop user use_1136631 cascade;