From da7673645e7eda4984a3ac8c151ac1c6d0a5fe0e Mon Sep 17 00:00:00 2001 From: shalinilohia50 <46928246+shalinilohia50@users.noreply.github.com> Date: Wed, 23 Oct 2024 22:41:36 +0530 Subject: [PATCH] Support db_datareader/db_datawriter (#68) Implement database roles `db_datareader` and `db_datawriter` * Members of the db_datareader fixed database role can read all data from all user tables and views. User objects can exist in any schema except sys and INFORMATION_SCHEMA. * Members of the db_datawriter fixed database role can add, delete, or change data in all user tables. In most use cases, this role is combined with db_datareader membership to allow reading the data that is to be modified. Engine PR: https://github.com/amazon-aurora/postgresql_modified_for_babelfish/pull/98 Task: [BABEL-3883](https://jira.rds.a2z.com/browse/BABEL-3883) Signed-off-by: Shalini Lohia --- .../babelfishpg_tsql/sql/babelfishpg_tsql.sql | 19 +- contrib/babelfishpg_tsql/sql/ownership.sql | 8 +- .../babelfishpg_tsql/sql/sys_functions.sql | 2 +- .../babelfishpg_tsql--4.3.0--4.4.0.sql | 164 +- contrib/babelfishpg_tsql/src/catalog.c | 4 +- contrib/babelfishpg_tsql/src/dbcmds.c | 190 +- contrib/babelfishpg_tsql/src/multidb.c | 39 +- contrib/babelfishpg_tsql/src/multidb.h | 2 + contrib/babelfishpg_tsql/src/pl_handler.c | 44 +- contrib/babelfishpg_tsql/src/pltsql.h | 14 +- contrib/babelfishpg_tsql/src/pltsql_utils.c | 111 +- contrib/babelfishpg_tsql/src/rolecmds.c | 1 - .../expected/1_GRANT_SCHEMA-vu-verify.out | 14 - test/JDBC/expected/BABEL-2403.out | 24 + test/JDBC/expected/BABEL-3637.out | 4 + .../BABEL-CHECK-CONSTRAINT-vu-prepare.out | 14 + test/JDBC/expected/BABEL-LOGIN-USER-EXT.out | 50 + test/JDBC/expected/BABEL-USER.out | 10 + .../Test-sp_helpdbfixedrole-dep-vu-verify.out | 6 +- .../Test-sp_helpdbfixedrole-vu-verify.out | 10 +- .../Test_alter_db_rename-vu-verify.out | 6 + .../expected/Test_rename_db_single-db.out | 16 + .../Test_sp_rename_database-vu-verify.out | 6 + .../expected/Test_sp_renamedb-vu-verify.out | 6 + .../datareader_datawriter-vu-cleanup.out | 119 + .../datareader_datawriter-vu-prepare.out | 53 + .../datareader_datawriter-vu-verify.out | 684 ++++++ test/JDBC/expected/datareader_datawriter.out | 1914 +++++++++++++++++ .../expected/db_accessadmin-vu-verify.out | 27 +- test/JDBC/expected/single_db/BABEL-2403.out | 24 + .../single_db/BABEL-LOGIN-USER-EXT.out | 46 + test/JDBC/expected/single_db/BABEL-USER.out | 10 + .../single_db/Test_rename_db_single-db.out | 16 + .../single_db/datareader_datawriter.out | 1914 +++++++++++++++++ .../single_db/db_accessadmin-vu-verify.out | 27 +- .../test_windows_login-vu-prepare.out | 1 + test/JDBC/input/1_GRANT_SCHEMA-vu-verify.mix | 14 - test/JDBC/input/BABEL-3637.mix | 4 + .../BABEL-CHECK-CONSTRAINT-vu-prepare.mix | 14 + .../datareader_datawriter-vu-cleanup.mix | 101 + .../datareader_datawriter-vu-prepare.mix | 53 + .../input/datareader_datawriter-vu-verify.mix | 360 ++++ test/JDBC/input/datareader_datawriter.mix | 1127 ++++++++++ test/JDBC/input/db_accessadmin-vu-verify.mix | 11 +- .../input/test_windows_login-vu-prepare.mix | 3 +- test/JDBC/upgrade/13_6/schedule | 1 + test/JDBC/upgrade/13_7/schedule | 1 + test/JDBC/upgrade/13_8/schedule | 1 + test/JDBC/upgrade/13_9/schedule | 1 + test/JDBC/upgrade/14_10/schedule | 1 + test/JDBC/upgrade/14_11/schedule | 1 + test/JDBC/upgrade/14_12/schedule | 1 + test/JDBC/upgrade/14_13/schedule | 1 + test/JDBC/upgrade/14_14/schedule | 1 + test/JDBC/upgrade/14_3/schedule | 1 + test/JDBC/upgrade/14_5/schedule | 1 + test/JDBC/upgrade/14_6/schedule | 1 + test/JDBC/upgrade/14_7/schedule | 1 + test/JDBC/upgrade/14_8/schedule | 1 + test/JDBC/upgrade/14_9/schedule | 1 + test/JDBC/upgrade/15_1/schedule | 1 + test/JDBC/upgrade/15_2/schedule | 1 + test/JDBC/upgrade/15_3/schedule | 1 + test/JDBC/upgrade/15_4/schedule | 1 + test/JDBC/upgrade/15_5/schedule | 1 + test/JDBC/upgrade/15_6/schedule | 1 + test/JDBC/upgrade/15_7/schedule | 1 + test/JDBC/upgrade/15_8/schedule | 1 + test/JDBC/upgrade/15_9/schedule | 1 + test/JDBC/upgrade/16_1/schedule | 1 + test/JDBC/upgrade/16_2/schedule | 1 + test/JDBC/upgrade/16_3/schedule | 3 + test/JDBC/upgrade/16_4/schedule | 1 + test/JDBC/upgrade/latest/schedule | 1 + 74 files changed, 7234 insertions(+), 83 deletions(-) create mode 100644 test/JDBC/expected/datareader_datawriter-vu-cleanup.out create mode 100644 test/JDBC/expected/datareader_datawriter-vu-prepare.out create mode 100644 test/JDBC/expected/datareader_datawriter-vu-verify.out create mode 100644 test/JDBC/expected/datareader_datawriter.out create mode 100644 test/JDBC/expected/single_db/datareader_datawriter.out create mode 100644 test/JDBC/input/datareader_datawriter-vu-cleanup.mix create mode 100644 test/JDBC/input/datareader_datawriter-vu-prepare.mix create mode 100644 test/JDBC/input/datareader_datawriter-vu-verify.mix create mode 100644 test/JDBC/input/datareader_datawriter.mix diff --git a/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql b/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql index d7080e4bca..0a6a567cad 100644 --- a/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql +++ b/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql @@ -1254,7 +1254,9 @@ FROM pg_catalog.pg_class t1 JOIN sys.pg_namespace_ext t2 ON t1.relnamespace = t2.oid JOIN sys.schemas s1 ON s1.schema_id = t1.relnamespace JOIN information_schema.column_privileges t5 ON t1.relname = t5.table_name AND t2.nspname = t5.table_schema - JOIN pg_attribute t6 ON t6.attrelid = t1.oid AND t6.attname = t5.column_name; + JOIN pg_attribute t6 ON t6.attrelid = t1.oid AND t6.attname = t5.column_name + JOIN sys.babelfish_authid_user_ext ext ON ext.rolname = t5.grantee +WHERE ext.orig_username NOT IN ('db_datawriter', 'db_datareader'); GRANT SELECT ON sys.sp_column_privileges_view TO PUBLIC; CREATE OR REPLACE PROCEDURE sys.sp_column_privileges( @@ -1362,7 +1364,8 @@ FROM pg_catalog.pg_class t1 JOIN sys.pg_namespace_ext t2 ON t1.relnamespace = t2.oid JOIN sys.schemas s1 ON s1.schema_id = t1.relnamespace JOIN information_schema.table_privileges t4 ON t1.relname = t4.table_name -WHERE t4.privilege_type = 'DELETE'; + JOIN sys.babelfish_authid_user_ext ext ON ext.rolname = t4.grantee +WHERE t4.privilege_type = 'DELETE' AND ext.orig_username != 'db_datawriter'; GRANT SELECT on sys.sp_table_privileges_view TO PUBLIC; CREATE OR REPLACE PROCEDURE sys.sp_table_privileges( @@ -2118,7 +2121,7 @@ BEGIN LEFT OUTER JOIN pg_catalog.pg_roles AS Base4 ON Base4.rolname = Bsdb.owner WHERE Ext1.database_name = DB_NAME() AND (Ext1.type != 'R' OR Ext1.type != 'A') - AND Ext1.orig_username NOT IN ('db_owner', 'db_accessadmin') + AND Ext1.orig_username NOT IN ('db_owner', 'db_accessadmin', 'db_datareader', 'db_datawriter') ORDER BY UserName, RoleName; END -- If the security account is the db fixed role - db_owner @@ -2150,7 +2153,7 @@ BEGIN WHERE Ext1.database_name = DB_NAME() AND Ext2.database_name = DB_NAME() AND Ext1.type = 'R' - AND Ext2.orig_username NOT IN ('db_owner', 'db_accessadmin') + AND Ext2.orig_username NOT IN ('db_owner', 'db_accessadmin', 'db_datareader', 'db_datawriter') AND (Ext1.orig_username = @name_in_db OR pg_catalog.lower(Ext1.orig_username) = pg_catalog.lower(@name_in_db)) ORDER BY Role_name, Users_in_role; END @@ -2188,7 +2191,7 @@ BEGIN LEFT OUTER JOIN pg_catalog.pg_roles AS Base4 ON Base4.rolname = Bsdb.owner WHERE Ext1.database_name = DB_NAME() AND (Ext1.type != 'R' OR Ext1.type != 'A') - AND Ext1.orig_username NOT IN ('db_owner', 'db_accessadmin') + AND Ext1.orig_username NOT IN ('db_owner', 'db_accessadmin', 'db_datareader', 'db_datawriter') AND (Ext1.orig_username = @name_in_db OR pg_catalog.lower(Ext1.orig_username) = pg_catalog.lower(@name_in_db)) ORDER BY UserName, RoleName; END @@ -2348,11 +2351,13 @@ CREATE OR REPLACE PROCEDURE sys.sp_helpdbfixedrole("@rolename" sys.SYSNAME = NUL $$ BEGIN -- Returns a list of the fixed database roles. - IF LOWER(RTRIM(@rolename)) IS NULL OR LOWER(RTRIM(@rolename)) IN ('db_owner', 'db_accessadmin') + IF LOWER(RTRIM(@rolename)) IS NULL OR LOWER(RTRIM(@rolename)) IN ('db_owner', 'db_accessadmin', 'db_datareader', 'db_datawriter') BEGIN SELECT CAST(DbFixedRole as sys.SYSNAME) AS DbFixedRole, CAST(Description AS sys.nvarchar(70)) AS Description FROM ( VALUES ('db_owner', 'DB Owners'), - ('db_accessadmin', 'DB Access Administrators')) x(DbFixedRole, Description) + ('db_accessadmin', 'DB Access Administrators'), + ('db_datareader', 'DB Data Reader'), + ('db_datawriter', 'DB Data Writer')) x(DbFixedRole, Description) WHERE LOWER(RTRIM(@rolename)) IS NULL OR LOWER(RTRIM(@rolename)) = DbFixedRole; END ELSE IF LOWER(RTRIM(@rolename)) IN ( diff --git a/contrib/babelfishpg_tsql/sql/ownership.sql b/contrib/babelfishpg_tsql/sql/ownership.sql index 226fc47926..078e32d1d4 100644 --- a/contrib/babelfishpg_tsql/sql/ownership.sql +++ b/contrib/babelfishpg_tsql/sql/ownership.sql @@ -260,9 +260,9 @@ LANGUAGE plpgsql AS $$ DECLARE reserved_roles varchar[] := ARRAY['sysadmin', 'securityadmin', - 'master_dbo', 'master_guest', 'master_db_owner', 'master_db_accessadmin', - 'tempdb_dbo', 'tempdb_guest', 'tempdb_db_owner', 'tempdb_db_accessadmin', - 'msdb_dbo', 'msdb_guest', 'msdb_db_owner', 'msdb_db_accessadmin']; + 'master_dbo', 'master_guest', 'master_db_owner', 'master_db_accessadmin', 'master_db_datareader', 'master_db_datawriter', + 'tempdb_dbo', 'tempdb_guest', 'tempdb_db_owner', 'tempdb_db_accessadmin', 'tempdb_db_datareader', 'tempdb_db_datawriter', + 'msdb_dbo', 'msdb_guest', 'msdb_db_owner', 'msdb_db_accessadmin', 'msdb_db_datareader', 'msdb_db_datawriter']; user_id oid := -1; db_name name := NULL; @@ -460,7 +460,7 @@ ON Base.rolname = Ext.rolname LEFT OUTER JOIN pg_catalog.pg_roles Base2 ON Ext.login_name = Base2.rolname WHERE Ext.database_name = DB_NAME() - AND (Ext.orig_username IN ('dbo', 'db_owner', 'db_accessadmin', 'guest') -- system users should always be visible + AND (Ext.orig_username IN ('dbo', 'db_owner', 'db_accessadmin', 'db_datareader', 'db_datawriter', 'guest') -- system users should always be visible OR pg_has_role(Ext.rolname, 'MEMBER')) -- Current user should be able to see users it has permission of UNION ALL SELECT diff --git a/contrib/babelfishpg_tsql/sql/sys_functions.sql b/contrib/babelfishpg_tsql/sql/sys_functions.sql index db18d570ad..a9d843ef03 100644 --- a/contrib/babelfishpg_tsql/sql/sys_functions.sql +++ b/contrib/babelfishpg_tsql/sql/sys_functions.sql @@ -4501,7 +4501,7 @@ BEGIN END IF; ELSIF EXISTS (SELECT orig_username FROM sys.babelfish_authid_user_ext WHERE orig_username = role COLLATE sys.database_default) THEN - IF (((SELECT orig_username FROM sys.babelfish_authid_user_ext WHERE rolname = CURRENT_USER) = 'dbo' COLLATE sys.database_default) AND role COLLATE sys.database_default IN ('db_owner', 'db_accessadmin')) + IF (((SELECT orig_username FROM sys.babelfish_authid_user_ext WHERE rolname = CURRENT_USER) = 'dbo' COLLATE sys.database_default) AND role COLLATE sys.database_default IN ('db_owner', 'db_accessadmin', 'db_datareader', 'db_datawriter')) THEN RETURN 1; ELSIF EXISTS (SELECT name FROM sys.user_token WHERE name = role COLLATE sys.database_default) THEN RETURN 1; -- Return 1 if current session user is a member of role or windows group diff --git a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.3.0--4.4.0.sql b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.3.0--4.4.0.sql index 40992655f4..3c25f110e5 100644 --- a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.3.0--4.4.0.sql +++ b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.3.0--4.4.0.sql @@ -1261,7 +1261,7 @@ BEGIN END IF; ELSIF EXISTS (SELECT orig_username FROM sys.babelfish_authid_user_ext WHERE orig_username = role COLLATE sys.database_default) THEN - IF (((SELECT orig_username FROM sys.babelfish_authid_user_ext WHERE rolname = CURRENT_USER) = 'dbo' COLLATE sys.database_default) AND role COLLATE sys.database_default IN ('db_owner', 'db_accessadmin')) + IF (((SELECT orig_username FROM sys.babelfish_authid_user_ext WHERE rolname = CURRENT_USER) = 'dbo' COLLATE sys.database_default) AND role COLLATE sys.database_default IN ('db_owner', 'db_accessadmin', 'db_datareader', 'db_datawriter')) THEN RETURN 1; ELSIF EXISTS (SELECT name FROM sys.user_token WHERE name = role COLLATE sys.database_default) THEN RETURN 1; -- Return 1 if current session user is a member of role or windows group @@ -1896,6 +1896,103 @@ BEGIN END; $$ LANGUAGE plpgsql; +CREATE OR REPLACE VIEW sys.sp_column_privileges_view AS +SELECT +CAST(t2.dbname AS sys.sysname) AS TABLE_QUALIFIER, +CAST(s1.name AS sys.sysname) AS TABLE_OWNER, +CAST(t1.relname AS sys.sysname) AS TABLE_NAME, +CAST(COALESCE(SPLIT_PART(t6.attoptions[1], '=', 2), t5.column_name) AS sys.sysname) AS COLUMN_NAME, +CAST((select orig_username from sys.babelfish_authid_user_ext where rolname = t5.grantor::name) AS sys.sysname) AS GRANTOR, +CAST((select orig_username from sys.babelfish_authid_user_ext where rolname = t5.grantee::name) AS sys.sysname) AS GRANTEE, +CAST(t5.privilege_type AS sys.varchar(32)) COLLATE sys.database_default AS PRIVILEGE, +CAST(t5.is_grantable AS sys.varchar(3)) COLLATE sys.database_default AS IS_GRANTABLE +FROM pg_catalog.pg_class t1 + JOIN sys.pg_namespace_ext t2 ON t1.relnamespace = t2.oid + JOIN sys.schemas s1 ON s1.schema_id = t1.relnamespace + JOIN information_schema.column_privileges t5 ON t1.relname = t5.table_name AND t2.nspname = t5.table_schema + JOIN pg_attribute t6 ON t6.attrelid = t1.oid AND t6.attname = t5.column_name + JOIN sys.babelfish_authid_user_ext ext ON ext.rolname = t5.grantee +WHERE ext.orig_username NOT IN ('db_datawriter', 'db_datareader'); + +CREATE OR REPLACE PROCEDURE sys.sp_column_privileges( + "@table_name" sys.sysname, + "@table_owner" sys.sysname = '', + "@table_qualifier" sys.sysname = '', + "@column_name" sys.nvarchar(384) = '' +) +AS $$ +BEGIN + IF (@table_qualifier != '') AND (LOWER(@table_qualifier) != LOWER(sys.db_name())) + BEGIN + THROW 33557097, N'The database name component of the object qualifier must be the name of the current database.', 1; + END + + IF (COALESCE(@table_owner, '') = '') + BEGIN + + IF EXISTS ( + SELECT * FROM sys.sp_column_privileges_view + WHERE LOWER(@table_name) = LOWER(table_name) and LOWER(SCHEMA_NAME()) = LOWER(table_qualifier) + ) + BEGIN + SELECT + TABLE_QUALIFIER, + TABLE_OWNER, + TABLE_NAME, + COLUMN_NAME, + GRANTOR, + GRANTEE, + PRIVILEGE, + IS_GRANTABLE + FROM sys.sp_column_privileges_view + WHERE LOWER(@table_name) = LOWER(table_name) + AND (LOWER(SCHEMA_NAME()) = LOWER(table_owner)) + AND ((SELECT COALESCE(@table_qualifier,'')) = '' OR LOWER(table_qualifier) = LOWER(@table_qualifier)) + AND ((SELECT COALESCE(@column_name,'')) = '' OR LOWER(column_name) LIKE LOWER(@column_name)) + ORDER BY table_qualifier, table_owner, table_name, column_name, privilege, grantee; + END + ELSE + BEGIN + SELECT + TABLE_QUALIFIER, + TABLE_OWNER, + TABLE_NAME, + COLUMN_NAME, + GRANTOR, + GRANTEE, + PRIVILEGE, + IS_GRANTABLE + FROM sys.sp_column_privileges_view + WHERE LOWER(@table_name) = LOWER(table_name) + AND (LOWER('dbo')= LOWER(table_owner)) + AND ((SELECT COALESCE(@table_qualifier,'')) = '' OR LOWER(table_qualifier) = LOWER(@table_qualifier)) + AND ((SELECT COALESCE(@column_name,'')) = '' OR LOWER(column_name) LIKE LOWER(@column_name)) + ORDER BY table_qualifier, table_owner, table_name, column_name, privilege, grantee; + END + END + ELSE + BEGIN + SELECT + TABLE_QUALIFIER, + TABLE_OWNER, + TABLE_NAME, + COLUMN_NAME, + GRANTOR, + GRANTEE, + PRIVILEGE, + IS_GRANTABLE + FROM sys.sp_column_privileges_view + WHERE LOWER(@table_name) = LOWER(table_name) + AND ((SELECT COALESCE(@table_owner,'')) = '' OR LOWER(table_owner) = LOWER(@table_owner)) + AND ((SELECT COALESCE(@table_qualifier,'')) = '' OR LOWER(table_qualifier) = LOWER(@table_qualifier)) + AND ((SELECT COALESCE(@column_name,'')) = '' OR LOWER(column_name) LIKE LOWER(@column_name)) + ORDER BY table_qualifier, table_owner, table_name, column_name, privilege, grantee; + END +END; +$$ +LANGUAGE 'pltsql'; +GRANT EXECUTE ON PROCEDURE sys.sp_column_privileges TO PUBLIC; + CREATE OR REPLACE VIEW sys.sp_table_privileges_view AS -- Will use sp_column_priivleges_view to get information from SELECT, INSERT and REFERENCES (only need permission from 1 column in table) SELECT DISTINCT @@ -1922,7 +2019,56 @@ FROM pg_catalog.pg_class t1 JOIN sys.pg_namespace_ext t2 ON t1.relnamespace = t2.oid JOIN sys.schemas s1 ON s1.schema_id = t1.relnamespace JOIN information_schema.table_privileges t4 ON t1.relname = t4.table_name -WHERE t4.privilege_type = 'DELETE'; + JOIN sys.babelfish_authid_user_ext ext ON ext.rolname = t4.grantee +WHERE t4.privilege_type = 'DELETE' AND ext.orig_username != 'db_datawriter'; + +CREATE OR REPLACE PROCEDURE sys.sp_table_privileges( + "@table_name" sys.nvarchar(384), + "@table_owner" sys.nvarchar(384) = '', + "@table_qualifier" sys.sysname = '', + "@fusepattern" sys.bit = 1 +) +AS $$ +BEGIN + + IF (@table_qualifier != '') AND (LOWER(@table_qualifier) != LOWER(sys.db_name())) + BEGIN + THROW 33557097, N'The database name component of the object qualifier must be the name of the current database.', 1; + END + + IF @fusepattern = 1 + BEGIN + SELECT + TABLE_QUALIFIER, + TABLE_OWNER, + TABLE_NAME, + GRANTOR, + GRANTEE, + PRIVILEGE, + IS_GRANTABLE FROM sys.sp_table_privileges_view + WHERE LOWER(TABLE_NAME) LIKE LOWER(@table_name) + AND ((SELECT COALESCE(@table_owner,'')) = '' OR LOWER(TABLE_OWNER) LIKE LOWER(@table_owner)) + ORDER BY table_qualifier, table_owner, table_name, privilege, grantee; + END + ELSE + BEGIN + SELECT + TABLE_QUALIFIER, + TABLE_OWNER, + TABLE_NAME, + GRANTOR, + GRANTEE, + PRIVILEGE, + IS_GRANTABLE FROM sys.sp_table_privileges_view + WHERE LOWER(TABLE_NAME) = LOWER(@table_name) + AND ((SELECT COALESCE(@table_owner,'')) = '' OR LOWER(TABLE_OWNER) = LOWER(@table_owner)) + ORDER BY table_qualifier, table_owner, table_name, privilege, grantee; + END + +END; +$$ +LANGUAGE 'pltsql'; +GRANT EXECUTE ON PROCEDURE sys.sp_table_privileges TO PUBLIC; CREATE OR REPLACE PROCEDURE sys.sp_helpuser("@name_in_db" sys.SYSNAME = NULL) AS $$ @@ -4257,7 +4403,7 @@ ON Base.rolname = Ext.rolname LEFT OUTER JOIN pg_catalog.pg_roles Base2 ON Ext.login_name = Base2.rolname WHERE Ext.database_name = DB_NAME() - AND (Ext.orig_username IN ('dbo', 'db_owner', 'db_accessadmin', 'guest') -- system users should always be visible + AND (Ext.orig_username IN ('dbo', 'db_owner', 'db_accessadmin', 'db_datareader', 'db_datawriter', 'guest') -- system users should always be visible OR pg_has_role(Ext.rolname, 'MEMBER')) -- Current user should be able to see users it has permission of UNION ALL SELECT @@ -4290,11 +4436,13 @@ CREATE OR REPLACE PROCEDURE sys.sp_helpdbfixedrole("@rolename" sys.SYSNAME = NUL $$ BEGIN -- Returns a list of the fixed database roles. - IF LOWER(RTRIM(@rolename)) IS NULL OR LOWER(RTRIM(@rolename)) IN ('db_owner', 'db_accessadmin') + IF LOWER(RTRIM(@rolename)) IS NULL OR LOWER(RTRIM(@rolename)) IN ('db_owner', 'db_accessadmin', 'db_datareader', 'db_datawriter') BEGIN SELECT CAST(DbFixedRole as sys.SYSNAME) AS DbFixedRole, CAST(Description AS sys.nvarchar(70)) AS Description FROM ( VALUES ('db_owner', 'DB Owners'), - ('db_accessadmin', 'DB Access Administrators')) x(DbFixedRole, Description) + ('db_accessadmin', 'DB Access Administrators'), + ('db_datareader', 'DB Data Reader'), + ('db_datawriter', 'DB Data Writer')) x(DbFixedRole, Description) WHERE LOWER(RTRIM(@rolename)) IS NULL OR LOWER(RTRIM(@rolename)) = DbFixedRole; END ELSE IF LOWER(RTRIM(@rolename)) IN ( @@ -4345,7 +4493,7 @@ BEGIN WHERE Ext1.database_name = DB_NAME() AND (Ext1.type != 'R' OR Ext1.type != 'A') AND Ext1.orig_username != 'db_owner' - AND Ext1.orig_username NOT IN ('db_owner', 'db_accessadmin') + AND Ext1.orig_username NOT IN ('db_owner', 'db_accessadmin', 'db_datareader', 'db_datawriter') ORDER BY UserName, RoleName; END -- If the security account is the db fixed role - db_owner @@ -4378,7 +4526,7 @@ BEGIN AND Ext2.database_name = DB_NAME() AND Ext1.type = 'R' AND Ext2.orig_username != 'db_owner' - AND Ext2.orig_username NOT IN ('db_owner', 'db_accessadmin') + AND Ext2.orig_username NOT IN ('db_owner', 'db_accessadmin', 'db_datareader', 'db_datawriter') AND (Ext1.orig_username = @name_in_db OR pg_catalog.lower(Ext1.orig_username) = pg_catalog.lower(@name_in_db)) ORDER BY Role_name, Users_in_role; END @@ -4417,7 +4565,7 @@ BEGIN WHERE Ext1.database_name = DB_NAME() AND (Ext1.type != 'R' OR Ext1.type != 'A') AND Ext1.orig_username != 'db_owner' - AND Ext1.orig_username NOT IN ('db_owner', 'db_accessadmin') + AND Ext1.orig_username NOT IN ('db_owner', 'db_accessadmin', 'db_datareader', 'db_datawriter') AND (Ext1.orig_username = @name_in_db OR pg_catalog.lower(Ext1.orig_username) = pg_catalog.lower(@name_in_db)) ORDER BY UserName, RoleName; END diff --git a/contrib/babelfishpg_tsql/src/catalog.c b/contrib/babelfishpg_tsql/src/catalog.c index 1922ae47b9..8edb5b8a01 100644 --- a/contrib/babelfishpg_tsql/src/catalog.c +++ b/contrib/babelfishpg_tsql/src/catalog.c @@ -4268,7 +4268,7 @@ grant_perms_to_objects_in_schema(const char *schema_name, /* do this step */ ProcessUtility(wrapper, - "(GRANT STATEMENT )", + INTERNAL_GRANT_STATEMENT, false, PROCESS_UTILITY_SUBCOMMAND, NULL, @@ -4366,7 +4366,7 @@ exec_internal_grant_on_function(const char *logicalschema, /* do this step */ ProcessUtility(wrapper, - "(GRANT STATEMENT )", + INTERNAL_GRANT_STATEMENT, false, PROCESS_UTILITY_SUBCOMMAND, NULL, diff --git a/contrib/babelfishpg_tsql/src/dbcmds.c b/contrib/babelfishpg_tsql/src/dbcmds.c index b97c23a253..8f38ac6383 100644 --- a/contrib/babelfishpg_tsql/src/dbcmds.c +++ b/contrib/babelfishpg_tsql/src/dbcmds.c @@ -91,6 +91,8 @@ gen_createdb_subcmds(const char *dbname, const char *owner) const char *guest_schema; Oid owner_oid; bool owner_is_sa; + const char *db_datareader; + const char *db_datawriter; schema = get_dbo_schema_name(dbname); dbo = get_dbo_role_name(dbname); @@ -100,6 +102,8 @@ gen_createdb_subcmds(const char *dbname, const char *owner) guest_schema = get_guest_schema_name(dbname); owner_oid = get_role_oid(owner, true); owner_is_sa = role_is_sa(owner_oid); + db_datareader = get_db_datareader_name(dbname); + db_datawriter = get_db_datawriter_name(dbname); /* * To avoid SQL injection, we generate statement parsetree with dummy @@ -117,6 +121,8 @@ gen_createdb_subcmds(const char *dbname, const char *owner) /* create db_accessadmin for database */ appendStringInfo(&query, "CREATE ROLE dummy ROLE dummy; "); + appendStringInfo(&query, "CREATE ROLE dummy ROLE dummy; "); + appendStringInfo(&query, "CREATE ROLE dummy ROLE dummy; "); appendStringInfo(&query, "GRANT CREATE ON DATABASE dummy TO dummy; "); if (guest) @@ -140,13 +146,13 @@ gen_createdb_subcmds(const char *dbname, const char *owner) if (guest) { if (!owner_is_sa) - expected_stmt_num = list_length(logins) > 0 ? 12 : 11; + expected_stmt_num = list_length(logins) > 0 ? 14 : 13; else - expected_stmt_num = list_length(logins) > 0 ? 11 : 10; + expected_stmt_num = list_length(logins) > 0 ? 13 : 12; } else { - expected_stmt_num = 8; + expected_stmt_num = 10; if (!owner_is_sa) expected_stmt_num++; @@ -176,6 +182,12 @@ gen_createdb_subcmds(const char *dbname, const char *owner) list_make1(make_rolespec_node(owner)), NULL); } + stmt = parsetree_nth_stmt(res, i++); + update_CreateRoleStmt(stmt, db_datareader, db_owner, NULL); + + stmt = parsetree_nth_stmt(res, i++); + update_CreateRoleStmt(stmt, db_datawriter, db_owner, NULL); + stmt = parsetree_nth_stmt(res, i++); update_CreateRoleStmt(stmt, db_accessadmin, db_owner, NULL); @@ -218,16 +230,22 @@ add_fixed_user_roles_to_bbf_authid_user_ext(const char *dbname) const char *dbo; const char *db_owner; const char *db_accessadmin; + const char *db_datareader; + const char *db_datawriter; const char *guest; dbo = get_dbo_role_name(dbname); db_owner = get_db_owner_name(dbname); db_accessadmin = get_db_accessadmin_role_name(dbname); guest = get_guest_role_name(dbname); + db_datareader = get_db_datareader_name(dbname); + db_datawriter = get_db_datawriter_name(dbname); - add_to_bbf_authid_user_ext(dbo, "dbo", dbname, "dbo", NULL, false, true, false); - add_to_bbf_authid_user_ext(db_owner, "db_owner", dbname, NULL, NULL, true, true, false); + add_to_bbf_authid_user_ext(dbo, DBO, dbname, DBO, NULL, false, true, false); + add_to_bbf_authid_user_ext(db_owner, DB_OWNER, dbname, NULL, NULL, true, true, false); add_to_bbf_authid_user_ext(db_accessadmin, DB_ACCESSADMIN, dbname, NULL, NULL, true, true, false); + add_to_bbf_authid_user_ext(db_datareader, DB_DATAREADER, dbname, NULL, NULL, true, true, false); + add_to_bbf_authid_user_ext(db_datawriter, DB_DATAWRITER, dbname, NULL, NULL, true, true, false); /* * For master, tempdb and msdb databases, the guest user will be @@ -249,30 +267,36 @@ gen_dropdb_subcmds(const char *dbname, List *db_users) List *stmt_list; ListCell *elem; Node *stmt; - int expected_stmts = 8; + int expected_stmts = 10; int i = 0; const char *dbo; const char *db_owner; const char *db_accessadmin; const char *schema; const char *guest_schema; + const char *db_datareader; + const char *db_datawriter; dbo = get_dbo_role_name(dbname); db_owner = get_db_owner_name(dbname); db_accessadmin = get_db_accessadmin_role_name(dbname); schema = get_dbo_schema_name(dbname); guest_schema = get_guest_schema_name(dbname); + db_datareader = get_db_datareader_name(dbname); + db_datawriter = get_db_datawriter_name(dbname); initStringInfo(&query); appendStringInfo(&query, "DROP SCHEMA dummy CASCADE; "); appendStringInfo(&query, "DROP SCHEMA dummy CASCADE; "); + /* First drop guest user and custom users if they exist */ foreach(elem, db_users) { char *user_name = (char *) lfirst(elem); if (strcmp(user_name, db_owner) != 0 && strcmp(user_name, dbo) != 0 && - strcmp(user_name, db_accessadmin) != 0) + strcmp(user_name, db_accessadmin) != 0 && strcmp(user_name, db_datareader) != 0 && + strcmp(user_name, db_datawriter) != 0) { appendStringInfo(&query, "DROP OWNED BY dummy CASCADE; "); appendStringInfo(&query, "DROP ROLE dummy; "); @@ -282,6 +306,9 @@ gen_dropdb_subcmds(const char *dbname, List *db_users) appendStringInfo(&query, "DROP OWNED BY dummy, dummy, dummy CASCADE; "); /* Then drop db_accessadmin, db_owner and dbo in that order */ + appendStringInfo(&query, "DROP ROLE dummy; "); + appendStringInfo(&query, "DROP ROLE dummy; "); + appendStringInfo(&query, "REVOKE CREATE ON DATABASE dummy FROM dummy; "); appendStringInfo(&query, "DROP ROLE dummy; "); appendStringInfo(&query, "REVOKE CREATE, CONNECT, TEMPORARY ON DATABASE dummy FROM dummy; "); @@ -307,7 +334,8 @@ gen_dropdb_subcmds(const char *dbname, List *db_users) char *user_name = (char *) lfirst(elem); if (strcmp(user_name, db_owner) != 0 && strcmp(user_name, dbo) != 0 && - strcmp(user_name, db_accessadmin) != 0) + strcmp(user_name, db_accessadmin) != 0 && strcmp(user_name, db_datareader) != 0 && + strcmp(user_name, db_datawriter) != 0) { stmt = parsetree_nth_stmt(stmt_list, i++); update_DropOwnedStmt(stmt, list_make1(user_name)); @@ -320,6 +348,11 @@ gen_dropdb_subcmds(const char *dbname, List *db_users) stmt = parsetree_nth_stmt(stmt_list, i++); update_DropOwnedStmt(stmt, list_make3(pstrdup(db_accessadmin), pstrdup(db_owner), pstrdup(dbo))); + stmt = parsetree_nth_stmt(stmt_list, i++); + update_DropRoleStmt(stmt, db_datareader); + stmt = parsetree_nth_stmt(stmt_list, i++); + update_DropRoleStmt(stmt, db_datawriter); + stmt = parsetree_nth_stmt(stmt_list, i++); update_GrantStmt(stmt, get_database_name(MyDatabaseId), NULL, db_accessadmin, NULL); stmt = parsetree_nth_stmt(stmt_list, i++); @@ -1263,8 +1296,118 @@ create_guest_schema_for_all_dbs(PG_FUNCTION_ARGS) PG_RETURN_INT32(0); } +/* Grant permissions on all the existing objects to db_datareader/db_datawriter. */ static void -create_db_roles_if_not_exists(const char *dbname, List *parsetree_list) +grant_perms_to_dbreader_dbwriter(const uint16 dbid, + const char *db_datareader, + const char *db_datawriter) +{ + Relation namespace_rel; + TupleDesc namespace_rel_descr; + ScanKeyData key; + HeapTuple tuple; + TableScanDesc tblscan; + StringInfoData query; + List *stmt_list; + char *dbname = get_db_name(dbid); + MigrationMode baseline_mode = is_user_database_singledb(dbname) ? SINGLE_DB : MULTI_DB; + + namespace_rel = table_open(namespace_ext_oid, RowExclusiveLock); + namespace_rel_descr = RelationGetDescr(namespace_rel); + + initStringInfo(&query); + appendStringInfo(&query, "GRANT SELECT ON ALL TABLES IN SCHEMA dummy TO dummy; "); + appendStringInfo(&query, "GRANT INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA dummy TO dummy; "); + + /* Grant ALTER DEFAULT PRIVILEGES on schema owner and dbo user. */ + appendStringInfo(&query, "ALTER DEFAULT PRIVILEGES FOR ROLE dummy, dummy IN SCHEMA dummy GRANT SELECT ON TABLES TO dummy; "); + appendStringInfo(&query, "ALTER DEFAULT PRIVILEGES FOR ROLE dummy, dummy IN SCHEMA dummy GRANT INSERT, UPDATE, DELETE ON TABLES TO dummy; "); + + stmt_list = raw_parser(query.data, RAW_PARSE_DEFAULT); + + ScanKeyInit(&key, + Anum_namespace_ext_dbid, + BTEqualStrategyNumber, F_INT2EQ, + Int16GetDatum(dbid)); + + tblscan = table_beginscan_catalog(namespace_rel, 1, &key); + + tuple = heap_getnext(tblscan, ForwardScanDirection); + + while (HeapTupleIsValid(tuple)) + { + bool isNull; + Datum datum; + char *schema_name; + Node *stmts; + int i = 0; + ListCell *parsetree_item; + char *schema_owner; + char *dbo_user; + + datum = heap_getattr(tuple, Anum_namespace_ext_namespace, namespace_rel_descr, &isNull); + schema_name = NameStr(*DatumGetName(datum)); + schema_owner = GetUserNameFromId(get_owner_of_schema(schema_name), false); + dbo_user = get_dbo_role_name_by_mode(dbname, baseline_mode); + + /* Replace dummy elements in parsetree with real values */ + stmts = parsetree_nth_stmt(stmt_list, i++); + update_GrantStmt(stmts, schema_name, NULL, db_datareader, NULL); + stmts = parsetree_nth_stmt(stmt_list, i++); + update_GrantStmt(stmts, schema_name, NULL, db_datawriter, NULL); + + stmts = parsetree_nth_stmt(stmt_list, i++); + update_AlterDefaultPrivilegesStmt(stmts, schema_name, schema_owner, dbo_user, db_datareader, NULL); + stmts = parsetree_nth_stmt(stmt_list, i++); + update_AlterDefaultPrivilegesStmt(stmts, schema_name, schema_owner, dbo_user, db_datawriter, NULL); + + /* Run all subcommands */ + foreach(parsetree_item, stmt_list) + { + Node *stmt = ((RawStmt *) lfirst(parsetree_item))->stmt; + PlannedStmt *wrapper; + + /* need to make a wrapper PlannedStmt */ + wrapper = makeNode(PlannedStmt); + wrapper->commandType = CMD_UTILITY; + wrapper->canSetTag = false; + wrapper->utilityStmt = stmt; + wrapper->stmt_location = 0; + wrapper->stmt_len = 0; + + /* do this step */ + ProcessUtility(wrapper, + CREATE_FIXED_DB_ROLES, + false, + PROCESS_UTILITY_SUBCOMMAND, + NULL, + NULL, + None_Receiver, + NULL); + } + tuple = heap_getnext(tblscan, ForwardScanDirection); + } + + /* Cleanup. */ + table_endscan(tblscan); + table_close(namespace_rel, RowExclusiveLock); + pfree(dbname); + pfree(query.data); +} + +static void +rolname_same_as_db_rolname(char *rolname) +{ + if (OidIsValid(get_role_oid(rolname, true))) + { + ereport(ERROR, + (errcode(ERRCODE_DUPLICATE_OBJECT), + errmsg("role \"%s\" already exists. Please drop the role and restart upgrade.", rolname))); + } +} + +static void +create_db_roles_in_database(const char *dbname, List *parsetree_list) { Node *stmt; Oid save_userid; @@ -1272,14 +1415,25 @@ create_db_roles_if_not_exists(const char *dbname, List *parsetree_list) int i = 0; char *db_owner; char *db_accessadmin; + char *db_datareader; + char *db_datawriter; + int16 dbid = get_db_id(dbname); db_owner = get_db_owner_name(dbname); db_accessadmin = get_db_accessadmin_role_name(dbname); + db_datareader = get_db_datareader_name(dbname); + db_datawriter = get_db_datawriter_name(dbname); - if (OidIsValid(get_role_oid(db_accessadmin, true))) - ereport(ERROR, - (errcode(ERRCODE_DUPLICATE_OBJECT), - errmsg("role \"%s\" already exists. Please drop the role and restart upgrade.", db_accessadmin))); + /* Throws error if a role exists already with the same name as db role. */ + rolname_same_as_db_rolname(db_accessadmin); + rolname_same_as_db_rolname(db_datareader); + rolname_same_as_db_rolname(db_datawriter); + + stmt = parsetree_nth_stmt(parsetree_list, i++); + update_CreateRoleStmt(stmt, db_datareader, db_owner, NULL); + + stmt = parsetree_nth_stmt(parsetree_list, i++); + update_CreateRoleStmt(stmt, db_datawriter, db_owner, NULL); stmt = parsetree_nth_stmt(parsetree_list, i++); update_CreateRoleStmt(stmt, db_accessadmin, db_owner, NULL); @@ -1295,6 +1449,8 @@ create_db_roles_if_not_exists(const char *dbname, List *parsetree_list) SetConfigOption("createrole_self_grant", "inherit", PGC_USERSET, PGC_S_OVERRIDE); add_to_bbf_authid_user_ext(db_accessadmin, DB_ACCESSADMIN, dbname, NULL, NULL, true, true, false); + add_to_bbf_authid_user_ext(db_datareader, DB_DATAREADER, dbname, NULL, NULL, true, true, false); + add_to_bbf_authid_user_ext(db_datawriter, DB_DATAWRITER, dbname, NULL, NULL, true, true, false); foreach(parsetree_item, parsetree_list) { @@ -1326,12 +1482,16 @@ create_db_roles_if_not_exists(const char *dbname, List *parsetree_list) CommandCounterIncrement(); } + /* Grant permissions on all the schemas in a database to db_datareader/db_datawriter */ + grant_perms_to_dbreader_dbwriter(dbid, db_datareader, db_datawriter); } PG_FINALLY(); { SetUserIdAndSecContext(save_userid, save_sec_context); pfree(db_owner); pfree(db_accessadmin); + pfree(db_datareader); + pfree(db_datawriter); } PG_END_TRY(); } @@ -1373,6 +1533,8 @@ create_db_roles_during_upgrade(PG_FUNCTION_ARGS) initStringInfo(&query); + appendStringInfo(&query, "CREATE ROLE dummy ROLE dummy; "); + appendStringInfo(&query, "CREATE ROLE dummy ROLE dummy; "); appendStringInfo(&query, "CREATE ROLE dummy ROLE dummy; "); appendStringInfo(&query, "GRANT CREATE ON DATABASE dummy TO dummy; "); @@ -1394,7 +1556,7 @@ create_db_roles_during_upgrade(PG_FUNCTION_ARGS) db_name = TextDatumGetCString(datum); - create_db_roles_if_not_exists(db_name, parsetree_list); + create_db_roles_in_database(db_name, parsetree_list); pfree(db_name); } diff --git a/contrib/babelfishpg_tsql/src/multidb.c b/contrib/babelfishpg_tsql/src/multidb.c index cdff39ef7c..b2e230c20c 100644 --- a/contrib/babelfishpg_tsql/src/multidb.c +++ b/contrib/babelfishpg_tsql/src/multidb.c @@ -1419,6 +1419,43 @@ get_db_owner_oid(const char *dbname, bool missing_ok) return db_owner_oid; } +char * +get_db_datareader_name(const char *dbname) +{ + char *name = palloc0(MAX_BBF_NAMEDATALEND); + Assert(dbname != NULL); + + if (get_migration_mode() == SINGLE_DB && !IS_BBF_BUILT_IN_DB(dbname)) + { + snprintf(name, MAX_BBF_NAMEDATALEND, "%s", DB_DATAREADER); + } + else + { + snprintf(name, MAX_BBF_NAMEDATALEND, "%s_%s", dbname, DB_DATAREADER); + truncate_identifier(name, strlen(name), false); + } + return name; +} + +char * +get_db_datawriter_name(const char *dbname) +{ + char *name = palloc0(MAX_BBF_NAMEDATALEND); + + Assert(dbname != NULL); + + if (get_migration_mode() == SINGLE_DB && !IS_BBF_BUILT_IN_DB(dbname)) + { + snprintf(name, MAX_BBF_NAMEDATALEND, "%s", DB_DATAWRITER); + } + else + { + snprintf(name, MAX_BBF_NAMEDATALEND, "%s_%s", dbname, DB_DATAWRITER); + truncate_identifier(name, strlen(name), false); + } + return name; +} + char * get_guest_role_name(const char *dbname) { @@ -1440,7 +1477,7 @@ get_db_accessadmin_role_name(const char *dbname) { char *name = palloc0(MAX_BBF_NAMEDATALEND); - Assert(dbname != NULL && strlen(dbname) != 0); + Assert(dbname != NULL); if (get_migration_mode() == SINGLE_DB && !IS_BBF_BUILT_IN_DB(dbname)) snprintf(name, MAX_BBF_NAMEDATALEND, "%s", DB_ACCESSADMIN); diff --git a/contrib/babelfishpg_tsql/src/multidb.h b/contrib/babelfishpg_tsql/src/multidb.h index 196ed8db76..f42f51e9fc 100644 --- a/contrib/babelfishpg_tsql/src/multidb.h +++ b/contrib/babelfishpg_tsql/src/multidb.h @@ -30,6 +30,8 @@ extern char *get_db_accessadmin_role_name(const char *dbname); extern Oid get_db_accessadmin_oid(const char *dbname, bool missing_ok); extern char *get_guest_role_name(const char *dbname); extern char *get_guest_schema_name(const char *dbname); +extern char *get_db_datareader_name(const char *dbname); +extern char *get_db_datawriter_name(const char *dbname); extern bool is_shared_schema(const char *name); extern void truncate_tsql_identifier(char *ident); extern bool physical_schema_name_exists(char *phys_schema_name); diff --git a/contrib/babelfishpg_tsql/src/pl_handler.c b/contrib/babelfishpg_tsql/src/pl_handler.c index 6cadde601c..42e14fcbdc 100644 --- a/contrib/babelfishpg_tsql/src/pl_handler.c +++ b/contrib/babelfishpg_tsql/src/pl_handler.c @@ -3816,6 +3816,14 @@ bbf_ProcessUtility(PlannedStmt *pstmt, } PG_END_TRY(); } + /* Execute subcommands for database roles.*/ + if (strcmp(queryString, CREATE_GUEST_SCHEMAS_DURING_UPGRADE) != 0) + { + if (rolspec) + exec_database_roles_subcmds(create_schema->schemaname, rolspec->rolename); + else + exec_database_roles_subcmds(create_schema->schemaname, NULL); + } /* Grant ALL schema privileges to the user.*/ if (rolspec && strcmp(queryString, CREATE_LOGICAL_DATABASE) != 0) @@ -4301,16 +4309,19 @@ bbf_ProcessUtility(PlannedStmt *pstmt, } case T_GrantStmt: { - GrantStmt *grant = (GrantStmt *) parsetree; - char *dbname = get_cur_db_name(); - const char *current_user = GetUserNameFromId(GetUserId(), false); + GrantStmt *grant = (GrantStmt *) parsetree; + char *dbname = get_cur_db_name(); + char *db_datareader = get_db_datareader_name(dbname); + char *db_datawriter = get_db_datawriter_name(dbname); + char *db_accessadmin = get_db_accessadmin_role_name(dbname); + /* Ignore when GRANT statement has no specific named object. */ if (sql_dialect != SQL_DIALECT_TSQL || grant->targtype != ACL_TARGET_OBJECT) break; Assert(list_length(grant->objects) == 1); if (grant->objtype == OBJECT_SCHEMA) break; - else if (grant->objtype == OBJECT_TABLE && strcmp(CREATE_LOGICAL_DATABASE, queryString) != 0) + else if (grant->objtype == OBJECT_TABLE && strcmp(CREATE_LOGICAL_DATABASE, queryString) != 0 && strcmp(queryString, CREATE_FIXED_DB_ROLES) != 0) { /* * Ignore GRANT statements that are executed implicitly as a part of @@ -4319,6 +4330,7 @@ bbf_ProcessUtility(PlannedStmt *pstmt, * schema permission or adding catalog entry. */ RangeVar *rv = (RangeVar *) linitial(grant->objects); + const char *current_user = GetUserNameFromId(GetUserId(), false); const char *logical_schema = NULL; char *obj = rv->relname; bool exec_pg_command = false; @@ -4337,6 +4349,8 @@ bbf_ProcessUtility(PlannedStmt *pstmt, foreach(lc, grant->grantees) { RoleSpec *rol_spec = (RoleSpec *) lfirst(lc); + /* Special database roles should throw an error. */ + throw_error_for_fixed_db_role(rol_spec->rolename, dbname); add_or_update_object_in_bbf_schema(logical_schema, obj, ALL_PERMISSIONS_ON_RELATION, rol_spec->rolename, OBJ_RELATION, true, NULL); } } @@ -4345,6 +4359,8 @@ bbf_ProcessUtility(PlannedStmt *pstmt, foreach(lc, grant->grantees) { RoleSpec *rol_spec = (RoleSpec *) lfirst(lc); + /* Special database roles should throw an error. */ + throw_error_for_fixed_db_role(rol_spec->rolename, dbname); /* * 1. If permission on schema exists, don't revoke any permission from the object. * 2. If permission on object exists, update the privilege in the catalog and revoke permission. @@ -4369,6 +4385,8 @@ bbf_ProcessUtility(PlannedStmt *pstmt, foreach(lc, grant->grantees) { RoleSpec *rol_spec = (RoleSpec *) lfirst(lc); + /* Special database roles should throw an error. */ + throw_error_for_fixed_db_role(rol_spec->rolename, dbname); add_or_update_object_in_bbf_schema(logical_schema, obj, privilege, rol_spec->rolename, OBJ_RELATION, true, NULL); } } @@ -4381,6 +4399,8 @@ bbf_ProcessUtility(PlannedStmt *pstmt, foreach(lc, grant->grantees) { RoleSpec *rol_spec = (RoleSpec *) lfirst(lc); + /* Special database roles should throw an error. */ + throw_error_for_fixed_db_role(rol_spec->rolename, dbname); /* * If permission on schema exists, don't revoke any permission from the object. */ @@ -4399,6 +4419,7 @@ bbf_ProcessUtility(PlannedStmt *pstmt, else if ((grant->objtype == OBJECT_PROCEDURE) || (grant->objtype == OBJECT_FUNCTION)) { ObjectWithArgs *ob = (ObjectWithArgs *) linitial(grant->objects); + const char *current_user = GetUserNameFromId(GetUserId(), false); ListCell *lc; ListCell *lc1; bool exec_pg_command = false; @@ -4449,6 +4470,8 @@ bbf_ProcessUtility(PlannedStmt *pstmt, foreach(lc, grant->grantees) { RoleSpec *rol_spec = (RoleSpec *) lfirst(lc); + /* Special database roles should throw an error. */ + throw_error_for_fixed_db_role(rol_spec->rolename, dbname); add_or_update_object_in_bbf_schema(logicalschema, funcname, ALL_PERMISSIONS_ON_FUNCTION, rol_spec->rolename, obj_type, true, func_args); } } @@ -4457,6 +4480,8 @@ bbf_ProcessUtility(PlannedStmt *pstmt, foreach(lc, grant->grantees) { RoleSpec *rol_spec = (RoleSpec *) lfirst(lc); + /* Special database roles should throw an error. */ + throw_error_for_fixed_db_role(rol_spec->rolename, dbname); /* * 1. If permission on schema exists, don't revoke any permission from the object. * 2. If permission on object exists, update the privilege in the catalog and revoke permission. @@ -4475,7 +4500,7 @@ bbf_ProcessUtility(PlannedStmt *pstmt, if (grant->is_grant) { exec_pg_command = true; - if (strcmp("(GRANT STATEMENT )", queryString) != 0) + if (strcmp(INTERNAL_GRANT_STATEMENT, queryString) != 0) { /* * If it is an implicit GRANT issued by exec_internal_grant_on_function, then we should not add catalog @@ -4484,6 +4509,8 @@ bbf_ProcessUtility(PlannedStmt *pstmt, foreach(lc, grant->grantees) { RoleSpec *rol_spec = (RoleSpec *) lfirst(lc); + /* Special database roles should throw an error. */ + throw_error_for_fixed_db_role(rol_spec->rolename, dbname); add_or_update_object_in_bbf_schema(logicalschema, funcname, privilege, rol_spec->rolename, obj_type, true, func_args); } } @@ -4493,7 +4520,8 @@ bbf_ProcessUtility(PlannedStmt *pstmt, foreach(lc, grant->grantees) { RoleSpec *rol_spec = (RoleSpec *) lfirst(lc); - + /* Special database roles should throw an error. */ + throw_error_for_fixed_db_role(rol_spec->rolename, dbname); /* * If permission on schema exists, don't revoke any permission from the object. */ @@ -4508,6 +4536,10 @@ bbf_ProcessUtility(PlannedStmt *pstmt, call_prev_ProcessUtility(pstmt, queryString, readOnlyTree, context, params, queryEnv, dest, qc); return; } + pfree(db_datareader); + pfree(db_datawriter); + pfree(db_accessadmin); + pfree(dbname); } default: break; diff --git a/contrib/babelfishpg_tsql/src/pltsql.h b/contrib/babelfishpg_tsql/src/pltsql.h index f9d2b6a9e1..b4a4d44b11 100644 --- a/contrib/babelfishpg_tsql/src/pltsql.h +++ b/contrib/babelfishpg_tsql/src/pltsql.h @@ -1986,11 +1986,15 @@ extern bool insert_bulk_check_constraints; #define CREATE_LOGICAL_DATABASE "(CREATE LOGICAL DATABASE )" #define CREATE_GUEST_SCHEMAS_DURING_UPGRADE "(CREATE GUEST SCHEMAS DURING UPGRADE )" #define CREATE_FIXED_DB_ROLES "(CREATE FIXED DATABASE ROLES )" +#define ALTER_DEFAULT_PRIVILEGES "(ALTER DEFAULT PRIVILEGES )" +#define INTERNAL_GRANT_STATEMENT "(GRANT STATEMENT )" /* FIXED DB PRINCIPALS */ #define DBO "dbo" #define DB_OWNER "db_owner" #define DB_ACCESSADMIN "db_accessadmin" +#define DB_DATAREADER "db_datareader" +#define DB_DATAWRITER "db_datawriter" #define IS_BBF_BUILT_IN_DB(dbname) \ (strncmp(dbname, "master", 6) == 0 || \ @@ -1998,9 +2002,11 @@ extern bool insert_bulk_check_constraints; strncmp(dbname, "msdb", 4) == 0) #define IS_FIXED_DB_PRINCIPAL(rolname) \ - (strncmp(rolname, DBO, 3) == 0 || \ - strncmp(rolname, DB_OWNER, 8) == 0 || \ - strncmp(rolname, DB_ACCESSADMIN, 14) == 0) + (strncmp(rolname, DBO, 3) == 0 || \ + strncmp(rolname, DB_OWNER, 8) == 0 || \ + strncmp(rolname, DB_ACCESSADMIN, 14) == 0 || \ + strncmp(rolname, DB_DATAREADER, 13) == 0 || \ + strncmp(rolname, DB_DATAWRITER, 13) == 0) /********************************************************************** * Function declarations @@ -2084,6 +2090,7 @@ extern char *get_original_query_string(void); extern AclMode string_to_privilege(const char *privname); extern const char *privilege_to_string(AclMode privilege); extern Oid get_owner_of_schema(const char *schema); +extern void exec_database_roles_subcmds(const char *physical_schema, char *schema_owner); /* * Functions for namespace handling in pl_funcs.c @@ -2198,6 +2205,7 @@ extern void update_ViewStmt(Node *n, const char *view_schema); extern void update_AlterDefaultPrivilegesStmt(Node *n, const char *schema, const char *role1, const char *role2, const char *grantee, const char *priv); extern AccessPriv *make_accesspriv_node(const char *priv_name); extern RoleSpec *make_rolespec_node(const char *rolename); +extern void throw_error_for_fixed_db_role(char *rolname, char *dbname); extern void pltsql_check_or_set_default_typmod_helper(TypeName *typeName, int32 *typmod, bool is_cast, bool is_procedure_or_func); extern void pltsql_check_or_set_default_typmod(TypeName *typeName, int32 *typmod, bool is_cast); extern bool TryLockLogicalDatabaseForSession(int16 dbid, LOCKMODE lockmode); diff --git a/contrib/babelfishpg_tsql/src/pltsql_utils.c b/contrib/babelfishpg_tsql/src/pltsql_utils.c index 5265477e72..7890a0f286 100644 --- a/contrib/babelfishpg_tsql/src/pltsql_utils.c +++ b/contrib/babelfishpg_tsql/src/pltsql_utils.c @@ -30,6 +30,7 @@ #include "multidb.h" #include "session.h" +#include "rolecmds.h" common_utility_plugin *common_utility_plugin_ptr = NULL; @@ -1140,7 +1141,7 @@ update_AlterDefaultPrivilegesStmt(Node *n, const char *schema, const char *role1 if (!IsA(stmt, AlterDefaultPrivilegesStmt)) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("query is not a AlterDefaultPrivilegesStmt"))); - if (grantee && priv && stmt->action) + if (grantee && stmt->action) { update_GrantStmt((Node *)(stmt->action), NULL, NULL, grantee, priv); } @@ -2509,3 +2510,111 @@ get_owner_of_schema(const char *schema) return result; } + +/* + * exec_database_roles_subcmds: + * Alter default privileges on all the objects in a schema to the db_datareader/db_datareader while creating a schema. + */ +void +exec_database_roles_subcmds(const char *schema, char *schema_owner) +{ + StringInfoData query; + char *db_datareader; + char *db_datawriter; + char *dbo_role; + char *db_owner; + const char *dbname = get_cur_db_name(); + List *stmt_list; + int expected_stmts = 2; + ListCell *parsetree_item; + Node *stmts; + int i=0; + Oid save_userid; + int save_sec_context; + + db_datareader = get_db_datareader_name(dbname); + db_datawriter = get_db_datawriter_name(dbname); + dbo_role = get_dbo_role_name(dbname); + db_owner = get_db_owner_name(dbname); + + GetUserIdAndSecContext(&save_userid, &save_sec_context); + + /* If schema owner is not the dbo/db_owner role. */ + if (schema_owner && strcmp(schema_owner, dbo_role) != 0 && strcmp(schema_owner, db_owner) != 0) + { + // do nothing + } + else + { + schema_owner = GetUserNameFromId(get_owner_of_schema(schema), false); + } + + initStringInfo(&query); + + appendStringInfo(&query, "ALTER DEFAULT PRIVILEGES FOR ROLE dummy, dummy IN SCHEMA dummy GRANT SELECT ON TABLES TO dummy; "); + appendStringInfo(&query, "ALTER DEFAULT PRIVILEGES FOR ROLE dummy, dummy IN SCHEMA dummy GRANT INSERT, UPDATE, DELETE ON TABLES TO dummy; "); + + stmt_list = raw_parser(query.data, RAW_PARSE_DEFAULT); + if (list_length(stmt_list) != expected_stmts) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("Expected %d statements, but got %d statements after parsing", + expected_stmts, list_length(stmt_list)))); + + stmts = parsetree_nth_stmt(stmt_list, i++); + update_AlterDefaultPrivilegesStmt(stmts, schema, schema_owner, dbo_role, db_datareader, NULL); + + stmts = parsetree_nth_stmt(stmt_list, i++); + update_AlterDefaultPrivilegesStmt(stmts, schema, schema_owner, dbo_role, db_datawriter, NULL); + + PG_TRY(); + { + SetUserIdAndSecContext(get_bbf_role_admin_oid(), save_sec_context | SECURITY_LOCAL_USERID_CHANGE); + /* Run all subcommands */ + foreach(parsetree_item, stmt_list) + { + Node *stmt = ((RawStmt *) lfirst(parsetree_item))->stmt; + PlannedStmt *wrapper; + + /* need to make a wrapper PlannedStmt */ + wrapper = makeNode(PlannedStmt); + wrapper->commandType = CMD_UTILITY; + wrapper->canSetTag = false; + wrapper->utilityStmt = stmt; + wrapper->stmt_location = 0; + wrapper->stmt_len = 0; + + /* do this step */ + ProcessUtility(wrapper, + ALTER_DEFAULT_PRIVILEGES, + false, + PROCESS_UTILITY_SUBCOMMAND, + NULL, + NULL, + None_Receiver, + NULL); + } + CommandCounterIncrement(); + } + PG_FINALLY(); + { + SetUserIdAndSecContext(save_userid, save_sec_context); + pfree(db_datareader); + pfree(db_datawriter); + pfree(dbo_role); + pfree(db_owner); + } + PG_END_TRY(); + pfree(query.data); +} + +void +throw_error_for_fixed_db_role(char *rolname, char *dbname) +{ + if (rolname != NULL && + IS_FIXED_DB_PRINCIPAL(get_authid_user_ext_original_name(rolname, dbname))) + { + ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("Cannot grant, deny or revoke permissions to or from special roles."))); + } +} \ No newline at end of file diff --git a/contrib/babelfishpg_tsql/src/rolecmds.c b/contrib/babelfishpg_tsql/src/rolecmds.c index 9f418d44ec..38edb03db6 100644 --- a/contrib/babelfishpg_tsql/src/rolecmds.c +++ b/contrib/babelfishpg_tsql/src/rolecmds.c @@ -952,7 +952,6 @@ get_original_login_name(char *login) return result; } - PG_FUNCTION_INFO_V1(suser_name); Datum suser_name(PG_FUNCTION_ARGS) diff --git a/test/JDBC/expected/1_GRANT_SCHEMA-vu-verify.out b/test/JDBC/expected/1_GRANT_SCHEMA-vu-verify.out index 06dd2ef585..66f5a44ea2 100644 --- a/test/JDBC/expected/1_GRANT_SCHEMA-vu-verify.out +++ b/test/JDBC/expected/1_GRANT_SCHEMA-vu-verify.out @@ -95,20 +95,6 @@ dbo#!#babel_4768_v1_new#!#2#!#master_babel_4768_u1#!#r#!# ~~END~~ --- psql --- This is needed so that MVU passes -DO $$ -BEGIN - IF EXISTS (SELECT 1 FROM -information_schema.tables WHERE -table_name = 'tbl_creation_should_succeed' AND -table_schema = 'master_dbo') THEN - EXECUTE 'GRANT ALL ON -master_dbo.tbl_creation_should_succeed TO master_dbo'; - END IF; -END $$; -GO - -- tsql REVOKE SELECT, EXECUTE ON SCHEMA::dbo FROM babel_4768_u1 GO diff --git a/test/JDBC/expected/BABEL-2403.out b/test/JDBC/expected/BABEL-2403.out index 9039d7ce19..18a6f78786 100644 --- a/test/JDBC/expected/BABEL-2403.out +++ b/test/JDBC/expected/BABEL-2403.out @@ -107,6 +107,18 @@ name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_user_ext m text#!#sys#!#name#!#{"Rule": " in babelfish_authid_user_ext must also exist in babelfish_sysdatabases"} name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_user_ext must also exist in pg_authid"} text#!#sys#!#name#!#{"Rule": " in babelfish_authid_user_ext must also exist in babelfish_sysdatabases"} +name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_user_ext must also exist in pg_authid"} +text#!#sys#!#name#!#{"Rule": " in babelfish_authid_user_ext must also exist in babelfish_sysdatabases"} +name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_user_ext must also exist in pg_authid"} +text#!#sys#!#name#!#{"Rule": " in babelfish_authid_user_ext must also exist in babelfish_sysdatabases"} +name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_user_ext must also exist in pg_authid"} +text#!#sys#!#name#!#{"Rule": " in babelfish_authid_user_ext must also exist in babelfish_sysdatabases"} +name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_user_ext must also exist in pg_authid"} +text#!#sys#!#name#!#{"Rule": " in babelfish_authid_user_ext must also exist in babelfish_sysdatabases"} +name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_user_ext must also exist in pg_authid"} +text#!#sys#!#name#!#{"Rule": " in babelfish_authid_user_ext must also exist in babelfish_sysdatabases"} +name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_user_ext must also exist in pg_authid"} +text#!#sys#!#name#!#{"Rule": " in babelfish_authid_user_ext must also exist in babelfish_sysdatabases"} name#!#sys#!#nspname#!#{"Rule": " in babelfish_function_ext must also exist in babelfish_namespace_ext"} name#!#pg_catalog#!#proname#!#{"Rule": " in babelfish_function_ext must also exist in pg_proc"} name#!#sys#!#nspname#!#{"Rule": " in babelfish_function_ext must also exist in babelfish_namespace_ext"} @@ -204,6 +216,18 @@ name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_user_ext m text#!#sys#!#name#!#{"Rule": " in babelfish_authid_user_ext must also exist in babelfish_sysdatabases"} name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_user_ext must also exist in pg_authid"} text#!#sys#!#name#!#{"Rule": " in babelfish_authid_user_ext must also exist in babelfish_sysdatabases"} +name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_user_ext must also exist in pg_authid"} +text#!#sys#!#name#!#{"Rule": " in babelfish_authid_user_ext must also exist in babelfish_sysdatabases"} +name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_user_ext must also exist in pg_authid"} +text#!#sys#!#name#!#{"Rule": " in babelfish_authid_user_ext must also exist in babelfish_sysdatabases"} +name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_user_ext must also exist in pg_authid"} +text#!#sys#!#name#!#{"Rule": " in babelfish_authid_user_ext must also exist in babelfish_sysdatabases"} +name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_user_ext must also exist in pg_authid"} +text#!#sys#!#name#!#{"Rule": " in babelfish_authid_user_ext must also exist in babelfish_sysdatabases"} +name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_user_ext must also exist in pg_authid"} +text#!#sys#!#name#!#{"Rule": " in babelfish_authid_user_ext must also exist in babelfish_sysdatabases"} +name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_user_ext must also exist in pg_authid"} +text#!#sys#!#name#!#{"Rule": " in babelfish_authid_user_ext must also exist in babelfish_sysdatabases"} name#!#sys#!#nspname#!#{"Rule": " in babelfish_function_ext must also exist in babelfish_namespace_ext"} name#!#pg_catalog#!#proname#!#{"Rule": " in babelfish_function_ext must also exist in pg_proc"} name#!#sys#!#nspname#!#{"Rule": " in babelfish_function_ext must also exist in babelfish_namespace_ext"} diff --git a/test/JDBC/expected/BABEL-3637.out b/test/JDBC/expected/BABEL-3637.out index 2b35c6b271..2ab8d103c9 100644 --- a/test/JDBC/expected/BABEL-3637.out +++ b/test/JDBC/expected/BABEL-3637.out @@ -549,5 +549,9 @@ GO -- tsql USE master GO +DROP PROC test_babel_3637_proc1; +GO +DROP PROC test_babel_3637_proc2; +GO DROP DATABASE babel_3637_db; GO diff --git a/test/JDBC/expected/BABEL-CHECK-CONSTRAINT-vu-prepare.out b/test/JDBC/expected/BABEL-CHECK-CONSTRAINT-vu-prepare.out index 580b467101..713fc05d13 100644 --- a/test/JDBC/expected/BABEL-CHECK-CONSTRAINT-vu-prepare.out +++ b/test/JDBC/expected/BABEL-CHECK-CONSTRAINT-vu-prepare.out @@ -46,3 +46,17 @@ CREATE TABLE master_dbo.tbl_creation_should_succeed ( AND ((a)::text < ('11'::text || '￿'::text COLLATE sys.bbf_unicode_cp1_ci_as)))))) ); GO + +-- psql +-- This is needed so that MVU passes +DO $$ +BEGIN + IF EXISTS (SELECT 1 FROM +information_schema.tables WHERE +table_name = 'tbl_creation_should_succeed' AND +table_schema = 'master_dbo') THEN + EXECUTE 'GRANT ALL ON +master_dbo.tbl_creation_should_succeed TO master_dbo'; + END IF; +END $$; +GO diff --git a/test/JDBC/expected/BABEL-LOGIN-USER-EXT.out b/test/JDBC/expected/BABEL-LOGIN-USER-EXT.out index 70d0b5e77b..4780d8a897 100644 --- a/test/JDBC/expected/BABEL-LOGIN-USER-EXT.out +++ b/test/JDBC/expected/BABEL-LOGIN-USER-EXT.out @@ -695,18 +695,26 @@ GO ~~START~~ varchar#!#nvarchar#!#varchar#!#nvarchar#!#nvarchar db1_db_accessadmin#!#db_accessadmin#!##!#db1#!# +db1_db_datareader#!#db_datareader#!##!#db1#!# +db1_db_datawriter#!#db_datawriter#!##!#db1#!# db1_db_owner#!#db_owner#!##!#db1#!# db1_dbo#!#dbo#!##!#db1#!#dbo db1_guest#!#guest#!##!#db1#!#guest master_db_accessadmin#!#db_accessadmin#!##!#master#!# +master_db_datareader#!#db_datareader#!##!#master#!# +master_db_datawriter#!#db_datawriter#!##!#master#!# master_db_owner#!#db_owner#!##!#master#!# master_dbo#!#dbo#!##!#master#!#dbo master_guest#!#guest#!##!#master#!#guest msdb_db_accessadmin#!#db_accessadmin#!##!#msdb#!# +msdb_db_datareader#!#db_datareader#!##!#msdb#!# +msdb_db_datawriter#!#db_datawriter#!##!#msdb#!# msdb_db_owner#!#db_owner#!##!#msdb#!# msdb_dbo#!#dbo#!##!#msdb#!#dbo msdb_guest#!#guest#!##!#msdb#!#guest tempdb_db_accessadmin#!#db_accessadmin#!##!#tempdb#!# +tempdb_db_datareader#!#db_datareader#!##!#tempdb#!# +tempdb_db_datawriter#!#db_datawriter#!##!#tempdb#!# tempdb_db_owner#!#db_owner#!##!#tempdb#!# tempdb_dbo#!#dbo#!##!#tempdb#!#dbo tempdb_guest#!#guest#!##!#tempdb#!#guest @@ -872,14 +880,20 @@ GO ~~START~~ varchar#!#nvarchar#!#varchar#!#nvarchar#!#nvarchar master_db_accessadmin#!#db_accessadmin#!##!#master#!# +master_db_datareader#!#db_datareader#!##!#master#!# +master_db_datawriter#!#db_datawriter#!##!#master#!# master_db_owner#!#db_owner#!##!#master#!# master_dbo#!#dbo#!##!#master#!#dbo master_guest#!#guest#!##!#master#!#guest msdb_db_accessadmin#!#db_accessadmin#!##!#msdb#!# +msdb_db_datareader#!#db_datareader#!##!#msdb#!# +msdb_db_datawriter#!#db_datawriter#!##!#msdb#!# msdb_db_owner#!#db_owner#!##!#msdb#!# msdb_dbo#!#dbo#!##!#msdb#!#dbo msdb_guest#!#guest#!##!#msdb#!#guest tempdb_db_accessadmin#!#db_accessadmin#!##!#tempdb#!# +tempdb_db_datareader#!#db_datareader#!##!#tempdb#!# +tempdb_db_datawriter#!#db_datawriter#!##!#tempdb#!# tempdb_db_owner#!#db_owner#!##!#tempdb#!# tempdb_dbo#!#dbo#!##!#tempdb#!#dbo tempdb_guest#!#guest#!##!#tempdb#!#guest @@ -926,22 +940,32 @@ GO ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar#!#nvarchar db1_db_accessadmin#!##!#db_accessadmin#!#db1#!# +db1_db_datareader#!##!#db_datareader#!#db1#!# +db1_db_datawriter#!##!#db_datawriter#!#db1#!# db1_db_owner#!##!#db_owner#!#db1#!# db1_dbo#!##!#dbo#!#db1#!#dbo db1_guest#!##!#guest#!#db1#!#guest db2_db_accessadmin#!##!#db_accessadmin#!#db2#!# +db2_db_datareader#!##!#db_datareader#!#db2#!# +db2_db_datawriter#!##!#db_datawriter#!#db2#!# db2_db_owner#!##!#db_owner#!#db2#!# db2_dbo#!##!#dbo#!#db2#!#dbo db2_guest#!##!#guest#!#db2#!#guest master_db_accessadmin#!##!#db_accessadmin#!#master#!# +master_db_datareader#!##!#db_datareader#!#master#!# +master_db_datawriter#!##!#db_datawriter#!#master#!# master_db_owner#!##!#db_owner#!#master#!# master_dbo#!##!#dbo#!#master#!#dbo master_guest#!##!#guest#!#master#!#guest msdb_db_accessadmin#!##!#db_accessadmin#!#msdb#!# +msdb_db_datareader#!##!#db_datareader#!#msdb#!# +msdb_db_datawriter#!##!#db_datawriter#!#msdb#!# msdb_db_owner#!##!#db_owner#!#msdb#!# msdb_dbo#!##!#dbo#!#msdb#!#dbo msdb_guest#!##!#guest#!#msdb#!#guest tempdb_db_accessadmin#!##!#db_accessadmin#!#tempdb#!# +tempdb_db_datareader#!##!#db_datareader#!#tempdb#!# +tempdb_db_datawriter#!##!#db_datawriter#!#tempdb#!# tempdb_db_owner#!##!#db_owner#!#tempdb#!# tempdb_dbo#!##!#dbo#!#tempdb#!#dbo tempdb_guest#!##!#guest#!#tempdb#!#guest @@ -957,6 +981,8 @@ varchar#!#varchar guest#!#guest dbo#!#dbo db_accessadmin#!# +db_datareader#!# +db_datawriter#!# db_owner#!# INFORMATION_SCHEMA#!# public#!# @@ -990,6 +1016,8 @@ varchar#!#varchar guest#!#guest dbo#!#dbo db_accessadmin#!# +db_datareader#!# +db_datawriter#!# db_owner#!# INFORMATION_SCHEMA#!# public#!# @@ -1125,18 +1153,26 @@ GO ~~START~~ varchar#!#nvarchar#!#varchar#!#nvarchar#!#nvarchar db2_db_accessadmin#!#db_accessadmin#!##!#db2#!# +db2_db_datareader#!#db_datareader#!##!#db2#!# +db2_db_datawriter#!#db_datawriter#!##!#db2#!# db2_db_owner#!#db_owner#!##!#db2#!# db2_dbo#!#dbo#!##!#db2#!#dbo db2_guest#!#guest#!##!#db2#!#guest master_db_accessadmin#!#db_accessadmin#!##!#master#!# +master_db_datareader#!#db_datareader#!##!#master#!# +master_db_datawriter#!#db_datawriter#!##!#master#!# master_db_owner#!#db_owner#!##!#master#!# master_dbo#!#dbo#!##!#master#!#dbo master_guest#!#guest#!##!#master#!#guest msdb_db_accessadmin#!#db_accessadmin#!##!#msdb#!# +msdb_db_datareader#!#db_datareader#!##!#msdb#!# +msdb_db_datawriter#!#db_datawriter#!##!#msdb#!# msdb_db_owner#!#db_owner#!##!#msdb#!# msdb_dbo#!#dbo#!##!#msdb#!#dbo msdb_guest#!#guest#!##!#msdb#!#guest tempdb_db_accessadmin#!#db_accessadmin#!##!#tempdb#!# +tempdb_db_datareader#!#db_datareader#!##!#tempdb#!# +tempdb_db_datawriter#!#db_datawriter#!##!#tempdb#!# tempdb_db_owner#!#db_owner#!##!#tempdb#!# tempdb_dbo#!#dbo#!##!#tempdb#!#dbo tempdb_guest#!#guest#!##!#tempdb#!#guest @@ -1153,14 +1189,20 @@ GO ~~START~~ varchar#!#nvarchar#!#varchar#!#nvarchar#!#nvarchar master_db_accessadmin#!#db_accessadmin#!##!#master#!# +master_db_datareader#!#db_datareader#!##!#master#!# +master_db_datawriter#!#db_datawriter#!##!#master#!# master_db_owner#!#db_owner#!##!#master#!# master_dbo#!#dbo#!##!#master#!#dbo master_guest#!#guest#!##!#master#!#guest msdb_db_accessadmin#!#db_accessadmin#!##!#msdb#!# +msdb_db_datareader#!#db_datareader#!##!#msdb#!# +msdb_db_datawriter#!#db_datawriter#!##!#msdb#!# msdb_db_owner#!#db_owner#!##!#msdb#!# msdb_dbo#!#dbo#!##!#msdb#!#dbo msdb_guest#!#guest#!##!#msdb#!#guest tempdb_db_accessadmin#!#db_accessadmin#!##!#tempdb#!# +tempdb_db_datareader#!#db_datareader#!##!#tempdb#!# +tempdb_db_datawriter#!#db_datawriter#!##!#tempdb#!# tempdb_db_owner#!#db_owner#!##!#tempdb#!# tempdb_dbo#!#dbo#!##!#tempdb#!#dbo tempdb_guest#!#guest#!##!#tempdb#!#guest @@ -1434,6 +1476,8 @@ varchar babel_4935_no_sysadmin1 babel_4935_no_sysadmin2 db_accessadmin +db_datareader +db_datawriter db_owner dbo guest @@ -1452,6 +1496,8 @@ varchar babel_4935_no_sysadmin1 babel_4935_no_sysadmin2 db_accessadmin +db_datareader +db_datawriter db_owner dbo guest @@ -1469,6 +1515,8 @@ GO varchar babel_4935_no_sysadmin1 db_accessadmin +db_datareader +db_datawriter db_owner dbo guest @@ -1485,6 +1533,8 @@ GO ~~START~~ varchar db_accessadmin +db_datareader +db_datawriter db_owner dbo guest diff --git a/test/JDBC/expected/BABEL-USER.out b/test/JDBC/expected/BABEL-USER.out index 6a9646102c..ba9aa1de6e 100644 --- a/test/JDBC/expected/BABEL-USER.out +++ b/test/JDBC/expected/BABEL-USER.out @@ -50,18 +50,26 @@ GO ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar#!#nvarchar db1_db_accessadmin#!##!#db_accessadmin#!#db1#!# +db1_db_datareader#!##!#db_datareader#!#db1#!# +db1_db_datawriter#!##!#db_datawriter#!#db1#!# db1_db_owner#!##!#db_owner#!#db1#!# db1_dbo#!##!#dbo#!#db1#!#dbo db1_guest#!##!#guest#!#db1#!#guest master_db_accessadmin#!##!#db_accessadmin#!#master#!# +master_db_datareader#!##!#db_datareader#!#master#!# +master_db_datawriter#!##!#db_datawriter#!#master#!# master_db_owner#!##!#db_owner#!#master#!# master_dbo#!##!#dbo#!#master#!#dbo master_guest#!##!#guest#!#master#!#guest msdb_db_accessadmin#!##!#db_accessadmin#!#msdb#!# +msdb_db_datareader#!##!#db_datareader#!#msdb#!# +msdb_db_datawriter#!##!#db_datawriter#!#msdb#!# msdb_db_owner#!##!#db_owner#!#msdb#!# msdb_dbo#!##!#dbo#!#msdb#!#dbo msdb_guest#!##!#guest#!#msdb#!#guest tempdb_db_accessadmin#!##!#db_accessadmin#!#tempdb#!# +tempdb_db_datareader#!##!#db_datareader#!#tempdb#!# +tempdb_db_datawriter#!##!#db_datawriter#!#tempdb#!# tempdb_db_owner#!##!#db_owner#!#tempdb#!# tempdb_dbo#!##!#dbo#!#tempdb#!#dbo tempdb_guest#!##!#guest#!#tempdb#!#guest @@ -77,6 +85,8 @@ varchar#!#varchar guest#!#guest dbo#!#dbo db_accessadmin#!# +db_datareader#!# +db_datawriter#!# db_owner#!# INFORMATION_SCHEMA#!# public#!# diff --git a/test/JDBC/expected/Test-sp_helpdbfixedrole-dep-vu-verify.out b/test/JDBC/expected/Test-sp_helpdbfixedrole-dep-vu-verify.out index 0d807bb979..3079345d3f 100644 --- a/test/JDBC/expected/Test-sp_helpdbfixedrole-dep-vu-verify.out +++ b/test/JDBC/expected/Test-sp_helpdbfixedrole-dep-vu-verify.out @@ -4,6 +4,8 @@ GO varchar#!#nvarchar db_owner#!#DB Owners db_accessadmin#!#DB Access Administrators +db_datareader#!#DB Data Reader +db_datawriter#!#DB Data Writer ~~END~~ @@ -19,7 +21,7 @@ SELECT dbo.test_sp_helpdbfixedrole_func() GO ~~START~~ int -2 +4 ~~END~~ @@ -27,7 +29,7 @@ SELECT * FROM test_sp_helpdbfixedrole_view GO ~~START~~ int -2 +4 ~~END~~ diff --git a/test/JDBC/expected/Test-sp_helpdbfixedrole-vu-verify.out b/test/JDBC/expected/Test-sp_helpdbfixedrole-vu-verify.out index 9c8bfa4e6b..5eee87026f 100644 --- a/test/JDBC/expected/Test-sp_helpdbfixedrole-vu-verify.out +++ b/test/JDBC/expected/Test-sp_helpdbfixedrole-vu-verify.out @@ -1,6 +1,6 @@ INSERT INTO test_sp_helpdbfixedrole_tbl (DbFixedRole, Description) EXEC sp_helpdbfixedrole GO -~~ROW COUNT: 2~~ +~~ROW COUNT: 4~~ SELECT DbFixedRole, Description FROM test_sp_helpdbfixedrole_tbl @@ -9,6 +9,8 @@ GO varchar#!#nvarchar db_owner#!#DB Owners db_accessadmin#!#DB Access Administrators +db_datareader#!#DB Data Reader +db_datawriter#!#DB Data Writer ~~END~~ @@ -59,8 +61,12 @@ INSERT INTO test_sp_helpdbfixedrole_tbl (DbFixedRole, Description) EXEC sp_helpd GO INSERT INTO test_sp_helpdbfixedrole_tbl (DbFixedRole, Description) EXEC sp_helpdbfixedrole 'db_datareader' GO +~~ROW COUNT: 1~~ + INSERT INTO test_sp_helpdbfixedrole_tbl (DbFixedRole, Description) EXEC sp_helpdbfixedrole 'db_datawriter' GO +~~ROW COUNT: 1~~ + INSERT INTO test_sp_helpdbfixedrole_tbl (DbFixedRole, Description) EXEC sp_helpdbfixedrole 'db_denydatareader' GO INSERT INTO test_sp_helpdbfixedrole_tbl (DbFixedRole, Description) EXEC sp_helpdbfixedrole 'db_denydatawriter' @@ -71,6 +77,8 @@ GO ~~START~~ varchar#!#nvarchar db_accessadmin#!#DB Access Administrators +db_datareader#!#DB Data Reader +db_datawriter#!#DB Data Writer ~~END~~ diff --git a/test/JDBC/expected/Test_alter_db_rename-vu-verify.out b/test/JDBC/expected/Test_alter_db_rename-vu-verify.out index 02c5571170..687dd6e3cc 100644 --- a/test/JDBC/expected/Test_alter_db_rename-vu-verify.out +++ b/test/JDBC/expected/Test_alter_db_rename-vu-verify.out @@ -20,6 +20,8 @@ rename_db_database1_rename_db_schema1#!#rename_db_schema1 ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar rename_db_database1_db_accessadmin#!##!#db_accessadmin#!#rename_db_database1 +rename_db_database1_db_datareader#!##!#db_datareader#!#rename_db_database1 +rename_db_database1_db_datawriter#!##!#db_datawriter#!#rename_db_database1 rename_db_database1_db_owner#!##!#db_owner#!#rename_db_database1 rename_db_database1_dbo#!##!#dbo#!#rename_db_database1 rename_db_database1_guest#!##!#guest#!#rename_db_database1 @@ -82,6 +84,8 @@ rename_db_database2_rename_db_schema1#!#rename_db_schema1 ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar rename_db_database2_db_accessadmin#!##!#db_accessadmin#!#rename_db_database2 +rename_db_database2_db_datareader#!##!#db_datareader#!#rename_db_database2 +rename_db_database2_db_datawriter#!##!#db_datawriter#!#rename_db_database2 rename_db_database2_db_owner#!##!#db_owner#!#rename_db_database2 rename_db_database2_dbo#!##!#dbo#!#rename_db_database2 rename_db_database2_guest#!##!#guest#!#rename_db_database2 @@ -192,8 +196,10 @@ thisnewdatabasenameiscasesensitc4313f9adf0e47cfa5aca25228e02f29#!#dbo varchar#!#varchar#!#nvarchar#!#nvarchar thisnewdatabasenameiscasesensit4e1f355d810759b9f1a59b04496ed2e1#!##!#guest#!#thisnewdatabasenameiscasesensit44f3247005ec268e1a10c736599cfb7e thisnewdatabasenameiscasesensit72e4dcc7ed25f5536033cf547cd7f001#!##!#db_owner#!#thisnewdatabasenameiscasesensit44f3247005ec268e1a10c736599cfb7e +thisnewdatabasenameiscasesensit7de06ed1a7bed768d6641b3e7841314c#!##!#db_datareader#!#thisnewdatabasenameiscasesensit44f3247005ec268e1a10c736599cfb7e thisnewdatabasenameiscasesensit944678472843354d6b3a4354630249a8#!##!#db_accessadmin#!#thisnewdatabasenameiscasesensit44f3247005ec268e1a10c736599cfb7e thisnewdatabasenameiscasesensitc4313f9adf0e47cfa5aca25228e02f29#!##!#dbo#!#thisnewdatabasenameiscasesensit44f3247005ec268e1a10c736599cfb7e +thisnewdatabasenameiscasesensitfa060d610d6e6cd0271b6ce99b258bcc#!##!#db_datawriter#!#thisnewdatabasenameiscasesensit44f3247005ec268e1a10c736599cfb7e ~~END~~ ~~START~~ diff --git a/test/JDBC/expected/Test_rename_db_single-db.out b/test/JDBC/expected/Test_rename_db_single-db.out index f1e8d609f7..541d359338 100644 --- a/test/JDBC/expected/Test_rename_db_single-db.out +++ b/test/JDBC/expected/Test_rename_db_single-db.out @@ -33,6 +33,8 @@ rename_db_database1_rename_db_schema1#!#rename_db_schema1 ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar rename_db_database1_db_accessadmin#!##!#db_accessadmin#!#rename_db_database1 +rename_db_database1_db_datareader#!##!#db_datareader#!#rename_db_database1 +rename_db_database1_db_datawriter#!##!#db_datawriter#!#rename_db_database1 rename_db_database1_db_owner#!##!#db_owner#!#rename_db_database1 rename_db_database1_dbo#!##!#dbo#!#rename_db_database1 rename_db_database1_guest#!##!#guest#!#rename_db_database1 @@ -82,6 +84,8 @@ rename_db_database2_rename_db_schema1#!#rename_db_schema1 ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar rename_db_database2_db_accessadmin#!##!#db_accessadmin#!#rename_db_database2 +rename_db_database2_db_datareader#!##!#db_datareader#!#rename_db_database2 +rename_db_database2_db_datawriter#!##!#db_datawriter#!#rename_db_database2 rename_db_database2_db_owner#!##!#db_owner#!#rename_db_database2 rename_db_database2_dbo#!##!#dbo#!#rename_db_database2 rename_db_database2_guest#!##!#guest#!#rename_db_database2 @@ -131,6 +135,8 @@ rename_db_database1_rename_db_schema1#!#rename_db_schema1 ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar rename_db_database1_db_accessadmin#!##!#db_accessadmin#!#rename_db_database1 +rename_db_database1_db_datareader#!##!#db_datareader#!#rename_db_database1 +rename_db_database1_db_datawriter#!##!#db_datawriter#!#rename_db_database1 rename_db_database1_db_owner#!##!#db_owner#!#rename_db_database1 rename_db_database1_dbo#!##!#dbo#!#rename_db_database1 rename_db_database1_guest#!##!#guest#!#rename_db_database1 @@ -180,6 +186,8 @@ rename_db_database2_rename_db_schema1#!#rename_db_schema1 ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar rename_db_database2_db_accessadmin#!##!#db_accessadmin#!#rename_db_database2 +rename_db_database2_db_datareader#!##!#db_datareader#!#rename_db_database2 +rename_db_database2_db_datawriter#!##!#db_datawriter#!#rename_db_database2 rename_db_database2_db_owner#!##!#db_owner#!#rename_db_database2 rename_db_database2_dbo#!##!#dbo#!#rename_db_database2 rename_db_database2_guest#!##!#guest#!#rename_db_database2 @@ -241,6 +249,8 @@ rename_db_database1_rename_db_schema1#!#rename_db_schema1 ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar rename_db_database1_db_accessadmin#!##!#db_accessadmin#!#rename_db_database1 +rename_db_database1_db_datareader#!##!#db_datareader#!#rename_db_database1 +rename_db_database1_db_datawriter#!##!#db_datawriter#!#rename_db_database1 rename_db_database1_db_owner#!##!#db_owner#!#rename_db_database1 rename_db_database1_dbo#!##!#dbo#!#rename_db_database1 rename_db_database1_guest#!##!#guest#!#rename_db_database1 @@ -290,6 +300,8 @@ rename_db_database2_rename_db_schema1#!#rename_db_schema1 ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar rename_db_database2_db_accessadmin#!##!#db_accessadmin#!#rename_db_database2 +rename_db_database2_db_datareader#!##!#db_datareader#!#rename_db_database2 +rename_db_database2_db_datawriter#!##!#db_datawriter#!#rename_db_database2 rename_db_database2_db_owner#!##!#db_owner#!#rename_db_database2 rename_db_database2_dbo#!##!#dbo#!#rename_db_database2 rename_db_database2_guest#!##!#guest#!#rename_db_database2 @@ -339,6 +351,8 @@ rename_db_database1_rename_db_schema1#!#rename_db_schema1 ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar rename_db_database1_db_accessadmin#!##!#db_accessadmin#!#rename_db_database1 +rename_db_database1_db_datareader#!##!#db_datareader#!#rename_db_database1 +rename_db_database1_db_datawriter#!##!#db_datawriter#!#rename_db_database1 rename_db_database1_db_owner#!##!#db_owner#!#rename_db_database1 rename_db_database1_dbo#!##!#dbo#!#rename_db_database1 rename_db_database1_guest#!##!#guest#!#rename_db_database1 @@ -388,6 +402,8 @@ rename_db_database2_rename_db_schema1#!#rename_db_schema1 ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar rename_db_database2_db_accessadmin#!##!#db_accessadmin#!#rename_db_database2 +rename_db_database2_db_datareader#!##!#db_datareader#!#rename_db_database2 +rename_db_database2_db_datawriter#!##!#db_datawriter#!#rename_db_database2 rename_db_database2_db_owner#!##!#db_owner#!#rename_db_database2 rename_db_database2_dbo#!##!#dbo#!#rename_db_database2 rename_db_database2_guest#!##!#guest#!#rename_db_database2 diff --git a/test/JDBC/expected/Test_sp_rename_database-vu-verify.out b/test/JDBC/expected/Test_sp_rename_database-vu-verify.out index b2cbeb5ef1..25ed3c274a 100644 --- a/test/JDBC/expected/Test_sp_rename_database-vu-verify.out +++ b/test/JDBC/expected/Test_sp_rename_database-vu-verify.out @@ -20,6 +20,8 @@ sp_rename_database1_sp_rename_schema1#!#sp_rename_schema1 ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar sp_rename_database1_db_accessadmin#!##!#db_accessadmin#!#sp_rename_database1 +sp_rename_database1_db_datareader#!##!#db_datareader#!#sp_rename_database1 +sp_rename_database1_db_datawriter#!##!#db_datawriter#!#sp_rename_database1 sp_rename_database1_db_owner#!##!#db_owner#!#sp_rename_database1 sp_rename_database1_dbo#!##!#dbo#!#sp_rename_database1 sp_rename_database1_guest#!##!#guest#!#sp_rename_database1 @@ -82,6 +84,8 @@ sp_rename_database2_sp_rename_schema1#!#sp_rename_schema1 ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar sp_rename_database2_db_accessadmin#!##!#db_accessadmin#!#sp_rename_database2 +sp_rename_database2_db_datareader#!##!#db_datareader#!#sp_rename_database2 +sp_rename_database2_db_datawriter#!##!#db_datawriter#!#sp_rename_database2 sp_rename_database2_db_owner#!##!#db_owner#!#sp_rename_database2 sp_rename_database2_dbo#!##!#dbo#!#sp_rename_database2 sp_rename_database2_guest#!##!#guest#!#sp_rename_database2 @@ -199,7 +203,9 @@ sp_rename_thisnewdatabasenameisfacf8af797f428fdc401ffddc672894d#!#dbo varchar#!#varchar#!#nvarchar#!#nvarchar sp_rename_thisnewdatabasenameis1e39ca7c78a1fba2342467331fb5bd56#!##!#db_owner#!#sp_rename_thisnewdatabasenameisb8bd7c94f797959aa629fc2f9e821637 sp_rename_thisnewdatabasenameis21f79a8b66248a73068dca6edd5b0ca3#!##!#guest#!#sp_rename_thisnewdatabasenameisb8bd7c94f797959aa629fc2f9e821637 +sp_rename_thisnewdatabasenameis95c235131f6db63ef16f222aa48d0554#!##!#db_datareader#!#sp_rename_thisnewdatabasenameisb8bd7c94f797959aa629fc2f9e821637 sp_rename_thisnewdatabasenameisa0a5aa90abf2314f4773860fda5e43a2#!##!#db_accessadmin#!#sp_rename_thisnewdatabasenameisb8bd7c94f797959aa629fc2f9e821637 +sp_rename_thisnewdatabasenameisc7c7032a834c11dbbbbf4911217c443a#!##!#db_datawriter#!#sp_rename_thisnewdatabasenameisb8bd7c94f797959aa629fc2f9e821637 sp_rename_thisnewdatabasenameisfacf8af797f428fdc401ffddc672894d#!##!#dbo#!#sp_rename_thisnewdatabasenameisb8bd7c94f797959aa629fc2f9e821637 ~~END~~ diff --git a/test/JDBC/expected/Test_sp_renamedb-vu-verify.out b/test/JDBC/expected/Test_sp_renamedb-vu-verify.out index 598688bd0a..a68d7ab49c 100644 --- a/test/JDBC/expected/Test_sp_renamedb-vu-verify.out +++ b/test/JDBC/expected/Test_sp_renamedb-vu-verify.out @@ -20,6 +20,8 @@ sp_renamedb_database1_sp_renamedb_schema1#!#sp_renamedb_schema1 ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar sp_renamedb_database1_db_accessadmin#!##!#db_accessadmin#!#sp_renamedb_database1 +sp_renamedb_database1_db_datareader#!##!#db_datareader#!#sp_renamedb_database1 +sp_renamedb_database1_db_datawriter#!##!#db_datawriter#!#sp_renamedb_database1 sp_renamedb_database1_db_owner#!##!#db_owner#!#sp_renamedb_database1 sp_renamedb_database1_dbo#!##!#dbo#!#sp_renamedb_database1 sp_renamedb_database1_guest#!##!#guest#!#sp_renamedb_database1 @@ -82,6 +84,8 @@ sp_renamedb_database2_sp_renamedb_schema1#!#sp_renamedb_schema1 ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar sp_renamedb_database2_db_accessadmin#!##!#db_accessadmin#!#sp_renamedb_database2 +sp_renamedb_database2_db_datareader#!##!#db_datareader#!#sp_renamedb_database2 +sp_renamedb_database2_db_datawriter#!##!#db_datawriter#!#sp_renamedb_database2 sp_renamedb_database2_db_owner#!##!#db_owner#!#sp_renamedb_database2 sp_renamedb_database2_dbo#!##!#dbo#!#sp_renamedb_database2 sp_renamedb_database2_guest#!##!#guest#!#sp_renamedb_database2 @@ -198,6 +202,8 @@ sp_renamedb_thisnewdatabasenamedeb7cafbbedd23f312d90e7c10a60901#!#guest ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar sp_renamedb_thisnewdatabasename115699cc11f7805d9b9b640d6455580c#!##!#dbo#!#sp_renamedb_thisnewdatabasename738bbb14cb857db43c693446c049f0bd +sp_renamedb_thisnewdatabasename2a476218bfa8dba9ac86fb898b11e9a5#!##!#db_datawriter#!#sp_renamedb_thisnewdatabasename738bbb14cb857db43c693446c049f0bd +sp_renamedb_thisnewdatabasename7052c471c798d0b08c69f719bcd607d7#!##!#db_datareader#!#sp_renamedb_thisnewdatabasename738bbb14cb857db43c693446c049f0bd sp_renamedb_thisnewdatabasenameb0dffbb56deab7ad4e684df689419c65#!##!#db_owner#!#sp_renamedb_thisnewdatabasename738bbb14cb857db43c693446c049f0bd sp_renamedb_thisnewdatabasenamedeb7cafbbedd23f312d90e7c10a60901#!##!#guest#!#sp_renamedb_thisnewdatabasename738bbb14cb857db43c693446c049f0bd sp_renamedb_thisnewdatabasenameeeb9e8f522c23281503d418ce3640572#!##!#db_accessadmin#!#sp_renamedb_thisnewdatabasename738bbb14cb857db43c693446c049f0bd diff --git a/test/JDBC/expected/datareader_datawriter-vu-cleanup.out b/test/JDBC/expected/datareader_datawriter-vu-cleanup.out new file mode 100644 index 0000000000..1ef86d7094 --- /dev/null +++ b/test/JDBC/expected/datareader_datawriter-vu-cleanup.out @@ -0,0 +1,119 @@ +-- psql +-- Need to terminate active session before cleaning up the login +SELECT pg_terminate_backend(pid) FROM pg_stat_get_activity(NULL) +WHERE sys.suser_name(usesysid) = 'db_roles_l1' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +go +~~START~~ +bool +~~END~~ + + +-- Wait to sync with another session +SELECT pg_sleep(1); +go +~~START~~ +void + +~~END~~ + + +-- Need to terminate active session before cleaning up the login +SELECT pg_terminate_backend(pid) FROM pg_stat_get_activity(NULL) +WHERE sys.suser_name(usesysid) = 'db_roles_l2' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +go +~~START~~ +bool +~~END~~ + + +-- Wait to sync with another session +SELECT pg_sleep(1); +go +~~START~~ +void + +~~END~~ + + +-- tsql +-- drop objects +use db_roles_db1 +go + +drop table db_roles_schema_1.before_t1; +go + +drop table db_roles_schema_1.after_t1; +go + +drop table db_roles_schema_1.after_t2; +go + +drop table db_roles_schema_2.before_created_by_dbo_t1; +go + +drop table db_roles_schema_2.after_created_by_dbo_t1; +go + +drop table db_roles_schema_2.after_created_by_dbo_t2; +go + +drop table db_roles_schema_2.before_created_by_u2_t1; +go + +drop table db_roles_schema_2.after_created_by_u2_t1; +go + +drop table db_roles_schema_2.after_created_by_u2_t2; +go + +drop view db_roles_schema_1.before_v1; +go + +drop view db_roles_schema_1.after_v1; +go + +drop view db_roles_schema_1.after_v2; +go + +drop view db_roles_schema_2.before_created_by_dbo_v1; +go + +drop view db_roles_schema_2.after_created_by_dbo_v1; +go + +drop view db_roles_schema_2.after_created_by_dbo_v2; +go + +drop view db_roles_schema_2.before_created_by_u2_v1; +go + +drop view db_roles_schema_2.after_created_by_u2_v1; +go + +drop view db_roles_schema_2.after_created_by_u2_v2; +go + +drop schema db_roles_schema_1; +go + +drop schema db_roles_schema_2; +go + +drop user db_roles_u1; +go + +drop user db_roles_u2; +go + +drop login db_roles_l1; +go + +drop login db_roles_l2; +go + +use master; +go + +drop database db_roles_db1; +go diff --git a/test/JDBC/expected/datareader_datawriter-vu-prepare.out b/test/JDBC/expected/datareader_datawriter-vu-prepare.out new file mode 100644 index 0000000000..e84dd65fe4 --- /dev/null +++ b/test/JDBC/expected/datareader_datawriter-vu-prepare.out @@ -0,0 +1,53 @@ +-- tsql +-- create login, user and add members +create database db_roles_db1; +go + +use db_roles_db1; +go + +create login db_roles_l1 with password = '123'; +go + +create login db_roles_l2 with password = '123'; +go + +create user db_roles_u1 for login db_roles_l1; +go + +create user db_roles_u2 for login db_roles_l2; +go + +create schema db_roles_schema_1; +go + +create schema db_roles_schema_2 authorization db_roles_u2; +go + +create table db_roles_schema_1.before_t1(a int); +go + +create view db_roles_schema_1.before_v1 as select 2; +go + +create table db_roles_schema_2.before_created_by_dbo_t1(a int); +go + +create view db_roles_schema_2.before_created_by_dbo_v1 as select 2; +go + +use master; +go + +-- tsql user=db_roles_l2 password=123 +use db_roles_db1; +go + +create table db_roles_schema_2.before_created_by_u2_t1(a int); +go + +create view db_roles_schema_2.before_created_by_u2_v1 as select 2; +go + +use master; +go diff --git a/test/JDBC/expected/datareader_datawriter-vu-verify.out b/test/JDBC/expected/datareader_datawriter-vu-verify.out new file mode 100644 index 0000000000..9e332ab99b --- /dev/null +++ b/test/JDBC/expected/datareader_datawriter-vu-verify.out @@ -0,0 +1,684 @@ +-- tsql +-- bbf dump does not dump password so reset the password +ALTER LOGIN db_roles_l2 WITH PASSWORD = '123' +GO +ALTER LOGIN db_roles_l1 WITH PASSWORD = '123' +GO + +-- IS_ROLEMEMBER & IS_MEMBER should show db_datareader as member of dbo but not of db_owner +SELECT IS_ROLEMEMBER('db_datareader') +GO +~~START~~ +int +1 +~~END~~ + +SELECT IS_ROLEMEMBER('db_datareader', 'dbo') +GO +~~START~~ +int +1 +~~END~~ + +SELECT IS_ROLEMEMBER('db_datareader', 'db_owner') +GO +~~START~~ +int +0 +~~END~~ + + +-- IS_ROLEMEMBER & IS_MEMBER should show db_datawriter as member of dbo but not of db_owner +SELECT IS_ROLEMEMBER('db_datawriter') +GO +~~START~~ +int +1 +~~END~~ + +SELECT IS_ROLEMEMBER('db_datawriter', 'dbo') +GO +~~START~~ +int +1 +~~END~~ + +SELECT IS_ROLEMEMBER('db_datawriter', 'db_owner') +GO +~~START~~ +int +0 +~~END~~ + + +-- tsql user=db_roles_l2 password=123 +-- create objects after upgrade +use db_roles_db1; +go + +create table db_roles_schema_2.after_created_by_u2_t1(a int); +go + +create view db_roles_schema_2.after_created_by_u2_v1 as select 1; +go + +use master; +go + +-- tsql +use db_roles_db1 +go + +create table db_roles_schema_1.after_t1(a int); +go + +create view db_roles_schema_1.after_v1 as select 2; +go + +create table db_roles_schema_2.after_created_by_dbo_t1(a int); +go + +create view db_roles_schema_2.after_created_by_dbo_v1 as select 2; +go + +alter role db_datareader add member db_roles_u1; +go + +alter role db_datawriter add member db_roles_u1; +go + +create table db_roles_schema_1.after_t2(a int); +go + +create view db_roles_schema_1.after_v2 as select 2; +go + +create table db_roles_schema_2.after_created_by_dbo_t2(a int); +go + +create view db_roles_schema_2.after_created_by_dbo_v2 as select 2; +go + +use master +go + +-- tsql user=db_roles_l2 password=123 +use db_roles_db1; +go + +create table db_roles_schema_2.after_created_by_u2_t2(a int); +go + +create view db_roles_schema_2.after_created_by_u2_v2 as select 1; +go + +use master; +go + +-- tsql user=db_roles_l1 password=123 +use db_roles_db1 +go + +-- user is a member of db_datareader/db_datawriter, objects should be accessible +select * from db_roles_schema_1.after_t1; -- allowed +go +~~START~~ +int +~~END~~ + + +select * from db_roles_schema_1.after_t2; -- allowed +go +~~START~~ +int +~~END~~ + + +select * from db_roles_schema_1.after_v1; -- allowed +go +~~START~~ +int +2 +~~END~~ + + +select * from db_roles_schema_1.after_v2; -- allowed +go +~~START~~ +int +2 +~~END~~ + + +insert into db_roles_schema_1.before_t1 values(1); -- allowed +go +~~ROW COUNT: 1~~ + + +update db_roles_schema_1.before_t1 set a = 2 where a = 1; -- allowed +go +~~ROW COUNT: 1~~ + + +delete from db_roles_schema_1.before_t1 where a = 2; -- allowed +go +~~ROW COUNT: 1~~ + + +select * from db_roles_schema_2.before_created_by_dbo_t1; -- allowed +go +~~START~~ +int +~~END~~ + + +select * from db_roles_schema_2.before_created_by_dbo_v1; -- allowed +go +~~START~~ +int +2 +~~END~~ + + +insert into db_roles_schema_2.before_created_by_dbo_t1 values(1); -- allowed +go +~~ROW COUNT: 1~~ + + +update db_roles_schema_2.before_created_by_dbo_t1 set a = 2 where a = 1; -- allowed +go +~~ROW COUNT: 1~~ + + +delete from db_roles_schema_2.before_created_by_dbo_t1 where a = 2; -- allowed +go +~~ROW COUNT: 1~~ + + +select * from db_roles_schema_2.after_created_by_dbo_t1; -- allowed +go +~~START~~ +int +~~END~~ + + +select * from db_roles_schema_2.after_created_by_dbo_v1; -- allowed +go +~~START~~ +int +2 +~~END~~ + + +insert into db_roles_schema_2.after_created_by_dbo_t1 values(1); -- allowed +go +~~ROW COUNT: 1~~ + + +update db_roles_schema_2.after_created_by_dbo_t1 set a = 2 where a = 1; -- allowed +go +~~ROW COUNT: 1~~ + + +delete from db_roles_schema_2.after_created_by_dbo_t1 where a = 2; -- allowed +go +~~ROW COUNT: 1~~ + + +select * from db_roles_schema_2.after_created_by_dbo_t2; -- allowed +go +~~START~~ +int +~~END~~ + + +select * from db_roles_schema_2.after_created_by_dbo_v2; -- allowed +go +~~START~~ +int +2 +~~END~~ + + +insert into db_roles_schema_2.after_created_by_dbo_t2 values(1); -- allowed +go +~~ROW COUNT: 1~~ + + +update db_roles_schema_2.after_created_by_dbo_t2 set a = 2 where a = 1; -- allowed +go +~~ROW COUNT: 1~~ + + +delete from db_roles_schema_2.after_created_by_dbo_t2 where a = 2; -- allowed +go +~~ROW COUNT: 1~~ + + +select * from db_roles_schema_2.before_created_by_u2_t1; -- allowed +go +~~START~~ +int +~~END~~ + + +select * from db_roles_schema_2.before_created_by_u2_v1; -- allowed +go +~~START~~ +int +2 +~~END~~ + + +insert into db_roles_schema_2.before_created_by_u2_t1 values(1); -- allowed +go +~~ROW COUNT: 1~~ + + +update db_roles_schema_2.before_created_by_u2_t1 set a = 2 where a = 1; -- allowed +go +~~ROW COUNT: 1~~ + + +delete from db_roles_schema_2.before_created_by_u2_t1 where a = 2; -- allowed +go +~~ROW COUNT: 1~~ + + +select * from db_roles_schema_2.after_created_by_u2_t2; -- allowed +go +~~START~~ +int +~~END~~ + + +select * from db_roles_schema_2.after_created_by_u2_v2; -- allowed +go +~~START~~ +int +1 +~~END~~ + + +insert into db_roles_schema_2.after_created_by_u2_t2 values(1); -- allowed +go +~~ROW COUNT: 1~~ + + +update db_roles_schema_2.after_created_by_u2_t2 set a = 2 where a = 1; -- allowed +go +~~ROW COUNT: 1~~ + + +delete from db_roles_schema_2.after_created_by_u2_t2 where a = 2; -- allowed +go +~~ROW COUNT: 1~~ + + +select * from db_roles_schema_2.after_created_by_u2_t1; -- allowed +go +~~START~~ +int +~~END~~ + + +select * from db_roles_schema_2.after_created_by_u2_v1; -- allowed +go +~~START~~ +int +1 +~~END~~ + + +insert into db_roles_schema_2.after_created_by_u2_t1 values(1); -- allowed +go +~~ROW COUNT: 1~~ + + +update db_roles_schema_2.after_created_by_u2_t1 set a = 2 where a = 1; -- allowed +go +~~ROW COUNT: 1~~ + + +delete from db_roles_schema_2.after_created_by_u2_t1 where a = 2; -- allowed +go +~~ROW COUNT: 1~~ + + +use master; +go + +-- tsql +use db_roles_db1; +go + +alter role db_datareader drop member db_roles_u1; +go + +alter role db_datawriter drop member db_roles_u1; +go + +use master; +go + +-- tsql user=db_roles_l1 password=123 +use db_roles_db1; +go + +select * from db_roles_schema_1.after_t1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t1)~~ + + +select * from db_roles_schema_1.after_t2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t2)~~ + + +select * from db_roles_schema_1.before_t1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_t1)~~ + + +select * from db_roles_schema_1.after_v1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view after_v1)~~ + + +select * from db_roles_schema_1.after_v2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view after_v2)~~ + + +select * from db_roles_schema_1.before_v1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view before_v1)~~ + + +insert into db_roles_schema_1.before_t1 values(1); -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_t1)~~ + + +update db_roles_schema_1.before_t1 set a = 2 where a = 1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_t1)~~ + + +delete from db_roles_schema_1.before_t1 where a = 2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_t1)~~ + + +insert into db_roles_schema_1.after_t1 values(1); -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t1)~~ + + +update db_roles_schema_1.after_t1 set a = 2 where a = 1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t1)~~ + + +delete from db_roles_schema_1.after_t1 where a = 2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t1)~~ + + +insert into db_roles_schema_1.after_t2 values(1); -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t2)~~ + + +update db_roles_schema_1.after_t2 set a = 2 where a = 1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t2)~~ + + +delete from db_roles_schema_1.after_t2 where a = 2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t2)~~ + + +select * from db_roles_schema_2.before_created_by_dbo_t1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_created_by_dbo_t1)~~ + + +select * from db_roles_schema_2.before_created_by_dbo_v1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view before_created_by_dbo_v1)~~ + + +insert into db_roles_schema_2.before_created_by_dbo_t1 values(1); -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_created_by_dbo_t1)~~ + + +update db_roles_schema_2.before_created_by_dbo_t1 set a = 2 where a = 1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_created_by_dbo_t1)~~ + + +delete from db_roles_schema_2.before_created_by_dbo_t1 where a = 2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_created_by_dbo_t1)~~ + + +select * from db_roles_schema_2.after_created_by_dbo_t1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_created_by_dbo_t1)~~ + + +select * from db_roles_schema_2.after_created_by_dbo_v1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view after_created_by_dbo_v1)~~ + + +insert into db_roles_schema_2.after_created_by_dbo_t1 values(1); -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_created_by_dbo_t1)~~ + + +update db_roles_schema_2.after_created_by_dbo_t1 set a = 2 where a = 1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_created_by_dbo_t1)~~ + + +delete from db_roles_schema_2.after_created_by_dbo_t1 where a = 2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_created_by_dbo_t1)~~ + + +select * from db_roles_schema_2.after_created_by_dbo_t2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_created_by_dbo_t2)~~ + + +select * from db_roles_schema_2.after_created_by_dbo_v2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view after_created_by_dbo_v2)~~ + + +insert into db_roles_schema_2.after_created_by_dbo_t2 values(1); -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_created_by_dbo_t2)~~ + + +update db_roles_schema_2.after_created_by_dbo_t2 set a = 2 where a = 1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_created_by_dbo_t2)~~ + + +delete from db_roles_schema_2.after_created_by_dbo_t2 where a = 2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_created_by_dbo_t2)~~ + + +select * from db_roles_schema_2.before_created_by_u2_t1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_created_by_u2_t1)~~ + + +select * from db_roles_schema_2.before_created_by_u2_v1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view before_created_by_u2_v1)~~ + + +insert into db_roles_schema_2.before_created_by_u2_t1 values(1); -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_created_by_u2_t1)~~ + + +update db_roles_schema_2.before_created_by_u2_t1 set a = 2 where a = 1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_created_by_u2_t1)~~ + + +delete from db_roles_schema_2.before_created_by_u2_t1 where a = 2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_created_by_u2_t1)~~ + + +select * from db_roles_schema_2.after_created_by_u2_t1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_created_by_u2_t1)~~ + + +select * from db_roles_schema_2.after_created_by_u2_v1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view after_created_by_u2_v1)~~ + + +insert into db_roles_schema_2.after_created_by_u2_t1 values(1); -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_created_by_u2_t1)~~ + + +update db_roles_schema_2.after_created_by_u2_t1 set a = 2 where a = 1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_created_by_u2_t1)~~ + + +delete from db_roles_schema_2.after_created_by_u2_t1 where a = 2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_created_by_u2_t1)~~ + + +select * from db_roles_schema_2.after_created_by_u2_t2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_created_by_u2_t2)~~ + + +select * from db_roles_schema_2.after_created_by_u2_v2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view after_created_by_u2_v2)~~ + + +insert into db_roles_schema_2.after_created_by_u2_t2 values(1); -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_created_by_u2_t2)~~ + + +update db_roles_schema_2.after_created_by_u2_t2 set a = 2 where a = 1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_created_by_u2_t2)~~ + + +delete from db_roles_schema_2.after_created_by_u2_t2 where a = 2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_created_by_u2_t2)~~ + + +use master; +go diff --git a/test/JDBC/expected/datareader_datawriter.out b/test/JDBC/expected/datareader_datawriter.out new file mode 100644 index 0000000000..8fe304b2bb --- /dev/null +++ b/test/JDBC/expected/datareader_datawriter.out @@ -0,0 +1,1914 @@ +-- tsql +-- Error cases +create role db_datareader; -- Error, this role already exists +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: role "master_db_datareader" already exists)~~ + + +create role db_datawriter; -- Error, this role already exists +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: role "master_db_datawriter" already exists)~~ + + +create table t1(a int); +go +create proc p1 as select 1; +go + +-- grants not allowed on these special roles +grant select on schema::dbo to db_datareader; -- Error, no grant on special roles +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny or revoke permissions to or from special roles.)~~ + + +grant execute on schema::dbo to db_datawriter; -- Error, no grant on special roles +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny or revoke permissions to or from special roles.)~~ + + +revoke select on schema::dbo from db_datareader; -- Error, no grant on special roles +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny or revoke permissions to or from special roles.)~~ + + +revoke execute on schema::dbo from db_datawriter; -- Error, no grant on special roles +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny or revoke permissions to or from special roles.)~~ + + +grant select on object::t1 to db_datareader; -- Error, no grant on special roles +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny or revoke permissions to or from special roles.)~~ + + +grant insert on object::t1 to db_datawriter; -- Error, no grant on special roles +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny or revoke permissions to or from special roles.)~~ + + +grant execute on object::p1 to db_datareader; -- Error, no grant on special roles +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny or revoke permissions to or from special roles.)~~ + + +revoke select on object::t1 to db_datareader; -- Error, no grant on special roles +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny or revoke permissions to or from special roles.)~~ + + +revoke insert on object::t1 to db_datawriter; -- Error, no grant on special roles +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny or revoke permissions to or from special roles.)~~ + + +revoke execute on object::p1 to db_datareader; -- Error, no grant on special roles +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny or revoke permissions to or from special roles.)~~ + + +grant all on object::t1 to db_datareader; -- Error, no grant on special roles +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny or revoke permissions to or from special roles.)~~ + + +revoke all on object::t1 to db_datareader; -- Error, no grant on special roles +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny or revoke permissions to or from special roles.)~~ + + +drop role db_datareader; -- Error, should not be dropped +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot drop the role 'db_datareader'.)~~ + + +drop role db_datawriter; -- Error, should not be dropped +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot drop the role 'db_datawriter'.)~~ + + +drop table t1; +go +drop proc p1; +go + +-- create login, user and add members +create database db_roles_db1; +go + +use db_roles_db1; +go + +create login db_roles_l1 with password = '123'; +go + +create login db_roles_l2 with password = '123'; +go + +create login db_roles_l3 with password = '123'; +go + +create login db_roles_l4 with password = '123'; +go + +create login db_roles_l5 with password = '123'; +go + +create user db_roles_u4 for login db_roles_l4; +go + +create user db_roles_u5 for login db_roles_l5; +go + +alter server role sysadmin add member db_roles_l2; +go + +create user db_datareader for login db_roles_l1; -- Error, this role already exists +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: role "db_roles_db1_db_datareader" already exists)~~ + + +create user db_datawriter for login db_roles_l1; -- Error, this role already exists +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: role "db_roles_db1_db_datawriter" already exists)~~ + + +create user db_roles_u1 for login db_roles_l1; +go + +create role db_roles_r1; +go + +alter role db_roles_r1 add member db_roles_u5; +go + +create schema db_roles_schema_1; +go + +create schema db_roles_schema_2 authorization db_roles_u4; +go + +create table db_roles_schema_1.before_t1(a int); +go + +create view db_roles_schema_1.before_v1 as select 2; +go + +create table db_roles_schema_2.before_created_by_dbo_t1(a int); +go + +create view db_roles_schema_2.before_created_by_dbo_v1 as select 2; +go + +create table before_t1(a int); +go + +create view before_v1 as select 2; +go + +use master; +go + +create user db_roles_u1 for login db_roles_l1; +go + +create table t1_in_master(a int); +go + +-- tsql user=db_roles_l4 password=123 +use db_roles_db1; +go + +create table db_roles_schema_2.before_created_by_u4_t1(a int); +go + +create view db_roles_schema_2.before_created_by_u4_v1 as select 2; +go + +use master; +go + +-- tsql +use db_roles_db1 +go + +alter role db_datareader add member db_roles_u1; +go + +alter role db_datawriter add member db_roles_u1; +go + +alter role db_datareader add member db_roles_r1; +go + +alter role db_datawriter add member db_roles_r1; +go + +select count(*) from sys.database_principals where name like '%db_datareader%'; +go +~~START~~ +int +1 +~~END~~ + + +select count(*) from sys.database_principals where name like '%db_datawriter%'; +go +~~START~~ +int +1 +~~END~~ + + +-- Test sp_helpuser +CREATE TABLE #UserRoles(userName sys.SYSNAME, roleName sys.SYSNAME, loginName sys.SYSNAME NULL, defdb sys.SYSNAME NULL, defschema sys.SYSNAME, userid INT, sid sys.VARBINARY(85)); +go +-- Insert the results of sp_helpuser into the temporary table +INSERT INTO #UserRoles EXEC sp_helpuser; +go +~~ROW COUNT: 8~~ + +-- Select the desired fields from the temporary table +SELECT userName, roleName FROM #UserRoles WHERE roleName IN ('db_datareader', 'db_datawriter'); +go +~~START~~ +varchar#!#varchar +db_roles_r1#!#db_datareader +db_roles_r1#!#db_datawriter +db_roles_u1#!#db_datareader +db_roles_u1#!#db_datawriter +~~END~~ + +-- Drop the temporary table +DROP TABLE #UserRoles; +go + +-- Test sp_helprole +CREATE TABLE #UserRoles(RoleName sys.SYSNAME, RoleId integer, IsAppRole integer); +go +-- Insert the results of sp_helprole into the temporary table +INSERT INTO #UserRoles EXEC sp_helprole; +go +~~ROW COUNT: 5~~ + +-- Select the desired fields from the temporary table +SELECT RoleName, IsAppRole FROM #UserRoles WHERE RoleName IN ('db_datareader', 'db_datawriter'); +go +~~START~~ +varchar#!#int +db_datareader#!#0 +db_datawriter#!#0 +~~END~~ + +-- Drop the temporary table +DROP TABLE #UserRoles; +go + +-- Test sp_helprolemember +CREATE TABLE #UserRoles(RoleName sys.SYSNAME, MemberName sys.SYSNAME, MemberSID sys.VARBINARY(85)); +go +-- Insert the results of sp_helprolemember into the temporary table +INSERT INTO #UserRoles EXEC sp_helprolemember; +go +~~ROW COUNT: 6~~ + +-- Select the desired fields from the temporary table +SELECT RoleName, MemberName FROM #UserRoles WHERE RoleName IN ('db_datareader', 'db_datawriter'); +go +~~START~~ +varchar#!#varchar +db_datareader#!#db_roles_r1 +db_datareader#!#db_roles_u1 +db_datawriter#!#db_roles_r1 +db_datawriter#!#db_roles_u1 +~~END~~ + +-- Drop the temporary table +DROP TABLE #UserRoles; +go + +use master +go + +-- tsql user=db_roles_l4 password=123 +use db_roles_db1; +go + +create table db_roles_schema_2.after_created_by_u4_t1(a int); +go + +create view db_roles_schema_2.after_created_by_u4_v1 as select 1; +go + +use master; +go + +-- tsql +use db_roles_db1 +go + +create table after_t1(a int); +go + +create view after_v1 as select 2; +go + +create table db_roles_schema_1.after_t1(a int); +go + +create view db_roles_schema_1.after_v1 as select 2; +go + +create table db_roles_schema_2.after_created_by_dbo_t1(a int); +go + +create view db_roles_schema_2.after_created_by_dbo_v1 as select 2; +go + +use master; +go + +-- tsql user=db_roles_l2 password=123 +-- member of sysadmin can add/drop user as a member of db_datareader/db_datawriter +use db_roles_db1; +go + +alter role db_datareader drop member db_roles_u1; +go + +alter role db_datawriter drop member db_roles_u1; +go + +alter role db_datareader add member db_roles_u1; +go + +alter role db_datawriter add member db_roles_u1; +go + +exec sp_droprolemember 'db_datareader', 'db_roles_u1'; +go + +exec sp_droprolemember 'db_datawriter', 'db_roles_u1'; +go + +exec sp_addrolemember 'db_datareader', 'db_roles_u1'; +go + +exec sp_addrolemember 'db_datawriter', 'db_roles_u1'; +go + +use master; +go + +-- tsql +alter authorization on database::db_roles_db1 to db_roles_l3; +go + +-- tsql user=db_roles_l3 password=123 +use db_roles_db1 +go + +create schema db_roles_schema_3; +go + +create table db_roles_schema_3.db_roles_t1(a int); +go + +create view db_roles_schema_3.db_roles_v1 as select 2; +go + +-- database owner can add other roles as a member of database roles +alter role db_datareader drop member db_roles_u1; +go + +alter role db_datawriter drop member db_roles_u1; +go + +alter role db_datareader add member db_roles_u1; +go + +alter role db_datawriter add member db_roles_u1; +go + +exec sp_droprolemember 'db_datareader', 'db_roles_u1'; +go + +exec sp_droprolemember 'db_datawriter', 'db_roles_u1'; +go + +exec sp_addrolemember 'db_datareader', 'db_roles_u1'; +go + +exec sp_addrolemember 'db_datawriter', 'db_roles_u1'; +go + +-- remove select privilege on the schema and object, still the objects should be accessible +revoke select on schema::db_roles_schema_1 from db_roles_u1; +go + +revoke select on object::db_roles_schema_1.before_t1 from db_roles_u1; +go + +use master; +go + +-- tsql user=db_roles_l1 password=123 +use db_roles_db1 +go + +-- members of db_datareader/db_datawriter cannot add another role/user as its member +alter role db_datareader drop member db_roles_r1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot alter the role 'db_datareader', because it does not exist or you do not have permission.)~~ + + +alter role db_datawriter drop member db_roles_r1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot alter the role 'db_datawriter', because it does not exist or you do not have permission.)~~ + + +alter role db_datareader add member db_roles_r1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot alter the role 'db_datareader', because it does not exist or you do not have permission.)~~ + + +alter role db_datawriter add member db_roles_r1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot alter the role 'db_datawriter', because it does not exist or you do not have permission.)~~ + + +exec sp_droprolemember 'db_datareader', 'db_roles_r1'; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot alter the role 'db_datareader', because it does not exist or you do not have permission.)~~ + + +exec sp_droprolemember 'db_datawriter', 'db_roles_r1'; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot alter the role 'db_datawriter', because it does not exist or you do not have permission.)~~ + + +exec sp_addrolemember 'db_datareader', 'db_roles_r1'; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot alter the role 'db_datareader', because it does not exist or you do not have permission.)~~ + + +exec sp_addrolemember 'db_datawriter', 'db_roles_r1'; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot alter the role 'db_datawriter', because it does not exist or you do not have permission.)~~ + + +-- Basic membership check +SELECT IS_MEMBER('db_datareader') +GO +~~START~~ +int +1 +~~END~~ + + +SELECT IS_MEMBER('db_datawriter') +GO +~~START~~ +int +1 +~~END~~ + + +-- user is a member of db_datareader/db_datawriter, objects should be accessible +-- objects created before and after adding the user to db roles should be accessible. +select * from after_t1; -- allowed +go +~~START~~ +int +~~END~~ + + +select * from after_v1; -- allowed +go +~~START~~ +int +2 +~~END~~ + + +insert into before_t1 values(1); -- allowed +go +~~ROW COUNT: 1~~ + + +update before_t1 set a = 2 where a = 1; -- allowed +go +~~ROW COUNT: 1~~ + + +delete from before_t1 where a = 2; -- allowed +go +~~ROW COUNT: 1~~ + + +select * from before_t1; -- allowed +go +~~START~~ +int +~~END~~ + + +select * from before_v1; -- allowed +go +~~START~~ +int +2 +~~END~~ + + +insert into after_t1 values(1); -- allowed +go +~~ROW COUNT: 1~~ + + +update after_t1 set a = 2 where a = 1; -- allowed +go +~~ROW COUNT: 1~~ + + +delete from after_t1 where a = 2; -- allowed +go +~~ROW COUNT: 1~~ + + +select * from db_roles_schema_1.after_t1; -- allowed +go +~~START~~ +int +~~END~~ + + +select * from db_roles_schema_1.after_v1; -- allowed +go +~~START~~ +int +2 +~~END~~ + + +insert into db_roles_schema_1.before_t1 values(1); -- allowed +go +~~ROW COUNT: 1~~ + + +update db_roles_schema_1.before_t1 set a = 2 where a = 1; -- allowed +go +~~ROW COUNT: 1~~ + + +delete from db_roles_schema_1.before_t1 where a = 2; -- allowed +go +~~ROW COUNT: 1~~ + + +select * from db_roles_schema_2.before_created_by_dbo_t1; -- allowed +go +~~START~~ +int +~~END~~ + + +select * from db_roles_schema_2.before_created_by_dbo_v1; -- allowed +go +~~START~~ +int +2 +~~END~~ + + +insert into db_roles_schema_2.before_created_by_dbo_t1 values(1); -- allowed +go +~~ROW COUNT: 1~~ + + +update db_roles_schema_2.before_created_by_dbo_t1 set a = 2 where a = 1; -- allowed +go +~~ROW COUNT: 1~~ + + +delete from db_roles_schema_2.before_created_by_dbo_t1 where a = 2; -- allowed +go +~~ROW COUNT: 1~~ + + +select * from db_roles_schema_2.after_created_by_dbo_t1; -- allowed +go +~~START~~ +int +~~END~~ + + +select * from db_roles_schema_2.after_created_by_dbo_v1; -- allowed +go +~~START~~ +int +2 +~~END~~ + + +insert into db_roles_schema_2.after_created_by_dbo_t1 values(1); -- allowed +go +~~ROW COUNT: 1~~ + + +update db_roles_schema_2.after_created_by_dbo_t1 set a = 2 where a = 1; -- allowed +go +~~ROW COUNT: 1~~ + + +delete from db_roles_schema_2.after_created_by_dbo_t1 where a = 2; -- allowed +go +~~ROW COUNT: 1~~ + + +select * from db_roles_schema_2.before_created_by_u4_t1; -- allowed +go +~~START~~ +int +~~END~~ + + +select * from db_roles_schema_2.before_created_by_u4_v1; -- allowed +go +~~START~~ +int +2 +~~END~~ + + +insert into db_roles_schema_2.before_created_by_u4_t1 values(1); -- allowed +go +~~ROW COUNT: 1~~ + + +update db_roles_schema_2.before_created_by_u4_t1 set a = 2 where a = 1; -- allowed +go +~~ROW COUNT: 1~~ + + +delete from db_roles_schema_2.before_created_by_u4_t1 where a = 2; -- allowed +go +~~ROW COUNT: 1~~ + + +select * from db_roles_schema_2.after_created_by_u4_t1; -- allowed +go +~~START~~ +int +~~END~~ + + +select * from db_roles_schema_2.after_created_by_u4_v1; -- allowed +go +~~START~~ +int +1 +~~END~~ + + +insert into db_roles_schema_2.after_created_by_u4_t1 values(1); -- allowed +go +~~ROW COUNT: 1~~ + + +update db_roles_schema_2.after_created_by_u4_t1 set a = 2 where a = 1; -- allowed +go +~~ROW COUNT: 1~~ + + +delete from db_roles_schema_2.after_created_by_u4_t1 where a = 2; -- allowed +go +~~ROW COUNT: 1~~ + + +select * from master.dbo.t1_in_master; -- not allowed since the user in master doesn't have read privilege +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table t1_in_master)~~ + + +insert into master.dbo.t1_in_master values(1); -- not allowed since the user in master doesn't have write privilege +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table t1_in_master)~~ + + +-- objects created by the database owner should be accessible too. +select * from db_roles_schema_3.db_roles_t1; -- allowed +go +~~START~~ +int +~~END~~ + + +select * from db_roles_schema_3.db_roles_v1; -- allowed +go +~~START~~ +int +2 +~~END~~ + + +insert into db_roles_schema_3.db_roles_t1 values(1); -- allowed +go +~~ROW COUNT: 1~~ + + +update db_roles_schema_3.db_roles_t1 set a = 2 where a = 1; -- allowed +go +~~ROW COUNT: 1~~ + + +delete from db_roles_schema_3.db_roles_t1 where a = 2; -- allowed +go +~~ROW COUNT: 1~~ + + +use master; +go + +-- tsql +-- Basic membership check +use db_roles_db1; +go + +SELECT IS_ROLEMEMBER('db_datareader', 'db_roles_u1') +GO +~~START~~ +int +1 +~~END~~ + + +SELECT IS_ROLEMEMBER('db_datawriter', 'db_roles_u1') +GO +~~START~~ +int +1 +~~END~~ + + +SELECT IS_ROLEMEMBER('db_datareader', 'db_roles_r1') +GO +~~START~~ +int +1 +~~END~~ + + +SELECT IS_ROLEMEMBER('db_datawriter', 'db_roles_r1') +GO +~~START~~ +int +1 +~~END~~ + + +alter role db_datareader drop member db_roles_u1; +go + +alter role db_datawriter drop member db_roles_u1; +go + +alter role db_datareader drop member db_roles_r1; +go + +-- Basic membership check +SELECT IS_ROLEMEMBER('db_datareader', 'db_roles_u1') +GO +~~START~~ +int +0 +~~END~~ + + +SELECT IS_ROLEMEMBER('db_datawriter', 'db_roles_u1') +GO +~~START~~ +int +0 +~~END~~ + + +SELECT IS_ROLEMEMBER('db_datareader', 'db_roles_r1') +GO +~~START~~ +int +0 +~~END~~ + + +SELECT IS_ROLEMEMBER('db_datawriter', 'db_roles_r1') +GO +~~START~~ +int +1 +~~END~~ + + +alter role db_datawriter drop member db_roles_r1; +go + +use master; +go + +alter role db_datareader add member db_roles_u1; +go + +alter role db_datawriter add member db_roles_u1; +go + +-- tsql user=db_roles_l1 password=123 +-- Basic membership check +use db_roles_db1 +go + +SELECT IS_MEMBER('db_datareader') +GO +~~START~~ +int +0 +~~END~~ + + +SELECT IS_MEMBER('db_datawriter') +GO +~~START~~ +int +0 +~~END~~ + + +-- user is not a member of db_datareader/db_datawriter, objects should not be accessible +select * from after_t1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t1)~~ + + +select * from after_v1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view after_v1)~~ + + +select * from before_t1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_t1)~~ + + +select * from before_v1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view before_v1)~~ + + +insert into before_t1 values(1); -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_t1)~~ + + +update before_t1 set a = 2 where a = 1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_t1)~~ + + +delete from before_t1 where a = 2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_t1)~~ + + +insert into after_t1 values(1); -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t1)~~ + + +update after_t1 set a = 2 where a = 1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t1)~~ + + +delete from after_t1 where a = 2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t1)~~ + + +select * from db_roles_schema_1.after_t1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t1)~~ + + +select * from db_roles_schema_1.before_t1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_t1)~~ + + +select * from db_roles_schema_1.after_v1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view after_v1)~~ + + +select * from db_roles_schema_1.before_v1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view before_v1)~~ + + +insert into db_roles_schema_1.before_t1 values(1); -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_t1)~~ + + +update db_roles_schema_1.before_t1 set a = 2 where a = 1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_t1)~~ + + +delete from db_roles_schema_1.before_t1 where a = 2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_t1)~~ + + +insert into db_roles_schema_1.after_t1 values(1); -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t1)~~ + + +update db_roles_schema_1.after_t1 set a = 2 where a = 1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t1)~~ + + +delete from db_roles_schema_1.after_t1 where a = 2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t1)~~ + + +select * from db_roles_schema_2.before_created_by_dbo_t1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_created_by_dbo_t1)~~ + + +select * from db_roles_schema_2.before_created_by_dbo_v1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view before_created_by_dbo_v1)~~ + + +insert into db_roles_schema_2.before_created_by_dbo_t1 values(1); -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_created_by_dbo_t1)~~ + + +update db_roles_schema_2.before_created_by_dbo_t1 set a = 2 where a = 1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_created_by_dbo_t1)~~ + + +delete from db_roles_schema_2.before_created_by_dbo_t1 where a = 2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_created_by_dbo_t1)~~ + + +select * from db_roles_schema_2.after_created_by_dbo_t1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_created_by_dbo_t1)~~ + + +select * from db_roles_schema_2.after_created_by_dbo_v1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view after_created_by_dbo_v1)~~ + + +insert into db_roles_schema_2.after_created_by_dbo_t1 values(1); -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_created_by_dbo_t1)~~ + + +update db_roles_schema_2.after_created_by_dbo_t1 set a = 2 where a = 1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_created_by_dbo_t1)~~ + + +delete from db_roles_schema_2.after_created_by_dbo_t1 where a = 2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_created_by_dbo_t1)~~ + + +select * from db_roles_schema_2.before_created_by_u4_t1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_created_by_u4_t1)~~ + + +select * from db_roles_schema_2.before_created_by_u4_v1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view before_created_by_u4_v1)~~ + + +insert into db_roles_schema_2.before_created_by_u4_t1 values(1); -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_created_by_u4_t1)~~ + + +update db_roles_schema_2.before_created_by_u4_t1 set a = 2 where a = 1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_created_by_u4_t1)~~ + + +delete from db_roles_schema_2.before_created_by_u4_t1 where a = 2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_created_by_u4_t1)~~ + + +select * from db_roles_schema_2.after_created_by_u4_t1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_created_by_u4_t1)~~ + + +select * from db_roles_schema_2.after_created_by_u4_v1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view after_created_by_u4_v1)~~ + + +insert into db_roles_schema_2.after_created_by_u4_t1 values(1); -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_created_by_u4_t1)~~ + + +update db_roles_schema_2.after_created_by_u4_t1 set a = 2 where a = 1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_created_by_u4_t1)~~ + + +delete from db_roles_schema_2.after_created_by_u4_t1 where a = 2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_created_by_u4_t1)~~ + + +-- objects created by the database owner should not be accessible +select * from db_roles_schema_3.db_roles_t1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table db_roles_t1)~~ + + +select * from db_roles_schema_3.db_roles_v1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view db_roles_v1)~~ + + +insert into db_roles_schema_3.db_roles_t1 values(1); -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table db_roles_t1)~~ + + +update db_roles_schema_3.db_roles_t1 set a = 2 where a = 1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table db_roles_t1)~~ + + +delete from db_roles_schema_3.db_roles_t1 where a = 2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table db_roles_t1)~~ + + +select * from master.dbo.t1_in_master; -- allowed since the user in master has read privilege +go +~~START~~ +int +~~END~~ + + +insert into master.dbo.t1_in_master values(1); -- allowed since the user in master has write privilege +go +~~ROW COUNT: 1~~ + + +use master; +go + +-- tsql +use db_roles_db1; +go + +exec sp_addrolemember 'db_datareader', 'db_roles_u1'; +go + +exec sp_addrolemember 'db_datawriter', 'db_roles_u1'; +go + +exec sp_addrolemember 'db_datareader', 'db_roles_r1'; +go + +exec sp_addrolemember 'db_datawriter', 'db_roles_r1'; +go + +use master; +go + +-- tsql user=db_roles_l1 password=123 +-- Basic membership check +use db_roles_db1 +go + +SELECT IS_MEMBER('db_datareader') +GO +~~START~~ +int +1 +~~END~~ + + +SELECT IS_MEMBER('db_datawriter') +GO +~~START~~ +int +1 +~~END~~ + + +-- user is a member of db_datareader/db_datawriter, objects should be accessible +select * from after_t1; -- allowed +go +~~START~~ +int +~~END~~ + + +select * from before_t1; -- allowed +go +~~START~~ +int +~~END~~ + + +select * from after_v1; -- allowed +go +~~START~~ +int +2 +~~END~~ + + +select * from before_v1; -- allowed +go +~~START~~ +int +2 +~~END~~ + + +insert into before_t1 values(1); -- allowed +go +~~ROW COUNT: 1~~ + + +update before_t1 set a = 2 where a = 1; -- allowed +go +~~ROW COUNT: 1~~ + + +delete from before_t1 where a = 2; -- allowed +go +~~ROW COUNT: 1~~ + + +insert into after_t1 values(1); -- allowed +go +~~ROW COUNT: 1~~ + + +update after_t1 set a = 2 where a = 1; -- allowed +go +~~ROW COUNT: 1~~ + + +delete from after_t1 where a = 2; -- allowed +go +~~ROW COUNT: 1~~ + + +use master; +go + +-- tsql user=db_roles_l5 password=123 +-- Basic membership check +use db_roles_db1 +go + +SELECT IS_MEMBER('db_datareader') +GO +~~START~~ +int +1 +~~END~~ + + +SELECT IS_MEMBER('db_datawriter') +GO +~~START~~ +int +1 +~~END~~ + + +-- user is a member of role which is a member of db_datareader/db_datawriter, objects should be accessible +select * from after_t1; -- allowed +go +~~START~~ +int +~~END~~ + + +select * from before_t1; -- allowed +go +~~START~~ +int +~~END~~ + + +select * from after_v1; -- allowed +go +~~START~~ +int +2 +~~END~~ + + +select * from before_v1; -- allowed +go +~~START~~ +int +2 +~~END~~ + + +insert into before_t1 values(1); -- allowed +go +~~ROW COUNT: 1~~ + + +update before_t1 set a = 2 where a = 1; -- allowed +go +~~ROW COUNT: 1~~ + + +delete from before_t1 where a = 2; -- allowed +go +~~ROW COUNT: 1~~ + + +insert into after_t1 values(1); -- allowed +go +~~ROW COUNT: 1~~ + + +update after_t1 set a = 2 where a = 1; -- allowed +go +~~ROW COUNT: 1~~ + + +delete from after_t1 where a = 2; -- allowed +go +~~ROW COUNT: 1~~ + + +use master; +go + +-- tsql +-- Basic membership check +use db_roles_db1 +go + +SELECT IS_ROLEMEMBER('db_datareader', 'db_roles_u1') +GO +~~START~~ +int +1 +~~END~~ + + +SELECT IS_ROLEMEMBER('db_datawriter', 'db_roles_u1') +GO +~~START~~ +int +1 +~~END~~ + + +SELECT IS_ROLEMEMBER('db_datareader', 'db_roles_r1') +GO +~~START~~ +int +1 +~~END~~ + + +SELECT IS_ROLEMEMBER('db_datawriter', 'db_roles_r1') +GO +~~START~~ +int +1 +~~END~~ + + +exec sp_droprolemember 'db_datareader', 'db_roles_u1'; +go + +exec sp_droprolemember 'db_datareader', 'db_roles_r1'; +go + +-- Basic membership check +SELECT IS_ROLEMEMBER('db_datareader', 'db_roles_u1') +GO +~~START~~ +int +0 +~~END~~ + + +SELECT IS_ROLEMEMBER('db_datawriter', 'db_roles_u1') +GO +~~START~~ +int +1 +~~END~~ + + +SELECT IS_ROLEMEMBER('db_datareader', 'db_roles_r1') +GO +~~START~~ +int +0 +~~END~~ + + +SELECT IS_ROLEMEMBER('db_datawriter', 'db_roles_r1') +GO +~~START~~ +int +1 +~~END~~ + + +use master; +go + +-- tsql user=db_roles_l5 password=123 +-- Basic membership check +use db_roles_db1 +go + +SELECT IS_MEMBER('db_datareader') +GO +~~START~~ +int +0 +~~END~~ + + +SELECT IS_MEMBER('db_datawriter') +GO +~~START~~ +int +1 +~~END~~ + + +-- user is a member of role which is not a member of db_datareader, objects should not be accessible +select * from after_t1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t1)~~ + + +select * from before_t1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_t1)~~ + + +select * from after_v1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view after_v1)~~ + + +select * from before_v1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view before_v1)~~ + + +insert into after_t1 values(1); -- allowed +go +~~ROW COUNT: 1~~ + + +use master +go + +-- tsql +use db_roles_db1 +go +exec sp_droprolemember 'db_datawriter', 'db_roles_r1'; +go +exec sp_droprolemember 'db_datawriter', 'db_roles_u1'; +go + +use master +go + +-- tsql user=db_roles_l5 password=123 +-- user is a member of role which is not a member of db_datawriter, objects should not be accessible +use db_roles_db1 +go +insert into before_t1 values(1); -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_t1)~~ + + +update before_t1 set a = 2 where a = 1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_t1)~~ + + +delete from before_t1 where a = 2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_t1)~~ + + +insert into after_t1 values(1); -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t1)~~ + + +update after_t1 set a = 2 where a = 1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t1)~~ + + +delete from after_t1 where a = 2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t1)~~ + + +use master; +go + +-- tsql user=db_roles_l1 password=123 +-- Basic membership check +use db_roles_db1 +go + +SELECT IS_MEMBER('db_datareader') +GO +~~START~~ +int +0 +~~END~~ + + +SELECT IS_MEMBER('db_datawriter') +GO +~~START~~ +int +0 +~~END~~ + + +-- user is not a member of db_datareader/db_datawriter, objects should not be accessible +select * from after_t1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t1)~~ + + +select * from before_t1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_t1)~~ + + +select * from after_v1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view after_v1)~~ + + +select * from before_v1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view before_v1)~~ + + +insert into before_t1 values(1); -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_t1)~~ + + +update before_t1 set a = 2 where a = 1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_t1)~~ + + +delete from before_t1 where a = 2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_t1)~~ + + +insert into after_t1 values(1); -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t1)~~ + + +update after_t1 set a = 2 where a = 1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t1)~~ + + +delete from after_t1 where a = 2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t1)~~ + + +use master; +go + +-- psql +-- Need to terminate active session before cleaning up the login +SELECT pg_terminate_backend(pid) FROM pg_stat_get_activity(NULL) +WHERE sys.suser_name(usesysid) = 'db_roles_l1' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +go +~~START~~ +bool +t +~~END~~ + + +-- Wait to sync with another session +SELECT pg_sleep(1); +go +~~START~~ +void + +~~END~~ + + +-- Need to terminate active session before cleaning up the login +SELECT pg_terminate_backend(pid) FROM pg_stat_get_activity(NULL) +WHERE sys.suser_name(usesysid) = 'db_roles_l2' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +go +~~START~~ +bool +t +~~END~~ + + +-- Wait to sync with another session +SELECT pg_sleep(1); +go +~~START~~ +void + +~~END~~ + + +-- Need to terminate active session before cleaning up the login +SELECT pg_terminate_backend(pid) FROM pg_stat_get_activity(NULL) +WHERE sys.suser_name(usesysid) = 'db_roles_l3' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +go +~~START~~ +bool +t +~~END~~ + + +-- Wait to sync with another session +SELECT pg_sleep(1); +go +~~START~~ +void + +~~END~~ + + +-- Need to terminate active session before cleaning up the login +SELECT pg_terminate_backend(pid) FROM pg_stat_get_activity(NULL) +WHERE sys.suser_name(usesysid) = 'db_roles_l4' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +go +~~START~~ +bool +t +~~END~~ + + +-- Wait to sync with another session +SELECT pg_sleep(1); +go +~~START~~ +void + +~~END~~ + + +-- Need to terminate active session before cleaning up the login +SELECT pg_terminate_backend(pid) FROM pg_stat_get_activity(NULL) +WHERE sys.suser_name(usesysid) = 'db_roles_l5' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +go +~~START~~ +bool +t +~~END~~ + + +-- Wait to sync with another session +SELECT pg_sleep(1); +go +~~START~~ +void + +~~END~~ + + +-- tsql +-- drop objects +use db_roles_db1 +go + +drop table db_roles_schema_1.before_t1; +go + +drop table db_roles_schema_1.after_t1; +go + +drop table db_roles_schema_2.before_created_by_dbo_t1; +go + +drop table db_roles_schema_2.after_created_by_dbo_t1; +go + +drop table db_roles_schema_2.before_created_by_u4_t1; +go + +drop table db_roles_schema_2.after_created_by_u4_t1; +go + +drop table db_roles_schema_3.db_roles_t1; +go + +drop view db_roles_schema_1.before_v1; +go + +drop view db_roles_schema_1.after_v1; +go + +drop view db_roles_schema_2.before_created_by_dbo_v1; +go + +drop view db_roles_schema_2.after_created_by_dbo_v1; +go + +drop view db_roles_schema_2.before_created_by_u4_v1; +go + +drop view db_roles_schema_2.after_created_by_u4_v1; +go + +drop view db_roles_schema_3.db_roles_v1; +go + +drop schema db_roles_schema_1; +go + +drop schema db_roles_schema_2; +go + +drop schema db_roles_schema_3; +go + +drop table before_t1; +go + +drop table after_t1; +go + +drop view before_v1; +go + +drop view after_v1; +go + +drop user db_roles_u1; +go + +drop user db_roles_u4; +go + +drop user db_roles_u5; +go + +drop role db_roles_r1; +go + +use master; +go + +drop table t1_in_master; +go + +drop user db_roles_u1; +go + +drop login db_roles_l1; +go + +drop login db_roles_l2; +go + +drop login db_roles_l3; +go + +drop login db_roles_l4; +go + +drop login db_roles_l5; +go + +drop database db_roles_db1; +go diff --git a/test/JDBC/expected/db_accessadmin-vu-verify.out b/test/JDBC/expected/db_accessadmin-vu-verify.out index 8c8ca2cf09..e3075155dd 100644 --- a/test/JDBC/expected/db_accessadmin-vu-verify.out +++ b/test/JDBC/expected/db_accessadmin-vu-verify.out @@ -51,7 +51,7 @@ GO ~~ERROR (Message: role "babel_5136_babel_5136_l1" does not exist)~~ --- Cannot add fixed roles ass member of db_accessadmin +-- Cannot add fixed roles as member of db_accessadmin ALTER ROLE db_accessadmin ADD MEMBER syadmin GO ~~ERROR (Code: 33557097)~~ @@ -100,6 +100,31 @@ GO ~~ERROR (Message: Cannot use the special principal 'db_accessadmin')~~ +-- Cannot GRANT/REVOKE on objects TO/FROM db_accessadmin +GRANT ALL on object::t1 to db_accessadmin; -- Error, no grant on special roles +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny or revoke permissions to or from special roles.)~~ + +REVOKE ALL on object::t1 to db_accessadmin; -- Error, no grant on special roles +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny or revoke permissions to or from special roles.)~~ + +GRANT SELECT on object::t1 to db_accessadmin; -- Error, no grant on special roles +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny or revoke permissions to or from special roles.)~~ + +REVOKE EXECUTE on object::t1 to db_accessadmin; -- Error, no grant on special roles +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny or revoke permissions to or from special roles.)~~ + -- MEMBERS OF db_accessadmin WILL ALWAYS HAVE CONNECT PRIVILEGES REVOKE CONNECT FROM babel_5136_db_accessadmin_user diff --git a/test/JDBC/expected/single_db/BABEL-2403.out b/test/JDBC/expected/single_db/BABEL-2403.out index c000969d27..916f4cdf66 100644 --- a/test/JDBC/expected/single_db/BABEL-2403.out +++ b/test/JDBC/expected/single_db/BABEL-2403.out @@ -95,6 +95,18 @@ name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_user_ext m text#!#sys#!#name#!#{"Rule": " in babelfish_authid_user_ext must also exist in babelfish_sysdatabases"} name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_user_ext must also exist in pg_authid"} text#!#sys#!#name#!#{"Rule": " in babelfish_authid_user_ext must also exist in babelfish_sysdatabases"} +name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_user_ext must also exist in pg_authid"} +text#!#sys#!#name#!#{"Rule": " in babelfish_authid_user_ext must also exist in babelfish_sysdatabases"} +name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_user_ext must also exist in pg_authid"} +text#!#sys#!#name#!#{"Rule": " in babelfish_authid_user_ext must also exist in babelfish_sysdatabases"} +name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_user_ext must also exist in pg_authid"} +text#!#sys#!#name#!#{"Rule": " in babelfish_authid_user_ext must also exist in babelfish_sysdatabases"} +name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_user_ext must also exist in pg_authid"} +text#!#sys#!#name#!#{"Rule": " in babelfish_authid_user_ext must also exist in babelfish_sysdatabases"} +name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_user_ext must also exist in pg_authid"} +text#!#sys#!#name#!#{"Rule": " in babelfish_authid_user_ext must also exist in babelfish_sysdatabases"} +name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_user_ext must also exist in pg_authid"} +text#!#sys#!#name#!#{"Rule": " in babelfish_authid_user_ext must also exist in babelfish_sysdatabases"} name#!#sys#!#nspname#!#{"Rule": " in babelfish_function_ext must also exist in babelfish_namespace_ext"} name#!#pg_catalog#!#proname#!#{"Rule": " in babelfish_function_ext must also exist in pg_proc"} name#!#sys#!#nspname#!#{"Rule": " in babelfish_function_ext must also exist in babelfish_namespace_ext"} @@ -180,6 +192,18 @@ name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_user_ext m text#!#sys#!#name#!#{"Rule": " in babelfish_authid_user_ext must also exist in babelfish_sysdatabases"} name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_user_ext must also exist in pg_authid"} text#!#sys#!#name#!#{"Rule": " in babelfish_authid_user_ext must also exist in babelfish_sysdatabases"} +name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_user_ext must also exist in pg_authid"} +text#!#sys#!#name#!#{"Rule": " in babelfish_authid_user_ext must also exist in babelfish_sysdatabases"} +name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_user_ext must also exist in pg_authid"} +text#!#sys#!#name#!#{"Rule": " in babelfish_authid_user_ext must also exist in babelfish_sysdatabases"} +name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_user_ext must also exist in pg_authid"} +text#!#sys#!#name#!#{"Rule": " in babelfish_authid_user_ext must also exist in babelfish_sysdatabases"} +name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_user_ext must also exist in pg_authid"} +text#!#sys#!#name#!#{"Rule": " in babelfish_authid_user_ext must also exist in babelfish_sysdatabases"} +name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_user_ext must also exist in pg_authid"} +text#!#sys#!#name#!#{"Rule": " in babelfish_authid_user_ext must also exist in babelfish_sysdatabases"} +name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_user_ext must also exist in pg_authid"} +text#!#sys#!#name#!#{"Rule": " in babelfish_authid_user_ext must also exist in babelfish_sysdatabases"} name#!#sys#!#nspname#!#{"Rule": " in babelfish_function_ext must also exist in babelfish_namespace_ext"} name#!#pg_catalog#!#proname#!#{"Rule": " in babelfish_function_ext must also exist in pg_proc"} name#!#sys#!#nspname#!#{"Rule": " in babelfish_function_ext must also exist in babelfish_namespace_ext"} diff --git a/test/JDBC/expected/single_db/BABEL-LOGIN-USER-EXT.out b/test/JDBC/expected/single_db/BABEL-LOGIN-USER-EXT.out index 78fe8fe42c..9b37746703 100644 --- a/test/JDBC/expected/single_db/BABEL-LOGIN-USER-EXT.out +++ b/test/JDBC/expected/single_db/BABEL-LOGIN-USER-EXT.out @@ -696,17 +696,25 @@ GO varchar#!#nvarchar#!#varchar#!#nvarchar#!#nvarchar db1_guest#!#guest#!##!#db1#!#guest db_accessadmin#!#db_accessadmin#!##!#db1#!# +db_datareader#!#db_datareader#!##!#db1#!# +db_datawriter#!#db_datawriter#!##!#db1#!# db_owner#!#db_owner#!##!#db1#!# dbo#!#dbo#!##!#db1#!#dbo master_db_accessadmin#!#db_accessadmin#!##!#master#!# +master_db_datareader#!#db_datareader#!##!#master#!# +master_db_datawriter#!#db_datawriter#!##!#master#!# master_db_owner#!#db_owner#!##!#master#!# master_dbo#!#dbo#!##!#master#!#dbo master_guest#!#guest#!##!#master#!#guest msdb_db_accessadmin#!#db_accessadmin#!##!#msdb#!# +msdb_db_datareader#!#db_datareader#!##!#msdb#!# +msdb_db_datawriter#!#db_datawriter#!##!#msdb#!# msdb_db_owner#!#db_owner#!##!#msdb#!# msdb_dbo#!#dbo#!##!#msdb#!#dbo msdb_guest#!#guest#!##!#msdb#!#guest tempdb_db_accessadmin#!#db_accessadmin#!##!#tempdb#!# +tempdb_db_datareader#!#db_datareader#!##!#tempdb#!# +tempdb_db_datawriter#!#db_datawriter#!##!#tempdb#!# tempdb_db_owner#!#db_owner#!##!#tempdb#!# tempdb_dbo#!#dbo#!##!#tempdb#!#dbo tempdb_guest#!#guest#!##!#tempdb#!#guest @@ -872,14 +880,20 @@ GO ~~START~~ varchar#!#nvarchar#!#varchar#!#nvarchar#!#nvarchar master_db_accessadmin#!#db_accessadmin#!##!#master#!# +master_db_datareader#!#db_datareader#!##!#master#!# +master_db_datawriter#!#db_datawriter#!##!#master#!# master_db_owner#!#db_owner#!##!#master#!# master_dbo#!#dbo#!##!#master#!#dbo master_guest#!#guest#!##!#master#!#guest msdb_db_accessadmin#!#db_accessadmin#!##!#msdb#!# +msdb_db_datareader#!#db_datareader#!##!#msdb#!# +msdb_db_datawriter#!#db_datawriter#!##!#msdb#!# msdb_db_owner#!#db_owner#!##!#msdb#!# msdb_dbo#!#dbo#!##!#msdb#!#dbo msdb_guest#!#guest#!##!#msdb#!#guest tempdb_db_accessadmin#!#db_accessadmin#!##!#tempdb#!# +tempdb_db_datareader#!#db_datareader#!##!#tempdb#!# +tempdb_db_datawriter#!#db_datawriter#!##!#tempdb#!# tempdb_db_owner#!#db_owner#!##!#tempdb#!# tempdb_dbo#!#dbo#!##!#tempdb#!#dbo tempdb_guest#!#guest#!##!#tempdb#!#guest @@ -931,17 +945,25 @@ GO varchar#!#varchar#!#nvarchar#!#nvarchar#!#nvarchar db1_guest#!##!#guest#!#db1#!#guest db_accessadmin#!##!#db_accessadmin#!#db1#!# +db_datareader#!##!#db_datareader#!#db1#!# +db_datawriter#!##!#db_datawriter#!#db1#!# db_owner#!##!#db_owner#!#db1#!# dbo#!##!#dbo#!#db1#!#dbo master_db_accessadmin#!##!#db_accessadmin#!#master#!# +master_db_datareader#!##!#db_datareader#!#master#!# +master_db_datawriter#!##!#db_datawriter#!#master#!# master_db_owner#!##!#db_owner#!#master#!# master_dbo#!##!#dbo#!#master#!#dbo master_guest#!##!#guest#!#master#!#guest msdb_db_accessadmin#!##!#db_accessadmin#!#msdb#!# +msdb_db_datareader#!##!#db_datareader#!#msdb#!# +msdb_db_datawriter#!##!#db_datawriter#!#msdb#!# msdb_db_owner#!##!#db_owner#!#msdb#!# msdb_dbo#!##!#dbo#!#msdb#!#dbo msdb_guest#!##!#guest#!#msdb#!#guest tempdb_db_accessadmin#!##!#db_accessadmin#!#tempdb#!# +tempdb_db_datareader#!##!#db_datareader#!#tempdb#!# +tempdb_db_datawriter#!##!#db_datawriter#!#tempdb#!# tempdb_db_owner#!##!#db_owner#!#tempdb#!# tempdb_dbo#!##!#dbo#!#tempdb#!#dbo tempdb_guest#!##!#guest#!#tempdb#!#guest @@ -957,6 +979,8 @@ varchar#!#varchar guest#!#guest dbo#!#dbo db_accessadmin#!# +db_datareader#!# +db_datawriter#!# db_owner#!# INFORMATION_SCHEMA#!# public#!# @@ -989,6 +1013,8 @@ varchar#!#varchar guest#!#guest dbo#!#dbo db_accessadmin#!# +db_datareader#!# +db_datawriter#!# db_owner#!# INFORMATION_SCHEMA#!# public#!# @@ -1128,14 +1154,20 @@ GO ~~START~~ varchar#!#nvarchar#!#varchar#!#nvarchar#!#nvarchar master_db_accessadmin#!#db_accessadmin#!##!#master#!# +master_db_datareader#!#db_datareader#!##!#master#!# +master_db_datawriter#!#db_datawriter#!##!#master#!# master_db_owner#!#db_owner#!##!#master#!# master_dbo#!#dbo#!##!#master#!#dbo master_guest#!#guest#!##!#master#!#guest msdb_db_accessadmin#!#db_accessadmin#!##!#msdb#!# +msdb_db_datareader#!#db_datareader#!##!#msdb#!# +msdb_db_datawriter#!#db_datawriter#!##!#msdb#!# msdb_db_owner#!#db_owner#!##!#msdb#!# msdb_dbo#!#dbo#!##!#msdb#!#dbo msdb_guest#!#guest#!##!#msdb#!#guest tempdb_db_accessadmin#!#db_accessadmin#!##!#tempdb#!# +tempdb_db_datareader#!#db_datareader#!##!#tempdb#!# +tempdb_db_datawriter#!#db_datawriter#!##!#tempdb#!# tempdb_db_owner#!#db_owner#!##!#tempdb#!# tempdb_dbo#!#dbo#!##!#tempdb#!#dbo tempdb_guest#!#guest#!##!#tempdb#!#guest @@ -1156,14 +1188,20 @@ GO ~~START~~ varchar#!#nvarchar#!#varchar#!#nvarchar#!#nvarchar master_db_accessadmin#!#db_accessadmin#!##!#master#!# +master_db_datareader#!#db_datareader#!##!#master#!# +master_db_datawriter#!#db_datawriter#!##!#master#!# master_db_owner#!#db_owner#!##!#master#!# master_dbo#!#dbo#!##!#master#!#dbo master_guest#!#guest#!##!#master#!#guest msdb_db_accessadmin#!#db_accessadmin#!##!#msdb#!# +msdb_db_datareader#!#db_datareader#!##!#msdb#!# +msdb_db_datawriter#!#db_datawriter#!##!#msdb#!# msdb_db_owner#!#db_owner#!##!#msdb#!# msdb_dbo#!#dbo#!##!#msdb#!#dbo msdb_guest#!#guest#!##!#msdb#!#guest tempdb_db_accessadmin#!#db_accessadmin#!##!#tempdb#!# +tempdb_db_datareader#!#db_datareader#!##!#tempdb#!# +tempdb_db_datawriter#!#db_datawriter#!##!#tempdb#!# tempdb_db_owner#!#db_owner#!##!#tempdb#!# tempdb_dbo#!#dbo#!##!#tempdb#!#dbo tempdb_guest#!#guest#!##!#tempdb#!#guest @@ -1454,6 +1492,8 @@ varchar babel_4935_no_sysadmin1 babel_4935_no_sysadmin2 db_accessadmin +db_datareader +db_datawriter db_owner dbo guest @@ -1472,6 +1512,8 @@ varchar babel_4935_no_sysadmin1 babel_4935_no_sysadmin2 db_accessadmin +db_datareader +db_datawriter db_owner dbo guest @@ -1489,6 +1531,8 @@ GO varchar babel_4935_no_sysadmin1 db_accessadmin +db_datareader +db_datawriter db_owner dbo guest @@ -1505,6 +1549,8 @@ GO ~~START~~ varchar db_accessadmin +db_datareader +db_datawriter db_owner dbo guest diff --git a/test/JDBC/expected/single_db/BABEL-USER.out b/test/JDBC/expected/single_db/BABEL-USER.out index 2917e1f1fc..c3ce6672b6 100644 --- a/test/JDBC/expected/single_db/BABEL-USER.out +++ b/test/JDBC/expected/single_db/BABEL-USER.out @@ -51,17 +51,25 @@ GO varchar#!#varchar#!#nvarchar#!#nvarchar#!#nvarchar db1_guest#!##!#guest#!#db1#!#guest db_accessadmin#!##!#db_accessadmin#!#db1#!# +db_datareader#!##!#db_datareader#!#db1#!# +db_datawriter#!##!#db_datawriter#!#db1#!# db_owner#!##!#db_owner#!#db1#!# dbo#!##!#dbo#!#db1#!#dbo master_db_accessadmin#!##!#db_accessadmin#!#master#!# +master_db_datareader#!##!#db_datareader#!#master#!# +master_db_datawriter#!##!#db_datawriter#!#master#!# master_db_owner#!##!#db_owner#!#master#!# master_dbo#!##!#dbo#!#master#!#dbo master_guest#!##!#guest#!#master#!#guest msdb_db_accessadmin#!##!#db_accessadmin#!#msdb#!# +msdb_db_datareader#!##!#db_datareader#!#msdb#!# +msdb_db_datawriter#!##!#db_datawriter#!#msdb#!# msdb_db_owner#!##!#db_owner#!#msdb#!# msdb_dbo#!##!#dbo#!#msdb#!#dbo msdb_guest#!##!#guest#!#msdb#!#guest tempdb_db_accessadmin#!##!#db_accessadmin#!#tempdb#!# +tempdb_db_datareader#!##!#db_datareader#!#tempdb#!# +tempdb_db_datawriter#!##!#db_datawriter#!#tempdb#!# tempdb_db_owner#!##!#db_owner#!#tempdb#!# tempdb_dbo#!##!#dbo#!#tempdb#!#dbo tempdb_guest#!##!#guest#!#tempdb#!#guest @@ -77,6 +85,8 @@ varchar#!#varchar guest#!#guest dbo#!#dbo db_accessadmin#!# +db_datareader#!# +db_datawriter#!# db_owner#!# INFORMATION_SCHEMA#!# public#!# diff --git a/test/JDBC/expected/single_db/Test_rename_db_single-db.out b/test/JDBC/expected/single_db/Test_rename_db_single-db.out index 227059870a..5a0c7abc7b 100644 --- a/test/JDBC/expected/single_db/Test_rename_db_single-db.out +++ b/test/JDBC/expected/single_db/Test_rename_db_single-db.out @@ -33,6 +33,8 @@ rename_db_schema1#!#rename_db_schema1 ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar db_accessadmin#!##!#db_accessadmin#!#rename_db_database1 +db_datareader#!##!#db_datareader#!#rename_db_database1 +db_datawriter#!##!#db_datawriter#!#rename_db_database1 db_owner#!##!#db_owner#!#rename_db_database1 dbo#!##!#dbo#!#rename_db_database1 rename_db_database1_guest#!##!#guest#!#rename_db_database1 @@ -82,6 +84,8 @@ rename_db_schema1#!#rename_db_schema1 ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar db_accessadmin#!##!#db_accessadmin#!#rename_db_database2 +db_datareader#!##!#db_datareader#!#rename_db_database2 +db_datawriter#!##!#db_datawriter#!#rename_db_database2 db_owner#!##!#db_owner#!#rename_db_database2 dbo#!##!#dbo#!#rename_db_database2 rename_db_database2_guest#!##!#guest#!#rename_db_database2 @@ -131,6 +135,8 @@ rename_db_schema1#!#rename_db_schema1 ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar db_accessadmin#!##!#db_accessadmin#!#rename_db_database1 +db_datareader#!##!#db_datareader#!#rename_db_database1 +db_datawriter#!##!#db_datawriter#!#rename_db_database1 db_owner#!##!#db_owner#!#rename_db_database1 dbo#!##!#dbo#!#rename_db_database1 rename_db_database1_guest#!##!#guest#!#rename_db_database1 @@ -180,6 +186,8 @@ rename_db_schema1#!#rename_db_schema1 ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar db_accessadmin#!##!#db_accessadmin#!#rename_db_database2 +db_datareader#!##!#db_datareader#!#rename_db_database2 +db_datawriter#!##!#db_datawriter#!#rename_db_database2 db_owner#!##!#db_owner#!#rename_db_database2 dbo#!##!#dbo#!#rename_db_database2 rename_db_database2_guest#!##!#guest#!#rename_db_database2 @@ -241,6 +249,8 @@ rename_db_schema1#!#rename_db_schema1 ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar db_accessadmin#!##!#db_accessadmin#!#rename_db_database1 +db_datareader#!##!#db_datareader#!#rename_db_database1 +db_datawriter#!##!#db_datawriter#!#rename_db_database1 db_owner#!##!#db_owner#!#rename_db_database1 dbo#!##!#dbo#!#rename_db_database1 rename_db_database1_guest#!##!#guest#!#rename_db_database1 @@ -290,6 +300,8 @@ rename_db_schema1#!#rename_db_schema1 ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar db_accessadmin#!##!#db_accessadmin#!#rename_db_database2 +db_datareader#!##!#db_datareader#!#rename_db_database2 +db_datawriter#!##!#db_datawriter#!#rename_db_database2 db_owner#!##!#db_owner#!#rename_db_database2 dbo#!##!#dbo#!#rename_db_database2 rename_db_database2_guest#!##!#guest#!#rename_db_database2 @@ -339,6 +351,8 @@ rename_db_schema1#!#rename_db_schema1 ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar db_accessadmin#!##!#db_accessadmin#!#rename_db_database1 +db_datareader#!##!#db_datareader#!#rename_db_database1 +db_datawriter#!##!#db_datawriter#!#rename_db_database1 db_owner#!##!#db_owner#!#rename_db_database1 dbo#!##!#dbo#!#rename_db_database1 rename_db_database1_guest#!##!#guest#!#rename_db_database1 @@ -388,6 +402,8 @@ rename_db_schema1#!#rename_db_schema1 ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar db_accessadmin#!##!#db_accessadmin#!#rename_db_database2 +db_datareader#!##!#db_datareader#!#rename_db_database2 +db_datawriter#!##!#db_datawriter#!#rename_db_database2 db_owner#!##!#db_owner#!#rename_db_database2 dbo#!##!#dbo#!#rename_db_database2 rename_db_database2_guest#!##!#guest#!#rename_db_database2 diff --git a/test/JDBC/expected/single_db/datareader_datawriter.out b/test/JDBC/expected/single_db/datareader_datawriter.out new file mode 100644 index 0000000000..570128b3df --- /dev/null +++ b/test/JDBC/expected/single_db/datareader_datawriter.out @@ -0,0 +1,1914 @@ +-- tsql +-- Error cases +create role db_datareader; -- Error, this role already exists +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: role "master_db_datareader" already exists)~~ + + +create role db_datawriter; -- Error, this role already exists +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: role "master_db_datawriter" already exists)~~ + + +create table t1(a int); +go +create proc p1 as select 1; +go + +-- grants not allowed on these special roles +grant select on schema::dbo to db_datareader; -- Error, no grant on special roles +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny or revoke permissions to or from special roles.)~~ + + +grant execute on schema::dbo to db_datawriter; -- Error, no grant on special roles +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny or revoke permissions to or from special roles.)~~ + + +revoke select on schema::dbo from db_datareader; -- Error, no grant on special roles +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny or revoke permissions to or from special roles.)~~ + + +revoke execute on schema::dbo from db_datawriter; -- Error, no grant on special roles +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny or revoke permissions to or from special roles.)~~ + + +grant select on object::t1 to db_datareader; -- Error, no grant on special roles +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny or revoke permissions to or from special roles.)~~ + + +grant insert on object::t1 to db_datawriter; -- Error, no grant on special roles +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny or revoke permissions to or from special roles.)~~ + + +grant execute on object::p1 to db_datareader; -- Error, no grant on special roles +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny or revoke permissions to or from special roles.)~~ + + +revoke select on object::t1 to db_datareader; -- Error, no grant on special roles +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny or revoke permissions to or from special roles.)~~ + + +revoke insert on object::t1 to db_datawriter; -- Error, no grant on special roles +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny or revoke permissions to or from special roles.)~~ + + +revoke execute on object::p1 to db_datareader; -- Error, no grant on special roles +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny or revoke permissions to or from special roles.)~~ + + +grant all on object::t1 to db_datareader; -- Error, no grant on special roles +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny or revoke permissions to or from special roles.)~~ + + +revoke all on object::t1 to db_datareader; -- Error, no grant on special roles +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny or revoke permissions to or from special roles.)~~ + + +drop role db_datareader; -- Error, should not be dropped +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot drop the role 'db_datareader'.)~~ + + +drop role db_datawriter; -- Error, should not be dropped +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot drop the role 'db_datawriter'.)~~ + + +drop table t1; +go +drop proc p1; +go + +-- create login, user and add members +create database db_roles_db1; +go + +use db_roles_db1; +go + +create login db_roles_l1 with password = '123'; +go + +create login db_roles_l2 with password = '123'; +go + +create login db_roles_l3 with password = '123'; +go + +create login db_roles_l4 with password = '123'; +go + +create login db_roles_l5 with password = '123'; +go + +create user db_roles_u4 for login db_roles_l4; +go + +create user db_roles_u5 for login db_roles_l5; +go + +alter server role sysadmin add member db_roles_l2; +go + +create user db_datareader for login db_roles_l1; -- Error, this role already exists +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: role "db_datareader" already exists)~~ + + +create user db_datawriter for login db_roles_l1; -- Error, this role already exists +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: role "db_datawriter" already exists)~~ + + +create user db_roles_u1 for login db_roles_l1; +go + +create role db_roles_r1; +go + +alter role db_roles_r1 add member db_roles_u5; +go + +create schema db_roles_schema_1; +go + +create schema db_roles_schema_2 authorization db_roles_u4; +go + +create table db_roles_schema_1.before_t1(a int); +go + +create view db_roles_schema_1.before_v1 as select 2; +go + +create table db_roles_schema_2.before_created_by_dbo_t1(a int); +go + +create view db_roles_schema_2.before_created_by_dbo_v1 as select 2; +go + +create table before_t1(a int); +go + +create view before_v1 as select 2; +go + +use master; +go + +create user db_roles_u1 for login db_roles_l1; +go + +create table t1_in_master(a int); +go + +-- tsql user=db_roles_l4 password=123 +use db_roles_db1; +go + +create table db_roles_schema_2.before_created_by_u4_t1(a int); +go + +create view db_roles_schema_2.before_created_by_u4_v1 as select 2; +go + +use master; +go + +-- tsql +use db_roles_db1 +go + +alter role db_datareader add member db_roles_u1; +go + +alter role db_datawriter add member db_roles_u1; +go + +alter role db_datareader add member db_roles_r1; +go + +alter role db_datawriter add member db_roles_r1; +go + +select count(*) from sys.database_principals where name like '%db_datareader%'; +go +~~START~~ +int +1 +~~END~~ + + +select count(*) from sys.database_principals where name like '%db_datawriter%'; +go +~~START~~ +int +1 +~~END~~ + + +-- Test sp_helpuser +CREATE TABLE #UserRoles(userName sys.SYSNAME, roleName sys.SYSNAME, loginName sys.SYSNAME NULL, defdb sys.SYSNAME NULL, defschema sys.SYSNAME, userid INT, sid sys.VARBINARY(85)); +go +-- Insert the results of sp_helpuser into the temporary table +INSERT INTO #UserRoles EXEC sp_helpuser; +go +~~ROW COUNT: 8~~ + +-- Select the desired fields from the temporary table +SELECT userName, roleName FROM #UserRoles WHERE roleName IN ('db_datareader', 'db_datawriter'); +go +~~START~~ +varchar#!#varchar +db_roles_r1#!#db_datareader +db_roles_r1#!#db_datawriter +db_roles_u1#!#db_datareader +db_roles_u1#!#db_datawriter +~~END~~ + +-- Drop the temporary table +DROP TABLE #UserRoles; +go + +-- Test sp_helprole +CREATE TABLE #UserRoles(RoleName sys.SYSNAME, RoleId integer, IsAppRole integer); +go +-- Insert the results of sp_helprole into the temporary table +INSERT INTO #UserRoles EXEC sp_helprole; +go +~~ROW COUNT: 5~~ + +-- Select the desired fields from the temporary table +SELECT RoleName, IsAppRole FROM #UserRoles WHERE RoleName IN ('db_datareader', 'db_datawriter'); +go +~~START~~ +varchar#!#int +db_datareader#!#0 +db_datawriter#!#0 +~~END~~ + +-- Drop the temporary table +DROP TABLE #UserRoles; +go + +-- Test sp_helprolemember +CREATE TABLE #UserRoles(RoleName sys.SYSNAME, MemberName sys.SYSNAME, MemberSID sys.VARBINARY(85)); +go +-- Insert the results of sp_helprolemember into the temporary table +INSERT INTO #UserRoles EXEC sp_helprolemember; +go +~~ROW COUNT: 6~~ + +-- Select the desired fields from the temporary table +SELECT RoleName, MemberName FROM #UserRoles WHERE RoleName IN ('db_datareader', 'db_datawriter'); +go +~~START~~ +varchar#!#varchar +db_datareader#!#db_roles_r1 +db_datareader#!#db_roles_u1 +db_datawriter#!#db_roles_r1 +db_datawriter#!#db_roles_u1 +~~END~~ + +-- Drop the temporary table +DROP TABLE #UserRoles; +go + +use master +go + +-- tsql user=db_roles_l4 password=123 +use db_roles_db1; +go + +create table db_roles_schema_2.after_created_by_u4_t1(a int); +go + +create view db_roles_schema_2.after_created_by_u4_v1 as select 1; +go + +use master; +go + +-- tsql +use db_roles_db1 +go + +create table after_t1(a int); +go + +create view after_v1 as select 2; +go + +create table db_roles_schema_1.after_t1(a int); +go + +create view db_roles_schema_1.after_v1 as select 2; +go + +create table db_roles_schema_2.after_created_by_dbo_t1(a int); +go + +create view db_roles_schema_2.after_created_by_dbo_v1 as select 2; +go + +use master; +go + +-- tsql user=db_roles_l2 password=123 +-- member of sysadmin can add/drop user as a member of db_datareader/db_datawriter +use db_roles_db1; +go + +alter role db_datareader drop member db_roles_u1; +go + +alter role db_datawriter drop member db_roles_u1; +go + +alter role db_datareader add member db_roles_u1; +go + +alter role db_datawriter add member db_roles_u1; +go + +exec sp_droprolemember 'db_datareader', 'db_roles_u1'; +go + +exec sp_droprolemember 'db_datawriter', 'db_roles_u1'; +go + +exec sp_addrolemember 'db_datareader', 'db_roles_u1'; +go + +exec sp_addrolemember 'db_datawriter', 'db_roles_u1'; +go + +use master; +go + +-- tsql +alter authorization on database::db_roles_db1 to db_roles_l3; +go + +-- tsql user=db_roles_l3 password=123 +use db_roles_db1 +go + +create schema db_roles_schema_3; +go + +create table db_roles_schema_3.db_roles_t1(a int); +go + +create view db_roles_schema_3.db_roles_v1 as select 2; +go + +-- database owner can add other roles as a member of database roles +alter role db_datareader drop member db_roles_u1; +go + +alter role db_datawriter drop member db_roles_u1; +go + +alter role db_datareader add member db_roles_u1; +go + +alter role db_datawriter add member db_roles_u1; +go + +exec sp_droprolemember 'db_datareader', 'db_roles_u1'; +go + +exec sp_droprolemember 'db_datawriter', 'db_roles_u1'; +go + +exec sp_addrolemember 'db_datareader', 'db_roles_u1'; +go + +exec sp_addrolemember 'db_datawriter', 'db_roles_u1'; +go + +-- remove select privilege on the schema and object, still the objects should be accessible +revoke select on schema::db_roles_schema_1 from db_roles_u1; +go + +revoke select on object::db_roles_schema_1.before_t1 from db_roles_u1; +go + +use master; +go + +-- tsql user=db_roles_l1 password=123 +use db_roles_db1 +go + +-- members of db_datareader/db_datawriter cannot add another role/user as its member +alter role db_datareader drop member db_roles_r1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot alter the role 'db_datareader', because it does not exist or you do not have permission.)~~ + + +alter role db_datawriter drop member db_roles_r1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot alter the role 'db_datawriter', because it does not exist or you do not have permission.)~~ + + +alter role db_datareader add member db_roles_r1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot alter the role 'db_datareader', because it does not exist or you do not have permission.)~~ + + +alter role db_datawriter add member db_roles_r1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot alter the role 'db_datawriter', because it does not exist or you do not have permission.)~~ + + +exec sp_droprolemember 'db_datareader', 'db_roles_r1'; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot alter the role 'db_datareader', because it does not exist or you do not have permission.)~~ + + +exec sp_droprolemember 'db_datawriter', 'db_roles_r1'; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot alter the role 'db_datawriter', because it does not exist or you do not have permission.)~~ + + +exec sp_addrolemember 'db_datareader', 'db_roles_r1'; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot alter the role 'db_datareader', because it does not exist or you do not have permission.)~~ + + +exec sp_addrolemember 'db_datawriter', 'db_roles_r1'; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot alter the role 'db_datawriter', because it does not exist or you do not have permission.)~~ + + +-- Basic membership check +SELECT IS_MEMBER('db_datareader') +GO +~~START~~ +int +1 +~~END~~ + + +SELECT IS_MEMBER('db_datawriter') +GO +~~START~~ +int +1 +~~END~~ + + +-- user is a member of db_datareader/db_datawriter, objects should be accessible +-- objects created before and after adding the user to db roles should be accessible. +select * from after_t1; -- allowed +go +~~START~~ +int +~~END~~ + + +select * from after_v1; -- allowed +go +~~START~~ +int +2 +~~END~~ + + +insert into before_t1 values(1); -- allowed +go +~~ROW COUNT: 1~~ + + +update before_t1 set a = 2 where a = 1; -- allowed +go +~~ROW COUNT: 1~~ + + +delete from before_t1 where a = 2; -- allowed +go +~~ROW COUNT: 1~~ + + +select * from before_t1; -- allowed +go +~~START~~ +int +~~END~~ + + +select * from before_v1; -- allowed +go +~~START~~ +int +2 +~~END~~ + + +insert into after_t1 values(1); -- allowed +go +~~ROW COUNT: 1~~ + + +update after_t1 set a = 2 where a = 1; -- allowed +go +~~ROW COUNT: 1~~ + + +delete from after_t1 where a = 2; -- allowed +go +~~ROW COUNT: 1~~ + + +select * from db_roles_schema_1.after_t1; -- allowed +go +~~START~~ +int +~~END~~ + + +select * from db_roles_schema_1.after_v1; -- allowed +go +~~START~~ +int +2 +~~END~~ + + +insert into db_roles_schema_1.before_t1 values(1); -- allowed +go +~~ROW COUNT: 1~~ + + +update db_roles_schema_1.before_t1 set a = 2 where a = 1; -- allowed +go +~~ROW COUNT: 1~~ + + +delete from db_roles_schema_1.before_t1 where a = 2; -- allowed +go +~~ROW COUNT: 1~~ + + +select * from db_roles_schema_2.before_created_by_dbo_t1; -- allowed +go +~~START~~ +int +~~END~~ + + +select * from db_roles_schema_2.before_created_by_dbo_v1; -- allowed +go +~~START~~ +int +2 +~~END~~ + + +insert into db_roles_schema_2.before_created_by_dbo_t1 values(1); -- allowed +go +~~ROW COUNT: 1~~ + + +update db_roles_schema_2.before_created_by_dbo_t1 set a = 2 where a = 1; -- allowed +go +~~ROW COUNT: 1~~ + + +delete from db_roles_schema_2.before_created_by_dbo_t1 where a = 2; -- allowed +go +~~ROW COUNT: 1~~ + + +select * from db_roles_schema_2.after_created_by_dbo_t1; -- allowed +go +~~START~~ +int +~~END~~ + + +select * from db_roles_schema_2.after_created_by_dbo_v1; -- allowed +go +~~START~~ +int +2 +~~END~~ + + +insert into db_roles_schema_2.after_created_by_dbo_t1 values(1); -- allowed +go +~~ROW COUNT: 1~~ + + +update db_roles_schema_2.after_created_by_dbo_t1 set a = 2 where a = 1; -- allowed +go +~~ROW COUNT: 1~~ + + +delete from db_roles_schema_2.after_created_by_dbo_t1 where a = 2; -- allowed +go +~~ROW COUNT: 1~~ + + +select * from db_roles_schema_2.before_created_by_u4_t1; -- allowed +go +~~START~~ +int +~~END~~ + + +select * from db_roles_schema_2.before_created_by_u4_v1; -- allowed +go +~~START~~ +int +2 +~~END~~ + + +insert into db_roles_schema_2.before_created_by_u4_t1 values(1); -- allowed +go +~~ROW COUNT: 1~~ + + +update db_roles_schema_2.before_created_by_u4_t1 set a = 2 where a = 1; -- allowed +go +~~ROW COUNT: 1~~ + + +delete from db_roles_schema_2.before_created_by_u4_t1 where a = 2; -- allowed +go +~~ROW COUNT: 1~~ + + +select * from db_roles_schema_2.after_created_by_u4_t1; -- allowed +go +~~START~~ +int +~~END~~ + + +select * from db_roles_schema_2.after_created_by_u4_v1; -- allowed +go +~~START~~ +int +1 +~~END~~ + + +insert into db_roles_schema_2.after_created_by_u4_t1 values(1); -- allowed +go +~~ROW COUNT: 1~~ + + +update db_roles_schema_2.after_created_by_u4_t1 set a = 2 where a = 1; -- allowed +go +~~ROW COUNT: 1~~ + + +delete from db_roles_schema_2.after_created_by_u4_t1 where a = 2; -- allowed +go +~~ROW COUNT: 1~~ + + +select * from master.dbo.t1_in_master; -- not allowed since the user in master doesn't have read privilege +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table t1_in_master)~~ + + +insert into master.dbo.t1_in_master values(1); -- not allowed since the user in master doesn't have write privilege +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table t1_in_master)~~ + + +-- objects created by the database owner should be accessible too. +select * from db_roles_schema_3.db_roles_t1; -- allowed +go +~~START~~ +int +~~END~~ + + +select * from db_roles_schema_3.db_roles_v1; -- allowed +go +~~START~~ +int +2 +~~END~~ + + +insert into db_roles_schema_3.db_roles_t1 values(1); -- allowed +go +~~ROW COUNT: 1~~ + + +update db_roles_schema_3.db_roles_t1 set a = 2 where a = 1; -- allowed +go +~~ROW COUNT: 1~~ + + +delete from db_roles_schema_3.db_roles_t1 where a = 2; -- allowed +go +~~ROW COUNT: 1~~ + + +use master; +go + +-- tsql +-- Basic membership check +use db_roles_db1; +go + +SELECT IS_ROLEMEMBER('db_datareader', 'db_roles_u1') +GO +~~START~~ +int +1 +~~END~~ + + +SELECT IS_ROLEMEMBER('db_datawriter', 'db_roles_u1') +GO +~~START~~ +int +1 +~~END~~ + + +SELECT IS_ROLEMEMBER('db_datareader', 'db_roles_r1') +GO +~~START~~ +int +1 +~~END~~ + + +SELECT IS_ROLEMEMBER('db_datawriter', 'db_roles_r1') +GO +~~START~~ +int +1 +~~END~~ + + +alter role db_datareader drop member db_roles_u1; +go + +alter role db_datawriter drop member db_roles_u1; +go + +alter role db_datareader drop member db_roles_r1; +go + +-- Basic membership check +SELECT IS_ROLEMEMBER('db_datareader', 'db_roles_u1') +GO +~~START~~ +int +0 +~~END~~ + + +SELECT IS_ROLEMEMBER('db_datawriter', 'db_roles_u1') +GO +~~START~~ +int +0 +~~END~~ + + +SELECT IS_ROLEMEMBER('db_datareader', 'db_roles_r1') +GO +~~START~~ +int +0 +~~END~~ + + +SELECT IS_ROLEMEMBER('db_datawriter', 'db_roles_r1') +GO +~~START~~ +int +1 +~~END~~ + + +alter role db_datawriter drop member db_roles_r1; +go + +use master; +go + +alter role db_datareader add member db_roles_u1; +go + +alter role db_datawriter add member db_roles_u1; +go + +-- tsql user=db_roles_l1 password=123 +-- Basic membership check +use db_roles_db1 +go + +SELECT IS_MEMBER('db_datareader') +GO +~~START~~ +int +0 +~~END~~ + + +SELECT IS_MEMBER('db_datawriter') +GO +~~START~~ +int +0 +~~END~~ + + +-- user is not a member of db_datareader/db_datawriter, objects should not be accessible +select * from after_t1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t1)~~ + + +select * from after_v1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view after_v1)~~ + + +select * from before_t1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_t1)~~ + + +select * from before_v1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view before_v1)~~ + + +insert into before_t1 values(1); -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_t1)~~ + + +update before_t1 set a = 2 where a = 1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_t1)~~ + + +delete from before_t1 where a = 2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_t1)~~ + + +insert into after_t1 values(1); -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t1)~~ + + +update after_t1 set a = 2 where a = 1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t1)~~ + + +delete from after_t1 where a = 2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t1)~~ + + +select * from db_roles_schema_1.after_t1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t1)~~ + + +select * from db_roles_schema_1.before_t1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_t1)~~ + + +select * from db_roles_schema_1.after_v1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view after_v1)~~ + + +select * from db_roles_schema_1.before_v1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view before_v1)~~ + + +insert into db_roles_schema_1.before_t1 values(1); -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_t1)~~ + + +update db_roles_schema_1.before_t1 set a = 2 where a = 1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_t1)~~ + + +delete from db_roles_schema_1.before_t1 where a = 2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_t1)~~ + + +insert into db_roles_schema_1.after_t1 values(1); -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t1)~~ + + +update db_roles_schema_1.after_t1 set a = 2 where a = 1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t1)~~ + + +delete from db_roles_schema_1.after_t1 where a = 2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t1)~~ + + +select * from db_roles_schema_2.before_created_by_dbo_t1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_created_by_dbo_t1)~~ + + +select * from db_roles_schema_2.before_created_by_dbo_v1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view before_created_by_dbo_v1)~~ + + +insert into db_roles_schema_2.before_created_by_dbo_t1 values(1); -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_created_by_dbo_t1)~~ + + +update db_roles_schema_2.before_created_by_dbo_t1 set a = 2 where a = 1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_created_by_dbo_t1)~~ + + +delete from db_roles_schema_2.before_created_by_dbo_t1 where a = 2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_created_by_dbo_t1)~~ + + +select * from db_roles_schema_2.after_created_by_dbo_t1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_created_by_dbo_t1)~~ + + +select * from db_roles_schema_2.after_created_by_dbo_v1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view after_created_by_dbo_v1)~~ + + +insert into db_roles_schema_2.after_created_by_dbo_t1 values(1); -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_created_by_dbo_t1)~~ + + +update db_roles_schema_2.after_created_by_dbo_t1 set a = 2 where a = 1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_created_by_dbo_t1)~~ + + +delete from db_roles_schema_2.after_created_by_dbo_t1 where a = 2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_created_by_dbo_t1)~~ + + +select * from db_roles_schema_2.before_created_by_u4_t1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_created_by_u4_t1)~~ + + +select * from db_roles_schema_2.before_created_by_u4_v1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view before_created_by_u4_v1)~~ + + +insert into db_roles_schema_2.before_created_by_u4_t1 values(1); -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_created_by_u4_t1)~~ + + +update db_roles_schema_2.before_created_by_u4_t1 set a = 2 where a = 1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_created_by_u4_t1)~~ + + +delete from db_roles_schema_2.before_created_by_u4_t1 where a = 2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_created_by_u4_t1)~~ + + +select * from db_roles_schema_2.after_created_by_u4_t1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_created_by_u4_t1)~~ + + +select * from db_roles_schema_2.after_created_by_u4_v1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view after_created_by_u4_v1)~~ + + +insert into db_roles_schema_2.after_created_by_u4_t1 values(1); -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_created_by_u4_t1)~~ + + +update db_roles_schema_2.after_created_by_u4_t1 set a = 2 where a = 1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_created_by_u4_t1)~~ + + +delete from db_roles_schema_2.after_created_by_u4_t1 where a = 2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_created_by_u4_t1)~~ + + +-- objects created by the database owner should not be accessible +select * from db_roles_schema_3.db_roles_t1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table db_roles_t1)~~ + + +select * from db_roles_schema_3.db_roles_v1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view db_roles_v1)~~ + + +insert into db_roles_schema_3.db_roles_t1 values(1); -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table db_roles_t1)~~ + + +update db_roles_schema_3.db_roles_t1 set a = 2 where a = 1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table db_roles_t1)~~ + + +delete from db_roles_schema_3.db_roles_t1 where a = 2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table db_roles_t1)~~ + + +select * from master.dbo.t1_in_master; -- allowed since the user in master has read privilege +go +~~START~~ +int +~~END~~ + + +insert into master.dbo.t1_in_master values(1); -- allowed since the user in master has write privilege +go +~~ROW COUNT: 1~~ + + +use master; +go + +-- tsql +use db_roles_db1; +go + +exec sp_addrolemember 'db_datareader', 'db_roles_u1'; +go + +exec sp_addrolemember 'db_datawriter', 'db_roles_u1'; +go + +exec sp_addrolemember 'db_datareader', 'db_roles_r1'; +go + +exec sp_addrolemember 'db_datawriter', 'db_roles_r1'; +go + +use master; +go + +-- tsql user=db_roles_l1 password=123 +-- Basic membership check +use db_roles_db1 +go + +SELECT IS_MEMBER('db_datareader') +GO +~~START~~ +int +1 +~~END~~ + + +SELECT IS_MEMBER('db_datawriter') +GO +~~START~~ +int +1 +~~END~~ + + +-- user is a member of db_datareader/db_datawriter, objects should be accessible +select * from after_t1; -- allowed +go +~~START~~ +int +~~END~~ + + +select * from before_t1; -- allowed +go +~~START~~ +int +~~END~~ + + +select * from after_v1; -- allowed +go +~~START~~ +int +2 +~~END~~ + + +select * from before_v1; -- allowed +go +~~START~~ +int +2 +~~END~~ + + +insert into before_t1 values(1); -- allowed +go +~~ROW COUNT: 1~~ + + +update before_t1 set a = 2 where a = 1; -- allowed +go +~~ROW COUNT: 1~~ + + +delete from before_t1 where a = 2; -- allowed +go +~~ROW COUNT: 1~~ + + +insert into after_t1 values(1); -- allowed +go +~~ROW COUNT: 1~~ + + +update after_t1 set a = 2 where a = 1; -- allowed +go +~~ROW COUNT: 1~~ + + +delete from after_t1 where a = 2; -- allowed +go +~~ROW COUNT: 1~~ + + +use master; +go + +-- tsql user=db_roles_l5 password=123 +-- Basic membership check +use db_roles_db1 +go + +SELECT IS_MEMBER('db_datareader') +GO +~~START~~ +int +1 +~~END~~ + + +SELECT IS_MEMBER('db_datawriter') +GO +~~START~~ +int +1 +~~END~~ + + +-- user is a member of role which is a member of db_datareader/db_datawriter, objects should be accessible +select * from after_t1; -- allowed +go +~~START~~ +int +~~END~~ + + +select * from before_t1; -- allowed +go +~~START~~ +int +~~END~~ + + +select * from after_v1; -- allowed +go +~~START~~ +int +2 +~~END~~ + + +select * from before_v1; -- allowed +go +~~START~~ +int +2 +~~END~~ + + +insert into before_t1 values(1); -- allowed +go +~~ROW COUNT: 1~~ + + +update before_t1 set a = 2 where a = 1; -- allowed +go +~~ROW COUNT: 1~~ + + +delete from before_t1 where a = 2; -- allowed +go +~~ROW COUNT: 1~~ + + +insert into after_t1 values(1); -- allowed +go +~~ROW COUNT: 1~~ + + +update after_t1 set a = 2 where a = 1; -- allowed +go +~~ROW COUNT: 1~~ + + +delete from after_t1 where a = 2; -- allowed +go +~~ROW COUNT: 1~~ + + +use master; +go + +-- tsql +-- Basic membership check +use db_roles_db1 +go + +SELECT IS_ROLEMEMBER('db_datareader', 'db_roles_u1') +GO +~~START~~ +int +1 +~~END~~ + + +SELECT IS_ROLEMEMBER('db_datawriter', 'db_roles_u1') +GO +~~START~~ +int +1 +~~END~~ + + +SELECT IS_ROLEMEMBER('db_datareader', 'db_roles_r1') +GO +~~START~~ +int +1 +~~END~~ + + +SELECT IS_ROLEMEMBER('db_datawriter', 'db_roles_r1') +GO +~~START~~ +int +1 +~~END~~ + + +exec sp_droprolemember 'db_datareader', 'db_roles_u1'; +go + +exec sp_droprolemember 'db_datareader', 'db_roles_r1'; +go + +-- Basic membership check +SELECT IS_ROLEMEMBER('db_datareader', 'db_roles_u1') +GO +~~START~~ +int +0 +~~END~~ + + +SELECT IS_ROLEMEMBER('db_datawriter', 'db_roles_u1') +GO +~~START~~ +int +1 +~~END~~ + + +SELECT IS_ROLEMEMBER('db_datareader', 'db_roles_r1') +GO +~~START~~ +int +0 +~~END~~ + + +SELECT IS_ROLEMEMBER('db_datawriter', 'db_roles_r1') +GO +~~START~~ +int +1 +~~END~~ + + +use master; +go + +-- tsql user=db_roles_l5 password=123 +-- Basic membership check +use db_roles_db1 +go + +SELECT IS_MEMBER('db_datareader') +GO +~~START~~ +int +0 +~~END~~ + + +SELECT IS_MEMBER('db_datawriter') +GO +~~START~~ +int +1 +~~END~~ + + +-- user is a member of role which is not a member of db_datareader, objects should not be accessible +select * from after_t1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t1)~~ + + +select * from before_t1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_t1)~~ + + +select * from after_v1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view after_v1)~~ + + +select * from before_v1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view before_v1)~~ + + +insert into after_t1 values(1); -- allowed +go +~~ROW COUNT: 1~~ + + +use master +go + +-- tsql +use db_roles_db1 +go +exec sp_droprolemember 'db_datawriter', 'db_roles_r1'; +go +exec sp_droprolemember 'db_datawriter', 'db_roles_u1'; +go + +use master +go + +-- tsql user=db_roles_l5 password=123 +-- user is a member of role which is not a member of db_datawriter, objects should not be accessible +use db_roles_db1 +go +insert into before_t1 values(1); -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_t1)~~ + + +update before_t1 set a = 2 where a = 1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_t1)~~ + + +delete from before_t1 where a = 2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_t1)~~ + + +insert into after_t1 values(1); -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t1)~~ + + +update after_t1 set a = 2 where a = 1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t1)~~ + + +delete from after_t1 where a = 2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t1)~~ + + +use master; +go + +-- tsql user=db_roles_l1 password=123 +-- Basic membership check +use db_roles_db1 +go + +SELECT IS_MEMBER('db_datareader') +GO +~~START~~ +int +0 +~~END~~ + + +SELECT IS_MEMBER('db_datawriter') +GO +~~START~~ +int +0 +~~END~~ + + +-- user is not a member of db_datareader/db_datawriter, objects should not be accessible +select * from after_t1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t1)~~ + + +select * from before_t1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_t1)~~ + + +select * from after_v1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view after_v1)~~ + + +select * from before_v1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view before_v1)~~ + + +insert into before_t1 values(1); -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_t1)~~ + + +update before_t1 set a = 2 where a = 1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_t1)~~ + + +delete from before_t1 where a = 2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table before_t1)~~ + + +insert into after_t1 values(1); -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t1)~~ + + +update after_t1 set a = 2 where a = 1; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t1)~~ + + +delete from after_t1 where a = 2; -- not allowed +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table after_t1)~~ + + +use master; +go + +-- psql +-- Need to terminate active session before cleaning up the login +SELECT pg_terminate_backend(pid) FROM pg_stat_get_activity(NULL) +WHERE sys.suser_name(usesysid) = 'db_roles_l1' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +go +~~START~~ +bool +t +~~END~~ + + +-- Wait to sync with another session +SELECT pg_sleep(1); +go +~~START~~ +void + +~~END~~ + + +-- Need to terminate active session before cleaning up the login +SELECT pg_terminate_backend(pid) FROM pg_stat_get_activity(NULL) +WHERE sys.suser_name(usesysid) = 'db_roles_l2' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +go +~~START~~ +bool +t +~~END~~ + + +-- Wait to sync with another session +SELECT pg_sleep(1); +go +~~START~~ +void + +~~END~~ + + +-- Need to terminate active session before cleaning up the login +SELECT pg_terminate_backend(pid) FROM pg_stat_get_activity(NULL) +WHERE sys.suser_name(usesysid) = 'db_roles_l3' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +go +~~START~~ +bool +t +~~END~~ + + +-- Wait to sync with another session +SELECT pg_sleep(1); +go +~~START~~ +void + +~~END~~ + + +-- Need to terminate active session before cleaning up the login +SELECT pg_terminate_backend(pid) FROM pg_stat_get_activity(NULL) +WHERE sys.suser_name(usesysid) = 'db_roles_l4' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +go +~~START~~ +bool +t +~~END~~ + + +-- Wait to sync with another session +SELECT pg_sleep(1); +go +~~START~~ +void + +~~END~~ + + +-- Need to terminate active session before cleaning up the login +SELECT pg_terminate_backend(pid) FROM pg_stat_get_activity(NULL) +WHERE sys.suser_name(usesysid) = 'db_roles_l5' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +go +~~START~~ +bool +t +~~END~~ + + +-- Wait to sync with another session +SELECT pg_sleep(1); +go +~~START~~ +void + +~~END~~ + + +-- tsql +-- drop objects +use db_roles_db1 +go + +drop table db_roles_schema_1.before_t1; +go + +drop table db_roles_schema_1.after_t1; +go + +drop table db_roles_schema_2.before_created_by_dbo_t1; +go + +drop table db_roles_schema_2.after_created_by_dbo_t1; +go + +drop table db_roles_schema_2.before_created_by_u4_t1; +go + +drop table db_roles_schema_2.after_created_by_u4_t1; +go + +drop table db_roles_schema_3.db_roles_t1; +go + +drop view db_roles_schema_1.before_v1; +go + +drop view db_roles_schema_1.after_v1; +go + +drop view db_roles_schema_2.before_created_by_dbo_v1; +go + +drop view db_roles_schema_2.after_created_by_dbo_v1; +go + +drop view db_roles_schema_2.before_created_by_u4_v1; +go + +drop view db_roles_schema_2.after_created_by_u4_v1; +go + +drop view db_roles_schema_3.db_roles_v1; +go + +drop schema db_roles_schema_1; +go + +drop schema db_roles_schema_2; +go + +drop schema db_roles_schema_3; +go + +drop table before_t1; +go + +drop table after_t1; +go + +drop view before_v1; +go + +drop view after_v1; +go + +drop user db_roles_u1; +go + +drop user db_roles_u4; +go + +drop user db_roles_u5; +go + +drop role db_roles_r1; +go + +use master; +go + +drop table t1_in_master; +go + +drop user db_roles_u1; +go + +drop login db_roles_l1; +go + +drop login db_roles_l2; +go + +drop login db_roles_l3; +go + +drop login db_roles_l4; +go + +drop login db_roles_l5; +go + +drop database db_roles_db1; +go diff --git a/test/JDBC/expected/single_db/db_accessadmin-vu-verify.out b/test/JDBC/expected/single_db/db_accessadmin-vu-verify.out index d39b87cfc1..5052b3cfcb 100644 --- a/test/JDBC/expected/single_db/db_accessadmin-vu-verify.out +++ b/test/JDBC/expected/single_db/db_accessadmin-vu-verify.out @@ -51,7 +51,7 @@ GO ~~ERROR (Message: role "babel_5136_babel_5136_l1" does not exist)~~ --- Cannot add fixed roles ass member of db_accessadmin +-- Cannot add fixed roles as member of db_accessadmin ALTER ROLE db_accessadmin ADD MEMBER syadmin GO ~~ERROR (Code: 33557097)~~ @@ -100,6 +100,31 @@ GO ~~ERROR (Message: Cannot use the special principal 'db_accessadmin')~~ +-- Cannot GRANT/REVOKE on objects TO/FROM db_accessadmin +GRANT ALL on object::t1 to db_accessadmin; -- Error, no grant on special roles +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny or revoke permissions to or from special roles.)~~ + +REVOKE ALL on object::t1 to db_accessadmin; -- Error, no grant on special roles +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny or revoke permissions to or from special roles.)~~ + +GRANT SELECT on object::t1 to db_accessadmin; -- Error, no grant on special roles +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny or revoke permissions to or from special roles.)~~ + +REVOKE EXECUTE on object::t1 to db_accessadmin; -- Error, no grant on special roles +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny or revoke permissions to or from special roles.)~~ + -- MEMBERS OF db_accessadmin WILL ALWAYS HAVE CONNECT PRIVILEGES REVOKE CONNECT FROM babel_5136_db_accessadmin_user diff --git a/test/JDBC/expected/test_windows_login-vu-prepare.out b/test/JDBC/expected/test_windows_login-vu-prepare.out index 04d81b332b..aedb3e8755 100644 --- a/test/JDBC/expected/test_windows_login-vu-prepare.out +++ b/test/JDBC/expected/test_windows_login-vu-prepare.out @@ -1,4 +1,5 @@ -- psql +-- TODO: BABEL-5349 do $$ begin if not exists (select * from pg_catalog.pg_roles where rolname = 'rds_ad') diff --git a/test/JDBC/input/1_GRANT_SCHEMA-vu-verify.mix b/test/JDBC/input/1_GRANT_SCHEMA-vu-verify.mix index 9860c00021..de07553bbe 100644 --- a/test/JDBC/input/1_GRANT_SCHEMA-vu-verify.mix +++ b/test/JDBC/input/1_GRANT_SCHEMA-vu-verify.mix @@ -46,20 +46,6 @@ go select schema_name, object_name, permission, grantee, object_type, function_args from sys.babelfish_schema_permissions where schema_name = 'dbo' collate sys.database_default and grantee like '%babel_4768_u1' collate sys.database_default order by object_name; go --- psql --- This is needed so that MVU passes -DO $$ -BEGIN - IF EXISTS (SELECT 1 FROM -information_schema.tables WHERE -table_name = 'tbl_creation_should_succeed' AND -table_schema = 'master_dbo') THEN - EXECUTE 'GRANT ALL ON -master_dbo.tbl_creation_should_succeed TO master_dbo'; - END IF; -END $$; -GO - -- tsql REVOKE SELECT, EXECUTE ON SCHEMA::dbo FROM babel_4768_u1 GO diff --git a/test/JDBC/input/BABEL-3637.mix b/test/JDBC/input/BABEL-3637.mix index 9c9b2c07ef..83465c87ed 100644 --- a/test/JDBC/input/BABEL-3637.mix +++ b/test/JDBC/input/BABEL-3637.mix @@ -246,5 +246,9 @@ GO -- tsql USE master GO +DROP PROC test_babel_3637_proc1; +GO +DROP PROC test_babel_3637_proc2; +GO DROP DATABASE babel_3637_db; GO \ No newline at end of file diff --git a/test/JDBC/input/BABEL-CHECK-CONSTRAINT-vu-prepare.mix b/test/JDBC/input/BABEL-CHECK-CONSTRAINT-vu-prepare.mix index 2ea3d635be..e303f88275 100644 --- a/test/JDBC/input/BABEL-CHECK-CONSTRAINT-vu-prepare.mix +++ b/test/JDBC/input/BABEL-CHECK-CONSTRAINT-vu-prepare.mix @@ -37,3 +37,17 @@ CREATE TABLE master_dbo.tbl_creation_should_succeed ( AND ((a)::text < ('11'::text || '￿'::text COLLATE sys.bbf_unicode_cp1_ci_as)))))) ); GO + +-- psql +-- This is needed so that MVU passes +DO $$ +BEGIN + IF EXISTS (SELECT 1 FROM +information_schema.tables WHERE +table_name = 'tbl_creation_should_succeed' AND +table_schema = 'master_dbo') THEN + EXECUTE 'GRANT ALL ON +master_dbo.tbl_creation_should_succeed TO master_dbo'; + END IF; +END $$; +GO diff --git a/test/JDBC/input/datareader_datawriter-vu-cleanup.mix b/test/JDBC/input/datareader_datawriter-vu-cleanup.mix new file mode 100644 index 0000000000..dba3f476ba --- /dev/null +++ b/test/JDBC/input/datareader_datawriter-vu-cleanup.mix @@ -0,0 +1,101 @@ +-- psql +-- Need to terminate active session before cleaning up the login +SELECT pg_terminate_backend(pid) FROM pg_stat_get_activity(NULL) +WHERE sys.suser_name(usesysid) = 'db_roles_l1' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +go + +-- Wait to sync with another session +SELECT pg_sleep(1); +go + +-- Need to terminate active session before cleaning up the login +SELECT pg_terminate_backend(pid) FROM pg_stat_get_activity(NULL) +WHERE sys.suser_name(usesysid) = 'db_roles_l2' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +go + +-- Wait to sync with another session +SELECT pg_sleep(1); +go + +-- tsql +-- drop objects +use db_roles_db1 +go + +drop table db_roles_schema_1.before_t1; +go + +drop table db_roles_schema_1.after_t1; +go + +drop table db_roles_schema_1.after_t2; +go + +drop table db_roles_schema_2.before_created_by_dbo_t1; +go + +drop table db_roles_schema_2.after_created_by_dbo_t1; +go + +drop table db_roles_schema_2.after_created_by_dbo_t2; +go + +drop table db_roles_schema_2.before_created_by_u2_t1; +go + +drop table db_roles_schema_2.after_created_by_u2_t1; +go + +drop table db_roles_schema_2.after_created_by_u2_t2; +go + +drop view db_roles_schema_1.before_v1; +go + +drop view db_roles_schema_1.after_v1; +go + +drop view db_roles_schema_1.after_v2; +go + +drop view db_roles_schema_2.before_created_by_dbo_v1; +go + +drop view db_roles_schema_2.after_created_by_dbo_v1; +go + +drop view db_roles_schema_2.after_created_by_dbo_v2; +go + +drop view db_roles_schema_2.before_created_by_u2_v1; +go + +drop view db_roles_schema_2.after_created_by_u2_v1; +go + +drop view db_roles_schema_2.after_created_by_u2_v2; +go + +drop schema db_roles_schema_1; +go + +drop schema db_roles_schema_2; +go + +drop user db_roles_u1; +go + +drop user db_roles_u2; +go + +drop login db_roles_l1; +go + +drop login db_roles_l2; +go + +use master; +go + +drop database db_roles_db1; +go diff --git a/test/JDBC/input/datareader_datawriter-vu-prepare.mix b/test/JDBC/input/datareader_datawriter-vu-prepare.mix new file mode 100644 index 0000000000..05acda9627 --- /dev/null +++ b/test/JDBC/input/datareader_datawriter-vu-prepare.mix @@ -0,0 +1,53 @@ +-- create login, user and add members +-- tsql +create database db_roles_db1; +go + +use db_roles_db1; +go + +create login db_roles_l1 with password = '123'; +go + +create login db_roles_l2 with password = '123'; +go + +create user db_roles_u1 for login db_roles_l1; +go + +create user db_roles_u2 for login db_roles_l2; +go + +create schema db_roles_schema_1; +go + +create schema db_roles_schema_2 authorization db_roles_u2; +go + +create table db_roles_schema_1.before_t1(a int); +go + +create view db_roles_schema_1.before_v1 as select 2; +go + +create table db_roles_schema_2.before_created_by_dbo_t1(a int); +go + +create view db_roles_schema_2.before_created_by_dbo_v1 as select 2; +go + +use master; +go + +-- tsql user=db_roles_l2 password=123 +use db_roles_db1; +go + +create table db_roles_schema_2.before_created_by_u2_t1(a int); +go + +create view db_roles_schema_2.before_created_by_u2_v1 as select 2; +go + +use master; +go diff --git a/test/JDBC/input/datareader_datawriter-vu-verify.mix b/test/JDBC/input/datareader_datawriter-vu-verify.mix new file mode 100644 index 0000000000..055893a83e --- /dev/null +++ b/test/JDBC/input/datareader_datawriter-vu-verify.mix @@ -0,0 +1,360 @@ +-- tsql +-- bbf dump does not dump password so reset the password +ALTER LOGIN db_roles_l2 WITH PASSWORD = '123' +GO +ALTER LOGIN db_roles_l1 WITH PASSWORD = '123' +GO + +-- IS_ROLEMEMBER & IS_MEMBER should show db_datareader as member of dbo but not of db_owner +SELECT IS_ROLEMEMBER('db_datareader') +GO +SELECT IS_ROLEMEMBER('db_datareader', 'dbo') +GO +SELECT IS_ROLEMEMBER('db_datareader', 'db_owner') +GO + +-- IS_ROLEMEMBER & IS_MEMBER should show db_datawriter as member of dbo but not of db_owner +SELECT IS_ROLEMEMBER('db_datawriter') +GO +SELECT IS_ROLEMEMBER('db_datawriter', 'dbo') +GO +SELECT IS_ROLEMEMBER('db_datawriter', 'db_owner') +GO + +-- tsql user=db_roles_l2 password=123 +-- create objects after upgrade +use db_roles_db1; +go + +create table db_roles_schema_2.after_created_by_u2_t1(a int); +go + +create view db_roles_schema_2.after_created_by_u2_v1 as select 1; +go + +use master; +go + +-- tsql +use db_roles_db1 +go + +create table db_roles_schema_1.after_t1(a int); +go + +create view db_roles_schema_1.after_v1 as select 2; +go + +create table db_roles_schema_2.after_created_by_dbo_t1(a int); +go + +create view db_roles_schema_2.after_created_by_dbo_v1 as select 2; +go + +alter role db_datareader add member db_roles_u1; +go + +alter role db_datawriter add member db_roles_u1; +go + +create table db_roles_schema_1.after_t2(a int); +go + +create view db_roles_schema_1.after_v2 as select 2; +go + +create table db_roles_schema_2.after_created_by_dbo_t2(a int); +go + +create view db_roles_schema_2.after_created_by_dbo_v2 as select 2; +go + +use master +go + +-- tsql user=db_roles_l2 password=123 +use db_roles_db1; +go + +create table db_roles_schema_2.after_created_by_u2_t2(a int); +go + +create view db_roles_schema_2.after_created_by_u2_v2 as select 1; +go + +use master; +go + +-- tsql user=db_roles_l1 password=123 +use db_roles_db1 +go + +-- user is a member of db_datareader/db_datawriter, objects should be accessible +select * from db_roles_schema_1.after_t1; -- allowed +go + +select * from db_roles_schema_1.after_t2; -- allowed +go + +select * from db_roles_schema_1.after_v1; -- allowed +go + +select * from db_roles_schema_1.after_v2; -- allowed +go + +insert into db_roles_schema_1.before_t1 values(1); -- allowed +go + +update db_roles_schema_1.before_t1 set a = 2 where a = 1; -- allowed +go + +delete from db_roles_schema_1.before_t1 where a = 2; -- allowed +go + +select * from db_roles_schema_2.before_created_by_dbo_t1; -- allowed +go + +select * from db_roles_schema_2.before_created_by_dbo_v1; -- allowed +go + +insert into db_roles_schema_2.before_created_by_dbo_t1 values(1); -- allowed +go + +update db_roles_schema_2.before_created_by_dbo_t1 set a = 2 where a = 1; -- allowed +go + +delete from db_roles_schema_2.before_created_by_dbo_t1 where a = 2; -- allowed +go + +select * from db_roles_schema_2.after_created_by_dbo_t1; -- allowed +go + +select * from db_roles_schema_2.after_created_by_dbo_v1; -- allowed +go + +insert into db_roles_schema_2.after_created_by_dbo_t1 values(1); -- allowed +go + +update db_roles_schema_2.after_created_by_dbo_t1 set a = 2 where a = 1; -- allowed +go + +delete from db_roles_schema_2.after_created_by_dbo_t1 where a = 2; -- allowed +go + +select * from db_roles_schema_2.after_created_by_dbo_t2; -- allowed +go + +select * from db_roles_schema_2.after_created_by_dbo_v2; -- allowed +go + +insert into db_roles_schema_2.after_created_by_dbo_t2 values(1); -- allowed +go + +update db_roles_schema_2.after_created_by_dbo_t2 set a = 2 where a = 1; -- allowed +go + +delete from db_roles_schema_2.after_created_by_dbo_t2 where a = 2; -- allowed +go + +select * from db_roles_schema_2.before_created_by_u2_t1; -- allowed +go + +select * from db_roles_schema_2.before_created_by_u2_v1; -- allowed +go + +insert into db_roles_schema_2.before_created_by_u2_t1 values(1); -- allowed +go + +update db_roles_schema_2.before_created_by_u2_t1 set a = 2 where a = 1; -- allowed +go + +delete from db_roles_schema_2.before_created_by_u2_t1 where a = 2; -- allowed +go + +select * from db_roles_schema_2.after_created_by_u2_t2; -- allowed +go + +select * from db_roles_schema_2.after_created_by_u2_v2; -- allowed +go + +insert into db_roles_schema_2.after_created_by_u2_t2 values(1); -- allowed +go + +update db_roles_schema_2.after_created_by_u2_t2 set a = 2 where a = 1; -- allowed +go + +delete from db_roles_schema_2.after_created_by_u2_t2 where a = 2; -- allowed +go + +select * from db_roles_schema_2.after_created_by_u2_t1; -- allowed +go + +select * from db_roles_schema_2.after_created_by_u2_v1; -- allowed +go + +insert into db_roles_schema_2.after_created_by_u2_t1 values(1); -- allowed +go + +update db_roles_schema_2.after_created_by_u2_t1 set a = 2 where a = 1; -- allowed +go + +delete from db_roles_schema_2.after_created_by_u2_t1 where a = 2; -- allowed +go + +use master; +go + +-- tsql +use db_roles_db1; +go + +alter role db_datareader drop member db_roles_u1; +go + +alter role db_datawriter drop member db_roles_u1; +go + +use master; +go + +-- tsql user=db_roles_l1 password=123 +use db_roles_db1; +go + +select * from db_roles_schema_1.after_t1; -- not allowed +go + +select * from db_roles_schema_1.after_t2; -- not allowed +go + +select * from db_roles_schema_1.before_t1; -- not allowed +go + +select * from db_roles_schema_1.after_v1; -- not allowed +go + +select * from db_roles_schema_1.after_v2; -- not allowed +go + +select * from db_roles_schema_1.before_v1; -- not allowed +go + +insert into db_roles_schema_1.before_t1 values(1); -- not allowed +go + +update db_roles_schema_1.before_t1 set a = 2 where a = 1; -- not allowed +go + +delete from db_roles_schema_1.before_t1 where a = 2; -- not allowed +go + +insert into db_roles_schema_1.after_t1 values(1); -- not allowed +go + +update db_roles_schema_1.after_t1 set a = 2 where a = 1; -- not allowed +go + +delete from db_roles_schema_1.after_t1 where a = 2; -- not allowed +go + +insert into db_roles_schema_1.after_t2 values(1); -- not allowed +go + +update db_roles_schema_1.after_t2 set a = 2 where a = 1; -- not allowed +go + +delete from db_roles_schema_1.after_t2 where a = 2; -- not allowed +go + +select * from db_roles_schema_2.before_created_by_dbo_t1; -- not allowed +go + +select * from db_roles_schema_2.before_created_by_dbo_v1; -- not allowed +go + +insert into db_roles_schema_2.before_created_by_dbo_t1 values(1); -- not allowed +go + +update db_roles_schema_2.before_created_by_dbo_t1 set a = 2 where a = 1; -- not allowed +go + +delete from db_roles_schema_2.before_created_by_dbo_t1 where a = 2; -- not allowed +go + +select * from db_roles_schema_2.after_created_by_dbo_t1; -- not allowed +go + +select * from db_roles_schema_2.after_created_by_dbo_v1; -- not allowed +go + +insert into db_roles_schema_2.after_created_by_dbo_t1 values(1); -- not allowed +go + +update db_roles_schema_2.after_created_by_dbo_t1 set a = 2 where a = 1; -- not allowed +go + +delete from db_roles_schema_2.after_created_by_dbo_t1 where a = 2; -- not allowed +go + +select * from db_roles_schema_2.after_created_by_dbo_t2; -- not allowed +go + +select * from db_roles_schema_2.after_created_by_dbo_v2; -- not allowed +go + +insert into db_roles_schema_2.after_created_by_dbo_t2 values(1); -- not allowed +go + +update db_roles_schema_2.after_created_by_dbo_t2 set a = 2 where a = 1; -- not allowed +go + +delete from db_roles_schema_2.after_created_by_dbo_t2 where a = 2; -- not allowed +go + +select * from db_roles_schema_2.before_created_by_u2_t1; -- not allowed +go + +select * from db_roles_schema_2.before_created_by_u2_v1; -- not allowed +go + +insert into db_roles_schema_2.before_created_by_u2_t1 values(1); -- not allowed +go + +update db_roles_schema_2.before_created_by_u2_t1 set a = 2 where a = 1; -- not allowed +go + +delete from db_roles_schema_2.before_created_by_u2_t1 where a = 2; -- not allowed +go + +select * from db_roles_schema_2.after_created_by_u2_t1; -- not allowed +go + +select * from db_roles_schema_2.after_created_by_u2_v1; -- not allowed +go + +insert into db_roles_schema_2.after_created_by_u2_t1 values(1); -- not allowed +go + +update db_roles_schema_2.after_created_by_u2_t1 set a = 2 where a = 1; -- not allowed +go + +delete from db_roles_schema_2.after_created_by_u2_t1 where a = 2; -- not allowed +go + +select * from db_roles_schema_2.after_created_by_u2_t2; -- not allowed +go + +select * from db_roles_schema_2.after_created_by_u2_v2; -- not allowed +go + +insert into db_roles_schema_2.after_created_by_u2_t2 values(1); -- not allowed +go + +update db_roles_schema_2.after_created_by_u2_t2 set a = 2 where a = 1; -- not allowed +go + +delete from db_roles_schema_2.after_created_by_u2_t2 where a = 2; -- not allowed +go + +use master; +go diff --git a/test/JDBC/input/datareader_datawriter.mix b/test/JDBC/input/datareader_datawriter.mix new file mode 100644 index 0000000000..4717ed6373 --- /dev/null +++ b/test/JDBC/input/datareader_datawriter.mix @@ -0,0 +1,1127 @@ +-- single_db_mode_expected +-- tsql +-- Error cases +create role db_datareader; -- Error, this role already exists +go + +create role db_datawriter; -- Error, this role already exists +go + +create table t1(a int); +go +create proc p1 as select 1; +go + +-- grants not allowed on these special roles +grant select on schema::dbo to db_datareader; -- Error, no grant on special roles +go + +grant execute on schema::dbo to db_datawriter; -- Error, no grant on special roles +go + +revoke select on schema::dbo from db_datareader; -- Error, no grant on special roles +go + +revoke execute on schema::dbo from db_datawriter; -- Error, no grant on special roles +go + +grant select on object::t1 to db_datareader; -- Error, no grant on special roles +go + +grant insert on object::t1 to db_datawriter; -- Error, no grant on special roles +go + +grant execute on object::p1 to db_datareader; -- Error, no grant on special roles +go + +revoke select on object::t1 to db_datareader; -- Error, no grant on special roles +go + +revoke insert on object::t1 to db_datawriter; -- Error, no grant on special roles +go + +revoke execute on object::p1 to db_datareader; -- Error, no grant on special roles +go + +grant all on object::t1 to db_datareader; -- Error, no grant on special roles +go + +revoke all on object::t1 to db_datareader; -- Error, no grant on special roles +go + +drop role db_datareader; -- Error, should not be dropped +go + +drop role db_datawriter; -- Error, should not be dropped +go + +drop table t1; +go +drop proc p1; +go + +-- create login, user and add members +create database db_roles_db1; +go + +use db_roles_db1; +go + +create login db_roles_l1 with password = '123'; +go + +create login db_roles_l2 with password = '123'; +go + +create login db_roles_l3 with password = '123'; +go + +create login db_roles_l4 with password = '123'; +go + +create login db_roles_l5 with password = '123'; +go + +create user db_roles_u4 for login db_roles_l4; +go + +create user db_roles_u5 for login db_roles_l5; +go + +alter server role sysadmin add member db_roles_l2; +go + +create user db_datareader for login db_roles_l1; -- Error, this role already exists +go + +create user db_datawriter for login db_roles_l1; -- Error, this role already exists +go + +create user db_roles_u1 for login db_roles_l1; +go + +create role db_roles_r1; +go + +alter role db_roles_r1 add member db_roles_u5; +go + +create schema db_roles_schema_1; +go + +create schema db_roles_schema_2 authorization db_roles_u4; +go + +create table db_roles_schema_1.before_t1(a int); +go + +create view db_roles_schema_1.before_v1 as select 2; +go + +create table db_roles_schema_2.before_created_by_dbo_t1(a int); +go + +create view db_roles_schema_2.before_created_by_dbo_v1 as select 2; +go + +create table before_t1(a int); +go + +create view before_v1 as select 2; +go + +use master; +go + +create user db_roles_u1 for login db_roles_l1; +go + +create table t1_in_master(a int); +go + +-- tsql user=db_roles_l4 password=123 +use db_roles_db1; +go + +create table db_roles_schema_2.before_created_by_u4_t1(a int); +go + +create view db_roles_schema_2.before_created_by_u4_v1 as select 2; +go + +use master; +go + +-- tsql +use db_roles_db1 +go + +alter role db_datareader add member db_roles_u1; +go + +alter role db_datawriter add member db_roles_u1; +go + +alter role db_datareader add member db_roles_r1; +go + +alter role db_datawriter add member db_roles_r1; +go + +select count(*) from sys.database_principals where name like '%db_datareader%'; +go + +select count(*) from sys.database_principals where name like '%db_datawriter%'; +go + +-- Test sp_helpuser +CREATE TABLE #UserRoles(userName sys.SYSNAME, roleName sys.SYSNAME, loginName sys.SYSNAME NULL, defdb sys.SYSNAME NULL, defschema sys.SYSNAME, userid INT, sid sys.VARBINARY(85)); +go +-- Insert the results of sp_helpuser into the temporary table +INSERT INTO #UserRoles EXEC sp_helpuser; +go +-- Select the desired fields from the temporary table +SELECT userName, roleName FROM #UserRoles WHERE roleName IN ('db_datareader', 'db_datawriter'); +go +-- Drop the temporary table +DROP TABLE #UserRoles; +go + +-- Test sp_helprole +CREATE TABLE #UserRoles(RoleName sys.SYSNAME, RoleId integer, IsAppRole integer); +go +-- Insert the results of sp_helprole into the temporary table +INSERT INTO #UserRoles EXEC sp_helprole; +go +-- Select the desired fields from the temporary table +SELECT RoleName, IsAppRole FROM #UserRoles WHERE RoleName IN ('db_datareader', 'db_datawriter'); +go +-- Drop the temporary table +DROP TABLE #UserRoles; +go + +-- Test sp_helprolemember +CREATE TABLE #UserRoles(RoleName sys.SYSNAME, MemberName sys.SYSNAME, MemberSID sys.VARBINARY(85)); +go +-- Insert the results of sp_helprolemember into the temporary table +INSERT INTO #UserRoles EXEC sp_helprolemember; +go +-- Select the desired fields from the temporary table +SELECT RoleName, MemberName FROM #UserRoles WHERE RoleName IN ('db_datareader', 'db_datawriter'); +go +-- Drop the temporary table +DROP TABLE #UserRoles; +go + +use master +go + +-- tsql user=db_roles_l4 password=123 +use db_roles_db1; +go + +create table db_roles_schema_2.after_created_by_u4_t1(a int); +go + +create view db_roles_schema_2.after_created_by_u4_v1 as select 1; +go + +use master; +go + +-- tsql +use db_roles_db1 +go + +create table after_t1(a int); +go + +create view after_v1 as select 2; +go + +create table db_roles_schema_1.after_t1(a int); +go + +create view db_roles_schema_1.after_v1 as select 2; +go + +create table db_roles_schema_2.after_created_by_dbo_t1(a int); +go + +create view db_roles_schema_2.after_created_by_dbo_v1 as select 2; +go + +use master; +go + +-- tsql user=db_roles_l2 password=123 +-- member of sysadmin can add/drop user as a member of db_datareader/db_datawriter +use db_roles_db1; +go + +alter role db_datareader drop member db_roles_u1; +go + +alter role db_datawriter drop member db_roles_u1; +go + +alter role db_datareader add member db_roles_u1; +go + +alter role db_datawriter add member db_roles_u1; +go + +exec sp_droprolemember 'db_datareader', 'db_roles_u1'; +go + +exec sp_droprolemember 'db_datawriter', 'db_roles_u1'; +go + +exec sp_addrolemember 'db_datareader', 'db_roles_u1'; +go + +exec sp_addrolemember 'db_datawriter', 'db_roles_u1'; +go + +use master; +go + +-- tsql +alter authorization on database::db_roles_db1 to db_roles_l3; +go + +-- tsql user=db_roles_l3 password=123 +use db_roles_db1 +go + +create schema db_roles_schema_3; +go + +create table db_roles_schema_3.db_roles_t1(a int); +go + +create view db_roles_schema_3.db_roles_v1 as select 2; +go + +-- database owner can add other roles as a member of database roles +alter role db_datareader drop member db_roles_u1; +go + +alter role db_datawriter drop member db_roles_u1; +go + +alter role db_datareader add member db_roles_u1; +go + +alter role db_datawriter add member db_roles_u1; +go + +exec sp_droprolemember 'db_datareader', 'db_roles_u1'; +go + +exec sp_droprolemember 'db_datawriter', 'db_roles_u1'; +go + +exec sp_addrolemember 'db_datareader', 'db_roles_u1'; +go + +exec sp_addrolemember 'db_datawriter', 'db_roles_u1'; +go + +-- remove select privilege on the schema and object, still the objects should be accessible +revoke select on schema::db_roles_schema_1 from db_roles_u1; +go + +revoke select on object::db_roles_schema_1.before_t1 from db_roles_u1; +go + +use master; +go + +-- tsql user=db_roles_l1 password=123 +use db_roles_db1 +go + +-- members of db_datareader/db_datawriter cannot add another role/user as its member +alter role db_datareader drop member db_roles_r1; +go + +alter role db_datawriter drop member db_roles_r1; +go + +alter role db_datareader add member db_roles_r1; +go + +alter role db_datawriter add member db_roles_r1; +go + +exec sp_droprolemember 'db_datareader', 'db_roles_r1'; +go + +exec sp_droprolemember 'db_datawriter', 'db_roles_r1'; +go + +exec sp_addrolemember 'db_datareader', 'db_roles_r1'; +go + +exec sp_addrolemember 'db_datawriter', 'db_roles_r1'; +go + +-- Basic membership check +SELECT IS_MEMBER('db_datareader') +GO + +SELECT IS_MEMBER('db_datawriter') +GO + +-- user is a member of db_datareader/db_datawriter, objects should be accessible +-- objects created before and after adding the user to db roles should be accessible. +select * from after_t1; -- allowed +go + +select * from after_v1; -- allowed +go + +insert into before_t1 values(1); -- allowed +go + +update before_t1 set a = 2 where a = 1; -- allowed +go + +delete from before_t1 where a = 2; -- allowed +go + +select * from before_t1; -- allowed +go + +select * from before_v1; -- allowed +go + +insert into after_t1 values(1); -- allowed +go + +update after_t1 set a = 2 where a = 1; -- allowed +go + +delete from after_t1 where a = 2; -- allowed +go + +select * from db_roles_schema_1.after_t1; -- allowed +go + +select * from db_roles_schema_1.after_v1; -- allowed +go + +insert into db_roles_schema_1.before_t1 values(1); -- allowed +go + +update db_roles_schema_1.before_t1 set a = 2 where a = 1; -- allowed +go + +delete from db_roles_schema_1.before_t1 where a = 2; -- allowed +go + +select * from db_roles_schema_2.before_created_by_dbo_t1; -- allowed +go + +select * from db_roles_schema_2.before_created_by_dbo_v1; -- allowed +go + +insert into db_roles_schema_2.before_created_by_dbo_t1 values(1); -- allowed +go + +update db_roles_schema_2.before_created_by_dbo_t1 set a = 2 where a = 1; -- allowed +go + +delete from db_roles_schema_2.before_created_by_dbo_t1 where a = 2; -- allowed +go + +select * from db_roles_schema_2.after_created_by_dbo_t1; -- allowed +go + +select * from db_roles_schema_2.after_created_by_dbo_v1; -- allowed +go + +insert into db_roles_schema_2.after_created_by_dbo_t1 values(1); -- allowed +go + +update db_roles_schema_2.after_created_by_dbo_t1 set a = 2 where a = 1; -- allowed +go + +delete from db_roles_schema_2.after_created_by_dbo_t1 where a = 2; -- allowed +go + +select * from db_roles_schema_2.before_created_by_u4_t1; -- allowed +go + +select * from db_roles_schema_2.before_created_by_u4_v1; -- allowed +go + +insert into db_roles_schema_2.before_created_by_u4_t1 values(1); -- allowed +go + +update db_roles_schema_2.before_created_by_u4_t1 set a = 2 where a = 1; -- allowed +go + +delete from db_roles_schema_2.before_created_by_u4_t1 where a = 2; -- allowed +go + +select * from db_roles_schema_2.after_created_by_u4_t1; -- allowed +go + +select * from db_roles_schema_2.after_created_by_u4_v1; -- allowed +go + +insert into db_roles_schema_2.after_created_by_u4_t1 values(1); -- allowed +go + +update db_roles_schema_2.after_created_by_u4_t1 set a = 2 where a = 1; -- allowed +go + +delete from db_roles_schema_2.after_created_by_u4_t1 where a = 2; -- allowed +go + +select * from master.dbo.t1_in_master; -- not allowed since the user in master doesn't have read privilege +go + +insert into master.dbo.t1_in_master values(1); -- not allowed since the user in master doesn't have write privilege +go + +-- objects created by the database owner should be accessible too. +select * from db_roles_schema_3.db_roles_t1; -- allowed +go + +select * from db_roles_schema_3.db_roles_v1; -- allowed +go + +insert into db_roles_schema_3.db_roles_t1 values(1); -- allowed +go + +update db_roles_schema_3.db_roles_t1 set a = 2 where a = 1; -- allowed +go + +delete from db_roles_schema_3.db_roles_t1 where a = 2; -- allowed +go + +use master; +go + +-- tsql +-- Basic membership check +use db_roles_db1; +go + +SELECT IS_ROLEMEMBER('db_datareader', 'db_roles_u1') +GO + +SELECT IS_ROLEMEMBER('db_datawriter', 'db_roles_u1') +GO + +SELECT IS_ROLEMEMBER('db_datareader', 'db_roles_r1') +GO + +SELECT IS_ROLEMEMBER('db_datawriter', 'db_roles_r1') +GO + +alter role db_datareader drop member db_roles_u1; +go + +alter role db_datawriter drop member db_roles_u1; +go + +alter role db_datareader drop member db_roles_r1; +go + +-- Basic membership check +SELECT IS_ROLEMEMBER('db_datareader', 'db_roles_u1') +GO + +SELECT IS_ROLEMEMBER('db_datawriter', 'db_roles_u1') +GO + +SELECT IS_ROLEMEMBER('db_datareader', 'db_roles_r1') +GO + +SELECT IS_ROLEMEMBER('db_datawriter', 'db_roles_r1') +GO + +alter role db_datawriter drop member db_roles_r1; +go + +use master; +go + +alter role db_datareader add member db_roles_u1; +go + +alter role db_datawriter add member db_roles_u1; +go + +-- tsql user=db_roles_l1 password=123 +-- Basic membership check +use db_roles_db1 +go + +SELECT IS_MEMBER('db_datareader') +GO + +SELECT IS_MEMBER('db_datawriter') +GO + +-- user is not a member of db_datareader/db_datawriter, objects should not be accessible +select * from after_t1; -- not allowed +go + +select * from after_v1; -- not allowed +go + +select * from before_t1; -- not allowed +go + +select * from before_v1; -- not allowed +go + +insert into before_t1 values(1); -- not allowed +go + +update before_t1 set a = 2 where a = 1; -- not allowed +go + +delete from before_t1 where a = 2; -- not allowed +go + +insert into after_t1 values(1); -- not allowed +go + +update after_t1 set a = 2 where a = 1; -- not allowed +go + +delete from after_t1 where a = 2; -- not allowed +go + +select * from db_roles_schema_1.after_t1; -- not allowed +go + +select * from db_roles_schema_1.before_t1; -- not allowed +go + +select * from db_roles_schema_1.after_v1; -- not allowed +go + +select * from db_roles_schema_1.before_v1; -- not allowed +go + +insert into db_roles_schema_1.before_t1 values(1); -- not allowed +go + +update db_roles_schema_1.before_t1 set a = 2 where a = 1; -- not allowed +go + +delete from db_roles_schema_1.before_t1 where a = 2; -- not allowed +go + +insert into db_roles_schema_1.after_t1 values(1); -- not allowed +go + +update db_roles_schema_1.after_t1 set a = 2 where a = 1; -- not allowed +go + +delete from db_roles_schema_1.after_t1 where a = 2; -- not allowed +go + +select * from db_roles_schema_2.before_created_by_dbo_t1; -- not allowed +go + +select * from db_roles_schema_2.before_created_by_dbo_v1; -- not allowed +go + +insert into db_roles_schema_2.before_created_by_dbo_t1 values(1); -- not allowed +go + +update db_roles_schema_2.before_created_by_dbo_t1 set a = 2 where a = 1; -- not allowed +go + +delete from db_roles_schema_2.before_created_by_dbo_t1 where a = 2; -- not allowed +go + +select * from db_roles_schema_2.after_created_by_dbo_t1; -- not allowed +go + +select * from db_roles_schema_2.after_created_by_dbo_v1; -- not allowed +go + +insert into db_roles_schema_2.after_created_by_dbo_t1 values(1); -- not allowed +go + +update db_roles_schema_2.after_created_by_dbo_t1 set a = 2 where a = 1; -- not allowed +go + +delete from db_roles_schema_2.after_created_by_dbo_t1 where a = 2; -- not allowed +go + +select * from db_roles_schema_2.before_created_by_u4_t1; -- not allowed +go + +select * from db_roles_schema_2.before_created_by_u4_v1; -- not allowed +go + +insert into db_roles_schema_2.before_created_by_u4_t1 values(1); -- not allowed +go + +update db_roles_schema_2.before_created_by_u4_t1 set a = 2 where a = 1; -- not allowed +go + +delete from db_roles_schema_2.before_created_by_u4_t1 where a = 2; -- not allowed +go + +select * from db_roles_schema_2.after_created_by_u4_t1; -- not allowed +go + +select * from db_roles_schema_2.after_created_by_u4_v1; -- not allowed +go + +insert into db_roles_schema_2.after_created_by_u4_t1 values(1); -- not allowed +go + +update db_roles_schema_2.after_created_by_u4_t1 set a = 2 where a = 1; -- not allowed +go + +delete from db_roles_schema_2.after_created_by_u4_t1 where a = 2; -- not allowed +go + +-- objects created by the database owner should not be accessible +select * from db_roles_schema_3.db_roles_t1; -- not allowed +go + +select * from db_roles_schema_3.db_roles_v1; -- not allowed +go + +insert into db_roles_schema_3.db_roles_t1 values(1); -- not allowed +go + +update db_roles_schema_3.db_roles_t1 set a = 2 where a = 1; -- not allowed +go + +delete from db_roles_schema_3.db_roles_t1 where a = 2; -- not allowed +go + +select * from master.dbo.t1_in_master; -- allowed since the user in master has read privilege +go + +insert into master.dbo.t1_in_master values(1); -- allowed since the user in master has write privilege +go + +use master; +go + +-- tsql +use db_roles_db1; +go + +exec sp_addrolemember 'db_datareader', 'db_roles_u1'; +go + +exec sp_addrolemember 'db_datawriter', 'db_roles_u1'; +go + +exec sp_addrolemember 'db_datareader', 'db_roles_r1'; +go + +exec sp_addrolemember 'db_datawriter', 'db_roles_r1'; +go + +use master; +go + +-- tsql user=db_roles_l1 password=123 +-- Basic membership check +use db_roles_db1 +go + +SELECT IS_MEMBER('db_datareader') +GO + +SELECT IS_MEMBER('db_datawriter') +GO + +-- user is a member of db_datareader/db_datawriter, objects should be accessible +select * from after_t1; -- allowed +go + +select * from before_t1; -- allowed +go + +select * from after_v1; -- allowed +go + +select * from before_v1; -- allowed +go + +insert into before_t1 values(1); -- allowed +go + +update before_t1 set a = 2 where a = 1; -- allowed +go + +delete from before_t1 where a = 2; -- allowed +go + +insert into after_t1 values(1); -- allowed +go + +update after_t1 set a = 2 where a = 1; -- allowed +go + +delete from after_t1 where a = 2; -- allowed +go + +use master; +go + +-- tsql user=db_roles_l5 password=123 +-- Basic membership check +use db_roles_db1 +go + +SELECT IS_MEMBER('db_datareader') +GO + +SELECT IS_MEMBER('db_datawriter') +GO + +-- user is a member of role which is a member of db_datareader/db_datawriter, objects should be accessible +select * from after_t1; -- allowed +go + +select * from before_t1; -- allowed +go + +select * from after_v1; -- allowed +go + +select * from before_v1; -- allowed +go + +insert into before_t1 values(1); -- allowed +go + +update before_t1 set a = 2 where a = 1; -- allowed +go + +delete from before_t1 where a = 2; -- allowed +go + +insert into after_t1 values(1); -- allowed +go + +update after_t1 set a = 2 where a = 1; -- allowed +go + +delete from after_t1 where a = 2; -- allowed +go + +use master; +go + +-- tsql +-- Basic membership check +use db_roles_db1 +go + +SELECT IS_ROLEMEMBER('db_datareader', 'db_roles_u1') +GO + +SELECT IS_ROLEMEMBER('db_datawriter', 'db_roles_u1') +GO + +SELECT IS_ROLEMEMBER('db_datareader', 'db_roles_r1') +GO + +SELECT IS_ROLEMEMBER('db_datawriter', 'db_roles_r1') +GO + +exec sp_droprolemember 'db_datareader', 'db_roles_u1'; +go + +exec sp_droprolemember 'db_datareader', 'db_roles_r1'; +go + +-- Basic membership check +SELECT IS_ROLEMEMBER('db_datareader', 'db_roles_u1') +GO + +SELECT IS_ROLEMEMBER('db_datawriter', 'db_roles_u1') +GO + +SELECT IS_ROLEMEMBER('db_datareader', 'db_roles_r1') +GO + +SELECT IS_ROLEMEMBER('db_datawriter', 'db_roles_r1') +GO + +use master; +go + +-- tsql user=db_roles_l5 password=123 +-- Basic membership check +use db_roles_db1 +go + +SELECT IS_MEMBER('db_datareader') +GO + +SELECT IS_MEMBER('db_datawriter') +GO + +-- user is a member of role which is not a member of db_datareader, objects should not be accessible +select * from after_t1; -- not allowed +go + +select * from before_t1; -- not allowed +go + +select * from after_v1; -- not allowed +go + +select * from before_v1; -- not allowed +go + +insert into after_t1 values(1); -- allowed +go + +use master +go + +-- tsql +use db_roles_db1 +go +exec sp_droprolemember 'db_datawriter', 'db_roles_r1'; +go +exec sp_droprolemember 'db_datawriter', 'db_roles_u1'; +go + +use master +go + +-- tsql user=db_roles_l5 password=123 +-- user is a member of role which is not a member of db_datawriter, objects should not be accessible +use db_roles_db1 +go +insert into before_t1 values(1); -- not allowed +go + +update before_t1 set a = 2 where a = 1; -- not allowed +go + +delete from before_t1 where a = 2; -- not allowed +go + +insert into after_t1 values(1); -- not allowed +go + +update after_t1 set a = 2 where a = 1; -- not allowed +go + +delete from after_t1 where a = 2; -- not allowed +go + +use master; +go + +-- tsql user=db_roles_l1 password=123 +-- Basic membership check +use db_roles_db1 +go + +SELECT IS_MEMBER('db_datareader') +GO + +SELECT IS_MEMBER('db_datawriter') +GO + +-- user is not a member of db_datareader/db_datawriter, objects should not be accessible +select * from after_t1; -- not allowed +go + +select * from before_t1; -- not allowed +go + +select * from after_v1; -- not allowed +go + +select * from before_v1; -- not allowed +go + +insert into before_t1 values(1); -- not allowed +go + +update before_t1 set a = 2 where a = 1; -- not allowed +go + +delete from before_t1 where a = 2; -- not allowed +go + +insert into after_t1 values(1); -- not allowed +go + +update after_t1 set a = 2 where a = 1; -- not allowed +go + +delete from after_t1 where a = 2; -- not allowed +go + +use master; +go + +-- psql +-- Need to terminate active session before cleaning up the login +SELECT pg_terminate_backend(pid) FROM pg_stat_get_activity(NULL) +WHERE sys.suser_name(usesysid) = 'db_roles_l1' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +go + +-- Wait to sync with another session +SELECT pg_sleep(1); +go + +-- Need to terminate active session before cleaning up the login +SELECT pg_terminate_backend(pid) FROM pg_stat_get_activity(NULL) +WHERE sys.suser_name(usesysid) = 'db_roles_l2' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +go + +-- Wait to sync with another session +SELECT pg_sleep(1); +go + +-- Need to terminate active session before cleaning up the login +SELECT pg_terminate_backend(pid) FROM pg_stat_get_activity(NULL) +WHERE sys.suser_name(usesysid) = 'db_roles_l3' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +go + +-- Wait to sync with another session +SELECT pg_sleep(1); +go + +-- Need to terminate active session before cleaning up the login +SELECT pg_terminate_backend(pid) FROM pg_stat_get_activity(NULL) +WHERE sys.suser_name(usesysid) = 'db_roles_l4' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +go + +-- Wait to sync with another session +SELECT pg_sleep(1); +go + +-- Need to terminate active session before cleaning up the login +SELECT pg_terminate_backend(pid) FROM pg_stat_get_activity(NULL) +WHERE sys.suser_name(usesysid) = 'db_roles_l5' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +go + +-- Wait to sync with another session +SELECT pg_sleep(1); +go + +-- tsql +-- drop objects +use db_roles_db1 +go + +drop table db_roles_schema_1.before_t1; +go + +drop table db_roles_schema_1.after_t1; +go + +drop table db_roles_schema_2.before_created_by_dbo_t1; +go + +drop table db_roles_schema_2.after_created_by_dbo_t1; +go + +drop table db_roles_schema_2.before_created_by_u4_t1; +go + +drop table db_roles_schema_2.after_created_by_u4_t1; +go + +drop table db_roles_schema_3.db_roles_t1; +go + +drop view db_roles_schema_1.before_v1; +go + +drop view db_roles_schema_1.after_v1; +go + +drop view db_roles_schema_2.before_created_by_dbo_v1; +go + +drop view db_roles_schema_2.after_created_by_dbo_v1; +go + +drop view db_roles_schema_2.before_created_by_u4_v1; +go + +drop view db_roles_schema_2.after_created_by_u4_v1; +go + +drop view db_roles_schema_3.db_roles_v1; +go + +drop schema db_roles_schema_1; +go + +drop schema db_roles_schema_2; +go + +drop schema db_roles_schema_3; +go + +drop table before_t1; +go + +drop table after_t1; +go + +drop view before_v1; +go + +drop view after_v1; +go + +drop user db_roles_u1; +go + +drop user db_roles_u4; +go + +drop user db_roles_u5; +go + +drop role db_roles_r1; +go + +use master; +go + +drop table t1_in_master; +go + +drop user db_roles_u1; +go + +drop login db_roles_l1; +go + +drop login db_roles_l2; +go + +drop login db_roles_l3; +go + +drop login db_roles_l4; +go + +drop login db_roles_l5; +go + +drop database db_roles_db1; +go diff --git a/test/JDBC/input/db_accessadmin-vu-verify.mix b/test/JDBC/input/db_accessadmin-vu-verify.mix index 7764a3e594..353e1fb123 100644 --- a/test/JDBC/input/db_accessadmin-vu-verify.mix +++ b/test/JDBC/input/db_accessadmin-vu-verify.mix @@ -38,7 +38,7 @@ GO -- Cannot add login as member of db_accessadmin ALTER ROLE db_accessadmin ADD MEMBER babel_5136_l1 GO --- Cannot add fixed roles ass member of db_accessadmin +-- Cannot add fixed roles as member of db_accessadmin ALTER ROLE db_accessadmin ADD MEMBER syadmin GO ALTER ROLE db_accessadmin ADD MEMBER dbo @@ -55,6 +55,15 @@ ALTER ROLE db_accessadmin DROP MEMBER db_owner GO ALTER ROLE db_accessadmin DROP MEMBER db_accessadmin GO +-- Cannot GRANT/REVOKE on objects TO/FROM db_accessadmin +GRANT ALL on object::t1 to db_accessadmin; -- Error, no grant on special roles +go +REVOKE ALL on object::t1 to db_accessadmin; -- Error, no grant on special roles +go +GRANT SELECT on object::t1 to db_accessadmin; -- Error, no grant on special roles +go +REVOKE EXECUTE on object::t1 to db_accessadmin; -- Error, no grant on special roles +go -- MEMBERS OF db_accessadmin WILL ALWAYS HAVE CONNECT PRIVILEGES REVOKE CONNECT FROM babel_5136_db_accessadmin_user diff --git a/test/JDBC/input/test_windows_login-vu-prepare.mix b/test/JDBC/input/test_windows_login-vu-prepare.mix index bb3cd2ab41..cfc5d8c6d9 100644 --- a/test/JDBC/input/test_windows_login-vu-prepare.mix +++ b/test/JDBC/input/test_windows_login-vu-prepare.mix @@ -1,4 +1,5 @@ --- sla 55000 +-- sla 70000 +-- TODO: BABEL-5349 -- psql do $$ begin diff --git a/test/JDBC/upgrade/13_6/schedule b/test/JDBC/upgrade/13_6/schedule index 2a149c3ba7..2a5686d466 100644 --- a/test/JDBC/upgrade/13_6/schedule +++ b/test/JDBC/upgrade/13_6/schedule @@ -360,3 +360,4 @@ binary-datatype-operators BABEL-5059-before-14_7-or-15_2 replace-before-15_8-or-16_4 BABEL-CASE_EXPR-before-16_5-or-15_9 +datareader_datawriter diff --git a/test/JDBC/upgrade/13_7/schedule b/test/JDBC/upgrade/13_7/schedule index 003a209571..d2cd296027 100644 --- a/test/JDBC/upgrade/13_7/schedule +++ b/test/JDBC/upgrade/13_7/schedule @@ -353,3 +353,4 @@ binary-datatype-operators BABEL-5059-before-14_7-or-15_2 replace-before-15_8-or-16_4 BABEL-CASE_EXPR-before-16_5-or-15_9 +datareader_datawriter diff --git a/test/JDBC/upgrade/13_8/schedule b/test/JDBC/upgrade/13_8/schedule index 1ba07c2c2b..3a86b97f70 100644 --- a/test/JDBC/upgrade/13_8/schedule +++ b/test/JDBC/upgrade/13_8/schedule @@ -353,3 +353,4 @@ binary-datatype-operators BABEL-5059-before-14_7-or-15_2 replace-before-15_8-or-16_4 BABEL-CASE_EXPR-before-16_5-or-15_9 +datareader_datawriter diff --git a/test/JDBC/upgrade/13_9/schedule b/test/JDBC/upgrade/13_9/schedule index 6c96e99210..93f5739e6e 100644 --- a/test/JDBC/upgrade/13_9/schedule +++ b/test/JDBC/upgrade/13_9/schedule @@ -358,3 +358,4 @@ binary-datatype-operators BABEL-5059-before-14_7-or-15_2 replace-before-15_8-or-16_4 BABEL-CASE_EXPR-before-16_5-or-15_9 +datareader_datawriter diff --git a/test/JDBC/upgrade/14_10/schedule b/test/JDBC/upgrade/14_10/schedule index 6b73f2b099..722ab4e6c5 100644 --- a/test/JDBC/upgrade/14_10/schedule +++ b/test/JDBC/upgrade/14_10/schedule @@ -468,5 +468,6 @@ cast-varchar-to-time db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 +datareader_datawriter BABEL-5186 diff --git a/test/JDBC/upgrade/14_11/schedule b/test/JDBC/upgrade/14_11/schedule index 237ce75847..7540a3f9dd 100644 --- a/test/JDBC/upgrade/14_11/schedule +++ b/test/JDBC/upgrade/14_11/schedule @@ -466,5 +466,6 @@ cast-varchar-to-time db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 +datareader_datawriter BABEL-5186 diff --git a/test/JDBC/upgrade/14_12/schedule b/test/JDBC/upgrade/14_12/schedule index 4742561d68..7d64b6986b 100644 --- a/test/JDBC/upgrade/14_12/schedule +++ b/test/JDBC/upgrade/14_12/schedule @@ -467,4 +467,5 @@ cast-varchar-to-time db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 +datareader_datawriter BABEL-5186 diff --git a/test/JDBC/upgrade/14_13/schedule b/test/JDBC/upgrade/14_13/schedule index cf5d1810be..dfb58fb29c 100644 --- a/test/JDBC/upgrade/14_13/schedule +++ b/test/JDBC/upgrade/14_13/schedule @@ -467,5 +467,6 @@ cast-varchar-to-time db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 +datareader_datawriter BABEL-5186 diff --git a/test/JDBC/upgrade/14_14/schedule b/test/JDBC/upgrade/14_14/schedule index cf5d1810be..dfb58fb29c 100644 --- a/test/JDBC/upgrade/14_14/schedule +++ b/test/JDBC/upgrade/14_14/schedule @@ -467,5 +467,6 @@ cast-varchar-to-time db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 +datareader_datawriter BABEL-5186 diff --git a/test/JDBC/upgrade/14_3/schedule b/test/JDBC/upgrade/14_3/schedule index 2e37b09c79..7c2c5abddd 100644 --- a/test/JDBC/upgrade/14_3/schedule +++ b/test/JDBC/upgrade/14_3/schedule @@ -387,4 +387,5 @@ cast-varchar-to-time db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 +datareader_datawriter BABEL-5186 diff --git a/test/JDBC/upgrade/14_5/schedule b/test/JDBC/upgrade/14_5/schedule index 9dc9c7b5dd..8bbb2f609c 100644 --- a/test/JDBC/upgrade/14_5/schedule +++ b/test/JDBC/upgrade/14_5/schedule @@ -399,5 +399,6 @@ cast-varchar-to-time db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 +datareader_datawriter BABEL-5186 diff --git a/test/JDBC/upgrade/14_6/schedule b/test/JDBC/upgrade/14_6/schedule index 52de103888..625322f3db 100644 --- a/test/JDBC/upgrade/14_6/schedule +++ b/test/JDBC/upgrade/14_6/schedule @@ -436,5 +436,6 @@ cast-varchar-to-time db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 +datareader_datawriter BABEL-5186 diff --git a/test/JDBC/upgrade/14_7/schedule b/test/JDBC/upgrade/14_7/schedule index 05bb943a0d..ff801914f5 100644 --- a/test/JDBC/upgrade/14_7/schedule +++ b/test/JDBC/upgrade/14_7/schedule @@ -458,5 +458,6 @@ cast-varchar-to-time db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 +datareader_datawriter BABEL-5186 diff --git a/test/JDBC/upgrade/14_8/schedule b/test/JDBC/upgrade/14_8/schedule index e517fcb0ea..a9243d76b7 100644 --- a/test/JDBC/upgrade/14_8/schedule +++ b/test/JDBC/upgrade/14_8/schedule @@ -460,5 +460,6 @@ cast-varchar-to-time db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 +datareader_datawriter BABEL-5186 diff --git a/test/JDBC/upgrade/14_9/schedule b/test/JDBC/upgrade/14_9/schedule index 0dbf8068d9..b75501c76a 100644 --- a/test/JDBC/upgrade/14_9/schedule +++ b/test/JDBC/upgrade/14_9/schedule @@ -463,5 +463,6 @@ cast-varchar-to-time db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 +datareader_datawriter BABEL-5186 diff --git a/test/JDBC/upgrade/15_1/schedule b/test/JDBC/upgrade/15_1/schedule index f843147b97..138fa9b358 100644 --- a/test/JDBC/upgrade/15_1/schedule +++ b/test/JDBC/upgrade/15_1/schedule @@ -435,6 +435,7 @@ cast-varchar-to-time db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 +datareader_datawriter BABEL-5186 BABEL-2736-before-15_3 diff --git a/test/JDBC/upgrade/15_2/schedule b/test/JDBC/upgrade/15_2/schedule index fbecc8b189..6dc7715174 100644 --- a/test/JDBC/upgrade/15_2/schedule +++ b/test/JDBC/upgrade/15_2/schedule @@ -471,6 +471,7 @@ cast-varchar-to-time db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 +datareader_datawriter BABEL-5186 BABEL-2736-before-15_3 diff --git a/test/JDBC/upgrade/15_3/schedule b/test/JDBC/upgrade/15_3/schedule index 871bb8b420..595e1d00c1 100644 --- a/test/JDBC/upgrade/15_3/schedule +++ b/test/JDBC/upgrade/15_3/schedule @@ -490,6 +490,7 @@ cast-varchar-to-time db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 +datareader_datawriter BABEL-5186 BABEL-2736-before-16_5 diff --git a/test/JDBC/upgrade/15_4/schedule b/test/JDBC/upgrade/15_4/schedule index e839788800..949d740815 100644 --- a/test/JDBC/upgrade/15_4/schedule +++ b/test/JDBC/upgrade/15_4/schedule @@ -503,6 +503,7 @@ cast-varchar-to-time db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 +datareader_datawriter BABEL-5186 BABEL-2736-before-16_5 diff --git a/test/JDBC/upgrade/15_5/schedule b/test/JDBC/upgrade/15_5/schedule index f81cb675ab..56bea7fc14 100644 --- a/test/JDBC/upgrade/15_5/schedule +++ b/test/JDBC/upgrade/15_5/schedule @@ -537,3 +537,4 @@ BABEL-CASE_EXPR-before-16_5-or-15_9 BABEL-5186 BABEL-2736-before-16_5 securityadmin_role +datareader_datawriter diff --git a/test/JDBC/upgrade/15_6/schedule b/test/JDBC/upgrade/15_6/schedule index f7511078a3..20fe181f52 100644 --- a/test/JDBC/upgrade/15_6/schedule +++ b/test/JDBC/upgrade/15_6/schedule @@ -552,3 +552,4 @@ BABEL-CASE_EXPR-before-16_5-or-15_9 BABEL-5186 BABEL-2736-before-16_5 securityadmin_role +datareader_datawriter diff --git a/test/JDBC/upgrade/15_7/schedule b/test/JDBC/upgrade/15_7/schedule index a52a2a3c65..7f7feca41a 100644 --- a/test/JDBC/upgrade/15_7/schedule +++ b/test/JDBC/upgrade/15_7/schedule @@ -560,3 +560,4 @@ BABEL-CASE_EXPR-before-16_5-or-15_9 BABEL-5186 BABEL-2736-before-16_5 securityadmin_role +datareader_datawriter diff --git a/test/JDBC/upgrade/15_8/schedule b/test/JDBC/upgrade/15_8/schedule index 9f860c69aa..2130bae88d 100644 --- a/test/JDBC/upgrade/15_8/schedule +++ b/test/JDBC/upgrade/15_8/schedule @@ -551,3 +551,4 @@ BABEL-CASE_EXPR-before-16_5-or-15_9 BABEL-5186 BABEL-2736-before-16_5 securityadmin_role +datareader_datawriter diff --git a/test/JDBC/upgrade/15_9/schedule b/test/JDBC/upgrade/15_9/schedule index f854a14c64..f1d4ef4843 100644 --- a/test/JDBC/upgrade/15_9/schedule +++ b/test/JDBC/upgrade/15_9/schedule @@ -549,6 +549,7 @@ xml_exist-before-16_5 BABEL-5119_before_16_5 db_accessadmin BABEL-CASE_EXPR +datareader_datawriter BABEL-5186 BABEL-2736 diff --git a/test/JDBC/upgrade/16_1/schedule b/test/JDBC/upgrade/16_1/schedule index 1fc95c8cfa..29fac3d06d 100644 --- a/test/JDBC/upgrade/16_1/schedule +++ b/test/JDBC/upgrade/16_1/schedule @@ -544,6 +544,7 @@ db_accessadmin securityadmin_role xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 +datareader_datawriter BABEL-5186 BABEL-2736-before-16_5 diff --git a/test/JDBC/upgrade/16_2/schedule b/test/JDBC/upgrade/16_2/schedule index f615e91895..07349d0ad2 100644 --- a/test/JDBC/upgrade/16_2/schedule +++ b/test/JDBC/upgrade/16_2/schedule @@ -560,3 +560,4 @@ BABEL-CASE_EXPR-before-16_5-or-15_9 BABEL-5186 BABEL-2736-before-16_5 securityadmin_role +datareader_datawriter diff --git a/test/JDBC/upgrade/16_3/schedule b/test/JDBC/upgrade/16_3/schedule index 95e031140a..44ca94ff42 100644 --- a/test/JDBC/upgrade/16_3/schedule +++ b/test/JDBC/upgrade/16_3/schedule @@ -564,3 +564,6 @@ BABEL-CASE_EXPR-before-16_5-or-15_9 BABEL-5186 BABEL-2736-before-16_5 securityadmin_role +datareader_datawriter +BABEL-5186 + diff --git a/test/JDBC/upgrade/16_4/schedule b/test/JDBC/upgrade/16_4/schedule index 37fc5051f3..22edbc5b16 100644 --- a/test/JDBC/upgrade/16_4/schedule +++ b/test/JDBC/upgrade/16_4/schedule @@ -577,3 +577,4 @@ charindex_replace_patindex BABEL-5186 BABEL-2736-before-16_5 securityadmin_role +datareader_datawriter diff --git a/test/JDBC/upgrade/latest/schedule b/test/JDBC/upgrade/latest/schedule index 629ea19334..60971cdce7 100644 --- a/test/JDBC/upgrade/latest/schedule +++ b/test/JDBC/upgrade/latest/schedule @@ -586,4 +586,5 @@ BABEL-CASE_EXPR charindex_replace_patindex BABEL-5186 BABEL-2736 +datareader_datawriter