From 1c2e0d91dc8a10ee4504043433aa924c9a713e9c Mon Sep 17 00:00:00 2001 From: Tanzeel Khan Date: Wed, 25 Sep 2024 09:02:38 +0000 Subject: [PATCH 01/44] support db_accessadmin Signed-off-by: Tanzeel Khan --- .../babelfishpg_tsql/sql/babelfishpg_tsql.sql | 13 +- contrib/babelfishpg_tsql/sql/ownership.sql | 6 +- .../babelfishpg_tsql--4.3.0--4.4.0.sql | 214 ++++++++++++++++++ contrib/babelfishpg_tsql/src/catalog.c | 91 +++++--- contrib/babelfishpg_tsql/src/catalog.h | 5 +- contrib/babelfishpg_tsql/src/dbcmds.c | 175 +++++++++++++- contrib/babelfishpg_tsql/src/multidb.c | 26 ++- contrib/babelfishpg_tsql/src/multidb.h | 1 + contrib/babelfishpg_tsql/src/pl_exec-2.c | 2 +- contrib/babelfishpg_tsql/src/pl_handler.c | 183 ++++++++++----- contrib/babelfishpg_tsql/src/procedures.c | 10 +- contrib/babelfishpg_tsql/src/rolecmds.c | 8 +- test/JDBC/expected/BABEL-2403.out | 12 + 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-vu-verify.out | 3 + .../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 + .../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/restrict_drop_user_role.out | 32 ++- test/JDBC/input/BABEL-LOGIN-USER-EXT.mix | 4 +- .../input/ownership/BABEL-LOGIN-vu-verify.mix | 2 +- test/JDBC/input/restrict_drop_user_role.mix | 9 + .../expected_drop.out | 1 + 31 files changed, 801 insertions(+), 157 deletions(-) diff --git a/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql b/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql index 8a0721961b..e16f957311 100644 --- a/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql +++ b/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql @@ -2118,7 +2118,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 @@ -2150,7 +2150,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 @@ -2188,7 +2188,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 @@ -2348,13 +2348,16 @@ CREATE OR REPLACE PROCEDURE sys.sp_helpdbfixedrole("@rolename" sys.SYSNAME = NUL $$ BEGIN -- Returns a list of the fixed database roles. - -- Only fixed role present in babelfish is db_owner. IF LOWER(RTRIM(@rolename)) IS NULL OR LOWER(RTRIM(@rolename)) = 'db_owner' BEGIN SELECT CAST('db_owner' AS sys.SYSNAME) AS DbFixedRole, CAST('DB Owners' AS sys.nvarchar(70)) AS Description; END + ELSE IF LOWER(RTRIM(@rolename)) IS NULL OR LOWER(RTRIM(@rolename)) = 'db_accessadmin' + BEGIN + SELECT CAST('db_accessadmin' AS sys.SYSNAME) AS DbFixedRole, CAST('DB Access Administrators' AS sys.nvarchar(70)) AS Description; + END ELSE IF LOWER(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 dbbda19e43..f746ea93c3 100644 --- a/contrib/babelfishpg_tsql/sql/ownership.sql +++ b/contrib/babelfishpg_tsql/sql/ownership.sql @@ -259,7 +259,9 @@ CREATE OR REPLACE PROCEDURE initialize_babelfish ( sa_name VARCHAR(128) ) LANGUAGE plpgsql AS $$ DECLARE - reserved_roles varchar[] := ARRAY['sysadmin', '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', '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; @@ -450,7 +452,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/upgrades/babelfishpg_tsql--4.3.0--4.4.0.sql b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.3.0--4.4.0.sql index b9831532a8..946df73dd0 100644 --- a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.3.0--4.4.0.sql +++ b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.3.0--4.4.0.sql @@ -38,6 +38,15 @@ LANGUAGE plpgsql; * final behaviour. */ + +CREATE OR REPLACE PROCEDURE sys.babel_create_database_roles() +LANGUAGE C +AS 'babelfishpg_tsql', 'create_database_roles_for_all_dbs'; + +CALL sys.babel_create_database_roles(); + +DROP PROCEDURE sys.babel_create_database_roles(); + -- Assigning dbo role to the db_owner login DO $$ DECLARE @@ -1906,6 +1915,211 @@ CALL sys.babelfish_drop_deprecated_object('function', 'sys', 'sp_statistics_inte CALL sys.babelfish_drop_deprecated_object('function', 'sys', 'sp_pkeys_internal_deprecated_in_4_4_0'); +-- 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_helpdbfixedrole("@rolename" sys.SYSNAME = NULL) AS +$$ +BEGIN + -- Returns a list of the fixed database roles. + -- Only fixed role present in babelfish is db_owner. + IF LOWER(RTRIM(@rolename)) IS NULL OR LOWER(RTRIM(@rolename)) = 'db_owner' + BEGIN + SELECT CAST('db_owner' AS sys.SYSNAME) AS DbFixedRole, CAST('DB Owners' AS sys.nvarchar(70)) AS Description; + END + ELSE IF LOWER(RTRIM(@rolename)) IS NULL OR LOWER(RTRIM(@rolename)) = 'db_accessadmin' + BEGIN + SELECT CAST('db_accessadmin' AS sys.SYSNAME) AS DbFixedRole, CAST('DB Access Administrators' AS sys.nvarchar(70)) AS Description; + END + ELSE IF LOWER(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 + SELECT CAST(NULL AS sys.SYSNAME) AS DbFixedRole, CAST(NULL AS sys.nvarchar(70)) AS Description + WHERE 1=0; + END + ELSE + RAISERROR('''%s'' is not a known fixed role.', 16, 1, @rolename); +END +$$ +LANGUAGE 'pltsql'; +GRANT EXECUTE ON PROCEDURE sys.sp_helpdbfixedrole 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 != '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 + 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 != '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 + -- 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 != '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 + -- 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; + -- Drops the temporary procedure used by the upgrade script. -- Please have this be one of the last statements executed in this upgrade script. DROP PROCEDURE sys.babelfish_drop_deprecated_object(varchar, varchar, varchar); diff --git a/contrib/babelfishpg_tsql/src/catalog.c b/contrib/babelfishpg_tsql/src/catalog.c index 1c2db7f299..30c2c28d8f 100644 --- a/contrib/babelfishpg_tsql/src/catalog.c +++ b/contrib/babelfishpg_tsql/src/catalog.c @@ -849,24 +849,17 @@ get_authid_login_ext_idx_oid(void) *****************************************/ bool -is_user(Oid role_oid) +is_user(Oid role_oid, bool current_db_only) { - bool is_user = true; + bool is_user = false; + 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)); + rolname = GetUserNameFromId(role_oid, false); + tuple = SearchSysCache1(AUTHIDUSEREXTROLENAME, CStringGetDatum(rolname)); - if (!HeapTupleIsValid(tuple)) - is_user = false; - else + if (HeapTupleIsValid(tuple)) { BpChar type = ((Form_authid_user_ext) GETSTRUCT(tuple))->type; char *type_str = bpchar_to_cstring(&type); @@ -875,45 +868,72 @@ is_user(Oid role_oid) * 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; + if (strcmp(type_str, "R") != 0) + { + if (current_db_only) + { + Datum db_name = SysCacheGetAttr(AUTHIDUSEREXTROLENAME, tuple, + Anum_bbf_authid_user_ext_database_name, &isnull); + char *db_name_cstring = TextDatumGetCString(db_name); + char *current_db_name = get_cur_db_name(); + + is_user = (strcmp(db_name_cstring, current_db_name) == 0); + + pfree(db_name_cstring); + pfree(current_db_name); + } + else + is_user = true; + } + ReleaseSysCache(tuple); + pfree(type_str); } - ReleaseSysCache(authtuple); + pfree(rolname); return is_user; } bool -is_role(Oid role_oid) +is_role(Oid role_oid, bool current_db_only) { - bool is_role = true; + bool is_role = false; + 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)); + rolname = GetUserNameFromId(role_oid, false); + tuple = SearchSysCache1(AUTHIDUSEREXTROLENAME, CStringGetDatum(rolname)); - if (!HeapTupleIsValid(tuple)) - is_role = false; - else + if (HeapTupleIsValid(tuple)) { BpChar type = ((Form_authid_user_ext) GETSTRUCT(tuple))->type; char *type_str = bpchar_to_cstring(&type); - if (strcmp(type_str, "R") != 0) - is_role = false; + if (strcmp(type_str, "R") == 0) + { + if (current_db_only) + { + Datum db_name = SysCacheGetAttr(AUTHIDUSEREXTROLENAME, tuple, + Anum_bbf_authid_user_ext_database_name, &isnull); + char *db_name_cstring = TextDatumGetCString(db_name); + char *current_db_name = get_cur_db_name(); + + is_role = (strcmp(db_name_cstring, current_db_name) == 0); + + pfree(db_name_cstring); + pfree(current_db_name); + } + else + is_role = true; + } + ReleaseSysCache(tuple); + pfree(type_str); } - ReleaseSysCache(authtuple); + pfree(rolname); return is_role; } @@ -4935,7 +4955,8 @@ rename_tsql_db(char *old_db_name, char *new_db_name) if (SINGLE_DB == get_migration_mode() && ((strlen(role) == 3 && strncmp(role, "dbo", 3) == 0) || - (strlen(role) == 8 && strncmp(role, "db_owner", 8) == 0))) + (strlen(role) == 8 && strncmp(role, "db_owner", 8) == 0) || + (strlen(role) == 14 && strncmp(role, DB_ACCESSADMIN, 14) == 0))) continue; old_role_name = get_physical_user_name(old_db_name, role, true); diff --git a/contrib/babelfishpg_tsql/src/catalog.h b/contrib/babelfishpg_tsql/src/catalog.h index 2125582eec..347b93baa9 100644 --- a/contrib/babelfishpg_tsql/src/catalog.h +++ b/contrib/babelfishpg_tsql/src/catalog.h @@ -146,8 +146,8 @@ 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); +extern bool is_user(Oid role_oid, bool current_db_only); +extern bool is_role(Oid role_oid, bool current_db_only); extern Oid get_authid_user_ext_oid(void); extern Oid get_authid_user_ext_idx_oid(void); extern char *get_authid_user_ext_physical_name(const char *db_name, const char *login_name); @@ -312,6 +312,7 @@ typedef FormData_bbf_function_ext *Form_bbf_function_ext; #define Anum_bbf_schema_perms_grantor 8 #define PUBLIC_ROLE_NAME "public" +#define DB_ACCESSADMIN "db_accessadmin" #define PERMISSIONS_FOR_ALL_OBJECTS_IN_SCHEMA "ALL" #define ALL_PERMISSIONS_ON_RELATION 47 /* last 6 bits as 101111 represents ALL privileges on a relation. */ #define ALL_PERMISSIONS_ON_FUNCTION 128 /* last 8 bits as 10000000 represents ALL privileges on a procedure/function. */ diff --git a/contrib/babelfishpg_tsql/src/dbcmds.c b/contrib/babelfishpg_tsql/src/dbcmds.c index ac02dd079e..fcca33daf3 100644 --- a/contrib/babelfishpg_tsql/src/dbcmds.c +++ b/contrib/babelfishpg_tsql/src/dbcmds.c @@ -86,12 +86,14 @@ 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; 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); @@ -106,6 +108,10 @@ gen_createdb_subcmds(const char *dbname, const char *owner) appendStringInfo(&query, "GRANT CREATE, CONNECT, TEMPORARY ON DATABASE dummy TO dummy; "); 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; "); @@ -125,9 +131,9 @@ gen_createdb_subcmds(const char *dbname, const char *owner) res = raw_parser(query.data, RAW_PARSE_DEFAULT); if (guest) - expected_stmt_num = list_length(logins) > 0 ? 10 : 9; + expected_stmt_num = list_length(logins) > 0 ? 12 : 11; else - expected_stmt_num = 7; + expected_stmt_num = 9; if (list_length(res) != expected_stmt_num) ereport(ERROR, @@ -147,10 +153,15 @@ gen_createdb_subcmds(const char *dbname, const char *owner) /* Grant dbo role to owner */ stmt = parsetree_nth_stmt(res, i++); - update_GrantRoleStmt(stmt, list_make1(make_accesspriv_node(dbo)), list_make1(make_rolespec_node(owner))); + 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++); @@ -186,14 +197,17 @@ 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 @@ -215,15 +229,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); @@ -235,13 +251,17 @@ 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; } } + /* Drop db_accessadmin*/ + appendStringInfo(&query, "REVOKE CREATE ON DATABASE dummy FROM dummy; "); + appendStringInfo(&query, "DROP ROLE dummy; "); /* Then drop db_owner and dbo in that order */ appendStringInfo(&query, "DROP OWNED BY dummy, dummy CASCADE; "); appendStringInfo(&query, "REVOKE CREATE, CONNECT, TEMPORARY ON DATABASE dummy FROM dummy; "); @@ -266,7 +286,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)); @@ -276,6 +297,11 @@ gen_dropdb_subcmds(const char *dbname, List *db_users) } } + 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_DropOwnedStmt(stmt, list_make2(pstrdup(db_owner), pstrdup(dbo))); @@ -579,6 +605,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; @@ -1206,3 +1238,134 @@ create_guest_schema_for_all_dbs(PG_FUNCTION_ARGS) PG_RETURN_INT32(0); } + + +/* +* 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_database_roles_for_all_dbs); +Datum +create_database_roles_for_all_dbs(PG_FUNCTION_ARGS) +{ + Relation sysdatabase_rel; + TableScanDesc scan; + HeapTuple tuple; + Form_sysdatabases bbf_db; + char *dbname; + int saved_nest_level = 0; + + /* We only allow this to be called from an extension's SQL script. */ + 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_database_roles_for_all_dbs()"))); + + saved_nest_level = pltsql_new_guc_nest_level(); + 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); + + sysdatabase_rel = table_open(sysdatabases_oid, RowExclusiveLock); + scan = table_beginscan_catalog(sysdatabase_rel, 0, NULL); + + while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + { + StringInfoData query; + List *parsetree_list; + Node *stmt; + const char *db_owner; + const char *db_accessadmin; + const char *old_createrole_self_grant = GetConfigOption("createrole_self_grant", false, true); + int i = 0; + int save_sec_context = 0; + Oid save_userid = InvalidOid; + + bbf_db = (Form_sysdatabases) GETSTRUCT(tuple); + dbname = text_to_cstring(&(bbf_db->name)); + db_owner = get_db_owner_name(dbname); + db_accessadmin = get_db_accessadmin_role_name(dbname); + + 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); + + 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; + /* + * We have performed all the permissions checks. + * Set current user to bbf_role_admin for create permissions. + * Set createrole_self_grant to "inherit" so that bbf_role_admin + * inherits the new role. + */ + 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); + /* Run all subcommands */ + 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); + } + + /* need to make a wrapper PlannedStmt */ + wrapper = makeNode(PlannedStmt); + wrapper->commandType = CMD_UTILITY; + wrapper->canSetTag = false; + wrapper->utilityStmt = ((RawStmt *) lfirst(parsetree_item))->stmt; + wrapper->stmt_location = 0; + + /* do this step */ + ProcessUtility(wrapper, + "(CREATE LOGICAL DATABASE )", + false, + PROCESS_UTILITY_SUBCOMMAND, + NULL, + NULL, + None_Receiver, + NULL); + + CommandCounterIncrement(); + } + } + PG_FINALLY(); + { + /* Clean up. Restore previous state. */ + SetConfigOption("createrole_self_grant", old_createrole_self_grant, PGC_USERSET, PGC_S_OVERRIDE); + SetUserIdAndSecContext(save_userid, save_sec_context); + } + PG_END_TRY(); + + pfree(query.data); + pfree(dbname); + + } + pltsql_revert_guc(saved_nest_level); + table_endscan(scan); + table_close(sysdatabase_rel, RowExclusiveLock); + + PG_RETURN_INT32(0); +} + diff --git a/contrib/babelfishpg_tsql/src/multidb.c b/contrib/babelfishpg_tsql/src/multidb.c index 033f2627f4..0e99e73dc1 100644 --- a/contrib/babelfishpg_tsql/src/multidb.c +++ b/contrib/babelfishpg_tsql/src/multidb.c @@ -264,7 +264,8 @@ rewrite_object_refs(Node *stmt) /* Forbidden the use of some special principals */ if (strcmp(principal_name, "dbo") == 0 || - strcmp(principal_name, "db_owner") == 0) + strcmp(principal_name, "db_owner") == 0 || + strcmp(principal_name, DB_ACCESSADMIN) == 0) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("Cannot use the special principal '%s'", principal_name))); @@ -389,7 +390,8 @@ rewrite_object_refs(Node *stmt) /* TODO: allow ALTER ROLE db_owner */ if (strcmp(user_name, "dbo") == 0 || strcmp(user_name, "db_owner") == 0 || - strcmp(user_name, "guest") == 0) + strcmp(user_name, "guest") == 0 || + strcmp(user_name, DB_ACCESSADMIN) == 0) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("Cannot alter the user %s", user_name))); @@ -1310,7 +1312,8 @@ get_physical_user_name(char *db_name, char *user_name, bool suppress_error) (strlen(db_name) != 4 || (strncmp(db_name, "msdb", 4) != 0))) { if ((strlen(user_name) == 3 && strncmp(user_name, "dbo", 3) == 0) || - (strlen(user_name) == 8 && strncmp(user_name, "db_owner", 8) == 0)) + (strlen(user_name) == 8 && strncmp(user_name, "db_owner", 8) == 0) || + (strlen(user_name) == 14 && strncmp(user_name, DB_ACCESSADMIN, 14) == 0)) { return new_user_name; } @@ -1414,6 +1417,21 @@ get_guest_role_name(const char *dbname) } } +const char * +get_db_accessadmin_role_name(const char *dbname) +{ + char *name = palloc0(MAX_BBF_NAMEDATALEND); + + if (get_migration_mode() == SINGLE_DB && strcmp(dbname, "master") != 0 + && strcmp(dbname, "tempdb") != 0 && strcmp(dbname, "msdb") != 0) + 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; +} + const char * get_guest_schema_name(const char *dbname) { @@ -1447,7 +1465,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 8312f9ade6..1f6d31149a 100644 --- a/contrib/babelfishpg_tsql/src/multidb.h +++ b/contrib/babelfishpg_tsql/src/multidb.h @@ -24,6 +24,7 @@ extern const char *get_dbo_schema_name(const char *dbname); extern const char *get_dbo_role_name(const char *dbname); extern const char *get_db_owner_name(const char *dbname); extern const char *get_guest_role_name(const char *dbname); +extern const char *get_db_accessadmin_role_name(const char *dbname); extern const char *get_guest_schema_name(const char *dbname); extern bool is_shared_schema(const char *name); extern void truncate_tsql_identifier(char *ident); diff --git a/contrib/babelfishpg_tsql/src/pl_exec-2.c b/contrib/babelfishpg_tsql/src/pl_exec-2.c index 32ff3a3139..d06b89eff0 100644 --- a/contrib/babelfishpg_tsql/src/pl_exec-2.c +++ b/contrib/babelfishpg_tsql/src/pl_exec-2.c @@ -3761,7 +3761,7 @@ exec_stmt_grantschema(PLtsql_execstate *estate, PLtsql_stmt_grantschema *stmt) role_oid = get_role_oid(rolname, true); /* Special database roles should throw an error. */ - if (strcmp(grantee_name, "db_owner") == 0) + if (strcmp(grantee_name, "db_owner") == 0 || strcmp(grantee_name, DB_ACCESSADMIN) == 0) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("Cannot grant, deny or revoke permissions to or from special roles."))); diff --git a/contrib/babelfishpg_tsql/src/pl_handler.c b/contrib/babelfishpg_tsql/src/pl_handler.c index cd294408cc..7f74b6bd1b 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" @@ -2924,13 +2925,25 @@ bbf_ProcessUtility(PlannedStmt *pstmt, } else if (isuser || isrole) { - const char *db_owner_name; + const char *current_db_name = get_cur_db_name(); + const char *db_owner_name = get_db_owner_name(current_db_name); + const char *db_accessadmin_role = get_db_accessadmin_role_name(current_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_role_oid(db_owner_name, false)) || + (isuser && has_privs_of_role(GetUserId(), get_role_oid(db_accessadmin_role, 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."))); + } + } /* @@ -3202,16 +3215,25 @@ bbf_ProcessUtility(PlannedStmt *pstmt, } else if (isuser || isrole) { - const 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_role_oid(get_db_owner_name(db_name), false); + Oid db_accessadmin = get_role_oid(get_db_accessadmin_role_name(db_name), false); + Oid user_name = get_role_oid(stmt->role->rolename, false); + + /* db principal being altered should be a user or role in the current active logical database */ + if (!((isuser && is_user(user_name, true)) || (isrole && is_role(user_name, true)))) + 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))); - db_name = get_cur_db_name(); - dbo_name = get_dbo_role_name(db_name); - user_name = stmt->role->rolename; - cur_user = GetUserNameFromId(GetUserId(), false); + 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. @@ -3222,19 +3244,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_name == 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_name, 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"))); + } } } @@ -3244,11 +3284,18 @@ 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"))); + } } } @@ -3256,11 +3303,11 @@ bbf_ProcessUtility(PlannedStmt *pstmt, * 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(); { + GetUserIdAndSecContext(&save_userid, &save_sec_context); + 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, @@ -3276,12 +3323,11 @@ 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); return; @@ -3329,42 +3375,48 @@ bbf_ProcessUtility(PlannedStmt *pstmt, if (db_name != NULL && strcmp(db_name, "") != 0) { + Oid db_owner = get_role_oid(get_db_owner_name(db_name), false); + Oid db_accessadmin = get_role_oid(get_db_accessadmin_role_name(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); const char *db_principal_type = drop_user ? "user" : "role"; - const 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); - 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); + int rolename_len = strlen(rolspec->rolename); + + if (!OidIsValid(role_oid) || /* Not found */ + (drop_user && !is_user(role_oid, true)) || /* Found but not a user in current logical db */ + (drop_role && !is_role(role_oid, true))) /* 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)) + (drop_role && rolename_len == 8 && strncmp(rolspec->rolename, "db_owner", 8) == 0) || + (drop_role && rolename_len == 14 && strncmp(rolspec->rolename, DB_ACCESSADMIN, 14) == 0)) 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))); @@ -3469,9 +3521,9 @@ bbf_ProcessUtility(PlannedStmt *pstmt, if (is_login(roleform->oid)) all_logins = true; - else if (is_user(roleform->oid)) + else if (is_user(roleform->oid, false)) all_users = true; - else if (is_role(roleform->oid)) + else if (is_role(roleform->oid, false)) all_roles = true; else other = true; @@ -3516,11 +3568,11 @@ bbf_ProcessUtility(PlannedStmt *pstmt, * We have performed all the permissions checks. * Set current user to bbf_role_admin for drop permissions. */ - GetUserIdAndSecContext(&save_userid, &save_sec_context); - SetUserIdAndSecContext(get_bbf_role_admin_oid(), save_sec_context | SECURITY_LOCAL_USERID_CHANGE); - PG_TRY(); { + GetUserIdAndSecContext(&save_userid, &save_sec_context); + 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, @@ -3551,6 +3603,9 @@ bbf_ProcessUtility(PlannedStmt *pstmt, GrantStmt *stmt; PlannedStmt *wrapper; RoleSpec *rolspec = create_schema->authrole; + Oid owner_oid = InvalidOid; + Oid db_accessadmin = get_role_oid(get_db_accessadmin_role_name(get_cur_db_name()), true); + bool alter_owner = false; if (strcmp(queryString, "(CREATE LOGICAL DATABASE )") == 0 && context == PROCESS_UTILITY_SUBCOMMAND) @@ -3560,6 +3615,22 @@ bbf_ProcessUtility(PlannedStmt *pstmt, else orig_schema = "dbo"; } + else + { + owner_oid = rolspec ? get_rolespec_oid(rolspec, true) : InvalidOid; + if (OidIsValid(owner_oid) && OidIsValid(db_accessadmin) && !member_can_set_role(GetUserId(), owner_oid) && + has_privs_of_role(GetUserId(), db_accessadmin) && + (is_user(owner_oid, true) || is_role(owner_oid, true))) + { + /* + * db_accessadmin members can create schema for other users as owner + * but it does not actually have the required permission from PG + * perspective to do so, hence handle it this way. + */ + create_schema->authrole = NULL; + alter_owner = true; + } + } if (prev_ProcessUtility) prev_ProcessUtility(pstmt, queryString, readOnlyTree, context, params, @@ -3599,6 +3670,12 @@ bbf_ProcessUtility(PlannedStmt *pstmt, NULL); CommandCounterIncrement(); + + if (alter_owner) + { + AlterSchemaOwner_oid(get_namespace_oid(create_schema->schemaname, false), owner_oid); + } + /* Grant ALL schema privileges to the user.*/ if (rolspec && strcmp(queryString, "(CREATE LOGICAL DATABASE )") != 0) { diff --git a/contrib/babelfishpg_tsql/src/procedures.c b/contrib/babelfishpg_tsql/src/procedures.c index 27f21c6790..95cd0b72de 100644 --- a/contrib/babelfishpg_tsql/src/procedures.c +++ b/contrib/babelfishpg_tsql/src/procedures.c @@ -2283,7 +2283,7 @@ sp_droprole(PG_FUNCTION_ARGS) role_oid = get_role_oid(physical_role_name, true); /* Check if the role does not exists */ - if (role_oid == InvalidOid || !is_role(role_oid)) + if (role_oid == InvalidOid || !is_role(role_oid, false)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("Cannot drop the role '%s', because it does not exist or you do not have permission.", rolname))); @@ -2436,7 +2436,7 @@ sp_addrolemember(PG_FUNCTION_ARGS) * 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 || (!is_role(member_oid, false) && !is_user(member_oid, false))) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("User or role '%s' does not exist in this database.", membername))); @@ -2446,7 +2446,7 @@ sp_addrolemember(PG_FUNCTION_ARGS) 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 || !is_role(role_oid, false)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("Cannot alter the role '%s', because it does not exist or you do not have permission.", rolname))); @@ -2598,7 +2598,7 @@ sp_droprolemember(PG_FUNCTION_ARGS) 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 || !is_role(role_oid, false)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("Cannot alter the role '%s', because it does not exist or you do not have permission.", rolname))); @@ -2611,7 +2611,7 @@ sp_droprolemember(PG_FUNCTION_ARGS) * 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 || (!is_role(role_oid, false) && !is_user(role_oid, false))) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("Cannot drop the principal '%s', because it does not exist or you do not have permission.", membername))); diff --git a/contrib/babelfishpg_tsql/src/rolecmds.c b/contrib/babelfishpg_tsql/src/rolecmds.c index 9cfbd25e4d..9df544ee51 100644 --- a/contrib/babelfishpg_tsql/src/rolecmds.c +++ b/contrib/babelfishpg_tsql/src/rolecmds.c @@ -290,7 +290,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 (is_user(roleid, false) || is_role(roleid, false)) drop_bbf_authid_user_ext(access, classId, roleid, subId, arg); } @@ -1755,7 +1755,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 || !is_role(granted, false)) return false; } @@ -1778,7 +1778,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 (!is_user(grantee, false) && !is_role(grantee, false)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("%s is not a database user or a user-defined database role", @@ -1940,7 +1940,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 (!is_role(role_oid, false) || ((principal_oid != cur_user_oid) && (!has_privs_of_role(cur_user_oid, role_oid) || !has_privs_of_role(cur_user_oid, principal_oid)))) diff --git a/test/JDBC/expected/BABEL-2403.out b/test/JDBC/expected/BABEL-2403.out index c879c5bf23..2608f117b0 100644 --- a/test/JDBC/expected/BABEL-2403.out +++ b/test/JDBC/expected/BABEL-2403.out @@ -99,6 +99,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"} @@ -188,6 +194,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-LOGIN-USER-EXT.out b/test/JDBC/expected/BABEL-LOGIN-USER-EXT.out index 5437c600c8..96ae98cc9c 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 22aa32d6ee..604d3702db 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-vu-verify.out b/test/JDBC/expected/Test-sp_helpdbfixedrole-vu-verify.out index 825df76dc1..9b79a1c785 100644 --- a/test/JDBC/expected/Test-sp_helpdbfixedrole-vu-verify.out +++ b/test/JDBC/expected/Test-sp_helpdbfixedrole-vu-verify.out @@ -48,6 +48,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 +69,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/restrict_drop_user_role.out b/test/JDBC/expected/restrict_drop_user_role.out index c058d8feff..a1d76dba08 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; @@ -344,10 +352,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 cb9a19347f..1350ce6276 100644 --- a/test/JDBC/expected/single_db/BABEL-2403.out +++ b/test/JDBC/expected/single_db/BABEL-2403.out @@ -87,6 +87,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"} @@ -164,6 +170,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 9e09597c85..94a8c2063f 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/restrict_drop_user_role.out b/test/JDBC/expected/single_db/restrict_drop_user_role.out index 51acb0056a..0016910d85 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/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 53d5d91596..a946314493 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/python/expected/sql_validation_framework/expected_drop.out b/test/python/expected/sql_validation_framework/expected_drop.out index 243d664edf..ff5414284b 100644 --- a/test/python/expected/sql_validation_framework/expected_drop.out +++ b/test/python/expected/sql_validation_framework/expected_drop.out @@ -43,6 +43,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.babel_create_database_roles 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_drop_deprecated_function in file babelfishpg_tsql--1.2.1--2.0.0.sql From 9366d6fa8701b58dc08f2e56a9d5d508e3c997f0 Mon Sep 17 00:00:00 2001 From: Tanzeel Khan Date: Wed, 25 Sep 2024 10:13:49 +0000 Subject: [PATCH 02/44] empty commit to rerun actions Signed-off-by: Tanzeel Khan From 1d235d6ebc91dff915dfb77838076ae285174e51 Mon Sep 17 00:00:00 2001 From: Tanzeel Khan Date: Wed, 25 Sep 2024 15:48:03 +0000 Subject: [PATCH 03/44] add basic tests Signed-off-by: Tanzeel Khan --- contrib/babelfishpg_tsql/src/catalog.c | 14 +- contrib/babelfishpg_tsql/src/multidb.c | 13 +- contrib/babelfishpg_tsql/src/multidb.h | 2 +- contrib/babelfishpg_tsql/src/pl_handler.c | 25 ++- .../expected/db_accessadmin-vu-cleanup.out | 25 +++ .../expected/db_accessadmin-vu-prepare.out | 35 ++++ .../expected/db_accessadmin-vu-verify.out | 163 ++++++++++++++++++ .../single_db/db_accessadmin-vu-verify.out | 163 ++++++++++++++++++ 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 | 112 ++++++++++++ 11 files changed, 598 insertions(+), 14 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/src/catalog.c b/contrib/babelfishpg_tsql/src/catalog.c index 30c2c28d8f..cc4c0f2677 100644 --- a/contrib/babelfishpg_tsql/src/catalog.c +++ b/contrib/babelfishpg_tsql/src/catalog.c @@ -984,20 +984,22 @@ get_authid_user_ext_physical_name(const char *db_name, const char *login) Anum_bbf_authid_user_ext_database_name, BTEqualStrategyNumber, F_TEXTEQ, CStringGetTextDatum(db_name)); - ScanKeyInit(&key[2], - Anum_bbf_authid_user_ext_user_can_connect, - BTEqualStrategyNumber, F_INT4EQ, - Int32GetDatum(1)); - scan = table_beginscan_catalog(bbf_authid_user_ext_rel, 3, key); + scan = table_beginscan_catalog(bbf_authid_user_ext_rel, 2, key); tuple_user_ext = heap_getnext(scan, ForwardScanDirection); if (HeapTupleIsValid(tuple_user_ext)) { Form_authid_user_ext userform; + char *db_accessadmin = get_db_accessadmin_role_name(db_name); userform = (Form_authid_user_ext) GETSTRUCT(tuple_user_ext); - user_name = pstrdup(NameStr(userform->rolname)); + if (userform->user_can_connect || + (has_privs_of_role(GetUserId(), get_role_oid(db_accessadmin, false)))) + { + user_name = pstrdup(NameStr(userform->rolname)); + } + pfree(db_accessadmin); } table_endscan(scan); diff --git a/contrib/babelfishpg_tsql/src/multidb.c b/contrib/babelfishpg_tsql/src/multidb.c index 0e99e73dc1..7ad0c379be 100644 --- a/contrib/babelfishpg_tsql/src/multidb.c +++ b/contrib/babelfishpg_tsql/src/multidb.c @@ -249,6 +249,17 @@ rewrite_object_refs(Node *stmt) errmsg("Dropping members to db_owner is not currently supported " "in Babelfish"))); } + else if (strcmp(role_name, DB_ACCESSADMIN) == 0) + { + if (has_privs_of_role(GetUserId(), get_role_oid(get_db_owner_name(db_name), false))) + { + /* only members of db_owner can alter drop members to fixed db roles */ + } + else + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("Cannot alter the role '%s', because it does not exist or you do not have permission.", role_name))); + } /* * Try to get physical granted role name, see if it's an @@ -1417,7 +1428,7 @@ get_guest_role_name(const char *dbname) } } -const char * +char * get_db_accessadmin_role_name(const char *dbname) { char *name = palloc0(MAX_BBF_NAMEDATALEND); diff --git a/contrib/babelfishpg_tsql/src/multidb.h b/contrib/babelfishpg_tsql/src/multidb.h index 1f6d31149a..d74efe1a26 100644 --- a/contrib/babelfishpg_tsql/src/multidb.h +++ b/contrib/babelfishpg_tsql/src/multidb.h @@ -24,7 +24,7 @@ extern const char *get_dbo_schema_name(const char *dbname); extern const char *get_dbo_role_name(const char *dbname); extern const char *get_db_owner_name(const char *dbname); extern const char *get_guest_role_name(const char *dbname); -extern const char *get_db_accessadmin_role_name(const char *dbname); +extern char *get_db_accessadmin_role_name(const char *dbname); extern const char *get_guest_schema_name(const char *dbname); extern bool is_shared_schema(const char *name); extern void truncate_tsql_identifier(char *ident); diff --git a/contrib/babelfishpg_tsql/src/pl_handler.c b/contrib/babelfishpg_tsql/src/pl_handler.c index 7f74b6bd1b..908fbe3c48 100644 --- a/contrib/babelfishpg_tsql/src/pl_handler.c +++ b/contrib/babelfishpg_tsql/src/pl_handler.c @@ -3232,7 +3232,7 @@ bbf_ProcessUtility(PlannedStmt *pstmt, 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) + if (!is_member_of_db_owner && isuser) is_member_of_db_accessadmin = has_privs_of_role(GetUserId(), db_accessadmin); /* @@ -3299,13 +3299,13 @@ bbf_ProcessUtility(PlannedStmt *pstmt, } } + GetUserIdAndSecContext(&save_userid, &save_sec_context); /* * We have performed all the permissions checks. * Set current user to bbf_role_admin for alter permissions. */ PG_TRY(); { - GetUserIdAndSecContext(&save_userid, &save_sec_context); SetUserIdAndSecContext(get_bbf_role_admin_oid(), save_sec_context | SECURITY_LOCAL_USERID_CHANGE); if (prev_ProcessUtility) @@ -3568,11 +3568,11 @@ bbf_ProcessUtility(PlannedStmt *pstmt, * We have performed all the permissions checks. * Set current user to bbf_role_admin for drop permissions. */ + GetUserIdAndSecContext(&save_userid, &save_sec_context); + SetUserIdAndSecContext(get_bbf_role_admin_oid(), save_sec_context | SECURITY_LOCAL_USERID_CHANGE); + PG_TRY(); { - GetUserIdAndSecContext(&save_userid, &save_sec_context); - 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, @@ -3673,7 +3673,20 @@ bbf_ProcessUtility(PlannedStmt *pstmt, if (alter_owner) { - AlterSchemaOwner_oid(get_namespace_oid(create_schema->schemaname, false), owner_oid); + 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.*/ 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..ec399a0ba3 --- /dev/null +++ b/test/JDBC/expected/db_accessadmin-vu-cleanup.out @@ -0,0 +1,25 @@ +-- tsql +USE master +GO +DROP DATABASE 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..f88da3019a --- /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 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..5765883a1d --- /dev/null +++ b/test/JDBC/expected/db_accessadmin-vu-verify.out @@ -0,0 +1,163 @@ + + +-- 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 +-- 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 +ALTER ROLE db_accessadmin ADD MEMBER babel_5136_db_accessadmin_user +GO +-- MEMBERS OF db_accessadmin WILL ALWAYS HAVE CONNECT PRIVILEGES +REVOKE CONNECT FROM babel_5136_db_accessadmin_user +GO +-- 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 + + +-- tsql user=babel_5136_db_accessadmin_l1 password=12345678 +-- Check all allowed operations +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~~ + + +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~~ + + +-- db_accessadmin can not add/drop members to db_accessadmin +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.)~~ + + +-- 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 + +-- ALTER USER and THEN DROP IT +ALTER USER babel_5136_u1 WITH DEFAULT_SCHEMA = dbo +GO +-- NOT SUPPORTED CURRENTLY IN BABELFISH +ALTER USER babel_5136_u1 WITH DEFAULT_LANGUAGE = English +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error at or near "DEFAULT_LANGUAGE")~~ + +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)~~ + +-- db_accessadmin should not be able to ALTER LOGIN MAPPING +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 babel_5136_u1_new_name 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 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'.)~~ + +-- terminate-tsql-conn user=babel_5136_db_accessadmin_l1 password=12345678 + 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..7e7cc39530 --- /dev/null +++ b/test/JDBC/expected/single_db/db_accessadmin-vu-verify.out @@ -0,0 +1,163 @@ + + +-- 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 +-- 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 +ALTER ROLE db_accessadmin ADD MEMBER babel_5136_db_accessadmin_user +GO +-- MEMBERS OF db_accessadmin WILL ALWAYS HAVE CONNECT PRIVILEGES +REVOKE CONNECT FROM babel_5136_db_accessadmin_user +GO +-- 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 + + +-- tsql user=babel_5136_db_accessadmin_l1 password=12345678 +-- Check all allowed operations +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~~ + + +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~~ + + +-- db_accessadmin can not add/drop members to db_accessadmin +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.)~~ + + +-- 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 + +-- ALTER USER and THEN DROP IT +ALTER USER babel_5136_u1 WITH DEFAULT_SCHEMA = dbo +GO +-- NOT SUPPORTED CURRENTLY IN BABELFISH +ALTER USER babel_5136_u1 WITH DEFAULT_LANGUAGE = English +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error at or near "DEFAULT_LANGUAGE")~~ + +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)~~ + +-- db_accessadmin should not be able to ALTER LOGIN MAPPING +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 babel_5136_u1_new_name 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 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'.)~~ + +-- terminate-tsql-conn user=babel_5136_db_accessadmin_l1 password=12345678 + 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..b94e7ff925 --- /dev/null +++ b/test/JDBC/input/db_accessadmin-vu-cleanup.mix @@ -0,0 +1,25 @@ +-- tsql +USE master +GO +DROP DATABASE 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 \ No newline at end of file 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..f88da3019a --- /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 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..eb9f82c39a --- /dev/null +++ b/test/JDBC/input/db_accessadmin-vu-verify.mix @@ -0,0 +1,112 @@ +-- 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 +-- 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 +ALTER ROLE db_accessadmin ADD MEMBER babel_5136_db_accessadmin_user +GO +-- MEMBERS OF db_accessadmin WILL ALWAYS HAVE CONNECT PRIVILEGES +REVOKE CONNECT FROM babel_5136_db_accessadmin_user +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 + + +-- Check all allowed operations +-- tsql user=babel_5136_db_accessadmin_l1 password=12345678 +USE master +GO + +SELECT current_user +GO + +-- should not be a member of db_accessadmin in master database +SELECT IS_ROLEMEMBER('db_accessadmin') +GO + +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 + +-- db_accessadmin can not add/drop members to db_accessadmin +ALTER ROLE db_accessadmin ADD MEMBER babel_5136_u1 +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 + +-- ALTER USER and THEN DROP IT +ALTER USER babel_5136_u1 WITH DEFAULT_SCHEMA = dbo +GO +-- NOT SUPPORTED CURRENTLY IN BABELFISH +ALTER USER babel_5136_u1 WITH DEFAULT_LANGUAGE = English +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 +-- db_accessadmin should not be able to ALTER LOGIN MAPPING +ALTER USER babel_5136_u1_new_name WITH LOGIN = babel_5136_l3 +GO +ALTER USER babel_5136_u1_new_name 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 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 +-- terminate-tsql-conn user=babel_5136_db_accessadmin_l1 password=12345678 + From 67782424772f892b3c159a71b4b32ed927a33fcb Mon Sep 17 00:00:00 2001 From: Tanzeel Khan Date: Wed, 25 Sep 2024 17:19:37 +0000 Subject: [PATCH 04/44] fix get_authid_user_ext_physical_name Signed-off-by: Tanzeel Khan --- contrib/babelfishpg_tsql/src/catalog.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/contrib/babelfishpg_tsql/src/catalog.c b/contrib/babelfishpg_tsql/src/catalog.c index cc4c0f2677..2f714f4fa4 100644 --- a/contrib/babelfishpg_tsql/src/catalog.c +++ b/contrib/babelfishpg_tsql/src/catalog.c @@ -877,6 +877,8 @@ is_user(Oid role_oid, bool current_db_only) char *db_name_cstring = TextDatumGetCString(db_name); char *current_db_name = get_cur_db_name(); + Assert(!isnull); + is_user = (strcmp(db_name_cstring, current_db_name) == 0); pfree(db_name_cstring); @@ -920,6 +922,8 @@ is_role(Oid role_oid, bool current_db_only) char *db_name_cstring = TextDatumGetCString(db_name); char *current_db_name = get_cur_db_name(); + Assert(!isnull); + is_role = (strcmp(db_name_cstring, current_db_name) == 0); pfree(db_name_cstring); @@ -963,7 +967,7 @@ get_authid_user_ext_physical_name(const char *db_name, const char *login) { Relation bbf_authid_user_ext_rel; HeapTuple tuple_user_ext; - ScanKeyData key[3]; + ScanKeyData key[2]; TableScanDesc scan; char *user_name = NULL; NameData *login_name; @@ -990,14 +994,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; char *db_accessadmin = get_db_accessadmin_role_name(db_name); + bool user_can_connect; + bool isnull; + + 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); - userform = (Form_authid_user_ext) GETSTRUCT(tuple_user_ext); - if (userform->user_can_connect || - (has_privs_of_role(GetUserId(), get_role_oid(db_accessadmin, false)))) + if (user_can_connect == 1 || + (has_privs_of_role(get_role_oid(login, false), get_role_oid(db_accessadmin, false)))) { - user_name = pstrdup(NameStr(userform->rolname)); + 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)); } pfree(db_accessadmin); } From aa8c3a5fd856ce68fdd6e7108f650261cc750984 Mon Sep 17 00:00:00 2001 From: Tanzeel Khan Date: Wed, 25 Sep 2024 18:14:11 +0000 Subject: [PATCH 05/44] refactor Signed-off-by: Tanzeel Khan --- contrib/babelfishpg_tsql/src/catalog.c | 12 ++++++++---- contrib/babelfishpg_tsql/src/dbcmds.c | 13 ++----------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/contrib/babelfishpg_tsql/src/catalog.c b/contrib/babelfishpg_tsql/src/catalog.c index 2f714f4fa4..58679effaa 100644 --- a/contrib/babelfishpg_tsql/src/catalog.c +++ b/contrib/babelfishpg_tsql/src/catalog.c @@ -874,10 +874,12 @@ is_user(Oid role_oid, bool current_db_only) { Datum db_name = SysCacheGetAttr(AUTHIDUSEREXTROLENAME, tuple, Anum_bbf_authid_user_ext_database_name, &isnull); - char *db_name_cstring = TextDatumGetCString(db_name); - char *current_db_name = get_cur_db_name(); + char *db_name_cstring; + char *current_db_name; Assert(!isnull); + db_name_cstring = TextDatumGetCString(db_name); + current_db_name = get_cur_db_name(); is_user = (strcmp(db_name_cstring, current_db_name) == 0); @@ -919,10 +921,12 @@ is_role(Oid role_oid, bool current_db_only) { Datum db_name = SysCacheGetAttr(AUTHIDUSEREXTROLENAME, tuple, Anum_bbf_authid_user_ext_database_name, &isnull); - char *db_name_cstring = TextDatumGetCString(db_name); - char *current_db_name = get_cur_db_name(); + char *db_name_cstring; + char *current_db_name; Assert(!isnull); + db_name_cstring = TextDatumGetCString(db_name); + current_db_name = get_cur_db_name(); is_role = (strcmp(db_name_cstring, current_db_name) == 0); diff --git a/contrib/babelfishpg_tsql/src/dbcmds.c b/contrib/babelfishpg_tsql/src/dbcmds.c index 56e55c98bb..204c61f78f 100644 --- a/contrib/babelfishpg_tsql/src/dbcmds.c +++ b/contrib/babelfishpg_tsql/src/dbcmds.c @@ -1275,7 +1275,6 @@ create_database_roles_for_all_dbs(PG_FUNCTION_ARGS) char *dbname; int saved_nest_level = 0; - /* We only allow this to be called from an extension's SQL script. */ if (!creating_extension) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), @@ -1328,15 +1327,10 @@ create_database_roles_for_all_dbs(PG_FUNCTION_ARGS) PG_TRY(); { ListCell *parsetree_item; - /* - * We have performed all the permissions checks. - * Set current user to bbf_role_admin for create permissions. - * Set createrole_self_grant to "inherit" so that bbf_role_admin - * inherits the new role. - */ + 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); - /* Run all subcommands */ + foreach(parsetree_item, parsetree_list) { PlannedStmt *wrapper; @@ -1350,14 +1344,12 @@ create_database_roles_for_all_dbs(PG_FUNCTION_ARGS) SetUserIdAndSecContext(get_bbf_role_admin_oid(), save_sec_context | SECURITY_LOCAL_USERID_CHANGE); } - /* need to make a wrapper PlannedStmt */ wrapper = makeNode(PlannedStmt); wrapper->commandType = CMD_UTILITY; wrapper->canSetTag = false; wrapper->utilityStmt = ((RawStmt *) lfirst(parsetree_item))->stmt; wrapper->stmt_location = 0; - /* do this step */ ProcessUtility(wrapper, "(CREATE LOGICAL DATABASE )", false, @@ -1372,7 +1364,6 @@ create_database_roles_for_all_dbs(PG_FUNCTION_ARGS) } PG_FINALLY(); { - /* Clean up. Restore previous state. */ SetConfigOption("createrole_self_grant", old_createrole_self_grant, PGC_USERSET, PGC_S_OVERRIDE); SetUserIdAndSecContext(save_userid, save_sec_context); } From 04161b7c6f680aece296a83dc588b612950441c6 Mon Sep 17 00:00:00 2001 From: Tanzeel Khan Date: Thu, 26 Sep 2024 13:50:38 +0000 Subject: [PATCH 06/44] refactor is_role() & is_user() to one function Signed-off-by: Tanzeel Khan --- contrib/babelfishpg_tsql/src/catalog.c | 100 ++++++---------------- contrib/babelfishpg_tsql/src/catalog.h | 5 +- contrib/babelfishpg_tsql/src/pl_handler.c | 25 +++--- contrib/babelfishpg_tsql/src/procedures.c | 10 +-- contrib/babelfishpg_tsql/src/rolecmds.c | 8 +- 5 files changed, 52 insertions(+), 96 deletions(-) diff --git a/contrib/babelfishpg_tsql/src/catalog.c b/contrib/babelfishpg_tsql/src/catalog.c index 58679effaa..4c7c853c70 100644 --- a/contrib/babelfishpg_tsql/src/catalog.c +++ b/contrib/babelfishpg_tsql/src/catalog.c @@ -848,102 +848,56 @@ get_authid_login_ext_idx_oid(void) * USER EXT *****************************************/ -bool -is_user(Oid role_oid, bool current_db_only) +/* + * 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 + * Looks only in current bbf db when current_db_only is set to true + */ + +const int +is_database_principal(Oid role_oid, bool current_db_only) { - bool is_user = false; - bool isnull; + char result; + bool isnull; HeapTuple tuple; char *rolname; 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); - /* - * 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) - { - if (current_db_only) - { - Datum db_name = SysCacheGetAttr(AUTHIDUSEREXTROLENAME, tuple, - Anum_bbf_authid_user_ext_database_name, &isnull); - char *db_name_cstring; - char *current_db_name; - - Assert(!isnull); - db_name_cstring = TextDatumGetCString(db_name); - current_db_name = get_cur_db_name(); - - is_user = (strcmp(db_name_cstring, current_db_name) == 0); + result = (strcmp(type_str, "R") == 0) ? BBF_ROLE : BBF_USER; - pfree(db_name_cstring); - pfree(current_db_name); - } - else - is_user = true; - } - - ReleaseSysCache(tuple); pfree(type_str); - } - pfree(rolname); - - return is_user; -} - -bool -is_role(Oid role_oid, bool current_db_only) -{ - bool is_role = false; - bool isnull; - HeapTuple tuple; - char *rolname; - - rolname = GetUserNameFromId(role_oid, false); - tuple = SearchSysCache1(AUTHIDUSEREXTROLENAME, CStringGetDatum(rolname)); - - if (HeapTupleIsValid(tuple)) - { - BpChar type = ((Form_authid_user_ext) GETSTRUCT(tuple))->type; - char *type_str = bpchar_to_cstring(&type); - - if (strcmp(type_str, "R") == 0) + if (current_db_only) { - if (current_db_only) - { - Datum db_name = SysCacheGetAttr(AUTHIDUSEREXTROLENAME, tuple, - Anum_bbf_authid_user_ext_database_name, &isnull); - char *db_name_cstring; - char *current_db_name; + Datum db_name = SysCacheGetAttr(AUTHIDUSEREXTROLENAME, tuple, + Anum_bbf_authid_user_ext_database_name, &isnull); + char *db_name_cstring; + char *current_db_name; - Assert(!isnull); - db_name_cstring = TextDatumGetCString(db_name); - current_db_name = get_cur_db_name(); + Assert(!isnull); + db_name_cstring = TextDatumGetCString(db_name); + current_db_name = get_cur_db_name(); - is_role = (strcmp(db_name_cstring, current_db_name) == 0); + /* db match failed */ + if (strcmp(db_name_cstring, current_db_name) != 0) + result = 0; - pfree(db_name_cstring); - pfree(current_db_name); - } - else - is_role = true; + pfree(db_name_cstring); + pfree(current_db_name); } - + ReleaseSysCache(tuple); - pfree(type_str); } - pfree(rolname); - - return is_role; + return result; } Oid diff --git a/contrib/babelfishpg_tsql/src/catalog.h b/contrib/babelfishpg_tsql/src/catalog.h index 347b93baa9..40d5c282d8 100644 --- a/contrib/babelfishpg_tsql/src/catalog.h +++ b/contrib/babelfishpg_tsql/src/catalog.h @@ -146,8 +146,9 @@ 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, bool current_db_only); -extern bool is_role(Oid role_oid, bool current_db_only); +#define BBF_ROLE 1 +#define BBF_USER 2 +const int is_database_principal(Oid role_oid, bool current_db_only); extern Oid get_authid_user_ext_oid(void); extern Oid get_authid_user_ext_idx_oid(void); extern char *get_authid_user_ext_physical_name(const char *db_name, const char *login_name); diff --git a/contrib/babelfishpg_tsql/src/pl_handler.c b/contrib/babelfishpg_tsql/src/pl_handler.c index 908fbe3c48..d0c0d62a1b 100644 --- a/contrib/babelfishpg_tsql/src/pl_handler.c +++ b/contrib/babelfishpg_tsql/src/pl_handler.c @@ -3222,10 +3222,11 @@ bbf_ProcessUtility(PlannedStmt *pstmt, Oid save_userid; Oid db_owner = get_role_oid(get_db_owner_name(db_name), false); Oid db_accessadmin = get_role_oid(get_db_accessadmin_role_name(db_name), false); - Oid user_name = get_role_oid(stmt->role->rolename, false); + Oid user_oid = get_role_oid(stmt->role->rolename, false); /* db principal being altered should be a user or role in the current active logical database */ - if (!((isuser && is_user(user_name, true)) || (isrole && is_role(user_name, true)))) + if ((isuser && is_database_principal(user_oid, true) != BBF_USER) || + (isrole && is_database_principal(user_oid, true) != 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))); @@ -3245,7 +3246,7 @@ bbf_ProcessUtility(PlannedStmt *pstmt, if (strcmp(defel->defname, "default_schema") == 0) { if (is_member_of_db_owner || (isuser && is_member_of_db_accessadmin) || - user_name == GetUserId()) + user_oid == GetUserId()) { /* * members of db_owner can alter default schema for any role or user @@ -3262,7 +3263,7 @@ bbf_ProcessUtility(PlannedStmt *pstmt, else if (strcmp(defel->defname, "rename") == 0) { if (is_member_of_db_owner || (isuser && is_member_of_db_accessadmin && - !has_privs_of_role(user_name, db_owner))) + !has_privs_of_role(user_oid, db_owner))) { /* * members of db_owner can rename any role or user @@ -3387,8 +3388,8 @@ bbf_ProcessUtility(PlannedStmt *pstmt, int rolename_len = strlen(rolspec->rolename); if (!OidIsValid(role_oid) || /* Not found */ - (drop_user && !is_user(role_oid, true)) || /* Found but not a user in current logical db */ - (drop_role && !is_role(role_oid, true))) /* Found but not a role in current logical db */ + (drop_user && is_database_principal(role_oid, true) != BBF_USER) || /* Found but not a user in current logical db */ + (drop_role && is_database_principal(role_oid, true) != BBF_ROLE)) /* Found but not a role in current logical db */ { if (stmt->missing_ok) { @@ -3521,9 +3522,9 @@ bbf_ProcessUtility(PlannedStmt *pstmt, if (is_login(roleform->oid)) all_logins = true; - else if (is_user(roleform->oid, false)) + else if (is_database_principal(roleform->oid, false) == BBF_USER) all_users = true; - else if (is_role(roleform->oid, false)) + else if (is_database_principal(roleform->oid, false) == BBF_ROLE) all_roles = true; else other = true; @@ -3615,12 +3616,12 @@ bbf_ProcessUtility(PlannedStmt *pstmt, else orig_schema = "dbo"; } - else + else if (rolspec) { - owner_oid = rolspec ? get_rolespec_oid(rolspec, true) : InvalidOid; - if (OidIsValid(owner_oid) && OidIsValid(db_accessadmin) && !member_can_set_role(GetUserId(), owner_oid) && + owner_oid = get_rolespec_oid(rolspec, true); + if (OidIsValid(db_accessadmin) && !member_can_set_role(GetUserId(), owner_oid) && has_privs_of_role(GetUserId(), db_accessadmin) && - (is_user(owner_oid, true) || is_role(owner_oid, true))) + (is_database_principal(owner_oid, true))) { /* * db_accessadmin members can create schema for other users as owner diff --git a/contrib/babelfishpg_tsql/src/procedures.c b/contrib/babelfishpg_tsql/src/procedures.c index 0ccd14a5aa..b3cc7aa69c 100644 --- a/contrib/babelfishpg_tsql/src/procedures.c +++ b/contrib/babelfishpg_tsql/src/procedures.c @@ -2284,7 +2284,7 @@ sp_droprole(PG_FUNCTION_ARGS) role_oid = get_role_oid(physical_role_name, true); /* Check if the role does not exists */ - if (role_oid == InvalidOid || !is_role(role_oid, false)) + if (role_oid == InvalidOid || is_database_principal(role_oid, true) != 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))); @@ -2437,7 +2437,7 @@ sp_addrolemember(PG_FUNCTION_ARGS) * 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, false) && !is_user(member_oid, false))) + if (member_oid == InvalidOid || is_database_principal(member_oid, true)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("User or role '%s' does not exist in this database.", membername))); @@ -2447,7 +2447,7 @@ sp_addrolemember(PG_FUNCTION_ARGS) 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, false)) + if (role_oid == InvalidOid || is_database_principal(role_oid, true) != 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))); @@ -2599,7 +2599,7 @@ sp_droprolemember(PG_FUNCTION_ARGS) 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, false)) + if (role_oid == InvalidOid || is_database_principal(role_oid, true) != 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))); @@ -2612,7 +2612,7 @@ sp_droprolemember(PG_FUNCTION_ARGS) * 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, false) && !is_user(role_oid, false))) + if (role_oid == InvalidOid || is_database_principal(role_oid, true)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("Cannot drop the principal '%s', because it does not exist or you do not have permission.", membername))); diff --git a/contrib/babelfishpg_tsql/src/rolecmds.c b/contrib/babelfishpg_tsql/src/rolecmds.c index c57535a5ce..51f564a471 100644 --- a/contrib/babelfishpg_tsql/src/rolecmds.c +++ b/contrib/babelfishpg_tsql/src/rolecmds.c @@ -290,7 +290,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, false) || is_role(roleid, false)) + else if (is_database_principal(roleid, false)) drop_bbf_authid_user_ext(access, classId, roleid, subId, arg); } @@ -1763,7 +1763,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, false)) + if (granted == InvalidOid || is_database_principal(granted, true) != BBF_ROLE) return false; } @@ -1786,7 +1786,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, false) && !is_role(grantee, false)) + if (is_database_principal(grantee, false)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("%s is not a database user or a user-defined database role", @@ -1948,7 +1948,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, false) || + if (is_database_principal(role_oid, false) != 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)))) From c26714acd993e48d078c1d2d8fb3f56e872a2548 Mon Sep 17 00:00:00 2001 From: Tanzeel Khan Date: Thu, 26 Sep 2024 16:25:49 +0000 Subject: [PATCH 07/44] address comments Signed-off-by: Tanzeel Khan --- .../babelfishpg_tsql/sql/babelfishpg_tsql.sql | 14 ++-- .../babelfishpg_tsql--4.3.0--4.4.0.sql | 16 ++--- contrib/babelfishpg_tsql/src/catalog.c | 64 ++++++++++++++++--- contrib/babelfishpg_tsql/src/catalog.h | 1 + contrib/babelfishpg_tsql/src/dbcmds.c | 53 +++++++-------- contrib/babelfishpg_tsql/src/hooks.c | 2 +- contrib/babelfishpg_tsql/src/multidb.c | 16 +---- contrib/babelfishpg_tsql/src/pl_handler.c | 19 +++--- contrib/babelfishpg_tsql/src/pltsql.h | 10 +++ contrib/babelfishpg_tsql/src/rolecmds.c | 15 ++++- .../Test-sp_helpdbfixedrole-vu-verify.out | 3 +- 11 files changed, 138 insertions(+), 75 deletions(-) diff --git a/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql b/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql index e16f957311..d17cff00db 100644 --- a/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql +++ b/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql @@ -2347,16 +2347,16 @@ GRANT EXECUTE ON PROCEDURE sys.sp_helpsrvrolemember TO PUBLIC; CREATE OR REPLACE PROCEDURE sys.sp_helpdbfixedrole("@rolename" sys.SYSNAME = NULL) AS $$ BEGIN + DECLARE @rolenamelower sys.SYSNAME = LOWER(RTRIM(@rolename)) -- Returns a list of the fixed database roles. - IF LOWER(RTRIM(@rolename)) IS NULL OR LOWER(RTRIM(@rolename)) = 'db_owner' + IF @rolenamelower IS NULL OR @rolenamelower 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), CAST(Description AS sys.nvarchar(70)) FROM ( + VALUES ('db_owner', 'DB Owners'), + ('db_accessadmin', 'DB Access Administrators')) x(DbFixedRole, Description) + WHERE @rolenamelower IS NULL OR @rolenamelower = DbFixedRole; END - ELSE IF LOWER(RTRIM(@rolename)) IS NULL OR LOWER(RTRIM(@rolename)) = 'db_accessadmin' - BEGIN - SELECT CAST('db_accessadmin' AS sys.SYSNAME) AS DbFixedRole, CAST('DB Access Administrators' AS sys.nvarchar(70)) AS Description; - END - ELSE IF LOWER(RTRIM(@rolename)) IN ( + ELSE IF @rolenamelower IN ( 'db_securityadmin','db_ddladmin', 'db_backupoperator', 'db_datareader', 'db_datawriter', 'db_denydatareader', 'db_denydatawriter') BEGIN diff --git a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.3.0--4.4.0.sql b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.3.0--4.4.0.sql index 5caeeb1dfa..5ce3cf286e 100644 --- a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.3.0--4.4.0.sql +++ b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.3.0--4.4.0.sql @@ -1977,18 +1977,16 @@ GRANT SELECT ON sys.database_principals TO PUBLIC; CREATE OR REPLACE PROCEDURE sys.sp_helpdbfixedrole("@rolename" sys.SYSNAME = NULL) AS $$ BEGIN + DECLARE @rolenamelower sys.SYSNAME = LOWER(RTRIM(@rolename)) -- Returns a list of the fixed database roles. - -- Only fixed role present in babelfish is db_owner. - IF LOWER(RTRIM(@rolename)) IS NULL OR LOWER(RTRIM(@rolename)) = 'db_owner' + IF @rolenamelower IS NULL OR @rolenamelower 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), CAST(Description AS sys.nvarchar(70)) FROM ( + VALUES ('db_owner', 'DB Owners'), + ('db_accessadmin', 'DB Access Administrators')) x(DbFixedRole, Description) + WHERE @rolenamelower IS NULL OR @rolenamelower = DbFixedRole; END - ELSE IF LOWER(RTRIM(@rolename)) IS NULL OR LOWER(RTRIM(@rolename)) = 'db_accessadmin' - BEGIN - SELECT CAST('db_accessadmin' AS sys.SYSNAME) AS DbFixedRole, CAST('DB Access Administrators' AS sys.nvarchar(70)) AS Description; - END - ELSE IF LOWER(RTRIM(@rolename)) IN ( - 'db_accessadmin','db_securityadmin','db_ddladmin', 'db_backupoperator', + ELSE IF @rolenamelower IN ( 'db_securityadmin','db_ddladmin', 'db_backupoperator', 'db_datareader', 'db_datawriter', 'db_denydatareader', 'db_denydatawriter') BEGIN diff --git a/contrib/babelfishpg_tsql/src/catalog.c b/contrib/babelfishpg_tsql/src/catalog.c index 4c7c853c70..5774cf668c 100644 --- a/contrib/babelfishpg_tsql/src/catalog.c +++ b/contrib/babelfishpg_tsql/src/catalog.c @@ -857,7 +857,7 @@ get_authid_login_ext_idx_oid(void) const int is_database_principal(Oid role_oid, bool current_db_only) { - char result; + char result = 0; bool isnull; HeapTuple tuple; char *rolname; @@ -871,10 +871,6 @@ is_database_principal(Oid role_oid, bool current_db_only) BpChar type = ((Form_authid_user_ext) GETSTRUCT(tuple))->type; char *type_str = bpchar_to_cstring(&type); - result = (strcmp(type_str, "R") == 0) ? BBF_ROLE : BBF_USER; - - pfree(type_str); - if (current_db_only) { Datum db_name = SysCacheGetAttr(AUTHIDUSEREXTROLENAME, tuple, @@ -886,14 +882,16 @@ is_database_principal(Oid role_oid, bool current_db_only) db_name_cstring = TextDatumGetCString(db_name); current_db_name = get_cur_db_name(); - /* db match failed */ - if (strcmp(db_name_cstring, current_db_name) != 0) - result = 0; + if (strcmp(db_name_cstring, current_db_name) == 0) + result = (strcmp(type_str, "R") == 0) ? BBF_ROLE : BBF_USER; pfree(db_name_cstring); pfree(current_db_name); } + else + result = (strcmp(type_str, "R") == 0) ? BBF_ROLE : BBF_USER; + pfree(type_str); ReleaseSysCache(tuple); } @@ -920,6 +918,53 @@ 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 + * Looks only in current bbf db when current_db_only is set to true + */ +char * +get_authid_user_ext_original_name(const char *physical_role_name, bool current_db_only) +{ + char* orig_username = NULL; + bool isnull; + HeapTuple tuple; + + Assert(physical_role_name != NULL && strlen(physical_role_name) != 0); + + tuple = SearchSysCache1(AUTHIDUSEREXTROLENAME, CStringGetDatum(physical_role_name)); + + if (HeapTupleIsValid(tuple)) + { + Datum orig_username_datum = SysCacheGetAttr(AUTHIDUSEREXTROLENAME, tuple, + Anum_bbf_authid_user_ext_orig_username, &isnull); + Assert(!isnull); + + if (current_db_only) + { + Datum db_name = SysCacheGetAttr(AUTHIDUSEREXTROLENAME, tuple, + Anum_bbf_authid_user_ext_database_name, &isnull); + char *db_name_cstring; + char *current_db_name; + + Assert(!isnull); + db_name_cstring = TextDatumGetCString(db_name); + current_db_name = get_cur_db_name(); + + if (strcmp(db_name_cstring, current_db_name) == 0) + orig_username = TextDatumGetCString(orig_username_datum); + + pfree(db_name_cstring); + pfree(current_db_name); + } + else + orig_username = TextDatumGetCString(orig_username_datum); + + ReleaseSysCache(tuple); + } + + return orig_username; +} + char * get_authid_user_ext_physical_name(const char *db_name, const char *login) { @@ -962,6 +1007,7 @@ get_authid_user_ext_physical_name(const char *db_name, const char *login) 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_role_oid(db_accessadmin, false)))) { @@ -3167,7 +3213,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, diff --git a/contrib/babelfishpg_tsql/src/catalog.h b/contrib/babelfishpg_tsql/src/catalog.h index 40d5c282d8..48e74a85cc 100644 --- a/contrib/babelfishpg_tsql/src/catalog.h +++ b/contrib/babelfishpg_tsql/src/catalog.h @@ -151,6 +151,7 @@ extern Oid bbf_authid_user_ext_idx_oid; const int is_database_principal(Oid role_oid, bool current_db_only); 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, bool current_db_only); 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 204c61f78f..e77a453bc1 100644 --- a/contrib/babelfishpg_tsql/src/dbcmds.c +++ b/contrib/babelfishpg_tsql/src/dbcmds.c @@ -279,11 +279,11 @@ gen_dropdb_subcmds(const char *dbname, List *db_users) expected_stmts += 2; } } - /* Drop db_accessadmin*/ + 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; "); - /* Then drop db_owner and dbo in that order */ - appendStringInfo(&query, "DROP OWNED BY dummy, dummy CASCADE; "); appendStringInfo(&query, "REVOKE CREATE, CONNECT, TEMPORARY ON DATABASE dummy FROM dummy; "); appendStringInfo(&query, "DROP ROLE dummy; "); appendStringInfo(&query, "DROP ROLE dummy; "); @@ -317,14 +317,14 @@ gen_dropdb_subcmds(const char *dbname, List *db_users) } } + stmt = parsetree_nth_stmt(stmt_list, i++); + update_DropOwnedStmt(stmt, list_make3(pstrdup(db_accessadmin), pstrdup(db_owner), pstrdup(dbo))); + stmt = parsetree_nth_stmt(stmt_list, i++); update_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_DropOwnedStmt(stmt, list_make2(pstrdup(db_owner), pstrdup(dbo))); - stmt = parsetree_nth_stmt(stmt_list, i++); update_GrantStmt(stmt, get_database_name(MyDatabaseId), NULL, dbo, NULL); @@ -645,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, @@ -1272,8 +1272,11 @@ create_database_roles_for_all_dbs(PG_FUNCTION_ARGS) TableScanDesc scan; HeapTuple tuple; Form_sysdatabases bbf_db; + StringInfoData query; + List *parsetree_list; char *dbname; - int saved_nest_level = 0; + int pltsql_save_nestlevel; + int save_nestlevel; if (!creating_extension) ereport(ERROR, @@ -1281,7 +1284,8 @@ create_database_roles_for_all_dbs(PG_FUNCTION_ARGS) errmsg("%s can only be called from an SQL script executed by CREATE/ALTER EXTENSION", "create_database_roles_for_all_dbs()"))); - saved_nest_level = pltsql_new_guc_nest_level(); + pltsql_save_nestlevel = pltsql_new_guc_nest_level(); + save_nestlevel = NewGUCNestLevel(); set_config_option("babelfishpg_tsql.sql_dialect", "tsql", GUC_CONTEXT_CONFIG, PGC_S_SESSION, GUC_ACTION_SAVE, true, 0, false); @@ -1289,33 +1293,30 @@ create_database_roles_for_all_dbs(PG_FUNCTION_ARGS) 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) { - StringInfoData query; - List *parsetree_list; Node *stmt; + Oid save_userid; + int save_sec_context; + int i = 0; const char *db_owner; const char *db_accessadmin; - const char *old_createrole_self_grant = GetConfigOption("createrole_self_grant", false, true); - int i = 0; - int save_sec_context = 0; - Oid save_userid = InvalidOid; bbf_db = (Form_sysdatabases) GETSTRUCT(tuple); dbname = text_to_cstring(&(bbf_db->name)); db_owner = get_db_owner_name(dbname); db_accessadmin = get_db_accessadmin_role_name(dbname); - 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); - stmt = parsetree_nth_stmt(parsetree_list, i++); update_CreateRoleStmt(stmt, db_accessadmin, db_owner, NULL); @@ -1351,7 +1352,7 @@ create_database_roles_for_all_dbs(PG_FUNCTION_ARGS) wrapper->stmt_location = 0; ProcessUtility(wrapper, - "(CREATE LOGICAL DATABASE )", + CREATE_FIXED_DB_ROLES, false, PROCESS_UTILITY_SUBCOMMAND, NULL, @@ -1364,16 +1365,16 @@ create_database_roles_for_all_dbs(PG_FUNCTION_ARGS) } PG_FINALLY(); { - SetConfigOption("createrole_self_grant", old_createrole_self_grant, PGC_USERSET, PGC_S_OVERRIDE); SetUserIdAndSecContext(save_userid, save_sec_context); } PG_END_TRY(); - pfree(query.data); pfree(dbname); } - pltsql_revert_guc(saved_nest_level); + pfree(query.data); + AtEOXact_GUC(false, save_nestlevel); + pltsql_revert_guc(pltsql_save_nestlevel); table_endscan(scan); table_close(sysdatabase_rel, RowExclusiveLock); diff --git a/contrib/babelfishpg_tsql/src/hooks.c b/contrib/babelfishpg_tsql/src/hooks.c index 54ad1ec59f..bb14edebdd 100644 --- a/contrib/babelfishpg_tsql/src/hooks.c +++ b/contrib/babelfishpg_tsql/src/hooks.c @@ -3198,7 +3198,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 7ad0c379be..e211bafd9d 100644 --- a/contrib/babelfishpg_tsql/src/multidb.c +++ b/contrib/babelfishpg_tsql/src/multidb.c @@ -249,17 +249,6 @@ rewrite_object_refs(Node *stmt) errmsg("Dropping members to db_owner is not currently supported " "in Babelfish"))); } - else if (strcmp(role_name, DB_ACCESSADMIN) == 0) - { - if (has_privs_of_role(GetUserId(), get_role_oid(get_db_owner_name(db_name), false))) - { - /* only members of db_owner can alter drop members to fixed db roles */ - } - else - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("Cannot alter the role '%s', because it does not exist or you do not have permission.", role_name))); - } /* * Try to get physical granted role name, see if it's an @@ -1433,8 +1422,9 @@ get_db_accessadmin_role_name(const char *dbname) { char *name = palloc0(MAX_BBF_NAMEDATALEND); - if (get_migration_mode() == SINGLE_DB && strcmp(dbname, "master") != 0 - && strcmp(dbname, "tempdb") != 0 && strcmp(dbname, "msdb") != 0) + 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); diff --git a/contrib/babelfishpg_tsql/src/pl_handler.c b/contrib/babelfishpg_tsql/src/pl_handler.c index d0c0d62a1b..25bc0016c5 100644 --- a/contrib/babelfishpg_tsql/src/pl_handler.c +++ b/contrib/babelfishpg_tsql/src/pl_handler.c @@ -2616,7 +2616,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; @@ -3604,11 +3605,10 @@ bbf_ProcessUtility(PlannedStmt *pstmt, GrantStmt *stmt; PlannedStmt *wrapper; RoleSpec *rolspec = create_schema->authrole; - Oid owner_oid = InvalidOid; - Oid db_accessadmin = get_role_oid(get_db_accessadmin_role_name(get_cur_db_name()), true); + 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) @@ -3616,8 +3616,10 @@ bbf_ProcessUtility(PlannedStmt *pstmt, else orig_schema = "dbo"; } - else if (rolspec) + else if (rolspec && strcmp(queryString, CREATE_FIXED_DB_ROLES) != 0) { + Oid db_accessadmin = get_role_oid(get_db_accessadmin_role_name(get_cur_db_name()), false); + owner_oid = get_rolespec_oid(rolspec, true); if (OidIsValid(db_accessadmin) && !member_can_set_role(GetUserId(), owner_oid) && has_privs_of_role(GetUserId(), db_accessadmin) && @@ -3691,7 +3693,7 @@ bbf_ProcessUtility(PlannedStmt *pstmt, } /* 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++) @@ -3773,7 +3775,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; @@ -4101,7 +4104,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 6efb1e8c53..a7b676e3cc 100644 --- a/contrib/babelfishpg_tsql/src/pltsql.h +++ b/contrib/babelfishpg_tsql/src/pltsql.h @@ -1979,6 +1979,16 @@ 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_FIXED_DB_ROLES "(CREATE FIXED DATABASE ROLES )" + +#define IS_BBF_BUILT_IN_DB(dbname) \ + (strncmp(dbname, "master", 6) == 0 || \ + strncmp(dbname, "tempdb", 6) == 0 || \ + strncmp(dbname, "msdb", 4) == 0) + /********************************************************************** * Function declarations **********************************************************************/ diff --git a/contrib/babelfishpg_tsql/src/rolecmds.c b/contrib/babelfishpg_tsql/src/rolecmds.c index 51f564a471..577d9f5ac5 100644 --- a/contrib/babelfishpg_tsql/src/rolecmds.c +++ b/contrib/babelfishpg_tsql/src/rolecmds.c @@ -1777,6 +1777,9 @@ 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_cur_db_name(); + const char *db_owner = get_db_owner_name(db_name); RoleSpec *granted_spec; RoleSpec *grantee_spec; @@ -1786,7 +1789,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_database_principal(grantee, false)) + if (!is_database_principal(grantee, true)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("%s is not a database user or a user-defined database role", @@ -1797,6 +1800,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, true); + Assert(original_user_name); + + /* only members of db_owner can alter drop members to fixed db roles */ + if (strcmp(original_user_name, DB_ACCESSADMIN) == 0 && + !has_privs_of_role(GetUserId(), get_role_oid(db_owner, 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 diff --git a/test/JDBC/expected/Test-sp_helpdbfixedrole-vu-verify.out b/test/JDBC/expected/Test-sp_helpdbfixedrole-vu-verify.out index 9b79a1c785..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~~ From 2f141fa008dba107229363c3856fb8b179d5af21 Mon Sep 17 00:00:00 2001 From: Tanzeel Khan Date: Thu, 26 Sep 2024 17:07:06 +0000 Subject: [PATCH 08/44] fix Signed-off-by: Tanzeel Khan --- contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql | 11 +++++------ .../sql/upgrades/babelfishpg_tsql--4.3.0--4.4.0.sql | 9 ++++----- contrib/babelfishpg_tsql/src/pl_handler.c | 12 ++++++------ contrib/babelfishpg_tsql/src/procedures.c | 4 ++-- contrib/babelfishpg_tsql/src/rolecmds.c | 2 +- .../Test-sp_helpdbfixedrole-dep-vu-verify.out | 5 +++-- 6 files changed, 21 insertions(+), 22 deletions(-) diff --git a/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql b/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql index d17cff00db..535072b138 100644 --- a/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql +++ b/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql @@ -2347,16 +2347,15 @@ GRANT EXECUTE ON PROCEDURE sys.sp_helpsrvrolemember TO PUBLIC; CREATE OR REPLACE PROCEDURE sys.sp_helpdbfixedrole("@rolename" sys.SYSNAME = NULL) AS $$ BEGIN - DECLARE @rolenamelower sys.SYSNAME = LOWER(RTRIM(@rolename)) -- Returns a list of the fixed database roles. - IF @rolenamelower IS NULL OR @rolenamelower IN ('db_owner', 'db_accessadmin') + IF LOWER(RTRIM(@rolename)) IS NULL OR LOWER(RTRIM(@rolename)) IN ('db_owner', 'db_accessadmin') BEGIN - SELECT CAST(DbFixedRole as sys.SYSNAME), CAST(Description AS sys.nvarchar(70)) FROM ( + 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 @rolenamelower IS NULL OR @rolenamelower = DbFixedRole; + WHERE LOWER(RTRIM(@rolename)) IS NULL OR LOWER(RTRIM(@rolename)) = DbFixedRole; END - ELSE IF @rolenamelower IN ( + ELSE IF LOWER(RTRIM(@rolename)) IN ( 'db_securityadmin','db_ddladmin', 'db_backupoperator', 'db_datareader', 'db_datawriter', 'db_denydatareader', 'db_denydatawriter') BEGIN @@ -2365,7 +2364,7 @@ BEGIN WHERE 1=0; END ELSE - RAISERROR('''%s'' is not a known fixed role.', 16, 1, @rolename); + RAISERROR('''%s'' is not a known fixed role.', 16, 1, LOWER(RTRIM(@rolename))); END $$ LANGUAGE 'pltsql'; diff --git a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.3.0--4.4.0.sql b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.3.0--4.4.0.sql index 5ce3cf286e..95161cec8e 100644 --- a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.3.0--4.4.0.sql +++ b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.3.0--4.4.0.sql @@ -1977,16 +1977,15 @@ GRANT SELECT ON sys.database_principals TO PUBLIC; CREATE OR REPLACE PROCEDURE sys.sp_helpdbfixedrole("@rolename" sys.SYSNAME = NULL) AS $$ BEGIN - DECLARE @rolenamelower sys.SYSNAME = LOWER(RTRIM(@rolename)) -- Returns a list of the fixed database roles. - IF @rolenamelower IS NULL OR @rolenamelower IN ('db_owner', 'db_accessadmin') + IF LOWER(RTRIM(@rolename)) IS NULL OR LOWER(RTRIM(@rolename)) IN ('db_owner', 'db_accessadmin') BEGIN - SELECT CAST(DbFixedRole as sys.SYSNAME), CAST(Description AS sys.nvarchar(70)) FROM ( + 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 @rolenamelower IS NULL OR @rolenamelower = DbFixedRole; + WHERE LOWER(RTRIM(@rolename)) IS NULL OR LOWER(RTRIM(@rolename)) = DbFixedRole; END - ELSE IF @rolenamelower IN ( + ELSE IF LOWER(RTRIM(@rolename)) IN ( 'db_securityadmin','db_ddladmin', 'db_backupoperator', 'db_datareader', 'db_datawriter', 'db_denydatareader', 'db_denydatawriter') BEGIN diff --git a/contrib/babelfishpg_tsql/src/pl_handler.c b/contrib/babelfishpg_tsql/src/pl_handler.c index 25bc0016c5..783f81fd48 100644 --- a/contrib/babelfishpg_tsql/src/pl_handler.c +++ b/contrib/babelfishpg_tsql/src/pl_handler.c @@ -3621,15 +3621,15 @@ bbf_ProcessUtility(PlannedStmt *pstmt, Oid db_accessadmin = get_role_oid(get_db_accessadmin_role_name(get_cur_db_name()), false); owner_oid = get_rolespec_oid(rolspec, true); - if (OidIsValid(db_accessadmin) && !member_can_set_role(GetUserId(), owner_oid) && + /* + * 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) && (is_database_principal(owner_oid, true))) { - /* - * db_accessadmin members can create schema for other users as owner - * but it does not actually have the required permission from PG - * perspective to do so, hence handle it this way. - */ create_schema->authrole = NULL; alter_owner = true; } diff --git a/contrib/babelfishpg_tsql/src/procedures.c b/contrib/babelfishpg_tsql/src/procedures.c index b3cc7aa69c..f8a6586206 100644 --- a/contrib/babelfishpg_tsql/src/procedures.c +++ b/contrib/babelfishpg_tsql/src/procedures.c @@ -2437,7 +2437,7 @@ sp_addrolemember(PG_FUNCTION_ARGS) * Check if the user, group or role does not exists and given member * name is an role or user */ - if (member_oid == InvalidOid || is_database_principal(member_oid, true)) + if (member_oid == InvalidOid || !is_database_principal(member_oid, true)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("User or role '%s' does not exist in this database.", membername))); @@ -2612,7 +2612,7 @@ sp_droprolemember(PG_FUNCTION_ARGS) * Throw an error id the given member name doesn't exist or isn't a * role or user */ - if (role_oid == InvalidOid || is_database_principal(role_oid, true)) + if (role_oid == InvalidOid || !is_database_principal(role_oid, true)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("Cannot drop the principal '%s', because it does not exist or you do not have permission.", membername))); diff --git a/contrib/babelfishpg_tsql/src/rolecmds.c b/contrib/babelfishpg_tsql/src/rolecmds.c index 577d9f5ac5..c784083868 100644 --- a/contrib/babelfishpg_tsql/src/rolecmds.c +++ b/contrib/babelfishpg_tsql/src/rolecmds.c @@ -1803,7 +1803,7 @@ check_alter_role_stmt(GrantRoleStmt *stmt) original_user_name = get_authid_user_ext_original_name(granted_name, true); Assert(original_user_name); - /* only members of db_owner can alter drop members to fixed db roles */ + /* only members of db_owner can alter drop members of fixed db roles */ if (strcmp(original_user_name, DB_ACCESSADMIN) == 0 && !has_privs_of_role(GetUserId(), get_role_oid(db_owner, false))) ereport(ERROR, 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~~ From ef055771fd58b0b5dd6a8a1bc70337d1974a2c88 Mon Sep 17 00:00:00 2001 From: Tanzeel Khan Date: Thu, 26 Sep 2024 17:53:37 +0000 Subject: [PATCH 09/44] fix Signed-off-by: Tanzeel Khan --- .../babelfishpg_tsql/sql/babelfishpg_tsql.sql | 2 +- .../babelfishpg_tsql--4.3.0--4.4.0.sql | 112 ------------------ 2 files changed, 1 insertion(+), 113 deletions(-) diff --git a/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql b/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql index 535072b138..a1439f30af 100644 --- a/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql +++ b/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql @@ -2364,7 +2364,7 @@ BEGIN WHERE 1=0; END ELSE - RAISERROR('''%s'' is not a known fixed role.', 16, 1, LOWER(RTRIM(@rolename))); + RAISERROR('''%s'' is not a known fixed role.', 16, 1, @rolename); END $$ LANGUAGE 'pltsql'; diff --git a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.3.0--4.4.0.sql b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.3.0--4.4.0.sql index 95161cec8e..cd9e23a772 100644 --- a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.3.0--4.4.0.sql +++ b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.3.0--4.4.0.sql @@ -1515,118 +1515,6 @@ BEGIN END; $$ LANGUAGE plpgsql STABLE; -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 != 'db_owner' - 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 != 'db_owner' - 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 != 'db_owner' - 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'; create or replace view sys.types As with RECURSIVE type_code_list as From f8263ada1fefe5ad3d962d3cef042673e6f669b5 Mon Sep 17 00:00:00 2001 From: Tanzeel Khan Date: Thu, 26 Sep 2024 19:29:15 +0000 Subject: [PATCH 10/44] empty commit to rerun actions Signed-off-by: Tanzeel Khan From 5ccc553e1c7b020d24888c4da40cbfae4e016799 Mon Sep 17 00:00:00 2001 From: Tanzeel Khan Date: Thu, 26 Sep 2024 20:21:52 +0000 Subject: [PATCH 11/44] fix Signed-off-by: Tanzeel Khan --- contrib/babelfishpg_tsql/src/dbcmds.c | 2 +- contrib/babelfishpg_tsql/src/pl_handler.c | 3 ++- contrib/babelfishpg_tsql/src/pltsql.h | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/contrib/babelfishpg_tsql/src/dbcmds.c b/contrib/babelfishpg_tsql/src/dbcmds.c index e77a453bc1..12cfcbae1d 100644 --- a/contrib/babelfishpg_tsql/src/dbcmds.c +++ b/contrib/babelfishpg_tsql/src/dbcmds.c @@ -1163,7 +1163,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, diff --git a/contrib/babelfishpg_tsql/src/pl_handler.c b/contrib/babelfishpg_tsql/src/pl_handler.c index 783f81fd48..66df5296e3 100644 --- a/contrib/babelfishpg_tsql/src/pl_handler.c +++ b/contrib/babelfishpg_tsql/src/pl_handler.c @@ -3616,7 +3616,8 @@ bbf_ProcessUtility(PlannedStmt *pstmt, else orig_schema = "dbo"; } - else if (rolspec && strcmp(queryString, CREATE_FIXED_DB_ROLES) != 0) + else if (rolspec && strcmp(queryString, CREATE_FIXED_DB_ROLES) != 0 && + strcmp(queryString, CREATE_GUEST_SCHEMAS_DURING_UPGRADE) != 0) { Oid db_accessadmin = get_role_oid(get_db_accessadmin_role_name(get_cur_db_name()), false); diff --git a/contrib/babelfishpg_tsql/src/pltsql.h b/contrib/babelfishpg_tsql/src/pltsql.h index b9055f4591..cde0f19b73 100644 --- a/contrib/babelfishpg_tsql/src/pltsql.h +++ b/contrib/babelfishpg_tsql/src/pltsql.h @@ -1984,6 +1984,7 @@ 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 )" #define IS_BBF_BUILT_IN_DB(dbname) \ From 2c6071d43ba65ba6c826125fb4bcf0d2b2c3ff6d Mon Sep 17 00:00:00 2001 From: Tanzeel Khan Date: Fri, 27 Sep 2024 05:41:15 +0000 Subject: [PATCH 12/44] fix Signed-off-by: Tanzeel Khan --- contrib/babelfishpg_tsql/src/pl_handler.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/contrib/babelfishpg_tsql/src/pl_handler.c b/contrib/babelfishpg_tsql/src/pl_handler.c index 66df5296e3..205e47b810 100644 --- a/contrib/babelfishpg_tsql/src/pl_handler.c +++ b/contrib/babelfishpg_tsql/src/pl_handler.c @@ -3616,8 +3616,11 @@ bbf_ProcessUtility(PlannedStmt *pstmt, else orig_schema = "dbo"; } - else if (rolspec && strcmp(queryString, CREATE_FIXED_DB_ROLES) != 0 && - strcmp(queryString, CREATE_GUEST_SCHEMAS_DURING_UPGRADE) != 0) + else if (strcmp(queryString, CREATE_GUEST_SCHEMAS_DURING_UPGRADE) == 0) + { + orig_schema = "guest"; + } + else if (rolspec && strcmp(queryString, CREATE_FIXED_DB_ROLES) != 0) { Oid db_accessadmin = get_role_oid(get_db_accessadmin_role_name(get_cur_db_name()), false); From 8e236afdfc583a21c9f6a37a9d361b19fe40b7b8 Mon Sep 17 00:00:00 2001 From: Tanzeel Khan Date: Fri, 27 Sep 2024 07:20:48 +0000 Subject: [PATCH 13/44] fix Signed-off-by: Tanzeel Khan From 262ab3b291390972ec3de25345e451c2f87e2bd0 Mon Sep 17 00:00:00 2001 From: Tanzeel Khan Date: Fri, 27 Sep 2024 13:13:54 +0000 Subject: [PATCH 14/44] add test to upgrade Signed-off-by: Tanzeel Khan --- test/JDBC/upgrade/14_10/schedule | 2 +- test/JDBC/upgrade/14_11/schedule | 2 +- test/JDBC/upgrade/14_12/schedule | 2 +- test/JDBC/upgrade/14_13/schedule | 2 +- test/JDBC/upgrade/14_14/schedule | 2 +- test/JDBC/upgrade/14_3/schedule | 2 +- test/JDBC/upgrade/14_5/schedule | 2 +- test/JDBC/upgrade/14_6/schedule | 2 +- test/JDBC/upgrade/14_7/schedule | 2 +- test/JDBC/upgrade/14_8/schedule | 2 +- test/JDBC/upgrade/14_9/schedule | 2 +- test/JDBC/upgrade/15_1/schedule | 2 +- test/JDBC/upgrade/15_2/schedule | 2 +- test/JDBC/upgrade/15_3/schedule | 2 +- test/JDBC/upgrade/15_4/schedule | 2 +- test/JDBC/upgrade/15_5/schedule | 2 +- test/JDBC/upgrade/15_6/schedule | 2 +- test/JDBC/upgrade/15_7/schedule | 2 +- test/JDBC/upgrade/15_8/schedule | 2 +- test/JDBC/upgrade/15_9/schedule | 2 +- test/JDBC/upgrade/16_1/schedule | 2 +- test/JDBC/upgrade/16_2/schedule | 2 +- test/JDBC/upgrade/16_3/schedule | 2 +- test/JDBC/upgrade/16_4/schedule | 1 + test/JDBC/upgrade/latest/schedule | 2 +- test/JDBC/upgrade/singledb/schedule | 3 ++- 26 files changed, 27 insertions(+), 25 deletions(-) diff --git a/test/JDBC/upgrade/14_10/schedule b/test/JDBC/upgrade/14_10/schedule index beb43d8043..67a39cda67 100644 --- a/test/JDBC/upgrade/14_10/schedule +++ b/test/JDBC/upgrade/14_10/schedule @@ -462,4 +462,4 @@ getdate-before-15_9-or-16_5 space binary-datatype-operators cast-varchar-to-time - +db_accessadmin diff --git a/test/JDBC/upgrade/14_11/schedule b/test/JDBC/upgrade/14_11/schedule index c3e8018e36..ad14d344a3 100644 --- a/test/JDBC/upgrade/14_11/schedule +++ b/test/JDBC/upgrade/14_11/schedule @@ -460,4 +460,4 @@ getdate-before-15_9-or-16_5 space binary-datatype-operators cast-varchar-to-time - +db_accessadmin diff --git a/test/JDBC/upgrade/14_12/schedule b/test/JDBC/upgrade/14_12/schedule index 3a7f033ff2..67e735ddc8 100644 --- a/test/JDBC/upgrade/14_12/schedule +++ b/test/JDBC/upgrade/14_12/schedule @@ -461,4 +461,4 @@ getdate-before-15_9-or-16_5 space binary-datatype-operators cast-varchar-to-time - +db_accessadmin diff --git a/test/JDBC/upgrade/14_13/schedule b/test/JDBC/upgrade/14_13/schedule index b382cf58a9..1b9d7c0745 100644 --- a/test/JDBC/upgrade/14_13/schedule +++ b/test/JDBC/upgrade/14_13/schedule @@ -461,4 +461,4 @@ getdate-before-15_9-or-16_5 space binary-datatype-operators cast-varchar-to-time - +db_accessadmin diff --git a/test/JDBC/upgrade/14_14/schedule b/test/JDBC/upgrade/14_14/schedule index b382cf58a9..1b9d7c0745 100644 --- a/test/JDBC/upgrade/14_14/schedule +++ b/test/JDBC/upgrade/14_14/schedule @@ -461,4 +461,4 @@ getdate-before-15_9-or-16_5 space binary-datatype-operators cast-varchar-to-time - +db_accessadmin diff --git a/test/JDBC/upgrade/14_3/schedule b/test/JDBC/upgrade/14_3/schedule index 4022b96bac..8a1d6b3cdd 100644 --- a/test/JDBC/upgrade/14_3/schedule +++ b/test/JDBC/upgrade/14_3/schedule @@ -382,4 +382,4 @@ getdate-before-15_9-or-16_5 space binary-datatype-operators cast-varchar-to-time - +db_accessadmin diff --git a/test/JDBC/upgrade/14_5/schedule b/test/JDBC/upgrade/14_5/schedule index 7ee0776874..8e76f0e264 100644 --- a/test/JDBC/upgrade/14_5/schedule +++ b/test/JDBC/upgrade/14_5/schedule @@ -393,4 +393,4 @@ string_agg-before-15_9-or-16_5 space binary-datatype-operators cast-varchar-to-time - +db_accessadmin diff --git a/test/JDBC/upgrade/14_6/schedule b/test/JDBC/upgrade/14_6/schedule index ef7e3736b2..434a96d130 100644 --- a/test/JDBC/upgrade/14_6/schedule +++ b/test/JDBC/upgrade/14_6/schedule @@ -430,4 +430,4 @@ string_agg-before-15_9-or-16_5 space binary-datatype-operators cast-varchar-to-time - +db_accessadmin diff --git a/test/JDBC/upgrade/14_7/schedule b/test/JDBC/upgrade/14_7/schedule index b12f17b421..6d81b4fcaa 100644 --- a/test/JDBC/upgrade/14_7/schedule +++ b/test/JDBC/upgrade/14_7/schedule @@ -452,4 +452,4 @@ string_agg-before-15_9-or-16_5 space binary-datatype-operators cast-varchar-to-time - +db_accessadmin diff --git a/test/JDBC/upgrade/14_8/schedule b/test/JDBC/upgrade/14_8/schedule index 7be63b7d01..67a671af35 100644 --- a/test/JDBC/upgrade/14_8/schedule +++ b/test/JDBC/upgrade/14_8/schedule @@ -454,4 +454,4 @@ string_agg-before-15_9-or-16_5 space binary-datatype-operators cast-varchar-to-time - +db_accessadmin diff --git a/test/JDBC/upgrade/14_9/schedule b/test/JDBC/upgrade/14_9/schedule index 16572c3e0f..68f0e5f32b 100644 --- a/test/JDBC/upgrade/14_9/schedule +++ b/test/JDBC/upgrade/14_9/schedule @@ -457,4 +457,4 @@ string_agg-before-15_9-or-16_5 space binary-datatype-operators cast-varchar-to-time - +db_accessadmin diff --git a/test/JDBC/upgrade/15_1/schedule b/test/JDBC/upgrade/15_1/schedule index 8503cbdbb7..319822ec5b 100644 --- a/test/JDBC/upgrade/15_1/schedule +++ b/test/JDBC/upgrade/15_1/schedule @@ -430,4 +430,4 @@ string_agg-before-15_9-or-16_5 space binary-datatype-operators cast-varchar-to-time - +db_accessadmin diff --git a/test/JDBC/upgrade/15_2/schedule b/test/JDBC/upgrade/15_2/schedule index 9d4a234e17..80324d35ec 100644 --- a/test/JDBC/upgrade/15_2/schedule +++ b/test/JDBC/upgrade/15_2/schedule @@ -465,4 +465,4 @@ string_agg-before-15_9-or-16_5 space binary-datatype-operators cast-varchar-to-time - +db_accessadmin diff --git a/test/JDBC/upgrade/15_3/schedule b/test/JDBC/upgrade/15_3/schedule index 38ab04cc37..96c61701eb 100644 --- a/test/JDBC/upgrade/15_3/schedule +++ b/test/JDBC/upgrade/15_3/schedule @@ -484,4 +484,4 @@ string_agg-before-15_9-or-16_5 space binary-datatype-operators cast-varchar-to-time - +db_accessadmin diff --git a/test/JDBC/upgrade/15_4/schedule b/test/JDBC/upgrade/15_4/schedule index b0fd286ccd..47088b7ebb 100644 --- a/test/JDBC/upgrade/15_4/schedule +++ b/test/JDBC/upgrade/15_4/schedule @@ -497,4 +497,4 @@ getdate-before-15_9-or-16_5 space binary-datatype-operators cast-varchar-to-time - +db_accessadmin diff --git a/test/JDBC/upgrade/15_5/schedule b/test/JDBC/upgrade/15_5/schedule index 7969757b3f..a97e9c5a97 100644 --- a/test/JDBC/upgrade/15_5/schedule +++ b/test/JDBC/upgrade/15_5/schedule @@ -528,4 +528,4 @@ getdate-before-15_9-or-16_5 space binary-datatype-operators cast-varchar-to-time - +db_accessadmin diff --git a/test/JDBC/upgrade/15_6/schedule b/test/JDBC/upgrade/15_6/schedule index 92cb04ef93..5c54d33950 100644 --- a/test/JDBC/upgrade/15_6/schedule +++ b/test/JDBC/upgrade/15_6/schedule @@ -544,4 +544,4 @@ getdate-before-15_9-or-16_5 space binary-datatype-operators cast-varchar-to-time - +db_accessadmin diff --git a/test/JDBC/upgrade/15_7/schedule b/test/JDBC/upgrade/15_7/schedule index ef41d3ad22..9db922b9d0 100644 --- a/test/JDBC/upgrade/15_7/schedule +++ b/test/JDBC/upgrade/15_7/schedule @@ -551,5 +551,5 @@ replicate-before-15_8-or-16_4 space binary-datatype-operators cast-varchar-to-time - +db_accessadmin diff --git a/test/JDBC/upgrade/15_8/schedule b/test/JDBC/upgrade/15_8/schedule index 2c3a41e440..49cd875e91 100644 --- a/test/JDBC/upgrade/15_8/schedule +++ b/test/JDBC/upgrade/15_8/schedule @@ -542,4 +542,4 @@ replace alter-procedure-15_8-or-16_4 binary-datatype-operators cast-varchar-to-time - +db_accessadmin diff --git a/test/JDBC/upgrade/15_9/schedule b/test/JDBC/upgrade/15_9/schedule index 53920cf5c5..d79753919d 100644 --- a/test/JDBC/upgrade/15_9/schedule +++ b/test/JDBC/upgrade/15_9/schedule @@ -543,4 +543,4 @@ binary-datatype-operators SELECT_INTO_TEST cast-varchar-to-time BABEL-5119 - +db_accessadmin diff --git a/test/JDBC/upgrade/16_1/schedule b/test/JDBC/upgrade/16_1/schedule index af72bac629..f7db676e87 100644 --- a/test/JDBC/upgrade/16_1/schedule +++ b/test/JDBC/upgrade/16_1/schedule @@ -537,4 +537,4 @@ space replace-before-15_8-or-16_4 binary-datatype-operators cast-varchar-to-time - +db_accessadmin diff --git a/test/JDBC/upgrade/16_2/schedule b/test/JDBC/upgrade/16_2/schedule index 426f5e369a..e9e97405a4 100644 --- a/test/JDBC/upgrade/16_2/schedule +++ b/test/JDBC/upgrade/16_2/schedule @@ -552,4 +552,4 @@ space replace-before-15_8-or-16_4 binary-datatype-operators cast-varchar-to-time - +db_accessadmin diff --git a/test/JDBC/upgrade/16_3/schedule b/test/JDBC/upgrade/16_3/schedule index 84c9a3d6ac..650e8ed209 100644 --- a/test/JDBC/upgrade/16_3/schedule +++ b/test/JDBC/upgrade/16_3/schedule @@ -555,4 +555,4 @@ space replace-before-15_8-or-16_4 binary-datatype-operators cast-varchar-to-time - +db_accessadmin diff --git a/test/JDBC/upgrade/16_4/schedule b/test/JDBC/upgrade/16_4/schedule index a3ea167892..e19e2dac5d 100644 --- a/test/JDBC/upgrade/16_4/schedule +++ b/test/JDBC/upgrade/16_4/schedule @@ -567,3 +567,4 @@ space binary-datatype-operators cast-varchar-to-time BABEL-5119 +db_accessadmin diff --git a/test/JDBC/upgrade/latest/schedule b/test/JDBC/upgrade/latest/schedule index 1c0825603e..fba914e823 100644 --- a/test/JDBC/upgrade/latest/schedule +++ b/test/JDBC/upgrade/latest/schedule @@ -572,4 +572,4 @@ cast-varchar-to-time test_db_collation BABEL-5119 BABEL-5129 - +db_accessadmin diff --git a/test/JDBC/upgrade/singledb/schedule b/test/JDBC/upgrade/singledb/schedule index 55ab635341..ff70ad0bf6 100644 --- a/test/JDBC/upgrade/singledb/schedule +++ b/test/JDBC/upgrade/singledb/schedule @@ -1 +1,2 @@ -TestInt \ No newline at end of file +TestInt +db_accessadmin \ No newline at end of file From 3377700424a23ec9e8393c0ac7968bee10a66203 Mon Sep 17 00:00:00 2001 From: Tanzeel Khan Date: Fri, 27 Sep 2024 13:24:22 +0000 Subject: [PATCH 15/44] add test to upgrade Signed-off-by: Tanzeel Khan --- test/JDBC/upgrade/13_9/schedule | 1 + 1 file changed, 1 insertion(+) diff --git a/test/JDBC/upgrade/13_9/schedule b/test/JDBC/upgrade/13_9/schedule index 458e9fcd19..e7919c74c3 100644 --- a/test/JDBC/upgrade/13_9/schedule +++ b/test/JDBC/upgrade/13_9/schedule @@ -355,3 +355,4 @@ string_agg-before-14_5 space binary-datatype-operators replace-before-15_8-or-16_4 +db_accessadmin From 9d88f540cbdff46c80566b3412c87d2fa883524c Mon Sep 17 00:00:00 2001 From: Harsh Lunagariya Date: Mon, 30 Sep 2024 08:10:42 +0000 Subject: [PATCH 16/44] Support db_secadmin Signed-off-by: Harsh Lunagariya --- .../babelfishpg_tsql/sql/babelfishpg_tsql.sql | 14 ++++-- contrib/babelfishpg_tsql/sql/ownership.sql | 8 ++-- .../babelfishpg_tsql--4.3.0--4.4.0.sql | 21 ++++----- contrib/babelfishpg_tsql/src/catalog.c | 3 +- contrib/babelfishpg_tsql/src/catalog.h | 1 + contrib/babelfishpg_tsql/src/dbcmds.c | 46 +++++++++++++++++-- contrib/babelfishpg_tsql/src/multidb.c | 24 ++++++++-- contrib/babelfishpg_tsql/src/multidb.h | 1 + contrib/babelfishpg_tsql/src/pl_exec-2.c | 4 +- contrib/babelfishpg_tsql/src/pl_handler.c | 24 ++++++++-- 10 files changed, 112 insertions(+), 34 deletions(-) diff --git a/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql b/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql index e16f957311..d7de56fff1 100644 --- a/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql +++ b/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql @@ -2118,7 +2118,7 @@ BEGIN LEFT OUTER JOIN pg_catalog.pg_roles AS Base4 ON Base4.rolname = Bsdb.owner WHERE Ext1.database_name = DB_NAME() AND (Ext1.type != 'R' OR Ext1.type != 'A') - AND Ext1.orig_username NOT IN ('db_owner', 'db_accessadmin') + AND Ext1.orig_username NOT IN ('db_owner', 'db_securityadmin', 'db_accessadmin') ORDER BY UserName, RoleName; END -- If the security account is the db fixed role - db_owner @@ -2150,7 +2150,7 @@ BEGIN WHERE Ext1.database_name = DB_NAME() AND Ext2.database_name = DB_NAME() AND Ext1.type = 'R' - AND Ext2.orig_username NOT IN ('db_owner', 'db_accessadmin') + AND Ext2.orig_username NOT IN ('db_owner', 'db_securityadmin', '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 @@ -2188,7 +2188,7 @@ BEGIN LEFT OUTER JOIN pg_catalog.pg_roles AS Base4 ON Base4.rolname = Bsdb.owner WHERE Ext1.database_name = DB_NAME() AND (Ext1.type != 'R' OR Ext1.type != 'A') - AND Ext1.orig_username NOT IN ('db_owner', 'db_accessadmin') + AND Ext1.orig_username NOT IN ('db_owner', 'db_securityadmin', '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 @@ -2352,13 +2352,17 @@ BEGIN BEGIN SELECT CAST('db_owner' AS sys.SYSNAME) AS DbFixedRole, CAST('DB Owners' AS sys.nvarchar(70)) AS Description; END + ELSE IF LOWER(RTRIM(@rolename)) IS NULL OR LOWER(RTRIM(@rolename)) = 'db_securityadmin' + BEGIN + SELECT CAST('db_securityadmin' AS sys.SYSNAME) AS DbFixedRole, CAST('DB Security Administrators' AS sys.nvarchar(70)) AS Description; + END ELSE IF LOWER(RTRIM(@rolename)) IS NULL OR LOWER(RTRIM(@rolename)) = 'db_accessadmin' BEGIN SELECT CAST('db_accessadmin' AS sys.SYSNAME) AS DbFixedRole, CAST('DB Access Administrators' AS sys.nvarchar(70)) AS Description; END ELSE IF LOWER(RTRIM(@rolename)) IN ( - 'db_securityadmin','db_ddladmin', 'db_backupoperator', - 'db_datareader', 'db_datawriter', 'db_denydatareader', 'db_denydatawriter') + 'db_ddladmin', 'db_backupoperator', 'db_datareader', + 'db_datawriter', 'db_denydatareader', 'db_denydatawriter') BEGIN -- Return an empty result set instead of raising an error SELECT CAST(NULL AS sys.SYSNAME) AS DbFixedRole, CAST(NULL AS sys.nvarchar(70)) AS Description diff --git a/contrib/babelfishpg_tsql/sql/ownership.sql b/contrib/babelfishpg_tsql/sql/ownership.sql index f746ea93c3..9e890ee852 100644 --- a/contrib/babelfishpg_tsql/sql/ownership.sql +++ b/contrib/babelfishpg_tsql/sql/ownership.sql @@ -259,9 +259,9 @@ CREATE OR REPLACE PROCEDURE initialize_babelfish ( sa_name VARCHAR(128) ) LANGUAGE plpgsql AS $$ DECLARE - reserved_roles varchar[] := ARRAY['sysadmin', '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']; + reserved_roles varchar[] := ARRAY['sysadmin', 'master_dbo', 'master_guest', 'master_db_owner', 'master_db_accessadmin', 'master_db_securityadmin', + 'tempdb_dbo', 'tempdb_guest', 'tempdb_db_owner', 'tempdb_db_accessadmin', 'tempdb_db_securityadmin', + 'msdb_dbo', 'msdb_guest', 'msdb_db_owner', 'msdb_db_accessadmin', 'msdb_db_securityadmin']; user_id oid := -1; db_name name := NULL; role_name varchar; @@ -452,7 +452,7 @@ ON Base.rolname = Ext.rolname LEFT OUTER JOIN pg_catalog.pg_roles Base2 ON Ext.login_name = Base2.rolname WHERE Ext.database_name = DB_NAME() - AND (Ext.orig_username IN ('dbo', 'db_owner', 'db_accessadmin', 'guest') -- system users should always be visible + AND (Ext.orig_username IN ('dbo', 'db_owner', 'db_securityadmin', '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/upgrades/babelfishpg_tsql--4.3.0--4.4.0.sql b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.3.0--4.4.0.sql index 5caeeb1dfa..1b453608f6 100644 --- a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.3.0--4.4.0.sql +++ b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.3.0--4.4.0.sql @@ -1945,7 +1945,7 @@ ON Base.rolname = Ext.rolname LEFT OUTER JOIN pg_catalog.pg_roles Base2 ON Ext.login_name = Base2.rolname WHERE Ext.database_name = DB_NAME() - AND (Ext.orig_username IN ('dbo', 'db_owner', 'db_accessadmin', 'guest') -- system users should always be visible + AND (Ext.orig_username IN ('dbo', 'db_owner', 'db_securityadmin', '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 @@ -1978,19 +1978,21 @@ CREATE OR REPLACE PROCEDURE sys.sp_helpdbfixedrole("@rolename" sys.SYSNAME = NUL $$ BEGIN -- Returns a list of the fixed database roles. - -- Only fixed role present in babelfish is db_owner. IF LOWER(RTRIM(@rolename)) IS NULL OR LOWER(RTRIM(@rolename)) = 'db_owner' BEGIN SELECT CAST('db_owner' AS sys.SYSNAME) AS DbFixedRole, CAST('DB Owners' AS sys.nvarchar(70)) AS Description; END + ELSE IF LOWER(RTRIM(@rolename)) IS NULL OR LOWER(RTRIM(@rolename)) = 'db_securityadmin' + BEGIN + SELECT CAST('db_securityadmin' AS sys.SYSNAME) AS DbFixedRole, CAST('DB Security Administrators' AS sys.nvarchar(70)) AS Description; + END ELSE IF LOWER(RTRIM(@rolename)) IS NULL OR LOWER(RTRIM(@rolename)) = 'db_accessadmin' BEGIN SELECT CAST('db_accessadmin' AS sys.SYSNAME) AS DbFixedRole, CAST('DB Access Administrators' AS sys.nvarchar(70)) AS Description; END ELSE IF LOWER(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') + 'db_ddladmin', 'db_backupoperator', 'db_datareader', + 'db_datawriter', 'db_denydatareader', 'db_denydatawriter') BEGIN -- Return an empty result set instead of raising an error SELECT CAST(NULL AS sys.SYSNAME) AS DbFixedRole, CAST(NULL AS sys.nvarchar(70)) AS Description @@ -2035,8 +2037,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 NOT IN ('db_owner', 'db_securityadmin', 'db_accessadmin') ORDER BY UserName, RoleName; END -- If the security account is the db fixed role - db_owner @@ -2068,8 +2069,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 Ext2.orig_username NOT IN ('db_owner', 'db_securityadmin', '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 @@ -2107,8 +2107,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 NOT IN ('db_owner', 'db_securityadmin', '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 diff --git a/contrib/babelfishpg_tsql/src/catalog.c b/contrib/babelfishpg_tsql/src/catalog.c index 58679effaa..3954407fa6 100644 --- a/contrib/babelfishpg_tsql/src/catalog.c +++ b/contrib/babelfishpg_tsql/src/catalog.c @@ -4976,7 +4976,8 @@ rename_tsql_db(char *old_db_name, char *new_db_name) if (SINGLE_DB == get_migration_mode() && ((strlen(role) == 3 && strncmp(role, "dbo", 3) == 0) || (strlen(role) == 8 && strncmp(role, "db_owner", 8) == 0) || - (strlen(role) == 14 && strncmp(role, DB_ACCESSADMIN, 14) == 0))) + (strlen(role) == 14 && strncmp(role, DB_ACCESSADMIN, 14) == 0) || + (strlen(role) == 16 && strncmp(role, DB_SECURITYADMIN, 16) == 0))) continue; old_role_name = get_physical_user_name(old_db_name, role, true); diff --git a/contrib/babelfishpg_tsql/src/catalog.h b/contrib/babelfishpg_tsql/src/catalog.h index 347b93baa9..16d1e6a317 100644 --- a/contrib/babelfishpg_tsql/src/catalog.h +++ b/contrib/babelfishpg_tsql/src/catalog.h @@ -313,6 +313,7 @@ typedef FormData_bbf_function_ext *Form_bbf_function_ext; #define PUBLIC_ROLE_NAME "public" #define DB_ACCESSADMIN "db_accessadmin" +#define DB_SECURITYADMIN "db_securityadmin" #define PERMISSIONS_FOR_ALL_OBJECTS_IN_SCHEMA "ALL" #define ALL_PERMISSIONS_ON_RELATION 47 /* last 6 bits as 101111 represents ALL privileges on a relation. */ #define ALL_PERMISSIONS_ON_FUNCTION 128 /* last 8 bits as 10000000 represents ALL privileges on a procedure/function. */ diff --git a/contrib/babelfishpg_tsql/src/dbcmds.c b/contrib/babelfishpg_tsql/src/dbcmds.c index 204c61f78f..5db3e3c2b2 100644 --- a/contrib/babelfishpg_tsql/src/dbcmds.c +++ b/contrib/babelfishpg_tsql/src/dbcmds.c @@ -87,6 +87,7 @@ gen_createdb_subcmds(const char *dbname, const char *owner) const char *dbo; const char *db_owner; const char *db_accessadmin; + const char *db_securityadmin; const char *guest; const char *guest_schema; Oid owner_oid; @@ -96,6 +97,7 @@ gen_createdb_subcmds(const char *dbname, const char *owner) dbo = get_dbo_role_name(dbname); db_owner = get_db_owner_name(dbname); db_accessadmin = get_db_accessadmin_role_name(dbname); + db_securityadmin = get_db_securityadmin_role_name(dbname); guest = get_guest_role_name(dbname); guest_schema = get_guest_schema_name(dbname); owner_oid = get_role_oid(owner, true); @@ -119,6 +121,10 @@ gen_createdb_subcmds(const char *dbname, const char *owner) appendStringInfo(&query, "CREATE ROLE dummy ROLE dummy; "); appendStringInfo(&query, "GRANT CREATE ON DATABASE dummy TO dummy; "); + /* create db_securityadmin */ + 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; "); @@ -140,13 +146,13 @@ gen_createdb_subcmds(const char *dbname, const char *owner) if (guest) { if (!owner_is_sa) - expected_stmt_num = list_length(logins) > 0 ? 12 : 11; + expected_stmt_num = list_length(logins) > 0 ? 14 : 13; else - expected_stmt_num = list_length(logins) > 0 ? 11 : 10; + expected_stmt_num = list_length(logins) > 0 ? 13 : 12; } else { - expected_stmt_num = 8; + expected_stmt_num = 10; if (!owner_is_sa) expected_stmt_num++; @@ -182,6 +188,12 @@ gen_createdb_subcmds(const char *dbname, const char *owner) stmt = parsetree_nth_stmt(res, i++); update_GrantStmt(stmt, get_database_name(MyDatabaseId), NULL, db_accessadmin, NULL); + stmt = parsetree_nth_stmt(res, i++); + update_CreateRoleStmt(stmt, db_securityadmin, db_owner, NULL); + + stmt = parsetree_nth_stmt(res, i++); + update_GrantStmt(stmt, get_database_name(MyDatabaseId), NULL, db_securityadmin, NULL); + if (guest) { stmt = parsetree_nth_stmt(res, i++); @@ -218,16 +230,19 @@ add_fixed_user_roles_to_bbf_authid_user_ext(const char *dbname) const char *dbo; const char *db_owner; const char *db_accessadmin; + const char *db_securityadmin; const char *guest; dbo = get_dbo_role_name(dbname); db_owner = get_db_owner_name(dbname); db_accessadmin = get_db_accessadmin_role_name(dbname); + db_securityadmin = get_db_securityadmin_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); + add_to_bbf_authid_user_ext(db_securityadmin, DB_SECURITYADMIN, dbname, NULL, NULL, true, true, false); /* * For master, tempdb and msdb databases, the guest user will be @@ -249,17 +264,19 @@ gen_dropdb_subcmds(const char *dbname, List *db_users) List *stmt_list; ListCell *elem; Node *stmt; - int expected_stmts = 8; + int expected_stmts = 10; int i = 0; const char *dbo; const char *db_owner; const char *db_accessadmin; + const char *db_securityadmin; 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); + db_securityadmin = get_db_securityadmin_role_name(dbname); schema = get_dbo_schema_name(dbname); guest_schema = get_guest_schema_name(dbname); @@ -272,7 +289,7 @@ gen_dropdb_subcmds(const char *dbname, List *db_users) char *user_name = (char *) lfirst(elem); if (strcmp(user_name, db_owner) != 0 && strcmp(user_name, dbo) != 0 && - strcmp(user_name, db_accessadmin) != 0) + strcmp(user_name, db_accessadmin) != 0 && strcmp(user_name, db_securityadmin) != 0) { appendStringInfo(&query, "DROP OWNED BY dummy CASCADE; "); appendStringInfo(&query, "DROP ROLE dummy; "); @@ -282,6 +299,9 @@ gen_dropdb_subcmds(const char *dbname, List *db_users) /* Drop db_accessadmin*/ appendStringInfo(&query, "REVOKE CREATE ON DATABASE dummy FROM dummy; "); appendStringInfo(&query, "DROP ROLE dummy; "); + /* Drop db_securityadmin */ + appendStringInfo(&query, "REVOKE CREATE ON DATABASE dummy FROM dummy; "); + appendStringInfo(&query, "DROP ROLE dummy; "); /* Then drop db_owner and dbo in that order */ appendStringInfo(&query, "DROP OWNED BY dummy, dummy CASCADE; "); appendStringInfo(&query, "REVOKE CREATE, CONNECT, TEMPORARY ON DATABASE dummy FROM dummy; "); @@ -322,6 +342,11 @@ gen_dropdb_subcmds(const char *dbname, List *db_users) 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, db_securityadmin, NULL); + stmt = parsetree_nth_stmt(stmt_list, i++); + update_DropRoleStmt(stmt, db_securityadmin); + stmt = parsetree_nth_stmt(stmt_list, i++); update_DropOwnedStmt(stmt, list_make2(pstrdup(db_owner), pstrdup(dbo))); @@ -1299,6 +1324,7 @@ create_database_roles_for_all_dbs(PG_FUNCTION_ARGS) Node *stmt; const char *db_owner; const char *db_accessadmin; + const char *db_securityadmin; const char *old_createrole_self_grant = GetConfigOption("createrole_self_grant", false, true); int i = 0; int save_sec_context = 0; @@ -1308,12 +1334,16 @@ create_database_roles_for_all_dbs(PG_FUNCTION_ARGS) dbname = text_to_cstring(&(bbf_db->name)); db_owner = get_db_owner_name(dbname); db_accessadmin = get_db_accessadmin_role_name(dbname); + db_securityadmin = get_db_securityadmin_role_name(dbname); initStringInfo(&query); appendStringInfo(&query, "CREATE ROLE dummy ROLE dummy; "); appendStringInfo(&query, "GRANT CREATE ON DATABASE dummy TO dummy; "); + 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); stmt = parsetree_nth_stmt(parsetree_list, i++); @@ -1322,6 +1352,12 @@ create_database_roles_for_all_dbs(PG_FUNCTION_ARGS) stmt = parsetree_nth_stmt(parsetree_list, i++); update_GrantStmt(stmt, get_database_name(MyDatabaseId), NULL, db_accessadmin, NULL); + stmt = parsetree_nth_stmt(parsetree_list, i++); + update_CreateRoleStmt(stmt, db_securityadmin, db_owner, NULL); + + stmt = parsetree_nth_stmt(parsetree_list, i++); + update_GrantStmt(stmt, get_database_name(MyDatabaseId), NULL, db_securityadmin, NULL); + GetUserIdAndSecContext(&save_userid, &save_sec_context); PG_TRY(); diff --git a/contrib/babelfishpg_tsql/src/multidb.c b/contrib/babelfishpg_tsql/src/multidb.c index 7ad0c379be..08df76fa24 100644 --- a/contrib/babelfishpg_tsql/src/multidb.c +++ b/contrib/babelfishpg_tsql/src/multidb.c @@ -276,7 +276,8 @@ rewrite_object_refs(Node *stmt) /* Forbidden the use of some special principals */ if (strcmp(principal_name, "dbo") == 0 || strcmp(principal_name, "db_owner") == 0 || - strcmp(principal_name, DB_ACCESSADMIN) == 0) + strcmp(principal_name, DB_ACCESSADMIN) == 0 || + strcmp(principal_name, DB_SECURITYADMIN) == 0) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("Cannot use the special principal '%s'", principal_name))); @@ -402,7 +403,8 @@ rewrite_object_refs(Node *stmt) if (strcmp(user_name, "dbo") == 0 || strcmp(user_name, "db_owner") == 0 || strcmp(user_name, "guest") == 0 || - strcmp(user_name, DB_ACCESSADMIN) == 0) + strcmp(user_name, DB_ACCESSADMIN) == 0 || + strcmp(user_name, DB_SECURITYADMIN) == 0) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("Cannot alter the user %s", user_name))); @@ -1324,7 +1326,8 @@ get_physical_user_name(char *db_name, char *user_name, bool suppress_error) { if ((strlen(user_name) == 3 && strncmp(user_name, "dbo", 3) == 0) || (strlen(user_name) == 8 && strncmp(user_name, "db_owner", 8) == 0) || - (strlen(user_name) == 14 && strncmp(user_name, DB_ACCESSADMIN, 14) == 0)) + (strlen(user_name) == 14 && strncmp(user_name, DB_ACCESSADMIN, 14) == 0) || + (strlen(user_name) == 16 && strncmp(user_name, DB_SECURITYADMIN, 16) == 0)) { return new_user_name; } @@ -1443,6 +1446,21 @@ get_db_accessadmin_role_name(const char *dbname) return name; } +char * +get_db_securityadmin_role_name(const char *dbname) +{ + char *name = palloc0(MAX_BBF_NAMEDATALEND); + + if (get_migration_mode() == SINGLE_DB && strcmp(dbname, "master") != 0 + && strcmp(dbname, "tempdb") != 0 && strcmp(dbname, "msdb") != 0) + snprintf(name, MAX_BBF_NAMEDATALEND, "%s", DB_SECURITYADMIN); + else + snprintf(name, MAX_BBF_NAMEDATALEND, "%s_%s", dbname, DB_SECURITYADMIN); + + truncate_identifier(name, strlen(name), false); + return name; +} + const char * get_guest_schema_name(const char *dbname) { diff --git a/contrib/babelfishpg_tsql/src/multidb.h b/contrib/babelfishpg_tsql/src/multidb.h index d74efe1a26..908219787c 100644 --- a/contrib/babelfishpg_tsql/src/multidb.h +++ b/contrib/babelfishpg_tsql/src/multidb.h @@ -25,6 +25,7 @@ extern const char *get_dbo_role_name(const char *dbname); extern const char *get_db_owner_name(const char *dbname); extern const char *get_guest_role_name(const char *dbname); extern char *get_db_accessadmin_role_name(const char *dbname); +extern char *get_db_securityadmin_role_name(const char *dbname); extern const char *get_guest_schema_name(const char *dbname); extern bool is_shared_schema(const char *name); extern void truncate_tsql_identifier(char *ident); diff --git a/contrib/babelfishpg_tsql/src/pl_exec-2.c b/contrib/babelfishpg_tsql/src/pl_exec-2.c index d06b89eff0..bdd561e7f1 100644 --- a/contrib/babelfishpg_tsql/src/pl_exec-2.c +++ b/contrib/babelfishpg_tsql/src/pl_exec-2.c @@ -3761,7 +3761,9 @@ exec_stmt_grantschema(PLtsql_execstate *estate, PLtsql_stmt_grantschema *stmt) role_oid = get_role_oid(rolname, true); /* Special database roles should throw an error. */ - if (strcmp(grantee_name, "db_owner") == 0 || strcmp(grantee_name, DB_ACCESSADMIN) == 0) + if (strcmp(grantee_name, "db_owner") == 0 || + strcmp(grantee_name, DB_ACCESSADMIN) == 0 || + strcmp(grantee_name, DB_SECURITYADMIN) == 0) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("Cannot grant, deny or revoke permissions to or from special roles."))); diff --git a/contrib/babelfishpg_tsql/src/pl_handler.c b/contrib/babelfishpg_tsql/src/pl_handler.c index 908fbe3c48..16fb3b6efa 100644 --- a/contrib/babelfishpg_tsql/src/pl_handler.c +++ b/contrib/babelfishpg_tsql/src/pl_handler.c @@ -2928,13 +2928,16 @@ bbf_ProcessUtility(PlannedStmt *pstmt, const char *current_db_name = get_cur_db_name(); const char *db_owner_name = get_db_owner_name(current_db_name); const char *db_accessadmin_role = get_db_accessadmin_role_name(current_db_name); + const char *db_securityadmin_role = get_db_accessadmin_role_name(current_db_name); if (has_privs_of_role(GetUserId(), get_role_oid(db_owner_name, false)) || - (isuser && has_privs_of_role(GetUserId(), get_role_oid(db_accessadmin_role, false)))) + (isuser && has_privs_of_role(GetUserId(), get_role_oid(db_accessadmin_role, false))) || + (isrole && has_privs_of_role(GetUserId(), get_role_oid(db_securityadmin_role, false)))) { /* * members of db_owner can create roles and users * members of db_accessadmin can only create users + * members of db_securityadmin can only create db roles */ } else @@ -3218,10 +3221,12 @@ bbf_ProcessUtility(PlannedStmt *pstmt, char *db_name = get_cur_db_name(); bool is_member_of_db_owner = false; bool is_member_of_db_accessadmin = false; + bool is_member_of_db_securityadmin = false; int save_sec_context; Oid save_userid; Oid db_owner = get_role_oid(get_db_owner_name(db_name), false); Oid db_accessadmin = get_role_oid(get_db_accessadmin_role_name(db_name), false); + Oid db_securityadmin = get_role_oid(get_db_securityadmin_role_name(db_name), false); Oid user_name = get_role_oid(stmt->role->rolename, false); /* db principal being altered should be a user or role in the current active logical database */ @@ -3235,6 +3240,9 @@ bbf_ProcessUtility(PlannedStmt *pstmt, if (!is_member_of_db_owner && isuser) is_member_of_db_accessadmin = has_privs_of_role(GetUserId(), db_accessadmin); + if (!is_member_of_db_owner && isrole) + is_member_of_db_securityadmin = has_privs_of_role(GetUserId(), db_securityadmin); + /* * Check if the current user has privileges. */ @@ -3262,11 +3270,13 @@ bbf_ProcessUtility(PlannedStmt *pstmt, else if (strcmp(defel->defname, "rename") == 0) { if (is_member_of_db_owner || (isuser && is_member_of_db_accessadmin && - !has_privs_of_role(user_name, db_owner))) + !has_privs_of_role(user_name, db_owner)) || + (isrole && is_member_of_db_securityadmin && !has_privs_of_role(user_name, 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 + * member of db_securityadmin can rename users who are not members of db_owner */ } else @@ -3377,6 +3387,7 @@ bbf_ProcessUtility(PlannedStmt *pstmt, { Oid db_owner = get_role_oid(get_db_owner_name(db_name), false); Oid db_accessadmin = get_role_oid(get_db_accessadmin_role_name(db_name), false); + Oid db_securityadmin = get_role_oid(get_db_securityadmin_role_name(db_name), false); foreach(item, stmt->roles) { @@ -3404,16 +3415,19 @@ bbf_ProcessUtility(PlannedStmt *pstmt, /* 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) || - (drop_role && rolename_len == 14 && strncmp(rolspec->rolename, DB_ACCESSADMIN, 14) == 0)) + (drop_role && rolename_len == 14 && strncmp(rolspec->rolename, DB_ACCESSADMIN, 14) == 0) || + (drop_role && rolename_len == 16 && strncmp(rolspec->rolename, DB_SECURITYADMIN, 16) == 0)) ereport(ERROR, (errcode(ERRCODE_CHECK_VIOLATION), errmsg("Cannot drop the %s '%s'.", db_principal_type, rolspec->rolename))); - if (has_privs_of_role(GetUserId(), db_owner) || (drop_user && has_privs_of_role(GetUserId(), db_accessadmin))) + if (has_privs_of_role(GetUserId(), db_owner) || (drop_user && has_privs_of_role(GetUserId(), db_accessadmin)) || + (drop_role && has_privs_of_role(GetUserId(), db_securityadmin))) { /* * db_owner can drop any user or role in database * db_accessadmin can drop users in a database + * db_securityadmin can drop roles in a database */ } else @@ -3605,6 +3619,7 @@ bbf_ProcessUtility(PlannedStmt *pstmt, RoleSpec *rolspec = create_schema->authrole; Oid owner_oid = InvalidOid; Oid db_accessadmin = get_role_oid(get_db_accessadmin_role_name(get_cur_db_name()), true); + Oid db_securityadmin = get_role_oid(get_db_securityadmin_role_name(get_cur_db_name()), true); bool alter_owner = false; if (strcmp(queryString, "(CREATE LOGICAL DATABASE )") == 0 @@ -3620,6 +3635,7 @@ bbf_ProcessUtility(PlannedStmt *pstmt, owner_oid = rolspec ? get_rolespec_oid(rolspec, true) : InvalidOid; if (OidIsValid(owner_oid) && OidIsValid(db_accessadmin) && !member_can_set_role(GetUserId(), owner_oid) && has_privs_of_role(GetUserId(), db_accessadmin) && + OidIsValid(db_securityadmin) && has_privs_of_role(GetUserId(), db_securityadmin) && (is_user(owner_oid, true) || is_role(owner_oid, true))) { /* From 92d35c4ab656efbcb98bc3d35a3740b367a798f5 Mon Sep 17 00:00:00 2001 From: Anju Bharti <66729219+anju15bharti@users.noreply.github.com> Date: Thu, 17 Oct 2024 15:53:30 +0530 Subject: [PATCH 17/44] Support Securityadmin fixed server role (#67) Added support for new fixed server role securityadmin. This role has following privileges with it: Members of the securityadmin fixed server role can manage logins and their properties. They can GRANT, DENY, and REVOKE server-level permissions. securityadmin can also GRANT, DENY, and REVOKE database-level permissions if they have access to a database. Original PR with all the comments babelfish-for-postgresql#2907 Issue resolved: BABEL-5040 Signed-off-by: ANJU BHARTI --- .../src/backend/tds/tdsutils.c | 13 +- contrib/babelfishpg_tds/src/include/tds_int.h | 1 + .../babelfishpg_tsql/sql/babelfishpg_tsql.sql | 13 +- contrib/babelfishpg_tsql/sql/ownership.sql | 14 +- .../babelfishpg_tsql/sql/sys_functions.sql | 4 + .../babelfishpg_tsql--4.3.0--4.4.0.sql | 256 ++- .../src/backend_parser/gram-tsql-epilogue.y.c | 21 + .../src/backend_parser/gram-tsql-prologue.y.h | 2 + .../src/backend_parser/gram-tsql-rule.y | 14 +- contrib/babelfishpg_tsql/src/catalog.h | 12 + contrib/babelfishpg_tsql/src/pl_exec-2.c | 6 +- contrib/babelfishpg_tsql/src/pl_handler.c | 88 +- contrib/babelfishpg_tsql/src/procedures.c | 96 +- contrib/babelfishpg_tsql/src/rolecmds.c | 48 +- contrib/babelfishpg_tsql/src/rolecmds.h | 1 + test/JDBC/expected/BABEL-2403.out | 4 + test/JDBC/expected/BABEL-LOGIN-USER-EXT.out | 14 +- test/JDBC/expected/BABEL-LOGIN-vu-verify.out | 4 +- .../expected/bbf_role_admin_restrictions.out | 2 +- .../expected/is_srvrolemember-vu-verify.out | 2 +- test/JDBC/expected/is_srvrolemember.out | 2 +- .../securityadmin_role-vu-cleanup.out | 63 + .../securityadmin_role-vu-prepare.out | 90 + .../expected/securityadmin_role-vu-verify.out | 1609 +++++++++++++++++ test/JDBC/expected/single_db/BABEL-2403.out | 4 + .../single_db/BABEL-LOGIN-USER-EXT.out | 14 +- .../sys-server_principals-vu-verify.out | 1 + .../input/securityadmin_role-vu-cleanup.mix | 63 + .../input/securityadmin_role-vu-prepare.mix | 90 + .../input/securityadmin_role-vu-verify.mix | 907 ++++++++++ test/JDBC/upgrade/15_5/schedule | 2 +- test/JDBC/upgrade/15_6/schedule | 2 +- test/JDBC/upgrade/15_7/schedule | 2 +- test/JDBC/upgrade/15_8/schedule | 2 +- test/JDBC/upgrade/15_9/schedule | 1 + test/JDBC/upgrade/16_1/schedule | 1 + test/JDBC/upgrade/16_2/schedule | 2 +- test/JDBC/upgrade/16_3/schedule | 1 + test/JDBC/upgrade/16_4/schedule | 1 + test/JDBC/upgrade/latest/schedule | 1 + .../expected_dependency.out | 1 + 41 files changed, 3332 insertions(+), 142 deletions(-) create mode 100644 test/JDBC/expected/securityadmin_role-vu-cleanup.out create mode 100644 test/JDBC/expected/securityadmin_role-vu-prepare.out create mode 100644 test/JDBC/expected/securityadmin_role-vu-verify.out create mode 100644 test/JDBC/input/securityadmin_role-vu-cleanup.mix create mode 100644 test/JDBC/input/securityadmin_role-vu-prepare.mix create mode 100644 test/JDBC/input/securityadmin_role-vu-verify.mix diff --git a/contrib/babelfishpg_tds/src/backend/tds/tdsutils.c b/contrib/babelfishpg_tds/src/backend/tds/tdsutils.c index dff1e6d58f..01e9c5a465 100644 --- a/contrib/babelfishpg_tds/src/backend/tds/tdsutils.c +++ b/contrib/babelfishpg_tds/src/backend/tds/tdsutils.c @@ -939,14 +939,17 @@ is_babelfish_role(const char *role) Oid bbf_master_guest_oid; Oid bbf_tempdb_guest_oid; Oid bbf_msdb_guest_oid; + Oid securityadmin_oid; sysadmin_oid = get_role_oid(BABELFISH_SYSADMIN, true); /* missing OK */ role_oid = get_role_oid(role, true); /* missing OK */ + securityadmin_oid = get_role_oid(BABELFISH_SECURITYADMIN, true); /* missing OK */ if (!OidIsValid(sysadmin_oid) || !OidIsValid(role_oid)) return false; if (is_member_of_role(sysadmin_oid, role_oid) || + is_member_of_role(securityadmin_oid, role_oid) || pg_strcasecmp(role, BABELFISH_ROLE_ADMIN) == 0) /* check if it is bbf_role_admin */ return true; @@ -1204,11 +1207,13 @@ handle_grant_role(GrantRoleStmt *grant_stmt) { ListCell *item; Oid bbf_role_admin_oid = InvalidOid; + Oid securityadmin_oid = InvalidOid; if (MyProcPort->is_tds_conn && sql_dialect == SQL_DIALECT_TSQL) return true; bbf_role_admin_oid = get_role_oid(BABELFISH_ROLE_ADMIN, false); + securityadmin_oid = get_role_oid(BABELFISH_SECURITYADMIN, false); /* * Allow GRANT ROLE if current user is bbf_role_admin as we need @@ -1218,7 +1223,7 @@ handle_grant_role(GrantRoleStmt *grant_stmt) if (bbf_role_admin_oid == GetUserId()) return true; - /* Restrict roles to added as a member of bbf_role_admin */ + /* Restrict roles to added as a member of bbf_role_admin/securityadmin */ foreach(item, grant_stmt->granted_roles) { AccessPriv *priv = (AccessPriv *) lfirst(item); @@ -1229,18 +1234,18 @@ handle_grant_role(GrantRoleStmt *grant_stmt) continue; roleid = get_role_oid(rolename, false); - if (OidIsValid(roleid) && roleid == bbf_role_admin_oid) + if (OidIsValid(roleid) && (roleid == bbf_role_admin_oid || roleid == securityadmin_oid)) check_babelfish_alterrole_restictions(false); } - /* Restrict grant to/from bbf_role_admin role */ + /* Restrict grant to/from bbf_role_admin/securityadmin role */ foreach(item, grant_stmt->grantee_roles) { RoleSpec *rolespec = lfirst_node(RoleSpec, item); Oid roleid; roleid = get_rolespec_oid(rolespec, false); - if (OidIsValid(roleid) && roleid == bbf_role_admin_oid) + if (OidIsValid(roleid) && (roleid == bbf_role_admin_oid || roleid == securityadmin_oid)) check_babelfish_alterrole_restictions(false); } diff --git a/contrib/babelfishpg_tds/src/include/tds_int.h b/contrib/babelfishpg_tds/src/include/tds_int.h index 5b7943d201..30894728d7 100644 --- a/contrib/babelfishpg_tds/src/include/tds_int.h +++ b/contrib/babelfishpg_tds/src/include/tds_int.h @@ -256,6 +256,7 @@ extern ProcessUtility_hook_type next_ProcessUtility; #define PUBLIC_ROLE_NAME "public" #define BABELFISH_SYSADMIN "sysadmin" #define BABELFISH_ROLE_ADMIN "bbf_role_admin" +#define BABELFISH_SECURITYADMIN "securityadmin" /* Functions in backend/tds/tdscomm.c */ extern void TdsSetMessageType(uint8_t msgType); diff --git a/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql b/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql index d9a7f1fd3b..93ec8d8710 100644 --- a/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql +++ b/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql @@ -2060,8 +2060,8 @@ BEGIN ELSIF role = 'public' COLLATE sys.database_default THEN RETURN 1; - ELSIF role = 'sysadmin' COLLATE sys.database_default THEN - has_role = pg_has_role(login::TEXT, role::TEXT, 'MEMBER'); + ELSIF role = 'sysadmin' COLLATE sys.database_default OR role = 'securityadmin' COLLATE sys.database_default THEN + has_role = (pg_has_role(login::TEXT, role::TEXT, 'MEMBER') OR pg_has_role(login::TEXT, 'sysadmin'::TEXT, 'MEMBER')); IF has_role THEN RETURN 1; ELSE @@ -2070,9 +2070,7 @@ BEGIN ELSIF role COLLATE sys.database_default IN ( 'serveradmin', - 'securityadmin', 'setupadmin', - 'securityadmin', 'processadmin', 'dbcreator', 'diskadmin', @@ -2427,7 +2425,12 @@ CAST( ELSE 0 END AS INT) AS sysadmin, -CAST(0 AS INT) AS securityadmin, +CAST( + CASE + WHEN is_srvrolemember('securityadmin', Base.name) = 1 THEN 1 + ELSE 0 + END +AS INT) AS securityadmin, CAST(0 AS INT) AS serveradmin, CAST(0 AS INT) AS setupadmin, CAST(0 AS INT) AS processadmin, diff --git a/contrib/babelfishpg_tsql/sql/ownership.sql b/contrib/babelfishpg_tsql/sql/ownership.sql index dbbda19e43..61f0f5eea9 100644 --- a/contrib/babelfishpg_tsql/sql/ownership.sql +++ b/contrib/babelfishpg_tsql/sql/ownership.sql @@ -259,7 +259,7 @@ CREATE OR REPLACE PROCEDURE initialize_babelfish ( sa_name VARCHAR(128) ) LANGUAGE plpgsql AS $$ DECLARE - reserved_roles varchar[] := ARRAY['sysadmin', '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', 'tempdb_dbo', 'tempdb_guest', 'tempdb_db_owner', 'msdb_dbo', 'msdb_guest', 'msdb_db_owner']; user_id oid := -1; db_name name := NULL; role_name varchar; @@ -285,11 +285,13 @@ BEGIN RAISE E'Could not initialize babelfish with given role name: % is not the DB owner of current database.', sa_name; END IF; + EXECUTE format('CREATE ROLE securityadmin CREATEROLE INHERIT PASSWORD NULL'); EXECUTE format('CREATE ROLE bbf_role_admin CREATEDB CREATEROLE INHERIT PASSWORD NULL'); EXECUTE format('GRANT CREATE ON DATABASE %s TO bbf_role_admin WITH GRANT OPTION', CURRENT_DATABASE()); EXECUTE format('GRANT %I to bbf_role_admin WITH ADMIN TRUE;', sa_name); EXECUTE format('CREATE ROLE sysadmin CREATEDB CREATEROLE INHERIT ROLE %I', sa_name); EXECUTE format('GRANT sysadmin TO bbf_role_admin WITH ADMIN TRUE'); + EXECUTE format('GRANT securityadmin TO bbf_role_admin WITH ADMIN TRUE'); EXECUTE format('GRANT USAGE, SELECT ON SEQUENCE sys.babelfish_partition_function_seq TO sysadmin WITH GRANT OPTION'); EXECUTE format('GRANT USAGE, SELECT ON SEQUENCE sys.babelfish_partition_scheme_seq TO sysadmin WITH GRANT OPTION'); EXECUTE format('GRANT USAGE, SELECT ON SEQUENCE sys.babelfish_db_seq TO sysadmin WITH GRANT OPTION'); @@ -299,6 +301,7 @@ BEGIN CALL sys.babel_initialize_logins(sa_name); CALL sys.babel_initialize_logins('sysadmin'); CALL sys.babel_initialize_logins('bbf_role_admin'); + CALL sys.babel_initialize_logins('securityadmin'); CALL sys.babel_create_builtin_dbs(sa_name); CALL sys.initialize_babel_extras(); -- run analyze for all babelfish catalog @@ -320,6 +323,8 @@ BEGIN DROP ROLE sysadmin; DROP OWNED BY bbf_role_admin; DROP ROLE bbf_role_admin; + DROP OWNED BY securityadmin; + DROP ROLE securityadmin; END $$; @@ -365,7 +370,8 @@ CAST(CASE WHEN Ext.type = 'R' THEN NULL ELSE Ext.credential_id END AS INT) AS cr CAST(CASE WHEN Ext.type = 'R' THEN 1 ELSE Ext.owning_principal_id END AS INT) AS owning_principal_id, CAST(CASE WHEN Ext.type = 'R' THEN 1 ELSE Ext.is_fixed_role END AS sys.BIT) AS is_fixed_role FROM pg_catalog.pg_roles AS Base INNER JOIN sys.babelfish_authid_login_ext AS Ext ON Base.rolname = Ext.rolname -WHERE (pg_has_role(suser_id(), 'sysadmin'::TEXT, 'MEMBER') +WHERE (pg_has_role(suser_id(), 'sysadmin'::TEXT, 'MEMBER') + OR pg_has_role(suser_id(), 'securityadmin'::TEXT, 'MEMBER') OR Ext.orig_loginname = suser_name() OR Ext.orig_loginname = (SELECT pg_get_userbyid(datdba) FROM pg_database WHERE datname = CURRENT_DATABASE()) COLLATE sys.database_default OR Ext.type = 'R') @@ -501,8 +507,8 @@ CAST(Ext.orig_loginname AS sys.nvarchar(128)) AS name, CAST('SERVER ROLE' AS sys.nvarchar(128)) AS type, CAST ('GRANT OR DENY' as sys.nvarchar(128)) as usage FROM pg_catalog.pg_roles AS Base INNER JOIN sys.babelfish_authid_login_ext AS Ext ON Base.rolname = Ext.rolname -WHERE Ext.type = 'R' AND -(pg_has_role(sys.suser_id(), 'sysadmin'::TEXT, 'MEMBER')); +WHERE Ext.type = 'R' +AND bbf_is_member_of_role_nosuper(sys.suser_id(), Base.oid); GRANT SELECT ON sys.login_token TO PUBLIC; diff --git a/contrib/babelfishpg_tsql/sql/sys_functions.sql b/contrib/babelfishpg_tsql/sql/sys_functions.sql index e66e6b61f5..d45dd0dd61 100644 --- a/contrib/babelfishpg_tsql/sql/sys_functions.sql +++ b/contrib/babelfishpg_tsql/sql/sys_functions.sql @@ -4530,6 +4530,10 @@ $$ $$ LANGUAGE SQL STRICT STABLE PARALLEL SAFE; +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; + CREATE OR REPLACE FUNCTION sys.replace (input_string sys.VARCHAR, pattern sys.VARCHAR, replacement sys.VARCHAR) RETURNS sys.VARCHAR AS $BODY$ diff --git a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.3.0--4.4.0.sql b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.3.0--4.4.0.sql index 4d64b65913..2c081c7f3e 100644 --- a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.3.0--4.4.0.sql +++ b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.3.0--4.4.0.sql @@ -70,6 +70,211 @@ EXCEPTION WHEN OTHERS THEN END; $$; +DO +LANGUAGE plpgsql +$$ +DECLARE securityadmin TEXT; +BEGIN + IF EXISTS ( + SELECT FROM pg_catalog.pg_roles + WHERE rolname = 'securityadmin') + THEN + RAISE EXCEPTION 'Role "securityadmin" already exists.'; + ELSE + EXECUTE format('CREATE ROLE securityadmin CREATEROLE INHERIT PASSWORD NULL'); + EXECUTE format('GRANT securityadmin TO bbf_role_admin WITH ADMIN TRUE'); + CALL sys.babel_initialize_logins('securityadmin'); + END IF; +END; +$$; + +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; + +-- SERVER_PRINCIPALS +CREATE OR REPLACE VIEW sys.server_principals +AS SELECT +CAST(Ext.orig_loginname AS sys.SYSNAME) AS name, +CAST(Base.oid As INT) AS principal_id, +CAST(CAST(Base.oid as INT) as sys.varbinary(85)) AS sid, +CAST(Ext.type AS CHAR(1)) as type, +CAST( + CASE + WHEN Ext.type = 'S' THEN 'SQL_LOGIN' + WHEN Ext.type = 'R' THEN 'SERVER_ROLE' + WHEN Ext.type = 'U' THEN 'WINDOWS_LOGIN' + ELSE NULL + END + AS NVARCHAR(60)) AS type_desc, +CAST(Ext.is_disabled AS INT) AS is_disabled, +CAST(Ext.create_date AS SYS.DATETIME) AS create_date, +CAST(Ext.modify_date AS SYS.DATETIME) AS modify_date, +CAST(CASE WHEN Ext.type = 'R' THEN NULL ELSE Ext.default_database_name END AS SYS.SYSNAME) AS default_database_name, +CAST(Ext.default_language_name AS SYS.SYSNAME) AS default_language_name, +CAST(CASE WHEN Ext.type = 'R' THEN NULL ELSE Ext.credential_id END AS INT) AS credential_id, +CAST(CASE WHEN Ext.type = 'R' THEN 1 ELSE Ext.owning_principal_id END AS INT) AS owning_principal_id, +CAST(CASE WHEN Ext.type = 'R' THEN 1 ELSE Ext.is_fixed_role END AS sys.BIT) AS is_fixed_role +FROM pg_catalog.pg_roles AS Base INNER JOIN sys.babelfish_authid_login_ext AS Ext ON Base.rolname = Ext.rolname +WHERE (pg_has_role(suser_id(), 'sysadmin'::TEXT, 'MEMBER') + OR pg_has_role(suser_id(), 'securityadmin'::TEXT, 'MEMBER') + OR Ext.orig_loginname = suser_name() + OR Ext.orig_loginname = (SELECT pg_get_userbyid(datdba) FROM pg_database WHERE datname = CURRENT_DATABASE()) COLLATE sys.database_default + OR Ext.type = 'R') + AND Ext.type != 'Z' +UNION ALL +SELECT +CAST('public' AS SYS.SYSNAME) AS name, +CAST(-1 AS INT) AS principal_id, +CAST(CAST(0 as INT) as sys.varbinary(85)) AS sid, +CAST('R' AS CHAR(1)) as type, +CAST('SERVER_ROLE' AS NVARCHAR(60)) AS type_desc, +CAST(0 AS INT) AS is_disabled, +CAST(NULL AS SYS.DATETIME) AS create_date, +CAST(NULL AS SYS.DATETIME) AS modify_date, +CAST(NULL AS SYS.SYSNAME) AS default_database_name, +CAST(NULL AS SYS.SYSNAME) AS default_language_name, +CAST(NULL AS INT) AS credential_id, +CAST(1 AS INT) AS owning_principal_id, +CAST(0 AS sys.BIT) AS is_fixed_role; + +GRANT SELECT ON sys.server_principals TO PUBLIC; + +-- login_token +CREATE OR REPLACE VIEW sys.login_token +AS SELECT +CAST(Base.oid As INT) AS principal_id, +CAST(CAST(Base.oid as INT) as sys.varbinary(85)) AS sid, +CAST(Ext.orig_loginname AS sys.nvarchar(128)) AS name, +CAST(CASE +WHEN Ext.type = 'U' THEN 'WINDOWS LOGIN' +ELSE 'SQL LOGIN' END AS SYS.NVARCHAR(128)) AS TYPE, +CAST('GRANT OR DENY' as sys.nvarchar(128)) as usage +FROM pg_catalog.pg_roles AS Base INNER JOIN sys.babelfish_authid_login_ext AS Ext ON Base.rolname = Ext.rolname +WHERE Ext.orig_loginname = sys.suser_name() +AND Ext.type in ('S','U') +UNION ALL +SELECT +CAST(Base.oid As INT) AS principal_id, +CAST(CAST(Base.oid as INT) as sys.varbinary(85)) AS sid, +CAST(Ext.orig_loginname AS sys.nvarchar(128)) AS name, +CAST('SERVER ROLE' AS sys.nvarchar(128)) AS type, +CAST ('GRANT OR DENY' as sys.nvarchar(128)) as usage +FROM pg_catalog.pg_roles AS Base INNER JOIN sys.babelfish_authid_login_ext AS Ext ON Base.rolname = Ext.rolname +WHERE Ext.type = 'R' +AND bbf_is_member_of_role_nosuper(sys.suser_id(), Base.oid); + +GRANT SELECT ON sys.login_token TO PUBLIC; + +CREATE OR REPLACE FUNCTION is_srvrolemember(role sys.SYSNAME, login sys.SYSNAME DEFAULT suser_name()) +RETURNS INTEGER AS +$$ +DECLARE has_role BOOLEAN; +DECLARE login_valid BOOLEAN; +BEGIN + role := TRIM(trailing from LOWER(role)); + login := TRIM(trailing from LOWER(login)); + + login_valid = (login = suser_name() COLLATE sys.database_default) OR + (EXISTS (SELECT name + FROM sys.server_principals + WHERE + LOWER(name) = login COLLATE sys.database_default + AND type = 'S')); + + IF NOT login_valid THEN + RETURN NULL; + + ELSIF role = 'public' COLLATE sys.database_default THEN + RETURN 1; + + ELSIF role = 'sysadmin' COLLATE sys.database_default OR role = 'securityadmin' COLLATE sys.database_default THEN + has_role = (pg_has_role(login::TEXT, role::TEXT, 'MEMBER') OR pg_has_role(login::TEXT, 'sysadmin'::TEXT, 'MEMBER')); + IF has_role THEN + RETURN 1; + ELSE + RETURN 0; + END IF; + + ELSIF role COLLATE sys.database_default IN ( + 'serveradmin', + 'setupadmin', + 'processadmin', + 'dbcreator', + 'diskadmin', + 'bulkadmin') THEN + RETURN 0; + + ELSE + RETURN NULL; + END IF; + + EXCEPTION WHEN OTHERS THEN + RETURN NULL; +END; +$$ LANGUAGE plpgsql STABLE; + +-- SYSLOGINS +CREATE OR REPLACE VIEW sys.syslogins +AS SELECT +Base.sid AS sid, +CAST(9 AS SYS.TINYINT) AS status, +Base.create_date AS createdate, +Base.modify_date AS updatedate, +Base.create_date AS accdate, +CAST(0 AS INT) AS totcpu, +CAST(0 AS INT) AS totio, +CAST(0 AS INT) AS spacelimit, +CAST(0 AS INT) AS timelimit, +CAST(0 AS INT) AS resultlimit, +Base.name AS name, +Base.default_database_name AS dbname, +Base.default_language_name AS default_language_name, +CAST(Base.name AS SYS.NVARCHAR(128)) AS loginname, +CAST(NULL AS SYS.NVARCHAR(128)) AS password, +CAST(0 AS INT) AS denylogin, +CAST(1 AS INT) AS hasaccess, +CAST( + CASE + WHEN Base.type_desc = 'WINDOWS_LOGIN' OR Base.type_desc = 'WINDOWS_GROUP' THEN 1 + ELSE 0 + END +AS INT) AS isntname, +CAST( + CASE + WHEN Base.type_desc = 'WINDOWS_GROUP' THEN 1 + ELSE 0 + END + AS INT) AS isntgroup, +CAST( + CASE + WHEN Base.type_desc = 'WINDOWS_LOGIN' THEN 1 + ELSE 0 + END +AS INT) AS isntuser, +CAST( + CASE + WHEN is_srvrolemember('sysadmin', Base.name) = 1 THEN 1 + ELSE 0 + END +AS INT) AS sysadmin, +CAST( + CASE + WHEN is_srvrolemember('securityadmin', Base.name) = 1 THEN 1 + ELSE 0 + END +AS INT) AS securityadmin, +CAST(0 AS INT) AS serveradmin, +CAST(0 AS INT) AS setupadmin, +CAST(0 AS INT) AS processadmin, +CAST(0 AS INT) AS diskadmin, +CAST(0 AS INT) AS dbcreator, +CAST(0 AS INT) AS bulkadmin +FROM sys.server_principals AS Base +WHERE Base.type in ('S', 'U'); + +GRANT SELECT ON sys.syslogins TO PUBLIC; + CREATE OR REPLACE VIEW sys.configurations AS SELECT configuration_id, @@ -136,6 +341,7 @@ SELECT c.value_in_use AS value, END AS status FROM sys.configurations c LEFT JOIN sys.babelfish_configurations b ON c.configuration_id = b.configuration_id; GRANT SELECT ON sys.sysconfigures TO PUBLIC; + -- Assigning dbo role to the db_owner login DO $$ DECLARE @@ -1707,56 +1913,6 @@ FROM pg_catalog.pg_class t1 JOIN information_schema.table_privileges t4 ON t1.relname = t4.table_name WHERE t4.privilege_type = 'DELETE'; -CREATE OR REPLACE FUNCTION is_srvrolemember(role sys.SYSNAME, login sys.SYSNAME DEFAULT suser_name()) -RETURNS INTEGER AS -$$ -DECLARE has_role BOOLEAN; -DECLARE login_valid BOOLEAN; -BEGIN - role := TRIM(trailing from LOWER(role)); - login := TRIM(trailing from LOWER(login)); - - login_valid = (login = suser_name() COLLATE sys.database_default) OR - (EXISTS (SELECT name - FROM sys.server_principals - WHERE - LOWER(name) = login COLLATE sys.database_default - AND type = 'S')); - - IF NOT login_valid THEN - RETURN NULL; - - ELSIF role = 'public' COLLATE sys.database_default THEN - RETURN 1; - - ELSIF role = 'sysadmin' COLLATE sys.database_default THEN - has_role = pg_has_role(login::TEXT, role::TEXT, 'MEMBER'); - IF has_role THEN - RETURN 1; - ELSE - RETURN 0; - END IF; - - ELSIF role COLLATE sys.database_default IN ( - 'serveradmin', - 'securityadmin', - 'setupadmin', - 'securityadmin', - 'processadmin', - 'dbcreator', - 'diskadmin', - 'bulkadmin') THEN - RETURN 0; - - ELSE - RETURN NULL; - END IF; - - EXCEPTION WHEN OTHERS THEN - RETURN NULL; -END; -$$ LANGUAGE plpgsql STABLE; - CREATE OR REPLACE PROCEDURE sys.sp_helpuser("@name_in_db" sys.SYSNAME = NULL) AS $$ BEGIN diff --git a/contrib/babelfishpg_tsql/src/backend_parser/gram-tsql-epilogue.y.c b/contrib/babelfishpg_tsql/src/backend_parser/gram-tsql-epilogue.y.c index 2fea1ee6ee..ad5bdf8295 100644 --- a/contrib/babelfishpg_tsql/src/backend_parser/gram-tsql-epilogue.y.c +++ b/contrib/babelfishpg_tsql/src/backend_parser/gram-tsql-epilogue.y.c @@ -2048,3 +2048,24 @@ tsql_index_nulls_order(List *indexParams, const char *accessMethod) } } } + +static void +check_server_role_and_throw_if_unsupported (const char *serverrole, int position, core_yyscan_t yyscanner) +{ + if (strcmp(serverrole, "serveradmin") == 0 + || strcmp(serverrole, "setupadmin") == 0 + || strcmp(serverrole, "processadmin") == 0 + || strcmp(serverrole, "diskadmin") == 0 + || strcmp(serverrole, "bulkadmin") == 0) + { + ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("Fixed server role '%s' is currently not supported in Babelfish", serverrole), + parser_errposition(position))); + } + else if (!IS_ROLENAME_SYSADMIN(serverrole) && !IS_ROLENAME_SECURITYADMIN(serverrole)) + { + ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("Only fixed server role is supported in ALTER SERVER ROLE statement"), + parser_errposition(position))); + } +} diff --git a/contrib/babelfishpg_tsql/src/backend_parser/gram-tsql-prologue.y.h b/contrib/babelfishpg_tsql/src/backend_parser/gram-tsql-prologue.y.h index 868cf6762c..10495fc466 100644 --- a/contrib/babelfishpg_tsql/src/backend_parser/gram-tsql-prologue.y.h +++ b/contrib/babelfishpg_tsql/src/backend_parser/gram-tsql-prologue.y.h @@ -14,6 +14,7 @@ #include "src/backend_parser/gramparse.h" #include "src/pltsql_instr.h" +#include "src/catalog.h" #include "src/multidb.h" #include "src/tsql_for/tsql_for.h" @@ -92,3 +93,4 @@ static Node *tsql_update_output_into_cte_transformation(WithClause *opt_with_cla static List *get_transformed_output_list(List *tsql_output_clause); static bool returning_list_has_column_name(List *existing_colnames, char *current_colname); static void tsql_index_nulls_order(List *indexParams, const char *accessMethod); +static void check_server_role_and_throw_if_unsupported(const char* serverrole, int position, core_yyscan_t yyscanner); diff --git a/contrib/babelfishpg_tsql/src/backend_parser/gram-tsql-rule.y b/contrib/babelfishpg_tsql/src/backend_parser/gram-tsql-rule.y index 8c96005ef7..a0170ceb6d 100644 --- a/contrib/babelfishpg_tsql/src/backend_parser/gram-tsql-rule.y +++ b/contrib/babelfishpg_tsql/src/backend_parser/gram-tsql-rule.y @@ -3127,12 +3127,9 @@ tsql_alter_server_role: { GrantRoleStmt *n = makeNode(GrantRoleStmt); AccessPriv *ap = makeNode(AccessPriv); - - if (0 != strcmp($4, "sysadmin")) - ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("only sysadmin role is supported in ALTER SERVER ROLE statement"), - parser_errposition(@4))); + check_server_role_and_throw_if_unsupported($4, @4, yyscanner); + ap->priv_name = $4; n->is_grant = true; n->granted_roles = list_make1(ap); @@ -3145,11 +3142,8 @@ tsql_alter_server_role: { GrantRoleStmt *n = makeNode(GrantRoleStmt); AccessPriv *ap = makeNode(AccessPriv); - - if (0 != strcmp($4, "sysadmin")) - ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("only sysadmin role is supported in ALTER SERVER ROLE statement"), - parser_errposition(@4))); + + check_server_role_and_throw_if_unsupported($4, @4, yyscanner); ap->priv_name = $4; n->is_grant = false; diff --git a/contrib/babelfishpg_tsql/src/catalog.h b/contrib/babelfishpg_tsql/src/catalog.h index ff0248c9fb..05e3b1d44b 100644 --- a/contrib/babelfishpg_tsql/src/catalog.h +++ b/contrib/babelfishpg_tsql/src/catalog.h @@ -313,6 +313,8 @@ typedef FormData_bbf_function_ext *Form_bbf_function_ext; #define Anum_bbf_schema_perms_grantor 8 #define PUBLIC_ROLE_NAME "public" +#define BABELFISH_SECURITYADMIN "securityadmin" +#define BABELFISH_SYSADMIN "sysadmin" #define PERMISSIONS_FOR_ALL_OBJECTS_IN_SCHEMA "ALL" #define ALL_PERMISSIONS_ON_RELATION 47 /* last 6 bits as 101111 represents ALL privileges on a relation. */ #define ALL_PERMISSIONS_ON_FUNCTION 128 /* last 8 bits as 10000000 represents ALL privileges on a procedure/function. */ @@ -322,6 +324,16 @@ typedef FormData_bbf_function_ext *Form_bbf_function_ext; #define OBJ_FUNCTION "f" #define NUMBER_OF_PERMISSIONS 6 +/* check if rolename is sysadmin */ +#define IS_ROLENAME_SYSADMIN(rolname) \ + (strlen(rolname) == 8 && \ + strncmp(rolname, BABELFISH_SYSADMIN, 8) == 0) + +/* check if rolename is securityadmin */ +#define IS_ROLENAME_SECURITYADMIN(rolname) \ + (strlen(rolname) == 13 && \ + strncmp(rolname, BABELFISH_SECURITYADMIN, 13) == 0) + extern int permissions[]; extern Oid bbf_schema_perms_oid; diff --git a/contrib/babelfishpg_tsql/src/pl_exec-2.c b/contrib/babelfishpg_tsql/src/pl_exec-2.c index 691caabecf..68cf22477a 100644 --- a/contrib/babelfishpg_tsql/src/pl_exec-2.c +++ b/contrib/babelfishpg_tsql/src/pl_exec-2.c @@ -22,6 +22,7 @@ #include "catalog.h" #include "dbcmds.h" +#include "rolecmds.h" #include "pl_explain.h" #include "pltsql.h" #include "rolecmds.h" @@ -3015,11 +3016,12 @@ exec_stmt_grantdb(PLtsql_execstate *estate, PLtsql_stmt_grantdb *stmt) /* * If the login is not the db owner or the login is not the member of - * sysadmin, then it doesn't have the permission to GRANT/REVOKE. + * sysadmin or securityadmin, then it doesn't have the permission to GRANT/REVOKE. */ login_is_db_owner = 0 == strncmp(login, get_owner_of_db(dbname), NAMEDATALEN); datdba = get_role_oid("sysadmin", false); - if (!is_member_of_role(GetSessionUserId(), datdba) && !login_is_db_owner) + if (!is_member_of_role(GetSessionUserId(), datdba) && !login_is_db_owner + && !is_member_of_role(GetSessionUserId(), get_securityadmin_oid())) ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), errmsg("Grantor does not have GRANT permission."))); diff --git a/contrib/babelfishpg_tsql/src/pl_handler.c b/contrib/babelfishpg_tsql/src/pl_handler.c index 5ce705352c..9be5bff532 100644 --- a/contrib/babelfishpg_tsql/src/pl_handler.c +++ b/contrib/babelfishpg_tsql/src/pl_handler.c @@ -2983,7 +2983,12 @@ bbf_ProcessUtility(PlannedStmt *pstmt, if (islogin) { - if (!has_privs_of_role(GetSessionUserId(), get_role_oid("sysadmin", false))) + /* + * Check if the current login has privileges to create + * login. + */ + if (!has_privs_of_role(GetSessionUserId(), get_sysadmin_oid()) && + !has_privs_of_role(GetSessionUserId(), get_securityadmin_oid())) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("Current login %s does not have permission to create new login", @@ -3187,8 +3192,12 @@ bbf_ProcessUtility(PlannedStmt *pstmt, char *temp_login_name = NULL; Oid save_userid; int save_sec_context; + Oid securityadm_oid; + Oid role_oid; - datdba = get_role_oid("sysadmin", false); + datdba = get_sysadmin_oid(); + securityadm_oid = get_securityadmin_oid(); + role_oid = get_role_oid(stmt->role->rolename, true); /* * Check if the current login has privileges to alter @@ -3200,7 +3209,8 @@ bbf_ProcessUtility(PlannedStmt *pstmt, if (strcmp(defel->defname, "password") == 0) { - if (get_role_oid(stmt->role->rolename, true) != GetSessionUserId() && !is_member_of_role(GetSessionUserId(), datdba)) + if (role_oid != GetSessionUserId() && (!is_member_of_role(GetSessionUserId(), datdba) + && (!is_member_of_role(GetSessionUserId(), securityadm_oid) || is_member_of_role(role_oid, datdba)))) ereport(ERROR,(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("Cannot alter the login '%s', because it does not exist or you do not have permission.", stmt->role->rolename))); @@ -3235,14 +3245,21 @@ bbf_ProcessUtility(PlannedStmt *pstmt, stmt->role->rolename = temp_login_name; } - if (!has_privs_of_role(GetSessionUserId(), datdba) && !has_password) - ereport(ERROR,(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("Cannot alter the login '%s', because it does not exist or you do not have permission.", stmt->role->rolename))); + role_oid = get_role_oid(stmt->role->rolename, true); - if (get_role_oid(stmt->role->rolename, true) == InvalidOid) + /* + * Check if login is valid and the current login + * has privileges to alter login. + */ + if (role_oid == InvalidOid) ereport(ERROR, (errcode(ERRCODE_DUPLICATE_OBJECT), errmsg("Cannot drop the login '%s', because it does not exist or you do not have permission.", stmt->role->rolename))); + if (!has_privs_of_role(GetSessionUserId(), datdba) && !has_password && + (!has_privs_of_role(GetSessionUserId(), securityadm_oid) || is_member_of_role(role_oid, datdba))) + ereport(ERROR,(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("Cannot alter the login '%s', because it does not exist or you do not have permission.", stmt->role->rolename))); + /* * We have performed all the permissions checks. * Set current user to bbf_role_admin for alter permissions. @@ -3380,6 +3397,9 @@ bbf_ProcessUtility(PlannedStmt *pstmt, char *db_name; Oid save_userid; int save_sec_context; + Oid securityadmin_oid; + + securityadmin_oid = get_securityadmin_oid(); /* Check if roles are users that need role name mapping */ if (stmt->roles != NIL) @@ -3555,7 +3575,12 @@ bbf_ProcessUtility(PlannedStmt *pstmt, else other = true; - if (drop_login && is_login(roleform->oid) && !has_privs_of_role(GetSessionUserId(), get_role_oid("sysadmin", false))){ + /* + * Check if the current login has privileges to drop + * login. + */ + if (drop_login && is_login(roleform->oid) && !has_privs_of_role(GetSessionUserId(), get_sysadmin_oid()) + && !has_privs_of_role(GetSessionUserId(), securityadmin_oid)){ ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("Cannot drop the login '%s', because it does not exist or you do not have permission.", role_name))); @@ -3575,9 +3600,8 @@ bbf_ProcessUtility(PlannedStmt *pstmt, { int role_oid = get_role_oid(role_name, true); - if (!OidIsValid(role_oid) || - !is_member_of_role(GetSessionUserId(), get_sysadmin_oid()) || - role_oid == get_bbf_role_admin_oid()) + if (!OidIsValid(role_oid) || role_oid == get_bbf_role_admin_oid() + || role_oid == securityadmin_oid || role_oid == get_sysadmin_oid()) ereport(ERROR, (errcode(ERRCODE_DUPLICATE_OBJECT), errmsg("Cannot drop the login '%s', because it does not exist or you do not have permission.", role_name))); @@ -3771,13 +3795,46 @@ bbf_ProcessUtility(PlannedStmt *pstmt, { StringInfoData query; RoleSpec *spec; + RoleSpec *rolspec; + Oid grantee_oid; + check_alter_server_stmt(grant_role); spec = (RoleSpec *) linitial(grant_role->grantee_roles); + rolspec = (RoleSpec *) linitial(grant_role->granted_roles); + grantee_oid = get_role_oid(spec->rolename, false); initStringInfo(&query); - if (grant_role->is_grant) - appendStringInfo(&query, "ALTER ROLE dummy WITH createrole createdb; "); + + /* If sysadmin, provide attribute for role and database priv */ + if (IS_ROLENAME_SYSADMIN(rolspec->rolename)) + { + if (grant_role->is_grant) + appendStringInfo(&query, "ALTER ROLE dummy WITH createrole createdb; "); + + /* If grantee role is member of securityadmin then only revoke createdb */ + else if (has_privs_of_role(grantee_oid, get_securityadmin_oid())) + appendStringInfo(&query, "ALTER ROLE dummy WITH nocreatedb; "); + else + appendStringInfo(&query, "ALTER ROLE dummy WITH nocreaterole nocreatedb; "); + } + + /* If securityadmin, provide attribute for role priv */ + else if (IS_ROLENAME_SECURITYADMIN(rolspec->rolename)) + { + if (grant_role->is_grant) + appendStringInfo(&query, "ALTER ROLE dummy WITH createrole; "); + + /* If grantee role is member of sysadmin then don't revoke createrole */ + else if (!has_privs_of_role(grantee_oid, get_sysadmin_oid())) + appendStringInfo(&query, "ALTER ROLE dummy WITH nocreaterole; "); + } + + /* Otherwise, throw error */ else - appendStringInfo(&query, "ALTER ROLE dummy WITH nocreaterole nocreatedb; "); + { + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("\"%s\" is not a supported fixed server role.", rolspec->rolename))); + } /* * Set to bbf_role_admin to grant the role @@ -3794,7 +3851,8 @@ bbf_ProcessUtility(PlannedStmt *pstmt, else standard_ProcessUtility(pstmt, queryString, readOnlyTree, context, params, queryEnv, dest, qc); - exec_alter_role_cmd(query.data, spec); + if (query.len) + exec_alter_role_cmd(query.data, spec); } PG_FINALLY(); diff --git a/contrib/babelfishpg_tsql/src/procedures.c b/contrib/babelfishpg_tsql/src/procedures.c index 6d95de49f8..0233975bd1 100644 --- a/contrib/babelfishpg_tsql/src/procedures.c +++ b/contrib/babelfishpg_tsql/src/procedures.c @@ -2997,6 +2997,8 @@ sp_addlinkedsrvlogin_internal(PG_FUNCTION_ARGS) char *locallogin = PG_ARGISNULL(2) ? NULL : text_to_cstring(PG_GETARG_VARCHAR_PP(2)); char *username = PG_ARGISNULL(3) ? NULL : text_to_cstring(PG_GETARG_VARCHAR_PP(3)); char *password = PG_ARGISNULL(4) ? NULL : text_to_cstring(PG_GETARG_VARCHAR_PP(4)); + Oid save_userid; + int save_sec_context; StringInfoData query; @@ -3023,6 +3025,16 @@ sp_addlinkedsrvlogin_internal(PG_FUNCTION_ARGS) initStringInfo(&query); + /* + * check privileges for login + * allow if has privileges of sysadmin or securityadmin. + */ + if (!has_privs_of_role(GetSessionUserId(), get_sysadmin_oid()) && + !has_privs_of_role(GetSessionUserId(), get_securityadmin_oid())) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("User does not have permission to perform this action."))); + /* * We prepare the following query to create a user mapping. This will be * executed using ProcessUtility(): @@ -3058,8 +3070,22 @@ sp_addlinkedsrvlogin_internal(PG_FUNCTION_ARGS) appendStringInfoString(&query, ")"); } + /* + * We have performed all the permissions checks. + * Set current user to bbf_role_admin for mapping permissions. + */ + GetUserIdAndSecContext(&save_userid, &save_sec_context); + SetUserIdAndSecContext(get_bbf_role_admin_oid(), save_sec_context | SECURITY_LOCAL_USERID_CHANGE); - exec_utility_cmd_helper(query.data); + PG_TRY(); + { + exec_utility_cmd_helper(query.data); + } + PG_FINALLY(); + { + SetUserIdAndSecContext(save_userid, save_sec_context); + } + PG_END_TRY(); if (servername) pfree(servername); @@ -3083,6 +3109,8 @@ sp_droplinkedsrvlogin_internal(PG_FUNCTION_ARGS) { char *servername = PG_ARGISNULL(0) ? NULL : lowerstr(text_to_cstring(PG_GETARG_VARCHAR_PP(0))); char *locallogin = PG_ARGISNULL(1) ? NULL : text_to_cstring(PG_GETARG_VARCHAR_PP(1)); + Oid save_userid; + int save_sec_context; StringInfoData query; @@ -3103,33 +3131,59 @@ sp_droplinkedsrvlogin_internal(PG_FUNCTION_ARGS) remove_trailing_spaces(servername); + /* + * check privileges for login + * allow if has privileges of sysadmin or securityadmin. + */ + if (!has_privs_of_role(GetSessionUserId(), get_sysadmin_oid()) && + !has_privs_of_role(GetSessionUserId(), get_securityadmin_oid())) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("User does not have permission to perform this action."))); + /* Check if servername is valid */ get_foreign_server_oid(servername, false); initStringInfo(&query); /* - * We prepare the following queries to drop a linked server login. This will - * be executed using ProcessUtility(): - * - * DROP USER MAPPING IF EXISTS FOR CURRENT_USER SERVER @SERVERNAME - * DROP USER MAPPING IF EXISTS FOR PUBLIC SERVER @SERVERNAME - * - * Linked logins were first implemented as PG USER MAPPINGs for the CURRENT_USER which - * was not entirely correct because T-SQL linked logins are not user or login specific. - * To address this we now create user mapping for the PG PUBLIC role internally. - * - * To ensure sp_droplinkedsrvlogin works in accordance with both the older and newer - * implementation of linked logins, we try to drop USER MAPPINGs for both the CURRENT_USER - * and PUBLIC PG roles. - */ - appendStringInfo(&query, "DROP USER MAPPING IF EXISTS FOR CURRENT_USER SERVER \"%s\"", servername); - exec_utility_cmd_helper(query.data); + * We have performed all the permissions checks. + * Set current user to bbf_role_admin for mapping permissions. + */ + GetUserIdAndSecContext(&save_userid, &save_sec_context); + SetUserIdAndSecContext(get_bbf_role_admin_oid(), save_sec_context | SECURITY_LOCAL_USERID_CHANGE); - resetStringInfo(&query); + PG_TRY(); + { + /* + * We prepare the following queries to drop a linked server login. This will + * be executed using ProcessUtility(): + * + * DROP USER MAPPING IF EXISTS FOR CURRENT_USER SERVER @SERVERNAME + * DROP USER MAPPING IF EXISTS FOR PUBLIC SERVER @SERVERNAME + * + * Linked logins were first implemented as PG USER MAPPINGs for the CURRENT_USER which + * was not entirely correct because T-SQL linked logins are not user or login specific. + * To address this we now create user mapping for the PG PUBLIC role internally. + * + * To ensure sp_droplinkedsrvlogin works in accordance with both the older and newer + * implementation of linked logins, we try to drop USER MAPPINGs for both the CURRENT_USER + * and PUBLIC PG roles. + */ + appendStringInfo(&query, "DROP USER MAPPING IF EXISTS FOR CURRENT_USER SERVER \"%s\"", servername); + exec_utility_cmd_helper(query.data); - appendStringInfo(&query, "DROP USER MAPPING IF EXISTS FOR PUBLIC SERVER \"%s\"", servername); - exec_utility_cmd_helper(query.data); + resetStringInfo(&query); + + appendStringInfo(&query, "DROP USER MAPPING IF EXISTS FOR PUBLIC SERVER \"%s\"", servername); + exec_utility_cmd_helper(query.data); + } + + PG_FINALLY(); + { + SetUserIdAndSecContext(save_userid, save_sec_context); + } + PG_END_TRY(); if (locallogin) pfree(locallogin); @@ -3137,6 +3191,8 @@ sp_droplinkedsrvlogin_internal(PG_FUNCTION_ARGS) if (servername) pfree(servername); + pfree(query.data); + return (Datum) 0; } diff --git a/contrib/babelfishpg_tsql/src/rolecmds.c b/contrib/babelfishpg_tsql/src/rolecmds.c index 136a97b1a4..58b35f70e2 100644 --- a/contrib/babelfishpg_tsql/src/rolecmds.c +++ b/contrib/babelfishpg_tsql/src/rolecmds.c @@ -77,6 +77,7 @@ static void validateNetBIOS(char *netbios); static void validateFQDN(char *fqdn); static Oid bbf_admin_oid = InvalidOid; +static Oid securityadmin_oid = InvalidOid; void create_bbf_authid_login_ext(CreateRoleStmt *stmt) @@ -146,6 +147,8 @@ create_bbf_authid_login_ext(CreateRoleStmt *stmt) new_record_login_ext[LOGIN_EXT_TYPE] = CStringGetTextDatum("R"); else if (strcmp(stmt->role, "bbf_role_admin") == 0) new_record_login_ext[LOGIN_EXT_TYPE] = CStringGetTextDatum("Z"); + else if (strcmp(stmt->role, BABELFISH_SECURITYADMIN) == 0) + new_record_login_ext[LOGIN_EXT_TYPE] = CStringGetTextDatum("R"); else if (from_windows) new_record_login_ext[LOGIN_EXT_TYPE] = CStringGetTextDatum("U"); else @@ -685,6 +688,16 @@ get_bbf_role_admin_oid(void) return bbf_admin_oid; } + +/* Returns OID of securityadmin server role */ +Oid +get_securityadmin_oid(void) +{ + if (!OidIsValid(securityadmin_oid)) + securityadmin_oid = get_role_oid(BABELFISH_SECURITYADMIN, false); + return securityadmin_oid; +} + /* * Returns OID of SA of the current database. * We assume that SA is the DBA of the babelfish DB. @@ -1662,7 +1675,7 @@ bool is_alter_server_stmt(GrantRoleStmt *stmt) { /* - * is alter server role statement, if one and the only one granted role is + * is alter server role statement, if the granted role is * server role */ @@ -1670,13 +1683,10 @@ is_alter_server_stmt(GrantRoleStmt *stmt) { RoleSpec *spec = (RoleSpec *) linitial(stmt->granted_roles); - if (strcmp(spec->rolename, "sysadmin") == 0) /* only supported server - * role */ + /* only supported server roles */ + if (IS_ROLENAME_SYSADMIN(spec->rolename) || IS_ROLENAME_SECURITYADMIN(spec->rolename)) return true; } - /* has one and only one grantee */ - if (list_length(stmt->grantee_roles) != 1) - return false; return false; } @@ -1716,8 +1726,12 @@ check_alter_server_stmt(GrantRoleStmt *stmt) (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("%s is not a login", grantee_name))); - /* only sysadmin role is assumed below */ - if (!has_privs_of_role(GetSessionUserId(), sysadmin)) + /* + * check if it has sysadmin privileges or + * if server role is securityadmin and it has privileges of securityadmin + */ + if (!has_privs_of_role(GetSessionUserId(), sysadmin) && ((strcmp(granted_name, BABELFISH_SECURITYADMIN) != 0) + || !has_privs_of_role(GetSessionUserId(), get_securityadmin_oid()))) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("Current login %s does not have permission to alter server role", @@ -2545,3 +2559,21 @@ remove_createrole_from_logins(PG_FUNCTION_ARGS) table_close(rel, AccessShareLock); PG_RETURN_INT32(0); } + +PG_FUNCTION_INFO_V1(bbf_is_member_of_role_nosuper); +Datum +bbf_is_member_of_role_nosuper(PG_FUNCTION_ARGS) +{ + Oid member, role; + bool result; + + if (PG_ARGISNULL(0) || PG_ARGISNULL(1)) + PG_RETURN_NULL(); + + member = PG_GETARG_OID(0); + role = PG_GETARG_OID(1); + + result = is_member_of_role_nosuper(member, role); + + PG_RETURN_BOOL(result); +} diff --git a/contrib/babelfishpg_tsql/src/rolecmds.h b/contrib/babelfishpg_tsql/src/rolecmds.h index e5f9f9db5b..b1459efee5 100644 --- a/contrib/babelfishpg_tsql/src/rolecmds.h +++ b/contrib/babelfishpg_tsql/src/rolecmds.h @@ -55,6 +55,7 @@ extern void drop_bbf_roles(ObjectAccessType access, void *arg); extern bool role_is_sa(Oid roleid); extern Oid get_bbf_role_admin_oid(void); +extern Oid get_securityadmin_oid(void); extern Oid get_sa_role_oid(void); extern bool tsql_has_pgstat_permissions(Oid roleid); extern bool tsql_has_linked_srv_permissions(Oid roleid); diff --git a/test/JDBC/expected/BABEL-2403.out b/test/JDBC/expected/BABEL-2403.out index c879c5bf23..c3e19ceb06 100644 --- a/test/JDBC/expected/BABEL-2403.out +++ b/test/JDBC/expected/BABEL-2403.out @@ -81,6 +81,8 @@ name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_login_ext text#!#sys#!#name#!#{"Rule": " in babelfish_authid_login_ext must also exist in babelfish_sysdatabases"} name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_login_ext must also exist in pg_authid"} text#!#sys#!#name#!#{"Rule": " in babelfish_authid_login_ext must also exist in babelfish_sysdatabases"} +name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_login_ext must also exist in pg_authid"} +text#!#sys#!#name#!#{"Rule": " in babelfish_authid_login_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"} @@ -170,6 +172,8 @@ name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_login_ext text#!#sys#!#name#!#{"Rule": " in babelfish_authid_login_ext must also exist in babelfish_sysdatabases"} name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_login_ext must also exist in pg_authid"} text#!#sys#!#name#!#{"Rule": " in babelfish_authid_login_ext must also exist in babelfish_sysdatabases"} +name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_login_ext must also exist in pg_authid"} +text#!#sys#!#name#!#{"Rule": " in babelfish_authid_login_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"} diff --git a/test/JDBC/expected/BABEL-LOGIN-USER-EXT.out b/test/JDBC/expected/BABEL-LOGIN-USER-EXT.out index 5437c600c8..e09fa162bb 100644 --- a/test/JDBC/expected/BABEL-LOGIN-USER-EXT.out +++ b/test/JDBC/expected/BABEL-LOGIN-USER-EXT.out @@ -277,7 +277,7 @@ SELECT COUNT(*) FROM sys.babelfish_authid_login_ext; go ~~START~~ int -3 +4 ~~END~~ @@ -288,7 +288,7 @@ SELECT COUNT(*) FROM sys.babelfish_authid_login_ext; go ~~START~~ int -4 +5 ~~END~~ @@ -300,7 +300,7 @@ SELECT COUNT(*) FROM sys.babelfish_authid_login_ext; go ~~START~~ int -5 +6 ~~END~~ @@ -388,7 +388,7 @@ SELECT COUNT(*) FROM sys.babelfish_authid_login_ext; go ~~START~~ int -4 +5 ~~END~~ @@ -418,7 +418,7 @@ SELECT COUNT(*) FROM sys.babelfish_authid_login_ext; go ~~START~~ int -3 +4 ~~END~~ @@ -489,14 +489,14 @@ ALTER SERVER ROLE db_owner ADD MEMBER dummy; GO ~~ERROR (Code: 33557097)~~ -~~ERROR (Message: only sysadmin role is supported in ALTER SERVER ROLE statement)~~ +~~ERROR (Message: Only fixed server role is supported in ALTER SERVER ROLE statement)~~ ALTER SERVER ROLE db_owner DROP MEMBER dummy; GO ~~ERROR (Code: 33557097)~~ -~~ERROR (Message: only sysadmin role is supported in ALTER SERVER ROLE statement)~~ +~~ERROR (Message: Only fixed server role is supported in ALTER SERVER ROLE statement)~~ CREATE LOGIN err_user WITH PASSWORD = '123'; diff --git a/test/JDBC/expected/BABEL-LOGIN-vu-verify.out b/test/JDBC/expected/BABEL-LOGIN-vu-verify.out index 22aa32d6ee..e35d0a6387 100644 --- a/test/JDBC/expected/BABEL-LOGIN-vu-verify.out +++ b/test/JDBC/expected/BABEL-LOGIN-vu-verify.out @@ -274,14 +274,14 @@ ALTER SERVER ROLE db_owner ADD MEMBER dummy; go ~~ERROR (Code: 33557097)~~ -~~ERROR (Message: only sysadmin role is supported in ALTER SERVER ROLE statement)~~ +~~ERROR (Message: Only fixed server role is supported in ALTER SERVER ROLE statement)~~ ALTER SERVER ROLE db_owner DROP MEMBER dummy; go ~~ERROR (Code: 33557097)~~ -~~ERROR (Message: only sysadmin role is supported in ALTER SERVER ROLE statement)~~ +~~ERROR (Message: Only fixed server role is supported in ALTER SERVER ROLE statement)~~ CREATE USER babel_login_vu_prepare_err_user; diff --git a/test/JDBC/expected/bbf_role_admin_restrictions.out b/test/JDBC/expected/bbf_role_admin_restrictions.out index ae3eef5526..113c662862 100644 --- a/test/JDBC/expected/bbf_role_admin_restrictions.out +++ b/test/JDBC/expected/bbf_role_admin_restrictions.out @@ -20,7 +20,7 @@ ALTER SERVER ROLE bbf_role_admin ADD MEMBER bbf_role_admin_restrictions_role; GO ~~ERROR (Code: 33557097)~~ -~~ERROR (Message: only sysadmin role is supported in ALTER SERVER ROLE statement)~~ +~~ERROR (Message: Only fixed server role is supported in ALTER SERVER ROLE statement)~~ ALTER ROLE bbf_role_admin_restrictions_role ADD MEMBER bbf_role_admin; diff --git a/test/JDBC/expected/is_srvrolemember-vu-verify.out b/test/JDBC/expected/is_srvrolemember-vu-verify.out index d68cecfa6e..4955dd3fbc 100644 --- a/test/JDBC/expected/is_srvrolemember-vu-verify.out +++ b/test/JDBC/expected/is_srvrolemember-vu-verify.out @@ -122,7 +122,7 @@ SELECT is_srvrolemember('securityadmin') GO ~~START~~ int -0 +1 ~~END~~ diff --git a/test/JDBC/expected/is_srvrolemember.out b/test/JDBC/expected/is_srvrolemember.out index d68cecfa6e..4955dd3fbc 100644 --- a/test/JDBC/expected/is_srvrolemember.out +++ b/test/JDBC/expected/is_srvrolemember.out @@ -122,7 +122,7 @@ SELECT is_srvrolemember('securityadmin') GO ~~START~~ int -0 +1 ~~END~~ diff --git a/test/JDBC/expected/securityadmin_role-vu-cleanup.out b/test/JDBC/expected/securityadmin_role-vu-cleanup.out new file mode 100644 index 0000000000..fb82964f8d --- /dev/null +++ b/test/JDBC/expected/securityadmin_role-vu-cleanup.out @@ -0,0 +1,63 @@ +-- tsql +drop user securityadmin_user1 +go + +drop user no_securityadmin_user1 +go + +drop login securityadmin_login1 +go + +use securityadmin_db1 +go + +drop user no_securityadmin_user1 +go + +use master +go + +drop login no_securityadmin_login1 +go + +drop database securityadmin_db1 +go + +drop schema securityadmin_scm1 +go + +drop view securityadmin_show_role_mem +go + +drop TRIGGER securityadmin_tggr1 +go + +drop table securityadmin_tb1 +go + +drop view securityadmin_v1 +go + +drop function securityadmin_func1() +go + +drop procedure securityadmin_proc1 +go + +drop procedure securityadmin_create_login_p1 +go + +drop procedure securityadmin_alter_login_p1 +go + +drop procedure securityadmin_drop_login_p1 +go + +drop procedure securityadmin_add_mem_p1 +go + +drop procedure securityadmin_drop_mem_p1 +go + +drop role securityadmin_rol +go diff --git a/test/JDBC/expected/securityadmin_role-vu-prepare.out b/test/JDBC/expected/securityadmin_role-vu-prepare.out new file mode 100644 index 0000000000..1f96ebe37e --- /dev/null +++ b/test/JDBC/expected/securityadmin_role-vu-prepare.out @@ -0,0 +1,90 @@ +-- tsql +create login securityadmin_login1 with password = '123' +go + +create login no_securityadmin_login1 with password = '123' +go + +create user securityadmin_user1 for login securityadmin_login1 +go + +create user no_securityadmin_user1 for login no_securityadmin_login1 +go + +-- tsql +create role securityadmin_rol +go + +create database securityadmin_db1 +go + +create schema securityadmin_scm1 +go + +CREATE VIEW securityadmin_show_role_mem AS +SELECT +roles.name AS RolePrincipalName +, members.name AS MemberPrincipalName +FROM sys.server_role_members AS server_role_members +INNER JOIN sys.server_principals AS roles + ON server_role_members.role_principal_id = roles.principal_id +INNER JOIN sys.server_principals AS members + ON server_role_members.member_principal_id = members.principal_id order by MemberPrincipalName; +GO + +create table securityadmin_tb1(a int) +go + +create view securityadmin_v1 as select 1; +go + +create function securityadmin_func1() returns int as begin return 1 end; +go + +create procedure securityadmin_proc1 as begin select 1; end +go + +CREATE TRIGGER securityadmin_tggr1 on securityadmin_tb1 AFTER INSERT AS BEGIN END; +go + +create procedure securityadmin_create_login_p1 as begin create login securityadmin_login_new with password ='123'; end +go + +Grant execute on securityadmin_create_login_p1 to PUBLIC; +go + +create procedure securityadmin_alter_login_p1 as begin alter login securityadmin_login_new with password ='1234'; end +go + +Grant execute on securityadmin_alter_login_p1 to PUBLIC; +go + +create procedure securityadmin_drop_login_p1 as begin drop login securityadmin_login_new; end +go + +Grant execute on securityadmin_drop_login_p1 to PUBLIC; +go + +create procedure securityadmin_add_mem_p1 as begin Alter server role securityadmin add member securityadmin_login_new; end +go + +Grant execute on securityadmin_add_mem_p1 to PUBLIC; +go + +create procedure securityadmin_drop_mem_p1 as begin Alter server role securityadmin drop member securityadmin_login_new; end +go + +Grant execute on securityadmin_drop_mem_p1 to PUBLIC; +go + +use securityadmin_db1 +go + +create user securityadmin_user1 for login securityadmin_login1 +go + +create user no_securityadmin_user1 for login no_securityadmin_login1 +go + +use master +go diff --git a/test/JDBC/expected/securityadmin_role-vu-verify.out b/test/JDBC/expected/securityadmin_role-vu-verify.out new file mode 100644 index 0000000000..f3b35d0386 --- /dev/null +++ b/test/JDBC/expected/securityadmin_role-vu-verify.out @@ -0,0 +1,1609 @@ +-- tsql +alter login securityadmin_login1 with password='123' +go + +alter login no_securityadmin_login1 with password='123' +go + +-- make login member of securityadmin +Alter server role securityadmin add member securityadmin_login1 +go + +select * from securityadmin_show_role_mem where MemberPrincipalName like 'jdbc_user' or MemberPrincipalName like '%securityadmin_%' +go +~~START~~ +varchar#!#varchar +sysadmin#!#jdbc_user +securityadmin#!#securityadmin_login1 +~~END~~ + + +-- should error out +create login securityadmin with password = '123' +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The Server principal 'securityadmin' already exists)~~ + + +-- terminate-tsql-conn + +-- tsql user=securityadmin_login1 password=123 +-- Case 1 - positives +-- securityadmin's login privileges +-- alter server role securityadmin should be allowed +select bbf_is_member_of_role_nosuper(suser_id(), suser_id('securityadmin')) +go +~~START~~ +bit +1 +~~END~~ + + +select bbf_is_member_of_role_nosuper(suser_id(), suser_id('sysadmin')) +go +~~START~~ +bit +0 +~~END~~ + + +Alter server role securityadmin add member no_securityadmin_login1 +go + +Alter server role securityadmin drop member no_securityadmin_login1 +go + +-- create login should be allowed +-- windows login +create login [babel\securityadmin_l1] from windows; +go + +-- password based login +create login securityadmin_l2 with password = '123' +go + +-- alter login should be allowed +-- password based login +alter login securityadmin_l2 with password = '123' +go + +ALTER LOGIN securityadmin_l2 WITH PASSWORD = '1234' OLD_PASSWORD = '123'; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'OLD_PASSWORD' is not currently supported in Babelfish. please use babelfishpg_tsql.escape_hatch_login_old_password to ignore)~~ + + +ALTER LOGIN securityadmin_l2 disable; +go + +ALTER LOGIN securityadmin_l2 enable; +go + +ALTER LOGIN securityadmin_l2 with default_database=securityadmin_db1; +go + +-- windows login +alter login [babel\securityadmin_l1] with PASSWORD='123' +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot use parameter PASSWORD for a windows login)~~ + + +ALTER LOGIN [babel\securityadmin_l1] WITH PASSWORD = '1234' OLD_PASSWORD = '123'; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'OLD_PASSWORD' is not currently supported in Babelfish. please use babelfishpg_tsql.escape_hatch_login_old_password to ignore)~~ + + +ALTER LOGIN [babel\securityadmin_l1] disable; +go + +ALTER LOGIN [babel\securityadmin_l1] enable; +go + +ALTER LOGIN [babel\securityadmin_l1] with default_database=securityadmin_db1; +go + +-- make altering login member of securityadmin +Alter server role securityadmin add member securityadmin_l2 +go + +-- alter securityadmin member login +-- allowed +alter login securityadmin_l2 with password = '123' +go + +-- drop login should be allowed +-- password based login +drop login securityadmin_l2 +go + +-- windows login +drop login [babel\securityadmin_l1] +go + +-- grant server permissions (currently not supported) +-- few examples +GRANT CONTROL SERVER TO no_securityadmin_login1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'GRANT Database' is not currently supported in Babelfish)~~ + + +GRANT ALTER ANY EVENT NOTIFICATION TO no_securityadmin_login1 WITH GRANT OPTION; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'GRANT Database' is not currently supported in Babelfish)~~ + + +GRANT ALTER ANY DATABASE TO no_securityadmin_login1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'GRANT Database' is not currently supported in Babelfish)~~ + + + +-- terminate-tsql-conn user=securityadmin_login1 password=123 + +-- tsql user=no_securityadmin_login1 password=123 +-- grant database permissions (only connect is supported) +-- allowed +use securityadmin_db1 +go + +-- terminate-tsql-conn user=no_securityadmin_login1 password=123 + +-- tsql user=securityadmin_login1 password=123 database=securityadmin_db1 +REVOKE CONNECT FROM no_securityadmin_user1 +go + +-- unsupported +GRANT SHOWPLAN TO no_securityadmin_user1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'GRANT Database' is not currently supported in Babelfish)~~ + + +GRANT CREATE VIEW TO no_securityadmin_user1 WITH GRANT OPTION; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'GRANT Database' is not currently supported in Babelfish)~~ + + +-- terminate-tsql-conn user=securityadmin_login1 password=123 database=securityadmin_db1 + +-- tsql user=no_securityadmin_login1 password=123 +-- connection revoked +use securityadmin_db1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The server principal "no_securityadmin_login1" is not able to access the database "securityadmin_db1" under the current security context)~~ + + +-- terminate-tsql-conn user=no_securityadmin_login1 password=123 + +-- tsql user=securityadmin_login1 password=123 database=securityadmin_db1 +-- revoke server permissions (currently not supported) +-- few examples +REVOKE CONTROL SERVER FROM no_securityadmin_login1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'REVOKE Database' is not currently supported in Babelfish)~~ + + +REVOKE ALTER ANY EVENT NOTIFICATION FROM no_securityadmin_login1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'REVOKE Database' is not currently supported in Babelfish)~~ + + +REVOKE ALTER ANY DATABASE FROM no_securityadmin_login1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'REVOKE Database' is not currently supported in Babelfish)~~ + + +-- grant database permissions (only connect is supported) +GRANT CONNECT TO no_securityadmin_user1 +go + +-- terminate-tsql-conn user=securityadmin_login1 password=123 database=securityadmin_db1 + +-- tsql user=no_securityadmin_login1 password=123 +use securityadmin_db1 +go + +-- Check unprivileged login should not have access +-- permission denied +EXEC sp_addlinkedsrvlogin 'Accounts', 'False' +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: User does not have permission to perform this action.)~~ + + +EXEC sp_droplinkedsrvlogin 'Accounts', NULL +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: User does not have permission to perform this action.)~~ + + +Alter server role securityadmin add member no_securityadmin_login1 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Current login no_securityadmin_login1 does not have permission to alter server role)~~ + + +Alter server role securityadmin drop member no_securityadmin_login1 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Current login no_securityadmin_login1 does not have permission to alter server role)~~ + + +-- only current login and fixed server roles +SELECT name, type, type_desc, default_database_name, default_language_name, credential_id, owning_principal_id, is_fixed_role +FROM sys.server_principals ORDER BY name +GO +~~START~~ +varchar#!#char#!#nvarchar#!#varchar#!#varchar#!#int#!#int#!#bit +jdbc_user#!#S#!#SQL_LOGIN#!#master#!#English#!#-1#!#-1#!#0 +no_securityadmin_login1#!#S#!#SQL_LOGIN#!#master#!#English#!#-1#!#-1#!#0 +public#!#R#!#SERVER_ROLE#!##!##!##!#1#!#0 +securityadmin#!#R#!#SERVER_ROLE#!##!#English#!##!#1#!#1 +sysadmin#!#R#!#SERVER_ROLE#!##!#English#!##!#1#!#1 +~~END~~ + + +-- only current login +select name, type, usage from sys.login_token order by name; +go +~~START~~ +nvarchar#!#nvarchar#!#nvarchar +no_securityadmin_login1#!#SQL LOGIN#!#GRANT OR DENY +~~END~~ + + +-- terminate-tsql-conn user=no_securityadmin_login1 password=123 + +-- tsql user=securityadmin_login1 password=123 +-- unsupported +REVOKE SHOWPLAN FROM no_securityadmin_user1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'REVOKE Database' is not currently supported in Babelfish)~~ + + +REVOKE CREATE VIEW FROM no_securityadmin_user1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'REVOKE Database' is not currently supported in Babelfish)~~ + + +-- System objects +-- All rows of server_prinicipals view should be visible to securityadmin login +-- limited rows should get displayed +SELECT name, type, type_desc, default_database_name, default_language_name, credential_id, owning_principal_id, is_fixed_role +FROM sys.server_principals +WHERE name in ('jdbc_user', 'sysadmin', 'public', 'securityadmin') ORDER BY name; +GO +~~START~~ +varchar#!#char#!#nvarchar#!#varchar#!#varchar#!#int#!#int#!#bit +jdbc_user#!#S#!#SQL_LOGIN#!#master#!#English#!#-1#!#-1#!#0 +public#!#R#!#SERVER_ROLE#!##!##!##!#1#!#0 +securityadmin#!#R#!#SERVER_ROLE#!##!#English#!##!#1#!#1 +sysadmin#!#R#!#SERVER_ROLE#!##!#English#!##!#1#!#1 +~~END~~ + + +SELECT name, type, type_desc, default_database_name, default_language_name, credential_id, owning_principal_id, is_fixed_role +FROM sys.server_principals name WHERE name like '%securityadmin%' ORDER BY name; +GO +~~START~~ +varchar#!#char#!#nvarchar#!#varchar#!#varchar#!#int#!#int#!#bit +no_securityadmin_login1#!#S#!#SQL_LOGIN#!#master#!#English#!#-1#!#-1#!#0 +securityadmin#!#R#!#SERVER_ROLE#!##!#English#!##!#1#!#1 +securityadmin_login1#!#S#!#SQL_LOGIN#!#master#!#English#!#-1#!#-1#!#0 +~~END~~ + + +-- current login along with current fixed role should be visible +select name, type, usage from sys.login_token order by name; +go +~~START~~ +nvarchar#!#nvarchar#!#nvarchar +securityadmin#!#SERVER ROLE#!#GRANT OR DENY +securityadmin_login1#!#SQL LOGIN#!#GRANT OR DENY +~~END~~ + + +select name, sysadmin, securityadmin from syslogins where name like '%securityadmin%' order by name +go +~~START~~ +varchar#!#int#!#int +no_securityadmin_login1#!#0#!#0 +securityadmin_login1#!#0#!#1 +~~END~~ + + +-- should return 0 +select is_srvrolemember ('sysadmin') +go +~~START~~ +int +0 +~~END~~ + + +-- should return 1 +select is_srvrolemember ('securityadmin') +go +~~START~~ +int +1 +~~END~~ + + +select is_srvrolemember ('securityadmin', 'securityadmin_login1') +go +~~START~~ +int +1 +~~END~~ + + +-- terminate-tsql-conn user=securityadmin_login1 password=123 + +-- psql +CREATE EXTENSION IF NOT EXISTS tds_fdw; +GO + +-- tsql +-- Add localhost as linked server +EXEC sp_addlinkedserver @server = N'server_4229', @srvproduct=N'', @provider=N'SQLNCLI', @datasrc=N'localhost', @catalog=N'master' +GO + +EXEC sp_addlinkedserver 'Accounts' +GO + +-- Add jdbc_user as linked server login +EXEC sp_addlinkedsrvlogin @rmtsrvname = 'server_4229', @useself = 'FALSE', @rmtuser = 'jdbc_user', @rmtpassword = '12345678' +GO + +drop database securityadmin_db1 +go + +-- terminate-tsql-conn + +-- tsql user=securityadmin_login1 password=123 +EXEC sp_addlinkedsrvlogin 'Accounts', 'False' +GO + +EXEC sp_droplinkedsrvlogin 'Accounts', NULL +GO + +-- inside procedure +exec securityadmin_create_login_p1 +go + +exec securityadmin_alter_login_p1 +go + +exec securityadmin_add_mem_p1 +go + +exec securityadmin_drop_mem_p1 +go + +exec securityadmin_drop_login_p1 +go + +-- terminate-tsql-conn user=securityadmin_login1 password=123 + +-- tsql +-- login is member of both securityadmin as well as sysadmin +drop user securityadmin_user1 +go + +Alter server role sysadmin add member securityadmin_login1 +go + +create database securityadmin_db1 +go + +-- terminate-tsql-conn + +-- tsql user=securityadmin_login1 password=123 +-- it should be able to connect to the database +use securityadmin_db1 +go + +-- it should be dbo +select current_user +go +~~START~~ +varchar +dbo +~~END~~ + + +-- both attribute should be true +select rolname, rolcreaterole, rolcreatedb from pg_roles where rolname = 'securityadmin_login1' +go +~~START~~ +varchar#!#bit#!#bit +securityadmin_login1#!#1#!#1 +~~END~~ + + +-- terminate-tsql-conn user=securityadmin_login1 password=123 + +-- tsql +-- only member of securityadmin +alter server role sysadmin drop member securityadmin_login1 +go + +create user securityadmin_user1 for login securityadmin_login1 +go + +-- terminate-tsql-conn + +-- tsql user=securityadmin_login1 password=123 + +-- only rolcreaterole attribute should be true +select rolname, rolcreaterole, rolcreatedb from pg_roles where rolname = 'securityadmin_login1' +go +~~START~~ +varchar#!#bit#!#bit +securityadmin_login1#!#1#!#0 +~~END~~ + + +-- should be able to create/drop login +create login test_securityadmin_l1 with password ='123' +go + +drop login test_securityadmin_l1 +go + +-- terminate-tsql-conn user=securityadmin_login1 password=123 + +-- tsql +-- only member of sysadmin +drop user securityadmin_user1 +go + +alter server role sysadmin add member securityadmin_login1 +go + +alter server role securityadmin drop member securityadmin_login1 +go + +-- terminate-tsql-conn + +-- tsql user=securityadmin_login1 password=123 + +-- both attribute should be true +select rolname, rolcreaterole, rolcreatedb from pg_roles where rolname = 'securityadmin_login1' +go +~~START~~ +varchar#!#bit#!#bit +securityadmin_login1#!#1#!#1 +~~END~~ + + +-- should be able to create/drop login +create login test_securityadmin_l1 with password ='123' +go + +drop login test_securityadmin_l1 +go + +-- should return 1 +select is_srvrolemember ('sysadmin') +go +~~START~~ +int +1 +~~END~~ + + +-- should return 1 +select is_srvrolemember ('securityadmin') +go +~~START~~ +int +1 +~~END~~ + + +-- terminate-tsql-conn user=securityadmin_login1 password=123 + +-- tsql +-- make it member of securityadmin only +alter server role sysadmin drop member securityadmin_login1 +go + +alter server role securityadmin add member securityadmin_login1 +go + +drop user no_securityadmin_user1 +go + +alter server role sysadmin add member no_securityadmin_login1 +go + +create user securityadmin_user1 for login securityadmin_login1 +go + +-- terminate-tsql-conn + +-- tsql user=securityadmin_login1 password=123 +-- Case 2 - negatives +-- alter server role sysadmin should give permission denied +Alter server role sysadmin add member no_securityadmin_login1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Current login securityadmin_login1 does not have permission to alter server role)~~ + + +-- alter server role securityadmin add member db roles should error out +Alter server role securityadmin add member guest +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: role "guest" does not exist)~~ + + +-- alter sysadmin login should give permission denied +-- login which is altered is member of sysadmin +Alter login no_securityadmin_login1 with password ='123' +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot alter the login 'no_securityadmin_login1', because it does not exist or you do not have permission.)~~ + + +-- terminate-tsql-conn user=securityadmin_login1 password=123 + +-- tsql +-- make member of securityadmin as well +alter server role securityadmin add member no_securityadmin_login1 +go + +-- terminate-tsql-conn + +-- tsql user=securityadmin_login1 password=123 +-- login which is altered is member of sysadmin and securityadmin both +-- permission denied +Alter login no_securityadmin_login1 with password ='123' +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot alter the login 'no_securityadmin_login1', because it does not exist or you do not have permission.)~~ + + +-- terminate-tsql-conn user=securityadmin_login1 password=123 + +-- tsql +alter server role securityadmin drop member no_securityadmin_login1 +go + +alter server role sysadmin drop member no_securityadmin_login1 +go + +create user no_securityadmin_user1 for login no_securityadmin_login1 +go + +create role dummy_role +go + +drop database securityadmin_db1 +go + +-- terminate-tsql-conn + +-- tsql user=securityadmin_login1 password=123 +-- should error out +Alter server role securityadmin add member dummy_role +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: role "dummy_role" does not exist)~~ + + +-- create database permission denied +create database perm_denied_db +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied to create database)~~ + + +-- terminate-tsql-conn user=securityadmin_login1 password=123 + +-- tsql +drop role dummy_role +go + +create database securityadmin_db1 +go + +use securityadmin_db1 +go + +create user securityadmin_user1 for login securityadmin_login1 +go + +create user no_securityadmin_user1 for login no_securityadmin_login1 +go + +-- terminate-tsql-conn + +-- tsql user=securityadmin_login1 password=123 +-- alter database permission denied +alter database securityadmin_db1 modify name = rename_db_database1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: User does not have permission to rename the database 'securityadmin_db1', the database does not exist, or the database is not in a state that allows access checks.)~~ + + +alter authorization on database::securityadmin_db1 to no_securityadmin_login1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot find the principal 'no_securityadmin_login1', because it does not exist or you do not have permission.)~~ + + +-- drop database permission denied +drop database securityadmin_db1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: must be owner of database securityadmin_db1)~~ + + +-- securityadmin login's mapped user should not have any priv +select current_user, db_name() +go +~~START~~ +varchar#!#nvarchar +securityadmin_user1#!#master +~~END~~ + + +select suser_name() +go +~~START~~ +nvarchar +securityadmin_login1 +~~END~~ + + +-- allowed +create login securityadmin_l2 with password = '123' +go + +-- create objects/user permission denied +create user securityadmin_l2 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: User does not have permission to perform this action.)~~ + + +create role securityadmin_role1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: User does not have permission to perform this action.)~~ + + +create schema perm_denied_scm +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for database jdbc_testdb)~~ + + +create view perm_denied_v1 as select 1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for schema master_dbo)~~ + + +create table perm_denied_tb1 (a int); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for schema master_dbo)~~ + + +select 1 into perm_denied_tb2; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for schema master_dbo)~~ + + +create function perm_denied_func1() returns int as begin return 1 end; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for schema master_dbo)~~ + + +create procedure perm_denied_proc1 as begin select 1; end +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for schema master_dbo)~~ + + +create type perm_denied_typ1 from int; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for schema master_dbo)~~ + + +create index perm_denied_index1 on securityadmin_tb1(a); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: must be owner of table securityadmin_tb1)~~ + + +CREATE FUNCTION perm_denied_func1() RETURNS TABLE AS RETURN ( SELECT 1 AS Value); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for schema master_dbo)~~ + + +-- DMLS on object permission denied +Alter user no_securityadmin_user1 with DEFAULT_SCHEMA=securityadmin_scm1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Current user does not have privileges to change schema)~~ + + +Alter role securityadmin_rol add member no_securityadmin_user1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Current login securityadmin_login1 does not have permission to alter role master_securityadmin_rol)~~ + + +Alter role securityadmin_rol drop member no_securityadmin_user1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Current login securityadmin_login1 does not have permission to alter role master_securityadmin_rol)~~ + + +Alter table securityadmin_tb1 add b int +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: must be owner of table securityadmin_tb1)~~ + + +Insert into securityadmin_tb1 values (1) +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table securityadmin_tb1)~~ + + +UPDATE securityadmin_tb1 SET a = 2 where a = 1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table securityadmin_tb1)~~ + + +DELETE FROM securityadmin_tb1 WHERE a = 1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table securityadmin_tb1)~~ + + +TRUNCATE TABLE securityadmin_tb1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table securityadmin_tb1)~~ + + +select * from securityadmin_tb1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table securityadmin_tb1)~~ + + +select * from securityadmin_v1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view securityadmin_v1)~~ + + +select securityadmin_func1() +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for function securityadmin_func1)~~ + + +exec securityadmin_proc1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for procedure securityadmin_proc1)~~ + + +Enable trigger securityadmin_tggr1 on securityadmin_tb1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: must be owner of table securityadmin_tb1)~~ + + +Disable trigger securityadmin_tggr1 on securityadmin_tb1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: must be owner of table securityadmin_tb1)~~ + + +-- grant on objects permission denied +Grant select on securityadmin_tb1 to no_securityadmin_user1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table securityadmin_tb1)~~ + + +Grant update on securityadmin_v1 to no_securityadmin_user1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table securityadmin_v1)~~ + + +Grant update on securityadmin_v1 to no_securityadmin_user1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table securityadmin_v1)~~ + + +Grant exec on securityadmin_func1 to no_securityadmin_user1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for function securityadmin_func1)~~ + + +Grant exec on securityadmin_proc1 to no_securityadmin_user1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for function securityadmin_proc1)~~ + + +-- Revoke on objects permission denied +Revoke select on securityadmin_tb1 from no_securityadmin_user1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table securityadmin_tb1)~~ + + +Revoke update on securityadmin_v1 from no_securityadmin_user1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table securityadmin_v1)~~ + + +Revoke update on securityadmin_v1 from no_securityadmin_user1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table securityadmin_v1)~~ + + +Revoke exec on securityadmin_func1 from no_securityadmin_user1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for function securityadmin_func1)~~ + + +Revoke exec on securityadmin_proc1 from no_securityadmin_user1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for function securityadmin_proc1)~~ + + +-- grant on schema +-- permission denied +grant select on securityadmin_v1 to no_securityadmin_user1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table securityadmin_v1)~~ + +grant select on dbo.securityadmin_v1 to no_securityadmin_user1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table securityadmin_v1)~~ + +grant execute on securityadmin_proc1 to no_securityadmin_user1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for function securityadmin_proc1)~~ + +grant execute on dbo.securityadmin_proc1 to no_securityadmin_user1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for function securityadmin_proc1)~~ + + +-- revoke on schema +-- permission denied +revoke select on securityadmin_v1 from no_securityadmin_user1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table securityadmin_v1)~~ + +revoke select on dbo.securityadmin_v1 from no_securityadmin_user1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table securityadmin_v1)~~ + +revoke execute on securityadmin_proc1 from no_securityadmin_user1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for function securityadmin_proc1)~~ + +revoke execute on dbo.securityadmin_proc1 from no_securityadmin_user1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for function securityadmin_proc1)~~ + + +-- drop object permission denied +drop user securityadmin_l2 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot drop the user 'securityadmin_l2', because it does not exist or you do not have permission.)~~ + + +drop role securityadmin_rol +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot drop the role 'securityadmin_rol', because it does not exist or you do not have permission.)~~ + + +drop schema securityadmin_scm1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: must be owner of schema master_securityadmin_scm1)~~ + + +drop view securityadmin_show_role_mem +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: must be owner of view securityadmin_show_role_mem)~~ + + +drop TRIGGER securityadmin_tggr1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: must be owner of relation securityadmin_tb1)~~ + + +drop table securityadmin_tb1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: must be owner of table securityadmin_tb1)~~ + + +drop view securityadmin_v1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: must be owner of view securityadmin_v1)~~ + + +drop function securityadmin_func1() +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: must be owner of function securityadmin_func1)~~ + + +drop procedure securityadmin_proc1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: must be owner of procedure securityadmin_proc1)~~ + + +-- allowed drop login +drop login securityadmin_l2 +go + +-- terminate-tsql-conn user=securityadmin_login1 password=123 + + +-- tsql database=securityadmin_db1 +-- securityadmin login should not get mapped to dbo if no user exist, it should disconnect +drop user securityadmin_user1 +go + +-- terminate-tsql-conn database=securityadmin_db1 + +-- tsql user=securityadmin_login1 password=123 +-- it should disconnect +use securityadmin_db1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The server principal "securityadmin_login1" is not able to access the database "securityadmin_db1" under the current security context)~~ + + +-- tsql +-- Case 3 - alter server role other than securityadmin and sysadmin should give unsupported +Alter server role false_role add member no_securityadmin_login1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Only fixed server role is supported in ALTER SERVER ROLE statement)~~ + + +Alter server role serveradmin add member no_securityadmin_login1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Fixed server role 'serveradmin' is currently not supported in Babelfish)~~ + + +Alter server role setupadmin add member no_securityadmin_login1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Fixed server role 'setupadmin' is currently not supported in Babelfish)~~ + + +Alter server role processadmin add member no_securityadmin_login1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Fixed server role 'processadmin' is currently not supported in Babelfish)~~ + + +Alter server role diskadmin add member no_securityadmin_login1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Fixed server role 'diskadmin' is currently not supported in Babelfish)~~ + + +Alter server role bulkadmin add member no_securityadmin_login1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Fixed server role 'bulkadmin' is currently not supported in Babelfish)~~ + + +Alter server role false_role drop member no_securityadmin_login1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Only fixed server role is supported in ALTER SERVER ROLE statement)~~ + + +Alter server role serveradmin drop member no_securityadmin_login1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Fixed server role 'serveradmin' is currently not supported in Babelfish)~~ + + +Alter server role setupadmin drop member no_securityadmin_login1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Fixed server role 'setupadmin' is currently not supported in Babelfish)~~ + + +Alter server role processadmin drop member no_securityadmin_login1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Fixed server role 'processadmin' is currently not supported in Babelfish)~~ + + +Alter server role diskadmin drop member no_securityadmin_login1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Fixed server role 'diskadmin' is currently not supported in Babelfish)~~ + + +Alter server role bulkadmin drop member no_securityadmin_login1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Fixed server role 'bulkadmin' is currently not supported in Babelfish)~~ + + +-- terminate-tsql-conn user=securityadmin_login1 password=123 + +-- tsql +-- Case 4 - check unintended/unauthorized use of securityadmin +CREATE LOGIN securityadmin_restrict_new_login WITH password = '12345678'; +go + +ALTER SERVER ROLE sysadmin ADD MEMBER securityadmin_restrict_new_login; +GO + +select * from securityadmin_show_role_mem where MemberPrincipalName like 'jdbc_user' or MemberPrincipalName like '%securityadmin_%' +go +~~START~~ +varchar#!#varchar +sysadmin#!#jdbc_user +securityadmin#!#securityadmin_login1 +sysadmin#!#securityadmin_restrict_new_login +~~END~~ + + +-- terminate-tsql-conn + +-- tsql user=securityadmin_restrict_new_login password=12345678 +select * from securityadmin_show_role_mem where MemberPrincipalName like 'jdbc_user' or MemberPrincipalName like '%securityadmin_%' +go +~~START~~ +varchar#!#varchar +sysadmin#!#jdbc_user +securityadmin#!#securityadmin_login1 +sysadmin#!#securityadmin_restrict_new_login +~~END~~ + + +select bbf_is_member_of_role_nosuper(suser_id(), suser_id('securityadmin')) +go +~~START~~ +bit +0 +~~END~~ + + +select bbf_is_member_of_role_nosuper(suser_id(), suser_id('sysadmin')) +go +~~START~~ +bit +1 +~~END~~ + + +select is_srvrolemember ('sysadmin') +go +~~START~~ +int +1 +~~END~~ + + +select is_srvrolemember ('securityadmin') +go +~~START~~ +int +1 +~~END~~ + + +select current_user, db_name() +go +~~START~~ +varchar#!#nvarchar +dbo#!#master +~~END~~ + + +CREATE ROLE securityadmin_restrictions_role; +GO + + +-- a tsql login should not be able to drop securityadmin explicitly from tsql port +-- should be denied +ALTER ROLE securityadmin_restrictions_role ADD MEMBER securityadmin; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: role "master_securityadmin" does not exist)~~ + + +DROP LOGIN securityadmin; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot drop the login 'securityadmin', because it does not exist or you do not have permission.)~~ + + +DROP ROLE securityadmin_restrictions_role; +GO + +-- terminate-tsql-conn user=securityadmin_restrict_new_login password=12345678 + +-- psql +create role securityadmin_restrict_new_pg_role +go + +-- psql user=securityadmin_restrict_new_login password=12345678 +-- a tsql login should not be able to alter/grant/drop securityadmin from pg port +ALTER ROLE securityadmin NOCREATEROLE; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Babelfish-created logins/users/roles cannot be altered outside of a Babelfish session + Server SQLState: 42501)~~ + + +ALTER ROLE securityadmin WITH PASSWORD '12345678'; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Babelfish-created logins/users/roles cannot be altered outside of a Babelfish session + Server SQLState: 42501)~~ + + +ALTER ROLE securityadmin VALID UNTIL 'infinity'; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Babelfish-created logins/users/roles cannot be altered outside of a Babelfish session + Server SQLState: 42501)~~ + + +ALTER ROLE securityadmin WITH CONNECTION LIMIT 1; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Babelfish-created logins/users/roles cannot be altered outside of a Babelfish session + Server SQLState: 42501)~~ + + +GRANT securityadmin TO securityadmin_restrict_new_login; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Babelfish-created logins/users/roles cannot be altered outside of a Babelfish session + Server SQLState: 42501)~~ + + +GRANT securityadmin TO securityadmin_restrict_new_pg_role +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Babelfish-created logins/users/roles cannot be altered outside of a Babelfish session + Server SQLState: 42501)~~ + + +GRANT sysadmin TO securityadmin +go +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Babelfish-created logins/users/roles cannot be altered outside of a Babelfish session + Server SQLState: 42501)~~ + + +GRANT securityadmin TO securityadmin +go +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Babelfish-created logins/users/roles cannot be altered outside of a Babelfish session + Server SQLState: 42501)~~ + + +GRANT securityadmin_restrict_new_login TO securityadmin; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Babelfish-created logins/users/roles cannot be altered outside of a Babelfish session + Server SQLState: 42501)~~ + + +REVOKE securityadmin FROM master_dbo; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Babelfish-created logins/users/roles cannot be altered outside of a Babelfish session + Server SQLState: 42501)~~ + + +REVOKE master_dbo FROM securityadmin; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Babelfish-created logins/users/roles cannot be altered outside of a Babelfish session + Server SQLState: 42501)~~ + + +DROP ROLE securityadmin; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Babelfish-created logins/users/roles cannot be dropped or altered outside of a Babelfish session + Server SQLState: 42501)~~ + + +SET SESSION AUTHORIZATION securityadmin; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: permission denied to set session authorization + Server SQLState: 42501)~~ + + +SET ROLE securityadmin; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: permission denied to set role "securityadmin" + Server SQLState: 42501)~~ + + +-- try granting object ownership to securityadmin +ALTER schema master_securityadmin_scm1 owner to securityadmin; +go +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: must be able to SET ROLE "securityadmin" + Server SQLState: 42501)~~ + + +ALTER table master_dbo.securityadmin_tb1 owner to securityadmin; +go +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: must be able to SET ROLE "securityadmin" + Server SQLState: 42501)~~ + + +ALTER procedure master_dbo.securityadmin_proc1 owner to securityadmin; +go +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: must be able to SET ROLE "securityadmin" + Server SQLState: 42501)~~ + + +ALTER function master_dbo.securityadmin_func1 owner to securityadmin; +go +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: must be able to SET ROLE "securityadmin" + Server SQLState: 42501)~~ + + +-- psql +-- drop role +drop role securityadmin_restrict_new_pg_role +go + +-- normal PG user +CREATE USER securityadmin_restrictions_pg_user WITH LOGIN CREATEROLE PASSWORD '12345678' inherit; +go + +-- psql user=securityadmin_restrictions_pg_user password=12345678 +-- a normal psql user should not be able to alter/grant/drop securityadmin from pg port +ALTER ROLE securityadmin NOCREATEROLE; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Babelfish-created logins/users/roles cannot be altered outside of a Babelfish session + Server SQLState: 42501)~~ + + +-- Altering a role by an underprivileged login should be restricted +alter user securityadmin_restrict_new_login with password '123' +go +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: permission denied to alter role + Detail: To change another role's password, the current user must have the CREATEROLE attribute and the ADMIN option on the role. + Server SQLState: 42501)~~ + + +ALTER ROLE securityadmin WITH PASSWORD '12345678'; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Babelfish-created logins/users/roles cannot be altered outside of a Babelfish session + Server SQLState: 42501)~~ + + +ALTER ROLE securityadmin VALID UNTIL 'infinity'; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Babelfish-created logins/users/roles cannot be altered outside of a Babelfish session + Server SQLState: 42501)~~ + + +ALTER ROLE securityadmin WITH CONNECTION LIMIT 1; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Babelfish-created logins/users/roles cannot be altered outside of a Babelfish session + Server SQLState: 42501)~~ + + +GRANT securityadmin TO securityadmin_restrict_new_login; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Babelfish-created logins/users/roles cannot be altered outside of a Babelfish session + Server SQLState: 42501)~~ + + +GRANT securityadmin_restrict_new_login TO securityadmin; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Babelfish-created logins/users/roles cannot be altered outside of a Babelfish session + Server SQLState: 42501)~~ + + +REVOKE securityadmin FROM master_dbo; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Babelfish-created logins/users/roles cannot be altered outside of a Babelfish session + Server SQLState: 42501)~~ + + +REVOKE sysadmin FROM securityadmin +go +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Babelfish-created logins/users/roles cannot be altered outside of a Babelfish session + Server SQLState: 42501)~~ + + +REVOKE securityadmin FROM securityadmin +go +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Babelfish-created logins/users/roles cannot be altered outside of a Babelfish session + Server SQLState: 42501)~~ + + +REVOKE master_dbo FROM securityadmin; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Babelfish-created logins/users/roles cannot be altered outside of a Babelfish session + Server SQLState: 42501)~~ + + +DROP ROLE securityadmin; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Babelfish-created logins/users/roles cannot be dropped or altered outside of a Babelfish session + Server SQLState: 42501)~~ + + +SET SESSION AUTHORIZATION securityadmin; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: permission denied to set session authorization + Server SQLState: 42501)~~ + + +SET ROLE securityadmin; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: permission denied to set role "securityadmin" + Server SQLState: 42501)~~ + + +-- tsql +EXEC sp_dropserver 'server_4229', 'droplogins' +GO + +EXEC sp_dropserver 'Accounts', 'droplogins' +GO + +-- terminate-tsql-conn + +-- psql +-- Drop extension only if not user mapping exists for bbf_server +-- Needed so that same test can be reused in upgrade in conjunction +-- with tests for OPENQUERY +DO +$$ +BEGIN +IF NOT EXISTS (SELECT * FROM pg_user_mappings WHERE srvname = 'bbf_server') THEN + SET client_min_messages = 'error'; + DROP EXTENSION tds_fdw CASCADE; +END IF; +END +$$ +GO + +-- psql +-- Need to terminate active session before cleaning up the login +SELECT pg_terminate_backend(pid) FROM pg_stat_get_activity(NULL) +WHERE sys.suser_name(usesysid) = 'securityadmin_restrict_new_login' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +go +~~START~~ +bool +t +~~END~~ + + +DROP USER securityadmin_restrictions_pg_user; +GO + +-- Wait to sync with another session +SELECT pg_sleep(1); +GO +~~START~~ +void + +~~END~~ + + +-- tsql + +ALTER SERVER ROLE sysadmin drop MEMBER securityadmin_restrict_new_login; +GO + +DROP LOGIN securityadmin_restrict_new_login +GO diff --git a/test/JDBC/expected/single_db/BABEL-2403.out b/test/JDBC/expected/single_db/BABEL-2403.out index cb9a19347f..f23cb91110 100644 --- a/test/JDBC/expected/single_db/BABEL-2403.out +++ b/test/JDBC/expected/single_db/BABEL-2403.out @@ -69,6 +69,8 @@ name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_login_ext text#!#sys#!#name#!#{"Rule": " in babelfish_authid_login_ext must also exist in babelfish_sysdatabases"} name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_login_ext must also exist in pg_authid"} text#!#sys#!#name#!#{"Rule": " in babelfish_authid_login_ext must also exist in babelfish_sysdatabases"} +name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_login_ext must also exist in pg_authid"} +text#!#sys#!#name#!#{"Rule": " in babelfish_authid_login_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"} @@ -146,6 +148,8 @@ name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_login_ext text#!#sys#!#name#!#{"Rule": " in babelfish_authid_login_ext must also exist in babelfish_sysdatabases"} name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_login_ext must also exist in pg_authid"} text#!#sys#!#name#!#{"Rule": " in babelfish_authid_login_ext must also exist in babelfish_sysdatabases"} +name#!#pg_catalog#!#rolname#!#{"Rule": " in babelfish_authid_login_ext must also exist in pg_authid"} +text#!#sys#!#name#!#{"Rule": " in babelfish_authid_login_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"} 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 9e09597c85..87a7f7ea48 100644 --- a/test/JDBC/expected/single_db/BABEL-LOGIN-USER-EXT.out +++ b/test/JDBC/expected/single_db/BABEL-LOGIN-USER-EXT.out @@ -277,7 +277,7 @@ SELECT COUNT(*) FROM sys.babelfish_authid_login_ext; go ~~START~~ int -3 +4 ~~END~~ @@ -288,7 +288,7 @@ SELECT COUNT(*) FROM sys.babelfish_authid_login_ext; go ~~START~~ int -4 +5 ~~END~~ @@ -300,7 +300,7 @@ SELECT COUNT(*) FROM sys.babelfish_authid_login_ext; go ~~START~~ int -5 +6 ~~END~~ @@ -388,7 +388,7 @@ SELECT COUNT(*) FROM sys.babelfish_authid_login_ext; go ~~START~~ int -4 +5 ~~END~~ @@ -418,7 +418,7 @@ SELECT COUNT(*) FROM sys.babelfish_authid_login_ext; go ~~START~~ int -3 +4 ~~END~~ @@ -489,14 +489,14 @@ ALTER SERVER ROLE db_owner ADD MEMBER dummy; GO ~~ERROR (Code: 33557097)~~ -~~ERROR (Message: only sysadmin role is supported in ALTER SERVER ROLE statement)~~ +~~ERROR (Message: Only fixed server role is supported in ALTER SERVER ROLE statement)~~ ALTER SERVER ROLE db_owner DROP MEMBER dummy; GO ~~ERROR (Code: 33557097)~~ -~~ERROR (Message: only sysadmin role is supported in ALTER SERVER ROLE statement)~~ +~~ERROR (Message: Only fixed server role is supported in ALTER SERVER ROLE statement)~~ CREATE LOGIN err_user WITH PASSWORD = '123'; diff --git a/test/JDBC/expected/sys-server_principals-vu-verify.out b/test/JDBC/expected/sys-server_principals-vu-verify.out index 5290e40805..aef130e734 100644 --- a/test/JDBC/expected/sys-server_principals-vu-verify.out +++ b/test/JDBC/expected/sys-server_principals-vu-verify.out @@ -63,6 +63,7 @@ GO varchar#!#char#!#nvarchar#!#varchar#!#varchar#!#int#!#int#!#bit jdbc_user#!#S#!#SQL_LOGIN#!#master#!#English#!#-1#!#-1#!#0 public#!#R#!#SERVER_ROLE#!##!##!##!#1#!#0 +securityadmin#!#R#!#SERVER_ROLE#!##!#English#!##!#1#!#1 sys_server_principals_vu_login_without_sa#!#S#!#SQL_LOGIN#!#master#!#English#!#-1#!#-1#!#0 sysadmin#!#R#!#SERVER_ROLE#!##!#English#!##!#1#!#1 ~~END~~ diff --git a/test/JDBC/input/securityadmin_role-vu-cleanup.mix b/test/JDBC/input/securityadmin_role-vu-cleanup.mix new file mode 100644 index 0000000000..5523e86385 --- /dev/null +++ b/test/JDBC/input/securityadmin_role-vu-cleanup.mix @@ -0,0 +1,63 @@ +-- tsql +drop user securityadmin_user1 +go + +drop user no_securityadmin_user1 +go + +drop login securityadmin_login1 +go + +use securityadmin_db1 +go + +drop user no_securityadmin_user1 +go + +use master +go + +drop login no_securityadmin_login1 +go + +drop database securityadmin_db1 +go + +drop schema securityadmin_scm1 +go + +drop view securityadmin_show_role_mem +go + +drop TRIGGER securityadmin_tggr1 +go + +drop table securityadmin_tb1 +go + +drop view securityadmin_v1 +go + +drop function securityadmin_func1() +go + +drop procedure securityadmin_proc1 +go + +drop procedure securityadmin_create_login_p1 +go + +drop procedure securityadmin_alter_login_p1 +go + +drop procedure securityadmin_drop_login_p1 +go + +drop procedure securityadmin_add_mem_p1 +go + +drop procedure securityadmin_drop_mem_p1 +go + +drop role securityadmin_rol +go \ No newline at end of file diff --git a/test/JDBC/input/securityadmin_role-vu-prepare.mix b/test/JDBC/input/securityadmin_role-vu-prepare.mix new file mode 100644 index 0000000000..6c901dbafa --- /dev/null +++ b/test/JDBC/input/securityadmin_role-vu-prepare.mix @@ -0,0 +1,90 @@ +-- tsql +create login securityadmin_login1 with password = '123' +go + +create login no_securityadmin_login1 with password = '123' +go + +create user securityadmin_user1 for login securityadmin_login1 +go + +create user no_securityadmin_user1 for login no_securityadmin_login1 +go + +-- tsql +create role securityadmin_rol +go + +create database securityadmin_db1 +go + +create schema securityadmin_scm1 +go + +CREATE VIEW securityadmin_show_role_mem AS +SELECT +roles.name AS RolePrincipalName +, members.name AS MemberPrincipalName +FROM sys.server_role_members AS server_role_members +INNER JOIN sys.server_principals AS roles + ON server_role_members.role_principal_id = roles.principal_id +INNER JOIN sys.server_principals AS members + ON server_role_members.member_principal_id = members.principal_id order by MemberPrincipalName; +GO + +create table securityadmin_tb1(a int) +go + +create view securityadmin_v1 as select 1; +go + +create function securityadmin_func1() returns int as begin return 1 end; +go + +create procedure securityadmin_proc1 as begin select 1; end +go + +CREATE TRIGGER securityadmin_tggr1 on securityadmin_tb1 AFTER INSERT AS BEGIN END; +go + +create procedure securityadmin_create_login_p1 as begin create login securityadmin_login_new with password ='123'; end +go + +Grant execute on securityadmin_create_login_p1 to PUBLIC; +go + +create procedure securityadmin_alter_login_p1 as begin alter login securityadmin_login_new with password ='1234'; end +go + +Grant execute on securityadmin_alter_login_p1 to PUBLIC; +go + +create procedure securityadmin_drop_login_p1 as begin drop login securityadmin_login_new; end +go + +Grant execute on securityadmin_drop_login_p1 to PUBLIC; +go + +create procedure securityadmin_add_mem_p1 as begin Alter server role securityadmin add member securityadmin_login_new; end +go + +Grant execute on securityadmin_add_mem_p1 to PUBLIC; +go + +create procedure securityadmin_drop_mem_p1 as begin Alter server role securityadmin drop member securityadmin_login_new; end +go + +Grant execute on securityadmin_drop_mem_p1 to PUBLIC; +go + +use securityadmin_db1 +go + +create user securityadmin_user1 for login securityadmin_login1 +go + +create user no_securityadmin_user1 for login no_securityadmin_login1 +go + +use master +go \ No newline at end of file diff --git a/test/JDBC/input/securityadmin_role-vu-verify.mix b/test/JDBC/input/securityadmin_role-vu-verify.mix new file mode 100644 index 0000000000..f121db6062 --- /dev/null +++ b/test/JDBC/input/securityadmin_role-vu-verify.mix @@ -0,0 +1,907 @@ +-- tsql +alter login securityadmin_login1 with password='123' +go + +alter login no_securityadmin_login1 with password='123' +go + +-- make login member of securityadmin +Alter server role securityadmin add member securityadmin_login1 +go + +select * from securityadmin_show_role_mem where MemberPrincipalName like 'jdbc_user' or MemberPrincipalName like '%securityadmin_%' +go + +-- should error out +create login securityadmin with password = '123' +go + +-- terminate-tsql-conn + +-- Case 1 - positives +-- securityadmin's login privileges +-- tsql user=securityadmin_login1 password=123 +-- alter server role securityadmin should be allowed +select bbf_is_member_of_role_nosuper(suser_id(), suser_id('securityadmin')) +go + +select bbf_is_member_of_role_nosuper(suser_id(), suser_id('sysadmin')) +go + +Alter server role securityadmin add member no_securityadmin_login1 +go + +Alter server role securityadmin drop member no_securityadmin_login1 +go + +-- create login should be allowed +-- windows login +create login [babel\securityadmin_l1] from windows; +go + +-- password based login +create login securityadmin_l2 with password = '123' +go + +-- alter login should be allowed +-- password based login +alter login securityadmin_l2 with password = '123' +go + +ALTER LOGIN securityadmin_l2 WITH PASSWORD = '1234' OLD_PASSWORD = '123'; +go + +ALTER LOGIN securityadmin_l2 disable; +go + +ALTER LOGIN securityadmin_l2 enable; +go + +ALTER LOGIN securityadmin_l2 with default_database=securityadmin_db1; +go + +-- windows login +alter login [babel\securityadmin_l1] with PASSWORD='123' +go + +ALTER LOGIN [babel\securityadmin_l1] WITH PASSWORD = '1234' OLD_PASSWORD = '123'; +go + +ALTER LOGIN [babel\securityadmin_l1] disable; +go + +ALTER LOGIN [babel\securityadmin_l1] enable; +go + +ALTER LOGIN [babel\securityadmin_l1] with default_database=securityadmin_db1; +go + +-- make altering login member of securityadmin +Alter server role securityadmin add member securityadmin_l2 +go + +-- alter securityadmin member login +-- allowed +alter login securityadmin_l2 with password = '123' +go + +-- drop login should be allowed +-- password based login +drop login securityadmin_l2 +go + +-- windows login +drop login [babel\securityadmin_l1] +go + +-- grant server permissions (currently not supported) +-- few examples +GRANT CONTROL SERVER TO no_securityadmin_login1 +go + +GRANT ALTER ANY EVENT NOTIFICATION TO no_securityadmin_login1 WITH GRANT OPTION; +go + +GRANT ALTER ANY DATABASE TO no_securityadmin_login1; +go + +-- grant database permissions (only connect is supported) + +-- terminate-tsql-conn user=securityadmin_login1 password=123 + +-- allowed +-- tsql user=no_securityadmin_login1 password=123 +use securityadmin_db1 +go + +-- terminate-tsql-conn user=no_securityadmin_login1 password=123 + +-- tsql user=securityadmin_login1 password=123 database=securityadmin_db1 +REVOKE CONNECT FROM no_securityadmin_user1 +go + +-- unsupported +GRANT SHOWPLAN TO no_securityadmin_user1; +go + +GRANT CREATE VIEW TO no_securityadmin_user1 WITH GRANT OPTION; +go + +-- terminate-tsql-conn user=securityadmin_login1 password=123 database=securityadmin_db1 + +-- connection revoked +-- tsql user=no_securityadmin_login1 password=123 +use securityadmin_db1 +go + +-- terminate-tsql-conn user=no_securityadmin_login1 password=123 + +-- revoke server permissions (currently not supported) +-- few examples +-- tsql user=securityadmin_login1 password=123 database=securityadmin_db1 +REVOKE CONTROL SERVER FROM no_securityadmin_login1 +go + +REVOKE ALTER ANY EVENT NOTIFICATION FROM no_securityadmin_login1; +go + +REVOKE ALTER ANY DATABASE FROM no_securityadmin_login1; +go + +-- grant database permissions (only connect is supported) +GRANT CONNECT TO no_securityadmin_user1 +go + +-- terminate-tsql-conn user=securityadmin_login1 password=123 database=securityadmin_db1 + +-- tsql user=no_securityadmin_login1 password=123 +use securityadmin_db1 +go + +-- Check unprivileged login should not have access +-- permission denied +EXEC sp_addlinkedsrvlogin 'Accounts', 'False' +GO + +EXEC sp_droplinkedsrvlogin 'Accounts', NULL +GO + +Alter server role securityadmin add member no_securityadmin_login1 +GO + +Alter server role securityadmin drop member no_securityadmin_login1 +GO + +-- only current login and fixed server roles +SELECT name, type, type_desc, default_database_name, default_language_name, credential_id, owning_principal_id, is_fixed_role +FROM sys.server_principals ORDER BY name +GO + +-- only current login +select name, type, usage from sys.login_token order by name; +go + +-- terminate-tsql-conn user=no_securityadmin_login1 password=123 + +-- tsql user=securityadmin_login1 password=123 +-- unsupported +REVOKE SHOWPLAN FROM no_securityadmin_user1; +go + +REVOKE CREATE VIEW FROM no_securityadmin_user1; +go + +-- System objects +-- All rows of server_prinicipals view should be visible to securityadmin login +-- limited rows should get displayed +SELECT name, type, type_desc, default_database_name, default_language_name, credential_id, owning_principal_id, is_fixed_role +FROM sys.server_principals +WHERE name in ('jdbc_user', 'sysadmin', 'public', 'securityadmin') ORDER BY name; +GO + +SELECT name, type, type_desc, default_database_name, default_language_name, credential_id, owning_principal_id, is_fixed_role +FROM sys.server_principals name WHERE name like '%securityadmin%' ORDER BY name; +GO + +-- current login along with current fixed role should be visible +select name, type, usage from sys.login_token order by name; +go + +select name, sysadmin, securityadmin from syslogins where name like '%securityadmin%' order by name +go + +-- should return 0 +select is_srvrolemember ('sysadmin') +go + +-- should return 1 +select is_srvrolemember ('securityadmin') +go + +select is_srvrolemember ('securityadmin', 'securityadmin_login1') +go + +-- terminate-tsql-conn user=securityadmin_login1 password=123 + +-- psql +CREATE EXTENSION IF NOT EXISTS tds_fdw; +GO + +-- tsql +-- Add localhost as linked server +EXEC sp_addlinkedserver @server = N'server_4229', @srvproduct=N'', @provider=N'SQLNCLI', @datasrc=N'localhost', @catalog=N'master' +GO + +EXEC sp_addlinkedserver 'Accounts' +GO + +-- Add jdbc_user as linked server login +EXEC sp_addlinkedsrvlogin @rmtsrvname = 'server_4229', @useself = 'FALSE', @rmtuser = 'jdbc_user', @rmtpassword = '12345678' +GO + +drop database securityadmin_db1 +go + +-- terminate-tsql-conn + +-- tsql user=securityadmin_login1 password=123 +EXEC sp_addlinkedsrvlogin 'Accounts', 'False' +GO + +EXEC sp_droplinkedsrvlogin 'Accounts', NULL +GO + +-- inside procedure +exec securityadmin_create_login_p1 +go + +exec securityadmin_alter_login_p1 +go + +exec securityadmin_add_mem_p1 +go + +exec securityadmin_drop_mem_p1 +go + +exec securityadmin_drop_login_p1 +go + +-- terminate-tsql-conn user=securityadmin_login1 password=123 + +-- login is member of both securityadmin as well as sysadmin +-- tsql +drop user securityadmin_user1 +go + +Alter server role sysadmin add member securityadmin_login1 +go + +create database securityadmin_db1 +go + +-- terminate-tsql-conn + +-- it should be able to connect to the database +-- tsql user=securityadmin_login1 password=123 +use securityadmin_db1 +go + +-- it should be dbo +select current_user +go + +-- both attribute should be true +select rolname, rolcreaterole, rolcreatedb from pg_roles where rolname = 'securityadmin_login1' +go + +-- terminate-tsql-conn user=securityadmin_login1 password=123 + +-- only member of securityadmin +-- tsql +alter server role sysadmin drop member securityadmin_login1 +go + +create user securityadmin_user1 for login securityadmin_login1 +go + +-- terminate-tsql-conn + +-- tsql user=securityadmin_login1 password=123 + +-- only rolcreaterole attribute should be true +select rolname, rolcreaterole, rolcreatedb from pg_roles where rolname = 'securityadmin_login1' +go + +-- should be able to create/drop login +create login test_securityadmin_l1 with password ='123' +go + +drop login test_securityadmin_l1 +go + +-- terminate-tsql-conn user=securityadmin_login1 password=123 + +-- tsql +-- only member of sysadmin +drop user securityadmin_user1 +go + +alter server role sysadmin add member securityadmin_login1 +go + +alter server role securityadmin drop member securityadmin_login1 +go + +-- terminate-tsql-conn + +-- tsql user=securityadmin_login1 password=123 + +-- both attribute should be true +select rolname, rolcreaterole, rolcreatedb from pg_roles where rolname = 'securityadmin_login1' +go + +-- should be able to create/drop login +create login test_securityadmin_l1 with password ='123' +go + +drop login test_securityadmin_l1 +go + +-- should return 1 +select is_srvrolemember ('sysadmin') +go + +-- should return 1 +select is_srvrolemember ('securityadmin') +go + +-- terminate-tsql-conn user=securityadmin_login1 password=123 + +-- tsql +-- make it member of securityadmin only +alter server role sysadmin drop member securityadmin_login1 +go + +alter server role securityadmin add member securityadmin_login1 +go + +drop user no_securityadmin_user1 +go + +alter server role sysadmin add member no_securityadmin_login1 +go + +create user securityadmin_user1 for login securityadmin_login1 +go + +-- terminate-tsql-conn + +-- tsql user=securityadmin_login1 password=123 +-- Case 2 - negatives +-- alter server role sysadmin should give permission denied +Alter server role sysadmin add member no_securityadmin_login1 +go + +-- alter server role securityadmin add member db roles should error out +Alter server role securityadmin add member guest +go + +-- alter sysadmin login should give permission denied +-- login which is altered is member of sysadmin +Alter login no_securityadmin_login1 with password ='123' +go + +-- terminate-tsql-conn user=securityadmin_login1 password=123 + +-- tsql +-- make member of securityadmin as well +alter server role securityadmin add member no_securityadmin_login1 +go + +-- terminate-tsql-conn + +-- tsql user=securityadmin_login1 password=123 +-- login which is altered is member of sysadmin and securityadmin both +-- permission denied +Alter login no_securityadmin_login1 with password ='123' +go + +-- terminate-tsql-conn user=securityadmin_login1 password=123 + +-- tsql +alter server role securityadmin drop member no_securityadmin_login1 +go + +alter server role sysadmin drop member no_securityadmin_login1 +go + +create user no_securityadmin_user1 for login no_securityadmin_login1 +go + +create role dummy_role +go + +drop database securityadmin_db1 +go + +-- terminate-tsql-conn + +-- tsql user=securityadmin_login1 password=123 +-- should error out +Alter server role securityadmin add member dummy_role +go + +-- create database permission denied +create database perm_denied_db +go + +-- terminate-tsql-conn user=securityadmin_login1 password=123 + +-- tsql +drop role dummy_role +go + +create database securityadmin_db1 +go + +use securityadmin_db1 +go + +create user securityadmin_user1 for login securityadmin_login1 +go + +create user no_securityadmin_user1 for login no_securityadmin_login1 +go + +-- terminate-tsql-conn + +-- tsql user=securityadmin_login1 password=123 +-- alter database permission denied +alter database securityadmin_db1 modify name = rename_db_database1; +go + +alter authorization on database::securityadmin_db1 to no_securityadmin_login1 +go + +-- drop database permission denied +drop database securityadmin_db1 +go + +-- securityadmin login's mapped user should not have any priv +select current_user, db_name() +go + +select suser_name() +go + +-- allowed +create login securityadmin_l2 with password = '123' +go + +-- create objects/user permission denied +create user securityadmin_l2 +go + +create role securityadmin_role1 +go + +create schema perm_denied_scm +go + +create view perm_denied_v1 as select 1; +go + +create table perm_denied_tb1 (a int); +go + +select 1 into perm_denied_tb2; +go + +create function perm_denied_func1() returns int as begin return 1 end; +go + +create procedure perm_denied_proc1 as begin select 1; end +go + +create type perm_denied_typ1 from int; +go + +create index perm_denied_index1 on securityadmin_tb1(a); +go + +CREATE FUNCTION perm_denied_func1() RETURNS TABLE AS RETURN ( SELECT 1 AS Value); +go + +-- DMLS on object permission denied +Alter user no_securityadmin_user1 with DEFAULT_SCHEMA=securityadmin_scm1 +go + +Alter role securityadmin_rol add member no_securityadmin_user1 +go + +Alter role securityadmin_rol drop member no_securityadmin_user1 +go + +Alter table securityadmin_tb1 add b int +go + +Insert into securityadmin_tb1 values (1) +go + +UPDATE securityadmin_tb1 SET a = 2 where a = 1; +go + +DELETE FROM securityadmin_tb1 WHERE a = 1; +go + +TRUNCATE TABLE securityadmin_tb1; +go + +select * from securityadmin_tb1 +go + +select * from securityadmin_v1 +go + +select securityadmin_func1() +go + +exec securityadmin_proc1 +go + +Enable trigger securityadmin_tggr1 on securityadmin_tb1 +go + +Disable trigger securityadmin_tggr1 on securityadmin_tb1 +go + +-- grant on objects permission denied +Grant select on securityadmin_tb1 to no_securityadmin_user1 +go + +Grant update on securityadmin_v1 to no_securityadmin_user1 +go + +Grant update on securityadmin_v1 to no_securityadmin_user1 +go + +Grant exec on securityadmin_func1 to no_securityadmin_user1 +go + +Grant exec on securityadmin_proc1 to no_securityadmin_user1 +go + +-- Revoke on objects permission denied +Revoke select on securityadmin_tb1 from no_securityadmin_user1 +go + +Revoke update on securityadmin_v1 from no_securityadmin_user1 +go + +Revoke update on securityadmin_v1 from no_securityadmin_user1 +go + +Revoke exec on securityadmin_func1 from no_securityadmin_user1 +go + +Revoke exec on securityadmin_proc1 from no_securityadmin_user1 +go + +-- grant on schema +-- permission denied +grant select on securityadmin_v1 to no_securityadmin_user1; +go +grant select on dbo.securityadmin_v1 to no_securityadmin_user1; +go +grant execute on securityadmin_proc1 to no_securityadmin_user1; +go +grant execute on dbo.securityadmin_proc1 to no_securityadmin_user1; +go + +-- revoke on schema +-- permission denied +revoke select on securityadmin_v1 from no_securityadmin_user1; +go +revoke select on dbo.securityadmin_v1 from no_securityadmin_user1; +go +revoke execute on securityadmin_proc1 from no_securityadmin_user1; +go +revoke execute on dbo.securityadmin_proc1 from no_securityadmin_user1; +go + +-- drop object permission denied +drop user securityadmin_l2 +go + +drop role securityadmin_rol +go + +drop schema securityadmin_scm1 +go + +drop view securityadmin_show_role_mem +go + +drop TRIGGER securityadmin_tggr1 +go + +drop table securityadmin_tb1 +go + +drop view securityadmin_v1 +go + +drop function securityadmin_func1() +go + +drop procedure securityadmin_proc1 +go + +-- allowed drop login +drop login securityadmin_l2 +go + +-- terminate-tsql-conn user=securityadmin_login1 password=123 + +-- securityadmin login should not get mapped to dbo if no user exist, it should disconnect + +-- tsql database=securityadmin_db1 +drop user securityadmin_user1 +go + +-- terminate-tsql-conn database=securityadmin_db1 + +-- it should disconnect +-- tsql user=securityadmin_login1 password=123 +use securityadmin_db1 +go + +-- Case 3 - alter server role other than securityadmin and sysadmin should give unsupported +-- tsql +Alter server role false_role add member no_securityadmin_login1 +go + +Alter server role serveradmin add member no_securityadmin_login1 +go + +Alter server role setupadmin add member no_securityadmin_login1 +go + +Alter server role processadmin add member no_securityadmin_login1 +go + +Alter server role diskadmin add member no_securityadmin_login1 +go + +Alter server role bulkadmin add member no_securityadmin_login1 +go + +Alter server role false_role drop member no_securityadmin_login1 +go + +Alter server role serveradmin drop member no_securityadmin_login1 +go + +Alter server role setupadmin drop member no_securityadmin_login1 +go + +Alter server role processadmin drop member no_securityadmin_login1 +go + +Alter server role diskadmin drop member no_securityadmin_login1 +go + +Alter server role bulkadmin drop member no_securityadmin_login1 +go + +-- terminate-tsql-conn user=securityadmin_login1 password=123 + +-- Case 4 - check unintended/unauthorized use of securityadmin +-- tsql +CREATE LOGIN securityadmin_restrict_new_login WITH password = '12345678'; +go + +ALTER SERVER ROLE sysadmin ADD MEMBER securityadmin_restrict_new_login; +GO + +select * from securityadmin_show_role_mem where MemberPrincipalName like 'jdbc_user' or MemberPrincipalName like '%securityadmin_%' +go + +-- terminate-tsql-conn + +-- tsql user=securityadmin_restrict_new_login password=12345678 +select * from securityadmin_show_role_mem where MemberPrincipalName like 'jdbc_user' or MemberPrincipalName like '%securityadmin_%' +go + +select bbf_is_member_of_role_nosuper(suser_id(), suser_id('securityadmin')) +go + +select bbf_is_member_of_role_nosuper(suser_id(), suser_id('sysadmin')) +go + +select is_srvrolemember ('sysadmin') +go + +select is_srvrolemember ('securityadmin') +go + +select current_user, db_name() +go + +CREATE ROLE securityadmin_restrictions_role; +GO + +-- a tsql login should not be able to drop securityadmin explicitly from tsql port + +-- should be denied +ALTER ROLE securityadmin_restrictions_role ADD MEMBER securityadmin; +GO + +DROP LOGIN securityadmin; +GO + +DROP ROLE securityadmin_restrictions_role; +GO + +-- terminate-tsql-conn user=securityadmin_restrict_new_login password=12345678 + +-- psql +create role securityadmin_restrict_new_pg_role +go + +-- psql user=securityadmin_restrict_new_login password=12345678 +-- a tsql login should not be able to alter/grant/drop securityadmin from pg port +ALTER ROLE securityadmin NOCREATEROLE; +GO + +ALTER ROLE securityadmin WITH PASSWORD '12345678'; +GO + +ALTER ROLE securityadmin VALID UNTIL 'infinity'; +GO + +ALTER ROLE securityadmin WITH CONNECTION LIMIT 1; +GO + +GRANT securityadmin TO securityadmin_restrict_new_login; +GO + +GRANT securityadmin TO securityadmin_restrict_new_pg_role +GO + +GRANT sysadmin TO securityadmin +go + +GRANT securityadmin TO securityadmin +go + +GRANT securityadmin_restrict_new_login TO securityadmin; +GO + +REVOKE securityadmin FROM master_dbo; +GO + +REVOKE master_dbo FROM securityadmin; +GO + +DROP ROLE securityadmin; +GO + +SET SESSION AUTHORIZATION securityadmin; +GO + +SET ROLE securityadmin; +GO + +-- try granting object ownership to securityadmin +ALTER schema master_securityadmin_scm1 owner to securityadmin; +go + +ALTER table master_dbo.securityadmin_tb1 owner to securityadmin; +go + +ALTER procedure master_dbo.securityadmin_proc1 owner to securityadmin; +go + +ALTER function master_dbo.securityadmin_func1 owner to securityadmin; +go + +-- psql +-- drop role +drop role securityadmin_restrict_new_pg_role +go + +-- normal PG user +CREATE USER securityadmin_restrictions_pg_user WITH LOGIN CREATEROLE PASSWORD '12345678' inherit; +go + +-- psql user=securityadmin_restrictions_pg_user password=12345678 +-- a normal psql user should not be able to alter/grant/drop securityadmin from pg port +ALTER ROLE securityadmin NOCREATEROLE; +GO + +-- Altering a role by an underprivileged login should be restricted +alter user securityadmin_restrict_new_login with password '123' +go + +ALTER ROLE securityadmin WITH PASSWORD '12345678'; +GO + +ALTER ROLE securityadmin VALID UNTIL 'infinity'; +GO + +ALTER ROLE securityadmin WITH CONNECTION LIMIT 1; +GO + +GRANT securityadmin TO securityadmin_restrict_new_login; +GO + +GRANT securityadmin_restrict_new_login TO securityadmin; +GO + +REVOKE securityadmin FROM master_dbo; +GO + +REVOKE sysadmin FROM securityadmin +go + +REVOKE securityadmin FROM securityadmin +go + +REVOKE master_dbo FROM securityadmin; +GO + +DROP ROLE securityadmin; +GO + +SET SESSION AUTHORIZATION securityadmin; +GO + +SET ROLE securityadmin; +GO + +-- tsql +EXEC sp_dropserver 'server_4229', 'droplogins' +GO + +EXEC sp_dropserver 'Accounts', 'droplogins' +GO + +-- terminate-tsql-conn + +-- psql +-- Drop extension only if not user mapping exists for bbf_server +-- Needed so that same test can be reused in upgrade in conjunction +-- with tests for OPENQUERY +DO +$$ +BEGIN +IF NOT EXISTS (SELECT * FROM pg_user_mappings WHERE srvname = 'bbf_server') THEN + SET client_min_messages = 'error'; + DROP EXTENSION tds_fdw CASCADE; +END IF; +END +$$ +GO + +-- psql +-- Need to terminate active session before cleaning up the login +SELECT pg_terminate_backend(pid) FROM pg_stat_get_activity(NULL) +WHERE sys.suser_name(usesysid) = 'securityadmin_restrict_new_login' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +go + +DROP USER securityadmin_restrictions_pg_user; +GO + +-- Wait to sync with another session +SELECT pg_sleep(1); +GO + +-- tsql + +ALTER SERVER ROLE sysadmin drop MEMBER securityadmin_restrict_new_login; +GO + +DROP LOGIN securityadmin_restrict_new_login +GO \ No newline at end of file diff --git a/test/JDBC/upgrade/15_5/schedule b/test/JDBC/upgrade/15_5/schedule index 3712409209..7b89244f1e 100644 --- a/test/JDBC/upgrade/15_5/schedule +++ b/test/JDBC/upgrade/15_5/schedule @@ -532,4 +532,4 @@ binary-datatype-operators cast-varchar-to-time xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 - +securityadmin_role diff --git a/test/JDBC/upgrade/15_6/schedule b/test/JDBC/upgrade/15_6/schedule index 5b1e557dd2..1796d4172a 100644 --- a/test/JDBC/upgrade/15_6/schedule +++ b/test/JDBC/upgrade/15_6/schedule @@ -548,4 +548,4 @@ binary-datatype-operators cast-varchar-to-time xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 - +securityadmin_role diff --git a/test/JDBC/upgrade/15_7/schedule b/test/JDBC/upgrade/15_7/schedule index 055ff30986..91f4348797 100644 --- a/test/JDBC/upgrade/15_7/schedule +++ b/test/JDBC/upgrade/15_7/schedule @@ -556,4 +556,4 @@ cast-varchar-to-time xml_exist-before-16_5 GRANT_SCHEMA-before-15_9-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 - +securityadmin_role diff --git a/test/JDBC/upgrade/15_8/schedule b/test/JDBC/upgrade/15_8/schedule index 16ecddfa0c..17d42f25ad 100644 --- a/test/JDBC/upgrade/15_8/schedule +++ b/test/JDBC/upgrade/15_8/schedule @@ -547,4 +547,4 @@ cast-varchar-to-time xml_exist-before-16_5 GRANT_SCHEMA-before-15_9-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 - +securityadmin_role diff --git a/test/JDBC/upgrade/15_9/schedule b/test/JDBC/upgrade/15_9/schedule index 5202e73a83..951c7bb158 100644 --- a/test/JDBC/upgrade/15_9/schedule +++ b/test/JDBC/upgrade/15_9/schedule @@ -543,6 +543,7 @@ space replace binary-datatype-operators SELECT_INTO_TEST +securityadmin_role cast-varchar-to-time xml_exist-before-16_5 BABEL-5119 diff --git a/test/JDBC/upgrade/16_1/schedule b/test/JDBC/upgrade/16_1/schedule index 93fc5b3a28..c2f1051423 100644 --- a/test/JDBC/upgrade/16_1/schedule +++ b/test/JDBC/upgrade/16_1/schedule @@ -539,6 +539,7 @@ space replace-before-15_8-or-16_4 binary-datatype-operators cast-varchar-to-time +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 ca2efcfdef..c58cd6893c 100644 --- a/test/JDBC/upgrade/16_2/schedule +++ b/test/JDBC/upgrade/16_2/schedule @@ -556,4 +556,4 @@ binary-datatype-operators cast-varchar-to-time xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 - +securityadmin_role diff --git a/test/JDBC/upgrade/16_3/schedule b/test/JDBC/upgrade/16_3/schedule index 1dcc7f4d17..a3d8eafdbe 100644 --- a/test/JDBC/upgrade/16_3/schedule +++ b/test/JDBC/upgrade/16_3/schedule @@ -560,3 +560,4 @@ cast-varchar-to-time xml_exist-before-16_5 GRANT_SCHEMA-before-15_9-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 +securityadmin_role diff --git a/test/JDBC/upgrade/16_4/schedule b/test/JDBC/upgrade/16_4/schedule index 01cf2abf5f..376bc96d6e 100644 --- a/test/JDBC/upgrade/16_4/schedule +++ b/test/JDBC/upgrade/16_4/schedule @@ -572,3 +572,4 @@ xml_exist-before-16_5 BABEL-5119 GRANT_SCHEMA-before-15_9-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 +securityadmin_role diff --git a/test/JDBC/upgrade/latest/schedule b/test/JDBC/upgrade/latest/schedule index aa3f9e6696..7c7d02de2a 100644 --- a/test/JDBC/upgrade/latest/schedule +++ b/test/JDBC/upgrade/latest/schedule @@ -571,6 +571,7 @@ replicate space SELECT_INTO_TEST binary-datatype-operators +securityadmin_role sys_dm_os_sys_info cast-varchar-to-time xml_exist diff --git a/test/python/expected/upgrade_validation/expected_dependency.out b/test/python/expected/upgrade_validation/expected_dependency.out index 876eca452f..0899d9360f 100644 --- a/test/python/expected/upgrade_validation/expected_dependency.out +++ b/test/python/expected/upgrade_validation/expected_dependency.out @@ -213,6 +213,7 @@ Function sys.bbf_binary_varbinary_cmp(sys.bbf_binary,sys.bbf_varbinary) Function sys.bbf_get_context_info() Function sys.bbf_get_current_physical_schema_name(text) Function sys.bbf_get_immediate_base_type_of_udt(oid) +Function sys.bbf_is_member_of_role_nosuper(oid,oid) Function sys.bbf_is_shared_schema(text) Function sys.bbf_string_agg_finalfn_nvarchar(internal) Function sys.bbf_string_agg_finalfn_varchar(internal) From 82d5e328c854602cb4ec3f930d4d7c521402f28b 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 18/44] Support fixed database role db_accessadmin (#66) * support db_accessadmin Signed-off-by: Tanzeel Khan * empty commit to rerun actions Signed-off-by: Tanzeel Khan * add basic tests Signed-off-by: Tanzeel Khan * fix get_authid_user_ext_physical_name Signed-off-by: Tanzeel Khan * refactor Signed-off-by: Tanzeel Khan * refactor is_role() & is_user() to one function Signed-off-by: Tanzeel Khan * address comments Signed-off-by: Tanzeel Khan * fix Signed-off-by: Tanzeel Khan * fix Signed-off-by: Tanzeel Khan * empty commit to rerun actions Signed-off-by: Tanzeel Khan * fix Signed-off-by: Tanzeel Khan * fix Signed-off-by: Tanzeel Khan * fix Signed-off-by: Tanzeel Khan * add test to upgrade Signed-off-by: Tanzeel Khan * add test to upgrade Signed-off-by: Tanzeel Khan * fix tests Signed-off-by: Tanzeel Khan * fix Signed-off-by: Tanzeel Khan * fix Signed-off-by: Tanzeel Khan * fix Signed-off-by: Tanzeel Khan * fix Signed-off-by: Tanzeel Khan * fix Signed-off-by: Tanzeel Khan * fix Signed-off-by: Tanzeel Khan * empty Signed-off-by: Tanzeel Khan * see dump restore actions logs Signed-off-by: Tanzeel Khan * ssh into github actions host Signed-off-by: Tanzeel Khan * remove temp changes and reset password for login in verify file Signed-off-by: Tanzeel Khan * empty Signed-off-by: Tanzeel Khan * refactor Signed-off-by: Tanzeel Khan * fix tests Signed-off-by: Tanzeel Khan * refactor Signed-off-by: Tanzeel Khan * fix is_member Signed-off-by: Tanzeel Khan * fix is_member Signed-off-by: Tanzeel Khan * fix Signed-off-by: Tanzeel Khan * refactor upgrade function for creating roles Signed-off-by: Tanzeel Khan * refactor Signed-off-by: Tanzeel Khan * fix merge issue Signed-off-by: Tanzeel Khan * refactor name for upgrade function Signed-off-by: Tanzeel Khan * use IS_BBF_BUILT_IN_DB macro in some more places Signed-off-by: Tanzeel Khan * empty Signed-off-by: Tanzeel Khan * fix upgrade file Signed-off-by: Tanzeel Khan * fix typo Signed-off-by: Tanzeel Khan --------- Signed-off-by: Tanzeel Khan --- .../babelfishpg_tsql/sql/babelfishpg_tsql.sql | 16 +- contrib/babelfishpg_tsql/sql/ownership.sql | 8 +- .../babelfishpg_tsql/sql/sys_functions.sql | 4 +- .../babelfishpg_tsql--4.3.0--4.4.0.sql | 215 ++++++- contrib/babelfishpg_tsql/src/catalog.c | 166 ++--- 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 | 2 +- test/JDBC/upgrade/14_11/schedule | 2 +- test/JDBC/upgrade/14_12/schedule | 1 + test/JDBC/upgrade/14_13/schedule | 2 +- test/JDBC/upgrade/14_14/schedule | 2 +- test/JDBC/upgrade/14_3/schedule | 2 +- test/JDBC/upgrade/14_5/schedule | 2 +- test/JDBC/upgrade/14_6/schedule | 2 +- test/JDBC/upgrade/14_7/schedule | 2 +- test/JDBC/upgrade/14_8/schedule | 2 +- test/JDBC/upgrade/14_9/schedule | 2 +- test/JDBC/upgrade/15_1/schedule | 2 +- test/JDBC/upgrade/15_2/schedule | 2 +- test/JDBC/upgrade/15_3/schedule | 2 +- test/JDBC/upgrade/15_4/schedule | 2 +- test/JDBC/upgrade/15_5/schedule | 1 + test/JDBC/upgrade/15_6/schedule | 1 + test/JDBC/upgrade/15_7/schedule | 1 + test/JDBC/upgrade/15_8/schedule | 1 + test/JDBC/upgrade/15_9/schedule | 1 + test/JDBC/upgrade/16_1/schedule | 2 +- test/JDBC/upgrade/16_2/schedule | 1 + test/JDBC/upgrade/16_3/schedule | 1 + test/JDBC/upgrade/16_4/schedule | 1 + test/JDBC/upgrade/latest/schedule | 2 +- test/JDBC/upgrade/singledb/schedule | 2 +- .../expected_drop.out | 1 + 71 files changed, 2579 insertions(+), 264 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 93ec8d8710..26b38a82e5 100644 --- a/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql +++ b/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql @@ -2118,7 +2118,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 @@ -2150,7 +2150,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 @@ -2188,7 +2188,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 @@ -2348,13 +2348,15 @@ CREATE OR REPLACE PROCEDURE sys.sp_helpdbfixedrole("@rolename" sys.SYSNAME = NUL $$ BEGIN -- Returns a list of the fixed database roles. - -- Only fixed role present in babelfish is db_owner. - IF LOWER(RTRIM(@rolename)) IS NULL OR LOWER(RTRIM(@rolename)) = 'db_owner' + IF LOWER(RTRIM(@rolename)) IS NULL OR LOWER(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 LOWER(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 d45dd0dd61..aefc2e5a07 100644 --- a/contrib/babelfishpg_tsql/sql/sys_functions.sql +++ b/contrib/babelfishpg_tsql/sql/sys_functions.sql @@ -4501,7 +4501,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.3.0--4.4.0.sql b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.3.0--4.4.0.sql index 2c081c7f3e..5c30a40c7c 100644 --- a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.3.0--4.4.0.sql +++ b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.3.0--4.4.0.sql @@ -70,6 +70,15 @@ EXCEPTION WHEN OTHERS THEN 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(); + DO LANGUAGE plpgsql $$ @@ -1252,7 +1261,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 @@ -4216,6 +4227,208 @@ CALL sys.babelfish_drop_deprecated_object('function', 'sys', 'sp_statistics_inte CALL sys.babelfish_drop_deprecated_object('function', 'sys', 'sp_pkeys_internal_deprecated_in_4_4_0'); +-- 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_helpdbfixedrole("@rolename" sys.SYSNAME = NULL) AS +$$ +BEGIN + -- Returns a list of the fixed database roles. + IF LOWER(RTRIM(@rolename)) IS NULL OR LOWER(RTRIM(@rolename)) IN ('db_owner', 'db_accessadmin') + BEGIN + SELECT CAST(DbFixedRole as sys.SYSNAME) AS DbFixedRole, CAST(Description AS sys.nvarchar(70)) AS Description FROM ( + VALUES ('db_owner', 'DB Owners'), + ('db_accessadmin', 'DB Access Administrators')) x(DbFixedRole, Description) + WHERE LOWER(RTRIM(@rolename)) IS NULL OR LOWER(RTRIM(@rolename)) = DbFixedRole; + END + ELSE IF LOWER(RTRIM(@rolename)) IN ( + '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 + SELECT CAST(NULL AS sys.SYSNAME) AS DbFixedRole, CAST(NULL AS sys.nvarchar(70)) AS Description + WHERE 1=0; + END + ELSE + RAISERROR('''%s'' is not a known fixed role.', 16, 1, @rolename); +END +$$ +LANGUAGE 'pltsql'; +GRANT EXECUTE ON PROCEDURE sys.sp_helpdbfixedrole 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 != '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 + 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 != '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 + -- 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 != '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 + -- 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 VIEW sys.sp_sproc_columns_view AS SELECT diff --git a/contrib/babelfishpg_tsql/src/catalog.c b/contrib/babelfishpg_tsql/src/catalog.c index 6501c09b61..6e09e0f02a 100644 --- a/contrib/babelfishpg_tsql/src/catalog.c +++ b/contrib/babelfishpg_tsql/src/catalog.c @@ -450,13 +450,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); } @@ -848,74 +847,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); - - /* - * 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); - } + Datum datum = SysCacheGetAttr(AUTHIDUSEREXTROLENAME, tuple, + Anum_bbf_authid_user_ext_database_name, + &isnull); + char *type_str; + char *db_name_cstring; - ReleaseSysCache(authtuple); + Assert(!isnull); - return is_user; -} + type_str = bpchar_to_cstring(&type); + db_name_cstring = TextDatumGetCString(datum); -bool -is_role(Oid role_oid) -{ - bool is_role = true; - HeapTuple tuple; - HeapTuple authtuple; - NameData rolname; + if (strcmp(db_name_cstring, db_name) == 0) + result = (strcmp(type_str, "R") == 0) ? BBF_ROLE : BBF_USER; - 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)); - - 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(type_str, "R") != 0) - is_role = false; + pfree(type_str); + pfree(db_name_cstring); ReleaseSysCache(tuple); } - ReleaseSysCache(authtuple); - - return is_role; + return result; } Oid @@ -938,12 +911,55 @@ 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) { Relation bbf_authid_user_ext_rel; HeapTuple tuple_user_ext; - ScanKeyData key[3]; + ScanKeyData key[2]; TableScanDesc scan; char *user_name = NULL; NameData *login_name; @@ -964,20 +980,30 @@ get_authid_user_ext_physical_name(const char *db_name, const char *login) Anum_bbf_authid_user_ext_database_name, BTEqualStrategyNumber, F_TEXTEQ, CStringGetTextDatum(db_name)); - ScanKeyInit(&key[2], - Anum_bbf_authid_user_ext_user_can_connect, - BTEqualStrategyNumber, F_INT4EQ, - Int32GetDatum(1)); - scan = table_beginscan_catalog(bbf_authid_user_ext_rel, 3, key); + scan = table_beginscan_catalog(bbf_authid_user_ext_rel, 2, key); 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); @@ -3175,7 +3201,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, @@ -4937,9 +4963,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 4a8f39637e..2755a370ee 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))); } + 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 54f3676666..0df96f624c 100644 --- a/contrib/babelfishpg_tsql/src/hooks.c +++ b/contrib/babelfishpg_tsql/src/hooks.c @@ -3197,7 +3197,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 68cf22477a..5b57247a47 100644 --- a/contrib/babelfishpg_tsql/src/pl_exec-2.c +++ b/contrib/babelfishpg_tsql/src/pl_exec-2.c @@ -3770,11 +3770,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. */ @@ -3793,6 +3788,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 9be5bff532..9fd72ce252 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" @@ -2686,7 +2687,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; @@ -3000,15 +3002,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); } /* @@ -3292,16 +3303,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. @@ -3312,19 +3333,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"))); + } } } @@ -3334,23 +3373,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, @@ -3366,14 +3412,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; } @@ -3423,42 +3467,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))); @@ -3491,8 +3538,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; } @@ -3504,7 +3549,6 @@ bbf_ProcessUtility(PlannedStmt *pstmt, } pfree(rolspec->rolename); - pfree(db_owner_name); rolspec->rolename = user_name; } @@ -3568,9 +3612,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; @@ -3654,8 +3698,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) @@ -3663,6 +3709,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, @@ -3702,8 +3771,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++) @@ -3785,7 +3873,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; @@ -4147,7 +4236,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 ff9eec6a66..b16888cf22 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 58b35f70e2..7c14f26b16 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); } @@ -1789,7 +1789,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; } @@ -1803,6 +1803,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; @@ -1812,7 +1814,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", @@ -1823,6 +1825,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 @@ -1923,7 +1935,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; @@ -1937,7 +1949,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); @@ -1953,7 +1965,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); } @@ -1977,7 +1989,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)))) @@ -1987,16 +1999,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 0470d0d0cd..7953611b48 100644 --- a/contrib/babelfishpg_tsql/src/session.c +++ b/contrib/babelfishpg_tsql/src/session.c @@ -48,12 +48,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 5e2083bb83..f3d4bf2619 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 c058d8feff..a1d76dba08 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; @@ -344,10 +352,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 51acb0056a..0016910d85 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 53d5d91596..a946314493 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 ca3d96ee6c..0bd0b4139d 100644 --- a/test/JDBC/upgrade/14_10/schedule +++ b/test/JDBC/upgrade/14_10/schedule @@ -464,6 +464,6 @@ concat_ws-before-15_9-or-16_5 space binary-datatype-operators cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 - diff --git a/test/JDBC/upgrade/14_11/schedule b/test/JDBC/upgrade/14_11/schedule index 833e931b39..dbdd45e4ae 100644 --- a/test/JDBC/upgrade/14_11/schedule +++ b/test/JDBC/upgrade/14_11/schedule @@ -462,6 +462,6 @@ concat_ws-before-15_9-or-16_5 space binary-datatype-operators cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 - diff --git a/test/JDBC/upgrade/14_12/schedule b/test/JDBC/upgrade/14_12/schedule index 007257c986..bae6e658dd 100644 --- a/test/JDBC/upgrade/14_12/schedule +++ b/test/JDBC/upgrade/14_12/schedule @@ -463,5 +463,6 @@ concat_ws-before-15_9-or-16_5 space binary-datatype-operators cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 diff --git a/test/JDBC/upgrade/14_13/schedule b/test/JDBC/upgrade/14_13/schedule index e5526542ee..1d9f3fd208 100644 --- a/test/JDBC/upgrade/14_13/schedule +++ b/test/JDBC/upgrade/14_13/schedule @@ -463,6 +463,6 @@ concat_ws-before-15_9-or-16_5 space binary-datatype-operators cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 - diff --git a/test/JDBC/upgrade/14_14/schedule b/test/JDBC/upgrade/14_14/schedule index e5526542ee..1d9f3fd208 100644 --- a/test/JDBC/upgrade/14_14/schedule +++ b/test/JDBC/upgrade/14_14/schedule @@ -463,6 +463,6 @@ concat_ws-before-15_9-or-16_5 space binary-datatype-operators cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 - diff --git a/test/JDBC/upgrade/14_3/schedule b/test/JDBC/upgrade/14_3/schedule index 75376ffeac..4143348ab3 100644 --- a/test/JDBC/upgrade/14_3/schedule +++ b/test/JDBC/upgrade/14_3/schedule @@ -384,6 +384,6 @@ concat_ws-before-15_9-or-16_5 space binary-datatype-operators cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 - diff --git a/test/JDBC/upgrade/14_5/schedule b/test/JDBC/upgrade/14_5/schedule index a308d7cc1a..546eb5e9f9 100644 --- a/test/JDBC/upgrade/14_5/schedule +++ b/test/JDBC/upgrade/14_5/schedule @@ -395,6 +395,6 @@ concat_ws-before-15_9-or-16_5 space binary-datatype-operators cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 - diff --git a/test/JDBC/upgrade/14_6/schedule b/test/JDBC/upgrade/14_6/schedule index 232ba6a5b3..404c99d265 100644 --- a/test/JDBC/upgrade/14_6/schedule +++ b/test/JDBC/upgrade/14_6/schedule @@ -432,6 +432,6 @@ concat_ws-before-15_9-or-16_5 space binary-datatype-operators cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 - diff --git a/test/JDBC/upgrade/14_7/schedule b/test/JDBC/upgrade/14_7/schedule index 2e72b39e9c..c767531cb6 100644 --- a/test/JDBC/upgrade/14_7/schedule +++ b/test/JDBC/upgrade/14_7/schedule @@ -454,6 +454,6 @@ concat_ws-before-15_9-or-16_5 space binary-datatype-operators cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 - diff --git a/test/JDBC/upgrade/14_8/schedule b/test/JDBC/upgrade/14_8/schedule index 325bcff6e5..b577e7c96f 100644 --- a/test/JDBC/upgrade/14_8/schedule +++ b/test/JDBC/upgrade/14_8/schedule @@ -456,6 +456,6 @@ concat_ws-before-15_9-or-16_5 space binary-datatype-operators cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 - diff --git a/test/JDBC/upgrade/14_9/schedule b/test/JDBC/upgrade/14_9/schedule index c952cece83..b0df109881 100644 --- a/test/JDBC/upgrade/14_9/schedule +++ b/test/JDBC/upgrade/14_9/schedule @@ -459,6 +459,6 @@ concat_ws-before-15_9-or-16_5 space binary-datatype-operators cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 - diff --git a/test/JDBC/upgrade/15_1/schedule b/test/JDBC/upgrade/15_1/schedule index 918fb0253b..ae4361ea5f 100644 --- a/test/JDBC/upgrade/15_1/schedule +++ b/test/JDBC/upgrade/15_1/schedule @@ -432,6 +432,6 @@ concat_ws-before-15_9-or-16_5 space binary-datatype-operators cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 - diff --git a/test/JDBC/upgrade/15_2/schedule b/test/JDBC/upgrade/15_2/schedule index 090b9d6bbf..7d06376169 100644 --- a/test/JDBC/upgrade/15_2/schedule +++ b/test/JDBC/upgrade/15_2/schedule @@ -467,6 +467,6 @@ concat_ws-before-15_9-or-16_5 space binary-datatype-operators cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 - diff --git a/test/JDBC/upgrade/15_3/schedule b/test/JDBC/upgrade/15_3/schedule index c080e512f8..1c58f8db0f 100644 --- a/test/JDBC/upgrade/15_3/schedule +++ b/test/JDBC/upgrade/15_3/schedule @@ -486,6 +486,6 @@ concat_ws-before-15_9-or-16_5 space binary-datatype-operators cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 - diff --git a/test/JDBC/upgrade/15_4/schedule b/test/JDBC/upgrade/15_4/schedule index 599dbe1967..ca50a1d7b3 100644 --- a/test/JDBC/upgrade/15_4/schedule +++ b/test/JDBC/upgrade/15_4/schedule @@ -499,6 +499,6 @@ concat_ws-before-15_9-or-16_5 space binary-datatype-operators cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 - diff --git a/test/JDBC/upgrade/15_5/schedule b/test/JDBC/upgrade/15_5/schedule index 7b89244f1e..90c9bb60b1 100644 --- a/test/JDBC/upgrade/15_5/schedule +++ b/test/JDBC/upgrade/15_5/schedule @@ -530,6 +530,7 @@ concat_ws-before-15_9-or-16_5 space binary-datatype-operators cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 securityadmin_role diff --git a/test/JDBC/upgrade/15_6/schedule b/test/JDBC/upgrade/15_6/schedule index 1796d4172a..163d9c6084 100644 --- a/test/JDBC/upgrade/15_6/schedule +++ b/test/JDBC/upgrade/15_6/schedule @@ -546,6 +546,7 @@ concat_ws-before-15_9-or-16_5 space binary-datatype-operators cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 securityadmin_role diff --git a/test/JDBC/upgrade/15_7/schedule b/test/JDBC/upgrade/15_7/schedule index 91f4348797..4422f22dfc 100644 --- a/test/JDBC/upgrade/15_7/schedule +++ b/test/JDBC/upgrade/15_7/schedule @@ -553,6 +553,7 @@ replicate-before-15_8-or-16_4 space binary-datatype-operators 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 17d42f25ad..ca61abc6a6 100644 --- a/test/JDBC/upgrade/15_8/schedule +++ b/test/JDBC/upgrade/15_8/schedule @@ -544,6 +544,7 @@ replace alter-procedure-15_8-or-16_4 binary-datatype-operators 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_9/schedule b/test/JDBC/upgrade/15_9/schedule index 951c7bb158..11603a1b79 100644 --- a/test/JDBC/upgrade/15_9/schedule +++ b/test/JDBC/upgrade/15_9/schedule @@ -547,5 +547,6 @@ securityadmin_role cast-varchar-to-time xml_exist-before-16_5 BABEL-5119 +db_accessadmin BABEL-CASE_EXPR diff --git a/test/JDBC/upgrade/16_1/schedule b/test/JDBC/upgrade/16_1/schedule index c2f1051423..a1daaf6b9f 100644 --- a/test/JDBC/upgrade/16_1/schedule +++ b/test/JDBC/upgrade/16_1/schedule @@ -539,7 +539,7 @@ space replace-before-15_8-or-16_4 binary-datatype-operators 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 c58cd6893c..1121f69d1a 100644 --- a/test/JDBC/upgrade/16_2/schedule +++ b/test/JDBC/upgrade/16_2/schedule @@ -554,6 +554,7 @@ space replace-before-15_8-or-16_4 binary-datatype-operators cast-varchar-to-time +db_accessadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 securityadmin_role diff --git a/test/JDBC/upgrade/16_3/schedule b/test/JDBC/upgrade/16_3/schedule index a3d8eafdbe..902ca8a68b 100644 --- a/test/JDBC/upgrade/16_3/schedule +++ b/test/JDBC/upgrade/16_3/schedule @@ -557,6 +557,7 @@ space replace-before-15_8-or-16_4 binary-datatype-operators 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 376bc96d6e..9be060bc1b 100644 --- a/test/JDBC/upgrade/16_4/schedule +++ b/test/JDBC/upgrade/16_4/schedule @@ -570,6 +570,7 @@ binary-datatype-operators cast-varchar-to-time xml_exist-before-16_5 BABEL-5119 +db_accessadmin GRANT_SCHEMA-before-15_9-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 securityadmin_role diff --git a/test/JDBC/upgrade/latest/schedule b/test/JDBC/upgrade/latest/schedule index 7c7d02de2a..3cc8162f27 100644 --- a/test/JDBC/upgrade/latest/schedule +++ b/test/JDBC/upgrade/latest/schedule @@ -578,5 +578,5 @@ xml_exist test_db_collation BABEL-5119 BABEL-5129 +db_accessadmin BABEL-CASE_EXPR - 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 2bf119eb05..ec6da0c9d8 100644 --- a/test/python/expected/sql_validation_framework/expected_drop.out +++ b/test/python/expected/sql_validation_framework/expected_drop.out @@ -43,6 +43,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 From 207391f1146a4aaeb11cc59d2285d84946c597c7 Mon Sep 17 00:00:00 2001 From: HarshLunagariya <40052763+HarshLunagariya@users.noreply.github.com> Date: Mon, 21 Oct 2024 01:01:43 +0530 Subject: [PATCH 19/44] Support db_securityadmin fixed database role Signed-off-by: Harsh Lunagariya --- .../babelfishpg_tsql/sql/babelfishpg_tsql.sql | 2 +- contrib/babelfishpg_tsql/src/dbcmds.c | 16 ++++++++++++ test/JDBC/expected/BABEL-2403.out | 12 +++++++++ test/JDBC/expected/BABEL-5119-vu-verify.out | 1 + test/JDBC/expected/BABEL-LOGIN-USER-EXT.out | 25 +++++++++++++++++++ test/JDBC/expected/BABEL-USER.out | 5 ++++ .../Test-sp_helpdbfixedrole-dep-vu-verify.out | 11 ++++---- .../Test-sp_helpdbfixedrole-vu-verify.out | 6 ++++- .../expected/Test_rename_db_single-db.out | 8 ++++++ test/JDBC/upgrade/13_9/schedule | 1 - test/JDBC/upgrade/14_10/schedule | 1 + test/JDBC/upgrade/14_11/schedule | 1 + test/JDBC/upgrade/14_12/schedule | 1 + test/JDBC/upgrade/14_13/schedule | 1 + test/JDBC/upgrade/14_14/schedule | 1 + test/JDBC/upgrade/14_3/schedule | 1 + test/JDBC/upgrade/14_5/schedule | 1 + test/JDBC/upgrade/14_6/schedule | 1 + test/JDBC/upgrade/14_7/schedule | 1 + test/JDBC/upgrade/14_8/schedule | 1 + test/JDBC/upgrade/14_9/schedule | 1 + test/JDBC/upgrade/15_1/schedule | 1 + test/JDBC/upgrade/15_2/schedule | 1 + test/JDBC/upgrade/15_3/schedule | 1 + test/JDBC/upgrade/15_4/schedule | 1 + test/JDBC/upgrade/15_5/schedule | 1 + test/JDBC/upgrade/15_6/schedule | 1 + test/JDBC/upgrade/15_7/schedule | 1 + test/JDBC/upgrade/15_8/schedule | 1 + test/JDBC/upgrade/15_9/schedule | 1 + test/JDBC/upgrade/16_1/schedule | 2 +- test/JDBC/upgrade/16_2/schedule | 1 + test/JDBC/upgrade/16_3/schedule | 1 + test/JDBC/upgrade/16_4/schedule | 1 + test/JDBC/upgrade/latest/schedule | 1 + test/JDBC/upgrade/singledb/schedule | 1 - 36 files changed, 104 insertions(+), 10 deletions(-) diff --git a/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql b/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql index fa19fbe705..bbddb239f9 100644 --- a/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql +++ b/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql @@ -2348,7 +2348,7 @@ CREATE OR REPLACE PROCEDURE sys.sp_helpdbfixedrole("@rolename" sys.SYSNAME = NUL $$ BEGIN -- Returns a list of the fixed database roles. - IF LOWER(RTRIM(@rolename)) IS NULL OR LOWER(RTRIM(@rolename)) IN ('db_owner', 'db_accessadmin') + IF LOWER(RTRIM(@rolename)) IS NULL OR LOWER(RTRIM(@rolename)) IN ('db_owner', 'db_accessadmin', 'db_securityadmin') BEGIN SELECT CAST(DbFixedRole as sys.SYSNAME) AS DbFixedRole, CAST(Description AS sys.nvarchar(70)) AS Description FROM ( VALUES ('db_owner', 'DB Owners'), diff --git a/contrib/babelfishpg_tsql/src/dbcmds.c b/contrib/babelfishpg_tsql/src/dbcmds.c index da7d557055..c1b8b6297c 100644 --- a/contrib/babelfishpg_tsql/src/dbcmds.c +++ b/contrib/babelfishpg_tsql/src/dbcmds.c @@ -1296,21 +1296,34 @@ create_db_roles_if_not_exists(const char *dbname, List *parsetree_list) int i = 0; char *db_owner; char *db_accessadmin; + char *db_securityadmin; db_owner = get_db_owner_name(dbname); db_accessadmin = get_db_accessadmin_role_name(dbname); + db_securityadmin = get_db_securityadmin_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))); + if (OidIsValid(get_role_oid(db_securityadmin, true))) + ereport(ERROR, + (errcode(ERRCODE_DUPLICATE_OBJECT), + errmsg("role \"%s\" already exists. Please drop the role and restart upgrade.", db_securityadmin))); + 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); + stmt = parsetree_nth_stmt(parsetree_list, i++); + update_CreateRoleStmt(stmt, db_securityadmin, db_owner, NULL); + + stmt = parsetree_nth_stmt(parsetree_list, i++); + update_GrantStmt(stmt, get_database_name(MyDatabaseId), NULL, db_securityadmin, NULL); + GetUserIdAndSecContext(&save_userid, &save_sec_context); PG_TRY(); @@ -1400,6 +1413,9 @@ create_db_roles_during_upgrade(PG_FUNCTION_ARGS) appendStringInfo(&query, "CREATE ROLE dummy ROLE dummy; "); appendStringInfo(&query, "GRANT CREATE ON DATABASE dummy TO dummy; "); + 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); diff --git a/test/JDBC/expected/BABEL-2403.out b/test/JDBC/expected/BABEL-2403.out index 9039d7ce19..e8725830d9 100644 --- a/test/JDBC/expected/BABEL-2403.out +++ b/test/JDBC/expected/BABEL-2403.out @@ -107,6 +107,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"} @@ -204,6 +210,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 f3d4bf2619..5c91ca38ba 100644 --- a/test/JDBC/expected/BABEL-5119-vu-verify.out +++ b/test/JDBC/expected/BABEL-5119-vu-verify.out @@ -759,6 +759,7 @@ GO ~~START~~ nvarchar#!#varchar db_accessadmin#!#=C +db_securityadmin#!#=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 70d0b5e77b..72aaf2620a 100644 --- a/test/JDBC/expected/BABEL-LOGIN-USER-EXT.out +++ b/test/JDBC/expected/BABEL-LOGIN-USER-EXT.out @@ -696,18 +696,22 @@ GO varchar#!#nvarchar#!#varchar#!#nvarchar#!#nvarchar db1_db_accessadmin#!#db_accessadmin#!##!#db1#!# db1_db_owner#!#db_owner#!##!#db1#!# +db1_db_securityadmin#!#db_securityadmin#!##!#db1#!# db1_dbo#!#dbo#!##!#db1#!#dbo db1_guest#!#guest#!##!#db1#!#guest master_db_accessadmin#!#db_accessadmin#!##!#master#!# master_db_owner#!#db_owner#!##!#master#!# +master_db_securityadmin#!#db_securityadmin#!##!#master#!# master_dbo#!#dbo#!##!#master#!#dbo master_guest#!#guest#!##!#master#!#guest msdb_db_accessadmin#!#db_accessadmin#!##!#msdb#!# msdb_db_owner#!#db_owner#!##!#msdb#!# +msdb_db_securityadmin#!#db_securityadmin#!##!#msdb#!# msdb_dbo#!#dbo#!##!#msdb#!#dbo msdb_guest#!#guest#!##!#msdb#!#guest tempdb_db_accessadmin#!#db_accessadmin#!##!#tempdb#!# tempdb_db_owner#!#db_owner#!##!#tempdb#!# +tempdb_db_securityadmin#!#db_securityadmin#!##!#tempdb#!# tempdb_dbo#!#dbo#!##!#tempdb#!#dbo tempdb_guest#!#guest#!##!#tempdb#!#guest ~~END~~ @@ -873,14 +877,17 @@ GO varchar#!#nvarchar#!#varchar#!#nvarchar#!#nvarchar master_db_accessadmin#!#db_accessadmin#!##!#master#!# master_db_owner#!#db_owner#!##!#master#!# +master_db_securityadmin#!#db_securityadmin#!##!#master#!# master_dbo#!#dbo#!##!#master#!#dbo master_guest#!#guest#!##!#master#!#guest msdb_db_accessadmin#!#db_accessadmin#!##!#msdb#!# msdb_db_owner#!#db_owner#!##!#msdb#!# +msdb_db_securityadmin#!#db_securityadmin#!##!#msdb#!# msdb_dbo#!#dbo#!##!#msdb#!#dbo msdb_guest#!#guest#!##!#msdb#!#guest tempdb_db_accessadmin#!#db_accessadmin#!##!#tempdb#!# tempdb_db_owner#!#db_owner#!##!#tempdb#!# +tempdb_db_securityadmin#!#db_securityadmin#!##!#tempdb#!# tempdb_dbo#!#dbo#!##!#tempdb#!#dbo tempdb_guest#!#guest#!##!#tempdb#!#guest ~~END~~ @@ -927,22 +934,27 @@ GO varchar#!#varchar#!#nvarchar#!#nvarchar#!#nvarchar db1_db_accessadmin#!##!#db_accessadmin#!#db1#!# db1_db_owner#!##!#db_owner#!#db1#!# +db1_db_securityadmin#!##!#db_securityadmin#!#db1#!# db1_dbo#!##!#dbo#!#db1#!#dbo db1_guest#!##!#guest#!#db1#!#guest db2_db_accessadmin#!##!#db_accessadmin#!#db2#!# db2_db_owner#!##!#db_owner#!#db2#!# +db2_db_securityadmin#!##!#db_securityadmin#!#db2#!# db2_dbo#!##!#dbo#!#db2#!#dbo db2_guest#!##!#guest#!#db2#!#guest master_db_accessadmin#!##!#db_accessadmin#!#master#!# master_db_owner#!##!#db_owner#!#master#!# +master_db_securityadmin#!##!#db_securityadmin#!#master#!# master_dbo#!##!#dbo#!#master#!#dbo master_guest#!##!#guest#!#master#!#guest msdb_db_accessadmin#!##!#db_accessadmin#!#msdb#!# msdb_db_owner#!##!#db_owner#!#msdb#!# +msdb_db_securityadmin#!##!#db_securityadmin#!#msdb#!# msdb_dbo#!##!#dbo#!#msdb#!#dbo msdb_guest#!##!#guest#!#msdb#!#guest tempdb_db_accessadmin#!##!#db_accessadmin#!#tempdb#!# tempdb_db_owner#!##!#db_owner#!#tempdb#!# +tempdb_db_securityadmin#!##!#db_securityadmin#!#tempdb#!# tempdb_dbo#!##!#dbo#!#tempdb#!#dbo tempdb_guest#!##!#guest#!#tempdb#!#guest ~~END~~ @@ -958,6 +970,7 @@ guest#!#guest dbo#!#dbo db_accessadmin#!# db_owner#!# +db_securityadmin#!# INFORMATION_SCHEMA#!# public#!# sys#!# @@ -991,6 +1004,7 @@ guest#!#guest dbo#!#dbo db_accessadmin#!# db_owner#!# +db_securityadmin#!# INFORMATION_SCHEMA#!# public#!# sys#!# @@ -1126,18 +1140,22 @@ GO varchar#!#nvarchar#!#varchar#!#nvarchar#!#nvarchar db2_db_accessadmin#!#db_accessadmin#!##!#db2#!# db2_db_owner#!#db_owner#!##!#db2#!# +db2_db_securityadmin#!#db_securityadmin#!##!#db2#!# db2_dbo#!#dbo#!##!#db2#!#dbo db2_guest#!#guest#!##!#db2#!#guest master_db_accessadmin#!#db_accessadmin#!##!#master#!# master_db_owner#!#db_owner#!##!#master#!# +master_db_securityadmin#!#db_securityadmin#!##!#master#!# master_dbo#!#dbo#!##!#master#!#dbo master_guest#!#guest#!##!#master#!#guest msdb_db_accessadmin#!#db_accessadmin#!##!#msdb#!# msdb_db_owner#!#db_owner#!##!#msdb#!# +msdb_db_securityadmin#!#db_securityadmin#!##!#msdb#!# msdb_dbo#!#dbo#!##!#msdb#!#dbo msdb_guest#!#guest#!##!#msdb#!#guest tempdb_db_accessadmin#!#db_accessadmin#!##!#tempdb#!# tempdb_db_owner#!#db_owner#!##!#tempdb#!# +tempdb_db_securityadmin#!#db_securityadmin#!##!#tempdb#!# tempdb_dbo#!#dbo#!##!#tempdb#!#dbo tempdb_guest#!#guest#!##!#tempdb#!#guest ~~END~~ @@ -1154,14 +1172,17 @@ GO varchar#!#nvarchar#!#varchar#!#nvarchar#!#nvarchar master_db_accessadmin#!#db_accessadmin#!##!#master#!# master_db_owner#!#db_owner#!##!#master#!# +master_db_securityadmin#!#db_securityadmin#!##!#master#!# master_dbo#!#dbo#!##!#master#!#dbo master_guest#!#guest#!##!#master#!#guest msdb_db_accessadmin#!#db_accessadmin#!##!#msdb#!# msdb_db_owner#!#db_owner#!##!#msdb#!# +msdb_db_securityadmin#!#db_securityadmin#!##!#msdb#!# msdb_dbo#!#dbo#!##!#msdb#!#dbo msdb_guest#!#guest#!##!#msdb#!#guest tempdb_db_accessadmin#!#db_accessadmin#!##!#tempdb#!# tempdb_db_owner#!#db_owner#!##!#tempdb#!# +tempdb_db_securityadmin#!#db_securityadmin#!##!#tempdb#!# tempdb_dbo#!#dbo#!##!#tempdb#!#dbo tempdb_guest#!#guest#!##!#tempdb#!#guest ~~END~~ @@ -1435,6 +1456,7 @@ babel_4935_no_sysadmin1 babel_4935_no_sysadmin2 db_accessadmin db_owner +db_securityadmin dbo guest INFORMATION_SCHEMA @@ -1453,6 +1475,7 @@ babel_4935_no_sysadmin1 babel_4935_no_sysadmin2 db_accessadmin db_owner +db_securityadmin dbo guest INFORMATION_SCHEMA @@ -1470,6 +1493,7 @@ varchar babel_4935_no_sysadmin1 db_accessadmin db_owner +db_securityadmin dbo guest INFORMATION_SCHEMA @@ -1486,6 +1510,7 @@ GO varchar db_accessadmin db_owner +db_securityadmin dbo guest INFORMATION_SCHEMA diff --git a/test/JDBC/expected/BABEL-USER.out b/test/JDBC/expected/BABEL-USER.out index 6a9646102c..92fbc99dcd 100644 --- a/test/JDBC/expected/BABEL-USER.out +++ b/test/JDBC/expected/BABEL-USER.out @@ -51,18 +51,22 @@ GO varchar#!#varchar#!#nvarchar#!#nvarchar#!#nvarchar db1_db_accessadmin#!##!#db_accessadmin#!#db1#!# db1_db_owner#!##!#db_owner#!#db1#!# +db1_db_securityadmin#!##!#db_securityadmin#!#db1#!# db1_dbo#!##!#dbo#!#db1#!#dbo db1_guest#!##!#guest#!#db1#!#guest master_db_accessadmin#!##!#db_accessadmin#!#master#!# master_db_owner#!##!#db_owner#!#master#!# +master_db_securityadmin#!##!#db_securityadmin#!#master#!# master_dbo#!##!#dbo#!#master#!#dbo master_guest#!##!#guest#!#master#!#guest msdb_db_accessadmin#!##!#db_accessadmin#!#msdb#!# msdb_db_owner#!##!#db_owner#!#msdb#!# +msdb_db_securityadmin#!##!#db_securityadmin#!#msdb#!# msdb_dbo#!##!#dbo#!#msdb#!#dbo msdb_guest#!##!#guest#!#msdb#!#guest tempdb_db_accessadmin#!##!#db_accessadmin#!#tempdb#!# tempdb_db_owner#!##!#db_owner#!#tempdb#!# +tempdb_db_securityadmin#!##!#db_securityadmin#!#tempdb#!# tempdb_dbo#!##!#dbo#!#tempdb#!#dbo tempdb_guest#!##!#guest#!#tempdb#!#guest ~~END~~ @@ -78,6 +82,7 @@ guest#!#guest dbo#!#dbo db_accessadmin#!# db_owner#!# +db_securityadmin#!# INFORMATION_SCHEMA#!# public#!# sys#!# diff --git a/test/JDBC/expected/Test-sp_helpdbfixedrole-dep-vu-verify.out b/test/JDBC/expected/Test-sp_helpdbfixedrole-dep-vu-verify.out index 0d807bb979..084447bf41 100644 --- a/test/JDBC/expected/Test-sp_helpdbfixedrole-dep-vu-verify.out +++ b/test/JDBC/expected/Test-sp_helpdbfixedrole-dep-vu-verify.out @@ -4,6 +4,7 @@ GO varchar#!#nvarchar db_owner#!#DB Owners db_accessadmin#!#DB Access Administrators +db_securityadmin#!#DB Security Adiministrators ~~END~~ @@ -19,7 +20,7 @@ SELECT dbo.test_sp_helpdbfixedrole_func() GO ~~START~~ int -2 +3 ~~END~~ @@ -27,15 +28,15 @@ SELECT * FROM test_sp_helpdbfixedrole_view GO ~~START~~ int -2 +3 ~~END~~ EXEC test_sp_helpdbfixedrole_proc 'DB_securityadmin' GO -~~START~~ -varchar#!#nvarchar -~~END~~ +~~ERROR (Code: 50000)~~ + +~~ERROR (Message: 'DB_securityadmin' is not a known fixed role.)~~ EXEC test_sp_helpdbfixedrole_proc 'error' diff --git a/test/JDBC/expected/Test-sp_helpdbfixedrole-vu-verify.out b/test/JDBC/expected/Test-sp_helpdbfixedrole-vu-verify.out index 9c8bfa4e6b..84fe14a933 100644 --- a/test/JDBC/expected/Test-sp_helpdbfixedrole-vu-verify.out +++ b/test/JDBC/expected/Test-sp_helpdbfixedrole-vu-verify.out @@ -1,6 +1,6 @@ INSERT INTO test_sp_helpdbfixedrole_tbl (DbFixedRole, Description) EXEC sp_helpdbfixedrole GO -~~ROW COUNT: 2~~ +~~ROW COUNT: 3~~ SELECT DbFixedRole, Description FROM test_sp_helpdbfixedrole_tbl @@ -9,6 +9,7 @@ GO varchar#!#nvarchar db_owner#!#DB Owners db_accessadmin#!#DB Access Administrators +db_securityadmin#!#DB Security Adiministrators ~~END~~ @@ -53,6 +54,8 @@ GO INSERT INTO test_sp_helpdbfixedrole_tbl (DbFixedRole, Description) EXEC sp_helpdbfixedrole 'DB_securityadmin' GO +~~ROW COUNT: 1~~ + INSERT INTO test_sp_helpdbfixedrole_tbl (DbFixedRole, Description) EXEC sp_helpdbfixedrole 'db_ddladmin ' GO INSERT INTO test_sp_helpdbfixedrole_tbl (DbFixedRole, Description) EXEC sp_helpdbfixedrole 'DB_backupoperator ' @@ -71,6 +74,7 @@ GO ~~START~~ varchar#!#nvarchar db_accessadmin#!#DB Access Administrators +db_securityadmin#!#DB Security Adiministrators ~~END~~ diff --git a/test/JDBC/expected/Test_rename_db_single-db.out b/test/JDBC/expected/Test_rename_db_single-db.out index f1e8d609f7..0c136fa31c 100644 --- a/test/JDBC/expected/Test_rename_db_single-db.out +++ b/test/JDBC/expected/Test_rename_db_single-db.out @@ -34,6 +34,7 @@ rename_db_database1_rename_db_schema1#!#rename_db_schema1 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_db_securityadmin#!##!#db_securityadmin#!#rename_db_database1 rename_db_database1_dbo#!##!#dbo#!#rename_db_database1 rename_db_database1_guest#!##!#guest#!#rename_db_database1 rename_db_database1_rename_db_role1#!##!#rename_db_role1#!#rename_db_database1 @@ -83,6 +84,7 @@ rename_db_database2_rename_db_schema1#!#rename_db_schema1 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_db_securityadmin#!##!#db_securityadmin#!#rename_db_database2 rename_db_database2_dbo#!##!#dbo#!#rename_db_database2 rename_db_database2_guest#!##!#guest#!#rename_db_database2 rename_db_database2_rename_db_role1#!##!#rename_db_role1#!#rename_db_database2 @@ -132,6 +134,7 @@ rename_db_database1_rename_db_schema1#!#rename_db_schema1 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_db_securityadmin#!##!#db_securityadmin#!#rename_db_database1 rename_db_database1_dbo#!##!#dbo#!#rename_db_database1 rename_db_database1_guest#!##!#guest#!#rename_db_database1 rename_db_database1_rename_db_role1#!##!#rename_db_role1#!#rename_db_database1 @@ -181,6 +184,7 @@ rename_db_database2_rename_db_schema1#!#rename_db_schema1 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_db_securityadmin#!##!#db_securityadmin#!#rename_db_database2 rename_db_database2_dbo#!##!#dbo#!#rename_db_database2 rename_db_database2_guest#!##!#guest#!#rename_db_database2 rename_db_database2_rename_db_role1#!##!#rename_db_role1#!#rename_db_database2 @@ -242,6 +246,7 @@ rename_db_database1_rename_db_schema1#!#rename_db_schema1 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_db_securityadmin#!##!#db_securityadmin#!#rename_db_database1 rename_db_database1_dbo#!##!#dbo#!#rename_db_database1 rename_db_database1_guest#!##!#guest#!#rename_db_database1 rename_db_database1_rename_db_role1#!##!#rename_db_role1#!#rename_db_database1 @@ -291,6 +296,7 @@ rename_db_database2_rename_db_schema1#!#rename_db_schema1 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_db_securityadmin#!##!#db_securityadmin#!#rename_db_database2 rename_db_database2_dbo#!##!#dbo#!#rename_db_database2 rename_db_database2_guest#!##!#guest#!#rename_db_database2 rename_db_database2_rename_db_role1#!##!#rename_db_role1#!#rename_db_database2 @@ -340,6 +346,7 @@ rename_db_database1_rename_db_schema1#!#rename_db_schema1 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_db_securityadmin#!##!#db_securityadmin#!#rename_db_database1 rename_db_database1_dbo#!##!#dbo#!#rename_db_database1 rename_db_database1_guest#!##!#guest#!#rename_db_database1 rename_db_database1_rename_db_role1#!##!#rename_db_role1#!#rename_db_database1 @@ -389,6 +396,7 @@ rename_db_database2_rename_db_schema1#!#rename_db_schema1 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_db_securityadmin#!##!#db_securityadmin#!#rename_db_database2 rename_db_database2_dbo#!##!#dbo#!#rename_db_database2 rename_db_database2_guest#!##!#guest#!#rename_db_database2 rename_db_database2_rename_db_role1#!##!#rename_db_role1#!#rename_db_database2 diff --git a/test/JDBC/upgrade/13_9/schedule b/test/JDBC/upgrade/13_9/schedule index 35091c51c9..d27cbfe05b 100644 --- a/test/JDBC/upgrade/13_9/schedule +++ b/test/JDBC/upgrade/13_9/schedule @@ -357,5 +357,4 @@ concat_ws-before-15_9-or-16_5 space binary-datatype-operators replace-before-15_8-or-16_4 -db_accessadmin BABEL-CASE_EXPR-before-16_5-or-15_9 diff --git a/test/JDBC/upgrade/14_10/schedule b/test/JDBC/upgrade/14_10/schedule index 0bd0b4139d..df1d4122e1 100644 --- a/test/JDBC/upgrade/14_10/schedule +++ b/test/JDBC/upgrade/14_10/schedule @@ -465,5 +465,6 @@ space binary-datatype-operators cast-varchar-to-time db_accessadmin +db_securityadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 diff --git a/test/JDBC/upgrade/14_11/schedule b/test/JDBC/upgrade/14_11/schedule index dbdd45e4ae..063796c540 100644 --- a/test/JDBC/upgrade/14_11/schedule +++ b/test/JDBC/upgrade/14_11/schedule @@ -463,5 +463,6 @@ space binary-datatype-operators cast-varchar-to-time db_accessadmin +db_securityadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 diff --git a/test/JDBC/upgrade/14_12/schedule b/test/JDBC/upgrade/14_12/schedule index bae6e658dd..b128a6636f 100644 --- a/test/JDBC/upgrade/14_12/schedule +++ b/test/JDBC/upgrade/14_12/schedule @@ -464,5 +464,6 @@ space binary-datatype-operators cast-varchar-to-time db_accessadmin +db_securityadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 diff --git a/test/JDBC/upgrade/14_13/schedule b/test/JDBC/upgrade/14_13/schedule index 1d9f3fd208..be613e43bd 100644 --- a/test/JDBC/upgrade/14_13/schedule +++ b/test/JDBC/upgrade/14_13/schedule @@ -464,5 +464,6 @@ space binary-datatype-operators cast-varchar-to-time db_accessadmin +db_securityadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 diff --git a/test/JDBC/upgrade/14_14/schedule b/test/JDBC/upgrade/14_14/schedule index 1d9f3fd208..be613e43bd 100644 --- a/test/JDBC/upgrade/14_14/schedule +++ b/test/JDBC/upgrade/14_14/schedule @@ -464,5 +464,6 @@ space binary-datatype-operators cast-varchar-to-time db_accessadmin +db_securityadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 diff --git a/test/JDBC/upgrade/14_3/schedule b/test/JDBC/upgrade/14_3/schedule index 4143348ab3..81ed055d16 100644 --- a/test/JDBC/upgrade/14_3/schedule +++ b/test/JDBC/upgrade/14_3/schedule @@ -385,5 +385,6 @@ space binary-datatype-operators cast-varchar-to-time db_accessadmin +db_securityadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 diff --git a/test/JDBC/upgrade/14_5/schedule b/test/JDBC/upgrade/14_5/schedule index 546eb5e9f9..87f8513db5 100644 --- a/test/JDBC/upgrade/14_5/schedule +++ b/test/JDBC/upgrade/14_5/schedule @@ -396,5 +396,6 @@ space binary-datatype-operators cast-varchar-to-time db_accessadmin +db_securityadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 diff --git a/test/JDBC/upgrade/14_6/schedule b/test/JDBC/upgrade/14_6/schedule index 404c99d265..1a04369904 100644 --- a/test/JDBC/upgrade/14_6/schedule +++ b/test/JDBC/upgrade/14_6/schedule @@ -433,5 +433,6 @@ space binary-datatype-operators cast-varchar-to-time db_accessadmin +db_securityadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 diff --git a/test/JDBC/upgrade/14_7/schedule b/test/JDBC/upgrade/14_7/schedule index c767531cb6..6271fda994 100644 --- a/test/JDBC/upgrade/14_7/schedule +++ b/test/JDBC/upgrade/14_7/schedule @@ -455,5 +455,6 @@ space binary-datatype-operators cast-varchar-to-time db_accessadmin +db_securityadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 diff --git a/test/JDBC/upgrade/14_8/schedule b/test/JDBC/upgrade/14_8/schedule index b577e7c96f..ee2717c16e 100644 --- a/test/JDBC/upgrade/14_8/schedule +++ b/test/JDBC/upgrade/14_8/schedule @@ -457,5 +457,6 @@ space binary-datatype-operators cast-varchar-to-time db_accessadmin +db_securityadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 diff --git a/test/JDBC/upgrade/14_9/schedule b/test/JDBC/upgrade/14_9/schedule index b0df109881..643334959c 100644 --- a/test/JDBC/upgrade/14_9/schedule +++ b/test/JDBC/upgrade/14_9/schedule @@ -460,5 +460,6 @@ space binary-datatype-operators cast-varchar-to-time db_accessadmin +db_securityadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 diff --git a/test/JDBC/upgrade/15_1/schedule b/test/JDBC/upgrade/15_1/schedule index ae4361ea5f..c2e8ea8655 100644 --- a/test/JDBC/upgrade/15_1/schedule +++ b/test/JDBC/upgrade/15_1/schedule @@ -433,5 +433,6 @@ space binary-datatype-operators cast-varchar-to-time db_accessadmin +db_securityadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 diff --git a/test/JDBC/upgrade/15_2/schedule b/test/JDBC/upgrade/15_2/schedule index 7d06376169..0ea77daf2c 100644 --- a/test/JDBC/upgrade/15_2/schedule +++ b/test/JDBC/upgrade/15_2/schedule @@ -468,5 +468,6 @@ space binary-datatype-operators cast-varchar-to-time db_accessadmin +db_securityadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 diff --git a/test/JDBC/upgrade/15_3/schedule b/test/JDBC/upgrade/15_3/schedule index 1c58f8db0f..1ca8b495ba 100644 --- a/test/JDBC/upgrade/15_3/schedule +++ b/test/JDBC/upgrade/15_3/schedule @@ -487,5 +487,6 @@ space binary-datatype-operators cast-varchar-to-time db_accessadmin +db_securityadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 diff --git a/test/JDBC/upgrade/15_4/schedule b/test/JDBC/upgrade/15_4/schedule index ca50a1d7b3..499385a101 100644 --- a/test/JDBC/upgrade/15_4/schedule +++ b/test/JDBC/upgrade/15_4/schedule @@ -500,5 +500,6 @@ space binary-datatype-operators cast-varchar-to-time db_accessadmin +db_securityadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 diff --git a/test/JDBC/upgrade/15_5/schedule b/test/JDBC/upgrade/15_5/schedule index 90c9bb60b1..c6ee38ce15 100644 --- a/test/JDBC/upgrade/15_5/schedule +++ b/test/JDBC/upgrade/15_5/schedule @@ -531,6 +531,7 @@ space binary-datatype-operators cast-varchar-to-time db_accessadmin +db_securityadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 securityadmin_role diff --git a/test/JDBC/upgrade/15_6/schedule b/test/JDBC/upgrade/15_6/schedule index 163d9c6084..9dd7bf794d 100644 --- a/test/JDBC/upgrade/15_6/schedule +++ b/test/JDBC/upgrade/15_6/schedule @@ -547,6 +547,7 @@ space binary-datatype-operators cast-varchar-to-time db_accessadmin +db_securityadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 securityadmin_role diff --git a/test/JDBC/upgrade/15_7/schedule b/test/JDBC/upgrade/15_7/schedule index 4422f22dfc..4ddb18e32e 100644 --- a/test/JDBC/upgrade/15_7/schedule +++ b/test/JDBC/upgrade/15_7/schedule @@ -554,6 +554,7 @@ space binary-datatype-operators cast-varchar-to-time db_accessadmin +db_securityadmin 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 ca61abc6a6..6dfb84b479 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 cast-varchar-to-time db_accessadmin +db_securityadmin 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_9/schedule b/test/JDBC/upgrade/15_9/schedule index 11603a1b79..a3dfd1da2d 100644 --- a/test/JDBC/upgrade/15_9/schedule +++ b/test/JDBC/upgrade/15_9/schedule @@ -548,5 +548,6 @@ cast-varchar-to-time xml_exist-before-16_5 BABEL-5119 db_accessadmin +db_securityadmin BABEL-CASE_EXPR diff --git a/test/JDBC/upgrade/16_1/schedule b/test/JDBC/upgrade/16_1/schedule index b0cb7e765d..2f9a5bcb3d 100644 --- a/test/JDBC/upgrade/16_1/schedule +++ b/test/JDBC/upgrade/16_1/schedule @@ -540,7 +540,7 @@ replace-before-15_8-or-16_4 binary-datatype-operators cast-varchar-to-time db_accessadmin -xml_exist-before-16_5 +db_securityadmin 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 1121f69d1a..27a54ec8d2 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 cast-varchar-to-time db_accessadmin +db_securityadmin xml_exist-before-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 securityadmin_role diff --git a/test/JDBC/upgrade/16_3/schedule b/test/JDBC/upgrade/16_3/schedule index 902ca8a68b..a73cf3c456 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 cast-varchar-to-time db_accessadmin +db_securityadmin 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 9be060bc1b..bc060b24aa 100644 --- a/test/JDBC/upgrade/16_4/schedule +++ b/test/JDBC/upgrade/16_4/schedule @@ -571,6 +571,7 @@ cast-varchar-to-time xml_exist-before-16_5 BABEL-5119 db_accessadmin +db_securityadmin GRANT_SCHEMA-before-15_9-16_5 BABEL-CASE_EXPR-before-16_5-or-15_9 securityadmin_role diff --git a/test/JDBC/upgrade/latest/schedule b/test/JDBC/upgrade/latest/schedule index 3cc8162f27..610f9c137f 100644 --- a/test/JDBC/upgrade/latest/schedule +++ b/test/JDBC/upgrade/latest/schedule @@ -579,4 +579,5 @@ test_db_collation BABEL-5119 BABEL-5129 db_accessadmin +db_securityadmin BABEL-CASE_EXPR diff --git a/test/JDBC/upgrade/singledb/schedule b/test/JDBC/upgrade/singledb/schedule index 34d42c30b1..b4bb4485a2 100644 --- a/test/JDBC/upgrade/singledb/schedule +++ b/test/JDBC/upgrade/singledb/schedule @@ -1,2 +1 @@ TestInt -db_accessadmin From 91c6778684a6732f5c529c93a873a84a7a3fc429 Mon Sep 17 00:00:00 2001 From: Harsh Lunagariya Date: Mon, 21 Oct 2024 11:25:24 +0000 Subject: [PATCH 20/44] test fix Signed-off-by: Harsh Lunagariya --- .../expected/Test-sp_helpdbfixedrole-dep-vu-verify.out | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) 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 084447bf41..8d9c0856e9 100644 --- a/test/JDBC/expected/Test-sp_helpdbfixedrole-dep-vu-verify.out +++ b/test/JDBC/expected/Test-sp_helpdbfixedrole-dep-vu-verify.out @@ -34,9 +34,10 @@ int EXEC test_sp_helpdbfixedrole_proc 'DB_securityadmin' GO -~~ERROR (Code: 50000)~~ - -~~ERROR (Message: 'DB_securityadmin' is not a known fixed role.)~~ +~~START~~ +varchar#!#nvarchar +db_securityadmin#!#DB Security Adiministrators +~~END~~ EXEC test_sp_helpdbfixedrole_proc 'error' From e11f41c855e040c877bbd659c32e0858551e7a28 Mon Sep 17 00:00:00 2001 From: Harsh Lunagariya Date: Mon, 21 Oct 2024 12:10:12 +0000 Subject: [PATCH 21/44] single-db test fix Signed-off-by: Harsh Lunagariya --- test/JDBC/expected/single_db/BABEL-2403.out | 12 ++++++++++ .../single_db/BABEL-LOGIN-USER-EXT.out | 23 +++++++++++++++++++ test/JDBC/expected/single_db/BABEL-USER.out | 5 ++++ .../single_db/Test_rename_db_single-db.out | 8 +++++++ 4 files changed, 48 insertions(+) diff --git a/test/JDBC/expected/single_db/BABEL-2403.out b/test/JDBC/expected/single_db/BABEL-2403.out index c000969d27..382968b6fd 100644 --- a/test/JDBC/expected/single_db/BABEL-2403.out +++ b/test/JDBC/expected/single_db/BABEL-2403.out @@ -95,6 +95,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"} @@ -180,6 +186,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 78fe8fe42c..4a43f41eed 100644 --- a/test/JDBC/expected/single_db/BABEL-LOGIN-USER-EXT.out +++ b/test/JDBC/expected/single_db/BABEL-LOGIN-USER-EXT.out @@ -697,17 +697,21 @@ varchar#!#nvarchar#!#varchar#!#nvarchar#!#nvarchar db1_guest#!#guest#!##!#db1#!#guest db_accessadmin#!#db_accessadmin#!##!#db1#!# db_owner#!#db_owner#!##!#db1#!# +db_securityadmin#!#db_securityadmin#!##!#db1#!# dbo#!#dbo#!##!#db1#!#dbo master_db_accessadmin#!#db_accessadmin#!##!#master#!# master_db_owner#!#db_owner#!##!#master#!# +master_db_securityadmin#!#db_securityadmin#!##!#master#!# master_dbo#!#dbo#!##!#master#!#dbo master_guest#!#guest#!##!#master#!#guest msdb_db_accessadmin#!#db_accessadmin#!##!#msdb#!# msdb_db_owner#!#db_owner#!##!#msdb#!# +msdb_db_securityadmin#!#db_securityadmin#!##!#msdb#!# msdb_dbo#!#dbo#!##!#msdb#!#dbo msdb_guest#!#guest#!##!#msdb#!#guest tempdb_db_accessadmin#!#db_accessadmin#!##!#tempdb#!# tempdb_db_owner#!#db_owner#!##!#tempdb#!# +tempdb_db_securityadmin#!#db_securityadmin#!##!#tempdb#!# tempdb_dbo#!#dbo#!##!#tempdb#!#dbo tempdb_guest#!#guest#!##!#tempdb#!#guest ~~END~~ @@ -873,14 +877,17 @@ GO varchar#!#nvarchar#!#varchar#!#nvarchar#!#nvarchar master_db_accessadmin#!#db_accessadmin#!##!#master#!# master_db_owner#!#db_owner#!##!#master#!# +master_db_securityadmin#!#db_securityadmin#!##!#master#!# master_dbo#!#dbo#!##!#master#!#dbo master_guest#!#guest#!##!#master#!#guest msdb_db_accessadmin#!#db_accessadmin#!##!#msdb#!# msdb_db_owner#!#db_owner#!##!#msdb#!# +msdb_db_securityadmin#!#db_securityadmin#!##!#msdb#!# msdb_dbo#!#dbo#!##!#msdb#!#dbo msdb_guest#!#guest#!##!#msdb#!#guest tempdb_db_accessadmin#!#db_accessadmin#!##!#tempdb#!# tempdb_db_owner#!#db_owner#!##!#tempdb#!# +tempdb_db_securityadmin#!#db_securityadmin#!##!#tempdb#!# tempdb_dbo#!#dbo#!##!#tempdb#!#dbo tempdb_guest#!#guest#!##!#tempdb#!#guest ~~END~~ @@ -932,17 +939,21 @@ varchar#!#varchar#!#nvarchar#!#nvarchar#!#nvarchar db1_guest#!##!#guest#!#db1#!#guest db_accessadmin#!##!#db_accessadmin#!#db1#!# db_owner#!##!#db_owner#!#db1#!# +db_securityadmin#!##!#db_securityadmin#!#db1#!# dbo#!##!#dbo#!#db1#!#dbo master_db_accessadmin#!##!#db_accessadmin#!#master#!# master_db_owner#!##!#db_owner#!#master#!# +master_db_securityadmin#!##!#db_securityadmin#!#master#!# master_dbo#!##!#dbo#!#master#!#dbo master_guest#!##!#guest#!#master#!#guest msdb_db_accessadmin#!##!#db_accessadmin#!#msdb#!# msdb_db_owner#!##!#db_owner#!#msdb#!# +msdb_db_securityadmin#!##!#db_securityadmin#!#msdb#!# msdb_dbo#!##!#dbo#!#msdb#!#dbo msdb_guest#!##!#guest#!#msdb#!#guest tempdb_db_accessadmin#!##!#db_accessadmin#!#tempdb#!# tempdb_db_owner#!##!#db_owner#!#tempdb#!# +tempdb_db_securityadmin#!##!#db_securityadmin#!#tempdb#!# tempdb_dbo#!##!#dbo#!#tempdb#!#dbo tempdb_guest#!##!#guest#!#tempdb#!#guest ~~END~~ @@ -958,6 +969,7 @@ guest#!#guest dbo#!#dbo db_accessadmin#!# db_owner#!# +db_securityadmin#!# INFORMATION_SCHEMA#!# public#!# sys#!# @@ -990,6 +1002,7 @@ guest#!#guest dbo#!#dbo db_accessadmin#!# db_owner#!# +db_securityadmin#!# INFORMATION_SCHEMA#!# public#!# sys#!# @@ -1129,14 +1142,17 @@ GO varchar#!#nvarchar#!#varchar#!#nvarchar#!#nvarchar master_db_accessadmin#!#db_accessadmin#!##!#master#!# master_db_owner#!#db_owner#!##!#master#!# +master_db_securityadmin#!#db_securityadmin#!##!#master#!# master_dbo#!#dbo#!##!#master#!#dbo master_guest#!#guest#!##!#master#!#guest msdb_db_accessadmin#!#db_accessadmin#!##!#msdb#!# msdb_db_owner#!#db_owner#!##!#msdb#!# +msdb_db_securityadmin#!#db_securityadmin#!##!#msdb#!# msdb_dbo#!#dbo#!##!#msdb#!#dbo msdb_guest#!#guest#!##!#msdb#!#guest tempdb_db_accessadmin#!#db_accessadmin#!##!#tempdb#!# tempdb_db_owner#!#db_owner#!##!#tempdb#!# +tempdb_db_securityadmin#!#db_securityadmin#!##!#tempdb#!# tempdb_dbo#!#dbo#!##!#tempdb#!#dbo tempdb_guest#!#guest#!##!#tempdb#!#guest ~~END~~ @@ -1157,14 +1173,17 @@ GO varchar#!#nvarchar#!#varchar#!#nvarchar#!#nvarchar master_db_accessadmin#!#db_accessadmin#!##!#master#!# master_db_owner#!#db_owner#!##!#master#!# +master_db_securityadmin#!#db_securityadmin#!##!#master#!# master_dbo#!#dbo#!##!#master#!#dbo master_guest#!#guest#!##!#master#!#guest msdb_db_accessadmin#!#db_accessadmin#!##!#msdb#!# msdb_db_owner#!#db_owner#!##!#msdb#!# +msdb_db_securityadmin#!#db_securityadmin#!##!#msdb#!# msdb_dbo#!#dbo#!##!#msdb#!#dbo msdb_guest#!#guest#!##!#msdb#!#guest tempdb_db_accessadmin#!#db_accessadmin#!##!#tempdb#!# tempdb_db_owner#!#db_owner#!##!#tempdb#!# +tempdb_db_securityadmin#!#db_securityadmin#!##!#tempdb#!# tempdb_dbo#!#dbo#!##!#tempdb#!#dbo tempdb_guest#!#guest#!##!#tempdb#!#guest ~~END~~ @@ -1455,6 +1474,7 @@ babel_4935_no_sysadmin1 babel_4935_no_sysadmin2 db_accessadmin db_owner +db_securityadmin dbo guest INFORMATION_SCHEMA @@ -1473,6 +1493,7 @@ babel_4935_no_sysadmin1 babel_4935_no_sysadmin2 db_accessadmin db_owner +db_securityadmin dbo guest INFORMATION_SCHEMA @@ -1490,6 +1511,7 @@ varchar babel_4935_no_sysadmin1 db_accessadmin db_owner +db_securityadmin dbo guest INFORMATION_SCHEMA @@ -1506,6 +1528,7 @@ GO varchar db_accessadmin db_owner +db_securityadmin dbo guest INFORMATION_SCHEMA diff --git a/test/JDBC/expected/single_db/BABEL-USER.out b/test/JDBC/expected/single_db/BABEL-USER.out index 2917e1f1fc..39136a39e0 100644 --- a/test/JDBC/expected/single_db/BABEL-USER.out +++ b/test/JDBC/expected/single_db/BABEL-USER.out @@ -52,17 +52,21 @@ varchar#!#varchar#!#nvarchar#!#nvarchar#!#nvarchar db1_guest#!##!#guest#!#db1#!#guest db_accessadmin#!##!#db_accessadmin#!#db1#!# db_owner#!##!#db_owner#!#db1#!# +db_securityadmin#!##!#db_securityadmin#!#db1#!# dbo#!##!#dbo#!#db1#!#dbo master_db_accessadmin#!##!#db_accessadmin#!#master#!# master_db_owner#!##!#db_owner#!#master#!# +master_db_securityadmin#!##!#db_securityadmin#!#master#!# master_dbo#!##!#dbo#!#master#!#dbo master_guest#!##!#guest#!#master#!#guest msdb_db_accessadmin#!##!#db_accessadmin#!#msdb#!# msdb_db_owner#!##!#db_owner#!#msdb#!# +msdb_db_securityadmin#!##!#db_securityadmin#!#msdb#!# msdb_dbo#!##!#dbo#!#msdb#!#dbo msdb_guest#!##!#guest#!#msdb#!#guest tempdb_db_accessadmin#!##!#db_accessadmin#!#tempdb#!# tempdb_db_owner#!##!#db_owner#!#tempdb#!# +tempdb_db_securityadmin#!##!#db_securityadmin#!#tempdb#!# tempdb_dbo#!##!#dbo#!#tempdb#!#dbo tempdb_guest#!##!#guest#!#tempdb#!#guest ~~END~~ @@ -78,6 +82,7 @@ guest#!#guest dbo#!#dbo db_accessadmin#!# db_owner#!# +db_securityadmin#!# INFORMATION_SCHEMA#!# public#!# sys#!# diff --git a/test/JDBC/expected/single_db/Test_rename_db_single-db.out b/test/JDBC/expected/single_db/Test_rename_db_single-db.out index 227059870a..9abd157482 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 @@ -34,6 +34,7 @@ rename_db_schema1#!#rename_db_schema1 varchar#!#varchar#!#nvarchar#!#nvarchar db_accessadmin#!##!#db_accessadmin#!#rename_db_database1 db_owner#!##!#db_owner#!#rename_db_database1 +db_securityadmin#!##!#db_securityadmin#!#rename_db_database1 dbo#!##!#dbo#!#rename_db_database1 rename_db_database1_guest#!##!#guest#!#rename_db_database1 rename_db_database1_rename_db_role1#!##!#rename_db_role1#!#rename_db_database1 @@ -83,6 +84,7 @@ rename_db_schema1#!#rename_db_schema1 varchar#!#varchar#!#nvarchar#!#nvarchar db_accessadmin#!##!#db_accessadmin#!#rename_db_database2 db_owner#!##!#db_owner#!#rename_db_database2 +db_securityadmin#!##!#db_securityadmin#!#rename_db_database2 dbo#!##!#dbo#!#rename_db_database2 rename_db_database2_guest#!##!#guest#!#rename_db_database2 rename_db_database2_rename_db_role1#!##!#rename_db_role1#!#rename_db_database2 @@ -132,6 +134,7 @@ rename_db_schema1#!#rename_db_schema1 varchar#!#varchar#!#nvarchar#!#nvarchar db_accessadmin#!##!#db_accessadmin#!#rename_db_database1 db_owner#!##!#db_owner#!#rename_db_database1 +db_securityadmin#!##!#db_securityadmin#!#rename_db_database1 dbo#!##!#dbo#!#rename_db_database1 rename_db_database1_guest#!##!#guest#!#rename_db_database1 rename_db_database1_rename_db_role1#!##!#rename_db_role1#!#rename_db_database1 @@ -181,6 +184,7 @@ rename_db_schema1#!#rename_db_schema1 varchar#!#varchar#!#nvarchar#!#nvarchar db_accessadmin#!##!#db_accessadmin#!#rename_db_database2 db_owner#!##!#db_owner#!#rename_db_database2 +db_securityadmin#!##!#db_securityadmin#!#rename_db_database2 dbo#!##!#dbo#!#rename_db_database2 rename_db_database2_guest#!##!#guest#!#rename_db_database2 rename_db_database2_rename_db_role1#!##!#rename_db_role1#!#rename_db_database2 @@ -242,6 +246,7 @@ rename_db_schema1#!#rename_db_schema1 varchar#!#varchar#!#nvarchar#!#nvarchar db_accessadmin#!##!#db_accessadmin#!#rename_db_database1 db_owner#!##!#db_owner#!#rename_db_database1 +db_securityadmin#!##!#db_securityadmin#!#rename_db_database1 dbo#!##!#dbo#!#rename_db_database1 rename_db_database1_guest#!##!#guest#!#rename_db_database1 rename_db_database1_rename_db_role1#!##!#rename_db_role1#!#rename_db_database1 @@ -291,6 +296,7 @@ rename_db_schema1#!#rename_db_schema1 varchar#!#varchar#!#nvarchar#!#nvarchar db_accessadmin#!##!#db_accessadmin#!#rename_db_database2 db_owner#!##!#db_owner#!#rename_db_database2 +db_securityadmin#!##!#db_securityadmin#!#rename_db_database2 dbo#!##!#dbo#!#rename_db_database2 rename_db_database2_guest#!##!#guest#!#rename_db_database2 rename_db_database2_rename_db_role1#!##!#rename_db_role1#!#rename_db_database2 @@ -340,6 +346,7 @@ rename_db_schema1#!#rename_db_schema1 varchar#!#varchar#!#nvarchar#!#nvarchar db_accessadmin#!##!#db_accessadmin#!#rename_db_database1 db_owner#!##!#db_owner#!#rename_db_database1 +db_securityadmin#!##!#db_securityadmin#!#rename_db_database1 dbo#!##!#dbo#!#rename_db_database1 rename_db_database1_guest#!##!#guest#!#rename_db_database1 rename_db_database1_rename_db_role1#!##!#rename_db_role1#!#rename_db_database1 @@ -389,6 +396,7 @@ rename_db_schema1#!#rename_db_schema1 varchar#!#varchar#!#nvarchar#!#nvarchar db_accessadmin#!##!#db_accessadmin#!#rename_db_database2 db_owner#!##!#db_owner#!#rename_db_database2 +db_securityadmin#!##!#db_securityadmin#!#rename_db_database2 dbo#!##!#dbo#!#rename_db_database2 rename_db_database2_guest#!##!#guest#!#rename_db_database2 rename_db_database2_rename_db_role1#!##!#rename_db_role1#!#rename_db_database2 From e8a7560d8ff8e916d7413bf6d8c2dd0675d915b2 Mon Sep 17 00:00:00 2001 From: Harsh Lunagariya Date: Mon, 21 Oct 2024 12:19:30 +0000 Subject: [PATCH 22/44] upgrade fix Signed-off-by: Harsh Lunagariya --- contrib/babelfishpg_tsql/src/dbcmds.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/contrib/babelfishpg_tsql/src/dbcmds.c b/contrib/babelfishpg_tsql/src/dbcmds.c index c1b8b6297c..b998a12690 100644 --- a/contrib/babelfishpg_tsql/src/dbcmds.c +++ b/contrib/babelfishpg_tsql/src/dbcmds.c @@ -1332,6 +1332,7 @@ create_db_roles_if_not_exists(const char *dbname, List *parsetree_list) SetConfigOption("createrole_self_grant", "inherit", PGC_USERSET, PGC_S_OVERRIDE); add_to_bbf_authid_user_ext(db_accessadmin, DB_ACCESSADMIN, dbname, NULL, NULL, true, true, false); + add_to_bbf_authid_user_ext(db_securityadmin, DB_SECURITYADMIN, dbname, NULL, NULL, true, true, false); foreach(parsetree_item, parsetree_list) { @@ -1369,6 +1370,7 @@ create_db_roles_if_not_exists(const char *dbname, List *parsetree_list) SetUserIdAndSecContext(save_userid, save_sec_context); pfree(db_owner); pfree(db_accessadmin); + pfree(db_securityadmin); } PG_END_TRY(); } From 38c2a6cb3f888b9ff03827cfc991745f7faf948a Mon Sep 17 00:00:00 2001 From: Harsh Lunagariya Date: Mon, 21 Oct 2024 13:03:41 +0000 Subject: [PATCH 23/44] upgarde script fix Signed-off-by: Harsh Lunagariya --- .../sql/upgrades/babelfishpg_tsql--4.3.0--4.4.0.sql | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.3.0--4.4.0.sql b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.3.0--4.4.0.sql index 75b44888f7..87db92d90a 100644 --- a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.3.0--4.4.0.sql +++ b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--4.3.0--4.4.0.sql @@ -4290,16 +4290,17 @@ CREATE OR REPLACE PROCEDURE sys.sp_helpdbfixedrole("@rolename" sys.SYSNAME = NUL $$ BEGIN -- Returns a list of the fixed database roles. - IF LOWER(RTRIM(@rolename)) IS NULL OR LOWER(RTRIM(@rolename)) IN ('db_owner', 'db_accessadmin') + IF LOWER(RTRIM(@rolename)) IS NULL OR LOWER(RTRIM(@rolename)) IN ('db_owner', 'db_accessadmin', 'db_securityadmin') BEGIN SELECT CAST(DbFixedRole as sys.SYSNAME) AS DbFixedRole, CAST(Description AS sys.nvarchar(70)) AS Description FROM ( VALUES ('db_owner', 'DB Owners'), - ('db_accessadmin', 'DB Access Administrators')) x(DbFixedRole, Description) + ('db_accessadmin', 'DB Access Administrators'), + ('db_securityadmin', 'DB Security Adiministrators')) x(DbFixedRole, Description) WHERE LOWER(RTRIM(@rolename)) IS NULL OR LOWER(RTRIM(@rolename)) = DbFixedRole; END ELSE IF LOWER(RTRIM(@rolename)) IN ( - 'db_securityadmin','db_ddladmin', 'db_backupoperator', - 'db_datareader', 'db_datawriter', 'db_denydatareader', 'db_denydatawriter') + 'db_ddladmin', 'db_backupoperator', 'db_datareader', + 'db_datawriter', 'db_denydatareader', 'db_denydatawriter') BEGIN -- Return an empty result set instead of raising an error SELECT CAST(NULL AS sys.SYSNAME) AS DbFixedRole, CAST(NULL AS sys.nvarchar(70)) AS Description @@ -4312,6 +4313,7 @@ $$ LANGUAGE 'pltsql'; GRANT EXECUTE ON PROCEDURE sys.sp_helpdbfixedrole TO PUBLIC; + CREATE OR REPLACE PROCEDURE sys.sp_helpuser("@name_in_db" sys.SYSNAME = NULL) AS $$ BEGIN From 9b9e5e975e54265cae1d8b8132ba1e137dcddc17 Mon Sep 17 00:00:00 2001 From: Harsh Lunagariya Date: Tue, 22 Oct 2024 09:03:58 +0000 Subject: [PATCH 24/44] add more tests Signed-off-by: Harsh Lunagariya --- .../ownership/db_securityadmin-vu-verify.mix | 114 +++++++++++++++++- 1 file changed, 113 insertions(+), 1 deletion(-) diff --git a/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix b/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix index aa3e0d5953..e1a97cf6e4 100644 --- a/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix +++ b/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix @@ -1,3 +1,14 @@ +-- tsql +-- bbf dump does not dump password so reset the password +ALTER LOGIN babel_5135_l1 WITH PASSWORD='12345678'; +GO + +ALTER LOGIN babel_5135_l2 WITH PASSWORD='12345678'; +GO + +ALTER LOGIN babel_5135_dbsecadmin_l1 WITH PASSWORD='12345678'; +GO + -- CASE 1 Allowed syntaxes to modify the membership of db_securityadmin -- CASE 1.1 Validate ALTER ROLE ... ADD/DROP MEMBER -- CASE 1.2 Validate sp_addrolemember @@ -125,6 +136,8 @@ DROP SCHEMA babel_5135_sch2; GO -- CASE 5 - GRANT/REVOKE management of permissions + -- CASE 5.1 - Validate GRANT/REVOKE of object/schema privileges + -- CASE 5.2 - Validate members of db_securityadmin can not actually access given objects GRANT SELECT, INSERT, UPDATE, DELETE ON babel_5135_schema1.babel_5135_t1 TO babel_5135_u1; GO @@ -235,7 +248,106 @@ GO SELECT babel_5135_schema1.babel_5135_f1(); GO --- ADD is_member(), is_rolemember(), system views testcases +-- CASE 5.2 - Validate members of db_securityadmin can not actually access given objects +-- tsql user=babel_5135_dbsecadmin_l1 password=12345678 +SELECT current_user; +GO + +SELECT COUNT(*) FROM babel_5135_schema1.babel_5135_t1; +INSERT INTO babel_5135_schema1.babel_5135_t1 VALUES (1); +UPDATE babel_5135_schema1.babel_5135_t1 SET a = 2 WHERE a = 1; +DELETE FROM babel_5135_schema1.babel_5135_t1 WHERE a = 2; +GO + +SELECT COUNT(*) FROM babel_5135_schema1.babel_5135_v1; +GO + +EXEC babel_5135_schema1.babel_5135_p1; +GO + +SELECT babel_5135_schema1.babel_5135_f1(); +GO + +-- CASE 6 - is_member() / is_rolemember() testcases +-- tsql +SELECT is_member('db_securityadmin'), is_rolemember('db_securityadmin'); +GO + +SELECT is_rolemember('db_securityadmin', 'dbo'); +GO + +SELECT is_rolemember('db_securityadmin', 'db_owner'); +GO + +SELECT is_rolemember('db_securityadmin', 'db_accessadmin'); +GO + +-- tsql user=babel_5135_dbsecadmin_l1 password=12345678 +SELECT is_member('db_securityadmin'), is_rolemember('db_securityadmin'); +GO + +-- tsql +EXEC sp_droprolemember 'db_securityadmin', 'babel_5135_dbsecadmin_u1'; +GO + +-- tsql user=babel_5135_dbsecadmin_l1 password=12345678 +SELECT is_member('db_securityadmin'), is_rolemember('db_securityadmin'); +GO + +-- tsql +EXEC sp_droprolemember 'db_securityadmin', 'babel_5135_dbsecadmin_u1'; +GO + +-- tsql user=babel_5135_dbsecadmin_l1 password=12345678 +SELECT is_member('db_securityadmin'), is_rolemember('db_securityadmin'); +GO + +-- CASE 7 - system procedures + -- CASE 7.1 - sp_helpdbfixedrole testcase are covered in respective test Test-sp_helpdbfixedrole file + -- CASE 7.2 - sp_helpuser + -- CASE 7.3 - sp_helprole + -- CASE 7.4 - sp_helprolemember + +-- tsql user=babel_5135_dbsecadmin_l1 password=12345678 +CREATE TABLE temp_sp_helpuser(UserName sys.sysname, RoleName sys.sysname, LoginName sys.sysname, +DefDBName sys.sysname, DefSchemaName sys.sysname, UserID int, SID SYS.VARBINARY(85)); +GO + +CREATE TABLE temp_sp_helprole(RoleName sys.sysname, RoleId smallint, IsAppRole int); +GO + +CREATE TABLE temp_sp_helprolemember(DbRole sys.sysname, MemberName sys.sysname, MemberSID SYS.VARBINARY(85)); +GO + +INSERT INTO temp_sp_helpuser(UserName, RoleName, LoginName, DefDBName, DefSchemaName, UserID, SID) EXEC sp_helpuser 'db_securityadmin'; +GO + +SELECT UserName, Rolename, LoginName, DefDBName, DefSchemaName FROM temp_sp_helpuser +where UserName = 'db_securityadmin'; +GO + +exec sp_helpuser 'db_securityadmin'; +GO + +exec sp_helprole 'db_securityadmin'; +GO + +exec sp_helprolemember 'sp_helprolemember'; +GO + +exec sp_helprole ''; + +-- cleanup +DROP TABLE temp_sp_helpuser; +GO + +DROP TABLE temp_sp_helprole; +GO + +DROP TABLE temp_sp_helprolemember; +GO + +-- system views testcases USE babel_5135_db1; GO From d06be3905dcb7b812af17f203fae667267c7a5e8 Mon Sep 17 00:00:00 2001 From: Harsh Lunagariya Date: Tue, 22 Oct 2024 18:37:26 +0000 Subject: [PATCH 25/44] Added tests Signed-off-by: Harsh Lunagariya --- .../expected/db_securityadmin-vu-verify.out | 266 +++++++++++++++++- .../ownership/db_securityadmin-vu-verify.mix | 86 ++++-- 2 files changed, 333 insertions(+), 19 deletions(-) diff --git a/test/JDBC/expected/db_securityadmin-vu-verify.out b/test/JDBC/expected/db_securityadmin-vu-verify.out index 82e94740c9..f88f8c63c8 100644 --- a/test/JDBC/expected/db_securityadmin-vu-verify.out +++ b/test/JDBC/expected/db_securityadmin-vu-verify.out @@ -1,3 +1,14 @@ +-- tsql +-- bbf dump does not dump password so reset the password +ALTER LOGIN babel_5135_l1 WITH PASSWORD='12345678'; +GO + +ALTER LOGIN babel_5135_l2 WITH PASSWORD='12345678'; +GO + +ALTER LOGIN babel_5135_dbsecadmin_l1 WITH PASSWORD='12345678'; +GO + -- tsql -- CASE 1 Allowed syntaxes to modify the membership of db_securityadmin -- CASE 1.1 Validate ALTER ROLE ... ADD/DROP MEMBER @@ -188,6 +199,8 @@ DROP SCHEMA babel_5135_sch2; GO -- CASE 5 - GRANT/REVOKE management of permissions + -- CASE 5.1 - Validate GRANT/REVOKE of object/schema privileges + -- CASE 5.2 - Validate members of db_securityadmin can not actually access given objects GRANT SELECT, INSERT, UPDATE, DELETE ON babel_5135_schema1.babel_5135_t1 TO babel_5135_u1; GO ~~ERROR (Code: 33557097)~~ @@ -408,14 +421,261 @@ GO ~~ERROR (Message: permission denied for function babel_5135_f1)~~ +-- tsql user=babel_5135_dbsecadmin_l1 password=12345678 +-- CASE 5.2 - Validate members of db_securityadmin can not actually access given objects +SELECT current_user; +GO +~~START~~ +varchar +babel_5135_dbsecadmin_u1 +~~END~~ + + +SELECT COUNT(*) FROM babel_5135_schema1.babel_5135_t1; +INSERT INTO babel_5135_schema1.babel_5135_t1 VALUES (1); +UPDATE babel_5135_schema1.babel_5135_t1 SET a = 2 WHERE a = 1; +DELETE FROM babel_5135_schema1.babel_5135_t1 WHERE a = 2; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table babel_5135_t1)~~ --- ADD is_member(), is_rolemember(), system views testcases -USE babel_5135_db1; + +SELECT COUNT(*) FROM babel_5135_schema1.babel_5135_v1; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view babel_5135_v1)~~ + + +EXEC babel_5135_schema1.babel_5135_p1; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for procedure babel_5135_p1)~~ + + +SELECT babel_5135_schema1.babel_5135_f1(); GO ~~ERROR (Code: 33557097)~~ -~~ERROR (Message: The server principal "babel_5135_l1" is not able to access the database "babel_5135_db1" under the current security context)~~ +~~ERROR (Message: permission denied for function babel_5135_f1)~~ + + +-- tsql +-- CASE 6 - is_member() / is_rolemember() testcases +SELECT is_member('db_securityadmin'), is_rolemember('db_securityadmin'); +GO +~~START~~ +int#!#int +0#!#1 +~~END~~ + +SELECT is_rolemember('db_securityadmin', 'dbo'); +GO +~~START~~ +int +1 +~~END~~ + + +SELECT is_rolemember('db_securityadmin', 'db_owner'); +GO +~~START~~ +int +0 +~~END~~ + + +SELECT is_rolemember('db_securityadmin', 'db_accessadmin'); +GO +~~START~~ +int +0 +~~END~~ + + +-- tsql user=babel_5135_dbsecadmin_l1 password=12345678 +SELECT is_member('db_securityadmin'), is_rolemember('db_securityadmin'); +GO +~~START~~ +int#!#int +1#!#1 +~~END~~ + + +-- tsql +EXEC sp_droprolemember 'db_securityadmin', 'babel_5135_dbsecadmin_u1'; +GO + +-- tsql user=babel_5135_dbsecadmin_l1 password=12345678 +SELECT is_member('db_securityadmin'), is_rolemember('db_securityadmin'); +GO +~~START~~ +int#!#int +0#!#0 +~~END~~ + + +-- tsql +EXEC sp_addrolemember 'db_securityadmin', 'babel_5135_dbsecadmin_u1'; +GO + +-- tsql user=babel_5135_dbsecadmin_l1 password=12345678 +SELECT is_member('db_securityadmin'), is_rolemember('db_securityadmin'); +GO +~~START~~ +int#!#int +1#!#1 +~~END~~ + + + +-- tsql +-- CASE 7 - system procedures + -- CASE 7.1 - sp_helpdbfixedrole testcase are covered in respective test Test-sp_helpdbfixedrole file + -- CASE 7.2 - sp_helpuser + -- CASE 7.3 - sp_helprole + -- CASE 7.4 - sp_helprolemember +-- test for helpuser +CREATE TABLE temp_sp_helpuser(RoleName sys.sysname, Role_id smallint, +Users_in_role sys.sysname, UserID smallint); +GO + +GRANT INSERT,SELECT ON temp_sp_helpuser TO PUBLIC; +GO + +-- tsql user=babel_5135_dbsecadmin_l1 password=12345678 +INSERT INTO temp_sp_helpuser(RoleName, Role_id, Users_in_role, UserID) EXEC sp_helpuser 'db_securityadmin'; +GO +~~ROW COUNT: 1~~ + + +SELECT Rolename, sys.user_name(Role_id), Users_in_role, sys.user_name(UserID) FROM temp_sp_helpuser +WHERE Rolename = 'db_securityadmin' ORDER BY Users_in_role; +GO +~~START~~ +varchar#!#nvarchar#!#varchar#!#nvarchar +db_securityadmin#!#db_securityadmin#!#babel_5135_dbsecadmin_u1#!#babel_5135_dbsecadmin_u1 +~~END~~ + + +-- tsql +TRUNCATE TABLE temp_sp_helpuser; +GO + +-- tsql +INSERT INTO temp_sp_helpuser(RoleName, Role_id, Users_in_role, UserID) EXEC sp_helpuser 'db_securityadmin'; +GO +~~ROW COUNT: 1~~ + + +SELECT Rolename, sys.user_name(Role_id), Users_in_role, sys.user_name(UserID) FROM temp_sp_helpuser +WHERE Rolename = 'db_securityadmin' ORDER BY Users_in_role; +GO +~~START~~ +varchar#!#nvarchar#!#varchar#!#nvarchar +db_securityadmin#!#db_securityadmin#!#babel_5135_dbsecadmin_u1#!#babel_5135_dbsecadmin_u1 +~~END~~ + + +-- tsql +DROP TABLE temp_sp_helpuser; +GO + +-- test for sp_helprole +CREATE TABLE temp_sp_helprole(RoleName sys.sysname, RoleId smallint, IsAppRole int); +GO + +GRANT INSERT,SELECT ON temp_sp_helprole TO PUBLIC; +GO + +-- tsql user=babel_5135_dbsecadmin_l1 password=12345678 +INSERT INTO temp_sp_helprole(RoleName, RoleId, IsAppRole) EXEC sp_helprole 'db_securityadmin'; +GO +~~ROW COUNT: 1~~ + + +SELECT RoleName, sys.user_name(RoleId), IsAppRole FROM temp_sp_helprole +WHERE RoleName = 'db_securityadmin'; +GO +~~START~~ +varchar#!#nvarchar#!#int +db_securityadmin#!#db_securityadmin#!#0 +~~END~~ + + +-- tsql +TRUNCATE TABLE temp_sp_helprole; +GO + +-- tsql +INSERT INTO temp_sp_helprole(RoleName, RoleId, IsAppRole) EXEC sp_helprole 'db_securityadmin'; +GO +~~ROW COUNT: 1~~ + + +SELECT RoleName, sys.user_name(RoleId), IsAppRole FROM temp_sp_helprole +WHERE RoleName = 'db_securityadmin'; +GO +~~START~~ +varchar#!#nvarchar#!#int +db_securityadmin#!#db_securityadmin#!#0 +~~END~~ + + +-- tsql +DROP TABLE temp_sp_helprole; +GO + +-- test for temp_sp_helprolemember +CREATE TABLE temp_sp_helprolemember(DbRole sys.sysname, MemberName sys.sysname, MemberSID SYS.VARBINARY(85)); +GO + +GRANT INSERT,SELECT ON temp_sp_helprolemember TO PUBLIC; +GO + +-- tsql user=babel_5135_dbsecadmin_l1 password=12345678 +INSERT INTO temp_sp_helprolemember(DbRole, MemberName, MemberSID) EXEC sp_helprolemember 'db_securityadmin'; +GO +~~ROW COUNT: 1~~ + + +SELECT DbRole, MemberName FROM temp_sp_helprolemember +WHERE DbRole = 'db_securityadmin' ORDER BY MemberName; +GO +~~START~~ +varchar#!#varchar +db_securityadmin#!#babel_5135_dbsecadmin_u1 +~~END~~ + + +-- tsql +TRUNCATE TABLE temp_sp_helprolemember; +GO + +-- tsql +INSERT INTO temp_sp_helprolemember(DbRole, MemberName, MemberSID) EXEC sp_helprolemember 'db_securityadmin'; +GO +~~ROW COUNT: 1~~ + + +SELECT DbRole, MemberName FROM temp_sp_helprolemember +WHERE DbRole = 'db_securityadmin' ORDER BY MemberName; +GO +~~START~~ +varchar#!#varchar +db_securityadmin#!#babel_5135_dbsecadmin_u1 +~~END~~ + + +-- tsql +DROP TABLE temp_sp_helprolemember; +GO + +USE babel_5135_db1; +GO SELECT name, type, type_desc, default_schema_name, is_fixed_role, authentication_type_desc FROM sys.database_principals WHERE NAME = 'db_securityadmin'; GO diff --git a/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix b/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix index e1a97cf6e4..ec21eb8275 100644 --- a/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix +++ b/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix @@ -295,7 +295,7 @@ SELECT is_member('db_securityadmin'), is_rolemember('db_securityadmin'); GO -- tsql -EXEC sp_droprolemember 'db_securityadmin', 'babel_5135_dbsecadmin_u1'; +EXEC sp_addrolemember 'db_securityadmin', 'babel_5135_dbsecadmin_u1'; GO -- tsql user=babel_5135_dbsecadmin_l1 password=12345678 @@ -308,46 +308,100 @@ GO -- CASE 7.3 - sp_helprole -- CASE 7.4 - sp_helprolemember +-- test for helpuser +-- tsql +CREATE TABLE temp_sp_helpuser(RoleName sys.sysname, Role_id smallint, +Users_in_role sys.sysname, UserID smallint); +GO + +GRANT INSERT,SELECT ON temp_sp_helpuser TO PUBLIC; +GO + -- tsql user=babel_5135_dbsecadmin_l1 password=12345678 -CREATE TABLE temp_sp_helpuser(UserName sys.sysname, RoleName sys.sysname, LoginName sys.sysname, -DefDBName sys.sysname, DefSchemaName sys.sysname, UserID int, SID SYS.VARBINARY(85)); +INSERT INTO temp_sp_helpuser(RoleName, Role_id, Users_in_role, UserID) EXEC sp_helpuser 'db_securityadmin'; GO -CREATE TABLE temp_sp_helprole(RoleName sys.sysname, RoleId smallint, IsAppRole int); +SELECT Rolename, sys.user_name(Role_id), Users_in_role, sys.user_name(UserID) FROM temp_sp_helpuser +WHERE Rolename = 'db_securityadmin' ORDER BY Users_in_role; GO -CREATE TABLE temp_sp_helprolemember(DbRole sys.sysname, MemberName sys.sysname, MemberSID SYS.VARBINARY(85)); +-- tsql +TRUNCATE TABLE temp_sp_helpuser; GO -INSERT INTO temp_sp_helpuser(UserName, RoleName, LoginName, DefDBName, DefSchemaName, UserID, SID) EXEC sp_helpuser 'db_securityadmin'; +-- tsql +INSERT INTO temp_sp_helpuser(RoleName, Role_id, Users_in_role, UserID) EXEC sp_helpuser 'db_securityadmin'; GO -SELECT UserName, Rolename, LoginName, DefDBName, DefSchemaName FROM temp_sp_helpuser -where UserName = 'db_securityadmin'; +SELECT Rolename, sys.user_name(Role_id), Users_in_role, sys.user_name(UserID) FROM temp_sp_helpuser +WHERE Rolename = 'db_securityadmin' ORDER BY Users_in_role; GO -exec sp_helpuser 'db_securityadmin'; +-- tsql +DROP TABLE temp_sp_helpuser; GO -exec sp_helprole 'db_securityadmin'; +-- test for sp_helprole +CREATE TABLE temp_sp_helprole(RoleName sys.sysname, RoleId smallint, IsAppRole int); GO -exec sp_helprolemember 'sp_helprolemember'; +GRANT INSERT,SELECT ON temp_sp_helprole TO PUBLIC; GO -exec sp_helprole ''; +-- tsql user=babel_5135_dbsecadmin_l1 password=12345678 +INSERT INTO temp_sp_helprole(RoleName, RoleId, IsAppRole) EXEC sp_helprole 'db_securityadmin'; +GO --- cleanup -DROP TABLE temp_sp_helpuser; +SELECT RoleName, sys.user_name(RoleId), IsAppRole FROM temp_sp_helprole +WHERE RoleName = 'db_securityadmin'; GO +-- tsql +TRUNCATE TABLE temp_sp_helprole; +GO + +-- tsql +INSERT INTO temp_sp_helprole(RoleName, RoleId, IsAppRole) EXEC sp_helprole 'db_securityadmin'; +GO + +SELECT RoleName, sys.user_name(RoleId), IsAppRole FROM temp_sp_helprole +WHERE RoleName = 'db_securityadmin'; +GO + +-- tsql DROP TABLE temp_sp_helprole; GO -DROP TABLE temp_sp_helprolemember; +-- test for temp_sp_helprolemember +CREATE TABLE temp_sp_helprolemember(DbRole sys.sysname, MemberName sys.sysname, MemberSID SYS.VARBINARY(85)); +GO + +GRANT INSERT,SELECT ON temp_sp_helprolemember TO PUBLIC; +GO + +-- tsql user=babel_5135_dbsecadmin_l1 password=12345678 +INSERT INTO temp_sp_helprolemember(DbRole, MemberName, MemberSID) EXEC sp_helprolemember 'db_securityadmin'; +GO + +SELECT DbRole, MemberName FROM temp_sp_helprolemember +WHERE DbRole = 'db_securityadmin' ORDER BY MemberName; GO --- system views testcases +-- tsql +TRUNCATE TABLE temp_sp_helprolemember; +GO + +-- tsql +INSERT INTO temp_sp_helprolemember(DbRole, MemberName, MemberSID) EXEC sp_helprolemember 'db_securityadmin'; +GO + +SELECT DbRole, MemberName FROM temp_sp_helprolemember +WHERE DbRole = 'db_securityadmin' ORDER BY MemberName; +GO + +-- tsql +DROP TABLE temp_sp_helprolemember; +GO USE babel_5135_db1; GO From e103d48c814de5b2383d35aa954c5caf8a0c3a6f Mon Sep 17 00:00:00 2001 From: Harsh Lunagariya Date: Thu, 24 Oct 2024 08:56:31 +0000 Subject: [PATCH 26/44] Address comments Signed-off-by: Harsh Lunagariya --- contrib/babelfishpg_tsql/src/dbcmds.c | 23 ++++++++++++++++++++++- contrib/babelfishpg_tsql/src/hooks.c | 4 +++- contrib/babelfishpg_tsql/src/multidb.c | 20 +++++++++++++++----- contrib/babelfishpg_tsql/src/multidb.h | 1 + contrib/babelfishpg_tsql/src/pl_exec-2.c | 3 +-- contrib/babelfishpg_tsql/src/pl_handler.c | 3 +-- 6 files changed, 43 insertions(+), 11 deletions(-) diff --git a/contrib/babelfishpg_tsql/src/dbcmds.c b/contrib/babelfishpg_tsql/src/dbcmds.c index b998a12690..6d9bb051ae 100644 --- a/contrib/babelfishpg_tsql/src/dbcmds.c +++ b/contrib/babelfishpg_tsql/src/dbcmds.c @@ -221,6 +221,14 @@ gen_createdb_subcmds(const char *dbname, const char *owner) update_CreateSchemaStmt(stmt, guest_schema, guest); } + pfree(schema); + pfree(dbo); + pfree(db_owner); + pfree(db_accessadmin); + pfree(db_securityadmin); + prfree(guest); + pfree(guest_schema); + return res; } @@ -242,7 +250,7 @@ add_fixed_user_roles_to_bbf_authid_user_ext(const char *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); - add_to_bbf_authid_user_ext(db_securityadmin, DB_SECURITYADMIN, dbname, NULL, NULL, true, true, false); + add_to_bbf_authid_user_ext(db_securityadmin, DB_SECURITYADMIN, dbname, NULL, NULL, true, false, false); /* * For master, tempdb and msdb databases, the guest user will be @@ -252,6 +260,12 @@ add_fixed_user_roles_to_bbf_authid_user_ext(const char *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); + + pfree(dbo); + pfree(db_owner); + pfree(db_accessadmin); + pfree(db_securityadmin); + pfree(guest); } /* @@ -357,6 +371,13 @@ gen_dropdb_subcmds(const char *dbname, List *db_users) stmt = parsetree_nth_stmt(stmt_list, i++); update_DropRoleStmt(stmt, dbo); + pfree(dbo); + pfree(db_owner); + pfree(db_accessadmin); + pfree(db_securityadmin); + pfree(schema); + pfree(guest_schema); + return stmt_list; } diff --git a/contrib/babelfishpg_tsql/src/hooks.c b/contrib/babelfishpg_tsql/src/hooks.c index 2de9c3b4dd..cceadb03a3 100644 --- a/contrib/babelfishpg_tsql/src/hooks.c +++ b/contrib/babelfishpg_tsql/src/hooks.c @@ -5605,10 +5605,12 @@ handle_grantstmt_for_dbsecadmin(ObjectType objType, Oid objId, Oid ownerId, AclM else { if (is_member_of_role(GetUserId(), - get_role_oid(get_db_securityadmin_role_name(get_cur_db_name()), false))) + get_role_oid(get_db_securityadmin_role_name(get_current_pltsql_db_name()), false))) { *grantorId = ownerId; *grantOptions = ACL_GRANT_OPTION_FOR(privileges); + if (nspname) + pfree(nspname); return; } } diff --git a/contrib/babelfishpg_tsql/src/multidb.c b/contrib/babelfishpg_tsql/src/multidb.c index 99cfff482c..d8451a0eb5 100644 --- a/contrib/babelfishpg_tsql/src/multidb.c +++ b/contrib/babelfishpg_tsql/src/multidb.c @@ -1451,6 +1451,16 @@ get_db_accessadmin_role_name(const char *dbname) 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_db_securityadmin_role_name(const char *dbname) { @@ -1467,13 +1477,13 @@ get_db_securityadmin_role_name(const char *dbname) } Oid -get_db_accessadmin_oid(const char *dbname, bool missing_ok) +get_db_securityadmin_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); + char *db_securityadmin_name = get_db_securityadmin_role_name(dbname); + Oid db_securityadmin_oid = get_role_oid(db_securityadmin_name, missing_ok); + pfree(db_securityadmin_name); - return db_accessadmin_oid; + return db_securityadmin_oid; } char * diff --git a/contrib/babelfishpg_tsql/src/multidb.h b/contrib/babelfishpg_tsql/src/multidb.h index 155cf08cf5..441b1f44c9 100644 --- a/contrib/babelfishpg_tsql/src/multidb.h +++ b/contrib/babelfishpg_tsql/src/multidb.h @@ -26,6 +26,7 @@ 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 char *get_db_securityadmin_role_name(const char *dbname); +extern Oid get_db_securityadmin_oid(const char *dbname, bool missing_ok); 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); diff --git a/contrib/babelfishpg_tsql/src/pl_exec-2.c b/contrib/babelfishpg_tsql/src/pl_exec-2.c index e02620fe71..607e9f9dbe 100644 --- a/contrib/babelfishpg_tsql/src/pl_exec-2.c +++ b/contrib/babelfishpg_tsql/src/pl_exec-2.c @@ -3738,7 +3738,6 @@ exec_stmt_grantschema(PLtsql_execstate *estate, PLtsql_stmt_grantschema *stmt) Oid schemaOid; char *user = GetUserNameFromId(GetUserId(), false); const char *db_owner = get_owner_of_db(dbname); - const char *db_securityadmin_role = get_db_securityadmin_role_name(dbname); login_is_db_owner = 0 == strcmp(login, db_owner); schema_name = get_physical_schema_name(dbname, stmt->schema_name); @@ -3803,7 +3802,7 @@ exec_stmt_grantschema(PLtsql_execstate *estate, PLtsql_stmt_grantschema *stmt) if (!is_member_of_role(GetSessionUserId(), get_sysadmin_oid()) && !login_is_db_owner && !object_ownercheck(NamespaceRelationId, schemaOid, GetUserId()) && - !has_privs_of_role(GetUserId(), get_role_oid(db_securityadmin_role, false))) + !has_privs_of_role(GetUserId(), get_db_securityadmin_oid(dbname, false))) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("Cannot find the schema \"%s\", because it does not exist or you do not have permission.", stmt->schema_name))); diff --git a/contrib/babelfishpg_tsql/src/pl_handler.c b/contrib/babelfishpg_tsql/src/pl_handler.c index dfec0aadc4..af71d7862f 100644 --- a/contrib/babelfishpg_tsql/src/pl_handler.c +++ b/contrib/babelfishpg_tsql/src/pl_handler.c @@ -3003,11 +3003,10 @@ bbf_ProcessUtility(PlannedStmt *pstmt, else if (isuser || isrole) { char *current_db_name = get_cur_db_name(); - const char *db_securityadmin_role = get_db_securityadmin_role_name(current_db_name); 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))) || - (isrole && has_privs_of_role(GetUserId(), get_role_oid(db_securityadmin_role, false)))) + (isrole && has_privs_of_role(GetUserId(), get_db_securityadmin_oid(current_db_name, false)))) { /* * members of db_owner can create roles and users From d45f5c7cc1a2b7e9b184e61fb93f7a72fda45c49 Mon Sep 17 00:00:00 2001 From: Harsh Lunagariya Date: Thu, 24 Oct 2024 10:42:35 +0000 Subject: [PATCH 27/44] Test update Signed-off-by: Harsh Lunagariya --- test/JDBC/expected/db_securityadmin-vu-verify.out | 4 ++-- test/JDBC/input/ownership/db_securityadmin-vu-verify.mix | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/JDBC/expected/db_securityadmin-vu-verify.out b/test/JDBC/expected/db_securityadmin-vu-verify.out index f88f8c63c8..ac734ccc3c 100644 --- a/test/JDBC/expected/db_securityadmin-vu-verify.out +++ b/test/JDBC/expected/db_securityadmin-vu-verify.out @@ -539,8 +539,8 @@ int#!#int -- CASE 7.3 - sp_helprole -- CASE 7.4 - sp_helprolemember -- test for helpuser -CREATE TABLE temp_sp_helpuser(RoleName sys.sysname, Role_id smallint, -Users_in_role sys.sysname, UserID smallint); +CREATE TABLE temp_sp_helpuser(RoleName sys.sysname, Role_id int, +Users_in_role sys.sysname, UserID int); GO GRANT INSERT,SELECT ON temp_sp_helpuser TO PUBLIC; diff --git a/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix b/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix index ec21eb8275..39b6c51cfd 100644 --- a/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix +++ b/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix @@ -310,8 +310,8 @@ GO -- test for helpuser -- tsql -CREATE TABLE temp_sp_helpuser(RoleName sys.sysname, Role_id smallint, -Users_in_role sys.sysname, UserID smallint); +CREATE TABLE temp_sp_helpuser(RoleName sys.sysname, Role_id int, +Users_in_role sys.sysname, UserID int); GO GRANT INSERT,SELECT ON temp_sp_helpuser TO PUBLIC; From 03d13019ff5dc7710b1f75ae908ad86f7a4d722e Mon Sep 17 00:00:00 2001 From: Harsh Lunagariya Date: Thu, 24 Oct 2024 16:06:36 +0000 Subject: [PATCH 28/44] fix Signed-off-by: Harsh Lunagariya --- contrib/babelfishpg_tsql/src/hooks.c | 19 +++--- .../Test-sp_helpdbfixedrole-vu-verify.out | 4 +- .../expected/db_securityadmin-vu-cleanup.out | 2 + .../expected/db_securityadmin-vu-prepare.out | 20 ++++++ .../expected/db_securityadmin-vu-verify.out | 51 +++++++++++++++ .../ownership/db_securityadmin-vu-cleanup.mix | 4 ++ .../ownership/db_securityadmin-vu-prepare.mix | 25 +++++++- .../ownership/db_securityadmin-vu-verify.mix | 63 +++++++++++++++++-- 8 files changed, 173 insertions(+), 15 deletions(-) diff --git a/contrib/babelfishpg_tsql/src/hooks.c b/contrib/babelfishpg_tsql/src/hooks.c index cceadb03a3..39a296f934 100644 --- a/contrib/babelfishpg_tsql/src/hooks.c +++ b/contrib/babelfishpg_tsql/src/hooks.c @@ -5547,23 +5547,28 @@ handle_grantstmt_for_dbsecadmin(ObjectType objType, Oid objId, Oid ownerId, AclM Oid classid = InvalidOid; Oid schema_oid = InvalidOid; - if (!IS_TDS_CLIENT() || sql_dialect != SQL_DIALECT_TSQL) + /* + * Return if any of following condition is true + * 1. Not a TDS client + * 2. Not a TSQL dialect + * 3. Grantor is same as owner OR Grantor already has all the required privileges. + * This means already the best grantor has been selected using select_best_grantor(). + */ + if (!IS_TDS_CLIENT() || + sql_dialect != SQL_DIALECT_TSQL || + *grantorId == ownerId || + *grantOptions == ACL_GRANT_OPTION_FOR(privileges)) return; switch(objType) { case OBJECT_TABLE: - case OBJECT_SEQUENCE: case OBJECT_COLUMN: + case OBJECT_VIEW: classid = RelationRelationId; break; - case OBJECT_DOMAIN: - case OBJECT_TYPE: - classid = TypeRelationId; - break; case OBJECT_FUNCTION: case OBJECT_PROCEDURE: - case OBJECT_ROUTINE: classid = ProcedureRelationId; break; case OBJECT_SCHEMA: diff --git a/test/JDBC/expected/Test-sp_helpdbfixedrole-vu-verify.out b/test/JDBC/expected/Test-sp_helpdbfixedrole-vu-verify.out index b5051c152f..24ff4bb1c3 100644 --- a/test/JDBC/expected/Test-sp_helpdbfixedrole-vu-verify.out +++ b/test/JDBC/expected/Test-sp_helpdbfixedrole-vu-verify.out @@ -9,7 +9,7 @@ GO varchar#!#nvarchar db_owner#!#DB Owners db_accessadmin#!#DB Access Administrators -db_securityadmin#!#DB Security Adiministrators +db_securityadmin#!#DB Security Administrators db_datareader#!#DB Data Reader db_datawriter#!#DB Data Writer ~~END~~ @@ -80,7 +80,7 @@ GO ~~START~~ varchar#!#nvarchar db_accessadmin#!#DB Access Administrators -db_securityadmin#!#DB Security Adiministrators +db_securityadmin#!#DB Security Administrators db_datareader#!#DB Data Reader db_datawriter#!#DB Data Writer ~~END~~ diff --git a/test/JDBC/expected/db_securityadmin-vu-cleanup.out b/test/JDBC/expected/db_securityadmin-vu-cleanup.out index ecc085cfbd..2bf359c50e 100644 --- a/test/JDBC/expected/db_securityadmin-vu-cleanup.out +++ b/test/JDBC/expected/db_securityadmin-vu-cleanup.out @@ -3,6 +3,8 @@ USE master GO DROP DATABASE IF EXISTS babel_5135_db1; GO +DROP DATABASE IF EXISTS babel_5135_longdb_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz; +GO DROP ROLE babel_5135_r1; GO DROP LOGIN babel_5135_l2 diff --git a/test/JDBC/expected/db_securityadmin-vu-prepare.out b/test/JDBC/expected/db_securityadmin-vu-prepare.out index 1f715236fc..b81d5fa9b5 100644 --- a/test/JDBC/expected/db_securityadmin-vu-prepare.out +++ b/test/JDBC/expected/db_securityadmin-vu-prepare.out @@ -48,3 +48,23 @@ GO create database babel_5135_db1; GO + +create database babel_5135_longdb_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz +GO + +USE babel_5135_longdb_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz; +GO + +create user babel_5135_u1 for login babel_5135_l1; +GO + +CREATE VIEW babel_5135_show_role_mem AS +SELECT +roles.name AS RolePrincipalName +, members.name AS MemberPrincipalName +FROM sys.database_role_members AS db_role_mems +INNER JOIN sys.database_principals AS roles + ON db_role_mems.role_principal_id = roles.principal_id +INNER JOIN sys.database_principals AS members + ON db_role_mems.member_principal_id = members.principal_id order by MemberPrincipalName; +GO diff --git a/test/JDBC/expected/db_securityadmin-vu-verify.out b/test/JDBC/expected/db_securityadmin-vu-verify.out index ac734ccc3c..52af546176 100644 --- a/test/JDBC/expected/db_securityadmin-vu-verify.out +++ b/test/JDBC/expected/db_securityadmin-vu-verify.out @@ -13,6 +13,7 @@ GO -- CASE 1 Allowed syntaxes to modify the membership of db_securityadmin -- CASE 1.1 Validate ALTER ROLE ... ADD/DROP MEMBER -- CASE 1.2 Validate sp_addrolemember + -- CASE 1.3 Test inside database with truncated name ALTER ROLE db_securityadmin ADD MEMBER babel_5135_u1; GO @@ -53,6 +54,55 @@ varchar#!#varchar ~~END~~ +-- CASE 1.3 Test inside database with truncated name +USE babel_5135_longdb_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz; +GO + +ALTER ROLE db_securityadmin ADD MEMBER babel_5135_u1; +GO + +SELECT * FROM babel_5135_show_role_mem WHERE RolePrincipalName = 'db_securityadmin'; +GO +~~START~~ +varchar#!#varchar +db_securityadmin#!#babel_5135_u1 +~~END~~ + + +ALTER ROLE db_securityadmin DROP MEMBER babel_5135_u1; +GO + +SELECT * FROM babel_5135_show_role_mem WHERE RolePrincipalName = 'db_securityadmin'; +GO +~~START~~ +varchar#!#varchar +~~END~~ + + +EXEC sp_addrolemember 'db_securityadmin', 'babel_5135_u1'; +GO + +SELECT * FROM babel_5135_show_role_mem WHERE RolePrincipalName = 'db_securityadmin'; +GO +~~START~~ +varchar#!#varchar +db_securityadmin#!#babel_5135_u1 +~~END~~ + + +EXEC sp_droprolemember 'db_securityadmin', 'babel_5135_u1'; +GO + +SELECT * FROM babel_5135_show_role_mem WHERE RolePrincipalName = 'db_securityadmin'; +GO +~~START~~ +varchar#!#varchar +~~END~~ + + +USE master; +GO + -- tsql -- CASE 2 - Only members of db_owner should be able to modify the membership of db_securityadmin -- [already covered by CASE 1] CASE 2.1 - Verify members of db_owner can modify the membership @@ -674,6 +724,7 @@ db_securityadmin#!#babel_5135_dbsecadmin_u1 DROP TABLE temp_sp_helprolemember; GO +-- CASE XXXXXX USE babel_5135_db1; GO diff --git a/test/JDBC/input/ownership/db_securityadmin-vu-cleanup.mix b/test/JDBC/input/ownership/db_securityadmin-vu-cleanup.mix index ecc085cfbd..e9cb35ba72 100644 --- a/test/JDBC/input/ownership/db_securityadmin-vu-cleanup.mix +++ b/test/JDBC/input/ownership/db_securityadmin-vu-cleanup.mix @@ -3,6 +3,8 @@ USE master GO DROP DATABASE IF EXISTS babel_5135_db1; GO +DROP DATABASE IF EXISTS babel_5135_longdb_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz; +GO DROP ROLE babel_5135_r1; GO DROP LOGIN babel_5135_l2 @@ -21,6 +23,8 @@ DROP PROCEDURE babel_5135_schema1.babel_5135_p1; GO DROP FUNCTION babel_5135_schema1.babel_5135_f1(); GO +DROP FUNCTION babel_5135_schema1.babel_5135_tvf1(); +GO DROP SCHEMA babel_5135_schema1; GO DROP USER babel_5135_u1; diff --git a/test/JDBC/input/ownership/db_securityadmin-vu-prepare.mix b/test/JDBC/input/ownership/db_securityadmin-vu-prepare.mix index 1f715236fc..213a541fe7 100644 --- a/test/JDBC/input/ownership/db_securityadmin-vu-prepare.mix +++ b/test/JDBC/input/ownership/db_securityadmin-vu-prepare.mix @@ -23,7 +23,7 @@ GO create schema babel_5135_schema1; GO -create table babel_5135_schema1.babel_5135_t1(a int); +create table babel_5135_schema1.babel_5135_t1(a int, b int); GO create view babel_5135_schema1.babel_5135_v1 as select 1; @@ -35,6 +35,9 @@ GO CREATE FUNCTION babel_5135_schema1.babel_5135_f1() RETURNS INT AS BEGIN return 1; END GO +CREATE FUNCTION babel_5135_schema1.babel_5135_tvf1() RETURNS TABLE AS RETURN (SELECT a, b FROM babel_5135_schema1.babel_5135_t1); +GO + CREATE VIEW babel_5135_show_role_mem AS SELECT roles.name AS RolePrincipalName @@ -48,3 +51,23 @@ GO create database babel_5135_db1; GO + +create database babel_5135_longdb_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz +GO + +USE babel_5135_longdb_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz; +GO + +create user babel_5135_u1 for login babel_5135_l1; +GO + +CREATE VIEW babel_5135_show_role_mem AS +SELECT +roles.name AS RolePrincipalName +, members.name AS MemberPrincipalName +FROM sys.database_role_members AS db_role_mems +INNER JOIN sys.database_principals AS roles + ON db_role_mems.role_principal_id = roles.principal_id +INNER JOIN sys.database_principals AS members + ON db_role_mems.member_principal_id = members.principal_id order by MemberPrincipalName; +GO \ No newline at end of file diff --git a/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix b/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix index 39b6c51cfd..b6dc69fa7d 100644 --- a/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix +++ b/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix @@ -12,6 +12,7 @@ GO -- CASE 1 Allowed syntaxes to modify the membership of db_securityadmin -- CASE 1.1 Validate ALTER ROLE ... ADD/DROP MEMBER -- CASE 1.2 Validate sp_addrolemember + -- CASE 1.3 Test inside database with truncated name -- tsql ALTER ROLE db_securityadmin ADD MEMBER babel_5135_u1; GO @@ -43,6 +44,37 @@ GO SELECT * FROM babel_5135_show_role_mem WHERE RolePrincipalName = 'db_securityadmin'; GO +-- CASE 1.3 Test inside database with truncated name +USE babel_5135_longdb_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz; +GO + +ALTER ROLE db_securityadmin ADD MEMBER babel_5135_u1; +GO + +SELECT * FROM babel_5135_show_role_mem WHERE RolePrincipalName = 'db_securityadmin'; +GO + +ALTER ROLE db_securityadmin DROP MEMBER babel_5135_u1; +GO + +SELECT * FROM babel_5135_show_role_mem WHERE RolePrincipalName = 'db_securityadmin'; +GO + +EXEC sp_addrolemember 'db_securityadmin', 'babel_5135_u1'; +GO + +SELECT * FROM babel_5135_show_role_mem WHERE RolePrincipalName = 'db_securityadmin'; +GO + +EXEC sp_droprolemember 'db_securityadmin', 'babel_5135_u1'; +GO + +SELECT * FROM babel_5135_show_role_mem WHERE RolePrincipalName = 'db_securityadmin'; +GO + +USE master; +GO + -- CASE 2 - Only members of db_owner should be able to modify the membership of db_securityadmin -- [already covered by CASE 1] CASE 2.1 - Verify members of db_owner can modify the membership -- CASE 2.2 - Verify that members of db_securityadmin itself can't modify it's own membership @@ -150,13 +182,15 @@ GO GRANT EXECUTE ON babel_5135_schema1.babel_5135_f1 TO babel_5135_u1; GO +GRANT EXECUTE ON babel_5135_schema1.babel_5135_tvf1 TO babel_5135_u1; +GO -- tsql user=babel_5135_l1 password=12345678 SELECT current_user; GO SELECT COUNT(*) FROM babel_5135_schema1.babel_5135_t1; -INSERT INTO babel_5135_schema1.babel_5135_t1 VALUES (1); +INSERT INTO babel_5135_schema1.babel_5135_t1 VALUES (1,2); UPDATE babel_5135_schema1.babel_5135_t1 SET a = 2 WHERE a = 1; DELETE FROM babel_5135_schema1.babel_5135_t1 WHERE a = 2; GO @@ -170,6 +204,9 @@ GO SELECT babel_5135_schema1.babel_5135_f1(); GO +SELECT * FROM babel_5135_schema1.babel_5135_tvf1(); +GO + -- tsql user=babel_5135_dbsecadmin_l1 password=12345678 REVOKE SELECT, INSERT, UPDATE, DELETE ON babel_5135_schema1.babel_5135_t1 FROM babel_5135_u1; GO @@ -183,12 +220,15 @@ GO REVOKE EXECUTE ON babel_5135_schema1.babel_5135_f1 FROM babel_5135_u1; GO +REVOKE EXECUTE ON babel_5135_schema1.babel_5135_tvf1 FROM babel_5135_u1; +GO + -- tsql user=babel_5135_l1 password=12345678 SELECT current_user; GO SELECT COUNT(*) FROM babel_5135_schema1.babel_5135_t1; -INSERT INTO babel_5135_schema1.babel_5135_t1 VALUES (1); +INSERT INTO babel_5135_schema1.babel_5135_t1 VALUES (1,2); UPDATE babel_5135_schema1.babel_5135_t1 SET a = 2 WHERE a = 1; DELETE FROM babel_5135_schema1.babel_5135_t1 WHERE a = 2; GO @@ -202,6 +242,9 @@ GO SELECT babel_5135_schema1.babel_5135_f1(); GO +SELECT * FROM babel_5135_schema1.babel_5135_tvf1(); +GO + -- tsql user=babel_5135_dbsecadmin_l1 password=12345678 GRANT SELECT, INSERT, UPDATE, DELETE, EXECUTE ON SCHEMA::babel_5135_schema1 TO babel_5135_u1; GO @@ -211,7 +254,7 @@ SELECT current_user; GO SELECT COUNT(*) FROM babel_5135_schema1.babel_5135_t1; -INSERT INTO babel_5135_schema1.babel_5135_t1 VALUES (1); +INSERT INTO babel_5135_schema1.babel_5135_t1 VALUES (1,2); UPDATE babel_5135_schema1.babel_5135_t1 SET a = 2 WHERE a = 1; DELETE FROM babel_5135_schema1.babel_5135_t1 WHERE a = 2; GO @@ -225,6 +268,9 @@ GO SELECT babel_5135_schema1.babel_5135_f1(); GO +SELECT * FROM babel_5135_schema1.babel_5135_tvf1(); +GO + -- tsql user=babel_5135_dbsecadmin_l1 password=12345678 REVOKE SELECT, INSERT, UPDATE, DELETE, EXECUTE ON SCHEMA::babel_5135_schema1 FROM babel_5135_u1; GO @@ -234,7 +280,7 @@ SELECT current_user; GO SELECT COUNT(*) FROM babel_5135_schema1.babel_5135_t1; -INSERT INTO babel_5135_schema1.babel_5135_t1 VALUES (1); +INSERT INTO babel_5135_schema1.babel_5135_t1 VALUES (1,2); UPDATE babel_5135_schema1.babel_5135_t1 SET a = 2 WHERE a = 1; DELETE FROM babel_5135_schema1.babel_5135_t1 WHERE a = 2; GO @@ -248,13 +294,16 @@ GO SELECT babel_5135_schema1.babel_5135_f1(); GO +SELECT * FROM babel_5135_schema1.babel_5135_tvf1(); +GO + -- CASE 5.2 - Validate members of db_securityadmin can not actually access given objects -- tsql user=babel_5135_dbsecadmin_l1 password=12345678 SELECT current_user; GO SELECT COUNT(*) FROM babel_5135_schema1.babel_5135_t1; -INSERT INTO babel_5135_schema1.babel_5135_t1 VALUES (1); +INSERT INTO babel_5135_schema1.babel_5135_t1 VALUES (1,2); UPDATE babel_5135_schema1.babel_5135_t1 SET a = 2 WHERE a = 1; DELETE FROM babel_5135_schema1.babel_5135_t1 WHERE a = 2; GO @@ -268,6 +317,9 @@ GO SELECT babel_5135_schema1.babel_5135_f1(); GO +SELECT * FROM babel_5135_schema1.babel_5135_tvf1(); +GO + -- CASE 6 - is_member() / is_rolemember() testcases -- tsql SELECT is_member('db_securityadmin'), is_rolemember('db_securityadmin'); @@ -403,6 +455,7 @@ GO DROP TABLE temp_sp_helprolemember; GO +-- CASE XXXXXX USE babel_5135_db1; GO From 0df1477bffb72142640efec0bc41abe30ed2c40e Mon Sep 17 00:00:00 2001 From: Harsh Lunagariya Date: Thu, 24 Oct 2024 18:31:02 +0000 Subject: [PATCH 29/44] fix Signed-off-by: Harsh Lunagariya --- .../expected/db_securityadmin-vu-cleanup.out | 2 + .../expected/db_securityadmin-vu-prepare.out | 5 +- .../expected/db_securityadmin-vu-verify.out | 54 +++++++++++++++++-- 3 files changed, 55 insertions(+), 6 deletions(-) diff --git a/test/JDBC/expected/db_securityadmin-vu-cleanup.out b/test/JDBC/expected/db_securityadmin-vu-cleanup.out index 2bf359c50e..e9cb35ba72 100644 --- a/test/JDBC/expected/db_securityadmin-vu-cleanup.out +++ b/test/JDBC/expected/db_securityadmin-vu-cleanup.out @@ -23,6 +23,8 @@ DROP PROCEDURE babel_5135_schema1.babel_5135_p1; GO DROP FUNCTION babel_5135_schema1.babel_5135_f1(); GO +DROP FUNCTION babel_5135_schema1.babel_5135_tvf1(); +GO DROP SCHEMA babel_5135_schema1; GO DROP USER babel_5135_u1; diff --git a/test/JDBC/expected/db_securityadmin-vu-prepare.out b/test/JDBC/expected/db_securityadmin-vu-prepare.out index b81d5fa9b5..932a2f2654 100644 --- a/test/JDBC/expected/db_securityadmin-vu-prepare.out +++ b/test/JDBC/expected/db_securityadmin-vu-prepare.out @@ -23,7 +23,7 @@ GO create schema babel_5135_schema1; GO -create table babel_5135_schema1.babel_5135_t1(a int); +create table babel_5135_schema1.babel_5135_t1(a int, b int); GO create view babel_5135_schema1.babel_5135_v1 as select 1; @@ -35,6 +35,9 @@ GO CREATE FUNCTION babel_5135_schema1.babel_5135_f1() RETURNS INT AS BEGIN return 1; END GO +CREATE FUNCTION babel_5135_schema1.babel_5135_tvf1() RETURNS TABLE AS RETURN (SELECT a, b FROM babel_5135_schema1.babel_5135_t1); +GO + CREATE VIEW babel_5135_show_role_mem AS SELECT roles.name AS RolePrincipalName diff --git a/test/JDBC/expected/db_securityadmin-vu-verify.out b/test/JDBC/expected/db_securityadmin-vu-verify.out index 52af546176..36dcdb1054 100644 --- a/test/JDBC/expected/db_securityadmin-vu-verify.out +++ b/test/JDBC/expected/db_securityadmin-vu-verify.out @@ -279,6 +279,12 @@ GO ~~ERROR (Message: permission denied for function babel_5135_f1)~~ +GRANT EXECUTE ON babel_5135_schema1.babel_5135_tvf1 TO babel_5135_u1; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for function babel_5135_tvf1)~~ + -- tsql user=babel_5135_l1 password=12345678 SELECT current_user; @@ -290,7 +296,7 @@ babel_5135_u1 SELECT COUNT(*) FROM babel_5135_schema1.babel_5135_t1; -INSERT INTO babel_5135_schema1.babel_5135_t1 VALUES (1); +INSERT INTO babel_5135_schema1.babel_5135_t1 VALUES (1,2); UPDATE babel_5135_schema1.babel_5135_t1 SET a = 2 WHERE a = 1; DELETE FROM babel_5135_schema1.babel_5135_t1 WHERE a = 2; GO @@ -320,6 +326,13 @@ GO ~~ERROR (Message: permission denied for function babel_5135_f1)~~ +SELECT * FROM babel_5135_schema1.babel_5135_tvf1(); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for function babel_5135_tvf1)~~ + + -- tsql user=babel_5135_dbsecadmin_l1 password=12345678 REVOKE SELECT, INSERT, UPDATE, DELETE ON babel_5135_schema1.babel_5135_t1 FROM babel_5135_u1; GO @@ -333,6 +346,9 @@ GO REVOKE EXECUTE ON babel_5135_schema1.babel_5135_f1 FROM babel_5135_u1; GO +REVOKE EXECUTE ON babel_5135_schema1.babel_5135_tvf1 FROM babel_5135_u1; +GO + -- tsql user=babel_5135_l1 password=12345678 SELECT current_user; GO @@ -343,7 +359,7 @@ babel_5135_u1 SELECT COUNT(*) FROM babel_5135_schema1.babel_5135_t1; -INSERT INTO babel_5135_schema1.babel_5135_t1 VALUES (1); +INSERT INTO babel_5135_schema1.babel_5135_t1 VALUES (1,2); UPDATE babel_5135_schema1.babel_5135_t1 SET a = 2 WHERE a = 1; DELETE FROM babel_5135_schema1.babel_5135_t1 WHERE a = 2; GO @@ -373,6 +389,13 @@ GO ~~ERROR (Message: permission denied for function babel_5135_f1)~~ +SELECT * FROM babel_5135_schema1.babel_5135_tvf1(); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for function babel_5135_tvf1)~~ + + -- tsql user=babel_5135_dbsecadmin_l1 password=12345678 GRANT SELECT, INSERT, UPDATE, DELETE, EXECUTE ON SCHEMA::babel_5135_schema1 TO babel_5135_u1; GO @@ -387,7 +410,7 @@ babel_5135_u1 SELECT COUNT(*) FROM babel_5135_schema1.babel_5135_t1; -INSERT INTO babel_5135_schema1.babel_5135_t1 VALUES (1); +INSERT INTO babel_5135_schema1.babel_5135_t1 VALUES (1,2); UPDATE babel_5135_schema1.babel_5135_t1 SET a = 2 WHERE a = 1; DELETE FROM babel_5135_schema1.babel_5135_t1 WHERE a = 2; GO @@ -427,6 +450,13 @@ int ~~END~~ +SELECT * FROM babel_5135_schema1.babel_5135_tvf1(); +GO +~~START~~ +int#!#int +~~END~~ + + -- tsql user=babel_5135_dbsecadmin_l1 password=12345678 REVOKE SELECT, INSERT, UPDATE, DELETE, EXECUTE ON SCHEMA::babel_5135_schema1 FROM babel_5135_u1; GO @@ -441,7 +471,7 @@ babel_5135_u1 SELECT COUNT(*) FROM babel_5135_schema1.babel_5135_t1; -INSERT INTO babel_5135_schema1.babel_5135_t1 VALUES (1); +INSERT INTO babel_5135_schema1.babel_5135_t1 VALUES (1,2); UPDATE babel_5135_schema1.babel_5135_t1 SET a = 2 WHERE a = 1; DELETE FROM babel_5135_schema1.babel_5135_t1 WHERE a = 2; GO @@ -471,6 +501,13 @@ GO ~~ERROR (Message: permission denied for function babel_5135_f1)~~ +SELECT * FROM babel_5135_schema1.babel_5135_tvf1(); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for function babel_5135_tvf1)~~ + + -- tsql user=babel_5135_dbsecadmin_l1 password=12345678 -- CASE 5.2 - Validate members of db_securityadmin can not actually access given objects SELECT current_user; @@ -482,7 +519,7 @@ babel_5135_dbsecadmin_u1 SELECT COUNT(*) FROM babel_5135_schema1.babel_5135_t1; -INSERT INTO babel_5135_schema1.babel_5135_t1 VALUES (1); +INSERT INTO babel_5135_schema1.babel_5135_t1 VALUES (1,2); UPDATE babel_5135_schema1.babel_5135_t1 SET a = 2 WHERE a = 1; DELETE FROM babel_5135_schema1.babel_5135_t1 WHERE a = 2; GO @@ -512,6 +549,13 @@ GO ~~ERROR (Message: permission denied for function babel_5135_f1)~~ +SELECT * FROM babel_5135_schema1.babel_5135_tvf1(); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for function babel_5135_tvf1)~~ + + -- tsql -- CASE 6 - is_member() / is_rolemember() testcases SELECT is_member('db_securityadmin'), is_rolemember('db_securityadmin'); From d0c1c27901a867b7735ce02b8b46db3368bed5df Mon Sep 17 00:00:00 2001 From: Harsh Lunagariya Date: Thu, 24 Oct 2024 20:30:38 +0000 Subject: [PATCH 30/44] Test update Signed-off-by: Harsh Lunagariya --- contrib/babelfishpg_tsql/src/hooks.c | 23 +++++-- .../expected/db_securityadmin-vu-verify.out | 69 ++++++++++++++++++- .../ownership/db_securityadmin-vu-verify.mix | 69 ++++++++++++++++++- 3 files changed, 153 insertions(+), 8 deletions(-) diff --git a/contrib/babelfishpg_tsql/src/hooks.c b/contrib/babelfishpg_tsql/src/hooks.c index 39a296f934..0038e7c612 100644 --- a/contrib/babelfishpg_tsql/src/hooks.c +++ b/contrib/babelfishpg_tsql/src/hooks.c @@ -34,6 +34,7 @@ #include "common/logging.h" #include "executor/execExpr.h" #include "funcapi.h" +#include "libpq/libpq.h" #include "miscadmin.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" @@ -5540,8 +5541,14 @@ pltsql_get_object_identity_event_trigger(ObjectAddress* address) return identity; } +/* + * Allows execution of GRANT/REVOKE statement if current_user is member of db_securityadmin + * given that GRANT/REVOKE is being executed on current database's object. It is being + * ensured that schema of given object(in GRANT/REVOKE statement) belongs to current database. + */ static void -handle_grantstmt_for_dbsecadmin(ObjectType objType, Oid objId, Oid ownerId, AclMode privileges, Oid *grantorId, AclMode *grantOptions) +handle_grantstmt_for_dbsecadmin(ObjectType objType, Oid objId, Oid ownerId, + AclMode privileges, Oid *grantorId, AclMode *grantOptions) { ObjectAddress address; Oid classid = InvalidOid; @@ -5554,7 +5561,7 @@ handle_grantstmt_for_dbsecadmin(ObjectType objType, Oid objId, Oid ownerId, AclM * 3. Grantor is same as owner OR Grantor already has all the required privileges. * This means already the best grantor has been selected using select_best_grantor(). */ - if (!IS_TDS_CLIENT() || + if (!MyProcPort->is_tds_conn || sql_dialect != SQL_DIALECT_TSQL || *grantorId == ownerId || *grantOptions == ACL_GRANT_OPTION_FOR(privileges)) @@ -5595,10 +5602,9 @@ handle_grantstmt_for_dbsecadmin(ObjectType objType, Oid objId, Oid ownerId, AclM { char *nspname = get_namespace_name(schema_oid); /* - * Check if function's schema is from a different logical database and - * it is not a shared schema. If yes, then set userid to session user - * to allow cross database access. - */ + * Don't allow if object's schema is not from current database OR + * it is a shared schema. + */ if (nspname == NULL || is_shared_schema(nspname) || !is_schema_from_db(schema_oid, get_cur_db_id())) @@ -5609,6 +5615,11 @@ handle_grantstmt_for_dbsecadmin(ObjectType objType, Oid objId, Oid ownerId, AclM } else { + /* + * Check if current user is member of db_securityadmin role. + * If so, then grant/revoke the requested privileges by overriding + * grantId with ownerId. + */ if (is_member_of_role(GetUserId(), get_role_oid(get_db_securityadmin_role_name(get_current_pltsql_db_name()), false))) { diff --git a/test/JDBC/expected/db_securityadmin-vu-verify.out b/test/JDBC/expected/db_securityadmin-vu-verify.out index 36dcdb1054..92dcdb4a49 100644 --- a/test/JDBC/expected/db_securityadmin-vu-verify.out +++ b/test/JDBC/expected/db_securityadmin-vu-verify.out @@ -250,7 +250,8 @@ GO -- CASE 5 - GRANT/REVOKE management of permissions -- CASE 5.1 - Validate GRANT/REVOKE of object/schema privileges - -- CASE 5.2 - Validate members of db_securityadmin can not actually access given objects + -- CASE 5.2 - Validate members of db_securityadmin can not actually access given objects + -- CASE 5.3 - Validate that after GRANT/REVOKE, objectowner/dbo can execute REVOKE/GRANT respectively GRANT SELECT, INSERT, UPDATE, DELETE ON babel_5135_schema1.babel_5135_t1 TO babel_5135_u1; GO ~~ERROR (Code: 33557097)~~ @@ -556,6 +557,72 @@ GO ~~ERROR (Message: permission denied for function babel_5135_tvf1)~~ +-- tsql user=babel_5135_dbsecadmin_l1 password=12345678 +-- CASE 5.3 - Validate that after GRANT/REVOKE, objectowner/dbo can execute REVOKE/GRANT respectively +-- execute GRANT via db_securityadmin member and REVOKE it with object owner +GRANT SELECT, INSERT, UPDATE, DELETE ON babel_5135_schema1.babel_5135_t1 TO babel_5135_u1; +GO + +GRANT SELECT ON babel_5135_schema1.babel_5135_v1 TO babel_5135_u1; +GO + +GRANT EXECUTE ON babel_5135_schema1.babel_5135_p1 TO babel_5135_u1; +GO + +GRANT EXECUTE ON babel_5135_schema1.babel_5135_f1 TO babel_5135_u1; +GO + +GRANT EXECUTE ON babel_5135_schema1.babel_5135_tvf1 TO babel_5135_u1; +GO + +-- tsql +REVOKE SELECT, INSERT, UPDATE, DELETE ON babel_5135_schema1.babel_5135_t1 FROM babel_5135_u1; +GO + +REVOKE SELECT ON babel_5135_schema1.babel_5135_v1 FROM babel_5135_u1; +GO + +REVOKE EXECUTE ON babel_5135_schema1.babel_5135_p1 FROM babel_5135_u1; +GO + +REVOKE EXECUTE ON babel_5135_schema1.babel_5135_f1 FROM babel_5135_u1; +GO + +REVOKE EXECUTE ON babel_5135_schema1.babel_5135_tvf1 FROM babel_5135_u1; +GO + +-- execute GRANT as objectowner/dbo +GRANT SELECT, INSERT, UPDATE, DELETE ON babel_5135_schema1.babel_5135_t1 TO babel_5135_u1; +GO + +GRANT SELECT ON babel_5135_schema1.babel_5135_v1 TO babel_5135_u1; +GO + +GRANT EXECUTE ON babel_5135_schema1.babel_5135_p1 TO babel_5135_u1; +GO + +GRANT EXECUTE ON babel_5135_schema1.babel_5135_f1 TO babel_5135_u1; +GO + +GRANT EXECUTE ON babel_5135_schema1.babel_5135_tvf1 TO babel_5135_u1; +GO + +-- tsql user=babel_5135_dbsecadmin_l1 password=12345678 +REVOKE SELECT, INSERT, UPDATE, DELETE ON babel_5135_schema1.babel_5135_t1 FROM babel_5135_u1; +GO + +REVOKE SELECT ON babel_5135_schema1.babel_5135_v1 FROM babel_5135_u1; +GO + +REVOKE EXECUTE ON babel_5135_schema1.babel_5135_p1 FROM babel_5135_u1; +GO + +REVOKE EXECUTE ON babel_5135_schema1.babel_5135_f1 FROM babel_5135_u1; +GO + +REVOKE EXECUTE ON babel_5135_schema1.babel_5135_tvf1 FROM babel_5135_u1; +GO + -- tsql -- CASE 6 - is_member() / is_rolemember() testcases SELECT is_member('db_securityadmin'), is_rolemember('db_securityadmin'); diff --git a/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix b/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix index b6dc69fa7d..4637b1c3c9 100644 --- a/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix +++ b/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix @@ -169,7 +169,8 @@ GO -- CASE 5 - GRANT/REVOKE management of permissions -- CASE 5.1 - Validate GRANT/REVOKE of object/schema privileges - -- CASE 5.2 - Validate members of db_securityadmin can not actually access given objects + -- CASE 5.2 - Validate members of db_securityadmin can not actually access given objects + -- CASE 5.3 - Validate that after GRANT/REVOKE, objectowner/dbo can execute REVOKE/GRANT respectively GRANT SELECT, INSERT, UPDATE, DELETE ON babel_5135_schema1.babel_5135_t1 TO babel_5135_u1; GO @@ -320,6 +321,72 @@ GO SELECT * FROM babel_5135_schema1.babel_5135_tvf1(); GO +-- CASE 5.3 - Validate that after GRANT/REVOKE, objectowner/dbo can execute REVOKE/GRANT respectively +-- execute GRANT via db_securityadmin member and REVOKE it with object owner +-- tsql user=babel_5135_dbsecadmin_l1 password=12345678 +GRANT SELECT, INSERT, UPDATE, DELETE ON babel_5135_schema1.babel_5135_t1 TO babel_5135_u1; +GO + +GRANT SELECT ON babel_5135_schema1.babel_5135_v1 TO babel_5135_u1; +GO + +GRANT EXECUTE ON babel_5135_schema1.babel_5135_p1 TO babel_5135_u1; +GO + +GRANT EXECUTE ON babel_5135_schema1.babel_5135_f1 TO babel_5135_u1; +GO + +GRANT EXECUTE ON babel_5135_schema1.babel_5135_tvf1 TO babel_5135_u1; +GO + +-- tsql +REVOKE SELECT, INSERT, UPDATE, DELETE ON babel_5135_schema1.babel_5135_t1 FROM babel_5135_u1; +GO + +REVOKE SELECT ON babel_5135_schema1.babel_5135_v1 FROM babel_5135_u1; +GO + +REVOKE EXECUTE ON babel_5135_schema1.babel_5135_p1 FROM babel_5135_u1; +GO + +REVOKE EXECUTE ON babel_5135_schema1.babel_5135_f1 FROM babel_5135_u1; +GO + +REVOKE EXECUTE ON babel_5135_schema1.babel_5135_tvf1 FROM babel_5135_u1; +GO + +-- execute GRANT as objectowner/dbo +GRANT SELECT, INSERT, UPDATE, DELETE ON babel_5135_schema1.babel_5135_t1 TO babel_5135_u1; +GO + +GRANT SELECT ON babel_5135_schema1.babel_5135_v1 TO babel_5135_u1; +GO + +GRANT EXECUTE ON babel_5135_schema1.babel_5135_p1 TO babel_5135_u1; +GO + +GRANT EXECUTE ON babel_5135_schema1.babel_5135_f1 TO babel_5135_u1; +GO + +GRANT EXECUTE ON babel_5135_schema1.babel_5135_tvf1 TO babel_5135_u1; +GO + +-- tsql user=babel_5135_dbsecadmin_l1 password=12345678 +REVOKE SELECT, INSERT, UPDATE, DELETE ON babel_5135_schema1.babel_5135_t1 FROM babel_5135_u1; +GO + +REVOKE SELECT ON babel_5135_schema1.babel_5135_v1 FROM babel_5135_u1; +GO + +REVOKE EXECUTE ON babel_5135_schema1.babel_5135_p1 FROM babel_5135_u1; +GO + +REVOKE EXECUTE ON babel_5135_schema1.babel_5135_f1 FROM babel_5135_u1; +GO + +REVOKE EXECUTE ON babel_5135_schema1.babel_5135_tvf1 FROM babel_5135_u1; +GO + -- CASE 6 - is_member() / is_rolemember() testcases -- tsql SELECT is_member('db_securityadmin'), is_rolemember('db_securityadmin'); From c1e03e8c78f2e82c343c619ca01f8a11a6334f66 Mon Sep 17 00:00:00 2001 From: Harsh Lunagariya Date: Mon, 28 Oct 2024 09:02:40 +0000 Subject: [PATCH 31/44] Update expected test files Signed-off-by: Harsh Lunagariya --- test/JDBC/expected/BABEL-2403.out | 12 ++++++++++++ .../Test-sp_helpdbfixedrole-dep-vu-verify.out | 4 ++-- .../JDBC/expected/Test_alter_db_rename-vu-verify.out | 3 +++ .../expected/Test_sp_rename_database-vu-verify.out | 3 +++ test/JDBC/expected/Test_sp_renamedb-vu-verify.out | 3 +++ test/JDBC/expected/datareader_datawriter.out | 2 +- 6 files changed, 24 insertions(+), 3 deletions(-) diff --git a/test/JDBC/expected/BABEL-2403.out b/test/JDBC/expected/BABEL-2403.out index 20cd61fe4f..6ee9a44d8b 100644 --- a/test/JDBC/expected/BABEL-2403.out +++ b/test/JDBC/expected/BABEL-2403.out @@ -121,6 +121,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"} @@ -232,6 +238,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/Test-sp_helpdbfixedrole-dep-vu-verify.out b/test/JDBC/expected/Test-sp_helpdbfixedrole-dep-vu-verify.out index 57d286d8ef..8a423a1cea 100644 --- a/test/JDBC/expected/Test-sp_helpdbfixedrole-dep-vu-verify.out +++ b/test/JDBC/expected/Test-sp_helpdbfixedrole-dep-vu-verify.out @@ -4,7 +4,7 @@ GO varchar#!#nvarchar db_owner#!#DB Owners db_accessadmin#!#DB Access Administrators -db_securityadmin#!#DB Security Adiministrators +db_securityadmin#!#DB Security Administrators db_datareader#!#DB Data Reader db_datawriter#!#DB Data Writer ~~END~~ @@ -38,7 +38,7 @@ EXEC test_sp_helpdbfixedrole_proc 'DB_securityadmin' GO ~~START~~ varchar#!#nvarchar -db_securityadmin#!#DB Security Adiministrators +db_securityadmin#!#DB Security 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 687dd6e3cc..c435e0dcbd 100644 --- a/test/JDBC/expected/Test_alter_db_rename-vu-verify.out +++ b/test/JDBC/expected/Test_alter_db_rename-vu-verify.out @@ -23,6 +23,7 @@ rename_db_database1_db_accessadmin#!##!#db_accessadmin#!#rename_db_database1 rename_db_database1_db_datareader#!##!#db_datareader#!#rename_db_database1 rename_db_database1_db_datawriter#!##!#db_datawriter#!#rename_db_database1 rename_db_database1_db_owner#!##!#db_owner#!#rename_db_database1 +rename_db_database1_db_securityadmin#!##!#db_securityadmin#!#rename_db_database1 rename_db_database1_dbo#!##!#dbo#!#rename_db_database1 rename_db_database1_guest#!##!#guest#!#rename_db_database1 rename_db_database1_rename_db_login2#!#rename_db_login2#!#rename_db_login2#!#rename_db_database1 @@ -87,6 +88,7 @@ rename_db_database2_db_accessadmin#!##!#db_accessadmin#!#rename_db_database2 rename_db_database2_db_datareader#!##!#db_datareader#!#rename_db_database2 rename_db_database2_db_datawriter#!##!#db_datawriter#!#rename_db_database2 rename_db_database2_db_owner#!##!#db_owner#!#rename_db_database2 +rename_db_database2_db_securityadmin#!##!#db_securityadmin#!#rename_db_database2 rename_db_database2_dbo#!##!#dbo#!#rename_db_database2 rename_db_database2_guest#!##!#guest#!#rename_db_database2 rename_db_database2_rename_db_login2#!#rename_db_login2#!#rename_db_login2#!#rename_db_database2 @@ -198,6 +200,7 @@ thisnewdatabasenameiscasesensit4e1f355d810759b9f1a59b04496ed2e1#!##!#guest#!#thi thisnewdatabasenameiscasesensit72e4dcc7ed25f5536033cf547cd7f001#!##!#db_owner#!#thisnewdatabasenameiscasesensit44f3247005ec268e1a10c736599cfb7e thisnewdatabasenameiscasesensit7de06ed1a7bed768d6641b3e7841314c#!##!#db_datareader#!#thisnewdatabasenameiscasesensit44f3247005ec268e1a10c736599cfb7e thisnewdatabasenameiscasesensit944678472843354d6b3a4354630249a8#!##!#db_accessadmin#!#thisnewdatabasenameiscasesensit44f3247005ec268e1a10c736599cfb7e +thisnewdatabasenameiscasesensit9bafb01adb257f37faf768d9b70d81a7#!##!#db_securityadmin#!#thisnewdatabasenameiscasesensit44f3247005ec268e1a10c736599cfb7e thisnewdatabasenameiscasesensitc4313f9adf0e47cfa5aca25228e02f29#!##!#dbo#!#thisnewdatabasenameiscasesensit44f3247005ec268e1a10c736599cfb7e thisnewdatabasenameiscasesensitfa060d610d6e6cd0271b6ce99b258bcc#!##!#db_datawriter#!#thisnewdatabasenameiscasesensit44f3247005ec268e1a10c736599cfb7e ~~END~~ 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 25ed3c274a..1900036990 100644 --- a/test/JDBC/expected/Test_sp_rename_database-vu-verify.out +++ b/test/JDBC/expected/Test_sp_rename_database-vu-verify.out @@ -23,6 +23,7 @@ sp_rename_database1_db_accessadmin#!##!#db_accessadmin#!#sp_rename_database1 sp_rename_database1_db_datareader#!##!#db_datareader#!#sp_rename_database1 sp_rename_database1_db_datawriter#!##!#db_datawriter#!#sp_rename_database1 sp_rename_database1_db_owner#!##!#db_owner#!#sp_rename_database1 +sp_rename_database1_db_securityadmin#!##!#db_securityadmin#!#sp_rename_database1 sp_rename_database1_dbo#!##!#dbo#!#sp_rename_database1 sp_rename_database1_guest#!##!#guest#!#sp_rename_database1 sp_rename_database1_sp_rename_login2#!#sp_rename_login2#!#sp_rename_login2#!#sp_rename_database1 @@ -87,6 +88,7 @@ sp_rename_database2_db_accessadmin#!##!#db_accessadmin#!#sp_rename_database2 sp_rename_database2_db_datareader#!##!#db_datareader#!#sp_rename_database2 sp_rename_database2_db_datawriter#!##!#db_datawriter#!#sp_rename_database2 sp_rename_database2_db_owner#!##!#db_owner#!#sp_rename_database2 +sp_rename_database2_db_securityadmin#!##!#db_securityadmin#!#sp_rename_database2 sp_rename_database2_dbo#!##!#dbo#!#sp_rename_database2 sp_rename_database2_guest#!##!#guest#!#sp_rename_database2 sp_rename_database2_sp_rename_login2#!#sp_rename_login2#!#sp_rename_login2#!#sp_rename_database2 @@ -206,6 +208,7 @@ sp_rename_thisnewdatabasenameis21f79a8b66248a73068dca6edd5b0ca3#!##!#guest#!#sp_ sp_rename_thisnewdatabasenameis95c235131f6db63ef16f222aa48d0554#!##!#db_datareader#!#sp_rename_thisnewdatabasenameisb8bd7c94f797959aa629fc2f9e821637 sp_rename_thisnewdatabasenameisa0a5aa90abf2314f4773860fda5e43a2#!##!#db_accessadmin#!#sp_rename_thisnewdatabasenameisb8bd7c94f797959aa629fc2f9e821637 sp_rename_thisnewdatabasenameisc7c7032a834c11dbbbbf4911217c443a#!##!#db_datawriter#!#sp_rename_thisnewdatabasenameisb8bd7c94f797959aa629fc2f9e821637 +sp_rename_thisnewdatabasenameisf37d42f2565acdd17a6e787fa43e9065#!##!#db_securityadmin#!#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 a68d7ab49c..460a11cb6a 100644 --- a/test/JDBC/expected/Test_sp_renamedb-vu-verify.out +++ b/test/JDBC/expected/Test_sp_renamedb-vu-verify.out @@ -23,6 +23,7 @@ sp_renamedb_database1_db_accessadmin#!##!#db_accessadmin#!#sp_renamedb_database1 sp_renamedb_database1_db_datareader#!##!#db_datareader#!#sp_renamedb_database1 sp_renamedb_database1_db_datawriter#!##!#db_datawriter#!#sp_renamedb_database1 sp_renamedb_database1_db_owner#!##!#db_owner#!#sp_renamedb_database1 +sp_renamedb_database1_db_securityadmin#!##!#db_securityadmin#!#sp_renamedb_database1 sp_renamedb_database1_dbo#!##!#dbo#!#sp_renamedb_database1 sp_renamedb_database1_guest#!##!#guest#!#sp_renamedb_database1 sp_renamedb_database1_sp_renamedb_login2#!#sp_renamedb_login2#!#sp_renamedb_login2#!#sp_renamedb_database1 @@ -87,6 +88,7 @@ sp_renamedb_database2_db_accessadmin#!##!#db_accessadmin#!#sp_renamedb_database2 sp_renamedb_database2_db_datareader#!##!#db_datareader#!#sp_renamedb_database2 sp_renamedb_database2_db_datawriter#!##!#db_datawriter#!#sp_renamedb_database2 sp_renamedb_database2_db_owner#!##!#db_owner#!#sp_renamedb_database2 +sp_renamedb_database2_db_securityadmin#!##!#db_securityadmin#!#sp_renamedb_database2 sp_renamedb_database2_dbo#!##!#dbo#!#sp_renamedb_database2 sp_renamedb_database2_guest#!##!#guest#!#sp_renamedb_database2 sp_renamedb_database2_sp_renamedb_login2#!#sp_renamedb_login2#!#sp_renamedb_login2#!#sp_renamedb_database2 @@ -205,6 +207,7 @@ sp_renamedb_thisnewdatabasename115699cc11f7805d9b9b640d6455580c#!##!#dbo#!#sp_re sp_renamedb_thisnewdatabasename2a476218bfa8dba9ac86fb898b11e9a5#!##!#db_datawriter#!#sp_renamedb_thisnewdatabasename738bbb14cb857db43c693446c049f0bd sp_renamedb_thisnewdatabasename7052c471c798d0b08c69f719bcd607d7#!##!#db_datareader#!#sp_renamedb_thisnewdatabasename738bbb14cb857db43c693446c049f0bd sp_renamedb_thisnewdatabasenameb0dffbb56deab7ad4e684df689419c65#!##!#db_owner#!#sp_renamedb_thisnewdatabasename738bbb14cb857db43c693446c049f0bd +sp_renamedb_thisnewdatabasenameda6915c331b2fe3a4c4e33126c0366c1#!##!#db_securityadmin#!#sp_renamedb_thisnewdatabasename738bbb14cb857db43c693446c049f0bd sp_renamedb_thisnewdatabasenamedeb7cafbbedd23f312d90e7c10a60901#!##!#guest#!#sp_renamedb_thisnewdatabasename738bbb14cb857db43c693446c049f0bd sp_renamedb_thisnewdatabasenameeeb9e8f522c23281503d418ce3640572#!##!#db_accessadmin#!#sp_renamedb_thisnewdatabasename738bbb14cb857db43c693446c049f0bd ~~END~~ diff --git a/test/JDBC/expected/datareader_datawriter.out b/test/JDBC/expected/datareader_datawriter.out index 8fe304b2bb..ddc726e3b2 100644 --- a/test/JDBC/expected/datareader_datawriter.out +++ b/test/JDBC/expected/datareader_datawriter.out @@ -284,7 +284,7 @@ go -- Insert the results of sp_helprole into the temporary table INSERT INTO #UserRoles EXEC sp_helprole; go -~~ROW COUNT: 5~~ +~~ROW COUNT: 6~~ -- Select the desired fields from the temporary table SELECT RoleName, IsAppRole FROM #UserRoles WHERE RoleName IN ('db_datareader', 'db_datawriter'); From bffd4ed10a71584b519ab98b1c7547c46d177ae4 Mon Sep 17 00:00:00 2001 From: Harsh Lunagariya Date: Tue, 29 Oct 2024 11:17:05 +0000 Subject: [PATCH 32/44] Fix Signed-off-by: Harsh Lunagariya --- contrib/babelfishpg_tsql/src/hooks.c | 9 +-------- test/JDBC/expected/single_db/BABEL-2403.out | 12 ++++++++++++ .../expected/single_db/datareader_datawriter.out | 2 +- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/contrib/babelfishpg_tsql/src/hooks.c b/contrib/babelfishpg_tsql/src/hooks.c index 0038e7c612..03a8097b56 100644 --- a/contrib/babelfishpg_tsql/src/hooks.c +++ b/contrib/babelfishpg_tsql/src/hooks.c @@ -5600,17 +5600,12 @@ handle_grantstmt_for_dbsecadmin(ObjectType objType, Oid objId, Oid ownerId, if (OidIsValid(schema_oid)) { - char *nspname = get_namespace_name(schema_oid); /* * Don't allow if object's schema is not from current database OR * it is a shared schema. */ - if (nspname == NULL || - is_shared_schema(nspname) || - !is_schema_from_db(schema_oid, get_cur_db_id())) + if (!is_schema_from_db(schema_oid, get_cur_db_id())) { - if (nspname) - pfree(nspname); return; } else @@ -5625,8 +5620,6 @@ handle_grantstmt_for_dbsecadmin(ObjectType objType, Oid objId, Oid ownerId, { *grantorId = ownerId; *grantOptions = ACL_GRANT_OPTION_FOR(privileges); - if (nspname) - pfree(nspname); return; } } diff --git a/test/JDBC/expected/single_db/BABEL-2403.out b/test/JDBC/expected/single_db/BABEL-2403.out index 2f20395b10..08d51c0417 100644 --- a/test/JDBC/expected/single_db/BABEL-2403.out +++ b/test/JDBC/expected/single_db/BABEL-2403.out @@ -109,6 +109,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"} @@ -208,6 +214,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/datareader_datawriter.out b/test/JDBC/expected/single_db/datareader_datawriter.out index 570128b3df..4a0dcfa4f5 100644 --- a/test/JDBC/expected/single_db/datareader_datawriter.out +++ b/test/JDBC/expected/single_db/datareader_datawriter.out @@ -284,7 +284,7 @@ go -- Insert the results of sp_helprole into the temporary table INSERT INTO #UserRoles EXEC sp_helprole; go -~~ROW COUNT: 5~~ +~~ROW COUNT: 6~~ -- Select the desired fields from the temporary table SELECT RoleName, IsAppRole FROM #UserRoles WHERE RoleName IN ('db_datareader', 'db_datawriter'); From 2e4e08285fa17e0771c4b0fdf954aa6aaf700b81 Mon Sep 17 00:00:00 2001 From: Harsh Lunagariya Date: Tue, 29 Oct 2024 11:41:26 +0000 Subject: [PATCH 33/44] fix Signed-off-by: Harsh Lunagariya --- test/JDBC/expected/db_securityadmin-vu-cleanup.out | 2 -- test/JDBC/expected/db_securityadmin-vu-prepare.out | 3 --- test/JDBC/expected/db_securityadmin-vu-verify.out | 4 ++-- test/JDBC/input/ownership/db_securityadmin-vu-cleanup.mix | 2 -- test/JDBC/input/ownership/db_securityadmin-vu-prepare.mix | 3 --- test/JDBC/input/ownership/db_securityadmin-vu-verify.mix | 4 ++-- 6 files changed, 4 insertions(+), 14 deletions(-) diff --git a/test/JDBC/expected/db_securityadmin-vu-cleanup.out b/test/JDBC/expected/db_securityadmin-vu-cleanup.out index e9cb35ba72..46f571eb21 100644 --- a/test/JDBC/expected/db_securityadmin-vu-cleanup.out +++ b/test/JDBC/expected/db_securityadmin-vu-cleanup.out @@ -1,8 +1,6 @@ -- tsql USE master GO -DROP DATABASE IF EXISTS babel_5135_db1; -GO DROP DATABASE IF EXISTS babel_5135_longdb_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz; GO DROP ROLE babel_5135_r1; diff --git a/test/JDBC/expected/db_securityadmin-vu-prepare.out b/test/JDBC/expected/db_securityadmin-vu-prepare.out index 932a2f2654..dd68deed2a 100644 --- a/test/JDBC/expected/db_securityadmin-vu-prepare.out +++ b/test/JDBC/expected/db_securityadmin-vu-prepare.out @@ -49,9 +49,6 @@ INNER JOIN sys.database_principals AS members ON db_role_mems.member_principal_id = members.principal_id order by MemberPrincipalName; GO -create database babel_5135_db1; -GO - create database babel_5135_longdb_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz GO diff --git a/test/JDBC/expected/db_securityadmin-vu-verify.out b/test/JDBC/expected/db_securityadmin-vu-verify.out index 92dcdb4a49..db664f94ba 100644 --- a/test/JDBC/expected/db_securityadmin-vu-verify.out +++ b/test/JDBC/expected/db_securityadmin-vu-verify.out @@ -746,7 +746,7 @@ DROP TABLE temp_sp_helpuser; GO -- test for sp_helprole -CREATE TABLE temp_sp_helprole(RoleName sys.sysname, RoleId smallint, IsAppRole int); +CREATE TABLE temp_sp_helprole(RoleName sys.sysname, RoleId int, IsAppRole int); GO GRANT INSERT,SELECT ON temp_sp_helprole TO PUBLIC; @@ -836,7 +836,7 @@ DROP TABLE temp_sp_helprolemember; GO -- CASE XXXXXX -USE babel_5135_db1; +USE babel_5135_longdb_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz; GO SELECT name, type, type_desc, default_schema_name, is_fixed_role, authentication_type_desc FROM sys.database_principals WHERE NAME = 'db_securityadmin'; diff --git a/test/JDBC/input/ownership/db_securityadmin-vu-cleanup.mix b/test/JDBC/input/ownership/db_securityadmin-vu-cleanup.mix index e9cb35ba72..46f571eb21 100644 --- a/test/JDBC/input/ownership/db_securityadmin-vu-cleanup.mix +++ b/test/JDBC/input/ownership/db_securityadmin-vu-cleanup.mix @@ -1,8 +1,6 @@ -- tsql USE master GO -DROP DATABASE IF EXISTS babel_5135_db1; -GO DROP DATABASE IF EXISTS babel_5135_longdb_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz; GO DROP ROLE babel_5135_r1; diff --git a/test/JDBC/input/ownership/db_securityadmin-vu-prepare.mix b/test/JDBC/input/ownership/db_securityadmin-vu-prepare.mix index 213a541fe7..f43ce39eb7 100644 --- a/test/JDBC/input/ownership/db_securityadmin-vu-prepare.mix +++ b/test/JDBC/input/ownership/db_securityadmin-vu-prepare.mix @@ -49,9 +49,6 @@ INNER JOIN sys.database_principals AS members ON db_role_mems.member_principal_id = members.principal_id order by MemberPrincipalName; GO -create database babel_5135_db1; -GO - create database babel_5135_longdb_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz GO diff --git a/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix b/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix index 4637b1c3c9..0ad66eb70c 100644 --- a/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix +++ b/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix @@ -461,7 +461,7 @@ DROP TABLE temp_sp_helpuser; GO -- test for sp_helprole -CREATE TABLE temp_sp_helprole(RoleName sys.sysname, RoleId smallint, IsAppRole int); +CREATE TABLE temp_sp_helprole(RoleName sys.sysname, RoleId int, IsAppRole int); GO GRANT INSERT,SELECT ON temp_sp_helprole TO PUBLIC; @@ -523,7 +523,7 @@ DROP TABLE temp_sp_helprolemember; GO -- CASE XXXXXX -USE babel_5135_db1; +USE babel_5135_longdb_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz; GO SELECT name, type, type_desc, default_schema_name, is_fixed_role, authentication_type_desc FROM sys.database_principals WHERE NAME = 'db_securityadmin'; From ff81672a42c1b5846ed47bcb02619a8ca83cdacf Mon Sep 17 00:00:00 2001 From: Harsh Lunagariya Date: Tue, 29 Oct 2024 13:16:59 +0000 Subject: [PATCH 34/44] [Temp Change] Debugging Signed-off-by: Harsh Lunagariya --- .../ownership/db_securityadmin-vu-verify.mix | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix b/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix index 0ad66eb70c..6c34d2ea82 100644 --- a/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix +++ b/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix @@ -526,6 +526,23 @@ GO USE babel_5135_longdb_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz; GO +SELECT nspname, dbid, orig_name FROM babelfish_namespace_ext; +SELECT * FROM sys.pg_namespace_ext; +SELECT rolname, orig_username, database_name FROM babelfish_authid_user_ext; +SELECT rolname, orig_username, database_name FROM babelfish_authid_user_ext; +SELECT name, principal_id FROM sys.database_principals; +GO + +USE master; +GO + +SELECT nspname, dbid, orig_name FROM babelfish_namespace_ext; +SELECT * FROM sys.pg_namespace_ext; +SELECT rolname, orig_username, database_name FROM babelfish_authid_user_ext; +SELECT rolname, orig_username, database_name FROM babelfish_authid_user_ext; +SELECT name, principal_id FROM sys.database_principals; +GO + SELECT name, type, type_desc, default_schema_name, is_fixed_role, authentication_type_desc FROM sys.database_principals WHERE NAME = 'db_securityadmin'; GO From 1422cc389b1a1346f6e43a5cd8e6562df3a2d3ab Mon Sep 17 00:00:00 2001 From: Harsh Lunagariya Date: Tue, 29 Oct 2024 14:19:30 +0000 Subject: [PATCH 35/44] [Temp] Debugging more Signed-off-by: Harsh Lunagariya --- test/JDBC/input/ownership/db_securityadmin-vu-cleanup.mix | 2 +- test/JDBC/input/ownership/db_securityadmin-vu-prepare.mix | 4 ++-- test/JDBC/input/ownership/db_securityadmin-vu-verify.mix | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test/JDBC/input/ownership/db_securityadmin-vu-cleanup.mix b/test/JDBC/input/ownership/db_securityadmin-vu-cleanup.mix index 46f571eb21..19bd9cec7a 100644 --- a/test/JDBC/input/ownership/db_securityadmin-vu-cleanup.mix +++ b/test/JDBC/input/ownership/db_securityadmin-vu-cleanup.mix @@ -1,7 +1,7 @@ -- tsql USE master GO -DROP DATABASE IF EXISTS babel_5135_longdb_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz; +DROP DATABASE IF EXISTS babel_5135_longdb; GO DROP ROLE babel_5135_r1; GO diff --git a/test/JDBC/input/ownership/db_securityadmin-vu-prepare.mix b/test/JDBC/input/ownership/db_securityadmin-vu-prepare.mix index f43ce39eb7..403ecd1f43 100644 --- a/test/JDBC/input/ownership/db_securityadmin-vu-prepare.mix +++ b/test/JDBC/input/ownership/db_securityadmin-vu-prepare.mix @@ -49,10 +49,10 @@ INNER JOIN sys.database_principals AS members ON db_role_mems.member_principal_id = members.principal_id order by MemberPrincipalName; GO -create database babel_5135_longdb_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz +create database babel_5135_longdb GO -USE babel_5135_longdb_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz; +USE babel_5135_longdb; GO create user babel_5135_u1 for login babel_5135_l1; diff --git a/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix b/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix index 6c34d2ea82..49b2935504 100644 --- a/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix +++ b/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix @@ -45,7 +45,7 @@ SELECT * FROM babel_5135_show_role_mem WHERE RolePrincipalName = 'db_securityadm GO -- CASE 1.3 Test inside database with truncated name -USE babel_5135_longdb_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz; +USE babel_5135_longdb; GO ALTER ROLE db_securityadmin ADD MEMBER babel_5135_u1; @@ -523,7 +523,7 @@ DROP TABLE temp_sp_helprolemember; GO -- CASE XXXXXX -USE babel_5135_longdb_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz; +USE babel_5135_longdb; GO SELECT nspname, dbid, orig_name FROM babelfish_namespace_ext; From f3d8954fef206a12a17b1c9dc363df5146a0e97e Mon Sep 17 00:00:00 2001 From: Harsh Lunagariya Date: Tue, 29 Oct 2024 15:29:34 +0000 Subject: [PATCH 36/44] [Temp] Signed-off-by: Harsh Lunagariya --- test/JDBC/expected/db_securityadmin-vu-cleanup.out | 2 +- test/JDBC/expected/db_securityadmin-vu-prepare.out | 4 ++-- test/JDBC/expected/db_securityadmin-vu-verify.out | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test/JDBC/expected/db_securityadmin-vu-cleanup.out b/test/JDBC/expected/db_securityadmin-vu-cleanup.out index 46f571eb21..19bd9cec7a 100644 --- a/test/JDBC/expected/db_securityadmin-vu-cleanup.out +++ b/test/JDBC/expected/db_securityadmin-vu-cleanup.out @@ -1,7 +1,7 @@ -- tsql USE master GO -DROP DATABASE IF EXISTS babel_5135_longdb_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz; +DROP DATABASE IF EXISTS babel_5135_longdb; GO DROP ROLE babel_5135_r1; GO diff --git a/test/JDBC/expected/db_securityadmin-vu-prepare.out b/test/JDBC/expected/db_securityadmin-vu-prepare.out index dd68deed2a..6d5d607697 100644 --- a/test/JDBC/expected/db_securityadmin-vu-prepare.out +++ b/test/JDBC/expected/db_securityadmin-vu-prepare.out @@ -49,10 +49,10 @@ INNER JOIN sys.database_principals AS members ON db_role_mems.member_principal_id = members.principal_id order by MemberPrincipalName; GO -create database babel_5135_longdb_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz +create database babel_5135_longdb GO -USE babel_5135_longdb_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz; +USE babel_5135_longdb; GO create user babel_5135_u1 for login babel_5135_l1; diff --git a/test/JDBC/expected/db_securityadmin-vu-verify.out b/test/JDBC/expected/db_securityadmin-vu-verify.out index db664f94ba..045d8b2f41 100644 --- a/test/JDBC/expected/db_securityadmin-vu-verify.out +++ b/test/JDBC/expected/db_securityadmin-vu-verify.out @@ -55,7 +55,7 @@ varchar#!#varchar -- CASE 1.3 Test inside database with truncated name -USE babel_5135_longdb_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz; +USE babel_5135_longdb; GO ALTER ROLE db_securityadmin ADD MEMBER babel_5135_u1; @@ -836,7 +836,7 @@ DROP TABLE temp_sp_helprolemember; GO -- CASE XXXXXX -USE babel_5135_longdb_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz; +USE babel_5135_longdb; GO SELECT name, type, type_desc, default_schema_name, is_fixed_role, authentication_type_desc FROM sys.database_principals WHERE NAME = 'db_securityadmin'; From 120b380295948f20e7d5770c6f500926aa347b8a Mon Sep 17 00:00:00 2001 From: Harsh Lunagariya Date: Tue, 29 Oct 2024 18:26:00 +0000 Subject: [PATCH 37/44] fix Signed-off-by: Harsh Lunagariya --- .../expected/db_securityadmin-vu-cleanup.out | 2 +- .../expected/db_securityadmin-vu-prepare.out | 4 ++-- .../expected/db_securityadmin-vu-verify.out | 4 ++-- .../ownership/db_securityadmin-vu-cleanup.mix | 2 +- .../ownership/db_securityadmin-vu-prepare.mix | 4 ++-- .../ownership/db_securityadmin-vu-verify.mix | 21 ++----------------- 6 files changed, 10 insertions(+), 27 deletions(-) diff --git a/test/JDBC/expected/db_securityadmin-vu-cleanup.out b/test/JDBC/expected/db_securityadmin-vu-cleanup.out index 19bd9cec7a..26a1b58b33 100644 --- a/test/JDBC/expected/db_securityadmin-vu-cleanup.out +++ b/test/JDBC/expected/db_securityadmin-vu-cleanup.out @@ -1,7 +1,7 @@ -- tsql USE master GO -DROP DATABASE IF EXISTS babel_5135_longdb; +DROP DATABASE IF EXISTS babel_5135_db1; GO DROP ROLE babel_5135_r1; GO diff --git a/test/JDBC/expected/db_securityadmin-vu-prepare.out b/test/JDBC/expected/db_securityadmin-vu-prepare.out index 6d5d607697..f5030f8094 100644 --- a/test/JDBC/expected/db_securityadmin-vu-prepare.out +++ b/test/JDBC/expected/db_securityadmin-vu-prepare.out @@ -49,10 +49,10 @@ INNER JOIN sys.database_principals AS members ON db_role_mems.member_principal_id = members.principal_id order by MemberPrincipalName; GO -create database babel_5135_longdb +create database babel_5135_db1 GO -USE babel_5135_longdb; +USE babel_5135_db1; GO create user babel_5135_u1 for login babel_5135_l1; diff --git a/test/JDBC/expected/db_securityadmin-vu-verify.out b/test/JDBC/expected/db_securityadmin-vu-verify.out index 045d8b2f41..ca1a0dff29 100644 --- a/test/JDBC/expected/db_securityadmin-vu-verify.out +++ b/test/JDBC/expected/db_securityadmin-vu-verify.out @@ -55,7 +55,7 @@ varchar#!#varchar -- CASE 1.3 Test inside database with truncated name -USE babel_5135_longdb; +USE babel_5135_db1; GO ALTER ROLE db_securityadmin ADD MEMBER babel_5135_u1; @@ -836,7 +836,7 @@ DROP TABLE temp_sp_helprolemember; GO -- CASE XXXXXX -USE babel_5135_longdb; +USE babel_5135_db1; GO SELECT name, type, type_desc, default_schema_name, is_fixed_role, authentication_type_desc FROM sys.database_principals WHERE NAME = 'db_securityadmin'; diff --git a/test/JDBC/input/ownership/db_securityadmin-vu-cleanup.mix b/test/JDBC/input/ownership/db_securityadmin-vu-cleanup.mix index 19bd9cec7a..26a1b58b33 100644 --- a/test/JDBC/input/ownership/db_securityadmin-vu-cleanup.mix +++ b/test/JDBC/input/ownership/db_securityadmin-vu-cleanup.mix @@ -1,7 +1,7 @@ -- tsql USE master GO -DROP DATABASE IF EXISTS babel_5135_longdb; +DROP DATABASE IF EXISTS babel_5135_db1; GO DROP ROLE babel_5135_r1; GO diff --git a/test/JDBC/input/ownership/db_securityadmin-vu-prepare.mix b/test/JDBC/input/ownership/db_securityadmin-vu-prepare.mix index 403ecd1f43..c34df3a242 100644 --- a/test/JDBC/input/ownership/db_securityadmin-vu-prepare.mix +++ b/test/JDBC/input/ownership/db_securityadmin-vu-prepare.mix @@ -49,10 +49,10 @@ INNER JOIN sys.database_principals AS members ON db_role_mems.member_principal_id = members.principal_id order by MemberPrincipalName; GO -create database babel_5135_longdb +create database babel_5135_db1 GO -USE babel_5135_longdb; +USE babel_5135_db1; GO create user babel_5135_u1 for login babel_5135_l1; diff --git a/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix b/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix index 49b2935504..3c1601e58f 100644 --- a/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix +++ b/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix @@ -45,7 +45,7 @@ SELECT * FROM babel_5135_show_role_mem WHERE RolePrincipalName = 'db_securityadm GO -- CASE 1.3 Test inside database with truncated name -USE babel_5135_longdb; +USE babel_5135_db1; GO ALTER ROLE db_securityadmin ADD MEMBER babel_5135_u1; @@ -523,24 +523,7 @@ DROP TABLE temp_sp_helprolemember; GO -- CASE XXXXXX -USE babel_5135_longdb; -GO - -SELECT nspname, dbid, orig_name FROM babelfish_namespace_ext; -SELECT * FROM sys.pg_namespace_ext; -SELECT rolname, orig_username, database_name FROM babelfish_authid_user_ext; -SELECT rolname, orig_username, database_name FROM babelfish_authid_user_ext; -SELECT name, principal_id FROM sys.database_principals; -GO - -USE master; -GO - -SELECT nspname, dbid, orig_name FROM babelfish_namespace_ext; -SELECT * FROM sys.pg_namespace_ext; -SELECT rolname, orig_username, database_name FROM babelfish_authid_user_ext; -SELECT rolname, orig_username, database_name FROM babelfish_authid_user_ext; -SELECT name, principal_id FROM sys.database_principals; +USE babel_5135_db1; GO SELECT name, type, type_desc, default_schema_name, is_fixed_role, authentication_type_desc FROM sys.database_principals WHERE NAME = 'db_securityadmin'; From 6adb0617e2b4c50fdd640b9dd12270a0ac236f20 Mon Sep 17 00:00:00 2001 From: Harsh Lunagariya Date: Tue, 29 Oct 2024 19:28:59 +0000 Subject: [PATCH 38/44] Fix Signed-off-by: Harsh Lunagariya --- contrib/babelfishpg_tsql/src/rolecmds.c | 13 ++++++--- .../expected/db_securityadmin-vu-cleanup.out | 8 ++++++ .../expected/db_securityadmin-vu-prepare.out | 18 +++++++++++++ .../expected/db_securityadmin-vu-verify.out | 27 ++++++++++++++----- .../ownership/db_securityadmin-vu-cleanup.mix | 8 ++++++ .../ownership/db_securityadmin-vu-prepare.mix | 18 +++++++++++++ .../ownership/db_securityadmin-vu-verify.mix | 23 ++++++++++++++++ 7 files changed, 105 insertions(+), 10 deletions(-) diff --git a/contrib/babelfishpg_tsql/src/rolecmds.c b/contrib/babelfishpg_tsql/src/rolecmds.c index 5253171557..e7330fb04c 100644 --- a/contrib/babelfishpg_tsql/src/rolecmds.c +++ b/contrib/babelfishpg_tsql/src/rolecmds.c @@ -1846,11 +1846,16 @@ check_alter_role_stmt(GrantRoleStmt *stmt) 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 - * the granted role + * Disallow ALTER ROLE if + * 1. Current login doesn't have permission on the granted role + * OR + * 2. Granted role is not a fixed db role or current user is a member of db_securityadmin + * OR + * 3. The current user is trying to add/drop itself from the granted role */ - if (!has_privs_of_role(GetSessionUserId(), granted) || + if ((!has_privs_of_role(GetSessionUserId(), granted) && + !(get_db_principal_kind(granted, db_name) == BBF_ROLE && + has_privs_of_role(GetUserId(), get_db_securityadmin_oid(get_current_pltsql_db_name(), false)))) || grantee == GetUserId()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), diff --git a/test/JDBC/expected/db_securityadmin-vu-cleanup.out b/test/JDBC/expected/db_securityadmin-vu-cleanup.out index 26a1b58b33..7df24745f0 100644 --- a/test/JDBC/expected/db_securityadmin-vu-cleanup.out +++ b/test/JDBC/expected/db_securityadmin-vu-cleanup.out @@ -23,6 +23,14 @@ DROP FUNCTION babel_5135_schema1.babel_5135_f1(); GO DROP FUNCTION babel_5135_schema1.babel_5135_tvf1(); GO +DROP PROCEDURE babel_5135_roleop_proc1; +GO +DROP PROCEDURE babel_5135_roleop_proc2; +GO +DROP PROCEDURE babel_5135_roleop_proc3; +GO +DROP PROCEDURE babel_5135_schemaop_proc1; +GO DROP SCHEMA babel_5135_schema1; GO DROP USER babel_5135_u1; diff --git a/test/JDBC/expected/db_securityadmin-vu-prepare.out b/test/JDBC/expected/db_securityadmin-vu-prepare.out index f5030f8094..9f0f26103f 100644 --- a/test/JDBC/expected/db_securityadmin-vu-prepare.out +++ b/test/JDBC/expected/db_securityadmin-vu-prepare.out @@ -49,6 +49,24 @@ INNER JOIN sys.database_principals AS members ON db_role_mems.member_principal_id = members.principal_id order by MemberPrincipalName; GO +CREATE PROCEDURE babel_5135_roleop_proc1 AS BEGIN CREATE ROLE babel_5135_role2; ALTER ROLE babel_5135_role2 WITH NAME = babel_5135_role3; DROP ROLE babel_5135_role3; END +GO +CREATE PROCEDURE babel_5135_roleop_proc2 AS BEGIN ALTER ROLE babel_5135_r1 ADD MEMBER babel_5135_u1; END +GO +CREATE PROCEDURE babel_5135_roleop_proc3 AS BEGIN ALTER ROLE babel_5135_r1 DROP MEMBER babel_5135_u1; END +GO +CREATE PROCEDURE babel_5135_schemaop_proc1 AS BEGIN CREATE SCHEMA babel_5135_sch11; END +GO + +GRANT EXECUTE ON babel_5135_roleop_proc1 TO PUBLIC; +GO +GRANT EXECUTE ON babel_5135_roleop_proc2 TO PUBLIC; +GO +GRANT EXECUTE ON babel_5135_roleop_proc3 TO PUBLIC; +GO +GRANT EXECUTE ON babel_5135_schemaop_proc1 TO PUBLIC; +GO + create database babel_5135_db1 GO diff --git a/test/JDBC/expected/db_securityadmin-vu-verify.out b/test/JDBC/expected/db_securityadmin-vu-verify.out index ca1a0dff29..3301d006dd 100644 --- a/test/JDBC/expected/db_securityadmin-vu-verify.out +++ b/test/JDBC/expected/db_securityadmin-vu-verify.out @@ -152,20 +152,27 @@ GO DROP ROLE babel_5135_role4; GO +-- create/alter/drop role inside procedure +-- execution should be succeeded with no error +EXEC babel_5135_roleop_proc1; +GO + -- CASE 3.2 - ADD/DROP the membership of user-defined database roles ALTER ROLE babel_5135_r1 ADD MEMBER babel_5135_u1; GO -~~ERROR (Code: 33557097)~~ - -~~ERROR (Message: Current login babel_5135_dbsecadmin_l1 does not have permission to alter role master_babel_5135_r1)~~ - ALTER ROLE babel_5135_r1 DROP MEMBER babel_5135_u1; GO -~~ERROR (Code: 33557097)~~ -~~ERROR (Message: Current login babel_5135_dbsecadmin_l1 does not have permission to alter role master_babel_5135_r1)~~ +-- alter role add member inside procedure +-- execution should be succeeded with no error +-- Add +EXEC babel_5135_roleop_proc2; +GO +-- Drop +EXEC babel_5135_roleop_proc3; +GO -- CASE 3.3 - ADD/DROP the membership of system-defined database roles should be blocked ALTER ROLE db_accessadmin ADD MEMBER babel_5135_u1; @@ -218,6 +225,14 @@ GO CREATE SCHEMA babel_5135_sch2 AUTHORIZATION babel_5135_u1; GO +-- schema creation inside procedure +-- execution should be succeeded with no error +EXEC babel_5135_schemaop_proc1; +GO + +DROP SCHEMA babel_5135_sch11; +GO + -- ALTER/DROP of unowned schema should not be allowed -- NOTE: Add testcase when supported ALTER SCHEMA babel_5135_schema1 TRANSFER t33144; diff --git a/test/JDBC/input/ownership/db_securityadmin-vu-cleanup.mix b/test/JDBC/input/ownership/db_securityadmin-vu-cleanup.mix index 26a1b58b33..7df24745f0 100644 --- a/test/JDBC/input/ownership/db_securityadmin-vu-cleanup.mix +++ b/test/JDBC/input/ownership/db_securityadmin-vu-cleanup.mix @@ -23,6 +23,14 @@ DROP FUNCTION babel_5135_schema1.babel_5135_f1(); GO DROP FUNCTION babel_5135_schema1.babel_5135_tvf1(); GO +DROP PROCEDURE babel_5135_roleop_proc1; +GO +DROP PROCEDURE babel_5135_roleop_proc2; +GO +DROP PROCEDURE babel_5135_roleop_proc3; +GO +DROP PROCEDURE babel_5135_schemaop_proc1; +GO DROP SCHEMA babel_5135_schema1; GO DROP USER babel_5135_u1; diff --git a/test/JDBC/input/ownership/db_securityadmin-vu-prepare.mix b/test/JDBC/input/ownership/db_securityadmin-vu-prepare.mix index c34df3a242..c66fc34aa3 100644 --- a/test/JDBC/input/ownership/db_securityadmin-vu-prepare.mix +++ b/test/JDBC/input/ownership/db_securityadmin-vu-prepare.mix @@ -49,6 +49,24 @@ INNER JOIN sys.database_principals AS members ON db_role_mems.member_principal_id = members.principal_id order by MemberPrincipalName; GO +CREATE PROCEDURE babel_5135_roleop_proc1 AS BEGIN CREATE ROLE babel_5135_role2; ALTER ROLE babel_5135_role2 WITH NAME = babel_5135_role3; DROP ROLE babel_5135_role3; END +GO +CREATE PROCEDURE babel_5135_roleop_proc2 AS BEGIN ALTER ROLE babel_5135_r1 ADD MEMBER babel_5135_u1; END +GO +CREATE PROCEDURE babel_5135_roleop_proc3 AS BEGIN ALTER ROLE babel_5135_r1 DROP MEMBER babel_5135_u1; END +GO +CREATE PROCEDURE babel_5135_schemaop_proc1 AS BEGIN CREATE SCHEMA babel_5135_sch11; END +GO + +GRANT EXECUTE ON babel_5135_roleop_proc1 TO PUBLIC; +GO +GRANT EXECUTE ON babel_5135_roleop_proc2 TO PUBLIC; +GO +GRANT EXECUTE ON babel_5135_roleop_proc3 TO PUBLIC; +GO +GRANT EXECUTE ON babel_5135_schemaop_proc1 TO PUBLIC; +GO + create database babel_5135_db1 GO diff --git a/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix b/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix index 3c1601e58f..f2805a20b0 100644 --- a/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix +++ b/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix @@ -116,6 +116,11 @@ GO DROP ROLE babel_5135_role4; GO +-- create/alter/drop role inside procedure +-- execution should be succeeded with no error +EXEC babel_5135_roleop_proc1; +GO + -- CASE 3.2 - ADD/DROP the membership of user-defined database roles ALTER ROLE babel_5135_r1 ADD MEMBER babel_5135_u1; GO @@ -123,6 +128,16 @@ GO ALTER ROLE babel_5135_r1 DROP MEMBER babel_5135_u1; GO +-- alter role add member inside procedure +-- execution should be succeeded with no error +-- Add +EXEC babel_5135_roleop_proc2; +GO + +-- Drop +EXEC babel_5135_roleop_proc3; +GO + -- CASE 3.3 - ADD/DROP the membership of system-defined database roles should be blocked ALTER ROLE db_accessadmin ADD MEMBER babel_5135_u1; GO @@ -150,6 +165,14 @@ GO CREATE SCHEMA babel_5135_sch2 AUTHORIZATION babel_5135_u1; GO +-- schema creation inside procedure +-- execution should be succeeded with no error +EXEC babel_5135_schemaop_proc1; +GO + +DROP SCHEMA babel_5135_sch11; +GO + -- ALTER/DROP of unowned schema should not be allowed -- NOTE: Add testcase when supported ALTER SCHEMA babel_5135_schema1 TRANSFER t33144; From 7731d8912b45119ea5dc8e6b6651a5cf3d68345c Mon Sep 17 00:00:00 2001 From: Harsh Lunagariya Date: Tue, 29 Oct 2024 19:39:04 +0000 Subject: [PATCH 39/44] Fix Signed-off-by: Harsh Lunagariya --- .../expected/db_securityadmin-vu-cleanup.out | 2 + .../expected/db_securityadmin-vu-prepare.out | 20 +++ .../expected/db_securityadmin-vu-verify.out | 115 ++++++++++++++++++ .../JDBC/input/BABEL-SP_COLUMN_PRIVILEGES.mix | 2 +- .../ownership/db_securityadmin-vu-cleanup.mix | 2 + .../ownership/db_securityadmin-vu-prepare.mix | 20 +++ .../ownership/db_securityadmin-vu-verify.mix | 55 +++++++++ 7 files changed, 215 insertions(+), 1 deletion(-) diff --git a/test/JDBC/expected/db_securityadmin-vu-cleanup.out b/test/JDBC/expected/db_securityadmin-vu-cleanup.out index 7df24745f0..94345389f4 100644 --- a/test/JDBC/expected/db_securityadmin-vu-cleanup.out +++ b/test/JDBC/expected/db_securityadmin-vu-cleanup.out @@ -31,6 +31,8 @@ DROP PROCEDURE babel_5135_roleop_proc3; GO DROP PROCEDURE babel_5135_schemaop_proc1; GO +DROP PROCEDURE babel_5135_grantop_proc1, babel_5135_revokeop_proc1; +GO DROP SCHEMA babel_5135_schema1; GO DROP USER babel_5135_u1; diff --git a/test/JDBC/expected/db_securityadmin-vu-prepare.out b/test/JDBC/expected/db_securityadmin-vu-prepare.out index 9f0f26103f..d1c19b8dd4 100644 --- a/test/JDBC/expected/db_securityadmin-vu-prepare.out +++ b/test/JDBC/expected/db_securityadmin-vu-prepare.out @@ -57,6 +57,22 @@ CREATE PROCEDURE babel_5135_roleop_proc3 AS BEGIN ALTER ROLE babel_5135_r1 DROP GO CREATE PROCEDURE babel_5135_schemaop_proc1 AS BEGIN CREATE SCHEMA babel_5135_sch11; END GO +CREATE PROCEDURE babel_5135_grantop_proc1 AS BEGIN +GRANT SELECT, INSERT, UPDATE, DELETE ON babel_5135_schema1.babel_5135_t1 TO babel_5135_u1; +GRANT SELECT ON babel_5135_schema1.babel_5135_v1 TO babel_5135_u1; +GRANT EXECUTE ON babel_5135_schema1.babel_5135_p1 TO babel_5135_u1; +GRANT EXECUTE ON babel_5135_schema1.babel_5135_f1 TO babel_5135_u1; +GRANT EXECUTE ON babel_5135_schema1.babel_5135_tvf1 TO babel_5135_u1; +END +GO +CREATE PROCEDURE babel_5135_revokeop_proc1 AS BEGIN +REVOKE SELECT, INSERT, UPDATE, DELETE ON babel_5135_schema1.babel_5135_t1 FROM babel_5135_u1; +REVOKE SELECT ON babel_5135_schema1.babel_5135_v1 FROM babel_5135_u1; +REVOKE EXECUTE ON babel_5135_schema1.babel_5135_p1 FROM babel_5135_u1; +REVOKE EXECUTE ON babel_5135_schema1.babel_5135_f1 FROM babel_5135_u1; +REVOKE EXECUTE ON babel_5135_schema1.babel_5135_tvf1 FROM babel_5135_u1; +END +GO GRANT EXECUTE ON babel_5135_roleop_proc1 TO PUBLIC; GO @@ -66,6 +82,10 @@ GRANT EXECUTE ON babel_5135_roleop_proc3 TO PUBLIC; GO GRANT EXECUTE ON babel_5135_schemaop_proc1 TO PUBLIC; GO +GRANT EXECUTE ON babel_5135_grantop_proc1 TO PUBLIC; +GO +GRANT EXECUTE ON babel_5135_revokeop_proc1 TO PUBLIC; +GO create database babel_5135_db1 GO diff --git a/test/JDBC/expected/db_securityadmin-vu-verify.out b/test/JDBC/expected/db_securityadmin-vu-verify.out index 3301d006dd..2b31cc90a2 100644 --- a/test/JDBC/expected/db_securityadmin-vu-verify.out +++ b/test/JDBC/expected/db_securityadmin-vu-verify.out @@ -412,6 +412,121 @@ GO ~~ERROR (Message: permission denied for function babel_5135_tvf1)~~ +-- tsql user=babel_5135_dbsecadmin_l1 password=12345678 +-- Testing GRANT inside procedure +EXEC babel_5135_grantop_proc1; +GO + +-- tsql user=babel_5135_l1 password=12345678 +SELECT current_user; +GO +~~START~~ +varchar +babel_5135_u1 +~~END~~ + + +SELECT COUNT(*) FROM babel_5135_schema1.babel_5135_t1; +INSERT INTO babel_5135_schema1.babel_5135_t1 VALUES (1,2); +UPDATE babel_5135_schema1.babel_5135_t1 SET a = 2 WHERE a = 1; +DELETE FROM babel_5135_schema1.babel_5135_t1 WHERE a = 2; +GO +~~START~~ +int +0 +~~END~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + + +SELECT COUNT(*) FROM babel_5135_schema1.babel_5135_v1; +GO +~~START~~ +int +1 +~~END~~ + + +EXEC babel_5135_schema1.babel_5135_p1; +GO +~~START~~ +int +1 +~~END~~ + + +SELECT babel_5135_schema1.babel_5135_f1(); +GO +~~START~~ +int +1 +~~END~~ + + +SELECT * FROM babel_5135_schema1.babel_5135_tvf1(); +GO +~~START~~ +int#!#int +~~END~~ + + +-- tsql user=babel_5135_dbsecadmin_l1 password=12345678 +-- Testing revokes inside procedure +EXEC babel_5135_revokeop_proc1; +GO + +-- tsql user=babel_5135_l1 password=12345678 +SELECT current_user; +GO +~~START~~ +varchar +babel_5135_u1 +~~END~~ + + +SELECT COUNT(*) FROM babel_5135_schema1.babel_5135_t1; +INSERT INTO babel_5135_schema1.babel_5135_t1 VALUES (1,2); +UPDATE babel_5135_schema1.babel_5135_t1 SET a = 2 WHERE a = 1; +DELETE FROM babel_5135_schema1.babel_5135_t1 WHERE a = 2; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table babel_5135_t1)~~ + + +SELECT COUNT(*) FROM babel_5135_schema1.babel_5135_v1; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view babel_5135_v1)~~ + + +EXEC babel_5135_schema1.babel_5135_p1; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for procedure babel_5135_p1)~~ + + +SELECT babel_5135_schema1.babel_5135_f1(); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for function babel_5135_f1)~~ + + +SELECT * FROM babel_5135_schema1.babel_5135_tvf1(); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for function babel_5135_tvf1)~~ + + + -- tsql user=babel_5135_dbsecadmin_l1 password=12345678 GRANT SELECT, INSERT, UPDATE, DELETE, EXECUTE ON SCHEMA::babel_5135_schema1 TO babel_5135_u1; GO diff --git a/test/JDBC/input/BABEL-SP_COLUMN_PRIVILEGES.mix b/test/JDBC/input/BABEL-SP_COLUMN_PRIVILEGES.mix index 992ddd6bf9..45f69a0de0 100644 --- a/test/JDBC/input/BABEL-SP_COLUMN_PRIVILEGES.mix +++ b/test/JDBC/input/BABEL-SP_COLUMN_PRIVILEGES.mix @@ -1,4 +1,4 @@ --- sla 20000 +-- sla 60000 -- sla_for_parallel_query_enforced 20000 -- tsql CREATE DATABASE db1 diff --git a/test/JDBC/input/ownership/db_securityadmin-vu-cleanup.mix b/test/JDBC/input/ownership/db_securityadmin-vu-cleanup.mix index 7df24745f0..94345389f4 100644 --- a/test/JDBC/input/ownership/db_securityadmin-vu-cleanup.mix +++ b/test/JDBC/input/ownership/db_securityadmin-vu-cleanup.mix @@ -31,6 +31,8 @@ DROP PROCEDURE babel_5135_roleop_proc3; GO DROP PROCEDURE babel_5135_schemaop_proc1; GO +DROP PROCEDURE babel_5135_grantop_proc1, babel_5135_revokeop_proc1; +GO DROP SCHEMA babel_5135_schema1; GO DROP USER babel_5135_u1; diff --git a/test/JDBC/input/ownership/db_securityadmin-vu-prepare.mix b/test/JDBC/input/ownership/db_securityadmin-vu-prepare.mix index c66fc34aa3..cb22ffdf6a 100644 --- a/test/JDBC/input/ownership/db_securityadmin-vu-prepare.mix +++ b/test/JDBC/input/ownership/db_securityadmin-vu-prepare.mix @@ -57,6 +57,22 @@ CREATE PROCEDURE babel_5135_roleop_proc3 AS BEGIN ALTER ROLE babel_5135_r1 DROP GO CREATE PROCEDURE babel_5135_schemaop_proc1 AS BEGIN CREATE SCHEMA babel_5135_sch11; END GO +CREATE PROCEDURE babel_5135_grantop_proc1 AS BEGIN +GRANT SELECT, INSERT, UPDATE, DELETE ON babel_5135_schema1.babel_5135_t1 TO babel_5135_u1; +GRANT SELECT ON babel_5135_schema1.babel_5135_v1 TO babel_5135_u1; +GRANT EXECUTE ON babel_5135_schema1.babel_5135_p1 TO babel_5135_u1; +GRANT EXECUTE ON babel_5135_schema1.babel_5135_f1 TO babel_5135_u1; +GRANT EXECUTE ON babel_5135_schema1.babel_5135_tvf1 TO babel_5135_u1; +END +GO +CREATE PROCEDURE babel_5135_revokeop_proc1 AS BEGIN +REVOKE SELECT, INSERT, UPDATE, DELETE ON babel_5135_schema1.babel_5135_t1 FROM babel_5135_u1; +REVOKE SELECT ON babel_5135_schema1.babel_5135_v1 FROM babel_5135_u1; +REVOKE EXECUTE ON babel_5135_schema1.babel_5135_p1 FROM babel_5135_u1; +REVOKE EXECUTE ON babel_5135_schema1.babel_5135_f1 FROM babel_5135_u1; +REVOKE EXECUTE ON babel_5135_schema1.babel_5135_tvf1 FROM babel_5135_u1; +END +GO GRANT EXECUTE ON babel_5135_roleop_proc1 TO PUBLIC; GO @@ -66,6 +82,10 @@ GRANT EXECUTE ON babel_5135_roleop_proc3 TO PUBLIC; GO GRANT EXECUTE ON babel_5135_schemaop_proc1 TO PUBLIC; GO +GRANT EXECUTE ON babel_5135_grantop_proc1 TO PUBLIC; +GO +GRANT EXECUTE ON babel_5135_revokeop_proc1 TO PUBLIC; +GO create database babel_5135_db1 GO diff --git a/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix b/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix index f2805a20b0..ed902e18ce 100644 --- a/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix +++ b/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix @@ -269,6 +269,61 @@ GO SELECT * FROM babel_5135_schema1.babel_5135_tvf1(); GO +-- Testing GRANT inside procedure +-- tsql user=babel_5135_dbsecadmin_l1 password=12345678 +EXEC babel_5135_grantop_proc1; +GO + +-- tsql user=babel_5135_l1 password=12345678 +SELECT current_user; +GO + +SELECT COUNT(*) FROM babel_5135_schema1.babel_5135_t1; +INSERT INTO babel_5135_schema1.babel_5135_t1 VALUES (1,2); +UPDATE babel_5135_schema1.babel_5135_t1 SET a = 2 WHERE a = 1; +DELETE FROM babel_5135_schema1.babel_5135_t1 WHERE a = 2; +GO + +SELECT COUNT(*) FROM babel_5135_schema1.babel_5135_v1; +GO + +EXEC babel_5135_schema1.babel_5135_p1; +GO + +SELECT babel_5135_schema1.babel_5135_f1(); +GO + +SELECT * FROM babel_5135_schema1.babel_5135_tvf1(); +GO + +-- Testing revokes inside procedure +-- tsql user=babel_5135_dbsecadmin_l1 password=12345678 +EXEC babel_5135_revokeop_proc1; +GO + +-- tsql user=babel_5135_l1 password=12345678 +SELECT current_user; +GO + +SELECT COUNT(*) FROM babel_5135_schema1.babel_5135_t1; +INSERT INTO babel_5135_schema1.babel_5135_t1 VALUES (1,2); +UPDATE babel_5135_schema1.babel_5135_t1 SET a = 2 WHERE a = 1; +DELETE FROM babel_5135_schema1.babel_5135_t1 WHERE a = 2; +GO + +SELECT COUNT(*) FROM babel_5135_schema1.babel_5135_v1; +GO + +EXEC babel_5135_schema1.babel_5135_p1; +GO + +SELECT babel_5135_schema1.babel_5135_f1(); +GO + +SELECT * FROM babel_5135_schema1.babel_5135_tvf1(); +GO + + -- tsql user=babel_5135_dbsecadmin_l1 password=12345678 GRANT SELECT, INSERT, UPDATE, DELETE, EXECUTE ON SCHEMA::babel_5135_schema1 TO babel_5135_u1; GO From d20c1e39e4ef1f1510276577058a9789bce67e7f Mon Sep 17 00:00:00 2001 From: Harsh Lunagariya Date: Tue, 29 Oct 2024 20:11:52 +0000 Subject: [PATCH 40/44] Add restrictions test Signed-off-by: Harsh Lunagariya --- .../expected/db_securityadmin-vu-verify.out | 262 +++++++++++++++++- .../ownership/db_securityadmin-vu-verify.mix | 119 +++++++- 2 files changed, 379 insertions(+), 2 deletions(-) diff --git a/test/JDBC/expected/db_securityadmin-vu-verify.out b/test/JDBC/expected/db_securityadmin-vu-verify.out index 2b31cc90a2..cfafacb6f5 100644 --- a/test/JDBC/expected/db_securityadmin-vu-verify.out +++ b/test/JDBC/expected/db_securityadmin-vu-verify.out @@ -965,7 +965,7 @@ db_securityadmin#!#babel_5135_dbsecadmin_u1 DROP TABLE temp_sp_helprolemember; GO --- CASE XXXXXX +-- CASE 8 USE babel_5135_db1; GO @@ -979,3 +979,263 @@ db_securityadmin#!#R#!#DATABASE_ROLE#!##!#1#!# USE master; GO + +-- tsql +-- CASE 9 - Restrictions +-- normal tsql login +CREATE LOGIN db_securityadmin_restrictions_login WITH password = '12345678'; +GO + +ALTER SERVER ROLE sysadmin ADD MEMBER db_securityadmin_restrictions_login; +GO + +-- psql +-- normal PG user +CREATE USER db_securityadmin_restrictions_pg_user WITH LOGIN CREATEROLE CREATEDB PASSWORD '12345678' inherit; +go + +-- tsql user=db_securityadmin_restrictions_login password=12345678 +-- a tsql login should not be able to rename/drop db_securityadmin and grant/revoke on it explicitly from tsql port +ALTER ROLE db_securityadmin WITH NAME = db_securityadmin1; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot alter the user db_securityadmin)~~ + + +DROP ROLE db_securityadmin; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot drop the role 'db_securityadmin'.)~~ + + +GRANT SELECT ON babel_5135_schema1.babel_5135_t1 TO db_securityadmin; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny or revoke permissions to or from special roles.)~~ + + +GRANT SELECT, INSERT, UPDATE, DELETE, EXECUTE ON SCHEMA::babel_5135_schema1 TO db_securityadmin; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny or revoke permissions to or from special roles.)~~ + + +REVOKE SELECT ON babel_5135_schema1.babel_5135_t1 FROM db_securityadmin; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny or revoke permissions to or from special roles.)~~ + + +REVOKE SELECT, INSERT, UPDATE, DELETE, EXECUTE ON SCHEMA::babel_5135_schema1 FROM db_securityadmin; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny or revoke permissions to or from special roles.)~~ + + +-- psql user=db_securityadmin_restrictions_login password=12345678 +-- a tsql login should not be able to alter/grant/drop db_securityadmin from pg port +ALTER ROLE master_db_securityadmin NOCREATEROLE; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Babelfish-created logins/users/roles cannot be altered outside of a Babelfish session + Server SQLState: 42501)~~ + + +ALTER ROLE master_db_securityadmin WITH PASSWORD '12345678'; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Babelfish-created logins/users/roles cannot be altered outside of a Babelfish session + Server SQLState: 42501)~~ + + +ALTER ROLE master_db_securityadmin VALID UNTIL 'infinity'; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Babelfish-created logins/users/roles cannot be altered outside of a Babelfish session + Server SQLState: 42501)~~ + + +ALTER ROLE master_db_securityadmin WITH CONNECTION LIMIT 1; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Babelfish-created logins/users/roles cannot be altered outside of a Babelfish session + Server SQLState: 42501)~~ + + +GRANT master_db_securityadmin TO db_securityadmin_restrictions_login; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: permission denied to grant role "master_db_securityadmin" + Detail: Only roles with the ADMIN option on role "master_db_securityadmin" may grant this role. + Server SQLState: 42501)~~ + + +GRANT db_securityadmin_restrictions_login TO master_db_securityadmin; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: permission denied to grant role "db_securityadmin_restrictions_login" + Detail: Only roles with the ADMIN option on role "db_securityadmin_restrictions_login" may grant this role. + Server SQLState: 42501)~~ + + +REVOKE master_db_securityadmin FROM master_dbo; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: permission denied to revoke role "master_db_securityadmin" + Detail: Only roles with the ADMIN option on role "master_db_securityadmin" may revoke this role. + Server SQLState: 42501)~~ + + +REVOKE master_dbo FROM master_db_securityadmin; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: permission denied to revoke role "master_dbo" + Detail: Only roles with the ADMIN option on role "master_dbo" may revoke this role. + Server SQLState: 42501)~~ + + +DROP ROLE master_db_securityadmin; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Babelfish-created logins/users/roles cannot be dropped or altered outside of a Babelfish session + Server SQLState: 42501)~~ + + +SET SESSION AUTHORIZATION master_db_securityadmin; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: permission denied to set session authorization + Server SQLState: 42501)~~ + + +SET ROLE master_db_securityadmin; +GO + +-- psql user=db_securityadmin_restrictions_pg_user password=12345678 +-- a normal psql user should not be able to alter/grant/drop db_securityadmin from pg port +ALTER ROLE master_db_securityadmin NOCREATEROLE; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Babelfish-created logins/users/roles cannot be altered outside of a Babelfish session + Server SQLState: 42501)~~ + + +ALTER ROLE master_db_securityadmin WITH PASSWORD '12345678'; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Babelfish-created logins/users/roles cannot be altered outside of a Babelfish session + Server SQLState: 42501)~~ + + +ALTER ROLE master_db_securityadmin VALID UNTIL 'infinity'; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Babelfish-created logins/users/roles cannot be altered outside of a Babelfish session + Server SQLState: 42501)~~ + + +ALTER ROLE master_db_securityadmin WITH CONNECTION LIMIT 1; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Babelfish-created logins/users/roles cannot be altered outside of a Babelfish session + Server SQLState: 42501)~~ + + +GRANT master_db_securityadmin TO db_securityadmin_restrictions_login; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: permission denied to grant role "master_db_securityadmin" + Detail: Only roles with the ADMIN option on role "master_db_securityadmin" may grant this role. + Server SQLState: 42501)~~ + + +GRANT db_securityadmin_restrictions_login TO master_db_securityadmin; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: permission denied to grant role "db_securityadmin_restrictions_login" + Detail: Only roles with the ADMIN option on role "db_securityadmin_restrictions_login" may grant this role. + Server SQLState: 42501)~~ + + +REVOKE master_db_securityadmin FROM master_dbo; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: permission denied to revoke role "master_db_securityadmin" + Detail: Only roles with the ADMIN option on role "master_db_securityadmin" may revoke this role. + Server SQLState: 42501)~~ + + +REVOKE master_dbo FROM master_db_securityadmin; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: permission denied to revoke role "master_dbo" + Detail: Only roles with the ADMIN option on role "master_dbo" may revoke this role. + Server SQLState: 42501)~~ + + +DROP ROLE master_db_securityadmin; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: Babelfish-created logins/users/roles cannot be dropped or altered outside of a Babelfish session + Server SQLState: 42501)~~ + + +SET SESSION AUTHORIZATION master_db_securityadmin; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: permission denied to set session authorization + Server SQLState: 42501)~~ + + +SET ROLE master_db_securityadmin; +GO +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: permission denied to set role "master_db_securityadmin" + Server SQLState: 42501)~~ + + +-- psql +DROP USER db_securityadmin_restrictions_pg_user; +GO + +-- Need to terminate active session before cleaning up the login +SELECT pg_terminate_backend(pid) FROM pg_stat_get_activity(NULL) +WHERE sys.suser_name(usesysid) = 'db_securityadmin_restrictions_login' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +GO +~~START~~ +bool +t +t +~~END~~ + + +-- tsql +DROP LOGIN db_securityadmin_restrictions_login; +GO diff --git a/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix b/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix index ed902e18ce..9c94471d98 100644 --- a/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix +++ b/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix @@ -600,7 +600,7 @@ GO DROP TABLE temp_sp_helprolemember; GO --- CASE XXXXXX +-- CASE 8 USE babel_5135_db1; GO @@ -609,3 +609,120 @@ GO USE master; GO + +-- CASE 9 - Restrictions +-- tsql +-- normal tsql login +CREATE LOGIN db_securityadmin_restrictions_login WITH password = '12345678'; +GO + +ALTER SERVER ROLE sysadmin ADD MEMBER db_securityadmin_restrictions_login; +GO + +-- psql +-- normal PG user +CREATE USER db_securityadmin_restrictions_pg_user WITH LOGIN CREATEROLE CREATEDB PASSWORD '12345678' inherit; +go + +-- tsql user=db_securityadmin_restrictions_login password=12345678 +-- a tsql login should not be able to rename/drop db_securityadmin and grant/revoke on it explicitly from tsql port +ALTER ROLE db_securityadmin WITH NAME = db_securityadmin1; +GO + +DROP ROLE db_securityadmin; +GO + +GRANT SELECT ON babel_5135_schema1.babel_5135_t1 TO db_securityadmin; +GO + +GRANT SELECT, INSERT, UPDATE, DELETE, EXECUTE ON SCHEMA::babel_5135_schema1 TO db_securityadmin; +GO + +REVOKE SELECT ON babel_5135_schema1.babel_5135_t1 FROM db_securityadmin; +GO + +REVOKE SELECT, INSERT, UPDATE, DELETE, EXECUTE ON SCHEMA::babel_5135_schema1 FROM db_securityadmin; +GO + +-- psql user=db_securityadmin_restrictions_login password=12345678 +-- a tsql login should not be able to alter/grant/drop db_securityadmin from pg port +ALTER ROLE master_db_securityadmin NOCREATEROLE; +GO + +ALTER ROLE master_db_securityadmin WITH PASSWORD '12345678'; +GO + +ALTER ROLE master_db_securityadmin VALID UNTIL 'infinity'; +GO + +ALTER ROLE master_db_securityadmin WITH CONNECTION LIMIT 1; +GO + +GRANT master_db_securityadmin TO db_securityadmin_restrictions_login; +GO + +GRANT db_securityadmin_restrictions_login TO master_db_securityadmin; +GO + +REVOKE master_db_securityadmin FROM master_dbo; +GO + +REVOKE master_dbo FROM master_db_securityadmin; +GO + +DROP ROLE master_db_securityadmin; +GO + +SET SESSION AUTHORIZATION master_db_securityadmin; +GO + +SET ROLE master_db_securityadmin; +GO + +-- psql user=db_securityadmin_restrictions_pg_user password=12345678 +-- a normal psql user should not be able to alter/grant/drop db_securityadmin from pg port +ALTER ROLE master_db_securityadmin NOCREATEROLE; +GO + +ALTER ROLE master_db_securityadmin WITH PASSWORD '12345678'; +GO + +ALTER ROLE master_db_securityadmin VALID UNTIL 'infinity'; +GO + +ALTER ROLE master_db_securityadmin WITH CONNECTION LIMIT 1; +GO + +GRANT master_db_securityadmin TO db_securityadmin_restrictions_login; +GO + +GRANT db_securityadmin_restrictions_login TO master_db_securityadmin; +GO + +REVOKE master_db_securityadmin FROM master_dbo; +GO + +REVOKE master_dbo FROM master_db_securityadmin; +GO + +DROP ROLE master_db_securityadmin; +GO + +SET SESSION AUTHORIZATION master_db_securityadmin; +GO + +SET ROLE master_db_securityadmin; +GO + +-- psql +DROP USER db_securityadmin_restrictions_pg_user; +GO + +-- Need to terminate active session before cleaning up the login +SELECT pg_terminate_backend(pid) FROM pg_stat_get_activity(NULL) +WHERE sys.suser_name(usesysid) = 'db_securityadmin_restrictions_login' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +GO + +-- tsql +DROP LOGIN db_securityadmin_restrictions_login; +GO From 677826409ff63216f5f165c414c4b8bc075ddf5b Mon Sep 17 00:00:00 2001 From: Harsh Lunagariya Date: Tue, 29 Oct 2024 20:28:38 +0000 Subject: [PATCH 41/44] fix Signed-off-by: Harsh Lunagariya --- .../expected/db_securityadmin-vu-verify.out | 46 +++++++++++++++++++ .../ownership/db_securityadmin-vu-verify.mix | 22 +++++++++ 2 files changed, 68 insertions(+) diff --git a/test/JDBC/expected/db_securityadmin-vu-verify.out b/test/JDBC/expected/db_securityadmin-vu-verify.out index cfafacb6f5..043b61a2ce 100644 --- a/test/JDBC/expected/db_securityadmin-vu-verify.out +++ b/test/JDBC/expected/db_securityadmin-vu-verify.out @@ -267,6 +267,7 @@ GO -- CASE 5.1 - Validate GRANT/REVOKE of object/schema privileges -- CASE 5.2 - Validate members of db_securityadmin can not actually access given objects -- CASE 5.3 - Validate that after GRANT/REVOKE, objectowner/dbo can execute REVOKE/GRANT respectively + -- CASE 5.4 - Grant/Revoke should not be allowed for show shared schema or any other database's schema GRANT SELECT, INSERT, UPDATE, DELETE ON babel_5135_schema1.babel_5135_t1 TO babel_5135_u1; GO ~~ERROR (Code: 33557097)~~ @@ -753,6 +754,51 @@ GO REVOKE EXECUTE ON babel_5135_schema1.babel_5135_tvf1 FROM babel_5135_u1; GO +-- tsql user=babel_5135_dbsecadmin_l1 password=12345678 +-- CASE 5.4 - Grant/Revoke should not be allowed for show shared schema or any other database's schema +-- Following error is misleading, will be fixed separately +GRANT SELECT ON sys.database_principals TO babel_5135_u1; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Could find logical schema name for: "sys")~~ + + +REVOKE SELECT ON sys.database_principals FROM babel_5135_u1; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Could find logical schema name for: "sys")~~ + + +GRANT SELECT ON pg_catalog.pg_namespace TO babel_5135_u1; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Could find logical schema name for: "pg_catalog")~~ + + +REVOKE SELECT ON pg_catalog.pg_namespace FROM babel_5135_u1; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Could find logical schema name for: "pg_catalog")~~ + + +REVOKE SELECT ON babel_5135_db1.dbo.babel_5135_show_role_mem TO babel_5135_u1; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table babel_5135_show_role_mem)~~ + + +REVOKE SELECT ON babel_5135_db1.dbo.babel_5135_show_role_mem FROM babel_5135_u1; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table babel_5135_show_role_mem)~~ + + -- tsql -- CASE 6 - is_member() / is_rolemember() testcases SELECT is_member('db_securityadmin'), is_rolemember('db_securityadmin'); diff --git a/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix b/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix index 9c94471d98..1b500af19d 100644 --- a/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix +++ b/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix @@ -194,6 +194,7 @@ GO -- CASE 5.1 - Validate GRANT/REVOKE of object/schema privileges -- CASE 5.2 - Validate members of db_securityadmin can not actually access given objects -- CASE 5.3 - Validate that after GRANT/REVOKE, objectowner/dbo can execute REVOKE/GRANT respectively + -- CASE 5.4 - Grant/Revoke should not be allowed for show shared schema or any other database's schema GRANT SELECT, INSERT, UPDATE, DELETE ON babel_5135_schema1.babel_5135_t1 TO babel_5135_u1; GO @@ -465,6 +466,27 @@ GO REVOKE EXECUTE ON babel_5135_schema1.babel_5135_tvf1 FROM babel_5135_u1; GO +-- CASE 5.4 - Grant/Revoke should not be allowed for show shared schema or any other database's schema +-- tsql user=babel_5135_dbsecadmin_l1 password=12345678 +-- Following error is misleading, will be fixed separately +GRANT SELECT ON sys.database_principals TO babel_5135_u1; +GO + +REVOKE SELECT ON sys.database_principals FROM babel_5135_u1; +GO + +GRANT SELECT ON pg_catalog.pg_namespace TO babel_5135_u1; +GO + +REVOKE SELECT ON pg_catalog.pg_namespace FROM babel_5135_u1; +GO + +REVOKE SELECT ON babel_5135_db1.dbo.babel_5135_show_role_mem TO babel_5135_u1; +GO + +REVOKE SELECT ON babel_5135_db1.dbo.babel_5135_show_role_mem FROM babel_5135_u1; +GO + -- CASE 6 - is_member() / is_rolemember() testcases -- tsql SELECT is_member('db_securityadmin'), is_rolemember('db_securityadmin'); From 1da239578f88889b0776abea3bdb440b16297a26 Mon Sep 17 00:00:00 2001 From: Harsh Lunagariya Date: Tue, 29 Oct 2024 20:47:01 +0000 Subject: [PATCH 42/44] Fix Signed-off-by: Harsh Lunagariya --- contrib/babelfishpg_tsql/src/dbcmds.c | 10 ++++++---- contrib/babelfishpg_tsql/src/hooks.c | 2 +- contrib/babelfishpg_tsql/src/pl_handler.c | 12 +++++++++--- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/contrib/babelfishpg_tsql/src/dbcmds.c b/contrib/babelfishpg_tsql/src/dbcmds.c index fbb52999a6..e435e55d74 100644 --- a/contrib/babelfishpg_tsql/src/dbcmds.c +++ b/contrib/babelfishpg_tsql/src/dbcmds.c @@ -326,10 +326,11 @@ 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 && strcmp(user_name, db_securityadmin) != 0 && - strcmp(user_name, db_datareader) != 0 && + strcmp(user_name, db_datareader) != 0 && strcmp(user_name, db_datawriter) != 0) { appendStringInfo(&query, "DROP OWNED BY dummy CASCADE; "); @@ -371,10 +372,11 @@ 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 && strcmp(user_name, db_securityadmin) != 0 && - strcmp(user_name, db_datareader) != 0 && + strcmp(user_name, db_datareader) != 0 && strcmp(user_name, db_datawriter) != 0) { stmt = parsetree_nth_stmt(stmt_list, i++); diff --git a/contrib/babelfishpg_tsql/src/hooks.c b/contrib/babelfishpg_tsql/src/hooks.c index 03a8097b56..eb76fc240d 100644 --- a/contrib/babelfishpg_tsql/src/hooks.c +++ b/contrib/babelfishpg_tsql/src/hooks.c @@ -5616,7 +5616,7 @@ handle_grantstmt_for_dbsecadmin(ObjectType objType, Oid objId, Oid ownerId, * grantId with ownerId. */ if (is_member_of_role(GetUserId(), - get_role_oid(get_db_securityadmin_role_name(get_current_pltsql_db_name()), false))) + get_db_securityadmin_oid(get_current_pltsql_db_name(), false))) { *grantorId = ownerId; *grantOptions = ACL_GRANT_OPTION_FOR(privileges); diff --git a/contrib/babelfishpg_tsql/src/pl_handler.c b/contrib/babelfishpg_tsql/src/pl_handler.c index 8a68e38dc1..60fe23fabc 100644 --- a/contrib/babelfishpg_tsql/src/pl_handler.c +++ b/contrib/babelfishpg_tsql/src/pl_handler.c @@ -3315,7 +3315,7 @@ bbf_ProcessUtility(PlannedStmt *pstmt, Oid save_userid; Oid db_owner = get_db_owner_oid(db_name, false); Oid db_accessadmin = get_db_accessadmin_oid(db_name, false); - Oid db_securityadmin = get_role_oid(get_db_securityadmin_role_name(db_name), false); + Oid db_securityadmin = get_db_securityadmin_oid(db_name, false); Oid user_oid = get_role_oid(stmt->role->rolename, false); if ((isuser && get_db_principal_kind(user_oid, db_name) != BBF_USER) || (isrole && get_db_principal_kind(user_oid, db_name) != BBF_ROLE)) @@ -3478,7 +3478,7 @@ bbf_ProcessUtility(PlannedStmt *pstmt, { Oid db_owner = get_db_owner_oid(db_name, false); Oid db_accessadmin = get_db_accessadmin_oid(db_name, false); - Oid db_securityadmin = get_role_oid(get_db_securityadmin_role_name(db_name), false); + Oid db_securityadmin = get_db_securityadmin_oid(db_name, false); foreach(item, stmt->roles) { @@ -3729,7 +3729,7 @@ bbf_ProcessUtility(PlannedStmt *pstmt, { const char *db_name = get_current_pltsql_db_name(); Oid db_accessadmin = get_db_accessadmin_oid(db_name, false); - Oid db_securityadmin = get_role_oid(get_db_securityadmin_role_name(get_cur_db_name()), false); + Oid db_securityadmin = get_db_securityadmin_oid(db_name, false); owner_oid = get_rolespec_oid(rolspec, true); /* @@ -4225,6 +4225,12 @@ bbf_ProcessUtility(PlannedStmt *pstmt, char *db_datawriter = get_db_datawriter_name(dbname); char *db_accessadmin = get_db_accessadmin_role_name(dbname); + /* + * NOTE: GRANT/REVOKE on OBJECT(schema-contained)/SCHEMA are allowed + * if current_user is member of db_securityadmin via engine hooks. + * Please refer handle_grantstmt_for_dbsecadmin() function for more details. + */ + /* Ignore when GRANT statement has no specific named object. */ if (sql_dialect != SQL_DIALECT_TSQL || grant->targtype != ACL_TARGET_OBJECT) break; From 79df47901732b4e7b2c5f344e9b8e217d3a35f2d Mon Sep 17 00:00:00 2001 From: Harsh Lunagariya Date: Tue, 29 Oct 2024 21:07:53 +0000 Subject: [PATCH 43/44] fix Signed-off-by: Harsh Lunagariya --- .../expected/db_securityadmin-vu-verify.out | 42 +++++++++++++++++++ .../ownership/db_securityadmin-vu-verify.mix | 26 ++++++++++++ 2 files changed, 68 insertions(+) diff --git a/test/JDBC/expected/db_securityadmin-vu-verify.out b/test/JDBC/expected/db_securityadmin-vu-verify.out index 043b61a2ce..6a3b756d49 100644 --- a/test/JDBC/expected/db_securityadmin-vu-verify.out +++ b/test/JDBC/expected/db_securityadmin-vu-verify.out @@ -225,6 +225,48 @@ GO CREATE SCHEMA babel_5135_sch2 AUTHORIZATION babel_5135_u1; GO +SELECT name, sys.user_name(principal_id) FROM sys.schemas WHERE name IN ('babel_5135_sch1','babel_5135_sch2') ORDER BY name; +GO +~~START~~ +varchar#!#nvarchar +babel_5135_sch1#!#babel_5135_dbsecadmin_u1 +babel_5135_sch2#!#babel_5135_u1 +~~END~~ + + +-- tsql +-- granting db_securityadmin to guest and create schema +alter role db_securityadmin add member guest; +GO + +-- tsql user=babel_5135_l2 password=12345678 +select current_user; +GO +~~START~~ +varchar +guest +~~END~~ + + +CREATE SCHEMA babel_5135_sch3; +GO + +SELECT name, sys.user_name(principal_id) FROM sys.schemas WHERE name LIKE 'babel_5135_sch3' ORDER BY name; +GO +~~START~~ +varchar#!#nvarchar +babel_5135_sch3#!#guest +~~END~~ + + +DROP SCHEMA babel_5135_sch3; +GO + +-- tsql +alter role db_securityadmin DROP member guest; +GO + +-- tsql user=babel_5135_dbsecadmin_l1 password=12345678 -- schema creation inside procedure -- execution should be succeeded with no error EXEC babel_5135_schemaop_proc1; diff --git a/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix b/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix index 1b500af19d..ec9c51066f 100644 --- a/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix +++ b/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix @@ -165,6 +165,32 @@ GO CREATE SCHEMA babel_5135_sch2 AUTHORIZATION babel_5135_u1; GO +SELECT name, sys.user_name(principal_id) FROM sys.schemas WHERE name IN ('babel_5135_sch1','babel_5135_sch2') ORDER BY name; +GO + +-- granting db_securityadmin to guest and create schema +-- tsql +alter role db_securityadmin add member guest; +GO + +-- tsql user=babel_5135_l2 password=12345678 +select current_user; +GO + +CREATE SCHEMA babel_5135_sch3; +GO + +SELECT name, sys.user_name(principal_id) FROM sys.schemas WHERE name LIKE 'babel_5135_sch3' ORDER BY name; +GO + +DROP SCHEMA babel_5135_sch3; +GO + +-- tsql +alter role db_securityadmin DROP member guest; +GO + +-- tsql user=babel_5135_dbsecadmin_l1 password=12345678 -- schema creation inside procedure -- execution should be succeeded with no error EXEC babel_5135_schemaop_proc1; From 0af5925b0d32e05d04351c180fc465e027d0b450 Mon Sep 17 00:00:00 2001 From: Harsh Lunagariya Date: Wed, 30 Oct 2024 16:44:06 +0000 Subject: [PATCH 44/44] Disable some tests Signed-off-by: Harsh Lunagariya --- .../expected/db_securityadmin-vu-verify.out | 20 ++++--------------- .../ownership/db_securityadmin-vu-verify.mix | 8 ++++---- 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/test/JDBC/expected/db_securityadmin-vu-verify.out b/test/JDBC/expected/db_securityadmin-vu-verify.out index 6a3b756d49..33a1c7defb 100644 --- a/test/JDBC/expected/db_securityadmin-vu-verify.out +++ b/test/JDBC/expected/db_securityadmin-vu-verify.out @@ -1160,15 +1160,9 @@ GO Server SQLState: 42501)~~ -GRANT master_db_securityadmin TO db_securityadmin_restrictions_login; -GO -~~ERROR (Code: 0)~~ - -~~ERROR (Message: ERROR: permission denied to grant role "master_db_securityadmin" - Detail: Only roles with the ADMIN option on role "master_db_securityadmin" may grant this role. - Server SQLState: 42501)~~ - +-- GRANT master_db_securityadmin TO db_securityadmin_restrictions_login; +-- GO GRANT db_securityadmin_restrictions_login TO master_db_securityadmin; GO ~~ERROR (Code: 0)~~ @@ -1178,15 +1172,9 @@ GO Server SQLState: 42501)~~ -REVOKE master_db_securityadmin FROM master_dbo; -GO -~~ERROR (Code: 0)~~ - -~~ERROR (Message: ERROR: permission denied to revoke role "master_db_securityadmin" - Detail: Only roles with the ADMIN option on role "master_db_securityadmin" may revoke this role. - Server SQLState: 42501)~~ - +-- REVOKE master_db_securityadmin FROM master_dbo; +-- GO REVOKE master_dbo FROM master_db_securityadmin; GO ~~ERROR (Code: 0)~~ diff --git a/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix b/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix index ec9c51066f..2f2f15acfc 100644 --- a/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix +++ b/test/JDBC/input/ownership/db_securityadmin-vu-verify.mix @@ -706,14 +706,14 @@ GO ALTER ROLE master_db_securityadmin WITH CONNECTION LIMIT 1; GO -GRANT master_db_securityadmin TO db_securityadmin_restrictions_login; -GO +-- GRANT master_db_securityadmin TO db_securityadmin_restrictions_login; +-- GO GRANT db_securityadmin_restrictions_login TO master_db_securityadmin; GO -REVOKE master_db_securityadmin FROM master_dbo; -GO +-- REVOKE master_db_securityadmin FROM master_dbo; +-- GO REVOKE master_dbo FROM master_db_securityadmin; GO