From 13d0506b1c4d525009a874c7a1f53d81e130e011 Mon Sep 17 00:00:00 2001 From: Tanzeel Khan <140405735+tanscorpio7@users.noreply.github.com> Date: Fri, 18 Oct 2024 15:25:39 +0530 Subject: [PATCH] Support fixed database role db_accessadmin (#66) Description For review comments see babelfish-for-postgresql#2970 Support fixed database role db_accessadmin in babelfish. Member of db_accessadmin can do the following CREATE SCHEMA CREATE/DROP USER ALTER USER They always have connect permission Engine PR: babelfish-for-postgresql/postgresql_modified_for_babelfish#447 Extension PR: #66 Issues Resolved [BABEL-5136] --- .../babelfishpg_tsql/sql/babelfishpg_tsql.sql | 15 +- contrib/babelfishpg_tsql/sql/ownership.sql | 8 +- .../babelfishpg_tsql/sql/sys_functions.sql | 4 +- .../babelfishpg_tsql--4.4.0--4.5.0.sql | 227 ++++++- contrib/babelfishpg_tsql/src/catalog.c | 158 +++-- contrib/babelfishpg_tsql/src/catalog.h | 6 +- contrib/babelfishpg_tsql/src/dbcmds.c | 212 ++++++- contrib/babelfishpg_tsql/src/hooks.c | 2 +- contrib/babelfishpg_tsql/src/multidb.c | 64 +- contrib/babelfishpg_tsql/src/multidb.h | 3 + contrib/babelfishpg_tsql/src/pl_exec-2.c | 10 +- contrib/babelfishpg_tsql/src/pl_handler.c | 211 +++++-- contrib/babelfishpg_tsql/src/pltsql.h | 21 + contrib/babelfishpg_tsql/src/procedures.c | 30 +- contrib/babelfishpg_tsql/src/rolecmds.c | 31 +- contrib/babelfishpg_tsql/src/session.c | 11 + contrib/babelfishpg_tsql/src/session.h | 1 + test/JDBC/expected/BABEL-2403.out | 12 + test/JDBC/expected/BABEL-5119-vu-verify.out | 1 + test/JDBC/expected/BABEL-LOGIN-USER-EXT.out | 35 +- test/JDBC/expected/BABEL-LOGIN-vu-verify.out | 10 +- test/JDBC/expected/BABEL-USER.out | 5 + .../Test-sp_helpdbfixedrole-dep-vu-verify.out | 5 +- .../Test-sp_helpdbfixedrole-vu-verify.out | 6 +- .../Test_alter_db_rename-vu-verify.out | 3 + .../expected/Test_rename_db_single-db.out | 8 + .../Test_sp_rename_database-vu-verify.out | 3 + .../expected/Test_sp_renamedb-vu-verify.out | 3 + .../expected/db_accessadmin-vu-cleanup.out | 25 + .../expected/db_accessadmin-vu-prepare.out | 35 ++ .../expected/db_accessadmin-vu-verify.out | 578 ++++++++++++++++++ .../JDBC/expected/restrict_drop_user_role.out | 36 +- test/JDBC/expected/single_db/BABEL-2403.out | 12 + .../single_db/BABEL-LOGIN-USER-EXT.out | 33 +- test/JDBC/expected/single_db/BABEL-USER.out | 5 + .../single_db/Test_rename_db_single-db.out | 8 + .../single_db/db_accessadmin-vu-verify.out | 578 ++++++++++++++++++ .../single_db/restrict_drop_user_role.out | 32 +- test/JDBC/input/BABEL-LOGIN-USER-EXT.mix | 4 +- test/JDBC/input/db_accessadmin-vu-cleanup.mix | 25 + test/JDBC/input/db_accessadmin-vu-prepare.mix | 35 ++ test/JDBC/input/db_accessadmin-vu-verify.mix | 280 +++++++++ .../input/ownership/BABEL-LOGIN-vu-verify.mix | 2 +- test/JDBC/input/restrict_drop_user_role.mix | 9 + 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_16/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_11/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/16_1/schedule | 1 + test/JDBC/upgrade/16_2/schedule | 1 + test/JDBC/upgrade/16_3/schedule | 1 + test/JDBC/upgrade/16_4/schedule | 1 + test/JDBC/upgrade/16_6/schedule | 2 + test/JDBC/upgrade/latest/schedule | 1 + test/JDBC/upgrade/singledb/schedule | 2 +- .../expected_drop.out | 1 + 72 files changed, 2589 insertions(+), 243 deletions(-) create mode 100644 test/JDBC/expected/db_accessadmin-vu-cleanup.out create mode 100644 test/JDBC/expected/db_accessadmin-vu-prepare.out create mode 100644 test/JDBC/expected/db_accessadmin-vu-verify.out create mode 100644 test/JDBC/expected/single_db/db_accessadmin-vu-verify.out create mode 100644 test/JDBC/input/db_accessadmin-vu-cleanup.mix create mode 100644 test/JDBC/input/db_accessadmin-vu-prepare.mix create mode 100644 test/JDBC/input/db_accessadmin-vu-verify.mix diff --git a/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql b/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql index c6460213bd..aab0e36403 100644 --- a/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql +++ b/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql @@ -2204,7 +2204,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 != 'db_owner' + AND Ext1.orig_username NOT IN ('db_owner', 'db_accessadmin') ORDER BY UserName, RoleName; END -- If the security account is the db fixed role - db_owner @@ -2236,7 +2236,7 @@ BEGIN WHERE Ext1.database_name = DB_NAME() 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 (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 @@ -2274,7 +2274,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 != 'db_owner' + AND Ext1.orig_username NOT IN ('db_owner', 'db_accessadmin') 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 @@ -2435,12 +2435,15 @@ $$ BEGIN -- Returns a list of the fixed database roles. -- Only fixed role present in babelfish is db_owner. - IF pg_catalog.lower(PG_CATALOG.RTRIM(@rolename)) IS NULL OR pg_catalog.lower(PG_CATALOG.RTRIM(@rolename)) = 'db_owner' + IF pg_catalog.lower(PG_CATALOG.RTRIM(@rolename)) IS NULL OR pg_catalog.lower(PG_CATALOG.RTRIM(@rolename)) IN ('db_owner', 'db_accessadmin') BEGIN - SELECT CAST('db_owner' AS sys.SYSNAME) AS DbFixedRole, CAST('DB Owners' AS sys.nvarchar(70)) AS Description; + 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) + WHERE LOWER(RTRIM(@rolename)) IS NULL OR LOWER(RTRIM(@rolename)) = DbFixedRole; END ELSE IF pg_catalog.lower(PG_CATALOG.RTRIM(@rolename)) IN ( - 'db_accessadmin','db_securityadmin','db_ddladmin', 'db_backupoperator', + 'db_securityadmin','db_ddladmin', 'db_backupoperator', 'db_datareader', 'db_datawriter', 'db_denydatareader', 'db_denydatawriter') BEGIN -- Return an empty result set instead of raising an error diff --git a/contrib/babelfishpg_tsql/sql/ownership.sql b/contrib/babelfishpg_tsql/sql/ownership.sql index 61f0f5eea9..226fc47926 100644 --- a/contrib/babelfishpg_tsql/sql/ownership.sql +++ b/contrib/babelfishpg_tsql/sql/ownership.sql @@ -259,7 +259,11 @@ CREATE OR REPLACE PROCEDURE initialize_babelfish ( sa_name VARCHAR(128) ) LANGUAGE plpgsql AS $$ DECLARE - reserved_roles varchar[] := ARRAY['sysadmin', 'securityadmin', 'master_dbo', 'master_guest', 'master_db_owner', 'tempdb_dbo', 'tempdb_guest', 'tempdb_db_owner', 'msdb_dbo', 'msdb_guest', 'msdb_db_owner']; + 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']; + user_id oid := -1; db_name name := NULL; role_name varchar; @@ -456,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', 'guest') -- system users should always be visible + AND (Ext.orig_username IN ('dbo', 'db_owner', 'db_accessadmin', '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 b3a9b7c51c..da36d9a42f 100644 --- a/contrib/babelfishpg_tsql/sql/sys_functions.sql +++ b/contrib/babelfishpg_tsql/sql/sys_functions.sql @@ -4500,7 +4500,9 @@ BEGIN END IF; ELSIF EXISTS (SELECT orig_username FROM sys.babelfish_authid_user_ext WHERE orig_username = role COLLATE sys.database_default) THEN - IF EXISTS (SELECT name FROM sys.user_token WHERE name = role COLLATE sys.database_default) + 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')) + 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 ELSIF (is_windows_grp) THEN RETURN NULL; -- Return NULL if session is not a windows auth session but argument is a windows group diff --git a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.4.0--4.5.0.sql b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.4.0--4.5.0.sql index a91c43e6a7..73050a9ef3 100644 --- a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.4.0--4.5.0.sql +++ b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.4.0--4.5.0.sql @@ -112,6 +112,224 @@ BEGIN END; $$; +CREATE OR REPLACE PROCEDURE sys.create_db_roles_during_upgrade() +LANGUAGE C +AS 'babelfishpg_tsql', 'create_db_roles_during_upgrade'; + +CALL sys.create_db_roles_during_upgrade(); + +DROP PROCEDURE sys.create_db_roles_during_upgrade(); + + +CREATE OR REPLACE FUNCTION sys.is_member(IN role sys.SYSNAME) +RETURNS INT AS +$$ +DECLARE + is_windows_grp boolean := (CHARINDEX('\', role) != 0); -- ' adding quote in comment to suppress build warning +BEGIN + -- Always return 1 for 'public' + IF (role = 'public' COLLATE sys.database_default ) + THEN RETURN 1; + END IF; + + IF EXISTS (SELECT orig_loginname FROM sys.babelfish_authid_login_ext WHERE orig_loginname = role COLLATE sys.database_default AND type != 'S') -- do not consider sql logins + THEN + IF ((EXISTS (SELECT name FROM sys.login_token WHERE name = role COLLATE sys.database_default AND type IN ('SERVER ROLE', 'SQL LOGIN'))) OR is_windows_grp) -- do not consider sql logins, server roles + THEN RETURN NULL; -- Also return NULL if session is not a windows auth session but argument is a windows group + ELSIF EXISTS (SELECT name FROM sys.login_token WHERE name = role COLLATE sys.database_default AND type NOT IN ('SERVER ROLE', 'SQL LOGIN')) + THEN RETURN 1; -- Return 1 if current session user is a member of role or windows group + ELSE RETURN 0; -- Return 0 if current session user is not a member of role or windows group + 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')) + 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 + ELSIF (is_windows_grp) + THEN RETURN NULL; -- Return NULL if session is not a windows auth session but argument is a windows group + ELSE RETURN 0; -- Return 0 if current session user is not a member of role or windows group + END IF; + ELSE RETURN NULL; -- Return NULL if role/group does not exist + END IF; +END; +$$ +LANGUAGE plpgsql STRICT STABLE; + +-- DATABASE_PRINCIPALS +CREATE OR REPLACE VIEW sys.database_principals AS +SELECT +CAST(Ext.orig_username AS SYS.SYSNAME) AS name, +CAST(Base.oid AS INT) AS principal_id, +CAST(Ext.type AS CHAR(1)) as type, +CAST( + CASE + WHEN Ext.type = 'S' THEN 'SQL_USER' + WHEN Ext.type = 'R' THEN 'DATABASE_ROLE' + WHEN Ext.type = 'U' THEN 'WINDOWS_USER' + ELSE NULL + END + AS SYS.NVARCHAR(60)) AS type_desc, +CAST(Ext.default_schema_name AS SYS.SYSNAME) AS default_schema_name, +CAST(Ext.create_date AS SYS.DATETIME) AS create_date, +CAST(Ext.modify_date AS SYS.DATETIME) AS modify_date, +CAST(Ext.owning_principal_id AS INT) AS owning_principal_id, +CAST(CAST(Base2.oid AS INT) AS SYS.VARBINARY(85)) AS SID, +CAST(Ext.is_fixed_role AS SYS.BIT) AS is_fixed_role, +CAST(Ext.authentication_type AS INT) AS authentication_type, +CAST(Ext.authentication_type_desc AS SYS.NVARCHAR(60)) AS authentication_type_desc, +CAST(Ext.default_language_name AS SYS.SYSNAME) AS default_language_name, +CAST(Ext.default_language_lcid AS INT) AS default_language_lcid, +CAST(Ext.allow_encrypted_value_modifications AS SYS.BIT) AS allow_encrypted_value_modifications +FROM pg_catalog.pg_roles AS Base INNER JOIN sys.babelfish_authid_user_ext AS Ext +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 + OR pg_has_role(Ext.rolname, 'MEMBER')) -- Current user should be able to see users it has permission of +UNION ALL +SELECT +CAST(name AS SYS.SYSNAME) AS name, +CAST(-1 AS INT) AS principal_id, +CAST(type AS CHAR(1)) as type, +CAST( + CASE + WHEN type = 'S' THEN 'SQL_USER' + WHEN type = 'R' THEN 'DATABASE_ROLE' + WHEN type = 'U' THEN 'WINDOWS_USER' + ELSE NULL + END + AS SYS.NVARCHAR(60)) AS type_desc, +CAST(NULL AS SYS.SYSNAME) AS default_schema_name, +CAST(NULL AS SYS.DATETIME) AS create_date, +CAST(NULL AS SYS.DATETIME) AS modify_date, +CAST(-1 AS INT) AS owning_principal_id, +CAST(CAST(0 AS INT) AS SYS.VARBINARY(85)) AS SID, +CAST(0 AS SYS.BIT) AS is_fixed_role, +CAST(-1 AS INT) AS authentication_type, +CAST(NULL AS SYS.NVARCHAR(60)) AS authentication_type_desc, +CAST(NULL AS SYS.SYSNAME) AS default_language_name, +CAST(-1 AS INT) AS default_language_lcid, +CAST(0 AS SYS.BIT) AS allow_encrypted_value_modifications +FROM (VALUES ('public', 'R'), ('sys', 'S'), ('INFORMATION_SCHEMA', 'S')) as dummy_principals(name, type); + +GRANT SELECT ON sys.database_principals TO PUBLIC; + +CREATE OR REPLACE PROCEDURE sys.sp_helpuser("@name_in_db" sys.SYSNAME = NULL) AS +$$ +BEGIN + -- If security account is not specified, return info about all users + IF @name_in_db IS NULL + BEGIN + SELECT CAST(Ext1.orig_username AS SYS.SYSNAME) AS 'UserName', + CAST(CASE WHEN Ext1.orig_username = 'dbo' THEN 'db_owner' + WHEN Ext2.orig_username IS NULL THEN 'public' + ELSE Ext2.orig_username END + AS SYS.SYSNAME) AS 'RoleName', + CAST(CASE WHEN Ext1.orig_username = 'dbo' THEN Base4.rolname COLLATE database_default + ELSE LogExt.orig_loginname END + AS SYS.SYSNAME) AS 'LoginName', + CAST(LogExt.default_database_name AS SYS.SYSNAME) AS 'DefDBName', + CAST(Ext1.default_schema_name AS SYS.SYSNAME) AS 'DefSchemaName', + CAST(Base1.oid AS INT) AS 'UserID', + CAST(CASE WHEN Ext1.orig_username = 'dbo' THEN CAST(Base4.oid AS INT) + WHEN Ext1.orig_username = 'guest' THEN CAST(0 AS INT) + ELSE CAST(Base3.oid AS INT) END + AS SYS.VARBINARY(85)) AS 'SID' + FROM sys.babelfish_authid_user_ext AS Ext1 + INNER JOIN pg_catalog.pg_roles AS Base1 ON Base1.rolname = Ext1.rolname + LEFT OUTER JOIN pg_catalog.pg_auth_members AS Authmbr ON Base1.oid = Authmbr.member + LEFT OUTER JOIN pg_catalog.pg_roles AS Base2 ON Base2.oid = Authmbr.roleid + LEFT OUTER JOIN sys.babelfish_authid_user_ext AS Ext2 ON Base2.rolname = Ext2.rolname + LEFT OUTER JOIN sys.babelfish_authid_login_ext As LogExt ON LogExt.rolname = Ext1.login_name + LEFT OUTER JOIN pg_catalog.pg_roles AS Base3 ON Base3.rolname = LogExt.rolname + LEFT OUTER JOIN sys.babelfish_sysdatabases AS Bsdb ON Bsdb.name = DB_NAME() + 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') + ORDER BY UserName, RoleName; + END + -- If the security account is the db fixed role - db_owner + ELSE IF @name_in_db = 'db_owner' + BEGIN + -- TODO: Need to change after we can add/drop members to/from db_owner + SELECT CAST('db_owner' AS SYS.SYSNAME) AS 'Role_name', + ROLE_ID('db_owner') AS 'Role_id', + CAST('dbo' AS SYS.SYSNAME) AS 'Users_in_role', + USER_ID('dbo') AS 'Userid'; + END + -- If the security account is a db role + ELSE IF EXISTS (SELECT 1 + FROM sys.babelfish_authid_user_ext + WHERE (orig_username = @name_in_db + OR pg_catalog.lower(orig_username) = pg_catalog.lower(@name_in_db)) + AND database_name = DB_NAME() + AND type = 'R') + BEGIN + SELECT CAST(Ext1.orig_username AS SYS.SYSNAME) AS 'Role_name', + CAST(Base1.oid AS INT) AS 'Role_id', + CAST(Ext2.orig_username AS SYS.SYSNAME) AS 'Users_in_role', + CAST(Base2.oid AS INT) AS 'Userid' + FROM sys.babelfish_authid_user_ext AS Ext2 + INNER JOIN pg_catalog.pg_roles AS Base2 ON Base2.rolname = Ext2.rolname + INNER JOIN pg_catalog.pg_auth_members AS Authmbr ON Base2.oid = Authmbr.member + LEFT OUTER JOIN pg_catalog.pg_roles AS Base1 ON Base1.oid = Authmbr.roleid + LEFT OUTER JOIN sys.babelfish_authid_user_ext AS Ext1 ON Base1.rolname = Ext1.rolname + 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 (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 + -- If the security account is a user + ELSE IF EXISTS (SELECT 1 + FROM sys.babelfish_authid_user_ext + WHERE (orig_username = @name_in_db + OR pg_catalog.lower(orig_username) = pg_catalog.lower(@name_in_db)) + AND database_name = DB_NAME() + AND type != 'R') + BEGIN + SELECT DISTINCT CAST(Ext1.orig_username AS SYS.SYSNAME) AS 'UserName', + CAST(CASE WHEN Ext1.orig_username = 'dbo' THEN 'db_owner' + WHEN Ext2.orig_username IS NULL THEN 'public' + ELSE Ext2.orig_username END + AS SYS.SYSNAME) AS 'RoleName', + CAST(CASE WHEN Ext1.orig_username = 'dbo' THEN Base4.rolname COLLATE database_default + ELSE LogExt.orig_loginname END + AS SYS.SYSNAME) AS 'LoginName', + CAST(LogExt.default_database_name AS SYS.SYSNAME) AS 'DefDBName', + CAST(Ext1.default_schema_name AS SYS.SYSNAME) AS 'DefSchemaName', + CAST(Base1.oid AS INT) AS 'UserID', + CAST(CASE WHEN Ext1.orig_username = 'dbo' THEN CAST(Base4.oid AS INT) + WHEN Ext1.orig_username = 'guest' THEN CAST(0 AS INT) + ELSE CAST(Base3.oid AS INT) END + AS SYS.VARBINARY(85)) AS 'SID' + FROM sys.babelfish_authid_user_ext AS Ext1 + INNER JOIN pg_catalog.pg_roles AS Base1 ON Base1.rolname = Ext1.rolname + LEFT OUTER JOIN pg_catalog.pg_auth_members AS Authmbr ON Base1.oid = Authmbr.member + LEFT OUTER JOIN pg_catalog.pg_roles AS Base2 ON Base2.oid = Authmbr.roleid + LEFT OUTER JOIN sys.babelfish_authid_user_ext AS Ext2 ON Base2.rolname = Ext2.rolname + LEFT OUTER JOIN sys.babelfish_authid_login_ext As LogExt ON LogExt.rolname = Ext1.login_name + LEFT OUTER JOIN pg_catalog.pg_roles AS Base3 ON Base3.rolname = LogExt.rolname + LEFT OUTER JOIN sys.babelfish_sysdatabases AS Bsdb ON Bsdb.name = DB_NAME() + 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 = @name_in_db OR pg_catalog.lower(Ext1.orig_username) = pg_catalog.lower(@name_in_db)) + ORDER BY UserName, RoleName; + END + -- If the security account is not valid + ELSE + RAISERROR ( 'The name supplied (%s) is not a user, role, or aliased login.', 16, 1, @name_in_db); +END; +$$ +LANGUAGE 'pltsql'; +GRANT EXECUTE on PROCEDURE sys.sp_helpuser TO PUBLIC; + CREATE OR REPLACE FUNCTION sys.bbf_is_member_of_role_nosuper(OID, OID) RETURNS BOOLEAN AS 'babelfishpg_tsql', 'bbf_is_member_of_role_nosuper' LANGUAGE C STABLE STRICT PARALLEL SAFE; @@ -1498,12 +1716,15 @@ $$ BEGIN -- Returns a list of the fixed database roles. -- Only fixed role present in babelfish is db_owner. - IF pg_catalog.lower(PG_CATALOG.RTRIM(@rolename)) IS NULL OR pg_catalog.lower(PG_CATALOG.RTRIM(@rolename)) = 'db_owner' + IF pg_catalog.lower(PG_CATALOG.RTRIM(@rolename)) IS NULL OR pg_catalog.lower(PG_CATALOG.RTRIM(@rolename)) IN ('db_owner', 'db_accessadmin') BEGIN - SELECT CAST('db_owner' AS sys.SYSNAME) AS DbFixedRole, CAST('DB Owners' AS sys.nvarchar(70)) AS Description; + 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) + WHERE LOWER(RTRIM(@rolename)) IS NULL OR LOWER(RTRIM(@rolename)) = DbFixedRole; END ELSE IF pg_catalog.lower(PG_CATALOG.RTRIM(@rolename)) IN ( - 'db_accessadmin','db_securityadmin','db_ddladmin', 'db_backupoperator', + 'db_securityadmin','db_ddladmin', 'db_backupoperator', 'db_datareader', 'db_datawriter', 'db_denydatareader', 'db_denydatawriter') BEGIN -- Return an empty result set instead of raising an error diff --git a/contrib/babelfishpg_tsql/src/catalog.c b/contrib/babelfishpg_tsql/src/catalog.c index f3e7211cdd..c11ce8f62a 100644 --- a/contrib/babelfishpg_tsql/src/catalog.c +++ b/contrib/babelfishpg_tsql/src/catalog.c @@ -449,13 +449,12 @@ get_one_user_db_name(void) db_name = TextDatumGetCString(name); /* check that db_name is not "master", "tempdb", or "msdb" */ - if ((strlen(db_name) != 6 || (strncmp(db_name, "master", 6) != 0)) && - (strlen(db_name) != 6 || (strncmp(db_name, "tempdb", 6) != 0)) && - (strlen(db_name) != 4 || (strncmp(db_name, "msdb", 4) != 0))) + if (!IS_BBF_BUILT_IN_DB(db_name)) { user_db_name = db_name; break; } + pfree(db_name); tuple = heap_getnext(scan, ForwardScanDirection); } @@ -847,74 +846,48 @@ get_authid_login_ext_idx_oid(void) * USER EXT *****************************************/ -bool -is_user(Oid role_oid) +/* + * Check if role is a bbf db principal. Returns BBF_ROLE if it is + * a db role, returns BBF_USER if it is db user else returns 0 + */ + +const int +get_db_principal_kind(Oid role_oid, const char *db_name) { - bool is_user = true; + char result = 0; + bool isnull; HeapTuple tuple; - HeapTuple authtuple; - NameData rolname; + char *rolname; - authtuple = SearchSysCache1(AUTHOID, ObjectIdGetDatum(role_oid)); - if (!HeapTupleIsValid(authtuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("role with OID %u does not exist", role_oid))); - rolname = ((Form_pg_authid) GETSTRUCT(authtuple))->rolname; - tuple = SearchSysCache1(AUTHIDUSEREXTROLENAME, NameGetDatum(&rolname)); + Assert(OidIsValid(role_oid) && db_name); - if (!HeapTupleIsValid(tuple)) - is_user = false; - else + rolname = GetUserNameFromId(role_oid, false); + tuple = SearchSysCache1(AUTHIDUSEREXTROLENAME, CStringGetDatum(rolname)); + pfree(rolname); + + if (HeapTupleIsValid(tuple)) { BpChar type = ((Form_authid_user_ext) GETSTRUCT(tuple))->type; - char *type_str = bpchar_to_cstring(&type); + Datum datum = SysCacheGetAttr(AUTHIDUSEREXTROLENAME, tuple, + Anum_bbf_authid_user_ext_database_name, + &isnull); + char *type_str; + char *db_name_cstring; - /* - * Only sysadmin can not be dropped. For the rest of the cases i.e., type - * is "S" or "U" etc, we should drop the user - */ - if (strcmp(type_str, "R") == 0) - is_user = false; - ReleaseSysCache(tuple); - } - - ReleaseSysCache(authtuple); - - return is_user; -} - -bool -is_role(Oid role_oid) -{ - bool is_role = true; - HeapTuple tuple; - HeapTuple authtuple; - NameData rolname; + Assert(!isnull); - authtuple = SearchSysCache1(AUTHOID, ObjectIdGetDatum(role_oid)); - if (!HeapTupleIsValid(authtuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("role with OID %u does not exist", role_oid))); - rolname = ((Form_pg_authid) GETSTRUCT(authtuple))->rolname; - tuple = SearchSysCache1(AUTHIDUSEREXTROLENAME, NameGetDatum(&rolname)); + type_str = bpchar_to_cstring(&type); + db_name_cstring = TextDatumGetCString(datum); - if (!HeapTupleIsValid(tuple)) - is_role = false; - else - { - BpChar type = ((Form_authid_user_ext) GETSTRUCT(tuple))->type; - char *type_str = bpchar_to_cstring(&type); + if (strcmp(db_name_cstring, db_name) == 0) + result = (strcmp(type_str, "R") == 0) ? BBF_ROLE : BBF_USER; - if (strcmp(type_str, "R") != 0) - is_role = false; + pfree(type_str); + pfree(db_name_cstring); ReleaseSysCache(tuple); } - ReleaseSysCache(authtuple); - - return is_role; + return result; } Oid @@ -937,6 +910,49 @@ get_authid_user_ext_idx_oid(void) return bbf_authid_user_ext_idx_oid; } +/* Returns palloc'd original name given the physical name of the db principal */ +char * +get_authid_user_ext_original_name(const char *physical_role_name, const char *db_name) +{ + char* orig_username = NULL; + bool isnull; + HeapTuple tuple; + + Assert(physical_role_name && strlen(physical_role_name) != 0); + Assert(db_name && strlen(db_name) != 0); + + tuple = SearchSysCache1(AUTHIDUSEREXTROLENAME, CStringGetDatum(physical_role_name)); + + if (HeapTupleIsValid(tuple)) + { + Datum datum = SysCacheGetAttr(AUTHIDUSEREXTROLENAME, tuple, + Anum_bbf_authid_user_ext_database_name, &isnull); + char *db_name_cstring; + + Assert(!isnull); + + db_name_cstring = TextDatumGetCString(datum); + + if (strcmp(db_name_cstring, db_name) == 0) + { + datum = SysCacheGetAttr(AUTHIDUSEREXTROLENAME, tuple, + Anum_bbf_authid_user_ext_orig_username, &isnull); + Assert(!isnull); + orig_username = TextDatumGetCString(datum); + } + + pfree(db_name_cstring); + ReleaseSysCache(tuple); + } + + if (orig_username == NULL) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("Could not find original name for db principal %s in database %s", physical_role_name, db_name))); + + return orig_username; +} + char * get_authid_user_ext_physical_name(const char *db_name, const char *login) { @@ -969,10 +985,24 @@ get_authid_user_ext_physical_name(const char *db_name, const char *login) tuple_user_ext = heap_getnext(scan, ForwardScanDirection); if (HeapTupleIsValid(tuple_user_ext)) { - Form_authid_user_ext userform; + Datum datum; + bool user_can_connect; + bool isnull; - userform = (Form_authid_user_ext) GETSTRUCT(tuple_user_ext); - user_name = pstrdup(NameStr(userform->rolname)); + datum = heap_getattr(tuple_user_ext, Anum_bbf_authid_user_ext_user_can_connect, + RelationGetDescr(bbf_authid_user_ext_rel), &isnull); + Assert(!isnull); + user_can_connect = DatumGetInt32(datum); + + /* db_accessadmin members should always have connect permissions */ + if (user_can_connect == 1 || + (has_privs_of_role(get_role_oid(login, false), get_db_accessadmin_oid(db_name, false)))) + { + datum = heap_getattr(tuple_user_ext, Anum_bbf_authid_user_ext_rolname, + RelationGetDescr(bbf_authid_user_ext_rel), &isnull); + Assert(!isnull); + user_name = pstrdup(DatumGetCString(datum)); + } } table_endscan(scan); @@ -3195,7 +3225,7 @@ create_guest_role_for_db(const char *dbname) /* do this step */ ProcessUtility(wrapper, - "(CREATE LOGICAL DATABASE )", + CREATE_LOGICAL_DATABASE, false, PROCESS_UTILITY_SUBCOMMAND, NULL, @@ -4957,9 +4987,7 @@ rename_tsql_db(char *old_db_name, char *new_db_name) char *old_role_name; char *new_role_name; - if (SINGLE_DB == get_migration_mode() && - ((strlen(role) == 3 && strncmp(role, "dbo", 3) == 0) || - (strlen(role) == 8 && strncmp(role, "db_owner", 8) == 0))) + if (SINGLE_DB == get_migration_mode() && IS_FIXED_DB_PRINCIPAL(role)) continue; old_role_name = get_physical_user_name(old_db_name, role, true, true); diff --git a/contrib/babelfishpg_tsql/src/catalog.h b/contrib/babelfishpg_tsql/src/catalog.h index 05e3b1d44b..75bb2ffdb5 100644 --- a/contrib/babelfishpg_tsql/src/catalog.h +++ b/contrib/babelfishpg_tsql/src/catalog.h @@ -146,10 +146,12 @@ extern Oid get_authid_login_ext_idx_oid(void); extern Oid bbf_authid_user_ext_oid; extern Oid bbf_authid_user_ext_idx_oid; -extern bool is_user(Oid role_oid); -extern bool is_role(Oid role_oid); +#define BBF_ROLE 1 +#define BBF_USER 2 +const int get_db_principal_kind(Oid role_oid, const char *db_name); extern Oid get_authid_user_ext_oid(void); extern Oid get_authid_user_ext_idx_oid(void); +extern char *get_authid_user_ext_original_name(const char *physical_role_name, const char *db_name); extern char *get_authid_user_ext_physical_name(const char *db_name, const char *login_name); extern char *get_authid_user_ext_schema_name(const char *db_name, const char *user_name); extern List *get_authid_user_ext_db_users(const char *db_name); diff --git a/contrib/babelfishpg_tsql/src/dbcmds.c b/contrib/babelfishpg_tsql/src/dbcmds.c index 4c1cbf12f9..b97c23a253 100644 --- a/contrib/babelfishpg_tsql/src/dbcmds.c +++ b/contrib/babelfishpg_tsql/src/dbcmds.c @@ -86,6 +86,7 @@ gen_createdb_subcmds(const char *dbname, const char *owner) const char *schema; const char *dbo; const char *db_owner; + const char *db_accessadmin; const char *guest; const char *guest_schema; Oid owner_oid; @@ -94,6 +95,7 @@ gen_createdb_subcmds(const char *dbname, const char *owner) schema = get_dbo_schema_name(dbname); 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); guest_schema = get_guest_schema_name(dbname); owner_oid = get_role_oid(owner, true); @@ -113,6 +115,10 @@ gen_createdb_subcmds(const char *dbname, const char *owner) if (!owner_is_sa) appendStringInfo(&query, "GRANT dummy TO dummy; "); + /* create db_accessadmin for database */ + appendStringInfo(&query, "CREATE ROLE dummy ROLE dummy; "); + appendStringInfo(&query, "GRANT CREATE ON DATABASE dummy TO dummy; "); + if (guest) { appendStringInfo(&query, "CREATE ROLE dummy INHERIT ROLE dummy; "); @@ -134,13 +140,13 @@ gen_createdb_subcmds(const char *dbname, const char *owner) if (guest) { if (!owner_is_sa) - expected_stmt_num = list_length(logins) > 0 ? 10 : 9; + expected_stmt_num = list_length(logins) > 0 ? 12 : 11; else - expected_stmt_num = list_length(logins) > 0 ? 9 : 8; + expected_stmt_num = list_length(logins) > 0 ? 11 : 10; } else { - expected_stmt_num = 6; + expected_stmt_num = 8; if (!owner_is_sa) expected_stmt_num++; @@ -170,6 +176,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_accessadmin, db_owner, NULL); + + stmt = parsetree_nth_stmt(res, i++); + update_GrantStmt(stmt, get_database_name(MyDatabaseId), NULL, db_accessadmin, NULL); + if (guest) { stmt = parsetree_nth_stmt(res, i++); @@ -205,20 +217,23 @@ 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 *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); 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); /* * For master, tempdb and msdb databases, the guest user will be * enabled by default */ - if (strcmp(dbname, "master") == 0 || strcmp(dbname, "tempdb") == 0 || strcmp(dbname, "msdb") == 0) + if (IS_BBF_BUILT_IN_DB(dbname)) add_to_bbf_authid_user_ext(guest, "guest", dbname, "guest", NULL, false, true, false); else add_to_bbf_authid_user_ext(guest, "guest", dbname, "guest", NULL, false, false, false); @@ -234,15 +249,17 @@ gen_dropdb_subcmds(const char *dbname, List *db_users) List *stmt_list; ListCell *elem; Node *stmt; - int expected_stmts = 6; + int expected_stmts = 8; int i = 0; const char *dbo; const char *db_owner; + const char *db_accessadmin; const char *schema; const char *guest_schema; 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); @@ -254,15 +271,19 @@ 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) + if (strcmp(user_name, db_owner) != 0 && strcmp(user_name, dbo) != 0 && + strcmp(user_name, db_accessadmin) != 0) { appendStringInfo(&query, "DROP OWNED BY dummy CASCADE; "); appendStringInfo(&query, "DROP ROLE dummy; "); expected_stmts += 2; } } - /* Then drop db_owner and dbo in that order */ - appendStringInfo(&query, "DROP OWNED BY dummy, dummy CASCADE; "); + appendStringInfo(&query, "DROP OWNED BY dummy, dummy, dummy CASCADE; "); + + /* Then drop db_accessadmin, db_owner and dbo in that order */ + 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; "); appendStringInfo(&query, "DROP ROLE dummy; "); appendStringInfo(&query, "DROP ROLE dummy; "); @@ -285,7 +306,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) + if (strcmp(user_name, db_owner) != 0 && strcmp(user_name, dbo) != 0 && + strcmp(user_name, db_accessadmin) != 0) { stmt = parsetree_nth_stmt(stmt_list, i++); update_DropOwnedStmt(stmt, list_make1(user_name)); @@ -296,7 +318,12 @@ gen_dropdb_subcmds(const char *dbname, List *db_users) } stmt = parsetree_nth_stmt(stmt_list, i++); - update_DropOwnedStmt(stmt, list_make2(pstrdup(db_owner), pstrdup(dbo))); + update_DropOwnedStmt(stmt, list_make3(pstrdup(db_accessadmin), pstrdup(db_owner), pstrdup(dbo))); + + 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++); + update_DropRoleStmt(stmt, db_accessadmin); stmt = parsetree_nth_stmt(stmt_list, i++); update_GrantStmt(stmt, get_database_name(MyDatabaseId), NULL, dbo, NULL); @@ -598,6 +625,12 @@ create_bbf_db_internal(ParseState *pstate, const char *dbname, List *options, co save_sec_context | SECURITY_LOCAL_USERID_CHANGE); is_set_userid = true; } + else if (stmt->type == T_GrantStmt) + { + SetUserIdAndSecContext(datdba, + save_sec_context | SECURITY_LOCAL_USERID_CHANGE); + is_set_userid = true; + } /* need to make a wrapper PlannedStmt */ wrapper = makeNode(PlannedStmt); wrapper->commandType = CMD_UTILITY; @@ -612,7 +645,7 @@ create_bbf_db_internal(ParseState *pstate, const char *dbname, List *options, co /* do this step */ ProcessUtility(wrapper, - "(CREATE LOGICAL DATABASE )", + CREATE_LOGICAL_DATABASE, false, PROCESS_UTILITY_SUBCOMMAND, NULL, @@ -656,9 +689,7 @@ drop_bbf_db(const char *dbname, bool missing_ok, bool force_drop) bool is_set_userid = false; Oid save_userid; - if ((strlen(dbname) == 6 && (strncmp(dbname, "master", 6) == 0)) || - ((strlen(dbname) == 6 && strncmp(dbname, "tempdb", 6) == 0)) || - (strlen(dbname) == 4 && (strncmp(dbname, "msdb", 4) == 0))) + if (IS_BBF_BUILT_IN_DB(dbname)) { if (!force_drop) ereport(ERROR, @@ -1134,7 +1165,7 @@ create_schema_if_not_exists(const uint16 dbid, wrapper->stmt_len = 0; ProcessUtility(wrapper, - query.data, + CREATE_GUEST_SCHEMAS_DURING_UPGRADE, false, PROCESS_UTILITY_SUBCOMMAND, NULL, @@ -1231,3 +1262,154 @@ create_guest_schema_for_all_dbs(PG_FUNCTION_ARGS) PG_RETURN_INT32(0); } + +static void +create_db_roles_if_not_exists(const char *dbname, List *parsetree_list) +{ + Node *stmt; + Oid save_userid; + int save_sec_context; + int i = 0; + char *db_owner; + char *db_accessadmin; + + db_owner = get_db_owner_name(dbname); + db_accessadmin = get_db_accessadmin_role_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))); + + stmt = parsetree_nth_stmt(parsetree_list, i++); + update_CreateRoleStmt(stmt, db_accessadmin, db_owner, NULL); + + stmt = parsetree_nth_stmt(parsetree_list, i++); + update_GrantStmt(stmt, get_database_name(MyDatabaseId), NULL, db_accessadmin, NULL); + + GetUserIdAndSecContext(&save_userid, &save_sec_context); + + PG_TRY(); + { + ListCell *parsetree_item; + + 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); + + foreach(parsetree_item, parsetree_list) + { + PlannedStmt *wrapper; + + if (stmt->type == T_GrantStmt) + { + SetUserIdAndSecContext(get_role_oid("sysadmin", false), save_sec_context | SECURITY_LOCAL_USERID_CHANGE); + } + else + { + SetUserIdAndSecContext(get_bbf_role_admin_oid(), save_sec_context | SECURITY_LOCAL_USERID_CHANGE); + } + + wrapper = makeNode(PlannedStmt); + wrapper->commandType = CMD_UTILITY; + wrapper->canSetTag = false; + wrapper->utilityStmt = ((RawStmt *) lfirst(parsetree_item))->stmt; + wrapper->stmt_location = 0; + + ProcessUtility(wrapper, + CREATE_FIXED_DB_ROLES, + false, + PROCESS_UTILITY_SUBCOMMAND, + NULL, + NULL, + None_Receiver, + NULL); + + CommandCounterIncrement(); + } + } + PG_FINALLY(); + { + SetUserIdAndSecContext(save_userid, save_sec_context); + pfree(db_owner); + pfree(db_accessadmin); + } + PG_END_TRY(); +} + + +/* +* This function is only being used during upgrade to v4.4.0 +* to create database roles db_accessadmin for each database +*/ +PG_FUNCTION_INFO_V1(create_db_roles_during_upgrade); +Datum +create_db_roles_during_upgrade(PG_FUNCTION_ARGS) +{ + Relation sysdatabase_rel; + TableScanDesc scan; + HeapTuple tuple; + StringInfoData query; + List *parsetree_list; + int pltsql_save_nestlevel; + int save_nestlevel; + + if (!creating_extension) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("%s can only be called from an SQL script executed by CREATE/ALTER EXTENSION", + "create_db_roles_during_upgrade()"))); + + pltsql_save_nestlevel = pltsql_new_guc_nest_level(); + save_nestlevel = NewGUCNestLevel(); + + PG_TRY(); + { + set_config_option("babelfishpg_tsql.sql_dialect", "tsql", + GUC_CONTEXT_CONFIG, + PGC_S_SESSION, GUC_ACTION_SAVE, true, 0, false); + set_config_option("babelfishpg_tsql.migration_mode", physical_schema_name_exists(DBO) ? "single-db" : "multi-db", + GUC_CONTEXT_CONFIG, + PGC_S_SESSION, GUC_ACTION_SAVE, true, 0, false); + + initStringInfo(&query); + + appendStringInfo(&query, "CREATE ROLE dummy ROLE dummy; "); + appendStringInfo(&query, "GRANT CREATE ON DATABASE dummy TO dummy; "); + + parsetree_list = raw_parser(query.data, RAW_PARSE_DEFAULT); + + sysdatabase_rel = table_open(sysdatabases_oid, RowExclusiveLock); + scan = table_beginscan_catalog(sysdatabase_rel, 0, NULL); + + while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + { + Datum datum; + bool isnull; + char *db_name; + + datum = heap_getattr(tuple, Anum_sysdatabases_name, + sysdatabase_rel->rd_att, &isnull); + + Assert(!isnull); + + db_name = TextDatumGetCString(datum); + + create_db_roles_if_not_exists(db_name, parsetree_list); + + pfree(db_name); + } + } + PG_FINALLY(); + { + pltsql_revert_guc(pltsql_save_nestlevel); + } + PG_END_TRY(); + + pfree(query.data); + AtEOXact_GUC(false, save_nestlevel); + table_endscan(scan); + table_close(sysdatabase_rel, RowExclusiveLock); + + PG_RETURN_INT32(0); +} + diff --git a/contrib/babelfishpg_tsql/src/hooks.c b/contrib/babelfishpg_tsql/src/hooks.c index 51c8856c92..a2d3173c35 100644 --- a/contrib/babelfishpg_tsql/src/hooks.c +++ b/contrib/babelfishpg_tsql/src/hooks.c @@ -3207,7 +3207,7 @@ pltsql_store_view_definition(const char *queryString, ObjectAddress address) return; /* Skip if it is for sysdatabases while creating logical database */ - if (strcmp("(CREATE LOGICAL DATABASE )", queryString) == 0) + if (strcmp(CREATE_LOGICAL_DATABASE, queryString) == 0) return; /* Fetch the object details from Relation */ diff --git a/contrib/babelfishpg_tsql/src/multidb.c b/contrib/babelfishpg_tsql/src/multidb.c index 894b7e938a..cdff39ef7c 100644 --- a/contrib/babelfishpg_tsql/src/multidb.c +++ b/contrib/babelfishpg_tsql/src/multidb.c @@ -263,8 +263,7 @@ rewrite_object_refs(Node *stmt) principal_name = grantee->rolename; /* Forbidden the use of some special principals */ - if (strcmp(principal_name, "dbo") == 0 || - strcmp(principal_name, "db_owner") == 0) + if (IS_FIXED_DB_PRINCIPAL(principal_name)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("Cannot use the special principal '%s'", principal_name))); @@ -387,8 +386,7 @@ rewrite_object_refs(Node *stmt) user_name = alter_role->role->rolename; /* TODO: allow ALTER ROLE db_owner */ - if (strcmp(user_name, "dbo") == 0 || - strcmp(user_name, "db_owner") == 0 || + if (IS_FIXED_DB_PRINCIPAL(user_name) || strcmp(user_name, "guest") == 0) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), @@ -1228,9 +1226,7 @@ get_physical_schema_name_by_mode(char *db_name, const char *schema_name, Migrati if (SINGLE_DB == mode) { - if ((strlen(db_name) == 6 && (strncmp(db_name, "master", 6) == 0)) || - (strlen(db_name) == 6 && (strncmp(db_name, "tempdb", 6) == 0)) || - (strlen(db_name) == 4 && (strncmp(db_name, "msdb", 4) == 0))) + if (IS_BBF_BUILT_IN_DB(db_name)) { result = palloc0(MAX_BBF_NAMEDATALEND); @@ -1310,12 +1306,9 @@ get_physical_user_name(char *db_name, char *user_name, bool suppress_db_error, b if (SINGLE_DB == get_migration_mode()) { /* check that db_name is not "master", "tempdb", or "msdb" */ - if ((strlen(db_name) != 6 || (strncmp(db_name, "master", 6) != 0)) && - (strlen(db_name) != 6 || (strncmp(db_name, "tempdb", 6) != 0)) && - (strlen(db_name) != 4 || (strncmp(db_name, "msdb", 4) != 0))) + if (!IS_BBF_BUILT_IN_DB(db_name)) { - if (((strlen(user_name) == 3 && strncmp(user_name, "dbo", 3) == 0) || - (strlen(user_name) == 8 && strncmp(user_name, "db_owner", 8) == 0)) + if (IS_FIXED_DB_PRINCIPAL(user_name) && (suppress_role_error || user_exists_for_db(db_name, new_user_name))) { return new_user_name; @@ -1354,8 +1347,7 @@ get_dbo_schema_name(const char *dbname) Assert(dbname != NULL); - if (SINGLE_DB == get_migration_mode() && 0 != strcmp(dbname, "master") - && 0 != strcmp(dbname, "tempdb") && 0 != strcmp(dbname, "msdb")) + if (SINGLE_DB == get_migration_mode() && !IS_BBF_BUILT_IN_DB(dbname)) { snprintf(name, MAX_BBF_NAMEDATALEND, "%s", "dbo"); } @@ -1374,8 +1366,7 @@ get_dbo_role_name_by_mode(const char *dbname, MigrationMode mode) Assert(dbname != NULL); - if (SINGLE_DB == mode && 0 != strcmp(dbname, "master") - && 0 != strcmp(dbname, "tempdb") && 0 != strcmp(dbname, "msdb")) + if (SINGLE_DB == mode && !IS_BBF_BUILT_IN_DB(dbname)) { snprintf(name, MAX_BBF_NAMEDATALEND, "%s", "dbo"); } @@ -1400,8 +1391,7 @@ get_db_owner_name_by_mode(const char *dbname, MigrationMode mode) Assert(dbname != NULL); - if (SINGLE_DB == mode && 0 != strcmp(dbname, "master") - && 0 != strcmp(dbname, "tempdb") && 0 != strcmp(dbname, "msdb")) + if (SINGLE_DB == mode && !IS_BBF_BUILT_IN_DB(dbname)) { snprintf(name, MAX_BBF_NAMEDATALEND, "%s", "db_owner"); } @@ -1419,6 +1409,16 @@ get_db_owner_name(const char *dbname) return get_db_owner_name_by_mode(dbname, get_migration_mode()); } +Oid +get_db_owner_oid(const char *dbname, bool missing_ok) +{ + char *db_owner_name = get_db_owner_name(dbname); + Oid db_owner_oid = get_role_oid(db_owner_name, missing_ok); + pfree(db_owner_name); + + return db_owner_oid; +} + char * get_guest_role_name(const char *dbname) { @@ -1435,6 +1435,32 @@ get_guest_role_name(const char *dbname) return name; } +char * +get_db_accessadmin_role_name(const char *dbname) +{ + char *name = palloc0(MAX_BBF_NAMEDATALEND); + + Assert(dbname != NULL && strlen(dbname) != 0); + + if (get_migration_mode() == SINGLE_DB && !IS_BBF_BUILT_IN_DB(dbname)) + snprintf(name, MAX_BBF_NAMEDATALEND, "%s", DB_ACCESSADMIN); + else + snprintf(name, MAX_BBF_NAMEDATALEND, "%s_%s", dbname, DB_ACCESSADMIN); + + truncate_identifier(name, strlen(name), false); + return name; +} + +Oid +get_db_accessadmin_oid(const char *dbname, bool missing_ok) +{ + char *db_accessadmin_name = get_db_accessadmin_role_name(dbname); + Oid db_accessadmin_oid = get_role_oid(db_accessadmin_name, missing_ok); + pfree(db_accessadmin_name); + + return db_accessadmin_oid; +} + char * get_guest_schema_name(const char *dbname) { @@ -1466,7 +1492,7 @@ is_builtin_database(const char *dbname) bool physical_schema_name_exists(char *phys_schema_name) { - return SearchSysCacheExists1(NAMESPACENAME, PointerGetDatum(phys_schema_name)); + return SearchSysCacheExists1(SYSNAMESPACENAME, CStringGetDatum(phys_schema_name)); } /* diff --git a/contrib/babelfishpg_tsql/src/multidb.h b/contrib/babelfishpg_tsql/src/multidb.h index c2dacdca5e..196ed8db76 100644 --- a/contrib/babelfishpg_tsql/src/multidb.h +++ b/contrib/babelfishpg_tsql/src/multidb.h @@ -25,6 +25,9 @@ extern char *get_dbo_role_name(const char *dbname); extern char *get_dbo_role_name_by_mode(const char *dbname, MigrationMode mode); extern char *get_db_owner_name(const char *dbname); extern char *get_db_owner_name_by_mode(const char *dbname, MigrationMode mode); +extern Oid get_db_owner_oid(const char *dbname, bool missing_ok); +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 bool is_shared_schema(const char *name); diff --git a/contrib/babelfishpg_tsql/src/pl_exec-2.c b/contrib/babelfishpg_tsql/src/pl_exec-2.c index f47b25c849..f8f265204b 100644 --- a/contrib/babelfishpg_tsql/src/pl_exec-2.c +++ b/contrib/babelfishpg_tsql/src/pl_exec-2.c @@ -3983,11 +3983,6 @@ exec_stmt_grantschema(PLtsql_execstate *estate, PLtsql_stmt_grantschema *stmt) rolname = pstrdup(PUBLIC_ROLE_NAME); role_oid = get_role_oid(rolname, true); - /* Special database roles should throw an error. */ - if (strcmp(grantee_name, "db_owner") == 0) - ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("Cannot grant, deny or revoke permissions to or from special roles."))); - if (!is_public && !OidIsValid(role_oid)) { /* sys or information_schema roles should throw an error. */ @@ -4006,6 +4001,11 @@ exec_stmt_grantschema(PLtsql_execstate *estate, PLtsql_stmt_grantschema *stmt) (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("Cannot grant, deny, or revoke permissions to sa, dbo, entity owner, information_schema, sys, or yourself."))); + /* Special database roles should throw an error. */ + if (IS_FIXED_DB_PRINCIPAL(grantee_name)) + ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("Cannot grant, deny or revoke permissions to or from special roles."))); + /* * If the login is not the db owner or the login is not the member of * sysadmin or login is not the schema owner, then it doesn't have the permission to GRANT/REVOKE. diff --git a/contrib/babelfishpg_tsql/src/pl_handler.c b/contrib/babelfishpg_tsql/src/pl_handler.c index b9d09ce49b..6cadde601c 100644 --- a/contrib/babelfishpg_tsql/src/pl_handler.c +++ b/contrib/babelfishpg_tsql/src/pl_handler.c @@ -34,6 +34,7 @@ #include "commands/dbcommands.h" #include "commands/defrem.h" #include "commands/extension.h" +#include "commands/schemacmds.h" #include "commands/sequence.h" #include "commands/tablecmds.h" #include "commands/trigger.h" @@ -2684,7 +2685,8 @@ bbf_ProcessUtility(PlannedStmt *pstmt, } case T_CreateRoleStmt: { - if (sql_dialect == SQL_DIALECT_TSQL && strcmp(queryString, "(CREATE LOGICAL DATABASE )") != 0) + if (sql_dialect == SQL_DIALECT_TSQL && strcmp(queryString, CREATE_LOGICAL_DATABASE) != 0 && + strcmp(queryString, CREATE_FIXED_DB_ROLES) != 0) { CreateRoleStmt *stmt = (CreateRoleStmt *) parsetree; List *login_options = NIL; @@ -2998,15 +3000,24 @@ bbf_ProcessUtility(PlannedStmt *pstmt, } else if (isuser || isrole) { - char *db_owner_name; + char *current_db_name = get_cur_db_name(); - db_owner_name = get_db_owner_name(get_cur_db_name()); - if (!has_privs_of_role(GetUserId(),get_role_oid(db_owner_name, false))) + if (has_privs_of_role(GetUserId(), get_db_owner_oid(current_db_name, false)) || + (isuser && has_privs_of_role(GetUserId(), get_db_accessadmin_oid(current_db_name, false)))) + { + /* + * members of db_owner can create roles and users + * members of db_accessadmin can only create users + */ + } + else + { ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("User does not have permission to perform this action."))); + } - pfree(db_owner_name); + pfree(current_db_name); } /* @@ -3319,16 +3330,26 @@ bbf_ProcessUtility(PlannedStmt *pstmt, } else if (isuser || isrole) { - char *dbo_name; - char *db_name; - char *user_name; - char *cur_user; - Oid prev_current_user; + char *db_name = get_cur_db_name(); + bool is_member_of_db_owner = false; + bool is_member_of_db_accessadmin = false; + int save_sec_context; + Oid save_userid; + Oid db_owner = get_db_owner_oid(db_name, false); + Oid db_accessadmin = get_db_accessadmin_oid(db_name, false); + Oid user_oid = get_role_oid(stmt->role->rolename, false); - db_name = get_cur_db_name(); - dbo_name = get_dbo_role_name(db_name); - user_name = stmt->role->rolename; - cur_user = GetUserNameFromId(GetUserId(), false); + /* db principal being altered should be a user or role in the current active logical database */ + if ((isuser && get_db_principal_kind(user_oid, db_name) != BBF_USER) || + (isrole && get_db_principal_kind(user_oid, db_name) != BBF_ROLE)) + ereport(ERROR, + (errcode(ERRCODE_CHECK_VIOLATION), + errmsg("Cannot alter the %s '%s', because it does not exist or you do not have permission.", isuser ? "user" : "role", stmt->role->rolename))); + + is_member_of_db_owner = has_privs_of_role(GetUserId(), db_owner); + /* check membership in db_accessadmin if alter user and not already a member of db_owner */ + if (!is_member_of_db_owner && isuser) + is_member_of_db_accessadmin = has_privs_of_role(GetUserId(), db_accessadmin); /* * Check if the current user has privileges. @@ -3339,19 +3360,37 @@ bbf_ProcessUtility(PlannedStmt *pstmt, if (strcmp(defel->defname, "default_schema") == 0) { - if (strcmp(cur_user, dbo_name) != 0 && - strcmp(cur_user, user_name) != 0) + if (is_member_of_db_owner || (isuser && is_member_of_db_accessadmin) || + user_oid == GetUserId()) + { + /* + * members of db_owner can alter default schema for any role or user + * members of db_accessadmin can alter default schema for any user + */ + } + else + { ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("Current user does not have privileges to change schema"))); + } } else if (strcmp(defel->defname, "rename") == 0) { - if (strcmp(cur_user, dbo_name) != 0 && - strcmp(cur_user, user_name) != 0) + if (is_member_of_db_owner || (isuser && is_member_of_db_accessadmin && + !has_privs_of_role(user_oid, db_owner))) + { + /* + * members of db_owner can rename any role or user + * members of db_accessadmin can rename users who are not members of db_owner + */ + } + else + { ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("Current user does not have privileges to change user name"))); + } } } @@ -3361,23 +3400,30 @@ bbf_ProcessUtility(PlannedStmt *pstmt, if (strcmp(defel->defname, "rolemembers") == 0) { - if (strcmp(cur_user, dbo_name) != 0 && - strcmp(cur_user, user_name) != 0) + if (is_member_of_db_owner) + { + /* + * Only members of db_owner can alter login for a user + */ + } + else + { ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("Current user does not have privileges to change login"))); + } } } + GetUserIdAndSecContext(&save_userid, &save_sec_context); /* * We have performed all the permissions checks. * Set current user to bbf_role_admin for alter permissions. */ - prev_current_user = GetUserId(); - SetCurrentRoleId(get_bbf_role_admin_oid(), true); - PG_TRY(); { + SetUserIdAndSecContext(get_bbf_role_admin_oid(), save_sec_context | SECURITY_LOCAL_USERID_CHANGE); + if (prev_ProcessUtility) prev_ProcessUtility(pstmt, queryString, readOnlyTree, context, params, queryEnv, dest, @@ -3393,14 +3439,12 @@ bbf_ProcessUtility(PlannedStmt *pstmt, } PG_FINALLY(); { - SetCurrentRoleId(prev_current_user, true); + SetUserIdAndSecContext(save_userid, save_sec_context); } PG_END_TRY(); set_session_properties(db_name); - pfree(cur_user); pfree(db_name); - pfree(dbo_name); return; } @@ -3450,42 +3494,45 @@ bbf_ProcessUtility(PlannedStmt *pstmt, if (db_name != NULL && strcmp(db_name, "") != 0) { + Oid db_owner = get_db_owner_oid(db_name, false); + Oid db_accessadmin = get_db_accessadmin_oid(db_name, false); + foreach(item, stmt->roles) { RoleSpec *rolspec = lfirst(item); - char *user_name; + char *user_name = get_physical_user_name(db_name, rolspec->rolename, false, true); const char *db_principal_type = drop_user ? "user" : "role"; - char *db_owner_name; - int role_oid; - int rolename_len; - bool is_tsql_db_principal = false; - bool is_psql_db_principal = false; - Oid dbowner; - - user_name = get_physical_user_name(db_name, rolspec->rolename, false, true); - db_owner_name = get_db_owner_name(db_name); - dbowner = get_role_oid(db_owner_name, false); - role_oid = get_role_oid(user_name, true); - rolename_len = strlen(rolspec->rolename); - is_tsql_db_principal = OidIsValid(role_oid) && - ((drop_user && is_user(role_oid)) || - (drop_role && is_role(role_oid))); - is_psql_db_principal = OidIsValid(role_oid) && !is_tsql_db_principal; + int role_oid = get_role_oid(user_name, true); + + if (!OidIsValid(role_oid) || /* Not found */ + (drop_user && get_db_principal_kind(role_oid, db_name) != BBF_USER) || /* Found but not a user in current logical db */ + (drop_role && get_db_principal_kind(role_oid, db_name) != BBF_ROLE)) /* Found but not a role in current logical db */ + { + if (stmt->missing_ok) + { + stmt->roles = foreach_delete_current(stmt->roles, item); + continue; + } + else + ereport(ERROR, + (errcode(ERRCODE_CHECK_VIOLATION), + errmsg("Cannot drop the %s '%s', because it does not exist or you do not have permission.", db_principal_type, rolspec->rolename))); + } /* If user is dbo or role is db_owner, restrict dropping */ - if ((drop_user && rolename_len == 3 && strncmp(rolspec->rolename, "dbo", 3) == 0) || - (drop_role && rolename_len == 8 && strncmp(rolspec->rolename, "db_owner", 8) == 0)) + if (IS_FIXED_DB_PRINCIPAL(rolspec->rolename)) ereport(ERROR, (errcode(ERRCODE_CHECK_VIOLATION), errmsg("Cannot drop the %s '%s'.", db_principal_type, rolspec->rolename))); - /* - * Check for current_user's privileges - * must be database owner to drop user/role - */ - if ((!stmt->missing_ok && !is_tsql_db_principal) || - !is_member_of_role(GetUserId(), dbowner) || - (is_tsql_db_principal && !is_member_of_role(dbowner, role_oid)) || is_psql_db_principal) + if (has_privs_of_role(GetUserId(), db_owner) || (drop_user && has_privs_of_role(GetUserId(), db_accessadmin))) + { + /* + * db_owner can drop any user or role in database + * db_accessadmin can drop users in a database + */ + } + else ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("Cannot drop the %s '%s', because it does not exist or you do not have permission.", db_principal_type, rolspec->rolename))); @@ -3518,8 +3565,6 @@ bbf_ProcessUtility(PlannedStmt *pstmt, errmsg("Cannot disable access to the guest user in master or tempdb."))); alter_user_can_connect(false, rolspec->rolename, db_name); - - pfree(db_owner_name); return; } @@ -3531,7 +3576,6 @@ bbf_ProcessUtility(PlannedStmt *pstmt, } pfree(rolspec->rolename); - pfree(db_owner_name); rolspec->rolename = user_name; } @@ -3595,9 +3639,9 @@ bbf_ProcessUtility(PlannedStmt *pstmt, if (is_login(roleform->oid)) all_logins = true; - else if (is_user(roleform->oid)) + else if (get_db_principal_kind(roleform->oid, get_current_pltsql_db_name()) == BBF_USER) all_users = true; - else if (is_role(roleform->oid)) + else if (get_db_principal_kind(roleform->oid, get_current_pltsql_db_name()) == BBF_ROLE) all_roles = true; else other = true; @@ -3681,8 +3725,10 @@ bbf_ProcessUtility(PlannedStmt *pstmt, GrantStmt *stmt; PlannedStmt *wrapper; RoleSpec *rolspec = create_schema->authrole; + Oid owner_oid; + bool alter_owner = false; - if (strcmp(queryString, "(CREATE LOGICAL DATABASE )") == 0 + if (strcmp(queryString, CREATE_LOGICAL_DATABASE) == 0 && context == PROCESS_UTILITY_SUBCOMMAND) { if (pstmt->stmt_len == 19) @@ -3690,6 +3736,29 @@ bbf_ProcessUtility(PlannedStmt *pstmt, else orig_schema = "dbo"; } + else if (strcmp(queryString, CREATE_GUEST_SCHEMAS_DURING_UPGRADE) == 0) + { + orig_schema = "guest"; + } + else if (rolspec && strcmp(queryString, CREATE_FIXED_DB_ROLES) != 0) + { + const char *db_name = get_current_pltsql_db_name(); + Oid db_accessadmin = get_db_accessadmin_oid(db_name, false); + + owner_oid = get_rolespec_oid(rolspec, true); + /* + * db_accessadmin members can create schema with owner being any db principal + * If it does not have the pg permission then handle it here. We will set owner + * to current user and later alter schema owner using bbf_role_admin + */ + if (!member_can_set_role(GetUserId(), owner_oid) && + has_privs_of_role(GetUserId(), db_accessadmin) && + (get_db_principal_kind(owner_oid, db_name))) + { + create_schema->authrole = NULL; + alter_owner = true; + } + } if (prev_ProcessUtility) prev_ProcessUtility(pstmt, queryString, readOnlyTree, context, params, @@ -3729,8 +3798,27 @@ bbf_ProcessUtility(PlannedStmt *pstmt, NULL); CommandCounterIncrement(); + + if (alter_owner) + { + Oid save_userid; + int save_sec_context; + + GetUserIdAndSecContext(&save_userid, &save_sec_context); + PG_TRY(); + { + SetUserIdAndSecContext(get_bbf_role_admin_oid(), save_sec_context | SECURITY_LOCAL_USERID_CHANGE); + AlterSchemaOwner_oid(get_namespace_oid(create_schema->schemaname, false), owner_oid); + } + PG_FINALLY(); + { + SetUserIdAndSecContext(save_userid, save_sec_context); + } + PG_END_TRY(); + } + /* Grant ALL schema privileges to the user.*/ - if (rolspec && strcmp(queryString, "(CREATE LOGICAL DATABASE )") != 0) + if (rolspec && strcmp(queryString, CREATE_LOGICAL_DATABASE) != 0) { int i; for (i = 0; i < NUMBER_OF_PERMISSIONS; i++) @@ -3812,7 +3900,8 @@ bbf_ProcessUtility(PlannedStmt *pstmt, } } case T_GrantRoleStmt: - if (sql_dialect == SQL_DIALECT_TSQL && strcmp(queryString, "(CREATE LOGICAL DATABASE )") != 0) + if (sql_dialect == SQL_DIALECT_TSQL && strcmp(queryString, CREATE_LOGICAL_DATABASE) != 0 && + strcmp(queryString, CREATE_FIXED_DB_ROLES) != 0) { GrantRoleStmt *grant_role = (GrantRoleStmt *) parsetree; Oid save_userid; @@ -4221,7 +4310,7 @@ bbf_ProcessUtility(PlannedStmt *pstmt, 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) { /* * Ignore GRANT statements that are executed implicitly as a part of diff --git a/contrib/babelfishpg_tsql/src/pltsql.h b/contrib/babelfishpg_tsql/src/pltsql.h index d27a24c945..f9d2b6a9e1 100644 --- a/contrib/babelfishpg_tsql/src/pltsql.h +++ b/contrib/babelfishpg_tsql/src/pltsql.h @@ -1981,6 +1981,27 @@ extern int insert_bulk_kilobytes_per_batch; extern bool insert_bulk_keep_nulls; extern bool insert_bulk_check_constraints; + +/* BBF SUBCOMMANDS QUERY STRING */ +#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 )" + +/* FIXED DB PRINCIPALS */ +#define DBO "dbo" +#define DB_OWNER "db_owner" +#define DB_ACCESSADMIN "db_accessadmin" + +#define IS_BBF_BUILT_IN_DB(dbname) \ + (strncmp(dbname, "master", 6) == 0 || \ + strncmp(dbname, "tempdb", 6) == 0 || \ + 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) + /********************************************************************** * Function declarations **********************************************************************/ diff --git a/contrib/babelfishpg_tsql/src/procedures.c b/contrib/babelfishpg_tsql/src/procedures.c index 0233975bd1..453fb1c567 100644 --- a/contrib/babelfishpg_tsql/src/procedures.c +++ b/contrib/babelfishpg_tsql/src/procedures.c @@ -2244,6 +2244,7 @@ sp_droprole(PG_FUNCTION_ARGS) *lowercase_rolname; size_t len; char *physical_role_name; + char *db_name = get_cur_db_name(); Oid role_oid; List *parsetree_list; ListCell *parsetree_item; @@ -2279,16 +2280,18 @@ sp_droprole(PG_FUNCTION_ARGS) errmsg("Name cannot be NULL."))); /* Map the logical role name to its physical name in the database. */ - physical_role_name = get_physical_user_name(get_cur_db_name(), lowercase_rolname, false, true); + physical_role_name = get_physical_user_name(db_name, lowercase_rolname, false, true); role_oid = get_role_oid(physical_role_name, true); pfree(physical_role_name); /* Check if the role does not exists */ - if (role_oid == InvalidOid || !is_role(role_oid)) + if (role_oid == InvalidOid || get_db_principal_kind(role_oid, db_name) != BBF_ROLE) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("Cannot drop the role '%s', because it does not exist or you do not have permission.", rolname))); + pfree(db_name); + /* Advance cmd counter to make the delete visible */ CommandCounterIncrement(); @@ -2380,6 +2383,7 @@ sp_addrolemember(PG_FUNCTION_ARGS) size_t len; char *physical_member_name; char *physical_role_name; + char *db_name = get_cur_db_name(); Oid role_oid, member_oid; List *parsetree_list; @@ -2430,24 +2434,24 @@ sp_addrolemember(PG_FUNCTION_ARGS) errmsg("Cannot make a role a member of itself."))); /* Map the logical member name to its physical name in the database. */ - physical_member_name = get_physical_user_name(get_cur_db_name(), lowercase_membername, false, true); + physical_member_name = get_physical_user_name(db_name, lowercase_membername, false, true); member_oid = get_role_oid(physical_member_name, true); /* * Check if the user, group or role does not exists and given member * name is an role or user */ - if (member_oid == InvalidOid || (!is_role(member_oid) && !is_user(member_oid))) + if (member_oid == InvalidOid || !get_db_principal_kind(member_oid, db_name)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("User or role '%s' does not exist in this database.", membername))); /* Map the logical role name to its physical name in the database. */ - physical_role_name = get_physical_user_name(get_cur_db_name(), lowercase_rolname, false, true); + physical_role_name = get_physical_user_name(db_name, lowercase_rolname, false, true); role_oid = get_role_oid(physical_role_name, true); /* Check if the role does not exists and given role name is an role */ - if (role_oid == InvalidOid || !is_role(role_oid)) + if (role_oid == InvalidOid || get_db_principal_kind(role_oid, db_name) != BBF_ROLE) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("Cannot alter the role '%s', because it does not exist or you do not have permission.", rolname))); @@ -2458,6 +2462,8 @@ sp_addrolemember(PG_FUNCTION_ARGS) (errcode(ERRCODE_SYNTAX_ERROR), errmsg("Cannot make a role a member of itself."))); + pfree(db_name); + /* Advance cmd counter to make the delete visible */ CommandCounterIncrement(); @@ -2554,6 +2560,7 @@ sp_droprolemember(PG_FUNCTION_ARGS) *lowercase_membername; size_t len; char *physical_name; + char *db_name= get_cur_db_name(); Oid role_oid; List *parsetree_list; ListCell *parsetree_item; @@ -2597,29 +2604,32 @@ sp_droprolemember(PG_FUNCTION_ARGS) errmsg("Name cannot be NULL."))); /* Map the logical role name to its physical name in the database. */ - physical_name = get_physical_user_name(get_cur_db_name(), lowercase_rolname, false, true); + physical_name = get_physical_user_name(db_name, lowercase_rolname, false, true); role_oid = get_role_oid(physical_name, true); /* Throw an error id the given role name doesn't exist or isn't a role */ - if (role_oid == InvalidOid || !is_role(role_oid)) + if (role_oid == InvalidOid || get_db_principal_kind(role_oid, db_name) != BBF_ROLE) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("Cannot alter the role '%s', because it does not exist or you do not have permission.", rolname))); /* Map the logical member name to its physical name in the database. */ pfree(physical_name); - physical_name = get_physical_user_name(get_cur_db_name(), lowercase_membername, false, true); + physical_name = get_physical_user_name(db_name, lowercase_membername, false, true); role_oid = get_role_oid(physical_name, true); /* * Throw an error id the given member name doesn't exist or isn't a * role or user */ - if (role_oid == InvalidOid || (!is_role(role_oid) && !is_user(role_oid))) + if (role_oid == InvalidOid || !get_db_principal_kind(role_oid, db_name)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("Cannot drop the principal '%s', because it does not exist or you do not have permission.", membername))); + + pfree(db_name); + /* Advance cmd counter to make the delete visible */ CommandCounterIncrement(); diff --git a/contrib/babelfishpg_tsql/src/rolecmds.c b/contrib/babelfishpg_tsql/src/rolecmds.c index d6c636decf..fe1cc3c2e6 100644 --- a/contrib/babelfishpg_tsql/src/rolecmds.c +++ b/contrib/babelfishpg_tsql/src/rolecmds.c @@ -293,7 +293,7 @@ drop_bbf_roles(ObjectAccessType access, { if (is_login(roleid)) drop_bbf_authid_login_ext(access, classId, roleid, subId, arg); - else if (is_user(roleid) || is_role(roleid)) + else if (get_db_principal_kind(roleid, get_current_pltsql_db_name())) drop_bbf_authid_user_ext(access, classId, roleid, subId, arg); } @@ -1926,7 +1926,7 @@ is_alter_role_stmt(GrantRoleStmt *stmt) Oid granted = get_role_oid(spec->rolename, true); /* Check if the granted role is an existing database role */ - if (granted == InvalidOid || !is_role(granted)) + if (granted == InvalidOid || get_db_principal_kind(granted, get_current_pltsql_db_name()) != BBF_ROLE) return false; } @@ -1940,6 +1940,8 @@ check_alter_role_stmt(GrantRoleStmt *stmt) Oid grantee; const char *granted_name; const char *grantee_name; + const char *original_user_name; + const char *db_name = get_current_pltsql_db_name(); RoleSpec *granted_spec; RoleSpec *grantee_spec; @@ -1949,7 +1951,7 @@ check_alter_role_stmt(GrantRoleStmt *stmt) grantee = get_role_oid(grantee_name, false); /* Disallow ALTER ROLE if the grantee is not a db principal */ - if (!is_user(grantee) && !is_role(grantee)) + if (!get_db_principal_kind(grantee, db_name)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("%s is not a database user or a user-defined database role", @@ -1960,6 +1962,16 @@ check_alter_role_stmt(GrantRoleStmt *stmt) granted_name = granted_spec->rolename; granted = get_role_oid(granted_name, false); + original_user_name = get_authid_user_ext_original_name(granted_name, db_name); + Assert(original_user_name); + + /* only members of db_owner can alter drop members of fixed db roles */ + if (IS_FIXED_DB_PRINCIPAL(original_user_name) && + !has_privs_of_role(GetUserId(), get_db_owner_oid(db_name, false))) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("Cannot alter the role '%s', because it does not exist or you do not have permission.", original_user_name))); + /* * Disallow ALTER ROLE if 1. Current login doesn't have permission on the * granted role, or 2. The current user is trying to add/drop itself from @@ -2060,7 +2072,7 @@ is_rolemember(PG_FUNCTION_ARGS) char *dc_principal = NULL; char *physical_role_name; char *physical_principal_name; - char *cur_db_name; + char *cur_db_name = get_cur_db_name(); char *db_owner_name; char *dbo_role_name; int idx; @@ -2074,7 +2086,7 @@ is_rolemember(PG_FUNCTION_ARGS) while (idx > 0 && isspace((unsigned char) role[idx - 1])) role[--idx] = '\0'; dc_role = downcase_identifier(role, strlen(role), false, false); - physical_role_name = get_physical_user_name(get_cur_db_name(), dc_role, false, true); + physical_role_name = get_physical_user_name(cur_db_name, dc_role, false, true); role_oid = get_role_oid(physical_role_name, true); pfree(physical_role_name); @@ -2090,7 +2102,7 @@ is_rolemember(PG_FUNCTION_ARGS) while (idx > 0 && isspace((unsigned char) principal[idx - 1])) principal[--idx] = '\0'; dc_principal = downcase_identifier(principal, strlen(principal), false, false); - physical_principal_name = get_physical_user_name(get_cur_db_name(), dc_principal, false, true); + physical_principal_name = get_physical_user_name(cur_db_name, dc_principal, false, true); principal_oid = get_role_oid(physical_principal_name, true); pfree(physical_principal_name); } @@ -2114,7 +2126,7 @@ is_rolemember(PG_FUNCTION_ARGS) * principal. Note that if given principal is current user, we'll always * have permissions. */ - if (!is_role(role_oid) || + if (get_db_principal_kind(role_oid, cur_db_name) != BBF_ROLE || ((principal_oid != cur_user_oid) && (!has_privs_of_role(cur_user_oid, role_oid) || !has_privs_of_role(cur_user_oid, principal_oid)))) @@ -2124,16 +2136,17 @@ is_rolemember(PG_FUNCTION_ARGS) * Recursively check if the given principal is a member of the role, not * considering superuserness */ - cur_db_name = get_cur_db_name(); db_owner_name = get_db_owner_name(cur_db_name); dbo_role_name = get_dbo_role_name(cur_db_name); db_owner_oid = get_role_oid(db_owner_name, false); dbo_role_oid = get_role_oid(dbo_role_name, false); + pfree(cur_db_name); pfree(db_owner_name); pfree(dbo_role_name); - if ((principal_oid == db_owner_oid) || (principal_oid == dbo_role_oid)) + /* Fixed db principals cannot be member of other roles except dbo which is member of all fixed roles */ + if ((principal_oid == db_owner_oid) || (principal_oid == dbo_role_oid && !IS_FIXED_DB_PRINCIPAL(role))) PG_RETURN_INT32(0); else if (is_member_of_role_nosuper(principal_oid, role_oid)) PG_RETURN_INT32(1); diff --git a/contrib/babelfishpg_tsql/src/session.c b/contrib/babelfishpg_tsql/src/session.c index 1698516ecc..b370392dde 100644 --- a/contrib/babelfishpg_tsql/src/session.c +++ b/contrib/babelfishpg_tsql/src/session.c @@ -49,12 +49,23 @@ get_cur_db_id(void) return current_db_id; } +/* same as get_current_pltsql_db_name but reurn value is palloc'd */ char * get_cur_db_name(void) { return pstrdup(current_db_name); } +/* + * returns current active babelfish db name + * Callers should NOT pfree the return value + */ +const char * +get_current_pltsql_db_name(void) +{ + return current_db_name; +} + void set_cur_db_name_for_parallel_worker(const char* logical_db_name) { diff --git a/contrib/babelfishpg_tsql/src/session.h b/contrib/babelfishpg_tsql/src/session.h index c5d17cb161..82f58e3bd9 100644 --- a/contrib/babelfishpg_tsql/src/session.h +++ b/contrib/babelfishpg_tsql/src/session.h @@ -7,6 +7,7 @@ extern int16 get_cur_db_id(void); extern void set_cur_db(int16 id, const char *name); extern char *get_cur_db_name(void); +extern const char *get_current_pltsql_db_name(void); extern void bbf_set_current_user(const char *user_name); extern void set_session_properties(const char *db_name); extern void check_session_db_access(const char *dn_name); diff --git a/test/JDBC/expected/BABEL-2403.out b/test/JDBC/expected/BABEL-2403.out index c3e19ceb06..9039d7ce19 100644 --- a/test/JDBC/expected/BABEL-2403.out +++ b/test/JDBC/expected/BABEL-2403.out @@ -101,6 +101,12 @@ 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#!#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"} @@ -192,6 +198,12 @@ 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#!#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-5119-vu-verify.out b/test/JDBC/expected/BABEL-5119-vu-verify.out index 330eb88303..fbccec6970 100644 --- a/test/JDBC/expected/BABEL-5119-vu-verify.out +++ b/test/JDBC/expected/BABEL-5119-vu-verify.out @@ -758,6 +758,7 @@ SELECT u.orig_username, SUBSTRING(a.datacl, strpos(a.datacl, '='), strpos(a.data GO ~~START~~ nvarchar#!#varchar +db_accessadmin#!#=C dbo#!#=CTc ~~END~~ diff --git a/test/JDBC/expected/BABEL-LOGIN-USER-EXT.out b/test/JDBC/expected/BABEL-LOGIN-USER-EXT.out index e09fa162bb..70d0b5e77b 100644 --- a/test/JDBC/expected/BABEL-LOGIN-USER-EXT.out +++ b/test/JDBC/expected/BABEL-LOGIN-USER-EXT.out @@ -130,14 +130,18 @@ master_r1#!#r1#!#r1#!#master#!#sch2 ALTER USER r1 WITH NAME = new_r1; go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Current user does not have privileges to change user name)~~ + SELECT rolname, orig_username, login_name, database_name, default_schema_name FROM sys.babelfish_authid_user_ext -WHERE orig_username = 'new_r1'; +WHERE orig_username = 'new_r1' or orig_username = 'r1'; go ~~START~~ varchar#!#nvarchar#!#varchar#!#nvarchar#!#nvarchar -master_new_r1#!#new_r1#!#r1#!#master#!#sch2 +master_r1#!#r1#!#r1#!#master#!#sch2 ~~END~~ @@ -217,7 +221,7 @@ r2 -- tsql -DROP USER new_r1; +DROP USER r1; go -- psql @@ -690,15 +694,19 @@ ORDER BY rolname; GO ~~START~~ varchar#!#nvarchar#!#varchar#!#nvarchar#!#nvarchar +db1_db_accessadmin#!#db_accessadmin#!##!#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_owner#!#db_owner#!##!#master#!# master_dbo#!#dbo#!##!#master#!#dbo master_guest#!#guest#!##!#master#!#guest +msdb_db_accessadmin#!#db_accessadmin#!##!#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_owner#!#db_owner#!##!#tempdb#!# tempdb_dbo#!#dbo#!##!#tempdb#!#dbo tempdb_guest#!#guest#!##!#tempdb#!#guest @@ -863,12 +871,15 @@ ORDER BY rolname; GO ~~START~~ varchar#!#nvarchar#!#varchar#!#nvarchar#!#nvarchar +master_db_accessadmin#!#db_accessadmin#!##!#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_owner#!#db_owner#!##!#msdb#!# msdb_dbo#!#dbo#!##!#msdb#!#dbo msdb_guest#!#guest#!##!#msdb#!#guest +tempdb_db_accessadmin#!#db_accessadmin#!##!#tempdb#!# tempdb_db_owner#!#db_owner#!##!#tempdb#!# tempdb_dbo#!#dbo#!##!#tempdb#!#dbo tempdb_guest#!#guest#!##!#tempdb#!#guest @@ -914,18 +925,23 @@ ORDER BY rolname; GO ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar#!#nvarchar +db1_db_accessadmin#!##!#db_accessadmin#!#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_owner#!##!#db_owner#!#db2#!# db2_dbo#!##!#dbo#!#db2#!#dbo db2_guest#!##!#guest#!#db2#!#guest +master_db_accessadmin#!##!#db_accessadmin#!#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_owner#!##!#db_owner#!#msdb#!# msdb_dbo#!##!#dbo#!#msdb#!#dbo msdb_guest#!##!#guest#!#msdb#!#guest +tempdb_db_accessadmin#!##!#db_accessadmin#!#tempdb#!# tempdb_db_owner#!##!#db_owner#!#tempdb#!# tempdb_dbo#!##!#dbo#!#tempdb#!#dbo tempdb_guest#!##!#guest#!#tempdb#!#guest @@ -940,6 +956,7 @@ GO varchar#!#varchar guest#!#guest dbo#!#dbo +db_accessadmin#!# db_owner#!# INFORMATION_SCHEMA#!# public#!# @@ -972,6 +989,7 @@ GO varchar#!#varchar guest#!#guest dbo#!#dbo +db_accessadmin#!# db_owner#!# INFORMATION_SCHEMA#!# public#!# @@ -1106,15 +1124,19 @@ ORDER BY rolname; GO ~~START~~ varchar#!#nvarchar#!#varchar#!#nvarchar#!#nvarchar +db2_db_accessadmin#!#db_accessadmin#!##!#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_owner#!#db_owner#!##!#master#!# master_dbo#!#dbo#!##!#master#!#dbo master_guest#!#guest#!##!#master#!#guest +msdb_db_accessadmin#!#db_accessadmin#!##!#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_owner#!#db_owner#!##!#tempdb#!# tempdb_dbo#!#dbo#!##!#tempdb#!#dbo tempdb_guest#!#guest#!##!#tempdb#!#guest @@ -1130,12 +1152,15 @@ ORDER BY rolname; GO ~~START~~ varchar#!#nvarchar#!#varchar#!#nvarchar#!#nvarchar +master_db_accessadmin#!#db_accessadmin#!##!#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_owner#!#db_owner#!##!#msdb#!# msdb_dbo#!#dbo#!##!#msdb#!#dbo msdb_guest#!#guest#!##!#msdb#!#guest +tempdb_db_accessadmin#!#db_accessadmin#!##!#tempdb#!# tempdb_db_owner#!#db_owner#!##!#tempdb#!# tempdb_dbo#!#dbo#!##!#tempdb#!#dbo tempdb_guest#!#guest#!##!#tempdb#!#guest @@ -1408,6 +1433,7 @@ GO varchar babel_4935_no_sysadmin1 babel_4935_no_sysadmin2 +db_accessadmin db_owner dbo guest @@ -1425,6 +1451,7 @@ GO varchar babel_4935_no_sysadmin1 babel_4935_no_sysadmin2 +db_accessadmin db_owner dbo guest @@ -1441,6 +1468,7 @@ GO ~~START~~ varchar babel_4935_no_sysadmin1 +db_accessadmin db_owner dbo guest @@ -1456,6 +1484,7 @@ SELECT name FROM sys.database_principals ORDER BY name GO ~~START~~ varchar +db_accessadmin db_owner dbo guest diff --git a/test/JDBC/expected/BABEL-LOGIN-vu-verify.out b/test/JDBC/expected/BABEL-LOGIN-vu-verify.out index e35d0a6387..8c9ae546db 100644 --- a/test/JDBC/expected/BABEL-LOGIN-vu-verify.out +++ b/test/JDBC/expected/BABEL-LOGIN-vu-verify.out @@ -68,6 +68,10 @@ go ALTER USER babel_login_vu_prepare_r1 WITH NAME = babel_login_vu_prepare_r1_new; go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Current user does not have privileges to change user name)~~ + ALTER USER babel_login_vu_prepare_r2 WITH DEFAULT_SCHEMA = NULL; go @@ -90,7 +94,7 @@ ORDER BY rolname; go ~~START~~ varchar#!#nvarchar#!#varchar#!#nvarchar#!#nvarchar -master_babel_login_vu_prepare_r1_new#!#babel_login_vu_prepare_r1_new#!#babel_login_vu_prepare_r1#!#master#!#babel_login_vu_prepare_sch +master_babel_login_vu_prepare_r1#!#babel_login_vu_prepare_r1#!#babel_login_vu_prepare_r1#!#master#!#babel_login_vu_prepare_sch master_babel_login_vu_prepare_r2#!#babel_login_vu_prepare_r2#!#babel_login_vu_prepare_r2#!#master#!#babel_login_vu_prepare_sch ~~END~~ @@ -124,7 +128,7 @@ ORDER BY rolname; go ~~START~~ varchar#!#nvarchar#!#varchar#!#nvarchar#!#nvarchar -master_babel_login_vu_prepare_r1_new#!#babel_login_vu_prepare_r1_new#!#babel_login_vu_prepare_r1#!#master#!#babel_login_vu_prepare_sch +master_babel_login_vu_prepare_r1#!#babel_login_vu_prepare_r1#!#babel_login_vu_prepare_r1#!#master#!#babel_login_vu_prepare_sch master_babel_login_vu_prepare_r2#!#babel_login_vu_prepare_r2#!#babel_login_vu_prepare_r2#!#master#!#babel_login_vu_prepare_sch ~~END~~ @@ -312,7 +316,7 @@ go DROP USER babel_login_vu_prepare_err_user; go -DROP USER babel_login_vu_prepare_r1_new +DROP USER babel_login_vu_prepare_r1 go DROP USER babel_login_vu_prepare_r2 diff --git a/test/JDBC/expected/BABEL-USER.out b/test/JDBC/expected/BABEL-USER.out index 819bf7c696..6a9646102c 100644 --- a/test/JDBC/expected/BABEL-USER.out +++ b/test/JDBC/expected/BABEL-USER.out @@ -49,15 +49,19 @@ ORDER BY rolname; GO ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar#!#nvarchar +db1_db_accessadmin#!##!#db_accessadmin#!#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_owner#!##!#db_owner#!#master#!# master_dbo#!##!#dbo#!#master#!#dbo master_guest#!##!#guest#!#master#!#guest +msdb_db_accessadmin#!##!#db_accessadmin#!#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_owner#!##!#db_owner#!#tempdb#!# tempdb_dbo#!##!#dbo#!#tempdb#!#dbo tempdb_guest#!##!#guest#!#tempdb#!#guest @@ -72,6 +76,7 @@ GO varchar#!#varchar guest#!#guest dbo#!#dbo +db_accessadmin#!# 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 a8ea04ef07..0d807bb979 100644 --- a/test/JDBC/expected/Test-sp_helpdbfixedrole-dep-vu-verify.out +++ b/test/JDBC/expected/Test-sp_helpdbfixedrole-dep-vu-verify.out @@ -3,6 +3,7 @@ GO ~~START~~ varchar#!#nvarchar db_owner#!#DB Owners +db_accessadmin#!#DB Access Administrators ~~END~~ @@ -18,7 +19,7 @@ SELECT dbo.test_sp_helpdbfixedrole_func() GO ~~START~~ int -1 +2 ~~END~~ @@ -26,7 +27,7 @@ SELECT * FROM test_sp_helpdbfixedrole_view GO ~~START~~ int -1 +2 ~~END~~ diff --git a/test/JDBC/expected/Test-sp_helpdbfixedrole-vu-verify.out b/test/JDBC/expected/Test-sp_helpdbfixedrole-vu-verify.out index 825df76dc1..9c8bfa4e6b 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: 1~~ +~~ROW COUNT: 2~~ SELECT DbFixedRole, Description FROM test_sp_helpdbfixedrole_tbl @@ -8,6 +8,7 @@ GO ~~START~~ varchar#!#nvarchar db_owner#!#DB Owners +db_accessadmin#!#DB Access Administrators ~~END~~ @@ -48,6 +49,8 @@ GO INSERT INTO test_sp_helpdbfixedrole_tbl (DbFixedRole, Description) EXEC sp_helpdbfixedrole 'db_accessadmin' GO +~~ROW COUNT: 1~~ + INSERT INTO test_sp_helpdbfixedrole_tbl (DbFixedRole, Description) EXEC sp_helpdbfixedrole 'DB_securityadmin' GO INSERT INTO test_sp_helpdbfixedrole_tbl (DbFixedRole, Description) EXEC sp_helpdbfixedrole 'db_ddladmin ' @@ -67,6 +70,7 @@ SELECT DbFixedRole, Description FROM test_sp_helpdbfixedrole_tbl GO ~~START~~ varchar#!#nvarchar +db_accessadmin#!#DB Access Administrators ~~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 daf6199cbc..02c5571170 100644 --- a/test/JDBC/expected/Test_alter_db_rename-vu-verify.out +++ b/test/JDBC/expected/Test_alter_db_rename-vu-verify.out @@ -19,6 +19,7 @@ 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_owner#!##!#db_owner#!#rename_db_database1 rename_db_database1_dbo#!##!#dbo#!#rename_db_database1 rename_db_database1_guest#!##!#guest#!#rename_db_database1 @@ -80,6 +81,7 @@ 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_owner#!##!#db_owner#!#rename_db_database2 rename_db_database2_dbo#!##!#dbo#!#rename_db_database2 rename_db_database2_guest#!##!#guest#!#rename_db_database2 @@ -190,6 +192,7 @@ thisnewdatabasenameiscasesensitc4313f9adf0e47cfa5aca25228e02f29#!#dbo varchar#!#varchar#!#nvarchar#!#nvarchar thisnewdatabasenameiscasesensit4e1f355d810759b9f1a59b04496ed2e1#!##!#guest#!#thisnewdatabasenameiscasesensit44f3247005ec268e1a10c736599cfb7e thisnewdatabasenameiscasesensit72e4dcc7ed25f5536033cf547cd7f001#!##!#db_owner#!#thisnewdatabasenameiscasesensit44f3247005ec268e1a10c736599cfb7e +thisnewdatabasenameiscasesensit944678472843354d6b3a4354630249a8#!##!#db_accessadmin#!#thisnewdatabasenameiscasesensit44f3247005ec268e1a10c736599cfb7e thisnewdatabasenameiscasesensitc4313f9adf0e47cfa5aca25228e02f29#!##!#dbo#!#thisnewdatabasenameiscasesensit44f3247005ec268e1a10c736599cfb7e ~~END~~ diff --git a/test/JDBC/expected/Test_rename_db_single-db.out b/test/JDBC/expected/Test_rename_db_single-db.out index 6c4d9dc470..f1e8d609f7 100644 --- a/test/JDBC/expected/Test_rename_db_single-db.out +++ b/test/JDBC/expected/Test_rename_db_single-db.out @@ -32,6 +32,7 @@ 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_owner#!##!#db_owner#!#rename_db_database1 rename_db_database1_dbo#!##!#dbo#!#rename_db_database1 rename_db_database1_guest#!##!#guest#!#rename_db_database1 @@ -80,6 +81,7 @@ 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_owner#!##!#db_owner#!#rename_db_database2 rename_db_database2_dbo#!##!#dbo#!#rename_db_database2 rename_db_database2_guest#!##!#guest#!#rename_db_database2 @@ -128,6 +130,7 @@ 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_owner#!##!#db_owner#!#rename_db_database1 rename_db_database1_dbo#!##!#dbo#!#rename_db_database1 rename_db_database1_guest#!##!#guest#!#rename_db_database1 @@ -176,6 +179,7 @@ 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_owner#!##!#db_owner#!#rename_db_database2 rename_db_database2_dbo#!##!#dbo#!#rename_db_database2 rename_db_database2_guest#!##!#guest#!#rename_db_database2 @@ -236,6 +240,7 @@ 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_owner#!##!#db_owner#!#rename_db_database1 rename_db_database1_dbo#!##!#dbo#!#rename_db_database1 rename_db_database1_guest#!##!#guest#!#rename_db_database1 @@ -284,6 +289,7 @@ 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_owner#!##!#db_owner#!#rename_db_database2 rename_db_database2_dbo#!##!#dbo#!#rename_db_database2 rename_db_database2_guest#!##!#guest#!#rename_db_database2 @@ -332,6 +338,7 @@ 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_owner#!##!#db_owner#!#rename_db_database1 rename_db_database1_dbo#!##!#dbo#!#rename_db_database1 rename_db_database1_guest#!##!#guest#!#rename_db_database1 @@ -380,6 +387,7 @@ 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_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 a59f3818fa..b2cbeb5ef1 100644 --- a/test/JDBC/expected/Test_sp_rename_database-vu-verify.out +++ b/test/JDBC/expected/Test_sp_rename_database-vu-verify.out @@ -19,6 +19,7 @@ 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_owner#!##!#db_owner#!#sp_rename_database1 sp_rename_database1_dbo#!##!#dbo#!#sp_rename_database1 sp_rename_database1_guest#!##!#guest#!#sp_rename_database1 @@ -80,6 +81,7 @@ 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_owner#!##!#db_owner#!#sp_rename_database2 sp_rename_database2_dbo#!##!#dbo#!#sp_rename_database2 sp_rename_database2_guest#!##!#guest#!#sp_rename_database2 @@ -197,6 +199,7 @@ 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_thisnewdatabasenameisa0a5aa90abf2314f4773860fda5e43a2#!##!#db_accessadmin#!#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 5e9f657003..598688bd0a 100644 --- a/test/JDBC/expected/Test_sp_renamedb-vu-verify.out +++ b/test/JDBC/expected/Test_sp_renamedb-vu-verify.out @@ -19,6 +19,7 @@ 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_owner#!##!#db_owner#!#sp_renamedb_database1 sp_renamedb_database1_dbo#!##!#dbo#!#sp_renamedb_database1 sp_renamedb_database1_guest#!##!#guest#!#sp_renamedb_database1 @@ -80,6 +81,7 @@ 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_owner#!##!#db_owner#!#sp_renamedb_database2 sp_renamedb_database2_dbo#!##!#dbo#!#sp_renamedb_database2 sp_renamedb_database2_guest#!##!#guest#!#sp_renamedb_database2 @@ -198,6 +200,7 @@ varchar#!#varchar#!#nvarchar#!#nvarchar sp_renamedb_thisnewdatabasename115699cc11f7805d9b9b640d6455580c#!##!#dbo#!#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 ~~END~~ ~~START~~ diff --git a/test/JDBC/expected/db_accessadmin-vu-cleanup.out b/test/JDBC/expected/db_accessadmin-vu-cleanup.out new file mode 100644 index 0000000000..234a2afc13 --- /dev/null +++ b/test/JDBC/expected/db_accessadmin-vu-cleanup.out @@ -0,0 +1,25 @@ +-- tsql +USE master +GO +DROP DATABASE IF EXISTS babel_5136 +GO +DROP LOGIN babel_5136_l1 +GO +DROP LOGIN babel_5136_l2 +GO +DROP LOGIN babel_5136_l3 +GO +DROP LOGIN babel_5136_db_accessadmin_l1 +GO +DROP USER babel_5136_u1 +GO +DROP USER babel_5136_user_master +GO +DROP ROLE babel_5136_r1 +GO +DROP TABLE babel_5136_t1 +GO +DROP PROC babel_5136_p1 +GO +DROP FUNCTION f1 +GO diff --git a/test/JDBC/expected/db_accessadmin-vu-prepare.out b/test/JDBC/expected/db_accessadmin-vu-prepare.out new file mode 100644 index 0000000000..a1e3bfe041 --- /dev/null +++ b/test/JDBC/expected/db_accessadmin-vu-prepare.out @@ -0,0 +1,35 @@ +-- tsql +USE master +GO +CREATE LOGIN babel_5136_l1 WITH PASSWORD = '12345678' +GO +CREATE LOGIN babel_5136_l2 WITH PASSWORD = '12345678' +GO +CREATE LOGIN babel_5136_l3 WITH PASSWORD = '12345678' +GO +CREATE USER babel_5136_u1 FOR LOGIN babel_5136_l1 +GO +CREATE ROLE babel_5136_r1 +GO +CREATE TABLE babel_5136_t1 (id INT) +GO +CREATE PROC babel_5136_p1 AS SELECT 1 +GO +CREATE FUNCTION f1() RETURNS INT AS BEGIN return 1; END +GO + +CREATE DATABASE babel_5136 +GO +USE babel_5136 +GO +CREATE USER babel_5136_u1 FOR LOGIN babel_5136_l1 +GO +CREATE ROLE babel_5136_r1 +GO +CREATE TABLE babel_5136_t1 (id INT) +GO +CREATE PROC babel_5136_p1 AS SELECT 1 +GO +CREATE FUNCTION babel_5136_f1() RETURNS INT AS BEGIN return 1; END +GO + diff --git a/test/JDBC/expected/db_accessadmin-vu-verify.out b/test/JDBC/expected/db_accessadmin-vu-verify.out new file mode 100644 index 0000000000..8c8ca2cf09 --- /dev/null +++ b/test/JDBC/expected/db_accessadmin-vu-verify.out @@ -0,0 +1,578 @@ + + +-- tsql +-- CREATE LOGIN AND ADD IT TO db_accessadmin + -- Only members of db_owner should be able to add/drop members to db_accessadmin +-- db_accessadmin should be able to do the following + -- CREATE USER in database + -- DROP ANY USER in database (except dbo) + -- ALTER default_schema for any user in database + -- RENAME user execpt for members of db_owner + -- CREATE SCHEMA for self or other users in database +-- bbf dump does not dump password so reset the password +ALTER LOGIN babel_5136_l1 WITH PASSWORD = '12345678' +GO +-- CREATE A USER WITH db_accessadmin privilege in DATABASE babel_5136 +USE master +GO +CREATE LOGIN babel_5136_db_accessadmin_l1 WITH PASSWORD = '12345678' +GO +CREATE USER babel_5136_user_master FOR LOGIN babel_5136_db_accessadmin_l1 +GO +USE babel_5136 +GO +CREATE USER babel_5136_db_accessadmin_user FOR LOGIN babel_5136_db_accessadmin_l1 +GO +-- ADD DROP MEMBERS TO db_accessadmin USING dbo +sp_addrolemember 'db_accessadmin', 'babel_5136_db_accessadmin_user' +GO +SELECT IS_ROLEMEMBER('db_accessadmin', 'babel_5136_db_accessadmin_user') +GO +~~START~~ +int +1 +~~END~~ + +sp_droprolemember 'db_accessadmin', 'babel_5136_db_accessadmin_user' +GO +SELECT IS_ROLEMEMBER('db_accessadmin', 'babel_5136_db_accessadmin_user') +GO +~~START~~ +int +0 +~~END~~ + +ALTER ROLE db_accessadmin ADD MEMBER babel_5136_db_accessadmin_user +GO +-- Cannot add login as member of db_accessadmin +ALTER ROLE db_accessadmin ADD MEMBER babel_5136_l1 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: role "babel_5136_babel_5136_l1" does not exist)~~ + +-- Cannot add fixed roles ass member of db_accessadmin +ALTER ROLE db_accessadmin ADD MEMBER syadmin +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: role "babel_5136_syadmin" does not exist)~~ + +ALTER ROLE db_accessadmin ADD MEMBER dbo +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot use the special principal 'dbo')~~ + +ALTER ROLE db_accessadmin ADD MEMBER db_owner +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot use the special principal 'db_owner')~~ + +ALTER ROLE db_accessadmin ADD MEMBER db_accessadmin +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot use the special principal 'db_accessadmin')~~ + +ALTER ROLE db_accessadmin DROP MEMBER syadmin +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: role "babel_5136_syadmin" does not exist)~~ + +ALTER ROLE db_accessadmin DROP MEMBER dbo +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot use the special principal 'dbo')~~ + +ALTER ROLE db_accessadmin DROP MEMBER db_owner +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot use the special principal 'db_owner')~~ + +ALTER ROLE db_accessadmin DROP MEMBER db_accessadmin +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot use the special principal 'db_accessadmin')~~ + + +-- MEMBERS OF db_accessadmin WILL ALWAYS HAVE CONNECT PRIVILEGES +REVOKE CONNECT FROM babel_5136_db_accessadmin_user +GO + +-- IS_ROLEMEMBER & IS_MEMBER should show db_accessadmin as member of dbo but not of db_owner +SELECT IS_ROLEMEMBER('db_accessadmin') +GO +~~START~~ +int +1 +~~END~~ + +SELECT IS_ROLEMEMBER('db_accessadmin', 'dbo') +GO +~~START~~ +int +1 +~~END~~ + +SELECT IS_ROLEMEMBER('db_accessadmin', 'db_owner') +GO +~~START~~ +int +0 +~~END~~ + +SELECT IS_ROLEMEMBER('babel_5136_r1', 'dbo') +GO +~~START~~ +int +0 +~~END~~ + +SELECT IS_MEMBER('db_accessadmin') +GO +~~START~~ +int +1 +~~END~~ + +SELECT IS_MEMBER('dbo') +GO +~~START~~ +int +1 +~~END~~ + +SELECT IS_MEMBER('db_owner') +GO +~~START~~ +int +1 +~~END~~ + +SELECT IS_MEMBER('babel_5136_r1') +GO +~~START~~ +int +0 +~~END~~ + +-- terminate-tsql-conn + +-- tsql user=babel_5136_l1 password=12345678 database=babel_5136 +-- Only db_owner members should be able to do this +ALTER ROLE db_accessadmin ADD MEMBER babel_5136_db_accessadmin_user +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot alter the role 'db_accessadmin', because it does not exist or you do not have permission.)~~ + +-- terminate-tsql-conn user=babel_5136_l1 password=12345678 database=babel_5136 + + +-- tsql user=babel_5136_db_accessadmin_l1 password=12345678 +-- Check all allowed operations +USE babel_5136 +GO + +SELECT current_user +GO +~~START~~ +varchar +babel_5136_db_accessadmin_user +~~END~~ + + +-- should be a member of db_accessadmin in babel_5136 database +SELECT IS_ROLEMEMBER('db_accessadmin') +GO +~~START~~ +int +1 +~~END~~ + + +-- CREATE DROP A NEW USER +CREATE USER babel_5136_u2 FOR LOGIN babel_5136_l2 +GO +DROP USER babel_5136_u2 +GO + +-- DROP & RECREATE EXISTING USER +DROP USER babel_5136_u1 +GO +CREATE USER babel_5136_u1 FOR LOGIN babel_5136_l1 +GO +-- terminate-tsql-conn user=babel_5136_db_accessadmin_l1 password=12345678 + +-- tsql database=babel_5136 +SELECT current_user +GO +~~START~~ +varchar +dbo +~~END~~ + +ALTER ROLE babel_5136_r1 ADD MEMBER babel_5136_u1 +GO +-- terminate-tsql-conn database=babel_5136 + +-- tsql user=babel_5136_db_accessadmin_l1 password=12345678 database=babel_5136 +-- ALTER EXISTING USER and THEN DROP IT +ALTER USER babel_5136_u1 WITH DEFAULT_SCHEMA = dbo +GO +ALTER USER babel_5136_u1 WITH NAME = babel_5136_u1_new_name +GO +-- NOT SUPPORTED CURRENTLY IN BABELFISH +ALTER USER babel_5136_u1_new_name WITH PASSWORD = 'shouldfail' +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '' at line 3 and character position 0)~~ + +DROP USER babel_5136_u1_new_name +GO +CREATE USER babel_5136_u1_new_name FOR LOGIN babel_5136_l1 +GO +-- ALTER NEW USER and THEN DROP IT +CREATE USER babel_5136_u2 FOR LOGIN babel_5136_l2 +GO +ALTER USER babel_5136_u2 WITH NAME = babel_5136_u1 +GO + +-- CREATE SCHEMA should be allowed db_accessadmin +CREATE SCHEMA s1 +GO +CREATE SCHEMA s2 AUTHORIZATION dbo +GO +CREATE SCHEMA s3 AUTHORIZATION babel_5136_u1 +GO + +-- Should be able to do GRANT/REVOKE on schema that it owns +GRANT SELECT, INSERT, EXECUTE ON SCHEMA::s1 TO babel_5136_u1 +GO +GRANT SELECT, INSERT, EXECUTE ON SCHEMA::s2 TO babel_5136_u1 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot find the schema "s2", because it does not exist or you do not have permission.)~~ + +GRANT SELECT, INSERT, EXECUTE ON SCHEMA::s3 TO babel_5136_u1 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny, or revoke permissions to sa, dbo, entity owner, information_schema, sys, or yourself.)~~ + +REVOKE SELECT, INSERT, EXECUTE ON SCHEMA::s1 TO babel_5136_u1 +GO +REVOKE SELECT, INSERT, EXECUTE ON SCHEMA::s2 TO babel_5136_u1 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot find the schema "s2", because it does not exist or you do not have permission.)~~ + +REVOKE SELECT, INSERT, EXECUTE ON SCHEMA::s3 TO babel_5136_u1 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny, or revoke permissions to sa, dbo, entity owner, information_schema, sys, or yourself.)~~ + +-- Should only be able to drop schema that it owns +DROP SCHEMA s1 +GO +DROP SCHEMA s2 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: must be owner of schema babel_5136_s2)~~ + +DROP SCHEMA s3 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: must be owner of schema babel_5136_s3)~~ + + +-- Should be restricted +DROP USER dbo +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot drop the user 'dbo'.)~~ + +DROP ROLE db_owner +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot drop the role 'db_owner'.)~~ + +DROP ROLE db_accessadmin +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot drop the role 'db_accessadmin'.)~~ + +DROP USER guest +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: User 'guest' cannot be dropped, it can only be disabled. The user is already disabled in the current database.)~~ + + +-- db_accessadmin can not add/drop members to any other role +ALTER ROLE db_accessadmin ADD MEMBER babel_5136_u1 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot alter the role 'db_accessadmin', because it does not exist or you do not have permission.)~~ + +ALTER ROLE db_owner ADD MEMBER babel_5136_u1 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Adding members to db_owner is not currently supported in Babelfish)~~ + +ALTER ROLE babel_5136_r1 ADD MEMBER babel_5136_u1 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Current login babel_5136_db_accessadmin_l1 does not have permission to alter role babel_5136_babel_5136_r1)~~ + +ALTER ROLE babel_5136_r1 DROP MEMBER babel_5136_u1 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Current login babel_5136_db_accessadmin_l1 does not have permission to alter role babel_5136_babel_5136_r1)~~ + +ALTER ROLE db_accessadmin DROP MEMBER 'babel_5136_db_accessadmin_user' +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near ''babel_5136_db_accessadmin_user'' at line 1 and character position 38)~~ + +sp_addrolemember 'db_accessadmin', 'babel_5136_u1' +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot alter the role 'db_accessadmin', because it does not exist or you do not have permission.)~~ + +sp_droprolemember 'db_accessadmin', 'babel_5136_db_accessadmin_user' +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot alter the role 'db_accessadmin', because it does not exist or you do not have permission.)~~ + +sp_addrolemember 'babel_5136_r1', 'babel_5136_u1' +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Current login babel_5136_db_accessadmin_l1 does not have permission to alter role babel_5136_babel_5136_r1)~~ + +sp_droprolemember 'babel_5136_r1', 'babel_5136_u1' +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Current login babel_5136_db_accessadmin_l1 does not have permission to alter role babel_5136_babel_5136_r1)~~ + +sp_droprolemember 'db_accessadmin', 'babel_5136_db_accessadmin_user' +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot alter the role 'db_accessadmin', because it does not exist or you do not have permission.)~~ + + +-- should not be able to alter users login mapping or rename members of db_owner +ALTER USER babel_5136_u1_new_name WITH LOGIN = babel_5136_l3 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Current user does not have privileges to change login)~~ + +ALTER USER dbo WITH LOGIN = babel_5136_l3 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot alter the user dbo)~~ + +ALTER USER dbo WITH NAME = dbo_should_not_be_renamed +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot alter the user dbo)~~ + +ALTER USER dbo WITH DEFAULT_SCHEMA = dbo +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot alter the user dbo)~~ + +GRANT CONNECT TO babel_5136_u1_new_name +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Grantor does not have GRANT permission.)~~ + +GRANT CONNECT TO dbo +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Grantor does not have GRANT permission.)~~ + +REVOKE CONNECT FROM babel_5136_u1_new_name +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Grantor does not have GRANT permission.)~~ + +REVOKE CONNECT FROM dbo +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Grantor does not have GRANT permission.)~~ + + +-- DMLs or EXECUTING FUNCTIONS SHOULD ALSO BE NOT ALLOWED +EXEC babel_5136_p1 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for procedure babel_5136_p1)~~ + +SELECT * FROM babel_5136_t1 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table babel_5136_t1)~~ + +SELECT babel_5136_f1() +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for function babel_5136_f1)~~ + + +-- NO OTHER DDLs SHOULD BE ALLOWED +CREATE TABLE babel_5136_t2 (id INT) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for schema babel_5136_dbo)~~ + +CREATE PROCEDURE babel_5136_p2 AS SELECT 1 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for schema babel_5136_dbo)~~ + +CREATE FUNCTION babel_5136_f2() RETURNS INT AS BEGIN RETURN 1 END +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for schema babel_5136_dbo)~~ + + +-- In master database the current login should not have db_accessadmin privilege +-- Since db_accessadmin is database level role +USE master +GO + +SELECT current_user +GO +~~START~~ +varchar +babel_5136_user_master +~~END~~ + + +-- should not be a member of db_accessadmin in master database +SELECT IS_ROLEMEMBER('db_accessadmin') +GO +~~START~~ +int +0 +~~END~~ + + +-- Should not be able to do any activity in master database +CREATE USER babel_5136_u2 FOR LOGIN babel_5136_l2 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: User does not have permission to perform this action.)~~ + +DROP USER babel_5136_u1 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot drop the user 'babel_5136_u1', because it does not exist or you do not have permission.)~~ + +DROP ROLE babel_5136_r1 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot drop the role 'babel_5136_r1', because it does not exist or you do not have permission.)~~ + +CREATE ROLE babel_5136_r2 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: User does not have permission to perform this action.)~~ + +CREATE TABLE babel_5136_t1 (id INT) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for schema master_dbo)~~ + +CREATE PROCEDURE babel_5136_p2 AS SELECT 1 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for schema master_dbo)~~ + +CREATE FUNCTION babel_5136_f2() RETURNS INT AS BEGIN RETURN 1 END +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for schema master_dbo)~~ + +CREATE SCHEMA babel_5136_s1 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for database jdbc_testdb)~~ + +CREATE SCHEMA babel_5136_s1 AUTHORIZATION babel_5136_u1 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for database jdbc_testdb)~~ + +-- Should not be able to drop a database +DROP DATABASE babel_5136 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: must be owner of database babel_5136)~~ + +-- terminate-tsql-conn user=babel_5136_db_accessadmin_l1 password=12345678 database=babel_5136 + +-- tsql +DROP DATABASE babel_5136 +GO +-- terminate-tsql-conn + +-- tsql user=babel_5136_db_accessadmin_l1 password=12345678 +-- Should not be able to create a database +CREATE DATABASE babel_5136 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied to create database)~~ + +-- terminate-tsql-conn user=babel_5136_db_accessadmin_l1 password=12345678 diff --git a/test/JDBC/expected/restrict_drop_user_role.out b/test/JDBC/expected/restrict_drop_user_role.out index d4bf6f9b88..7ecf190c2e 100644 --- a/test/JDBC/expected/restrict_drop_user_role.out +++ b/test/JDBC/expected/restrict_drop_user_role.out @@ -213,19 +213,35 @@ go -- both of the following statements should be executed successfully since user/role exists drop role if exists no_priv_user3; go -~~ERROR (Code: 33557097)~~ -~~ERROR (Message: Cannot drop the role 'no_priv_user3', because it does not exist or you do not have permission.)~~ +select count(*) from sys.database_principals where name like '%no_priv_%3'; +go +~~START~~ +int +2 +~~END~~ drop user if exists no_priv_user3; go +select count(*) from sys.database_principals where name like '%no_priv_%3'; +go +~~START~~ +int +1 +~~END~~ + + drop user if exists no_priv_role3; go -~~ERROR (Code: 33557097)~~ -~~ERROR (Message: Cannot drop the user 'no_priv_role3', because it does not exist or you do not have permission.)~~ +select count(*) from sys.database_principals where name like '%no_priv_%3'; +go +~~START~~ +int +1 +~~END~~ drop role if exists no_priv_role3; @@ -263,17 +279,9 @@ go -- bbf_role_admin won't have privilege to drop non-babelfish roles drop user if exists pguser1; go -~~ERROR (Code: 33557097)~~ - -~~ERROR (Message: Cannot drop the user 'pguser1', because it does not exist or you do not have permission.)~~ - drop role if exists pguser1; go -~~ERROR (Code: 33557097)~~ - -~~ERROR (Message: Cannot drop the role 'pguser1', because it does not exist or you do not have permission.)~~ - -- psql drop role master_pguser1; @@ -361,10 +369,6 @@ go drop user if exists user1; go -~~ERROR (Code: 33557097)~~ - -~~ERROR (Message: Cannot drop the user 'user1', because it does not exist or you do not have permission.)~~ - use master go diff --git a/test/JDBC/expected/single_db/BABEL-2403.out b/test/JDBC/expected/single_db/BABEL-2403.out index f23cb91110..c000969d27 100644 --- a/test/JDBC/expected/single_db/BABEL-2403.out +++ b/test/JDBC/expected/single_db/BABEL-2403.out @@ -89,6 +89,12 @@ 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#!#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"} @@ -168,6 +174,12 @@ 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#!#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 87a7f7ea48..78fe8fe42c 100644 --- a/test/JDBC/expected/single_db/BABEL-LOGIN-USER-EXT.out +++ b/test/JDBC/expected/single_db/BABEL-LOGIN-USER-EXT.out @@ -130,14 +130,18 @@ master_r1#!#r1#!#r1#!#master#!#sch2 ALTER USER r1 WITH NAME = new_r1; go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Current user does not have privileges to change user name)~~ + SELECT rolname, orig_username, login_name, database_name, default_schema_name FROM sys.babelfish_authid_user_ext -WHERE orig_username = 'new_r1'; +WHERE orig_username = 'new_r1' or orig_username = 'r1'; go ~~START~~ varchar#!#nvarchar#!#varchar#!#nvarchar#!#nvarchar -master_new_r1#!#new_r1#!#r1#!#master#!#sch2 +master_r1#!#r1#!#r1#!#master#!#sch2 ~~END~~ @@ -217,7 +221,7 @@ r2 -- tsql -DROP USER new_r1; +DROP USER r1; go -- psql @@ -691,14 +695,18 @@ GO ~~START~~ varchar#!#nvarchar#!#varchar#!#nvarchar#!#nvarchar db1_guest#!#guest#!##!#db1#!#guest +db_accessadmin#!#db_accessadmin#!##!#db1#!# db_owner#!#db_owner#!##!#db1#!# dbo#!#dbo#!##!#db1#!#dbo +master_db_accessadmin#!#db_accessadmin#!##!#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_owner#!#db_owner#!##!#msdb#!# msdb_dbo#!#dbo#!##!#msdb#!#dbo msdb_guest#!#guest#!##!#msdb#!#guest +tempdb_db_accessadmin#!#db_accessadmin#!##!#tempdb#!# tempdb_db_owner#!#db_owner#!##!#tempdb#!# tempdb_dbo#!#dbo#!##!#tempdb#!#dbo tempdb_guest#!#guest#!##!#tempdb#!#guest @@ -863,12 +871,15 @@ ORDER BY rolname; GO ~~START~~ varchar#!#nvarchar#!#varchar#!#nvarchar#!#nvarchar +master_db_accessadmin#!#db_accessadmin#!##!#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_owner#!#db_owner#!##!#msdb#!# msdb_dbo#!#dbo#!##!#msdb#!#dbo msdb_guest#!#guest#!##!#msdb#!#guest +tempdb_db_accessadmin#!#db_accessadmin#!##!#tempdb#!# tempdb_db_owner#!#db_owner#!##!#tempdb#!# tempdb_dbo#!#dbo#!##!#tempdb#!#dbo tempdb_guest#!#guest#!##!#tempdb#!#guest @@ -919,14 +930,18 @@ GO ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar#!#nvarchar db1_guest#!##!#guest#!#db1#!#guest +db_accessadmin#!##!#db_accessadmin#!#db1#!# db_owner#!##!#db_owner#!#db1#!# dbo#!##!#dbo#!#db1#!#dbo +master_db_accessadmin#!##!#db_accessadmin#!#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_owner#!##!#db_owner#!#msdb#!# msdb_dbo#!##!#dbo#!#msdb#!#dbo msdb_guest#!##!#guest#!#msdb#!#guest +tempdb_db_accessadmin#!##!#db_accessadmin#!#tempdb#!# tempdb_db_owner#!##!#db_owner#!#tempdb#!# tempdb_dbo#!##!#dbo#!#tempdb#!#dbo tempdb_guest#!##!#guest#!#tempdb#!#guest @@ -941,6 +956,7 @@ GO varchar#!#varchar guest#!#guest dbo#!#dbo +db_accessadmin#!# db_owner#!# INFORMATION_SCHEMA#!# public#!# @@ -972,6 +988,7 @@ GO varchar#!#varchar guest#!#guest dbo#!#dbo +db_accessadmin#!# db_owner#!# INFORMATION_SCHEMA#!# public#!# @@ -1110,12 +1127,15 @@ ORDER BY rolname; GO ~~START~~ varchar#!#nvarchar#!#varchar#!#nvarchar#!#nvarchar +master_db_accessadmin#!#db_accessadmin#!##!#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_owner#!#db_owner#!##!#msdb#!# msdb_dbo#!#dbo#!##!#msdb#!#dbo msdb_guest#!#guest#!##!#msdb#!#guest +tempdb_db_accessadmin#!#db_accessadmin#!##!#tempdb#!# tempdb_db_owner#!#db_owner#!##!#tempdb#!# tempdb_dbo#!#dbo#!##!#tempdb#!#dbo tempdb_guest#!#guest#!##!#tempdb#!#guest @@ -1135,12 +1155,15 @@ ORDER BY rolname; GO ~~START~~ varchar#!#nvarchar#!#varchar#!#nvarchar#!#nvarchar +master_db_accessadmin#!#db_accessadmin#!##!#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_owner#!#db_owner#!##!#msdb#!# msdb_dbo#!#dbo#!##!#msdb#!#dbo msdb_guest#!#guest#!##!#msdb#!#guest +tempdb_db_accessadmin#!#db_accessadmin#!##!#tempdb#!# tempdb_db_owner#!#db_owner#!##!#tempdb#!# tempdb_dbo#!#dbo#!##!#tempdb#!#dbo tempdb_guest#!#guest#!##!#tempdb#!#guest @@ -1430,6 +1453,7 @@ GO varchar babel_4935_no_sysadmin1 babel_4935_no_sysadmin2 +db_accessadmin db_owner dbo guest @@ -1447,6 +1471,7 @@ GO varchar babel_4935_no_sysadmin1 babel_4935_no_sysadmin2 +db_accessadmin db_owner dbo guest @@ -1463,6 +1488,7 @@ GO ~~START~~ varchar babel_4935_no_sysadmin1 +db_accessadmin db_owner dbo guest @@ -1478,6 +1504,7 @@ SELECT name FROM sys.database_principals ORDER BY name GO ~~START~~ varchar +db_accessadmin 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 d22202a7e1..2917e1f1fc 100644 --- a/test/JDBC/expected/single_db/BABEL-USER.out +++ b/test/JDBC/expected/single_db/BABEL-USER.out @@ -50,14 +50,18 @@ GO ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar#!#nvarchar db1_guest#!##!#guest#!#db1#!#guest +db_accessadmin#!##!#db_accessadmin#!#db1#!# db_owner#!##!#db_owner#!#db1#!# dbo#!##!#dbo#!#db1#!#dbo +master_db_accessadmin#!##!#db_accessadmin#!#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_owner#!##!#db_owner#!#msdb#!# msdb_dbo#!##!#dbo#!#msdb#!#dbo msdb_guest#!##!#guest#!#msdb#!#guest +tempdb_db_accessadmin#!##!#db_accessadmin#!#tempdb#!# tempdb_db_owner#!##!#db_owner#!#tempdb#!# tempdb_dbo#!##!#dbo#!#tempdb#!#dbo tempdb_guest#!##!#guest#!#tempdb#!#guest @@ -72,6 +76,7 @@ GO varchar#!#varchar guest#!#guest dbo#!#dbo +db_accessadmin#!# 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 fbb07e25cf..227059870a 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 @@ -32,6 +32,7 @@ rename_db_schema1#!#rename_db_schema1 ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar +db_accessadmin#!##!#db_accessadmin#!#rename_db_database1 db_owner#!##!#db_owner#!#rename_db_database1 dbo#!##!#dbo#!#rename_db_database1 rename_db_database1_guest#!##!#guest#!#rename_db_database1 @@ -80,6 +81,7 @@ rename_db_schema1#!#rename_db_schema1 ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar +db_accessadmin#!##!#db_accessadmin#!#rename_db_database2 db_owner#!##!#db_owner#!#rename_db_database2 dbo#!##!#dbo#!#rename_db_database2 rename_db_database2_guest#!##!#guest#!#rename_db_database2 @@ -128,6 +130,7 @@ rename_db_schema1#!#rename_db_schema1 ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar +db_accessadmin#!##!#db_accessadmin#!#rename_db_database1 db_owner#!##!#db_owner#!#rename_db_database1 dbo#!##!#dbo#!#rename_db_database1 rename_db_database1_guest#!##!#guest#!#rename_db_database1 @@ -176,6 +179,7 @@ rename_db_schema1#!#rename_db_schema1 ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar +db_accessadmin#!##!#db_accessadmin#!#rename_db_database2 db_owner#!##!#db_owner#!#rename_db_database2 dbo#!##!#dbo#!#rename_db_database2 rename_db_database2_guest#!##!#guest#!#rename_db_database2 @@ -236,6 +240,7 @@ rename_db_schema1#!#rename_db_schema1 ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar +db_accessadmin#!##!#db_accessadmin#!#rename_db_database1 db_owner#!##!#db_owner#!#rename_db_database1 dbo#!##!#dbo#!#rename_db_database1 rename_db_database1_guest#!##!#guest#!#rename_db_database1 @@ -284,6 +289,7 @@ rename_db_schema1#!#rename_db_schema1 ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar +db_accessadmin#!##!#db_accessadmin#!#rename_db_database2 db_owner#!##!#db_owner#!#rename_db_database2 dbo#!##!#dbo#!#rename_db_database2 rename_db_database2_guest#!##!#guest#!#rename_db_database2 @@ -332,6 +338,7 @@ rename_db_schema1#!#rename_db_schema1 ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar +db_accessadmin#!##!#db_accessadmin#!#rename_db_database1 db_owner#!##!#db_owner#!#rename_db_database1 dbo#!##!#dbo#!#rename_db_database1 rename_db_database1_guest#!##!#guest#!#rename_db_database1 @@ -380,6 +387,7 @@ rename_db_schema1#!#rename_db_schema1 ~~START~~ varchar#!#varchar#!#nvarchar#!#nvarchar +db_accessadmin#!##!#db_accessadmin#!#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/db_accessadmin-vu-verify.out b/test/JDBC/expected/single_db/db_accessadmin-vu-verify.out new file mode 100644 index 0000000000..d39b87cfc1 --- /dev/null +++ b/test/JDBC/expected/single_db/db_accessadmin-vu-verify.out @@ -0,0 +1,578 @@ + + +-- tsql +-- CREATE LOGIN AND ADD IT TO db_accessadmin + -- Only members of db_owner should be able to add/drop members to db_accessadmin +-- db_accessadmin should be able to do the following + -- CREATE USER in database + -- DROP ANY USER in database (except dbo) + -- ALTER default_schema for any user in database + -- RENAME user execpt for members of db_owner + -- CREATE SCHEMA for self or other users in database +-- bbf dump does not dump password so reset the password +ALTER LOGIN babel_5136_l1 WITH PASSWORD = '12345678' +GO +-- CREATE A USER WITH db_accessadmin privilege in DATABASE babel_5136 +USE master +GO +CREATE LOGIN babel_5136_db_accessadmin_l1 WITH PASSWORD = '12345678' +GO +CREATE USER babel_5136_user_master FOR LOGIN babel_5136_db_accessadmin_l1 +GO +USE babel_5136 +GO +CREATE USER babel_5136_db_accessadmin_user FOR LOGIN babel_5136_db_accessadmin_l1 +GO +-- ADD DROP MEMBERS TO db_accessadmin USING dbo +sp_addrolemember 'db_accessadmin', 'babel_5136_db_accessadmin_user' +GO +SELECT IS_ROLEMEMBER('db_accessadmin', 'babel_5136_db_accessadmin_user') +GO +~~START~~ +int +1 +~~END~~ + +sp_droprolemember 'db_accessadmin', 'babel_5136_db_accessadmin_user' +GO +SELECT IS_ROLEMEMBER('db_accessadmin', 'babel_5136_db_accessadmin_user') +GO +~~START~~ +int +0 +~~END~~ + +ALTER ROLE db_accessadmin ADD MEMBER babel_5136_db_accessadmin_user +GO +-- Cannot add login as member of db_accessadmin +ALTER ROLE db_accessadmin ADD MEMBER babel_5136_l1 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: role "babel_5136_babel_5136_l1" does not exist)~~ + +-- Cannot add fixed roles ass member of db_accessadmin +ALTER ROLE db_accessadmin ADD MEMBER syadmin +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: role "babel_5136_syadmin" does not exist)~~ + +ALTER ROLE db_accessadmin ADD MEMBER dbo +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot use the special principal 'dbo')~~ + +ALTER ROLE db_accessadmin ADD MEMBER db_owner +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot use the special principal 'db_owner')~~ + +ALTER ROLE db_accessadmin ADD MEMBER db_accessadmin +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot use the special principal 'db_accessadmin')~~ + +ALTER ROLE db_accessadmin DROP MEMBER syadmin +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: role "babel_5136_syadmin" does not exist)~~ + +ALTER ROLE db_accessadmin DROP MEMBER dbo +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot use the special principal 'dbo')~~ + +ALTER ROLE db_accessadmin DROP MEMBER db_owner +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot use the special principal 'db_owner')~~ + +ALTER ROLE db_accessadmin DROP MEMBER db_accessadmin +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot use the special principal 'db_accessadmin')~~ + + +-- MEMBERS OF db_accessadmin WILL ALWAYS HAVE CONNECT PRIVILEGES +REVOKE CONNECT FROM babel_5136_db_accessadmin_user +GO + +-- IS_ROLEMEMBER & IS_MEMBER should show db_accessadmin as member of dbo but not of db_owner +SELECT IS_ROLEMEMBER('db_accessadmin') +GO +~~START~~ +int +1 +~~END~~ + +SELECT IS_ROLEMEMBER('db_accessadmin', 'dbo') +GO +~~START~~ +int +1 +~~END~~ + +SELECT IS_ROLEMEMBER('db_accessadmin', 'db_owner') +GO +~~START~~ +int +0 +~~END~~ + +SELECT IS_ROLEMEMBER('babel_5136_r1', 'dbo') +GO +~~START~~ +int +0 +~~END~~ + +SELECT IS_MEMBER('db_accessadmin') +GO +~~START~~ +int +1 +~~END~~ + +SELECT IS_MEMBER('dbo') +GO +~~START~~ +int +1 +~~END~~ + +SELECT IS_MEMBER('db_owner') +GO +~~START~~ +int +1 +~~END~~ + +SELECT IS_MEMBER('babel_5136_r1') +GO +~~START~~ +int +0 +~~END~~ + +-- terminate-tsql-conn + +-- tsql user=babel_5136_l1 password=12345678 database=babel_5136 +-- Only db_owner members should be able to do this +ALTER ROLE db_accessadmin ADD MEMBER babel_5136_db_accessadmin_user +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot alter the role 'db_accessadmin', because it does not exist or you do not have permission.)~~ + +-- terminate-tsql-conn user=babel_5136_l1 password=12345678 database=babel_5136 + + +-- tsql user=babel_5136_db_accessadmin_l1 password=12345678 +-- Check all allowed operations +USE babel_5136 +GO + +SELECT current_user +GO +~~START~~ +varchar +babel_5136_db_accessadmin_user +~~END~~ + + +-- should be a member of db_accessadmin in babel_5136 database +SELECT IS_ROLEMEMBER('db_accessadmin') +GO +~~START~~ +int +1 +~~END~~ + + +-- CREATE DROP A NEW USER +CREATE USER babel_5136_u2 FOR LOGIN babel_5136_l2 +GO +DROP USER babel_5136_u2 +GO + +-- DROP & RECREATE EXISTING USER +DROP USER babel_5136_u1 +GO +CREATE USER babel_5136_u1 FOR LOGIN babel_5136_l1 +GO +-- terminate-tsql-conn user=babel_5136_db_accessadmin_l1 password=12345678 + +-- tsql database=babel_5136 +SELECT current_user +GO +~~START~~ +varchar +dbo +~~END~~ + +ALTER ROLE babel_5136_r1 ADD MEMBER babel_5136_u1 +GO +-- terminate-tsql-conn database=babel_5136 + +-- tsql user=babel_5136_db_accessadmin_l1 password=12345678 database=babel_5136 +-- ALTER EXISTING USER and THEN DROP IT +ALTER USER babel_5136_u1 WITH DEFAULT_SCHEMA = dbo +GO +ALTER USER babel_5136_u1 WITH NAME = babel_5136_u1_new_name +GO +-- NOT SUPPORTED CURRENTLY IN BABELFISH +ALTER USER babel_5136_u1_new_name WITH PASSWORD = 'shouldfail' +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '' at line 3 and character position 0)~~ + +DROP USER babel_5136_u1_new_name +GO +CREATE USER babel_5136_u1_new_name FOR LOGIN babel_5136_l1 +GO +-- ALTER NEW USER and THEN DROP IT +CREATE USER babel_5136_u2 FOR LOGIN babel_5136_l2 +GO +ALTER USER babel_5136_u2 WITH NAME = babel_5136_u1 +GO + +-- CREATE SCHEMA should be allowed db_accessadmin +CREATE SCHEMA s1 +GO +CREATE SCHEMA s2 AUTHORIZATION dbo +GO +CREATE SCHEMA s3 AUTHORIZATION babel_5136_u1 +GO + +-- Should be able to do GRANT/REVOKE on schema that it owns +GRANT SELECT, INSERT, EXECUTE ON SCHEMA::s1 TO babel_5136_u1 +GO +GRANT SELECT, INSERT, EXECUTE ON SCHEMA::s2 TO babel_5136_u1 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot find the schema "s2", because it does not exist or you do not have permission.)~~ + +GRANT SELECT, INSERT, EXECUTE ON SCHEMA::s3 TO babel_5136_u1 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny, or revoke permissions to sa, dbo, entity owner, information_schema, sys, or yourself.)~~ + +REVOKE SELECT, INSERT, EXECUTE ON SCHEMA::s1 TO babel_5136_u1 +GO +REVOKE SELECT, INSERT, EXECUTE ON SCHEMA::s2 TO babel_5136_u1 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot find the schema "s2", because it does not exist or you do not have permission.)~~ + +REVOKE SELECT, INSERT, EXECUTE ON SCHEMA::s3 TO babel_5136_u1 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny, or revoke permissions to sa, dbo, entity owner, information_schema, sys, or yourself.)~~ + +-- Should only be able to drop schema that it owns +DROP SCHEMA s1 +GO +DROP SCHEMA s2 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: must be owner of schema s2)~~ + +DROP SCHEMA s3 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: must be owner of schema s3)~~ + + +-- Should be restricted +DROP USER dbo +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot drop the user 'dbo'.)~~ + +DROP ROLE db_owner +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot drop the role 'db_owner'.)~~ + +DROP ROLE db_accessadmin +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot drop the role 'db_accessadmin'.)~~ + +DROP USER guest +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: User 'guest' cannot be dropped, it can only be disabled. The user is already disabled in the current database.)~~ + + +-- db_accessadmin can not add/drop members to any other role +ALTER ROLE db_accessadmin ADD MEMBER babel_5136_u1 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot alter the role 'db_accessadmin', because it does not exist or you do not have permission.)~~ + +ALTER ROLE db_owner ADD MEMBER babel_5136_u1 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Adding members to db_owner is not currently supported in Babelfish)~~ + +ALTER ROLE babel_5136_r1 ADD MEMBER babel_5136_u1 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Current login babel_5136_db_accessadmin_l1 does not have permission to alter role babel_5136_babel_5136_r1)~~ + +ALTER ROLE babel_5136_r1 DROP MEMBER babel_5136_u1 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Current login babel_5136_db_accessadmin_l1 does not have permission to alter role babel_5136_babel_5136_r1)~~ + +ALTER ROLE db_accessadmin DROP MEMBER 'babel_5136_db_accessadmin_user' +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near ''babel_5136_db_accessadmin_user'' at line 1 and character position 38)~~ + +sp_addrolemember 'db_accessadmin', 'babel_5136_u1' +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot alter the role 'db_accessadmin', because it does not exist or you do not have permission.)~~ + +sp_droprolemember 'db_accessadmin', 'babel_5136_db_accessadmin_user' +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot alter the role 'db_accessadmin', because it does not exist or you do not have permission.)~~ + +sp_addrolemember 'babel_5136_r1', 'babel_5136_u1' +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Current login babel_5136_db_accessadmin_l1 does not have permission to alter role babel_5136_babel_5136_r1)~~ + +sp_droprolemember 'babel_5136_r1', 'babel_5136_u1' +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Current login babel_5136_db_accessadmin_l1 does not have permission to alter role babel_5136_babel_5136_r1)~~ + +sp_droprolemember 'db_accessadmin', 'babel_5136_db_accessadmin_user' +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot alter the role 'db_accessadmin', because it does not exist or you do not have permission.)~~ + + +-- should not be able to alter users login mapping or rename members of db_owner +ALTER USER babel_5136_u1_new_name WITH LOGIN = babel_5136_l3 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Current user does not have privileges to change login)~~ + +ALTER USER dbo WITH LOGIN = babel_5136_l3 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot alter the user dbo)~~ + +ALTER USER dbo WITH NAME = dbo_should_not_be_renamed +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot alter the user dbo)~~ + +ALTER USER dbo WITH DEFAULT_SCHEMA = dbo +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot alter the user dbo)~~ + +GRANT CONNECT TO babel_5136_u1_new_name +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Grantor does not have GRANT permission.)~~ + +GRANT CONNECT TO dbo +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Grantor does not have GRANT permission.)~~ + +REVOKE CONNECT FROM babel_5136_u1_new_name +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Grantor does not have GRANT permission.)~~ + +REVOKE CONNECT FROM dbo +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Grantor does not have GRANT permission.)~~ + + +-- DMLs or EXECUTING FUNCTIONS SHOULD ALSO BE NOT ALLOWED +EXEC babel_5136_p1 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for procedure babel_5136_p1)~~ + +SELECT * FROM babel_5136_t1 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table babel_5136_t1)~~ + +SELECT babel_5136_f1() +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for function babel_5136_f1)~~ + + +-- NO OTHER DDLs SHOULD BE ALLOWED +CREATE TABLE babel_5136_t2 (id INT) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for schema dbo)~~ + +CREATE PROCEDURE babel_5136_p2 AS SELECT 1 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for schema dbo)~~ + +CREATE FUNCTION babel_5136_f2() RETURNS INT AS BEGIN RETURN 1 END +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for schema dbo)~~ + + +-- In master database the current login should not have db_accessadmin privilege +-- Since db_accessadmin is database level role +USE master +GO + +SELECT current_user +GO +~~START~~ +varchar +babel_5136_user_master +~~END~~ + + +-- should not be a member of db_accessadmin in master database +SELECT IS_ROLEMEMBER('db_accessadmin') +GO +~~START~~ +int +0 +~~END~~ + + +-- Should not be able to do any activity in master database +CREATE USER babel_5136_u2 FOR LOGIN babel_5136_l2 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: User does not have permission to perform this action.)~~ + +DROP USER babel_5136_u1 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot drop the user 'babel_5136_u1', because it does not exist or you do not have permission.)~~ + +DROP ROLE babel_5136_r1 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot drop the role 'babel_5136_r1', because it does not exist or you do not have permission.)~~ + +CREATE ROLE babel_5136_r2 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: User does not have permission to perform this action.)~~ + +CREATE TABLE babel_5136_t1 (id INT) +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for schema master_dbo)~~ + +CREATE PROCEDURE babel_5136_p2 AS SELECT 1 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for schema master_dbo)~~ + +CREATE FUNCTION babel_5136_f2() RETURNS INT AS BEGIN RETURN 1 END +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for schema master_dbo)~~ + +CREATE SCHEMA babel_5136_s1 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for database jdbc_testdb)~~ + +CREATE SCHEMA babel_5136_s1 AUTHORIZATION babel_5136_u1 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for database jdbc_testdb)~~ + +-- Should not be able to drop a database +DROP DATABASE babel_5136 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: must be owner of database babel_5136)~~ + +-- terminate-tsql-conn user=babel_5136_db_accessadmin_l1 password=12345678 database=babel_5136 + +-- tsql +DROP DATABASE babel_5136 +GO +-- terminate-tsql-conn + +-- tsql user=babel_5136_db_accessadmin_l1 password=12345678 +-- Should not be able to create a database +CREATE DATABASE babel_5136 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied to create database)~~ + +-- terminate-tsql-conn user=babel_5136_db_accessadmin_l1 password=12345678 diff --git a/test/JDBC/expected/single_db/restrict_drop_user_role.out b/test/JDBC/expected/single_db/restrict_drop_user_role.out index 8be4aeff75..dbea73d2fc 100644 --- a/test/JDBC/expected/single_db/restrict_drop_user_role.out +++ b/test/JDBC/expected/single_db/restrict_drop_user_role.out @@ -213,19 +213,35 @@ go -- both of the following statements should be executed successfully since user/role exists drop role if exists no_priv_user3; go -~~ERROR (Code: 33557097)~~ -~~ERROR (Message: Cannot drop the role 'no_priv_user3', because it does not exist or you do not have permission.)~~ +select count(*) from sys.database_principals where name like '%no_priv_%3'; +go +~~START~~ +int +2 +~~END~~ drop user if exists no_priv_user3; go +select count(*) from sys.database_principals where name like '%no_priv_%3'; +go +~~START~~ +int +1 +~~END~~ + + drop user if exists no_priv_role3; go -~~ERROR (Code: 33557097)~~ -~~ERROR (Message: Cannot drop the user 'no_priv_role3', because it does not exist or you do not have permission.)~~ +select count(*) from sys.database_principals where name like '%no_priv_%3'; +go +~~START~~ +int +1 +~~END~~ drop role if exists no_priv_role3; @@ -263,17 +279,9 @@ go -- bbf_role_admin won't have privilege to drop non-babelfish roles drop user if exists pguser1; go -~~ERROR (Code: 33557097)~~ - -~~ERROR (Message: Cannot drop the user 'pguser1', because it does not exist or you do not have permission.)~~ - drop role if exists pguser1; go -~~ERROR (Code: 33557097)~~ - -~~ERROR (Message: Cannot drop the role 'pguser1', because it does not exist or you do not have permission.)~~ - -- psql drop role master_pguser1; diff --git a/test/JDBC/input/BABEL-LOGIN-USER-EXT.mix b/test/JDBC/input/BABEL-LOGIN-USER-EXT.mix index 2ccb1e5e89..a8e0ddb912 100644 --- a/test/JDBC/input/BABEL-LOGIN-USER-EXT.mix +++ b/test/JDBC/input/BABEL-LOGIN-USER-EXT.mix @@ -81,7 +81,7 @@ go SELECT rolname, orig_username, login_name, database_name, default_schema_name FROM sys.babelfish_authid_user_ext -WHERE orig_username = 'new_r1'; +WHERE orig_username = 'new_r1' or orig_username = 'r1'; go ALTER USER r2 WITH DEFAULT_SCHEMA = NULL; @@ -117,7 +117,7 @@ SELECT user_name(user_id()); go -- tsql -DROP USER new_r1; +DROP USER r1; go -- psql diff --git a/test/JDBC/input/db_accessadmin-vu-cleanup.mix b/test/JDBC/input/db_accessadmin-vu-cleanup.mix new file mode 100644 index 0000000000..234a2afc13 --- /dev/null +++ b/test/JDBC/input/db_accessadmin-vu-cleanup.mix @@ -0,0 +1,25 @@ +-- tsql +USE master +GO +DROP DATABASE IF EXISTS babel_5136 +GO +DROP LOGIN babel_5136_l1 +GO +DROP LOGIN babel_5136_l2 +GO +DROP LOGIN babel_5136_l3 +GO +DROP LOGIN babel_5136_db_accessadmin_l1 +GO +DROP USER babel_5136_u1 +GO +DROP USER babel_5136_user_master +GO +DROP ROLE babel_5136_r1 +GO +DROP TABLE babel_5136_t1 +GO +DROP PROC babel_5136_p1 +GO +DROP FUNCTION f1 +GO diff --git a/test/JDBC/input/db_accessadmin-vu-prepare.mix b/test/JDBC/input/db_accessadmin-vu-prepare.mix new file mode 100644 index 0000000000..a1e3bfe041 --- /dev/null +++ b/test/JDBC/input/db_accessadmin-vu-prepare.mix @@ -0,0 +1,35 @@ +-- tsql +USE master +GO +CREATE LOGIN babel_5136_l1 WITH PASSWORD = '12345678' +GO +CREATE LOGIN babel_5136_l2 WITH PASSWORD = '12345678' +GO +CREATE LOGIN babel_5136_l3 WITH PASSWORD = '12345678' +GO +CREATE USER babel_5136_u1 FOR LOGIN babel_5136_l1 +GO +CREATE ROLE babel_5136_r1 +GO +CREATE TABLE babel_5136_t1 (id INT) +GO +CREATE PROC babel_5136_p1 AS SELECT 1 +GO +CREATE FUNCTION f1() RETURNS INT AS BEGIN return 1; END +GO + +CREATE DATABASE babel_5136 +GO +USE babel_5136 +GO +CREATE USER babel_5136_u1 FOR LOGIN babel_5136_l1 +GO +CREATE ROLE babel_5136_r1 +GO +CREATE TABLE babel_5136_t1 (id INT) +GO +CREATE PROC babel_5136_p1 AS SELECT 1 +GO +CREATE FUNCTION babel_5136_f1() RETURNS INT AS BEGIN return 1; END +GO + diff --git a/test/JDBC/input/db_accessadmin-vu-verify.mix b/test/JDBC/input/db_accessadmin-vu-verify.mix new file mode 100644 index 0000000000..7764a3e594 --- /dev/null +++ b/test/JDBC/input/db_accessadmin-vu-verify.mix @@ -0,0 +1,280 @@ +-- single_db_mode_expected +-- CREATE LOGIN AND ADD IT TO db_accessadmin + -- Only members of db_owner should be able to add/drop members to db_accessadmin + +-- db_accessadmin should be able to do the following + -- CREATE USER in database + -- DROP ANY USER in database (except dbo) + -- ALTER default_schema for any user in database + -- RENAME user execpt for members of db_owner + -- CREATE SCHEMA for self or other users in database + +-- tsql +-- bbf dump does not dump password so reset the password +ALTER LOGIN babel_5136_l1 WITH PASSWORD = '12345678' +GO +-- CREATE A USER WITH db_accessadmin privilege in DATABASE babel_5136 +USE master +GO +CREATE LOGIN babel_5136_db_accessadmin_l1 WITH PASSWORD = '12345678' +GO +CREATE USER babel_5136_user_master FOR LOGIN babel_5136_db_accessadmin_l1 +GO +USE babel_5136 +GO +CREATE USER babel_5136_db_accessadmin_user FOR LOGIN babel_5136_db_accessadmin_l1 +GO +-- ADD DROP MEMBERS TO db_accessadmin USING dbo +sp_addrolemember 'db_accessadmin', 'babel_5136_db_accessadmin_user' +GO +SELECT IS_ROLEMEMBER('db_accessadmin', 'babel_5136_db_accessadmin_user') +GO +sp_droprolemember 'db_accessadmin', 'babel_5136_db_accessadmin_user' +GO +SELECT IS_ROLEMEMBER('db_accessadmin', 'babel_5136_db_accessadmin_user') +GO +ALTER ROLE db_accessadmin ADD MEMBER babel_5136_db_accessadmin_user +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 +ALTER ROLE db_accessadmin ADD MEMBER syadmin +GO +ALTER ROLE db_accessadmin ADD MEMBER dbo +GO +ALTER ROLE db_accessadmin ADD MEMBER db_owner +GO +ALTER ROLE db_accessadmin ADD MEMBER db_accessadmin +GO +ALTER ROLE db_accessadmin DROP MEMBER syadmin +GO +ALTER ROLE db_accessadmin DROP MEMBER dbo +GO +ALTER ROLE db_accessadmin DROP MEMBER db_owner +GO +ALTER ROLE db_accessadmin DROP MEMBER db_accessadmin +GO + +-- MEMBERS OF db_accessadmin WILL ALWAYS HAVE CONNECT PRIVILEGES +REVOKE CONNECT FROM babel_5136_db_accessadmin_user +GO + +-- IS_ROLEMEMBER & IS_MEMBER should show db_accessadmin as member of dbo but not of db_owner +SELECT IS_ROLEMEMBER('db_accessadmin') +GO +SELECT IS_ROLEMEMBER('db_accessadmin', 'dbo') +GO +SELECT IS_ROLEMEMBER('db_accessadmin', 'db_owner') +GO +SELECT IS_ROLEMEMBER('babel_5136_r1', 'dbo') +GO +SELECT IS_MEMBER('db_accessadmin') +GO +SELECT IS_MEMBER('dbo') +GO +SELECT IS_MEMBER('db_owner') +GO +SELECT IS_MEMBER('babel_5136_r1') +GO +-- terminate-tsql-conn + +-- Only db_owner members should be able to do this +-- tsql user=babel_5136_l1 password=12345678 database=babel_5136 +ALTER ROLE db_accessadmin ADD MEMBER babel_5136_db_accessadmin_user +GO +-- terminate-tsql-conn user=babel_5136_l1 password=12345678 database=babel_5136 + + +-- Check all allowed operations +-- tsql user=babel_5136_db_accessadmin_l1 password=12345678 +USE babel_5136 +GO + +SELECT current_user +GO + +-- should be a member of db_accessadmin in babel_5136 database +SELECT IS_ROLEMEMBER('db_accessadmin') +GO + +-- CREATE DROP A NEW USER +CREATE USER babel_5136_u2 FOR LOGIN babel_5136_l2 +GO +DROP USER babel_5136_u2 +GO + +-- DROP & RECREATE EXISTING USER +DROP USER babel_5136_u1 +GO +CREATE USER babel_5136_u1 FOR LOGIN babel_5136_l1 +GO +-- terminate-tsql-conn user=babel_5136_db_accessadmin_l1 password=12345678 + +-- tsql database=babel_5136 +SELECT current_user +GO +ALTER ROLE babel_5136_r1 ADD MEMBER babel_5136_u1 +GO +-- terminate-tsql-conn database=babel_5136 + +-- tsql user=babel_5136_db_accessadmin_l1 password=12345678 database=babel_5136 +-- ALTER EXISTING USER and THEN DROP IT +ALTER USER babel_5136_u1 WITH DEFAULT_SCHEMA = dbo +GO +ALTER USER babel_5136_u1 WITH NAME = babel_5136_u1_new_name +GO +-- NOT SUPPORTED CURRENTLY IN BABELFISH +ALTER USER babel_5136_u1_new_name WITH PASSWORD = 'shouldfail' +GO +DROP USER babel_5136_u1_new_name +GO +CREATE USER babel_5136_u1_new_name FOR LOGIN babel_5136_l1 +GO +-- ALTER NEW USER and THEN DROP IT +CREATE USER babel_5136_u2 FOR LOGIN babel_5136_l2 +GO +ALTER USER babel_5136_u2 WITH NAME = babel_5136_u1 +GO + +-- CREATE SCHEMA should be allowed db_accessadmin +CREATE SCHEMA s1 +GO +CREATE SCHEMA s2 AUTHORIZATION dbo +GO +CREATE SCHEMA s3 AUTHORIZATION babel_5136_u1 +GO + +-- Should be able to do GRANT/REVOKE on schema that it owns +GRANT SELECT, INSERT, EXECUTE ON SCHEMA::s1 TO babel_5136_u1 +GO +GRANT SELECT, INSERT, EXECUTE ON SCHEMA::s2 TO babel_5136_u1 +GO +GRANT SELECT, INSERT, EXECUTE ON SCHEMA::s3 TO babel_5136_u1 +GO +REVOKE SELECT, INSERT, EXECUTE ON SCHEMA::s1 TO babel_5136_u1 +GO +REVOKE SELECT, INSERT, EXECUTE ON SCHEMA::s2 TO babel_5136_u1 +GO +REVOKE SELECT, INSERT, EXECUTE ON SCHEMA::s3 TO babel_5136_u1 +GO +-- Should only be able to drop schema that it owns +DROP SCHEMA s1 +GO +DROP SCHEMA s2 +GO +DROP SCHEMA s3 +GO + +-- Should be restricted +DROP USER dbo +GO +DROP ROLE db_owner +GO +DROP ROLE db_accessadmin +GO +DROP USER guest +GO + +-- db_accessadmin can not add/drop members to any other role +ALTER ROLE db_accessadmin ADD MEMBER babel_5136_u1 +GO +ALTER ROLE db_owner ADD MEMBER babel_5136_u1 +GO +ALTER ROLE babel_5136_r1 ADD MEMBER babel_5136_u1 +GO +ALTER ROLE babel_5136_r1 DROP MEMBER babel_5136_u1 +GO +ALTER ROLE db_accessadmin DROP MEMBER 'babel_5136_db_accessadmin_user' +GO +sp_addrolemember 'db_accessadmin', 'babel_5136_u1' +GO +sp_droprolemember 'db_accessadmin', 'babel_5136_db_accessadmin_user' +GO +sp_addrolemember 'babel_5136_r1', 'babel_5136_u1' +GO +sp_droprolemember 'babel_5136_r1', 'babel_5136_u1' +GO +sp_droprolemember 'db_accessadmin', 'babel_5136_db_accessadmin_user' +GO + +-- should not be able to alter users login mapping or rename members of db_owner +ALTER USER babel_5136_u1_new_name WITH LOGIN = babel_5136_l3 +GO +ALTER USER dbo WITH LOGIN = babel_5136_l3 +GO +ALTER USER dbo WITH NAME = dbo_should_not_be_renamed +GO +ALTER USER dbo WITH DEFAULT_SCHEMA = dbo +GO +GRANT CONNECT TO babel_5136_u1_new_name +GO +GRANT CONNECT TO dbo +GO +REVOKE CONNECT FROM babel_5136_u1_new_name +GO +REVOKE CONNECT FROM dbo +GO + +-- DMLs or EXECUTING FUNCTIONS SHOULD ALSO BE NOT ALLOWED +EXEC babel_5136_p1 +GO +SELECT * FROM babel_5136_t1 +GO +SELECT babel_5136_f1() +GO + +-- NO OTHER DDLs SHOULD BE ALLOWED +CREATE TABLE babel_5136_t2 (id INT) +GO +CREATE PROCEDURE babel_5136_p2 AS SELECT 1 +GO +CREATE FUNCTION babel_5136_f2() RETURNS INT AS BEGIN RETURN 1 END +GO + +-- In master database the current login should not have db_accessadmin privilege +-- Since db_accessadmin is database level role +USE master +GO + +SELECT current_user +GO + +-- should not be a member of db_accessadmin in master database +SELECT IS_ROLEMEMBER('db_accessadmin') +GO + +-- Should not be able to do any activity in master database +CREATE USER babel_5136_u2 FOR LOGIN babel_5136_l2 +GO +DROP USER babel_5136_u1 +GO +DROP ROLE babel_5136_r1 +GO +CREATE ROLE babel_5136_r2 +GO +CREATE TABLE babel_5136_t1 (id INT) +GO +CREATE PROCEDURE babel_5136_p2 AS SELECT 1 +GO +CREATE FUNCTION babel_5136_f2() RETURNS INT AS BEGIN RETURN 1 END +GO +CREATE SCHEMA babel_5136_s1 +GO +CREATE SCHEMA babel_5136_s1 AUTHORIZATION babel_5136_u1 +GO +-- Should not be able to drop a database +DROP DATABASE babel_5136 +GO +-- terminate-tsql-conn user=babel_5136_db_accessadmin_l1 password=12345678 database=babel_5136 + +-- tsql +DROP DATABASE babel_5136 +GO +-- terminate-tsql-conn + +-- tsql user=babel_5136_db_accessadmin_l1 password=12345678 +-- Should not be able to create a database +CREATE DATABASE babel_5136 +GO +-- terminate-tsql-conn user=babel_5136_db_accessadmin_l1 password=12345678 diff --git a/test/JDBC/input/ownership/BABEL-LOGIN-vu-verify.mix b/test/JDBC/input/ownership/BABEL-LOGIN-vu-verify.mix index 914a52ca5f..63b1532bbe 100644 --- a/test/JDBC/input/ownership/BABEL-LOGIN-vu-verify.mix +++ b/test/JDBC/input/ownership/BABEL-LOGIN-vu-verify.mix @@ -162,7 +162,7 @@ go DROP USER babel_login_vu_prepare_err_user; go -DROP USER babel_login_vu_prepare_r1_new +DROP USER babel_login_vu_prepare_r1 go DROP USER babel_login_vu_prepare_r2 diff --git a/test/JDBC/input/restrict_drop_user_role.mix b/test/JDBC/input/restrict_drop_user_role.mix index 8bba2e96e7..2c1015c562 100644 --- a/test/JDBC/input/restrict_drop_user_role.mix +++ b/test/JDBC/input/restrict_drop_user_role.mix @@ -147,12 +147,21 @@ go drop role if exists no_priv_user3; go +select count(*) from sys.database_principals where name like '%no_priv_%3'; +go + drop user if exists no_priv_user3; go +select count(*) from sys.database_principals where name like '%no_priv_%3'; +go + drop user if exists no_priv_role3; go +select count(*) from sys.database_principals where name like '%no_priv_%3'; +go + drop role if exists no_priv_role3; go diff --git a/test/JDBC/upgrade/14_10/schedule b/test/JDBC/upgrade/14_10/schedule index f472eac75f..fefb36f30f 100644 --- a/test/JDBC/upgrade/14_10/schedule +++ b/test/JDBC/upgrade/14_10/schedule @@ -465,6 +465,7 @@ space binary-datatype-operators BABEL-5059_before_16_5 cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 BABEL-5186 diff --git a/test/JDBC/upgrade/14_11/schedule b/test/JDBC/upgrade/14_11/schedule index 3b7968c4bb..cfe9e59cef 100644 --- a/test/JDBC/upgrade/14_11/schedule +++ b/test/JDBC/upgrade/14_11/schedule @@ -463,6 +463,7 @@ space binary-datatype-operators BABEL-5059_before_16_5 cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 BABEL-5186 diff --git a/test/JDBC/upgrade/14_12/schedule b/test/JDBC/upgrade/14_12/schedule index 9a130151c0..96a1d896ec 100644 --- a/test/JDBC/upgrade/14_12/schedule +++ b/test/JDBC/upgrade/14_12/schedule @@ -464,6 +464,7 @@ space binary-datatype-operators BABEL-5059_before_16_5 cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 BABEL-5186 diff --git a/test/JDBC/upgrade/14_13/schedule b/test/JDBC/upgrade/14_13/schedule index 7bbcf6b961..3ef30c4707 100644 --- a/test/JDBC/upgrade/14_13/schedule +++ b/test/JDBC/upgrade/14_13/schedule @@ -464,6 +464,7 @@ space binary-datatype-operators BABEL-5059_before_16_5 cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 BABEL-5186 diff --git a/test/JDBC/upgrade/14_16/schedule b/test/JDBC/upgrade/14_16/schedule index 8df0ea03d8..2aa0cf4f37 100644 --- a/test/JDBC/upgrade/14_16/schedule +++ b/test/JDBC/upgrade/14_16/schedule @@ -463,6 +463,7 @@ space binary-datatype-operators BABEL-5059_before_16_5 cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 BABEL-5186 diff --git a/test/JDBC/upgrade/14_3/schedule b/test/JDBC/upgrade/14_3/schedule index 1724176cda..b88c792662 100644 --- a/test/JDBC/upgrade/14_3/schedule +++ b/test/JDBC/upgrade/14_3/schedule @@ -384,6 +384,7 @@ space binary-datatype-operators BABEL-5059-before-14_7-or-15_2 cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 BABEL-5186 diff --git a/test/JDBC/upgrade/14_5/schedule b/test/JDBC/upgrade/14_5/schedule index d9962c2661..f6d6ecbc73 100644 --- a/test/JDBC/upgrade/14_5/schedule +++ b/test/JDBC/upgrade/14_5/schedule @@ -396,6 +396,7 @@ space binary-datatype-operators BABEL-5059-before-14_7-or-15_2 cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 BABEL-5186 diff --git a/test/JDBC/upgrade/14_6/schedule b/test/JDBC/upgrade/14_6/schedule index 801893a8b1..afc6523e03 100644 --- a/test/JDBC/upgrade/14_6/schedule +++ b/test/JDBC/upgrade/14_6/schedule @@ -433,6 +433,7 @@ space binary-datatype-operators BABEL-5059-before-14_7-or-15_2 cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 BABEL-5186 diff --git a/test/JDBC/upgrade/14_7/schedule b/test/JDBC/upgrade/14_7/schedule index 47e5466b23..7bd9947de9 100644 --- a/test/JDBC/upgrade/14_7/schedule +++ b/test/JDBC/upgrade/14_7/schedule @@ -455,6 +455,7 @@ space binary-datatype-operators BABEL-5059_before_16_5 cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 BABEL-5186 diff --git a/test/JDBC/upgrade/14_8/schedule b/test/JDBC/upgrade/14_8/schedule index 95606e2149..8b630ef669 100644 --- a/test/JDBC/upgrade/14_8/schedule +++ b/test/JDBC/upgrade/14_8/schedule @@ -457,6 +457,7 @@ space binary-datatype-operators BABEL-5059_before_16_5 cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 BABEL-5186 diff --git a/test/JDBC/upgrade/14_9/schedule b/test/JDBC/upgrade/14_9/schedule index 273c3b6e99..32ed2ab583 100644 --- a/test/JDBC/upgrade/14_9/schedule +++ b/test/JDBC/upgrade/14_9/schedule @@ -460,6 +460,7 @@ space binary-datatype-operators BABEL-5059_before_16_5 cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 BABEL-5186 diff --git a/test/JDBC/upgrade/15_1/schedule b/test/JDBC/upgrade/15_1/schedule index 60cb64abce..1f1fe0c54e 100644 --- a/test/JDBC/upgrade/15_1/schedule +++ b/test/JDBC/upgrade/15_1/schedule @@ -432,6 +432,7 @@ space binary-datatype-operators BABEL-5059-before-14_7-or-15_2 cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 BABEL-5186 diff --git a/test/JDBC/upgrade/15_11/schedule b/test/JDBC/upgrade/15_11/schedule index 6cdfba9ba9..eed03ae843 100644 --- a/test/JDBC/upgrade/15_11/schedule +++ b/test/JDBC/upgrade/15_11/schedule @@ -547,6 +547,7 @@ securityadmin_role cast-varchar-to-time xml_exist-before-16_5 BABEL-5119_before_16_5 +db_accessadmin BABEL-CASE_EXPR BABEL-5186 BABEL-2736 diff --git a/test/JDBC/upgrade/15_2/schedule b/test/JDBC/upgrade/15_2/schedule index 6704aa9806..7eac926aa5 100644 --- a/test/JDBC/upgrade/15_2/schedule +++ b/test/JDBC/upgrade/15_2/schedule @@ -468,6 +468,7 @@ space binary-datatype-operators BABEL-5059_before_16_5 cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 BABEL-5186 diff --git a/test/JDBC/upgrade/15_3/schedule b/test/JDBC/upgrade/15_3/schedule index 88a37bfa46..bc93405530 100644 --- a/test/JDBC/upgrade/15_3/schedule +++ b/test/JDBC/upgrade/15_3/schedule @@ -487,6 +487,7 @@ space binary-datatype-operators BABEL-5059_before_16_5 cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 BABEL-5186 diff --git a/test/JDBC/upgrade/15_4/schedule b/test/JDBC/upgrade/15_4/schedule index 76502d18f7..28cb5c58fb 100644 --- a/test/JDBC/upgrade/15_4/schedule +++ b/test/JDBC/upgrade/15_4/schedule @@ -500,6 +500,7 @@ space binary-datatype-operators BABEL-5059_before_16_5 cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 BABEL-5186 diff --git a/test/JDBC/upgrade/15_5/schedule b/test/JDBC/upgrade/15_5/schedule index 89d76f668f..b94438a58a 100644 --- a/test/JDBC/upgrade/15_5/schedule +++ b/test/JDBC/upgrade/15_5/schedule @@ -531,6 +531,7 @@ space binary-datatype-operators BABEL-5059_before_16_5 cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 BABEL-5186 diff --git a/test/JDBC/upgrade/15_6/schedule b/test/JDBC/upgrade/15_6/schedule index c3c08cf4d3..32e4b79942 100644 --- a/test/JDBC/upgrade/15_6/schedule +++ b/test/JDBC/upgrade/15_6/schedule @@ -547,6 +547,7 @@ space binary-datatype-operators BABEL-5059_before_16_5 cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 BABEL-5186 diff --git a/test/JDBC/upgrade/15_7/schedule b/test/JDBC/upgrade/15_7/schedule index 3730c60a8b..8e35d71bce 100644 --- a/test/JDBC/upgrade/15_7/schedule +++ b/test/JDBC/upgrade/15_7/schedule @@ -554,6 +554,7 @@ space binary-datatype-operators BABEL-5059_before_16_5 cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 GRANT_SCHEMA-before-15_9-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 diff --git a/test/JDBC/upgrade/15_8/schedule b/test/JDBC/upgrade/15_8/schedule index dd59445351..814960cddd 100644 --- a/test/JDBC/upgrade/15_8/schedule +++ b/test/JDBC/upgrade/15_8/schedule @@ -545,6 +545,7 @@ alter-procedure-15_8-or-16_4 binary-datatype-operators BABEL-5059_before_16_5 cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 GRANT_SCHEMA-before-15_9-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 diff --git a/test/JDBC/upgrade/16_1/schedule b/test/JDBC/upgrade/16_1/schedule index a3db4e0269..652a65cdce 100644 --- a/test/JDBC/upgrade/16_1/schedule +++ b/test/JDBC/upgrade/16_1/schedule @@ -540,6 +540,7 @@ replace-before-15_8-or-16_4 binary-datatype-operators BABEL-5059_before_16_5 cast-varchar-to-time +db_accessadmin securityadmin_role xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 diff --git a/test/JDBC/upgrade/16_2/schedule b/test/JDBC/upgrade/16_2/schedule index aeb19393e6..1d65cce8d0 100644 --- a/test/JDBC/upgrade/16_2/schedule +++ b/test/JDBC/upgrade/16_2/schedule @@ -555,6 +555,7 @@ replace-before-15_8-or-16_4 binary-datatype-operators BABEL-5059_before_16_5 cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 declare_atatglobalvars_upgrade-before-16_5 diff --git a/test/JDBC/upgrade/16_3/schedule b/test/JDBC/upgrade/16_3/schedule index cfd5d2a9db..d2d2557666 100644 --- a/test/JDBC/upgrade/16_3/schedule +++ b/test/JDBC/upgrade/16_3/schedule @@ -558,6 +558,7 @@ replace-before-15_8-or-16_4 binary-datatype-operators BABEL-5059_before_16_5 cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 GRANT_SCHEMA-before-15_9-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 diff --git a/test/JDBC/upgrade/16_4/schedule b/test/JDBC/upgrade/16_4/schedule index 887a53a941..f40ed89941 100644 --- a/test/JDBC/upgrade/16_4/schedule +++ b/test/JDBC/upgrade/16_4/schedule @@ -571,6 +571,7 @@ BABEL-5059_before_16_5 cast-varchar-to-time xml_exist-before-16_5 BABEL-5119_before_16_5 +db_accessadmin GRANT_SCHEMA-before-15_9-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 charindex_replace_patindex diff --git a/test/JDBC/upgrade/16_6/schedule b/test/JDBC/upgrade/16_6/schedule index d7ca4ae625..a23930a572 100644 --- a/test/JDBC/upgrade/16_6/schedule +++ b/test/JDBC/upgrade/16_6/schedule @@ -583,3 +583,5 @@ BABEL-5186 BABEL-2736 smalldatetime_date_cmp securityadmin_role +db_accessadmin + diff --git a/test/JDBC/upgrade/latest/schedule b/test/JDBC/upgrade/latest/schedule index 9d656e7811..bd2739900c 100644 --- a/test/JDBC/upgrade/latest/schedule +++ b/test/JDBC/upgrade/latest/schedule @@ -582,6 +582,7 @@ xml_exist test_db_collation BABEL-5119 BABEL-5129 +db_accessadmin BABEL-CASE_EXPR charindex_replace_patindex BABEL-5186 diff --git a/test/JDBC/upgrade/singledb/schedule b/test/JDBC/upgrade/singledb/schedule index 55ab635341..b4bb4485a2 100644 --- a/test/JDBC/upgrade/singledb/schedule +++ b/test/JDBC/upgrade/singledb/schedule @@ -1 +1 @@ -TestInt \ No newline at end of file +TestInt diff --git a/test/python/expected/sql_validation_framework/expected_drop.out b/test/python/expected/sql_validation_framework/expected_drop.out index c967fb8166..be489ac211 100644 --- a/test/python/expected/sql_validation_framework/expected_drop.out +++ b/test/python/expected/sql_validation_framework/expected_drop.out @@ -54,6 +54,7 @@ Unexpected drop found for operator sys./ in file babelfishpg_common--1.1.0--1.2. Unexpected drop found for operator sys./ in file babelfishpg_common--1.1.0--1.2.0.sql Unexpected drop found for operator sys./ in file babelfishpg_common--1.1.0--1.2.0.sql Unexpected drop found for procedure babelfish_drop_deprecated_opclass in file babelfishpg_common--1.0.0--1.1.0.sql +Unexpected drop found for procedure sys.create_db_roles_during_upgrade in file babelfishpg_tsql--4.3.0--4.4.0.sql Unexpected drop found for procedure sys.babel_create_guest_schemas in file babelfishpg_tsql--2.3.0--2.4.0.sql Unexpected drop found for procedure sys.babel_create_guest_schemas in file babelfishpg_tsql--3.0.0--3.1.0.sql Unexpected drop found for procedure sys.babelfish_alter_default_privilege_on_schema in file babelfishpg_tsql--4.3.0--4.4.0.sql