6
0
mirror of https://github.com/FirebirdSQL/firebird-qa.git synced 2025-01-22 13:33:07 +01:00

Added/Updated tests\bugs\core_5887_trusted_role_test.py: One need to check for admin rights of current OS user (noted by Dimitry Sibiryakov).

This commit is contained in:
pavel-zotov 2024-08-02 12:04:17 +03:00
parent 9c70256e56
commit 3f3b172866

View File

@ -1,151 +1,180 @@
#coding:utf-8
"""
ID: issue-6145-B
ISSUE: 6145
TITLE: Allow the use of management statements in PSQL blocks
DESCRIPTION:
Role can be set as TRUSTED when following conditions are true:
* BOTH AuthServer and AuthClient parameters from firebird.conf contain 'Win_Sspi' as plugin, in any place;
* current OS user has admin rights;
* OS environment has *no* variables ISC_USER and ISC_PASSWORD (i.e. they must be UNSET);
* Two mappings are created (both uses plugin win_sspi):
** from any user to user;
** from predefined_group domain_any_rid_admins to role <role_to_be_trusted>
Connect to database should be done in form: CONNECT '<computername>:<our_database>' role <role_to_be_trusted>',
and after this we can user 'SET TRUSTED ROLE' statement.
This test checks that statement 'SET TRUSTED ROLE' can be used within PSQL block rather than as DSQL.
JIRA: CORE-5887
FBTEST: bugs.core_5887_trusted_role
NOTES:
[15.08.2022] pzotov
Checked on 5.0.0.623, 4.0.1.2692.
[04.03.2023] pzotov
Computer name must be converted to UPPERCASE, otherwise test fails.
"""
import os
import socket
import getpass
import pytest
from firebird.qa import *
for v in ('ISC_USER','ISC_PASSWORD'):
try:
del os.environ[ v ]
except KeyError as e:
pass
THIS_COMPUTER_NAME = socket.gethostname().upper()
CURRENT_WIN_ADMIN = getpass.getuser()
db = db_factory()
act = python_act('db', substitutions=[('\t+', ' '), ('TCPv(4|6)', 'TCP')])
tmp_role_senior = role_factory('db', name='tmp_role_5887_senior')
tmp_role_junior = role_factory('db', name='tmp_role_5887_junior')
@pytest.mark.version('>=4.0')
@pytest.mark.platform('Windows')
def test_1(act: Action, tmp_role_junior: Role, tmp_role_senior: Role, capsys):
sql_init = f"""
create table test(id int);
grant select on test to role {tmp_role_senior.name};
commit;
-- We have to use here "create mapping trusted_auth ... from any user to user" otherwise get
-- Statement failed, SQLSTATE = 28000 /Missing security context for <test_database>
-- on connect statement which specifies COMPUTERNAME:USERNAME instead path to DB:
create or alter mapping trusted_auth using plugin win_sspi from any user to user;
-- We have to use here "create mapping win_admins ... DOMAIN_ANY_RID_ADMINS" otherwise get
-- Statement failed, SQLSTATE = 0P000 / Your attachment has no trusted role
create or alter mapping win_admins1 using plugin win_sspi from predefined_group domain_any_rid_admins to role {tmp_role_junior.name};
commit;
create view v_info as
select a.mon$user, a.mon$role, a.mon$remote_protocol, a.mon$auth_method from mon$attachments a where mon$attachment_id = current_connection
;
grant select on v_info to public;
commit;
"""
act.isql(switches=['-q'], input = sql_init)
assert act.clean_stdout == ''
act.reset()
sql_check = f"""
-- This will make connection with tole = {tmp_role_junior.name}
connect '{THIS_COMPUTER_NAME}:{act.db.db_path}';
set list on;
select 'point-1' as msg, v.* from v_info v;
-- MUST FAIL because neither user nor its role has no access rights to the 'TEST' table:
select count(*) as test_rows from test;
commit;
-- Make temporary connection as SYSDBA and change mapping from predefined_group domain_any_rid_admins
-- so that any connection can get {tmp_role_senior.name} role as trusted role:
connect '{act.db.dsn}' user {act.db.user} password '{act.db.password}';
drop mapping win_admins1;
grant {tmp_role_junior.name} to public;
-- Following statement means that any attachment will be granted with role <tmp_role_senior>
-- which, in turn was granted for SELECT from table 'test':
create or alter mapping win_admins2 using plugin win_sspi from predefined_group domain_any_rid_admins to role {tmp_role_senior.name};
commit;
connect '{THIS_COMPUTER_NAME}:{act.db.db_path}' role {tmp_role_junior.name.upper()};
select 'point-2' as msg, v.* from v_info v;
set term ^;
execute block as
begin
-- Following statement:
-- 1) must pass without any error;
-- 2) leads to change effective role from {tmp_role_junior.name} to {tmp_role_senior.name}:
set trusted role;
end
^
set term ;^
commit;
select 'point-3' as msg, v.* from v_info v;
-- this MUST PASS because of trusted role {tmp_role_senior.name} whic has needed access rights:
select count(*) as test_rows from test;
commit;
"""
expected_out = f"""
MSG point-1
MON$USER {THIS_COMPUTER_NAME}\\{CURRENT_WIN_ADMIN.upper()}
MON$ROLE {tmp_role_junior.name.upper()}
MON$REMOTE_PROTOCOL TCP
MON$AUTH_METHOD Mapped from Win_Sspi
Statement failed, SQLSTATE = 28000
no permission for SELECT access to TABLE TEST
-Effective user is {THIS_COMPUTER_NAME}\\{CURRENT_WIN_ADMIN.upper()}
MSG point-2
MON$USER {THIS_COMPUTER_NAME}\\{CURRENT_WIN_ADMIN.upper()}
MON$ROLE {tmp_role_junior.name.upper()}
MON$REMOTE_PROTOCOL TCP
MON$AUTH_METHOD Mapped from Win_Sspi
MSG point-3
MON$USER {THIS_COMPUTER_NAME}\\{CURRENT_WIN_ADMIN.upper()}
MON$ROLE {tmp_role_senior.name.upper()}
MON$REMOTE_PROTOCOL TCP
MON$AUTH_METHOD Mapped from Win_Sspi
TEST_ROWS 0
"""
act.expected_stdout = expected_out
act.isql(switches=['-q'], input = sql_check, connect_db=False, credentials = False, combine_output = True)
assert act.clean_stdout == act.clean_expected_stdout
#coding:utf-8
"""
ID: issue-6145-B
ISSUE: 6145
TITLE: Allow the use of management statements in PSQL blocks
DESCRIPTION:
Role can be set as TRUSTED when following conditions are true:
* BOTH AuthServer and AuthClient parameters from firebird.conf contain 'Win_Sspi' as plugin, in any place;
* current OS user has admin rights;
* OS environment has *no* variables ISC_USER and ISC_PASSWORD (i.e. they must be UNSET);
* Two mappings are created (both uses plugin win_sspi):
** from any user to user;
** from predefined_group domain_any_rid_admins to role <role_to_be_trusted>
Connect to database should be done in form: CONNECT '<computername>:<our_database>' role <role_to_be_trusted>',
and after this we can user 'SET TRUSTED ROLE' statement.
This test checks that statement 'SET TRUSTED ROLE' can be used within PSQL block rather than as DSQL.
JIRA: CORE-5887
FBTEST: bugs.core_5887_trusted_role
NOTES:
[15.08.2022] pzotov
Checked on 5.0.0.623, 4.0.1.2692.
[04.03.2023] pzotov
Computer name must be converted to UPPERCASE, otherwise test fails.
[02.08.2024] pzotov
One need to check for admin rights of current OS user (noted by Dimitry Sibiryakov).
Checked on Windows 6.0.0.406, 5.0.1.1469, 4.0.5.3139
"""
import os
import ctypes
import socket
import getpass
import pytest
from firebird.qa import *
for v in ('ISC_USER','ISC_PASSWORD'):
try:
del os.environ[ v ]
except KeyError as e:
pass
THIS_COMPUTER_NAME = socket.gethostname().upper()
CURRENT_WIN_ADMIN = getpass.getuser()
db = db_factory()
act = python_act('db', substitutions=[('\t+', ' '), ('TCPv(4|6)', 'TCP')])
tmp_role_senior = role_factory('db', name='tmp_role_5887_senior')
tmp_role_junior = role_factory('db', name='tmp_role_5887_junior')
#----------------------------------------------------------
def is_admin():
# https://serverfault.com/questions/29659/crossplatform-way-to-check-admin-rights-in-python-script
# Checked on Windows 10.
try:
is_admin = os.getuid() == 0
except AttributeError:
is_admin = ctypes.windll.shell32.IsUserAnAdmin()
return is_admin
#----------------------------------------------------------
@pytest.mark.version('>=4.0')
@pytest.mark.platform('Windows')
def test_1(act: Action, tmp_role_junior: Role, tmp_role_senior: Role, capsys):
if not is_admin():
pytest.skip("Current OS user must have admin rights.")
sql_init = f"""
set bail on;
create table test(id int);
grant select on test to role {tmp_role_senior.name};
commit;
-- We have to use here "create mapping trusted_auth ... from any user to user" otherwise get
-- Statement failed, SQLSTATE = 28000 /Missing security context for <test_database>
-- on connect statement which specifies COMPUTERNAME:USERNAME instead path to DB:
create or alter mapping trusted_auth using plugin win_sspi from any user to user;
commit;
-- We have to use here "create mapping win_admins ... DOMAIN_ANY_RID_ADMINS" otherwise get
-- Statement failed, SQLSTATE = 0P000 / Your attachment has no trusted role
create or alter mapping win_admins1 using plugin win_sspi from predefined_group domain_any_rid_admins to role {tmp_role_junior.name};
create view v_info as
select a.mon$user, a.mon$role, a.mon$remote_protocol, a.mon$auth_method from mon$attachments a where mon$attachment_id = current_connection
;
grant select on v_info to public;
commit;
"""
act.isql(switches=['-q'], input = sql_init, combine_output = True)
assert act.clean_stdout == ''
act.reset()
sql_check = f"""
-- DO NOT add 'set bail' here!
-- This will make connection with tole = {tmp_role_junior.name}
connect '{THIS_COMPUTER_NAME}:{act.db.db_path}';
set list on;
select 'point-1' as msg, v.* from v_info v;
-- MUST FAIL because neither user nor its role has no access rights to the 'TEST' table:
select count(*) as test_rows from test;
commit;
-- Make temporary connection as SYSDBA and change mapping from predefined_group domain_any_rid_admins
-- so that any connection can get {tmp_role_senior.name} role as trusted role:
connect '{act.db.dsn}' user {act.db.user} password '{act.db.password}';
drop mapping win_admins1;
grant {tmp_role_junior.name} to public;
-- Following statement means that any attachment will be granted with role <tmp_role_senior>
-- which, in turn was granted for SELECT from table 'test':
create or alter mapping win_admins2 using plugin win_sspi from predefined_group domain_any_rid_admins to role {tmp_role_senior.name};
commit;
connect '{THIS_COMPUTER_NAME}:{act.db.db_path}' role {tmp_role_junior.name.upper()};
select 'point-2' as msg, v.* from v_info v;
set bail on;
set term ^;
execute block as
begin
-- Following statement:
-- 1) must pass without any error;
-- 2) leads to change effective role from {tmp_role_junior.name} to {tmp_role_senior.name}:
-- NB: if current OS user has no admin rights then following error will raise at this point:
-- Statement failed, SQLSTATE = 0P000
-- Your attachment has no trusted role
set trusted role;
end
^
set term ;^
commit;
set bail off;
select 'point-3' as msg, v.* from v_info v;
-- this MUST PASS because of trusted role {tmp_role_senior.name} whic has needed access rights:
select count(*) as test_rows from test;
commit;
"""
expected_out = f"""
MSG point-1
MON$USER {THIS_COMPUTER_NAME}\\{CURRENT_WIN_ADMIN.upper()}
MON$ROLE {tmp_role_junior.name.upper()}
MON$REMOTE_PROTOCOL TCP
MON$AUTH_METHOD Mapped from Win_Sspi
Statement failed, SQLSTATE = 28000
no permission for SELECT access to TABLE TEST
-Effective user is {THIS_COMPUTER_NAME}\\{CURRENT_WIN_ADMIN.upper()}
MSG point-2
MON$USER {THIS_COMPUTER_NAME}\\{CURRENT_WIN_ADMIN.upper()}
MON$ROLE {tmp_role_junior.name.upper()}
MON$REMOTE_PROTOCOL TCP
MON$AUTH_METHOD Mapped from Win_Sspi
MSG point-3
MON$USER {THIS_COMPUTER_NAME}\\{CURRENT_WIN_ADMIN.upper()}
MON$ROLE {tmp_role_senior.name.upper()}
MON$REMOTE_PROTOCOL TCP
MON$AUTH_METHOD Mapped from Win_Sspi
TEST_ROWS 0
"""
act.expected_stdout = expected_out
act.isql(switches=['-q'], input = sql_check, connect_db=False, credentials = False, combine_output = True)
assert act.clean_stdout == act.clean_expected_stdout