mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-02-02 08:40:39 +01:00
Implemented CORE-3370: Resolve additional aspects of multiple security databases from services and cross-database requests POV (mapping names)
This commit is contained in:
parent
b826331d55
commit
20e846369e
@ -27,6 +27,7 @@ employee = $(dir_sampleDb)/employee.fdb
|
||||
security.db = $(dir_secDb)/security3.fdb
|
||||
{
|
||||
RemoteAccess = false
|
||||
DefaultDbCachePages = 50
|
||||
}
|
||||
|
||||
#
|
||||
|
240
doc/sql.extensions/README.mapping.html
Normal file
240
doc/sql.extensions/README.mapping.html
Normal file
@ -0,0 +1,240 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=iso-8859-1">
|
||||
<TITLE></TITLE>
|
||||
<META NAME="GENERATOR" CONTENT="OpenOffice 4.0.1 (Unix)">
|
||||
<META NAME="AUTHOR" CONTENT="irina ">
|
||||
<META NAME="CREATED" CONTENT="20140325;10305100">
|
||||
<META NAME="CHANGEDBY" CONTENT="Alex Peshkoff">
|
||||
<META NAME="CHANGED" CONTENT="20140404;19502000">
|
||||
<STYLE TYPE="text/css">
|
||||
<!--
|
||||
@page { margin: 0.79in }
|
||||
P { margin-bottom: 0.08in }
|
||||
A:link { so-language: zxx }
|
||||
-->
|
||||
</STYLE>
|
||||
</HEAD>
|
||||
<BODY LANG="ru-RU" DIR="LTR">
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>SQL Language
|
||||
Extension: CREATE/ALTER/CREATE_OR_ALTER/DROP MAPPING</FONT></P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"> <FONT SIZE=4>Implements
|
||||
capability to control mapping of security objects to and between
|
||||
databases.</FONT></P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>Author:</FONT></P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"> <FONT SIZE=4>Alex
|
||||
Peshkoff <<A HREF="mailto:peshkoff@mail.ru">peshkoff@mail.ru</A>></FONT></P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>Preamble:</FONT></P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>Firebird 3
|
||||
supports multiple security databases. This is great feature, but it
|
||||
raises some problems, missing in systems with single security
|
||||
database. Clusters of databases, using same security database, are
|
||||
efficiently separated and this is what we typically want to achieve
|
||||
using different security databases. But in some cases we need
|
||||
controlled limited interaction between such clusters. As an examples
|
||||
can be provided EXECUTE STATEMENT ON EXTERNAL DATA SOURCE when some
|
||||
data exchange between clusters is required and letting server-wide
|
||||
SYSDBA access databases from other clusters using services. More or
|
||||
less similar problems were already known in windows version of
|
||||
firebird since v. 2.1 due to presence of trusted windows
|
||||
authentication – we had 2 separate lists of users (in security
|
||||
database and OS) and sometimes it was needed to make them be related.
|
||||
For example it appears to be good idea to automatically assign to
|
||||
windows users from some group appropriate firebird role.</FONT></P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>Single
|
||||
solution for all this problems is MAPPING login information, assigned
|
||||
to user when it connected to firebird server, to internal security
|
||||
objects in database – current_user and current_role. Mapping
|
||||
rule contains 4 parts of information: </FONT>
|
||||
</P>
|
||||
<UL>
|
||||
<LI><P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>mapping
|
||||
scope (is mapping local for current database or affects all
|
||||
databases in cluster, including security database),</FONT></P>
|
||||
<LI><P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>mapping
|
||||
name (mappings are named like all the other objects in database), </FONT>
|
||||
</P>
|
||||
<LI><P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>from
|
||||
what we map </FONT>
|
||||
</P>
|
||||
<LI><P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>to what
|
||||
we map.</FONT></P>
|
||||
</UL>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>Here it's necessary to
|
||||
mention that all versions of firebird had one hardcoded global
|
||||
default rule – users authenticated in security database are
|
||||
always mapped into any database one-to-one. This rule is safe - if we
|
||||
have some security database it makes no use not to trust itself.
|
||||
Therefore (and due to backward compatibility) this rule is kept as is
|
||||
in firebird 3. What about mapping windows users to current_user
|
||||
(which was enabled by default in 2.1 & 2.5 when trusted
|
||||
authentication enabled) in firebird 3 it must be done explicitly.
|
||||
This is required for systems with multiple security databases - not
|
||||
all of them need/use windows trusted authentication.</FONT></P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>'From' part
|
||||
of mapping has 4 items:</FONT></P>
|
||||
<UL>
|
||||
<LI><P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>authentication
|
||||
source (plugin name or result of mapping in other database or use of
|
||||
serverwide authentication or any method),</FONT></P>
|
||||
<LI><P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>name of
|
||||
database where authentication succeeded, </FONT>
|
||||
</P>
|
||||
<LI><P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>name
|
||||
from which mapping is performed,</FONT></P>
|
||||
<LI><P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>type of
|
||||
that name (username, role, OS group – this depends upon plugin
|
||||
which added that name during authentication).</FONT></P>
|
||||
</UL>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>Each item may
|
||||
be ignored (any item is accepted) except type – it's definitely
|
||||
bad idea to mix different types of security objects.</FONT></P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>'To' part has
|
||||
2 items:</FONT></P>
|
||||
<UL>
|
||||
<LI><P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>name to
|
||||
which mapping is performed,</FONT></P>
|
||||
<LI><P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>type of
|
||||
that name (only USER/ROLE are accepted here).</FONT></P>
|
||||
</UL>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>Mappings are
|
||||
defined using SQL (DDL) commands.</FONT></P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>Syntax:</FONT></P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P LANG="en-US" STYLE="margin-left: 0.46in; margin-bottom: 0in; page-break-before: auto">
|
||||
<FONT SIZE=4>{CREATE | ALTER | CREATE OR ALTER} [GLOBAL] MAPPING name
|
||||
USING {PLUGIN name [IN database] | ANY PLUGIN [IN database |
|
||||
SERVERWIDE] | MAPPING [IN database] | '*' [IN database]} FROM {ANY
|
||||
type | type name} TO {USER | ROLE} [name]</FONT></P>
|
||||
<P LANG="en-US" STYLE="margin-left: 0.46in; margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P LANG="en-US" STYLE="margin-left: 0.46in; margin-bottom: 0in"><FONT SIZE=4>DROP
|
||||
[GLOBAL] MAPPING</FONT></P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>Description:</FONT></P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>Each mapping
|
||||
may be tagged as GLOBAL. Pay attention that global and local maps
|
||||
with same name may exist and they are different objects!</FONT></P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>Create, alter
|
||||
and create or alter commands use same set of options. Name of mapping
|
||||
is used to identify it in former DDL commands. USING clause has a
|
||||
most complicated set of options. One can provide explicit plugin
|
||||
name, making it work only for given plugin, or make it use any plugin
|
||||
(but not a result of previous mappings), or make it work only with
|
||||
server-wide plugins, or make it work only with previous mapping
|
||||
results, or let it use any method using asterisk. In almost all cases
|
||||
(except server-wide authentication which is not related with
|
||||
databases) one can also provide name of database in which name from
|
||||
which mapping is performed was “born”. FROM clause must
|
||||
set required parameter – type of name from which mapping is
|
||||
done. When mapping names from plugins type is defined by plugin,
|
||||
when previous mapping results - type can be only user or role. One
|
||||
can provide explicit name which will be taken into an account by this
|
||||
mapping or use ANY keyword to work with any name of given type. In TO
|
||||
clause USER or ROLE (to what mapping is done) must be specified, name
|
||||
is optional - when it is not provided original name (from what
|
||||
mapping is done) is used.</FONT></P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>Samples:</FONT></P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>All sample
|
||||
are provided for CREATE command, use of ALTER is exactly the same,
|
||||
use of DROP is obvious.</FONT></P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>Enable use of
|
||||
windows trusted authentication in all databases, using current
|
||||
security database:</FONT></P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>CREATE GLOBAL
|
||||
MAPPING TRUSTED_AUTH USING PLUGIN WIN_SSPI FROM ANY USER TO USER;</FONT></P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>Enable
|
||||
SYSDBA-like access for windows admins:</FONT></P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>CREATE
|
||||
MAPPING WIN_ADMINS USING PLUGIN WIN_SSPI FROM Predefined_Group
|
||||
DOMAIN_ANY_RID_ADMINS TO ROLE RDB$ADMIN;</FONT></P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>(there is no
|
||||
group DOMAIN_ANY_RID_ADMINS in windows, but such name is added by
|
||||
win_sspi plugin to provide exact backwards compatibility)</FONT></P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>Enable
|
||||
particular user from other database access current database with
|
||||
other name:</FONT></P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>CREATE
|
||||
MAPPING FROM_RT USING PLUGIN SRP IN "rt" FROM USER U1 TO
|
||||
USER U2;</FONT></P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>(providing
|
||||
database names/aliases in double quotes is important for file name
|
||||
case-sensitive operating systems)</FONT></P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>Enable
|
||||
server's SYDBA (from main security database) access current database
|
||||
assuming I has non-default security database:</FONT></P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>CREATE
|
||||
MAPPING DEF_SYSDBA USING PLUGIN SRP IN "security.db" FROM
|
||||
USER SYSDBA TO USER;</FONT></P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>Force people
|
||||
who logged in using legacy authentication plugin have not too much
|
||||
rights:</FONT></P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>CREATE
|
||||
MAPPING LEGACY_2_GUEST USING PLUGIN legacy_auth FROM ANY USER TO USER
|
||||
GUEST;</FONT></P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>Notice:</FONT></P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><FONT SIZE=4>Global
|
||||
mapping works best if firebird 3 or higher version database is used
|
||||
as security database. If you plan to use other database as security
|
||||
one (using for example your own provider) please create in it table
|
||||
RDB$MAP with structure repeating one in firebird 3 database and
|
||||
SYSDBA-only write access.</FONT></P>
|
||||
<P LANG="en-US" STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
</BODY>
|
||||
</HTML>
|
@ -1564,6 +1564,28 @@ C --
|
||||
PARAMETER (GDS__forupdate_temptbl = 335545075)
|
||||
INTEGER*4 GDS__cant_modify_sysobj
|
||||
PARAMETER (GDS__cant_modify_sysobj = 335545076)
|
||||
INTEGER*4 GDS__server_misconfigured
|
||||
PARAMETER (GDS__server_misconfigured = 335545077)
|
||||
INTEGER*4 GDS__alter_role
|
||||
PARAMETER (GDS__alter_role = 335545078)
|
||||
INTEGER*4 GDS__map_already_exists
|
||||
PARAMETER (GDS__map_already_exists = 335545079)
|
||||
INTEGER*4 GDS__map_not_exists
|
||||
PARAMETER (GDS__map_not_exists = 335545080)
|
||||
INTEGER*4 GDS__map_load
|
||||
PARAMETER (GDS__map_load = 335545081)
|
||||
INTEGER*4 GDS__map_aster
|
||||
PARAMETER (GDS__map_aster = 335545082)
|
||||
INTEGER*4 GDS__map_multi
|
||||
PARAMETER (GDS__map_multi = 335545083)
|
||||
INTEGER*4 GDS__map_undefined
|
||||
PARAMETER (GDS__map_undefined = 335545084)
|
||||
INTEGER*4 GDS__baddpb_damaged_mode
|
||||
PARAMETER (GDS__baddpb_damaged_mode = 335545085)
|
||||
INTEGER*4 GDS__baddpb_buffers_range
|
||||
PARAMETER (GDS__baddpb_buffers_range = 335545086)
|
||||
INTEGER*4 GDS__baddpb_temp_buffers
|
||||
PARAMETER (GDS__baddpb_temp_buffers = 335545087)
|
||||
INTEGER*4 GDS__gfix_db_name
|
||||
PARAMETER (GDS__gfix_db_name = 335740929)
|
||||
INTEGER*4 GDS__gfix_invalid_sw
|
||||
@ -2256,6 +2278,8 @@ C --
|
||||
PARAMETER (GDS__dsql_revoke_failed = 336397320)
|
||||
INTEGER*4 GDS__dsql_cte_recursive_aggregate
|
||||
PARAMETER (GDS__dsql_cte_recursive_aggregate = 336397321)
|
||||
INTEGER*4 GDS__dsql_mapping_failed
|
||||
PARAMETER (GDS__dsql_mapping_failed = 336397322)
|
||||
INTEGER*4 GDS__gsec_cant_open_db
|
||||
PARAMETER (GDS__gsec_cant_open_db = 336723983)
|
||||
INTEGER*4 GDS__gsec_switches_error
|
||||
|
@ -789,6 +789,17 @@ const
|
||||
gds_forupdate_systbl = 335545074;
|
||||
gds_forupdate_temptbl = 335545075;
|
||||
gds_cant_modify_sysobj = 335545076;
|
||||
gds_server_misconfigured = 335545077;
|
||||
gds_alter_role = 335545078;
|
||||
gds_map_already_exists = 335545079;
|
||||
gds_map_not_exists = 335545080;
|
||||
gds_map_load = 335545081;
|
||||
gds_map_aster = 335545082;
|
||||
gds_map_multi = 335545083;
|
||||
gds_map_undefined = 335545084;
|
||||
gds_baddpb_damaged_mode = 335545085;
|
||||
gds_baddpb_buffers_range = 335545086;
|
||||
gds_baddpb_temp_buffers = 335545087;
|
||||
gds_gfix_db_name = 335740929;
|
||||
gds_gfix_invalid_sw = 335740930;
|
||||
gds_gfix_incmp_sw = 335740932;
|
||||
@ -1135,6 +1146,7 @@ const
|
||||
gds_dsql_grant_failed = 336397319;
|
||||
gds_dsql_revoke_failed = 336397320;
|
||||
gds_dsql_cte_recursive_aggregate = 336397321;
|
||||
gds_dsql_mapping_failed = 336397322;
|
||||
gds_gsec_cant_open_db = 336723983;
|
||||
gds_gsec_switches_error = 336723984;
|
||||
gds_gsec_no_op_spec = 336723985;
|
||||
|
@ -200,7 +200,7 @@ int alice(Firebird::UtilSvc* uSvc)
|
||||
version = true;
|
||||
}
|
||||
|
||||
if (table->in_sw_value & sw_trusted_svc)
|
||||
/* if (table->in_sw_value & sw_trusted_svc)
|
||||
{
|
||||
uSvc->checkService();
|
||||
if (--argc <= 0) {
|
||||
@ -214,7 +214,7 @@ int alice(Firebird::UtilSvc* uSvc)
|
||||
uSvc->checkService();
|
||||
tdgbl->ALICE_data.ua_tr_role = true;
|
||||
continue;
|
||||
}
|
||||
} */
|
||||
#ifdef TRUSTED_AUTH
|
||||
if (table->in_sw_value & sw_trusted_auth)
|
||||
{
|
||||
@ -472,7 +472,7 @@ int alice(Firebird::UtilSvc* uSvc)
|
||||
}
|
||||
|
||||
if (!flags || !(flags & ~(sw_user | sw_password | sw_fetch_password |
|
||||
sw_trusted_auth | sw_trusted_svc | sw_trusted_role)))
|
||||
sw_trusted_auth/* | sw_trusted_svc | sw_trusted_role*/)))
|
||||
{
|
||||
if (!help && !uSvc->isService())
|
||||
{
|
||||
|
@ -60,8 +60,8 @@ const SINT64 sw_buffers = 0x0000000020000000L;
|
||||
const SINT64 sw_mode = 0x0000000040000000L;
|
||||
const SINT64 sw_set_db_dialect = 0x0000000080000000L;
|
||||
const SINT64 sw_trusted_auth = QUADCONST(0x0000000100000000); // Byte 4, Bit 0
|
||||
const SINT64 sw_trusted_svc = QUADCONST(0x0000000200000000);
|
||||
const SINT64 sw_trusted_role = QUADCONST(0x0000000400000000);
|
||||
//const SINT64 sw_trusted_svc = QUADCONST(0x0000000200000000);
|
||||
//const SINT64 sw_trusted_role = QUADCONST(0x0000000400000000);
|
||||
const SINT64 sw_fetch_password = QUADCONST(0x0000000800000000);
|
||||
const SINT64 sw_nolinger = QUADCONST(0x0000001000000000);
|
||||
|
||||
@ -115,8 +115,8 @@ enum alice_switches
|
||||
#ifdef TRUSTED_AUTH
|
||||
IN_SW_ALICE_TRUSTED_AUTH = 44,
|
||||
#endif
|
||||
IN_SW_ALICE_TRUSTED_USER = 45,
|
||||
IN_SW_ALICE_TRUSTED_ROLE = 46,
|
||||
// IN_SW_ALICE_TRUSTED_USER = 45,
|
||||
// IN_SW_ALICE_TRUSTED_ROLE = 46,
|
||||
IN_SW_ALICE_HIDDEN_ONLINE = 47,
|
||||
IN_SW_ALICE_FETCH_PASSWORD = 48,
|
||||
IN_SW_ALICE_NOLINGER = 49
|
||||
@ -199,7 +199,7 @@ static const Switches::in_sw_tab_t alice_in_sw_table[] =
|
||||
sw_list, 0, false, 41, 2, NULL},
|
||||
// msg 41: \t-prompt\t\tprompt for commit/rollback (-l)
|
||||
{IN_SW_ALICE_PASSWORD, 0, "PASSWORD", sw_password,
|
||||
0, (sw_trusted_auth | sw_trusted_svc | sw_trusted_role | sw_fetch_password),
|
||||
0, (sw_trusted_auth /*| sw_trusted_svc | sw_trusted_role */| sw_fetch_password),
|
||||
false, 42, 2, NULL},
|
||||
// msg 42: \t-password\tdefault password
|
||||
#ifdef DEV_BUILD
|
||||
@ -233,15 +233,15 @@ static const Switches::in_sw_tab_t alice_in_sw_table[] =
|
||||
0, (sw_user | sw_password), false, 115, 3, NULL},
|
||||
// msg 115: -trusted use trusted authentication
|
||||
#endif
|
||||
{IN_SW_ALICE_TRUSTED_USER, 0, TRUSTED_USER_SWITCH, sw_trusted_svc,
|
||||
/* {IN_SW_ALICE_TRUSTED_USER, 0, TRUSTED_USER_SWITCH, sw_trusted_svc,
|
||||
0, (sw_trusted_svc | sw_user | sw_password), false, 0, TRUSTED_USER_SWITCH_LEN, NULL},
|
||||
{IN_SW_ALICE_TRUSTED_ROLE, 0, TRUSTED_ROLE_SWITCH, sw_trusted_role,
|
||||
sw_trusted_svc, (sw_user | sw_password), false, 0, TRUSTED_ROLE_SWITCH_LEN, NULL},
|
||||
sw_trusted_svc, (sw_user | sw_password), false, 0, TRUSTED_ROLE_SWITCH_LEN, NULL}, */
|
||||
{IN_SW_ALICE_NO_RESERVE, 0, "USE", sw_no_reserve,
|
||||
0, ~(sw_no_reserve | sw_user | sw_password | sw_nolinger), false, 49, 1, NULL},
|
||||
// msg 49: \t-use\t\tuse full or reserve space for versions
|
||||
{IN_SW_ALICE_USER, 0, "USER", sw_user,
|
||||
0, (sw_trusted_auth | sw_trusted_svc | sw_trusted_role), false, 50, 4, NULL},
|
||||
0, (sw_trusted_auth /*| sw_trusted_svc | sw_trusted_role*/), false, 50, 4, NULL},
|
||||
// msg 50: \t-user\t\tdefault user name
|
||||
{IN_SW_ALICE_VALIDATE, isc_spb_rpr_validate_db, "VALIDATE", sw_validate,
|
||||
0, ~(sw_validate | sw_user | sw_password | sw_nolinger), false, 51, 1, NULL},
|
||||
|
@ -1,8 +1,8 @@
|
||||
/*
|
||||
* PROGRAM: Firebird authentication
|
||||
* MODULE: Auth.cpp
|
||||
* DESCRIPTION: Implementation of interfaces, passed to plugins
|
||||
* Plugins loader
|
||||
* MODULE: AuthDbg.cpp
|
||||
* DESCRIPTION: Test module for various auth types
|
||||
* NOT FOR PRODUCTION USE !
|
||||
*
|
||||
* The contents of this file are subject to the Initial
|
||||
* Developer's Public License Version 1.0 (the "License");
|
||||
@ -54,8 +54,9 @@ extern "C" void FB_PLUGIN_ENTRY_POINT(Firebird::IMaster* master)
|
||||
|
||||
namespace Auth {
|
||||
|
||||
DebugServer::DebugServer(Firebird::IPluginConfig*)
|
||||
: str(getPool())
|
||||
DebugServer::DebugServer(Firebird::IPluginConfig* pConf)
|
||||
: str(getPool()),
|
||||
config(Firebird::REF_NO_INCR, pConf->getDefaultConfig())
|
||||
{ }
|
||||
|
||||
int FB_CARG DebugServer::authenticate(Firebird::IStatus* status, IServerBlock* sb,
|
||||
@ -96,6 +97,13 @@ int FB_CARG DebugServer::authenticate(Firebird::IStatus* status, IServerBlock* s
|
||||
writerInterface->add(str.c_str());
|
||||
str.erase();
|
||||
|
||||
Firebird::RefPtr<Firebird::IConfigEntry> group(Firebird::REF_NO_INCR, config->find("GROUP"));
|
||||
if (group)
|
||||
{
|
||||
writerInterface->add(group->getValue());
|
||||
writerInterface->setType("GROUP");
|
||||
}
|
||||
|
||||
return AUTH_SUCCESS;
|
||||
}
|
||||
catch (const Firebird::Exception& ex)
|
||||
|
@ -35,6 +35,7 @@
|
||||
#ifdef AUTH_DEBUG
|
||||
|
||||
#include "firebird/Auth.h"
|
||||
#include "firebird/Plugin.h"
|
||||
#include "../common/classes/ImplementHelper.h"
|
||||
#include "../common/classes/ClumpletWriter.h"
|
||||
#include "../common/classes/init.h"
|
||||
@ -57,6 +58,7 @@ public:
|
||||
|
||||
private:
|
||||
Firebird::string str;
|
||||
Firebird::RefPtr<Firebird::IConfig> config;
|
||||
};
|
||||
|
||||
class DebugClient FB_FINAL : public Firebird::StdPlugin<IClient, FB_AUTH_CLIENT_VERSION>
|
||||
|
@ -1,42 +1,110 @@
|
||||
#ifdef INCLUDE_Firebird_H // Internal build
|
||||
#define INTERNAL_FIREBIRD
|
||||
#endif
|
||||
|
||||
#include "firebird/Provider.h"
|
||||
|
||||
#ifdef INTERNAL_FIREBIRD
|
||||
|
||||
#include "../common/classes/alloc.h"
|
||||
#include "../common/classes/auto.h"
|
||||
#include "../common/StatusHolder.h"
|
||||
#include "../common/MsgMetadata.h"
|
||||
#include "../common/classes/ImplementHelper.h"
|
||||
|
||||
#else // INTERNAL_FIREBIRD
|
||||
|
||||
#include <assert.h>
|
||||
#define fb_assert(x) assert(x)
|
||||
#include <string.h>
|
||||
|
||||
#endif // INTERNAL_FIREBIRD
|
||||
|
||||
#ifdef INTERNAL_FIREBIRD
|
||||
// This class helps to work with metadata iface
|
||||
class Meta : public Firebird::RefPtr<Firebird::IMessageMetadata>
|
||||
{
|
||||
public:
|
||||
explicit Meta(Firebird::IStatement* stmt, bool out)
|
||||
Meta(Firebird::IStatement* stmt, bool out)
|
||||
{
|
||||
Firebird::LocalStatus s;
|
||||
Firebird::IMessageMetadata* m = out ? stmt->getOutputMetadata(&s) : stmt->getInputMetadata(&s);
|
||||
if (!s.isSuccess())
|
||||
Firebird::LocalStatus st;
|
||||
Firebird::IMessageMetadata* m = out ? stmt->getOutputMetadata(&st) : stmt->getInputMetadata(&st);
|
||||
if (!st.isSuccess())
|
||||
{
|
||||
Firebird::status_exception::raise(s.get());
|
||||
Firebird::status_exception::raise(st.get());
|
||||
}
|
||||
assignRefNoIncr(m);
|
||||
}
|
||||
};
|
||||
#endif // INTERNAL_FIREBIRD
|
||||
|
||||
|
||||
// This class helps to fill message with correct values
|
||||
class Message : public Firebird::GlobalStorage
|
||||
// Linked list of various fields
|
||||
class FieldLink
|
||||
{
|
||||
public:
|
||||
Message(Firebird::IMessageMetadata* aMeta)
|
||||
: dataBuf(getPool()), fieldCount(0)
|
||||
virtual ~FieldLink() { }
|
||||
virtual void linkWithMessage(const unsigned char* buf) = 0;
|
||||
|
||||
FieldLink* next;
|
||||
};
|
||||
|
||||
|
||||
// This class helps to exchange values with a message
|
||||
class Message
|
||||
// : public AutoStorage
|
||||
{
|
||||
public:
|
||||
Message(Firebird::IMessageMetadata* aMeta = NULL)
|
||||
: metadata(NULL), buffer(NULL), builder(NULL),
|
||||
fieldCount(0), fieldList(NULL)
|
||||
{
|
||||
Firebird::LocalStatus st;
|
||||
buffer = dataBuf.getBuffer(aMeta->getMessageLength(&st));
|
||||
check(&st);
|
||||
metadata = aMeta;
|
||||
#ifdef INTERNAL_FIREBIRD
|
||||
s = &st;
|
||||
#else
|
||||
s = fb_get_master_interface()->getStatus();
|
||||
#endif
|
||||
|
||||
try
|
||||
{
|
||||
if (aMeta)
|
||||
{
|
||||
createBuffer(aMeta);
|
||||
metadata = aMeta;
|
||||
metadata->addRef();
|
||||
}
|
||||
else
|
||||
{
|
||||
Firebird::IMetadataBuilder* bld =
|
||||
#ifdef INTERNAL_FIREBIRD
|
||||
Firebird::MasterInterfacePtr()->
|
||||
#else
|
||||
fb_get_master_interface()->
|
||||
#endif
|
||||
getMetadataBuilder(s, 0);
|
||||
check(s);
|
||||
builder = bld;
|
||||
builder->addRef();
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
s->dispose();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
~Message()
|
||||
{ }
|
||||
{
|
||||
delete buffer;
|
||||
#ifndef INTERNAL_FIREBIRD
|
||||
s->dispose();
|
||||
#endif
|
||||
if (builder)
|
||||
builder->release();
|
||||
if (metadata)
|
||||
metadata->release();
|
||||
}
|
||||
|
||||
public:
|
||||
template <typename T>
|
||||
static bool checkType(unsigned t, unsigned /*sz*/)
|
||||
{
|
||||
@ -44,25 +112,58 @@ public:
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
unsigned add(unsigned& t, unsigned& sz)
|
||||
static unsigned getType(unsigned& sz)
|
||||
{
|
||||
Firebird::LocalStatus st;
|
||||
return T::SQL_UnknownDataType;
|
||||
}
|
||||
|
||||
unsigned l = metadata->getCount(&st);
|
||||
check(&st);
|
||||
if (fieldCount >= metadata->getMessageLength(&st))
|
||||
template <typename T>
|
||||
unsigned add(unsigned& t, unsigned& sz, FieldLink* lnk)
|
||||
{
|
||||
if (metadata)
|
||||
{
|
||||
(Firebird::Arg::Gds(isc_random) <<
|
||||
"Attempt to add to the message more variables than possible").raise();
|
||||
unsigned l = metadata->getCount(s);
|
||||
check(s);
|
||||
if (fieldCount >= l)
|
||||
{
|
||||
#ifdef INTERNAL_FIREBIRD
|
||||
(Firebird::Arg::Gds(isc_random) <<
|
||||
"Attempt to add to the message more variables than possible").raise();
|
||||
#else
|
||||
fatalErrorHandler("Attempt to add to the message more variables than possible");
|
||||
#endif
|
||||
}
|
||||
|
||||
t = metadata->getType(s, fieldCount);
|
||||
check(s);
|
||||
sz = metadata->getLength(s, fieldCount);
|
||||
check(s);
|
||||
if (!checkType<T>(t, sz))
|
||||
{
|
||||
#ifdef INTERNAL_FIREBIRD
|
||||
(Firebird::Arg::Gds(isc_random) << "Incompatible data type").raise();
|
||||
#else
|
||||
fatalErrorHandler("Incompatible data type");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
t = metadata->getType(&st, fieldCount);
|
||||
check(&st);
|
||||
sz = metadata->getLength(&st, fieldCount);
|
||||
check(&st);
|
||||
if (!checkType<T>(t, sz))
|
||||
else
|
||||
{
|
||||
(Firebird::Arg::Gds(isc_random) << "Incompatible data type").raise();
|
||||
fb_assert(builder);
|
||||
|
||||
unsigned f = builder->addField(s);
|
||||
check(s);
|
||||
|
||||
fb_assert(f == fieldCount);
|
||||
|
||||
t = getType<T>(sz);
|
||||
builder->setType(s, f, t);
|
||||
check(s);
|
||||
builder->setLength(s, f, sz);
|
||||
check(s);
|
||||
|
||||
lnk->next = fieldList;
|
||||
fieldList = lnk;
|
||||
}
|
||||
|
||||
return fieldCount++;
|
||||
@ -72,61 +173,91 @@ public:
|
||||
{
|
||||
if (!status->isSuccess())
|
||||
{
|
||||
#ifdef INTERNAL_FIREBIRD
|
||||
Firebird::status_exception::raise(status->get());
|
||||
#else
|
||||
char s[100];
|
||||
const ISC_STATUS *st = status->get();
|
||||
fb_interpret(s, sizeof(s), &st);
|
||||
fatalErrorHandler(s);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// makes it possible to use metadata in ?: operator
|
||||
// Attention!
|
||||
// No addRef/release interface here!
|
||||
// Lifetime is equal at least to Message lifetime
|
||||
Firebird::IMessageMetadata* getMetadata()
|
||||
{
|
||||
if (!metadata)
|
||||
{
|
||||
fb_assert(builder);
|
||||
Firebird::IMessageMetadata* aMeta = builder->getMetadata(s);
|
||||
check(s);
|
||||
metadata = aMeta;
|
||||
metadata->addRef();
|
||||
builder->release();
|
||||
builder = NULL;
|
||||
}
|
||||
|
||||
return metadata;
|
||||
}
|
||||
|
||||
public:
|
||||
Firebird::RefPtr<Firebird::IMessageMetadata> metadata;
|
||||
UCHAR* buffer;
|
||||
bool hasMetadata()
|
||||
{
|
||||
return metadata ? true : false;
|
||||
}
|
||||
|
||||
// access to message's data buffer
|
||||
unsigned char* getBuffer()
|
||||
{
|
||||
if (!buffer)
|
||||
{
|
||||
getMetadata();
|
||||
|
||||
createBuffer(metadata);
|
||||
while(fieldList)
|
||||
{
|
||||
fieldList->linkWithMessage(buffer);
|
||||
fieldList = fieldList->next;
|
||||
}
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
private:
|
||||
Firebird::UCharBuffer dataBuf;
|
||||
void createBuffer(Firebird::IMessageMetadata* aMeta)
|
||||
{
|
||||
unsigned l = aMeta->getMessageLength(s);
|
||||
check(s);
|
||||
buffer = new unsigned char[l];
|
||||
}
|
||||
|
||||
public:
|
||||
Firebird::IStatus* s;
|
||||
|
||||
private:
|
||||
#ifdef INTERNAL_FIREBIRD
|
||||
Firebird::LocalStatus st;
|
||||
#endif
|
||||
Firebird::IMessageMetadata* metadata;
|
||||
unsigned char* buffer;
|
||||
Firebird::IMetadataBuilder* builder;
|
||||
unsigned fieldCount;
|
||||
FieldLink* fieldList;
|
||||
};
|
||||
|
||||
|
||||
// With template magic, we make the fields strongly-typed.
|
||||
template <>
|
||||
bool Message::checkType<SLONG>(unsigned t, unsigned sz)
|
||||
{
|
||||
return t == SQL_LONG && sz == sizeof(SLONG);
|
||||
}
|
||||
|
||||
template <>
|
||||
bool Message::checkType<ISC_QUAD>(unsigned t, unsigned sz)
|
||||
{
|
||||
return (t == SQL_BLOB || t == SQL_QUAD) && sz == sizeof(ISC_QUAD);
|
||||
}
|
||||
|
||||
template <>
|
||||
bool Message::checkType<ISC_INT64>(unsigned t, unsigned sz)
|
||||
{
|
||||
return t == SQL_INT64 && sz == sizeof(ISC_INT64);
|
||||
}
|
||||
|
||||
template <>
|
||||
bool Message::checkType<FB_BOOLEAN>(unsigned t, unsigned sz)
|
||||
{
|
||||
return t == SQL_BOOLEAN && sz == sizeof(FB_BOOLEAN);
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
class Field
|
||||
class Field : public FieldLink
|
||||
{
|
||||
public:
|
||||
class Null
|
||||
{
|
||||
public:
|
||||
Null()
|
||||
: ptr(NULL)
|
||||
Null(Message* m)
|
||||
: msg(m), ptr(NULL)
|
||||
{ }
|
||||
|
||||
void linkMessage(short* p)
|
||||
@ -137,46 +268,57 @@ public:
|
||||
|
||||
operator FB_BOOLEAN() const
|
||||
{
|
||||
msg->getBuffer();
|
||||
return (*ptr) ? FB_TRUE : FB_FALSE;
|
||||
}
|
||||
|
||||
FB_BOOLEAN operator=(FB_BOOLEAN val)
|
||||
{
|
||||
msg->getBuffer();
|
||||
*ptr = val ? -1 : 0;
|
||||
return val;
|
||||
}
|
||||
|
||||
private:
|
||||
Message* msg;
|
||||
short* ptr;
|
||||
};
|
||||
|
||||
explicit Field(Message& m)
|
||||
: ptr(NULL), type(0), size(0)
|
||||
explicit Field(Message& m, unsigned sz = 0)
|
||||
: ptr(NULL), charBuffer(NULL), msg(&m), null(msg), ind(~0), type(0), size(sz)
|
||||
{
|
||||
unsigned ind = m.add<T>(type, size);
|
||||
ind = msg->add<T>(type, size, this);
|
||||
|
||||
Firebird::LocalStatus st;
|
||||
unsigned tmp = m.metadata->getOffset(&st, ind);
|
||||
Message::check(&st);
|
||||
ptr = (T*) (m.buffer + tmp);
|
||||
if (msg->hasMetadata())
|
||||
setPointers(msg->getBuffer());
|
||||
}
|
||||
|
||||
tmp = m.metadata->getNullOffset(&st, ind);
|
||||
Message::check(&st);
|
||||
null.linkMessage((short*) (m.buffer + tmp));
|
||||
~Field()
|
||||
{
|
||||
delete charBuffer;
|
||||
}
|
||||
|
||||
operator T()
|
||||
{
|
||||
msg->getBuffer();
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
T* operator&()
|
||||
{
|
||||
msg->getBuffer();
|
||||
return ptr;
|
||||
}
|
||||
|
||||
T* operator->()
|
||||
{
|
||||
msg->getBuffer();
|
||||
return ptr;
|
||||
}
|
||||
|
||||
T operator= (T newVal)
|
||||
{
|
||||
msg->getBuffer();
|
||||
*ptr = newVal;
|
||||
null = FB_FALSE;
|
||||
return newVal;
|
||||
@ -184,49 +326,71 @@ public:
|
||||
|
||||
operator const char*()
|
||||
{
|
||||
msg->getBuffer();
|
||||
|
||||
if (!charBuffer)
|
||||
{
|
||||
charBuffer.reset(FB_NEW(*getDefaultMemoryPool()) char[size + 1]);
|
||||
charBuffer = new char[size + 1];
|
||||
}
|
||||
|
||||
getStrValue(charBuffer);
|
||||
return charBuffer;
|
||||
}
|
||||
|
||||
const char* operator= (const char* newVal)
|
||||
{
|
||||
setStrValue(newVal, strlen(newVal));
|
||||
msg->getBuffer();
|
||||
setStrValue(newVal, strnlen(newVal, size));
|
||||
null = FB_FALSE;
|
||||
return newVal;
|
||||
}
|
||||
|
||||
void set(unsigned length, const void* newVal)
|
||||
{
|
||||
msg->getBuffer();
|
||||
setStrValue(newVal, length);
|
||||
null = FB_FALSE;
|
||||
}
|
||||
|
||||
private:
|
||||
void linkWithMessage(const unsigned char* buf)
|
||||
{
|
||||
setPointers(buf);
|
||||
}
|
||||
|
||||
void setPointers(const unsigned char* buf)
|
||||
{
|
||||
unsigned tmp = msg->getMetadata()->getOffset(msg->s, ind);
|
||||
Message::check(msg->s);
|
||||
ptr = (T*) (buf + tmp);
|
||||
|
||||
tmp = msg->getMetadata()->getNullOffset(msg->s, ind);
|
||||
Message::check(msg->s);
|
||||
null.linkMessage((short*) (buf + tmp));
|
||||
}
|
||||
|
||||
void getStrValue(char* to)
|
||||
{
|
||||
T::incompatibleDataType();
|
||||
//(Firebird::Arg::Gds(isc_random) << "Incompatible data type").raise();
|
||||
}
|
||||
|
||||
void setStrValue(const void* from, unsigned len)
|
||||
{
|
||||
T::incompatibleDataType();
|
||||
//(Firebird::Arg::Gds(isc_random) << "Incompatible data type").raise();
|
||||
}
|
||||
|
||||
T* ptr;
|
||||
Firebird::AutoPtr<char, Firebird::ArrayDelete<char> > charBuffer;
|
||||
char* charBuffer;
|
||||
Message* msg;
|
||||
|
||||
public:
|
||||
Null null;
|
||||
unsigned type, size;
|
||||
|
||||
private:
|
||||
unsigned ind, type, size;
|
||||
};
|
||||
|
||||
|
||||
// ---------------------------------------------
|
||||
struct Varying
|
||||
{
|
||||
short len;
|
||||
@ -234,13 +398,22 @@ struct Varying
|
||||
};
|
||||
|
||||
template <>
|
||||
bool Message::checkType<Varying>(unsigned t, unsigned /*sz*/)
|
||||
inline bool Message::checkType<Varying>(unsigned t, unsigned /*sz*/)
|
||||
{
|
||||
return t == SQL_VARYING;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline unsigned Message::getType<Varying>(unsigned& sz)
|
||||
{
|
||||
if (!sz)
|
||||
sz = 1;
|
||||
sz += sizeof(short);
|
||||
return SQL_VARYING;
|
||||
}
|
||||
|
||||
template<>
|
||||
void Field<Varying>::getStrValue(char* to)
|
||||
inline void Field<Varying>::getStrValue(char* to)
|
||||
{
|
||||
unsigned len = ptr->len;
|
||||
if (len > size)
|
||||
@ -250,7 +423,7 @@ void Field<Varying>::getStrValue(char* to)
|
||||
}
|
||||
|
||||
template<>
|
||||
void Field<Varying>::setStrValue(const void* from, unsigned len)
|
||||
inline void Field<Varying>::setStrValue(const void* from, unsigned len)
|
||||
{
|
||||
if (len > size)
|
||||
len = size;
|
||||
@ -264,13 +437,21 @@ struct Text
|
||||
};
|
||||
|
||||
template <>
|
||||
bool Message::checkType<Text>(unsigned t, unsigned /*sz*/)
|
||||
inline bool Message::checkType<Text>(unsigned t, unsigned /*sz*/)
|
||||
{
|
||||
return t == SQL_TEXT;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline unsigned Message::getType<Text>(unsigned& sz)
|
||||
{
|
||||
if (!sz)
|
||||
sz = 1;
|
||||
return SQL_TEXT;
|
||||
}
|
||||
|
||||
template<>
|
||||
void Field<Text>::getStrValue(char* to)
|
||||
inline void Field<Text>::getStrValue(char* to)
|
||||
{
|
||||
memcpy(to, ptr->data, size);
|
||||
to[size] = 0;
|
||||
@ -285,7 +466,7 @@ void Field<Text>::getStrValue(char* to)
|
||||
}
|
||||
|
||||
template<>
|
||||
void Field<Text>::setStrValue(const void* from, unsigned len)
|
||||
inline void Field<Text>::setStrValue(const void* from, unsigned len)
|
||||
{
|
||||
if (len > size)
|
||||
len = size;
|
||||
@ -293,3 +474,68 @@ void Field<Text>::setStrValue(const void* from, unsigned len)
|
||||
if (len < size)
|
||||
memset(&ptr->data[len], ' ', size - len);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool Message::checkType<ISC_SHORT>(unsigned t, unsigned sz)
|
||||
{
|
||||
return t == SQL_SHORT && sz == sizeof(ISC_SHORT);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool Message::checkType<ISC_LONG>(unsigned t, unsigned sz)
|
||||
{
|
||||
return t == SQL_LONG && sz == sizeof(ISC_LONG);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool Message::checkType<ISC_QUAD>(unsigned t, unsigned sz)
|
||||
{
|
||||
return (t == SQL_BLOB || t == SQL_QUAD) && sz == sizeof(ISC_QUAD);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool Message::checkType<ISC_INT64>(unsigned t, unsigned sz)
|
||||
{
|
||||
return t == SQL_INT64 && sz == sizeof(ISC_INT64);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool Message::checkType<FB_BOOLEAN>(unsigned t, unsigned sz)
|
||||
{
|
||||
return t == SQL_BOOLEAN && sz == sizeof(FB_BOOLEAN);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline unsigned Message::getType<ISC_SHORT>(unsigned& sz)
|
||||
{
|
||||
sz = sizeof(ISC_SHORT);
|
||||
return SQL_SHORT;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline unsigned Message::getType<ISC_LONG>(unsigned& sz)
|
||||
{
|
||||
sz = sizeof(ISC_LONG);
|
||||
return SQL_LONG;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline unsigned Message::getType<ISC_QUAD>(unsigned& sz)
|
||||
{
|
||||
sz = sizeof(ISC_QUAD);
|
||||
return SQL_BLOB;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline unsigned Message::getType<ISC_INT64>(unsigned& sz)
|
||||
{
|
||||
sz = sizeof(ISC_INT64);
|
||||
return SQL_INT64;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline unsigned Message::getType<FB_BOOLEAN>(unsigned& sz)
|
||||
{
|
||||
sz = sizeof(FB_BOOLEAN);
|
||||
return SQL_BOOLEAN;
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ public:
|
||||
"SELECT PLG$USER_NAME, PLG$VERIFIER, PLG$SALT, PLG$COMMENT, "
|
||||
" PLG$FIRST, PLG$MIDDLE, PLG$LAST, PLG$ATTRIBUTES, PLG$ACTIVE "
|
||||
"FROM PLG$SRP WHERE CURRENT_USER = 'SYSDBA' "
|
||||
" OR CURRENT_ROLE = 'RDB$ADMIN' OR CURRENT_USER = PLG$SRP.PLG$USER_NAME"
|
||||
" OR CURRENT_ROLE = '" ADMIN_ROLE "' OR CURRENT_USER = PLG$SRP.PLG$USER_NAME"
|
||||
,
|
||||
"GRANT ALL ON PLG$SRP to VIEW PLG$SRP_VIEW"
|
||||
,
|
||||
@ -94,7 +94,7 @@ public:
|
||||
{
|
||||
for (const char** sql = script; *sql; ++sql)
|
||||
{
|
||||
att->execute(&s, ddlTran, 0, *sql, 3, NULL, NULL, NULL, NULL);
|
||||
att->execute(&s, ddlTran, 0, *sql, SQL_DIALECT_V6, NULL, NULL, NULL, NULL);
|
||||
check(&s);
|
||||
}
|
||||
|
||||
@ -143,19 +143,24 @@ public:
|
||||
unsigned int authBlockSize = logonInfo->authBlock(&authBlock);
|
||||
|
||||
if (authBlockSize)
|
||||
{
|
||||
#if SRP_DEBUG > 0
|
||||
fprintf(stderr, "SrpManagement: Using authBlock size %d\n", authBlockSize);
|
||||
#endif
|
||||
dpb.insertBytes(isc_dpb_auth_block, authBlock, authBlockSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* str = logonInfo->name();
|
||||
#if SRP_DEBUG > 0
|
||||
fprintf(stderr, "SrpManagement: Using name '%s'\n", str);
|
||||
#endif
|
||||
if (str && str[0])
|
||||
dpb.insertString(isc_dpb_trusted_auth, str, strlen(str));
|
||||
|
||||
str = logonInfo->role();
|
||||
|
||||
if (str && str[0])
|
||||
dpb.insertString(isc_dpb_sql_role_name, str, strlen(str));
|
||||
else if (logonInfo->forceAdmin())
|
||||
dpb.insertString(isc_dpb_trusted_role, ADMIN_ROLE, strlen(ADMIN_ROLE));
|
||||
}
|
||||
|
||||
Firebird::DispatcherPtr p;
|
||||
@ -200,9 +205,9 @@ public:
|
||||
case MAP_SET_OPER:
|
||||
{
|
||||
Firebird::string sql;
|
||||
sql.printf("ALTER ROLE RDB$ADMIN %s AUTO ADMIN MAPPING",
|
||||
sql.printf("ALTER ROLE " ADMIN_ROLE " %s AUTO ADMIN MAPPING",
|
||||
user->operation() == MAP_SET_OPER ? "SET" : "DROP");
|
||||
att->execute(status, tra, sql.length(), sql.c_str(), 3, NULL, NULL, NULL, NULL);
|
||||
att->execute(status, tra, sql.length(), sql.c_str(), SQL_DIALECT_V6, NULL, NULL, NULL, NULL);
|
||||
check(status);
|
||||
}
|
||||
break;
|
||||
@ -218,7 +223,7 @@ public:
|
||||
{
|
||||
for (unsigned repeat = 0; ; ++repeat)
|
||||
{
|
||||
stmt = att->prepare(status, tra, 0, insert, 3, Firebird::IStatement::PREPARE_PREFETCH_METADATA);
|
||||
stmt = att->prepare(status, tra, 0, insert, SQL_DIALECT_V6, Firebird::IStatement::PREPARE_PREFETCH_METADATA);
|
||||
if (status->isSuccess())
|
||||
{
|
||||
break;
|
||||
@ -286,7 +291,7 @@ public:
|
||||
dumpIt("verifier", s);
|
||||
verifier.set(s.getCount(), s.begin());
|
||||
|
||||
stmt->execute(status, tra, add.metadata, add.buffer, NULL, NULL);
|
||||
stmt->execute(status, tra, add.getMetadata(), add.getBuffer(), NULL, NULL);
|
||||
check(status);
|
||||
|
||||
stmt->free(status);
|
||||
@ -333,7 +338,7 @@ public:
|
||||
Firebird::IStatement* stmt = NULL;
|
||||
try
|
||||
{
|
||||
stmt = att->prepare(status, tra, 0, update.c_str(), 3, Firebird::IStatement::PREPARE_PREFETCH_METADATA);
|
||||
stmt = att->prepare(status, tra, 0, update.c_str(), SQL_DIALECT_V6, Firebird::IStatement::PREPARE_PREFETCH_METADATA);
|
||||
check(status);
|
||||
|
||||
Meta im(stmt, false);
|
||||
@ -381,7 +386,7 @@ public:
|
||||
assignField(active, user->active());
|
||||
setField(login, user->userName());
|
||||
|
||||
stmt->execute(status, tra, up.metadata, up.buffer, NULL, NULL);
|
||||
stmt->execute(status, tra, up.getMetadata(), up.getBuffer(), NULL, NULL);
|
||||
check(status);
|
||||
|
||||
if (!checkCount(status, &upCount, isc_info_update_count))
|
||||
@ -410,7 +415,7 @@ public:
|
||||
Firebird::IStatement* stmt = NULL;
|
||||
try
|
||||
{
|
||||
stmt = att->prepare(status, tra, 0, del, 3, Firebird::IStatement::PREPARE_PREFETCH_METADATA);
|
||||
stmt = att->prepare(status, tra, 0, del, SQL_DIALECT_V6, Firebird::IStatement::PREPARE_PREFETCH_METADATA);
|
||||
check(status);
|
||||
|
||||
Meta im(stmt, false);
|
||||
@ -418,7 +423,7 @@ public:
|
||||
Name login(dl);
|
||||
setField(login, user->userName());
|
||||
|
||||
stmt->execute(status, tra, dl.metadata, dl.buffer, NULL, NULL);
|
||||
stmt->execute(status, tra, dl.getMetadata(), dl.getBuffer(), NULL, NULL);
|
||||
check(status);
|
||||
|
||||
if (!checkCount(status, &delCount, isc_info_delete_count))
|
||||
@ -448,7 +453,7 @@ public:
|
||||
" CASE WHEN RDB$RELATION_NAME IS NULL THEN 0 ELSE 1 END, PLG$ACTIVE "
|
||||
"FROM PLG$SRP_VIEW LEFT JOIN RDB$USER_PRIVILEGES "
|
||||
" ON PLG$SRP_VIEW.PLG$USER_NAME = RDB$USER_PRIVILEGES.RDB$USER "
|
||||
" AND RDB$RELATION_NAME = 'RDB$ADMIN' "
|
||||
" AND RDB$RELATION_NAME = '" ADMIN_ROLE "' "
|
||||
" AND RDB$PRIVILEGE = 'M' ";
|
||||
if (user->userName()->entered())
|
||||
{
|
||||
@ -459,7 +464,7 @@ public:
|
||||
Firebird::IResultSet* rs = NULL;
|
||||
try
|
||||
{
|
||||
stmt = att->prepare(status, tra, 0, disp.c_str(), 3,
|
||||
stmt = att->prepare(status, tra, 0, disp.c_str(), SQL_DIALECT_V6,
|
||||
Firebird::IStatement::PREPARE_PREFETCH_METADATA);
|
||||
check(status);
|
||||
|
||||
@ -481,10 +486,10 @@ public:
|
||||
}
|
||||
|
||||
rs = stmt->openCursor(status, tra, (par ? par->getMetadata() : NULL),
|
||||
(par ? par->buffer : NULL), om);
|
||||
(par ? par->getBuffer() : NULL), om);
|
||||
check(status);
|
||||
|
||||
while (rs->fetchNext(status, di.buffer))
|
||||
while (rs->fetchNext(status, di.getBuffer()))
|
||||
{
|
||||
check(status);
|
||||
|
||||
|
@ -174,7 +174,8 @@ int SrpServer::authenticate(IStatus* status, IServerBlock* sb, IWriter* writerIn
|
||||
Field<Varying> slt(dat);
|
||||
HANDSHAKE_DEBUG(fprintf(stderr, "Srv: SRP1: Ready to run statement with login '%s'\n", account.c_str()));
|
||||
|
||||
stmt->execute(status, tra, par.metadata, par.buffer, dat.metadata, dat.buffer);
|
||||
stmt->execute(status, tra, par.getMetadata(), par.getBuffer(),
|
||||
dat.getMetadata(), dat.getBuffer());
|
||||
if (!status->isSuccess())
|
||||
{
|
||||
status_exception::raise(status->get());
|
||||
@ -266,7 +267,7 @@ int SrpServer::authenticate(IStatus* status, IServerBlock* sb, IWriter* writerIn
|
||||
{
|
||||
MasterInterfacePtr()->upgradeInterface(writerInterface, FB_AUTH_WRITER_VERSION, upInfo);
|
||||
writerInterface->add(account.c_str());
|
||||
writerInterface->setAttribute(AuthReader::AUTH_SECURE_DB, secDbName);
|
||||
writerInterface->setDb(secDbName);
|
||||
return AUTH_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ static bool grantRevokeAdmin(ISC_STATUS* isc_status, FB_API_HANDLE database, FB_
|
||||
|
||||
Firebird::string sql;
|
||||
sql.printf((user->admin()->get() ? "GRANT %s TO \"%s\"" : "REVOKE %s FROM \"%s\""),
|
||||
"RDB$ADMIN", userName.c_str());
|
||||
ADMIN_ROLE, userName.c_str());
|
||||
isc_dsql_execute_immediate(isc_status, &database, &trans, sql.length(), sql.c_str(), SQL_DIALECT_V6, NULL);
|
||||
|
||||
if (isc_status[1] && user->admin()->get() == 0)
|
||||
@ -79,7 +79,7 @@ static bool grantRevokeAdmin(ISC_STATUS* isc_status, FB_API_HANDLE database, FB_
|
||||
WITH R.RDB$USER EQ user->userName()->get()
|
||||
AND R.RDB$RELATION_NAME EQ 'RDB$ADMIN'
|
||||
AND R.RDB$PRIVILEGE EQ 'M'
|
||||
sql.printf("REVOKE RDB$ADMIN FROM \"%s\" GRANTED BY \"%s\"",
|
||||
sql.printf("REVOKE " ADMIN_ROLE " FROM \"%s\" GRANTED BY \"%s\"",
|
||||
userName.c_str(), R.RDB$GRANTOR);
|
||||
END_FOR
|
||||
|
||||
@ -162,11 +162,8 @@ void FB_CARG SecurityDatabaseManagement::start(Firebird::IStatus* st, ILogonInfo
|
||||
dpb.insertString(isc_dpb_trusted_auth, str, strlen(str));
|
||||
|
||||
str = logonInfo->role();
|
||||
|
||||
if (str && str[0])
|
||||
dpb.insertString(isc_dpb_sql_role_name, str, strlen(str));
|
||||
else if (logonInfo->forceAdmin())
|
||||
dpb.insertString(isc_dpb_trusted_role, ADMIN_ROLE, strlen(ADMIN_ROLE));
|
||||
}
|
||||
|
||||
ISC_STATUS_ARRAY status;
|
||||
@ -350,7 +347,7 @@ int FB_CARG SecurityDatabaseManagement::execute(Firebird::IStatus* st, IUser* us
|
||||
case MAP_SET_OPER:
|
||||
{
|
||||
Firebird::string sql;
|
||||
sql.printf("ALTER ROLE RDB$ADMIN %s AUTO ADMIN MAPPING",
|
||||
sql.printf("ALTER ROLE " ADMIN_ROLE " %s AUTO ADMIN MAPPING",
|
||||
user->operation() == MAP_SET_OPER ? "SET" : "DROP");
|
||||
isc_dsql_execute_immediate(isc_status, &database, &transaction, sql.length(), sql.c_str(), 1, NULL);
|
||||
if (isc_status[1] != 0)
|
||||
|
@ -351,7 +351,7 @@ int SecurityDatabase::verify(IWriter* authBlock, IServerBlock* sBlock)
|
||||
|
||||
MasterInterfacePtr()->upgradeInterface(authBlock, FB_AUTH_WRITER_VERSION, upInfo);
|
||||
authBlock->add(login.c_str());
|
||||
authBlock->setAttribute(AuthReader::AUTH_SECURE_DB, secureDbName);
|
||||
authBlock->setDb(secureDbName);
|
||||
return AUTH_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -369,7 +369,12 @@ int WinSspiServer::authenticate(Firebird::IStatus* status,
|
||||
|
||||
writerInterface->add(login.c_str());
|
||||
if (wheel)
|
||||
writerInterface->add("RDB$ADMIN");
|
||||
{
|
||||
writerInterface->add(FB_DOMAIN_ANY_RID_ADMINS);
|
||||
writerInterface->setType(FB_PREDEFINED_GROUP);
|
||||
}
|
||||
|
||||
// ToDo: walk groups to which login belongs and list them using writerInterface
|
||||
|
||||
return AUTH_SUCCESS;
|
||||
}
|
||||
|
@ -30,6 +30,10 @@
|
||||
|
||||
#include <firebird.h>
|
||||
|
||||
// This is old versions backward compatibility
|
||||
#define FB_PREDEFINED_GROUP "Predefined_Group"
|
||||
#define FB_DOMAIN_ANY_RID_ADMINS "DOMAIN_ANY_RID_ADMINS"
|
||||
|
||||
#ifdef TRUSTED_AUTH
|
||||
|
||||
#include <../common/classes/fb_string.h>
|
||||
|
@ -4073,16 +4073,45 @@ void write_mapping()
|
||||
*
|
||||
**************************************/
|
||||
isc_req_handle req_handle = 0;
|
||||
TEXT temp[GDS_NAME_LEN];
|
||||
|
||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||
|
||||
if (tdgbl->runtimeODS >= DB_VERSION_DDL11_2)
|
||||
if (tdgbl->runtimeODS >= DB_VERSION_DDL12)
|
||||
{
|
||||
FOR (REQUEST_HANDLE req_handle)
|
||||
M IN RDB$MAP
|
||||
WITH (M.RDB$SYSTEM_FLAG EQ 0 OR M.RDB$SYSTEM_FLAG MISSING)
|
||||
|
||||
put(tdgbl, rec_mapping);
|
||||
const SSHORT l = PUT_TEXT(att_map_name, M.RDB$MAP_NAME);
|
||||
PUT_TEXT(att_map_using, M.RDB$MAP_USING);
|
||||
if (!M.RDB$MAP_PLUGIN.NULL) PUT_TEXT(att_map_plugin, M.RDB$MAP_PLUGIN);
|
||||
if (!M.RDB$MAP_DB.NULL) PUT_TEXT(att_map_db, M.RDB$MAP_DB);
|
||||
PUT_TEXT(att_map_from_type, M.RDB$MAP_FROM_TYPE);
|
||||
if (!M.RDB$MAP_FROM.NULL) PUT_TEXT(att_map_from, M.RDB$MAP_FROM);
|
||||
put_int32(att_map_to_type, M.RDB$MAP_TO_TYPE);
|
||||
if (!M.RDB$MAP_TO.NULL) PUT_TEXT(att_map_to, M.RDB$MAP_TO);
|
||||
if (!M.RDB$DESCRIPTION.NULL)
|
||||
put_source_blob(att_map_description, att_map_description, M.RDB$DESCRIPTION);
|
||||
put(tdgbl, att_end);
|
||||
|
||||
MISC_terminate (M.RDB$MAP_NAME, temp, l, sizeof(temp));
|
||||
BURP_verbose (297, temp);
|
||||
// msg 297 writing mapping for %s
|
||||
|
||||
END_FOR;
|
||||
ON_ERROR
|
||||
general_on_error();
|
||||
END_ERROR;
|
||||
}
|
||||
else if (tdgbl->runtimeODS >= DB_VERSION_DDL11_2)
|
||||
{
|
||||
FOR (REQUEST_HANDLE req_handle)
|
||||
X IN RDB$ROLES
|
||||
WITH X.RDB$ROLE_NAME EQ ADMIN_ROLE
|
||||
|
||||
if (X.RDB$SYSTEM_FLAG == (ROLE_FLAG_MAY_TRUST | ROLE_FLAG_DBO))
|
||||
if (X.RDB$SYSTEM_FLAG == ROLE_FLAG_DBO)
|
||||
{
|
||||
put(tdgbl, rec_mapping);
|
||||
//put_text(att_map_os, DOMAIN-ADMINS, strlen(DOMAIN-ADMINS) + 1);
|
||||
|
@ -683,7 +683,7 @@ int gbak(Firebird::UtilSvc* uSvc)
|
||||
}
|
||||
tdgbl->gbl_sw_user = argv[itr];
|
||||
break;
|
||||
case IN_SW_BURP_TRUSTED_USER:
|
||||
/* case IN_SW_BURP_TRUSTED_USER:
|
||||
uSvc->checkService();
|
||||
if (++itr >= argc)
|
||||
{
|
||||
@ -692,7 +692,7 @@ int gbak(Firebird::UtilSvc* uSvc)
|
||||
}
|
||||
tdgbl->gbl_sw_tr_user = argv[itr];
|
||||
break;
|
||||
case IN_SW_BURP_ROLE:
|
||||
*/ case IN_SW_BURP_ROLE:
|
||||
if (++itr >= argc)
|
||||
{
|
||||
BURP_error(253, true);
|
||||
@ -1029,7 +1029,7 @@ int gbak(Firebird::UtilSvc* uSvc)
|
||||
}
|
||||
break;
|
||||
|
||||
case IN_SW_BURP_TRUSTED_USER:
|
||||
/* case IN_SW_BURP_TRUSTED_USER:
|
||||
uSvc->checkService();
|
||||
if (!authBlock)
|
||||
{
|
||||
@ -1046,7 +1046,7 @@ int gbak(Firebird::UtilSvc* uSvc)
|
||||
dpb.insertString(isc_dpb_trusted_role, ADMIN_ROLE, strlen(ADMIN_ROLE));
|
||||
}
|
||||
break;
|
||||
|
||||
*/
|
||||
#ifdef TRUSTED_AUTH
|
||||
case IN_SW_BURP_TRUSTED_AUTH:
|
||||
if (!dpb.find(isc_dpb_trusted_auth))
|
||||
|
@ -596,10 +596,16 @@ enum att_type {
|
||||
att_coll_owner_name,
|
||||
|
||||
// Names mapping
|
||||
att_map_os = SERIES,
|
||||
att_map_user,
|
||||
att_map_role,
|
||||
att_auto_map_role,
|
||||
att_map_name = SERIES,
|
||||
att_map_using,
|
||||
att_map_plugin,
|
||||
att_auto_map_role, // Keep it at pos.4 - ODS11.2 compatibility issue
|
||||
att_map_db,
|
||||
att_map_from_type,
|
||||
att_map_from,
|
||||
att_map_to_type,
|
||||
att_map_to,
|
||||
att_map_description,
|
||||
|
||||
// Package attributes
|
||||
att_package_name = SERIES,
|
||||
|
@ -171,8 +171,8 @@ static const Switches::in_sw_tab_t reference_burp_in_sw_table[] =
|
||||
{IN_SW_BURP_TRUSTED_AUTH, 0, "TRUSTED", 0, 0, 0, false, 295, 3, NULL, boGeneral},
|
||||
// msg 295: @1TRU(STED) use trusted authentication
|
||||
#endif
|
||||
{IN_SW_BURP_TRUSTED_USER, 0, TRUSTED_USER_SWITCH, 0, 0, 0, false, 0, TRUSTED_USER_SWITCH_LEN, NULL, boGeneral},
|
||||
{IN_SW_BURP_TRUSTED_ROLE, 0, TRUSTED_ROLE_SWITCH, 0, 0, 0, false, 0, TRUSTED_ROLE_SWITCH_LEN, NULL, boGeneral},
|
||||
// {IN_SW_BURP_TRUSTED_USER, 0, TRUSTED_USER_SWITCH, 0, 0, 0, false, 0, TRUSTED_USER_SWITCH_LEN, NULL, boGeneral},
|
||||
// {IN_SW_BURP_TRUSTED_ROLE, 0, TRUSTED_ROLE_SWITCH, 0, 0, 0, false, 0, TRUSTED_ROLE_SWITCH_LEN, NULL, boGeneral},
|
||||
/*
|
||||
{IN_SW_BURP_U, 0, "UNPROTECTED", 0, 0, 0, false, 0, 5, NULL, boGeneral},
|
||||
*/
|
||||
|
@ -54,6 +54,7 @@
|
||||
#include "../common/utils_proto.h"
|
||||
#include "memory_routines.h"
|
||||
#include "../burp/OdsDetection.h"
|
||||
#include "../auth/trusted/AuthSspi.h"
|
||||
|
||||
using MsgFormat::SafeArg;
|
||||
|
||||
@ -7971,38 +7972,156 @@ bool get_mapping(BurpGlobals* tdgbl)
|
||||
*
|
||||
* Functional description
|
||||
* Restore mapping to users and roles
|
||||
* Restricted version - only single
|
||||
* mapping is accepted
|
||||
*
|
||||
**************************************/
|
||||
att_type attribute;
|
||||
scan_attr_t scan_next_attr;
|
||||
TEXT temp[GDS_NAME_LEN];
|
||||
SSHORT l;
|
||||
Firebird::string role, os;
|
||||
Firebird::string role;
|
||||
|
||||
if (tdgbl->runtimeODS >= DB_VERSION_DDL11_1)
|
||||
if (tdgbl->runtimeODS >= DB_VERSION_DDL12)
|
||||
{
|
||||
STORE (REQUEST_HANDLE tdgbl->handles_get_mapping_req_handle1)
|
||||
M IN RDB$MAP
|
||||
|
||||
M.RDB$MAP_TO_TYPE.NULL = TRUE;
|
||||
M.RDB$MAP_NAME.NULL = TRUE;
|
||||
M.RDB$MAP_USING.NULL = TRUE;
|
||||
M.RDB$MAP_PLUGIN.NULL = TRUE;
|
||||
M.RDB$MAP_DB.NULL = TRUE;
|
||||
M.RDB$MAP_FROM_TYPE.NULL = TRUE;
|
||||
M.RDB$MAP_FROM.NULL = TRUE;
|
||||
M.RDB$MAP_TO.NULL = TRUE;
|
||||
M.RDB$DESCRIPTION.NULL = TRUE;
|
||||
|
||||
skip_init(&scan_next_attr);
|
||||
while (skip_scan(&scan_next_attr), get_attribute(&attribute, tdgbl) != att_end)
|
||||
{
|
||||
switch (attribute)
|
||||
{
|
||||
case att_auto_map_role:
|
||||
GET_TEXT(temp);
|
||||
M.RDB$MAP_NAME.NULL = FALSE;
|
||||
strcpy(M.RDB$MAP_NAME, "AutoAdminImplementationMapping");
|
||||
M.RDB$MAP_FROM.NULL = FALSE;
|
||||
strcpy(M.RDB$MAP_FROM, FB_DOMAIN_ANY_RID_ADMINS);
|
||||
M.RDB$MAP_FROM_TYPE.NULL = FALSE;
|
||||
strcpy(M.RDB$MAP_FROM_TYPE, FB_PREDEFINED_GROUP);
|
||||
M.RDB$MAP_USING.NULL = FALSE;
|
||||
strcpy(M.RDB$MAP_USING, "P");
|
||||
M.RDB$MAP_PLUGIN.NULL = FALSE;
|
||||
strcpy(M.RDB$MAP_PLUGIN, "Win_Sspi");
|
||||
M.RDB$MAP_TO_TYPE.NULL = FALSE;
|
||||
M.RDB$MAP_TO_TYPE = 1;
|
||||
M.RDB$MAP_TO.NULL = FALSE;
|
||||
strcpy(M.RDB$MAP_TO, ADMIN_ROLE);
|
||||
|
||||
BURP_verbose(301);
|
||||
// msg 301, restoring names mapping
|
||||
BURP_verbose (298, M.RDB$MAP_NAME);
|
||||
break;
|
||||
|
||||
case att_map_name:
|
||||
M.RDB$MAP_NAME.NULL = FALSE;
|
||||
GET_TEXT(M.RDB$MAP_NAME);
|
||||
if (tdgbl->firstMap)
|
||||
{
|
||||
tdgbl->firstMap = false;
|
||||
BURP_verbose(301);
|
||||
// msg 301, restoring names mapping
|
||||
}
|
||||
BURP_verbose (298, M.RDB$MAP_NAME);
|
||||
break;
|
||||
|
||||
case att_map_using:
|
||||
M.RDB$MAP_USING.NULL = FALSE;
|
||||
GET_TEXT(M.RDB$MAP_USING);
|
||||
break;
|
||||
|
||||
case att_map_plugin:
|
||||
M.RDB$MAP_PLUGIN.NULL = FALSE;
|
||||
GET_TEXT(M.RDB$MAP_PLUGIN);
|
||||
break;
|
||||
|
||||
case att_map_db:
|
||||
M.RDB$MAP_DB.NULL = FALSE;
|
||||
GET_TEXT(M.RDB$MAP_DB);
|
||||
break;
|
||||
|
||||
case att_map_from_type:
|
||||
M.RDB$MAP_FROM_TYPE.NULL = FALSE;
|
||||
GET_TEXT(M.RDB$MAP_FROM_TYPE);
|
||||
break;
|
||||
|
||||
case att_map_from:
|
||||
M.RDB$MAP_FROM.NULL = FALSE;
|
||||
GET_TEXT(M.RDB$MAP_FROM);
|
||||
break;
|
||||
|
||||
case att_map_to_type:
|
||||
M.RDB$MAP_TO_TYPE.NULL = FALSE;
|
||||
M.RDB$MAP_TO_TYPE = (USHORT) get_int32(tdgbl);
|
||||
break;
|
||||
|
||||
case att_map_to:
|
||||
M.RDB$MAP_TO.NULL = FALSE;
|
||||
GET_TEXT(M.RDB$MAP_TO);
|
||||
break;
|
||||
|
||||
case att_map_description:
|
||||
M.RDB$DESCRIPTION.NULL = FALSE;
|
||||
get_source_blob (tdgbl, M.RDB$DESCRIPTION, false);
|
||||
break;
|
||||
|
||||
default:
|
||||
// msg 299 name mapping
|
||||
bad_attribute(scan_next_attr, attribute, 299);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (M.RDB$MAP_NAME.NULL || M.RDB$MAP_USING.NULL ||
|
||||
M.RDB$MAP_FROM_TYPE.NULL || M.RDB$MAP_TO_TYPE.NULL)
|
||||
{
|
||||
// msg 353 required mapping attributes are missing in backup file
|
||||
BURP_error(353, true);
|
||||
}
|
||||
|
||||
END_STORE;
|
||||
ON_ERROR
|
||||
general_on_error ();
|
||||
END_ERROR;
|
||||
}
|
||||
else if (tdgbl->runtimeODS >= DB_VERSION_DDL11_1)
|
||||
{
|
||||
skip_init(&scan_next_attr);
|
||||
while (skip_scan(&scan_next_attr), get_attribute(&attribute, tdgbl) != att_end)
|
||||
{
|
||||
switch (attribute)
|
||||
{
|
||||
/* case att_map_role:
|
||||
l = GET_TEXT(temp);
|
||||
role.assign(temp, l);
|
||||
break;
|
||||
|
||||
case att_map_os:
|
||||
l = GET_TEXT(temp);
|
||||
os.assign(temp, l);
|
||||
break;
|
||||
*/
|
||||
case att_auto_map_role:
|
||||
l = GET_TEXT(temp);
|
||||
role.assign(temp, l);
|
||||
break;
|
||||
|
||||
case att_map_to_type:
|
||||
get_int32(tdgbl);
|
||||
break;
|
||||
|
||||
case att_map_name:
|
||||
case att_map_using:
|
||||
case att_map_plugin:
|
||||
case att_map_db:
|
||||
case att_map_from_type:
|
||||
case att_map_from:
|
||||
case att_map_to:
|
||||
GET_TEXT(temp);
|
||||
break;
|
||||
|
||||
case att_map_description:
|
||||
eat_blob(tdgbl);
|
||||
|
||||
default:
|
||||
// msg 299 name mapping
|
||||
bad_attribute(scan_next_attr, attribute, 299);
|
||||
@ -8015,24 +8134,25 @@ bool get_mapping(BurpGlobals* tdgbl)
|
||||
return true; // silently skip attributes on old server
|
||||
}
|
||||
|
||||
if (role != ADMIN_ROLE)
|
||||
{
|
||||
BURP_error(300, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (tdgbl->firstMap)
|
||||
{
|
||||
tdgbl->firstMap = false;
|
||||
BURP_verbose(301);
|
||||
// msg 301, restoring names mapping
|
||||
}
|
||||
|
||||
if (role != ADMIN_ROLE)
|
||||
{
|
||||
BURP_error(300, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
BURP_verbose(298, ADMIN_ROLE);
|
||||
// msg 298, restoring map @1
|
||||
Firebird::string sql;
|
||||
sql.printf("%s ('%s', %d) %s",
|
||||
"UPDATE OR INSERT INTO RDB$ROLES(RDB$ROLE_NAME, RDB$SYSTEM_FLAG) VALUES",
|
||||
ADMIN_ROLE, ROLE_FLAG_MAY_TRUST | ROLE_FLAG_DBO,
|
||||
ADMIN_ROLE, ROLE_FLAG_DBO,
|
||||
"MATCHING (RDB$ROLE_NAME)");
|
||||
isc_dsql_execute_immediate(tdgbl->status_vector, &tdgbl->db_handle, &tdgbl->tr_handle,
|
||||
sql.length(), sql.c_str(), 1, NULL);
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "../jrd/ibase.h"
|
||||
#include "../common/classes/ImplementHelper.h"
|
||||
#include "../common/utils_proto.h"
|
||||
#include "../common/db_alias.h"
|
||||
|
||||
using namespace Firebird;
|
||||
|
||||
@ -38,7 +39,7 @@ namespace Auth {
|
||||
WriterImplementation::WriterImplementation()
|
||||
: current(*getDefaultMemoryPool(), ClumpletReader::WideUnTagged, MAX_DPB_SIZE),
|
||||
result(*getDefaultMemoryPool(), ClumpletReader::WideUnTagged, MAX_DPB_SIZE),
|
||||
method(*getDefaultMemoryPool()),
|
||||
plugin(*getDefaultMemoryPool()), type(*getDefaultMemoryPool()),
|
||||
sequence(0)
|
||||
{ }
|
||||
|
||||
@ -65,16 +66,17 @@ void WriterImplementation::add(const char* name)
|
||||
|
||||
current.clear();
|
||||
current.insertString(AuthReader::AUTH_NAME, name);
|
||||
fb_assert(method.hasData());
|
||||
if (method.hasData())
|
||||
fb_assert(plugin.hasData());
|
||||
if (plugin.hasData())
|
||||
{
|
||||
current.insertString(AuthReader::AUTH_METHOD, method);
|
||||
current.insertString(AuthReader::AUTH_PLUGIN, plugin);
|
||||
}
|
||||
type = "USER";
|
||||
}
|
||||
|
||||
void WriterImplementation::setMethod(const char* m)
|
||||
void WriterImplementation::setPlugin(const char* m)
|
||||
{
|
||||
method = m;
|
||||
plugin = m;
|
||||
}
|
||||
|
||||
void WriterImplementation::putLevel()
|
||||
@ -84,15 +86,24 @@ void WriterImplementation::putLevel()
|
||||
{
|
||||
return;
|
||||
}
|
||||
current.insertString(AuthReader::AUTH_TYPE, type);
|
||||
|
||||
result.insertBytes(sequence++, current.getBuffer(), current.getBufferLength());
|
||||
}
|
||||
|
||||
void WriterImplementation::setAttribute(unsigned char tag, const char* value)
|
||||
void WriterImplementation::setType(const char* value)
|
||||
{
|
||||
if (value)
|
||||
type = value;
|
||||
}
|
||||
|
||||
void WriterImplementation::setDb(const char* value)
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
current.insertString(tag, value);
|
||||
PathName target;
|
||||
expandDatabaseName(value, target, NULL);
|
||||
current.insertPath(AuthReader::AUTH_SECURE_DB, target);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,16 +45,17 @@ public:
|
||||
WriterImplementation();
|
||||
|
||||
void store(Firebird::ClumpletWriter* to, unsigned char tag);
|
||||
void setMethod(const char* m);
|
||||
void setPlugin(const char* m);
|
||||
|
||||
// IWriter implementation
|
||||
void FB_CARG reset();
|
||||
void FB_CARG add(const char* name);
|
||||
void FB_CARG setAttribute(unsigned char tag, const char* value);
|
||||
void FB_CARG setType(const char* value);
|
||||
void FB_CARG setDb(const char* value);
|
||||
|
||||
private:
|
||||
Firebird::ClumpletWriter current, result;
|
||||
Firebird::string method;
|
||||
Firebird::string plugin, type;
|
||||
unsigned int sequence;
|
||||
|
||||
void putLevel();
|
||||
|
@ -29,234 +29,246 @@
|
||||
#include "../common/StatusHolder.h"
|
||||
#include "../jrd/align.h"
|
||||
|
||||
using namespace Firebird;
|
||||
namespace Firebird {
|
||||
|
||||
namespace {
|
||||
|
||||
class MetadataBuilder FB_FINAL : public RefCntIface<IMetadataBuilder, FB_METADATA_BUILDER_VERSION>
|
||||
MetadataBuilder::MetadataBuilder(const MsgMetadata* from)
|
||||
: msgMetadata(new MsgMetadata)
|
||||
{
|
||||
public:
|
||||
MetadataBuilder(const MsgMetadata* from)
|
||||
: msgMetadata(new MsgMetadata)
|
||||
msgMetadata->items = from->items;
|
||||
}
|
||||
|
||||
MetadataBuilder::MetadataBuilder(unsigned fieldCount)
|
||||
: msgMetadata(new MsgMetadata)
|
||||
{
|
||||
if (fieldCount)
|
||||
msgMetadata->items.grow(fieldCount);
|
||||
}
|
||||
|
||||
int FB_CARG MetadataBuilder::release()
|
||||
{
|
||||
if (--refCounter != 0)
|
||||
{
|
||||
msgMetadata->items = from->items;
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual int FB_CARG release()
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void FB_CARG MetadataBuilder::setType(IStatus* status, unsigned index, unsigned type)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (--refCounter != 0)
|
||||
MutexLockGuard g(mtx, FB_FUNCTION);
|
||||
|
||||
indexError(index, "setType");
|
||||
msgMetadata->items[index].type = type;
|
||||
if (!msgMetadata->items[index].length)
|
||||
{
|
||||
return 1;
|
||||
unsigned dtype;
|
||||
fb_utils::sqlTypeToDsc(0, type, 0, &dtype, NULL, NULL, NULL);
|
||||
if (dtype < DTYPE_TYPE_MAX)
|
||||
msgMetadata->items[index].length = type_lengths[dtype];
|
||||
}
|
||||
|
||||
delete this;
|
||||
return 0;
|
||||
// Setting type & length is enough for an item to be ready for use
|
||||
if (msgMetadata->items[index].length)
|
||||
msgMetadata->items[index].finished = true;
|
||||
}
|
||||
|
||||
// IMetadataBuilder implementation
|
||||
|
||||
virtual void FB_CARG setType(IStatus* status, unsigned index, unsigned type)
|
||||
catch (const Exception& ex)
|
||||
{
|
||||
try
|
||||
{
|
||||
MutexLockGuard g(mtx, FB_FUNCTION);
|
||||
ex.stuffException(status);
|
||||
}
|
||||
}
|
||||
|
||||
indexError(index, "setType");
|
||||
msgMetadata->items[index].type = type;
|
||||
if (!msgMetadata->items[index].length)
|
||||
void FB_CARG MetadataBuilder::setSubType(IStatus* status, unsigned index, int subType)
|
||||
{
|
||||
try
|
||||
{
|
||||
MutexLockGuard g(mtx, FB_FUNCTION);
|
||||
|
||||
indexError(index, "setSubType");
|
||||
msgMetadata->items[index].subType = subType;
|
||||
}
|
||||
catch (const Exception& ex)
|
||||
{
|
||||
ex.stuffException(status);
|
||||
}
|
||||
}
|
||||
|
||||
void FB_CARG MetadataBuilder::setLength(IStatus* status, unsigned index, unsigned length)
|
||||
{
|
||||
try
|
||||
{
|
||||
MutexLockGuard g(mtx, FB_FUNCTION);
|
||||
indexError(index, "setLength");
|
||||
msgMetadata->items[index].length = length;
|
||||
|
||||
// Setting type & length is enough for an item to be ready for use
|
||||
if (msgMetadata->items[index].type)
|
||||
msgMetadata->items[index].finished = true;
|
||||
}
|
||||
catch (const Exception& ex)
|
||||
{
|
||||
ex.stuffException(status);
|
||||
}
|
||||
}
|
||||
|
||||
void FB_CARG MetadataBuilder::setCharSet(IStatus* status, unsigned index, unsigned charSet)
|
||||
{
|
||||
try
|
||||
{
|
||||
MutexLockGuard g(mtx, FB_FUNCTION);
|
||||
|
||||
indexError(index, "setCharSet");
|
||||
msgMetadata->items[index].charSet = charSet;
|
||||
}
|
||||
catch (const Exception& ex)
|
||||
{
|
||||
ex.stuffException(status);
|
||||
}
|
||||
}
|
||||
|
||||
void FB_CARG MetadataBuilder::setScale(IStatus* status, unsigned index, unsigned scale)
|
||||
{
|
||||
try
|
||||
{
|
||||
MutexLockGuard g(mtx, FB_FUNCTION);
|
||||
|
||||
indexError(index, "setScale");
|
||||
msgMetadata->items[index].scale = scale;
|
||||
}
|
||||
catch (const Exception& ex)
|
||||
{
|
||||
ex.stuffException(status);
|
||||
}
|
||||
}
|
||||
|
||||
void FB_CARG MetadataBuilder::truncate(IStatus* status, unsigned count)
|
||||
{
|
||||
try
|
||||
{
|
||||
MutexLockGuard g(mtx, FB_FUNCTION);
|
||||
|
||||
if (count != 0)
|
||||
indexError(count - 1, "truncate");
|
||||
|
||||
msgMetadata->items.shrink(count);
|
||||
}
|
||||
catch (const Exception& ex)
|
||||
{
|
||||
ex.stuffException(status);
|
||||
}
|
||||
}
|
||||
|
||||
void FB_CARG MetadataBuilder::remove(IStatus* status, unsigned index)
|
||||
{
|
||||
try
|
||||
{
|
||||
MutexLockGuard g(mtx, FB_FUNCTION);
|
||||
|
||||
indexError(index, "remove");
|
||||
|
||||
msgMetadata->items.remove(index);
|
||||
}
|
||||
catch (const Exception& ex)
|
||||
{
|
||||
ex.stuffException(status);
|
||||
}
|
||||
}
|
||||
|
||||
void FB_CARG MetadataBuilder::moveNameToIndex(IStatus* status, const char* name, unsigned index)
|
||||
{
|
||||
try
|
||||
{
|
||||
MutexLockGuard g(mtx, FB_FUNCTION);
|
||||
|
||||
indexError(index, "moveNameToIndex");
|
||||
|
||||
for (ObjectsArray<MsgMetadata::Item>::iterator i = msgMetadata->items.begin();
|
||||
i != msgMetadata->items.end();
|
||||
++i)
|
||||
{
|
||||
if (i->field == name)
|
||||
{
|
||||
unsigned dtype;
|
||||
fb_utils::sqlTypeToDsc(0, type, 0, &dtype, NULL, NULL, NULL);
|
||||
if (dtype < DTYPE_TYPE_MAX)
|
||||
msgMetadata->items[index].length = type_lengths[dtype];
|
||||
MsgMetadata::Item copy(getPool(), *i);
|
||||
msgMetadata->items.remove(i);
|
||||
msgMetadata->items.insert(index, copy);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Setting type & length is enough for an item to be ready for use
|
||||
if (msgMetadata->items[index].length)
|
||||
msgMetadata->items[index].finished = true;
|
||||
}
|
||||
catch (const Exception& ex)
|
||||
{
|
||||
ex.stuffException(status);
|
||||
}
|
||||
(Arg::Gds(isc_random) << (string("Name not found in IMetadataBuilder: ") + name)).raise();
|
||||
}
|
||||
|
||||
virtual void FB_CARG setSubType(IStatus* status, unsigned index, int subType)
|
||||
catch (const Exception& ex)
|
||||
{
|
||||
try
|
||||
{
|
||||
MutexLockGuard g(mtx, FB_FUNCTION);
|
||||
|
||||
indexError(index, "setSubType");
|
||||
msgMetadata->items[index].subType = subType;
|
||||
}
|
||||
catch (const Exception& ex)
|
||||
{
|
||||
ex.stuffException(status);
|
||||
}
|
||||
ex.stuffException(status);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void FB_CARG setLength(IStatus* status, unsigned index, unsigned length)
|
||||
unsigned FB_CARG MetadataBuilder::addField(IStatus* status)
|
||||
{
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
MutexLockGuard g(mtx, FB_FUNCTION);
|
||||
MutexLockGuard g(mtx, FB_FUNCTION);
|
||||
|
||||
indexError(index, "setLength");
|
||||
msgMetadata->items[index].length = length;
|
||||
metadataError("addField");
|
||||
|
||||
// Setting type & length is enough for an item to be ready for use
|
||||
if (msgMetadata->items[index].type)
|
||||
msgMetadata->items[index].finished = true;
|
||||
}
|
||||
catch (const Exception& ex)
|
||||
{
|
||||
ex.stuffException(status);
|
||||
}
|
||||
msgMetadata->items.add();
|
||||
return msgMetadata->items.getCount() - 1;
|
||||
}
|
||||
|
||||
virtual void FB_CARG setCharSet(IStatus* status, unsigned index, unsigned charSet)
|
||||
catch (const Exception& ex)
|
||||
{
|
||||
try
|
||||
{
|
||||
MutexLockGuard g(mtx, FB_FUNCTION);
|
||||
|
||||
indexError(index, "setCharSet");
|
||||
msgMetadata->items[index].charSet = charSet;
|
||||
}
|
||||
catch (const Exception& ex)
|
||||
{
|
||||
ex.stuffException(status);
|
||||
}
|
||||
ex.stuffException(status);
|
||||
return ~0;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void FB_CARG setScale(IStatus* status, unsigned index, unsigned scale)
|
||||
IMessageMetadata* FB_CARG MetadataBuilder::getMetadata(IStatus* status)
|
||||
{
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
MutexLockGuard g(mtx, FB_FUNCTION);
|
||||
MutexLockGuard g(mtx, FB_FUNCTION);
|
||||
|
||||
indexError(index, "setScale");
|
||||
msgMetadata->items[index].scale = scale;
|
||||
}
|
||||
catch (const Exception& ex)
|
||||
metadataError("getMetadata");
|
||||
|
||||
unsigned i = msgMetadata->makeOffsets();
|
||||
if (i != ~0u)
|
||||
{
|
||||
ex.stuffException(status);
|
||||
(Arg::Gds(isc_item_finish) << Arg::Num(i)).raise();
|
||||
}
|
||||
|
||||
IMessageMetadata* rc = msgMetadata;
|
||||
rc->addRef();
|
||||
msgMetadata = NULL;
|
||||
return rc;
|
||||
}
|
||||
|
||||
virtual void FB_CARG truncate(IStatus* status, unsigned count)
|
||||
catch (const Exception& ex)
|
||||
{
|
||||
try
|
||||
{
|
||||
MutexLockGuard g(mtx, FB_FUNCTION);
|
||||
|
||||
if (count != 0)
|
||||
indexError(count - 1, "truncate");
|
||||
|
||||
msgMetadata->items.shrink(count);
|
||||
}
|
||||
catch (const Exception& ex)
|
||||
{
|
||||
ex.stuffException(status);
|
||||
}
|
||||
ex.stuffException(status);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
virtual void FB_CARG remove(IStatus* status, unsigned index)
|
||||
void MetadataBuilder::metadataError(const char* functionName)
|
||||
{
|
||||
if (!msgMetadata)
|
||||
{
|
||||
try
|
||||
{
|
||||
MutexLockGuard g(mtx, FB_FUNCTION);
|
||||
|
||||
indexError(index, "remove");
|
||||
|
||||
msgMetadata->items.remove(index);
|
||||
}
|
||||
catch (const Exception& ex)
|
||||
{
|
||||
ex.stuffException(status);
|
||||
}
|
||||
(Arg::Gds(isc_random) << (string("IMetadataBuilder interface is already inactive: "
|
||||
"IMetadataBuilder::") + functionName)).raise();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void FB_CARG moveNameToIndex(IStatus* status, const char* name, unsigned index)
|
||||
void MetadataBuilder::indexError(unsigned index, const char* functionName)
|
||||
{
|
||||
metadataError(functionName);
|
||||
|
||||
if (index >= msgMetadata->items.getCount())
|
||||
{
|
||||
try
|
||||
{
|
||||
MutexLockGuard g(mtx, FB_FUNCTION);
|
||||
|
||||
indexError(index, "moveNameToIndex");
|
||||
|
||||
for (ObjectsArray<MsgMetadata::Item>::iterator i = msgMetadata->items.begin();
|
||||
i != msgMetadata->items.end();
|
||||
++i)
|
||||
{
|
||||
if (i->field == name)
|
||||
{
|
||||
MsgMetadata::Item copy(getPool(), *i);
|
||||
msgMetadata->items.remove(i);
|
||||
msgMetadata->items.insert(index, copy);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
(Arg::Gds(isc_random) << (string("Name not found in IMetadataBuilder: ") + name)).raise();
|
||||
}
|
||||
catch (const Exception& ex)
|
||||
{
|
||||
ex.stuffException(status);
|
||||
}
|
||||
(Arg::Gds(isc_invalid_index_val) << Arg::Num(index) << (string("IMetadataBuilder::") +
|
||||
functionName)).raise();
|
||||
}
|
||||
|
||||
virtual IMessageMetadata* FB_CARG getMetadata(IStatus* status)
|
||||
{
|
||||
try
|
||||
{
|
||||
MutexLockGuard g(mtx, FB_FUNCTION);
|
||||
|
||||
metadataError("getMetadata");
|
||||
|
||||
unsigned i = msgMetadata->makeOffsets();
|
||||
if (i != ~0u)
|
||||
{
|
||||
(Arg::Gds(isc_item_finish) << Arg::Num(i)).raise();
|
||||
}
|
||||
|
||||
IMessageMetadata* rc = msgMetadata;
|
||||
rc->addRef();
|
||||
msgMetadata = NULL;
|
||||
return rc;
|
||||
}
|
||||
catch (const Exception& ex)
|
||||
{
|
||||
ex.stuffException(status);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<MsgMetadata> msgMetadata;
|
||||
Mutex mtx;
|
||||
|
||||
void metadataError(const char* functionName)
|
||||
{
|
||||
if (!msgMetadata)
|
||||
{
|
||||
(Arg::Gds(isc_random) << (string("IMetadataBuilder interface is already inactive: "
|
||||
"IMetadataBuilder::") + functionName)).raise();
|
||||
}
|
||||
}
|
||||
|
||||
void indexError(unsigned index, const char* functionName)
|
||||
{
|
||||
metadataError(functionName);
|
||||
|
||||
if (index >= msgMetadata->items.getCount())
|
||||
{
|
||||
(Arg::Gds(isc_invalid_index_val) << Arg::Num(index) << (string("IMetadataBuilder::") +
|
||||
functionName)).raise();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void check(IStatus* status)
|
||||
{
|
||||
@ -266,11 +278,6 @@ void check(IStatus* status)
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace anonymous
|
||||
|
||||
|
||||
namespace Firebird {
|
||||
|
||||
|
||||
// Add an item based on a descriptor.
|
||||
void MsgMetadata::addItem(const MetaName& name, bool nullable, const dsc& desc)
|
||||
|
@ -256,6 +256,34 @@ public:
|
||||
RefPtr<IAttachment> attachment;
|
||||
};
|
||||
|
||||
class MetadataBuilder FB_FINAL : public RefCntIface<IMetadataBuilder, FB_METADATA_BUILDER_VERSION>
|
||||
{
|
||||
public:
|
||||
MetadataBuilder(const MsgMetadata* from);
|
||||
MetadataBuilder(unsigned fieldCount);
|
||||
|
||||
virtual int FB_CARG release();
|
||||
|
||||
// IMetadataBuilder implementation
|
||||
virtual void FB_CARG setType(IStatus* status, unsigned index, unsigned type);
|
||||
virtual void FB_CARG setSubType(IStatus* status, unsigned index, int subType);
|
||||
virtual void FB_CARG setLength(IStatus* status, unsigned index, unsigned length);
|
||||
virtual void FB_CARG setCharSet(IStatus* status, unsigned index, unsigned charSet);
|
||||
virtual void FB_CARG setScale(IStatus* status, unsigned index, unsigned scale);
|
||||
virtual void FB_CARG truncate(IStatus* status, unsigned count);
|
||||
virtual void FB_CARG remove(IStatus* status, unsigned index);
|
||||
virtual void FB_CARG moveNameToIndex(IStatus* status, const char* name, unsigned index);
|
||||
virtual unsigned FB_CARG addField(IStatus* status);
|
||||
virtual IMessageMetadata* FB_CARG getMetadata(IStatus* status);
|
||||
|
||||
private:
|
||||
RefPtr<MsgMetadata> msgMetadata;
|
||||
Mutex mtx;
|
||||
|
||||
void metadataError(const char* functionName);
|
||||
void indexError(unsigned index, const char* functionName);
|
||||
};
|
||||
|
||||
} // namespace Firebird
|
||||
|
||||
#endif // COMMON_MSG_METADATA_H
|
||||
|
@ -273,6 +273,13 @@ OsError::OsError() throw() :
|
||||
#else
|
||||
Base(isc_arg_unix, errno) { }
|
||||
#endif
|
||||
|
||||
OsError::OsError(ISC_STATUS s) throw() :
|
||||
#ifdef WIN_NT
|
||||
Base(isc_arg_win32, s) { }
|
||||
#else
|
||||
Base(isc_arg_unix, s) { }
|
||||
#endif
|
||||
} // namespace Arg
|
||||
|
||||
} // namespace Firebird
|
||||
|
@ -274,6 +274,7 @@ class OsError : public Base
|
||||
{
|
||||
public:
|
||||
OsError() throw();
|
||||
explicit OsError(ISC_STATUS s) throw();
|
||||
};
|
||||
|
||||
} // namespace Arg
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "fb_exception.h"
|
||||
|
||||
#include "../jrd/ibase.h"
|
||||
#include "firebird/Auth.h"
|
||||
|
||||
#ifdef DEBUG_CLUMPLETS
|
||||
#include "../yvalve/gds_proto.h"
|
||||
@ -827,48 +828,44 @@ AuthReader::AuthReader(const AuthBlock& authBlock)
|
||||
rewind();
|
||||
}
|
||||
|
||||
bool AuthReader::getInfo(string* name, string* method, PathName* secureDb)
|
||||
static inline void erase(NoCaseString& s)
|
||||
{
|
||||
s.erase();
|
||||
}
|
||||
|
||||
static inline void set(NoCaseString& s, const ClumpletReader& rdr)
|
||||
{
|
||||
s.assign(rdr.getBytes(), rdr.getClumpLength());
|
||||
}
|
||||
|
||||
bool AuthReader::getInfo(Info& info)
|
||||
{
|
||||
if (isEof())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (name)
|
||||
{
|
||||
*name = "";
|
||||
}
|
||||
if (method)
|
||||
{
|
||||
*method = "";
|
||||
}
|
||||
if (secureDb)
|
||||
{
|
||||
*secureDb = "";
|
||||
}
|
||||
erase(info.type);
|
||||
erase(info.name);
|
||||
erase(info.plugin);
|
||||
erase(info.secDb);
|
||||
|
||||
ClumpletReader internal(WideUnTagged, getBytes(), getClumpLength());
|
||||
for (internal.rewind(); !internal.isEof(); internal.moveNext())
|
||||
{
|
||||
switch(internal.getClumpTag())
|
||||
{
|
||||
case AUTH_NAME:
|
||||
if (name)
|
||||
{
|
||||
internal.getString(*name);
|
||||
}
|
||||
case AUTH_TYPE:
|
||||
set(info.type, internal);
|
||||
break;
|
||||
case AUTH_METHOD:
|
||||
if (method)
|
||||
{
|
||||
internal.getString(*method);
|
||||
}
|
||||
case AUTH_NAME:
|
||||
set(info.name, internal);
|
||||
break;
|
||||
case AUTH_PLUGIN:
|
||||
set(info.plugin, internal);
|
||||
break;
|
||||
case AUTH_SECURE_DB:
|
||||
if (secureDb)
|
||||
{
|
||||
internal.getPath(*secureDb);
|
||||
}
|
||||
set(info.secDb, internal);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -887,12 +884,12 @@ void dumpAuthBlock(const char* text, ClumpletReader* pb, unsigned char param)
|
||||
Firebird::AuthReader::AuthBlock tmp;
|
||||
tmp.assign(pb->getBytes(), pb->getClumpLength());
|
||||
Firebird::AuthReader rdr(tmp);
|
||||
string name, method;
|
||||
string name, plugin;
|
||||
PathName secureDb;
|
||||
bool x = false;
|
||||
while (rdr.getInfo(&name, &method, &secureDb))
|
||||
while (rdr.getInfo(&name, &plugin, &secureDb))
|
||||
{
|
||||
fprintf(stderr, " %s::%s::%s", name.c_str(), method.c_str(), secureDb.c_str());
|
||||
fprintf(stderr, " %s::%s::%s", name.c_str(), plugin.c_str(), secureDb.c_str());
|
||||
x = true;
|
||||
rdr.moveNext();
|
||||
}
|
||||
|
@ -185,20 +185,29 @@ public:
|
||||
class AuthReader : public ClumpletReader
|
||||
{
|
||||
public:
|
||||
static const unsigned char AUTH_NAME = 1; // name described by it's type
|
||||
static const unsigned char AUTH_PLUGIN = 2; // plugin which added a record
|
||||
static const unsigned char AUTH_TYPE = 3; // it can be user/group/role/etc. - what plugin sets
|
||||
static const unsigned char AUTH_SECURE_DB = 4; // sec. db in which context record was added
|
||||
// missing when plugin is server-wide
|
||||
typedef Array<UCHAR> AuthBlock;
|
||||
|
||||
// name and method are required attributes for any record
|
||||
// name is set by plugin when it calls add()
|
||||
static const unsigned char AUTH_NAME = 0;
|
||||
// method is just a name of plugin which created this record
|
||||
static const unsigned char AUTH_METHOD = 1;
|
||||
struct Info
|
||||
{
|
||||
NoCaseString type, name, plugin, secDb;
|
||||
unsigned found, current;
|
||||
|
||||
// additional attributes - only security database is used currently
|
||||
static const unsigned char AUTH_SECURE_DB = 100;
|
||||
Info()
|
||||
: found(0), current(0)
|
||||
{ }
|
||||
};
|
||||
|
||||
explicit AuthReader(const AuthBlock& authBlock);
|
||||
AuthReader(const ClumpletReader& rdr)
|
||||
: ClumpletReader(rdr)
|
||||
{ }
|
||||
|
||||
bool getInfo(string* name, string* method, PathName* secDb);
|
||||
bool getInfo(Info& info);
|
||||
};
|
||||
|
||||
//#define AUTH_BLOCK_DEBUG
|
||||
|
@ -73,11 +73,12 @@ namespace Firebird
|
||||
return hash(&value, sizeof value, hashSize);
|
||||
}
|
||||
|
||||
const static size_t DEFAULT_SIZE = 97; // largest prime number < 100
|
||||
};
|
||||
|
||||
const size_t DEFAULT_HASH_SIZE = 97; // largest prime number < 100
|
||||
|
||||
template <typename C,
|
||||
size_t HASHSIZE = DefaultHash<C>::DEFAULT_SIZE,
|
||||
size_t HASHSIZE = DEFAULT_HASH_SIZE,
|
||||
typename K = C, // default key
|
||||
typename KeyOfValue = DefaultKeyValue<C>, // default keygen
|
||||
typename F = DefaultHash<K> > // hash function definition
|
||||
@ -163,12 +164,22 @@ namespace Firebird
|
||||
}
|
||||
|
||||
~Hash()
|
||||
{
|
||||
// by default we let hash entries be cleaned by someone else
|
||||
cleanup(NULL);
|
||||
}
|
||||
|
||||
typedef void CleanupRoutine(C* toClean);
|
||||
void cleanup(CleanupRoutine* cleanupRoutine)
|
||||
{
|
||||
for (size_t n = 0; n < HASHSIZE; ++n)
|
||||
{
|
||||
while (data[n])
|
||||
{
|
||||
data[n]->unLink();
|
||||
Entry* entry = data[n];
|
||||
entry->unLink();
|
||||
if (cleanupRoutine)
|
||||
cleanupRoutine(entry->get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -347,7 +347,7 @@ static bool setPath(const PathName& filename, PathName& expandedName)
|
||||
|
||||
// Full processing of database name
|
||||
// Returns true if alias was found in databases.conf
|
||||
bool expandDatabaseName(const Firebird::PathName& alias,
|
||||
bool expandDatabaseName(Firebird::PathName alias,
|
||||
Firebird::PathName& file,
|
||||
Firebird::RefPtr<Config>* config)
|
||||
{
|
||||
@ -358,9 +358,12 @@ bool expandDatabaseName(const Firebird::PathName& alias,
|
||||
catch (const fatal_exception& ex)
|
||||
{
|
||||
gds__log("File databases.conf contains bad data: %s", ex.what());
|
||||
(Arg::Gds(isc_random) << "Server misconfigured - contact administrator please").raise();
|
||||
Arg::Gds(isc_server_misconfigured).raise();
|
||||
}
|
||||
|
||||
// remove whitespaces from database name
|
||||
alias.trim();
|
||||
|
||||
ReadLockGuard guard(aliasesConf().rwLock, "expandDatabaseName");
|
||||
|
||||
// First of all check in databases.conf
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
class Config;
|
||||
|
||||
bool expandDatabaseName(const Firebird::PathName& alias,
|
||||
bool expandDatabaseName(Firebird::PathName alias,
|
||||
Firebird::PathName& file,
|
||||
Firebird::RefPtr<Config>* config);
|
||||
|
||||
|
@ -325,7 +325,8 @@ public:
|
||||
SRAM_DATABASE_SNAPSHOT = 0xFE, // use downcount for shared memory types
|
||||
SRAM_EVENT_MANAGER = 0xFD,
|
||||
SRAM_TRACE_CONFIG = 0xFC,
|
||||
SRAM_TRACE_LOG = 0xFB
|
||||
SRAM_TRACE_LOG = 0xFB,
|
||||
SRAM_MAPPING_RESET = 0xFA,
|
||||
};
|
||||
|
||||
protected:
|
||||
|
@ -54,7 +54,7 @@ Get::Get(Config* firebirdConf)
|
||||
|
||||
void FB_CARG UserData::clear()
|
||||
{
|
||||
op = trustedRole = trustedAuth = 0;
|
||||
op = 0;
|
||||
|
||||
// interface fields
|
||||
user.clear();
|
||||
@ -72,7 +72,6 @@ void FB_CARG UserData::clear()
|
||||
dba.clear();
|
||||
dbaPassword.clear();
|
||||
role.clear();
|
||||
trustedUser.clear();
|
||||
|
||||
// never clear this permanent block! authenticationBlock.clear();
|
||||
|
||||
|
@ -146,7 +146,7 @@ class UserData : public IUser
|
||||
{
|
||||
public:
|
||||
UserData()
|
||||
: op(0), trustedRole(0), trustedAuth(0), authenticationBlock(*getDefaultMemoryPool())
|
||||
: op(0), trustedAuth(0), authenticationBlock(*getDefaultMemoryPool())
|
||||
{ }
|
||||
|
||||
// IUser implementation
|
||||
@ -204,10 +204,10 @@ public:
|
||||
|
||||
typedef Firebird::Array<UCHAR> AuthenticationBlock;
|
||||
|
||||
int op, trustedRole, trustedAuth;
|
||||
int op, trustedAuth;
|
||||
CharField user, pass, first, last, middle, com, attr;
|
||||
IntField adm, act;
|
||||
CharField database, dba, dbaPassword, role, trustedUser;
|
||||
CharField database, dba, dbaPassword, role;
|
||||
AuthenticationBlock authenticationBlock;
|
||||
|
||||
// deprecated
|
||||
|
@ -59,6 +59,7 @@
|
||||
#include "../utilities/gsec/gsec.h"
|
||||
#include "../common/dsc_proto.h"
|
||||
#include "../common/StatusArg.h"
|
||||
#include "../auth/SecureRemotePassword/Message.h"
|
||||
|
||||
namespace Jrd {
|
||||
|
||||
@ -9147,55 +9148,426 @@ bool CreateRoleNode::isItUserName(thread_db* tdbb, jrd_tra* transaction)
|
||||
//----------------------
|
||||
|
||||
|
||||
void AlterRoleNode::print(string& text) const
|
||||
void MappingNode::print(string& text) const
|
||||
{
|
||||
const char* null = "<Null>";
|
||||
|
||||
text.printf(
|
||||
"AlterRoleNode\n"
|
||||
" name: '%s'\n"
|
||||
" map: '%d'\n",
|
||||
name.c_str(), map);
|
||||
"MappingNode\n"
|
||||
" op: '%s'\n"
|
||||
" global: '%d'\n"
|
||||
" mode: '%c'\n"
|
||||
" plugin: '%s'\n"
|
||||
" db: '%s'\n"
|
||||
" fromType: '%s'\n"
|
||||
" from: '%s'\n"
|
||||
" role: '%d'\n"
|
||||
" to: '%s'\n",
|
||||
op, global, mode,
|
||||
plugin ? plugin->c_str() : null, db ? db->c_str() : null,
|
||||
fromType ? fromType->c_str() : null, from ? from->getString().c_str() : null,
|
||||
role, to ? to->c_str() : null);
|
||||
}
|
||||
|
||||
// It's purpose is to add/drop mapping from OS security name to DB security object.
|
||||
void AlterRoleNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction)
|
||||
void MappingNode::validateAdmin()
|
||||
{
|
||||
// run all statements under savepoint control
|
||||
AutoSavePoint savePoint(tdbb, transaction);
|
||||
if (to && (*to != ADMIN_ROLE))
|
||||
Arg::Gds(isc_alter_role).raise();
|
||||
}
|
||||
|
||||
// This is FB 2.5 limited implementation!
|
||||
// Later it should work with new system table, something like RDB$MAPPING.
|
||||
|
||||
if (name != ADMIN_ROLE)
|
||||
status_exception::raise(Arg::Gds(isc_wish_list));
|
||||
// add some item to DLL in "double quotes"
|
||||
void MappingNode::addItem(string& ddl, const char* text)
|
||||
{
|
||||
ddl += '"';
|
||||
char c;
|
||||
while (c = *text++)
|
||||
{
|
||||
ddl += c;
|
||||
if (c == '"')
|
||||
ddl += c;
|
||||
}
|
||||
ddl += '"';
|
||||
}
|
||||
|
||||
// It's purpose is to add/drop mapping from any security name to DB security object.
|
||||
void MappingNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction)
|
||||
{
|
||||
if (!(tdbb->getAttachment() && tdbb->getAttachment()->locksmith()))
|
||||
status_exception::raise(Arg::Gds(isc_adm_task_denied));
|
||||
|
||||
AutoCacheRequest request(tdbb, drq_m_map, DYN_REQUESTS);
|
||||
bool found = false;
|
||||
if (global)
|
||||
{
|
||||
LocalStatus st;
|
||||
LocalStatus s2; // we will use it in DDL case and remember
|
||||
IStatus* s = &st;
|
||||
class Check
|
||||
{
|
||||
public:
|
||||
static void status(IStatus* s)
|
||||
{
|
||||
if (!s->isSuccess())
|
||||
status_exception::raise(s->get());
|
||||
}
|
||||
};
|
||||
|
||||
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
|
||||
ROL IN RDB$ROLES
|
||||
WITH ROL.RDB$ROLE_NAME EQ name.c_str()
|
||||
SecDbContext* secDbContext = transaction->getSecDbContext();
|
||||
if (!secDbContext)
|
||||
{
|
||||
const char* secDb = tdbb->getDatabase()->dbb_config->getSecurityDatabase();
|
||||
ClumpletWriter dpb(ClumpletWriter::WideTagged, MAX_DPB_SIZE, isc_dpb_version2);
|
||||
if (tdbb->getAttachment()->att_user)
|
||||
tdbb->getAttachment()->att_user->populateDpb(dpb);
|
||||
IAttachment* att = DispatcherPtr()->attachDatabase(s, secDb,
|
||||
dpb.getBufferLength(), dpb.getBuffer());
|
||||
Check::status(s);
|
||||
|
||||
ITransaction* tra = att->startTransaction(s, 0, NULL);
|
||||
Check::status(s);
|
||||
|
||||
secDbContext = transaction->setSecDbContext(att, tra);
|
||||
}
|
||||
|
||||
// run all statements under savepoint control
|
||||
string savePoint;
|
||||
savePoint.printf("GLOBALMAP%d", secDbContext->savePoint++);
|
||||
secDbContext->att->execute(s, secDbContext->tra, 0, ("SAVEPOINT " + savePoint).c_str(),
|
||||
SQL_DIALECT_V6, NULL, NULL, NULL, NULL);
|
||||
Check::status(s);
|
||||
|
||||
try
|
||||
{
|
||||
// first of all try to use regenerated DDL statement
|
||||
// that's the best way if security database is FB3 or higher fb version
|
||||
string ddl;
|
||||
|
||||
switch(op)
|
||||
{
|
||||
case MAP_ADD:
|
||||
ddl = "CREATE MAPPING ";
|
||||
break;
|
||||
case MAP_MOD:
|
||||
ddl = "ALTER MAPPING ";
|
||||
break;
|
||||
case MAP_DROP:
|
||||
ddl = "DROP MAPPING ";
|
||||
break;
|
||||
case MAP_RPL:
|
||||
ddl = "CREATE OR ALTER MAPPING ";
|
||||
break;
|
||||
}
|
||||
|
||||
addItem(ddl, name.c_str());
|
||||
if (op != MAP_DROP)
|
||||
{
|
||||
ddl += " USING ";
|
||||
switch (mode)
|
||||
{
|
||||
case 'P':
|
||||
if (!plugin)
|
||||
ddl += "ANY PLUGIN ";
|
||||
else
|
||||
{
|
||||
ddl += "PLUGIN ";
|
||||
addItem(ddl, plugin->c_str());
|
||||
ddl += ' ';
|
||||
}
|
||||
break;
|
||||
case 'S':
|
||||
ddl += "ANY PLUGIN SERVERWIDE ";
|
||||
break;
|
||||
case '*':
|
||||
ddl += "* ";
|
||||
break;
|
||||
case 'M':
|
||||
ddl += "MAPPING ";
|
||||
break;
|
||||
}
|
||||
|
||||
if (db)
|
||||
{
|
||||
ddl += "IN ";
|
||||
addItem(ddl, db->c_str());
|
||||
ddl += ' ';
|
||||
}
|
||||
|
||||
if (fromType)
|
||||
{
|
||||
ddl += "FROM ";
|
||||
if (!from)
|
||||
ddl += "ANY ";
|
||||
addItem(ddl, fromType->c_str());
|
||||
ddl += ' ';
|
||||
if (from)
|
||||
{
|
||||
addItem(ddl, from->getString().c_str());
|
||||
ddl += ' ';
|
||||
}
|
||||
}
|
||||
|
||||
ddl += "TO ";
|
||||
ddl += (role ? "ROLE" : "USER");
|
||||
if (to)
|
||||
{
|
||||
ddl += ' ';
|
||||
addItem(ddl, to->c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// Now try to run DDL
|
||||
secDbContext->att->execute(&s2, secDbContext->tra, 0, ddl.c_str(), SQL_DIALECT_V6,
|
||||
NULL, NULL, NULL, NULL);
|
||||
|
||||
if (!s2.isSuccess())
|
||||
{
|
||||
// try direct access to rdb$map table in secure db
|
||||
|
||||
// check presence of such record in the table
|
||||
Message check;
|
||||
Field<Varying> nm(check, 1);
|
||||
nm = name.c_str();
|
||||
|
||||
Message result;
|
||||
Field<ISC_INT64> cnt(result);
|
||||
|
||||
const char* checkSql = "select count(*) from RDB$MAP where RDB$MAP_NAME = ?";
|
||||
|
||||
secDbContext->att->execute(s, secDbContext->tra, 0, checkSql, SQL_DIALECT_V6,
|
||||
check.getMetadata(), check.getBuffer(), result.getMetadata(), result.getBuffer());
|
||||
Check::status(s);
|
||||
|
||||
if (cnt > 1 && op != MAP_DROP)
|
||||
ERRD_bugcheck("Database mapping misconfigured");
|
||||
|
||||
bool hasLine = cnt > 0;
|
||||
switch(op)
|
||||
{
|
||||
case MAP_ADD:
|
||||
if (hasLine)
|
||||
(Arg::Gds(isc_map_already_exists) << name).raise();
|
||||
break;
|
||||
|
||||
case MAP_MOD:
|
||||
case MAP_DROP:
|
||||
if (!hasLine)
|
||||
(Arg::Gds(isc_map_not_exists) << name).raise();
|
||||
break;
|
||||
|
||||
case MAP_RPL:
|
||||
op = hasLine ? MAP_MOD : MAP_DROP;
|
||||
break;
|
||||
}
|
||||
|
||||
// Get ready to modify table
|
||||
Message full;
|
||||
Field<ISC_SHORT> toType(full);
|
||||
Field<Varying> t(full, MAX_SQL_IDENTIFIER_LEN);
|
||||
Field<Varying> usng2(full, 1);
|
||||
Field<Varying> plug2(full, MAX_SQL_IDENTIFIER_LEN);
|
||||
Field<Varying> d2(full, MAX_SQL_IDENTIFIER_LEN);
|
||||
Field<Varying> type2(full, MAX_SQL_IDENTIFIER_LEN);
|
||||
Field<Varying> f2(full, 255);
|
||||
Field<Varying> nm2(full, MAX_SQL_IDENTIFIER_LEN);
|
||||
|
||||
toType = role ? 1 : 0;
|
||||
if (to)
|
||||
t = to->c_str();
|
||||
usng2.set(1, &mode);
|
||||
if (plugin)
|
||||
plug2 = plugin->c_str();
|
||||
if (db)
|
||||
d2 = db->c_str();
|
||||
if (fromType)
|
||||
type2 = fromType->c_str();
|
||||
if (from)
|
||||
f2 = from->getString().c_str();
|
||||
nm2 = name.c_str();
|
||||
|
||||
Message* msg = NULL;
|
||||
const char* sql = NULL;
|
||||
switch(op)
|
||||
{
|
||||
case MAP_ADD:
|
||||
sql = "insert into RDB$MAP(RDB$MAP_TO_TYPE, RDB$MAP_TO, RDB$MAP_USING, "
|
||||
"RDB$MAP_PLUGIN, RDB$MAP_DB, RDB$MAP_FROM_TYPE, RDB$MAP_FROM, RDB$MAP_NAME) "
|
||||
"values (?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
msg = &full;
|
||||
break;
|
||||
case MAP_MOD:
|
||||
sql = "update RDB$MAP set RDB$MAP_TO_TYPE = ?, RDB$MAP_TO = ?, "
|
||||
"RDB$MAP_USING = ?, RDB$MAP_PLUGIN = ?, RDB$MAP_DB = ?, "
|
||||
"RDB$MAP_FROM_TYPE = ?, RDB$MAP_FROM = ? "
|
||||
"where RDB$MAP_NAME = ?";
|
||||
msg = &full;
|
||||
break;
|
||||
case MAP_DROP:
|
||||
sql = "delete from RDB$MAP where RDB$MAP_NAME = ?";
|
||||
msg = ✓
|
||||
break;
|
||||
}
|
||||
|
||||
// Actual modification
|
||||
fb_assert(sql && msg);
|
||||
secDbContext->att->execute(s, secDbContext->tra, 0, sql, SQL_DIALECT_V6,
|
||||
msg->getMetadata(), msg->getBuffer(), NULL, NULL);
|
||||
Check::status(s);
|
||||
|
||||
secDbContext->att->execute(s, secDbContext->tra, 0, ("RELEASE SAVEPOINT " + savePoint).c_str(),
|
||||
SQL_DIALECT_V6, NULL, NULL, NULL, NULL);
|
||||
savePoint.erase();
|
||||
Check::status(s);
|
||||
}
|
||||
}
|
||||
catch(const Exception&)
|
||||
{
|
||||
if (savePoint.hasData())
|
||||
{
|
||||
secDbContext->att->execute(s, secDbContext->tra, 0, ("ROLLBACK TO SAVEPOINT " + savePoint).c_str(),
|
||||
SQL_DIALECT_V6, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
if (!s2.isSuccess())
|
||||
{
|
||||
const ISC_STATUS* stat2 = s2.get();
|
||||
if (stat2[1] != isc_dsql_token_unk_err)
|
||||
{
|
||||
status_exception::raise(stat2);
|
||||
}
|
||||
}
|
||||
throw;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// run all statements under savepoint control
|
||||
AutoSavePoint savePoint(tdbb, transaction);
|
||||
|
||||
fb_assert(op == MAP_DROP || fromType);
|
||||
|
||||
short plugNull = plugin ? FALSE : TRUE;
|
||||
short dbNull = db ? FALSE : TRUE;
|
||||
short fromNull = from ? FALSE : TRUE;
|
||||
|
||||
char usingText[2];
|
||||
usingText[0] = mode;
|
||||
usingText[1] = '\0';
|
||||
|
||||
AutoCacheRequest request1(tdbb, drq_map_mod, DYN_REQUESTS);
|
||||
bool found = false;
|
||||
int ddlTriggerAction = 0;
|
||||
|
||||
FOR(REQUEST_HANDLE request1 TRANSACTION_HANDLE transaction)
|
||||
M IN RDB$MAP
|
||||
WITH M.RDB$MAP_NAME EQ name.c_str()
|
||||
{
|
||||
found = true;
|
||||
switch (op)
|
||||
{
|
||||
case MAP_ADD:
|
||||
break;
|
||||
|
||||
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, DDL_TRIGGER_ALTER_ROLE, name);
|
||||
case MAP_MOD:
|
||||
case MAP_RPL:
|
||||
ddlTriggerAction = DDL_TRIGGER_ALTER_MAPPING;
|
||||
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, ddlTriggerAction, name);
|
||||
|
||||
MODIFY ROL
|
||||
ROL.RDB$SYSTEM_FLAG = ROLE_FLAG_DBO | (map ? ROLE_FLAG_MAY_TRUST : 0);
|
||||
END_MODIFY
|
||||
MODIFY M
|
||||
if (to)
|
||||
{
|
||||
M.RDB$MAP_TO.NULL = FALSE;
|
||||
strcpy(M.RDB$MAP_TO, to->c_str());
|
||||
}
|
||||
else
|
||||
M.RDB$MAP_TO.NULL = TRUE;
|
||||
M.RDB$MAP_TO_TYPE = role ? 1 : 0;
|
||||
|
||||
strcpy(M.RDB$MAP_USING, usingText);
|
||||
M.RDB$MAP_PLUGIN.NULL = plugNull;
|
||||
if (!plugNull)
|
||||
strcpy(M.RDB$MAP_PLUGIN, plugin->c_str());
|
||||
|
||||
M.RDB$MAP_DB.NULL = dbNull;
|
||||
if (!dbNull)
|
||||
strcpy(M.RDB$MAP_DB, db->c_str());
|
||||
|
||||
strcpy(M.RDB$MAP_FROM_TYPE, fromType->c_str());
|
||||
M.RDB$MAP_FROM.NULL = fromNull;
|
||||
if (!fromNull)
|
||||
strcpy(M.RDB$MAP_FROM, from->getString().c_str());
|
||||
END_MODIFY
|
||||
break;
|
||||
|
||||
case MAP_DROP:
|
||||
ddlTriggerAction = DDL_TRIGGER_DROP_MAPPING;
|
||||
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, ddlTriggerAction, name);
|
||||
|
||||
ERASE M;
|
||||
break;
|
||||
}
|
||||
}
|
||||
END_FOR
|
||||
|
||||
if (found)
|
||||
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, DDL_TRIGGER_ALTER_ROLE, name);
|
||||
else
|
||||
AutoCacheRequest request2(tdbb, drq_map_sto, DYN_REQUESTS);
|
||||
switch (op)
|
||||
{
|
||||
status_exception::raise(
|
||||
Arg::Gds(isc_random) << Arg::Str("Missing RDB$ADMIN role in the database"));
|
||||
case MAP_ADD:
|
||||
if (found)
|
||||
{
|
||||
(Arg::Gds(isc_map_already_exists) << name).raise();
|
||||
}
|
||||
// fall through ...
|
||||
|
||||
case MAP_RPL:
|
||||
if (found)
|
||||
break;
|
||||
|
||||
ddlTriggerAction = DDL_TRIGGER_CREATE_MAPPING;
|
||||
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, ddlTriggerAction, name);
|
||||
|
||||
STORE(REQUEST_HANDLE request2 TRANSACTION_HANDLE transaction)
|
||||
M IN RDB$MAP
|
||||
{
|
||||
strcpy(M.RDB$MAP_NAME, name.c_str());
|
||||
strcpy(M.RDB$MAP_USING, usingText);
|
||||
M.RDB$MAP_PLUGIN.NULL = plugNull;
|
||||
if (!plugNull)
|
||||
strcpy(M.RDB$MAP_PLUGIN, plugin->c_str());
|
||||
|
||||
M.RDB$MAP_DB.NULL = dbNull;
|
||||
if (!dbNull)
|
||||
strcpy(M.RDB$MAP_DB, db->c_str());
|
||||
|
||||
strcpy(M.RDB$MAP_FROM_TYPE, fromType->c_str());
|
||||
M.RDB$MAP_FROM.NULL = fromNull;
|
||||
if (!fromNull)
|
||||
strcpy(M.RDB$MAP_FROM, from->getString().c_str());
|
||||
|
||||
M.RDB$MAP_TO_TYPE = role ? 1 : 0;
|
||||
if (to)
|
||||
{
|
||||
M.RDB$MAP_TO.NULL = FALSE;
|
||||
strcpy(M.RDB$MAP_TO, to->c_str());
|
||||
}
|
||||
else
|
||||
M.RDB$MAP_TO.NULL = TRUE;
|
||||
}
|
||||
END_STORE
|
||||
break;
|
||||
|
||||
case MAP_MOD:
|
||||
case MAP_DROP:
|
||||
if (!found)
|
||||
{
|
||||
(Arg::Gds(isc_map_not_exists) << name).raise();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
fb_assert(ddlTriggerAction > 0);
|
||||
if (ddlTriggerAction > 0)
|
||||
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, ddlTriggerAction, name);
|
||||
|
||||
DFW_post_work(transaction, dfw_flash_cache, NULL, 0);
|
||||
savePoint.release(); // everything is ok
|
||||
}
|
||||
|
||||
|
@ -1749,16 +1749,28 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class AlterRoleNode : public DdlNode
|
||||
class MappingNode : public DdlNode
|
||||
{
|
||||
public:
|
||||
AlterRoleNode(MemoryPool& p, const Firebird::MetaName& aName, bool aMap)
|
||||
enum OP {MAP_ADD, MAP_MOD, MAP_RPL, MAP_DROP};
|
||||
|
||||
MappingNode(MemoryPool& p, OP o, const Firebird::MetaName& nm)
|
||||
: DdlNode(p),
|
||||
name(p, aName),
|
||||
map(aMap)
|
||||
name(p, nm),
|
||||
plugin(NULL),
|
||||
db(NULL),
|
||||
fromType(NULL),
|
||||
from(NULL),
|
||||
to(NULL),
|
||||
op(o),
|
||||
mode('#'),
|
||||
global(false),
|
||||
role(false)
|
||||
{
|
||||
}
|
||||
|
||||
void validateAdmin();
|
||||
|
||||
public:
|
||||
virtual void print(Firebird::string& text) const;
|
||||
virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction);
|
||||
@ -1766,12 +1778,25 @@ public:
|
||||
protected:
|
||||
virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector)
|
||||
{
|
||||
statusVector << Firebird::Arg::Gds(isc_dsql_alter_role_failed) << name;
|
||||
statusVector << Firebird::Arg::Gds(isc_dsql_mapping_failed) << name <<
|
||||
(op == MAP_ADD ? "CREATE" : op == MAP_MOD ?
|
||||
"ALTER" : op == MAP_RPL ? "CREATE OR ALTER" : "DROP");
|
||||
}
|
||||
|
||||
private:
|
||||
void addItem(Firebird::string& ddl, const char* text);
|
||||
|
||||
public:
|
||||
Firebird::MetaName name;
|
||||
bool map;
|
||||
Firebird::MetaName* plugin;
|
||||
Firebird::MetaName* db;
|
||||
Firebird::MetaName* fromType;
|
||||
IntlString* from;
|
||||
Firebird::MetaName* to;
|
||||
OP op;
|
||||
char mode; // * - any source, P - plugin, M - mapping, S - any serverwide plugin
|
||||
bool global;
|
||||
bool role;
|
||||
};
|
||||
|
||||
|
||||
|
213
src/dsql/parse.y
213
src/dsql/parse.y
@ -96,6 +96,9 @@
|
||||
#include "../jrd/Attachment.h"
|
||||
#include "../common/StatusArg.h"
|
||||
|
||||
// This is needed here to provide backward compatibility when working with SSPI plugin
|
||||
#include "../auth/trusted/AuthSspi.h"
|
||||
|
||||
// since UNIX isn't standard, we have to define
|
||||
// stuff which is in <limits.h> (which isn't available on all UNIXes...
|
||||
|
||||
@ -563,6 +566,8 @@ using namespace Firebird;
|
||||
%token <metaNamePtr> RDB_RECORD_VERSION
|
||||
%token <metaNamePtr> LINGER
|
||||
%token <metaNamePtr> TAGS
|
||||
%token <metaNamePtr> PLUGIN
|
||||
%token <metaNamePtr> SERVERWIDE
|
||||
|
||||
// precedence declarations for expression evaluation
|
||||
|
||||
@ -687,6 +692,8 @@ using namespace Firebird;
|
||||
Jrd::DeclareSubFuncNode* declareSubFuncNode;
|
||||
Jrd::dsql_req* dsqlReq;
|
||||
Jrd::CreateAlterUserNode* createAlterUserNode;
|
||||
Jrd::MappingNode* mappingNode;
|
||||
Jrd::MappingNode::OP mappingOp;
|
||||
}
|
||||
|
||||
%include types.y
|
||||
@ -1231,6 +1238,8 @@ create_clause
|
||||
| USER create_user_clause { $$ = $2; }
|
||||
| PACKAGE package_clause { $$ = $2; }
|
||||
| PACKAGE BODY package_body_clause { $$ = $3; }
|
||||
| MAPPING create_map_clause(false) { $$ = $2; }
|
||||
| GLOBAL MAPPING create_map_clause(true) { $$ = $3; }
|
||||
;
|
||||
|
||||
|
||||
@ -1272,15 +1281,17 @@ create_or_alter
|
||||
|
||||
%type <ddlNode> replace_clause
|
||||
replace_clause
|
||||
: PROCEDURE replace_procedure_clause { $$ = $2; }
|
||||
| FUNCTION replace_function_clause { $$ = $2; }
|
||||
| TRIGGER replace_trigger_clause { $$ = $2; }
|
||||
| PACKAGE replace_package_clause { $$ = $2; }
|
||||
| VIEW replace_view_clause { $$ = $2; }
|
||||
| EXCEPTION replace_exception_clause { $$ = $2; }
|
||||
| GENERATOR replace_sequence_clause { $$ = $2; }
|
||||
| SEQUENCE replace_sequence_clause { $$ = $2; }
|
||||
| USER replace_user_clause { $$ = $2; }
|
||||
: PROCEDURE replace_procedure_clause { $$ = $2; }
|
||||
| FUNCTION replace_function_clause { $$ = $2; }
|
||||
| TRIGGER replace_trigger_clause { $$ = $2; }
|
||||
| PACKAGE replace_package_clause { $$ = $2; }
|
||||
| VIEW replace_view_clause { $$ = $2; }
|
||||
| EXCEPTION replace_exception_clause { $$ = $2; }
|
||||
| GENERATOR replace_sequence_clause { $$ = $2; }
|
||||
| SEQUENCE replace_sequence_clause { $$ = $2; }
|
||||
| USER replace_user_clause { $$ = $2; }
|
||||
| MAPPING replace_map_clause(false) { $$ = $2; }
|
||||
| GLOBAL MAPPING replace_map_clause(true) { $$ = $3; }
|
||||
;
|
||||
|
||||
|
||||
@ -3330,6 +3341,9 @@ trigger_ddl_type_items
|
||||
| DROP PACKAGE { $$ = TRIGGER_TYPE_DDL | (1LL << DDL_TRIGGER_DROP_PACKAGE); }
|
||||
| CREATE PACKAGE BODY { $$ = TRIGGER_TYPE_DDL | (1LL << DDL_TRIGGER_CREATE_PACKAGE_BODY); }
|
||||
| DROP PACKAGE BODY { $$ = TRIGGER_TYPE_DDL | (1LL << DDL_TRIGGER_DROP_PACKAGE_BODY); }
|
||||
| CREATE MAPPING { $$ = TRIGGER_TYPE_DDL | (1LL << DDL_TRIGGER_CREATE_MAPPING); }
|
||||
| ALTER MAPPING { $$ = TRIGGER_TYPE_DDL | (1LL << DDL_TRIGGER_ALTER_MAPPING); }
|
||||
| DROP MAPPING { $$ = TRIGGER_TYPE_DDL | (1LL << DDL_TRIGGER_DROP_MAPPING); }
|
||||
| trigger_ddl_type OR
|
||||
trigger_ddl_type { $$ = $1 | $3; }
|
||||
;
|
||||
@ -3398,6 +3412,8 @@ alter_clause
|
||||
| CHARACTER SET alter_charset_clause { $$ = $3; }
|
||||
| GENERATOR alter_sequence_clause { $$ = $2; }
|
||||
| SEQUENCE alter_sequence_clause { $$ = $2; }
|
||||
| MAPPING alter_map_clause(false) { $$ = $2; }
|
||||
| GLOBAL MAPPING alter_map_clause(true) { $$ = $3; }
|
||||
;
|
||||
|
||||
%type <alterDomainNode> alter_domain
|
||||
@ -3664,10 +3680,20 @@ module_op
|
||||
| MODULE_NAME utf_string { $$ = $2; }
|
||||
;
|
||||
|
||||
%type <ddlNode> alter_role_clause
|
||||
%type <mappingNode> alter_role_clause
|
||||
alter_role_clause
|
||||
: symbol_role_name alter_role_enable AUTO ADMIN MAPPING
|
||||
{ $$ = newNode<AlterRoleNode>(*$1, $2); }
|
||||
{
|
||||
$$ = newNode<MappingNode>(MappingNode::MAP_RPL, "AutoAdminImplementationMapping");
|
||||
$$->op = $2 ? MappingNode::MAP_RPL : MappingNode::MAP_DROP;
|
||||
$$->from = newNode<IntlString>(FB_DOMAIN_ANY_RID_ADMINS);
|
||||
$$->fromType = newNode<MetaName>(FB_PREDEFINED_GROUP);
|
||||
$$->mode = 'P';
|
||||
$$->plugin = newNode<MetaName>("Win_Sspi");
|
||||
$$->role = true;
|
||||
$$->to = $1;
|
||||
$$->validateAdmin();
|
||||
}
|
||||
;
|
||||
|
||||
%type <boolVal> alter_role_enable
|
||||
@ -3804,6 +3830,10 @@ drop_clause
|
||||
{ $$ = newNode<DropPackageNode>(*$2); }
|
||||
| PACKAGE BODY symbol_package_name
|
||||
{ $$ = newNode<DropPackageBodyNode>(*$3); }
|
||||
| MAPPING drop_map_clause(false)
|
||||
{ $$ = $2; }
|
||||
| GLOBAL MAPPING drop_map_clause(true)
|
||||
{ $$ = $3; }
|
||||
;
|
||||
|
||||
|
||||
@ -5926,6 +5956,165 @@ user_var_option($node)
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
// logons mapping
|
||||
|
||||
%type <mappingNode> create_map_clause(<boolVal>)
|
||||
create_map_clause($global)
|
||||
: map_clause(MappingNode::MAP_ADD)
|
||||
{
|
||||
$$ = $1;
|
||||
$$->global = $global;
|
||||
}
|
||||
map_to(NOTRIAL($2))
|
||||
{
|
||||
$$ = $2;
|
||||
}
|
||||
;
|
||||
|
||||
%type <mappingNode> alter_map_clause(<boolVal>)
|
||||
alter_map_clause($global)
|
||||
: map_clause(MappingNode::MAP_MOD)
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
map_to(NOTRIAL($2))
|
||||
{
|
||||
$$ = $2;
|
||||
}
|
||||
;
|
||||
|
||||
%type <mappingNode> replace_map_clause(<boolVal>)
|
||||
replace_map_clause($global)
|
||||
: map_clause(MappingNode::MAP_RPL)
|
||||
{
|
||||
$$ = $1;
|
||||
$$->global = $global;
|
||||
}
|
||||
map_to(NOTRIAL($2))
|
||||
{
|
||||
$$ = $2;
|
||||
}
|
||||
;
|
||||
|
||||
%type <mappingNode> drop_map_clause(<boolVal>)
|
||||
drop_map_clause($global)
|
||||
: map_name
|
||||
{
|
||||
MappingNode* node = newNode<MappingNode>(MappingNode::MAP_DROP, *$1);
|
||||
node->global = $global;
|
||||
$$ = node;
|
||||
}
|
||||
;
|
||||
|
||||
%type <mappingNode> map_clause(<mappingOp>)
|
||||
map_clause($op)
|
||||
: map_name
|
||||
{
|
||||
$$ = newNode<MappingNode>($op, *$1);
|
||||
}
|
||||
USING map_using(NOTRIAL($2))
|
||||
FROM map_from(NOTRIAL($2))
|
||||
{
|
||||
$$ = $2;
|
||||
}
|
||||
;
|
||||
|
||||
%type <metaNamePtr> map_name
|
||||
map_name
|
||||
: valid_symbol_name
|
||||
{ $$ = $1; }
|
||||
;
|
||||
|
||||
%type map_from(<mappingNode>)
|
||||
map_from($node)
|
||||
: map_from_symbol_name map_logoninfo
|
||||
{
|
||||
$node->fromType = $1;
|
||||
$node->from = $2;
|
||||
}
|
||||
| ANY map_from_symbol_name
|
||||
{
|
||||
$node->fromType = $2;
|
||||
$node->from = newNode<IntlString>("*");
|
||||
}
|
||||
;
|
||||
|
||||
%type <metaNamePtr> map_from_symbol_name
|
||||
map_from_symbol_name
|
||||
: valid_symbol_name
|
||||
| USER
|
||||
{ $$ = newNode<MetaName>("USER"); }
|
||||
| GROUP
|
||||
{ $$ = newNode<MetaName>("GROUP"); }
|
||||
;
|
||||
|
||||
%type <intlStringPtr> map_logoninfo
|
||||
map_logoninfo
|
||||
: STRING
|
||||
| valid_symbol_name
|
||||
{ $$ = newNode<IntlString>($1->c_str()); }
|
||||
;
|
||||
|
||||
%type map_using(<mappingNode>)
|
||||
map_using($node)
|
||||
: PLUGIN valid_symbol_name map_in
|
||||
{
|
||||
$node->mode = 'P';
|
||||
$node->plugin = $2;
|
||||
$node->db = $3;
|
||||
}
|
||||
| ANY PLUGIN map_in
|
||||
{
|
||||
$node->mode = 'P';
|
||||
$node->db = $3;
|
||||
}
|
||||
| ANY PLUGIN SERVERWIDE
|
||||
{
|
||||
$node->mode = 'S';
|
||||
}
|
||||
| MAPPING map_in
|
||||
{
|
||||
$node->mode = 'M';
|
||||
$node->db = $2;
|
||||
}
|
||||
| '*' map_in
|
||||
{
|
||||
$node->mode = '*';
|
||||
$node->db = $2;
|
||||
}
|
||||
;
|
||||
|
||||
%type <metaNamePtr> map_in
|
||||
map_in
|
||||
: // nothing
|
||||
{ $$ = NULL; }
|
||||
| KW_IN valid_symbol_name
|
||||
{ $$ = $2; }
|
||||
;
|
||||
|
||||
%type map_to(<mappingNode>)
|
||||
map_to($node)
|
||||
: TO map_role valid_symbol_name
|
||||
{
|
||||
$node->role = $2;
|
||||
$node->to = $3;
|
||||
}
|
||||
| TO map_role
|
||||
{
|
||||
$node->role = $2;
|
||||
}
|
||||
;
|
||||
|
||||
%type <boolVal> map_role
|
||||
map_role
|
||||
: ROLE
|
||||
{ $$ = true; }
|
||||
| USER
|
||||
{ $$ = false; }
|
||||
;
|
||||
|
||||
|
||||
// value types
|
||||
|
||||
%type <valueExprNode> value
|
||||
@ -7163,6 +7352,8 @@ non_reserved_word
|
||||
| USAGE
|
||||
| LINGER
|
||||
| TAGS
|
||||
| PLUGIN
|
||||
| SERVERWIDE
|
||||
;
|
||||
|
||||
%%
|
||||
|
@ -47,9 +47,10 @@ class IWriter : public Firebird::IVersioned
|
||||
public:
|
||||
virtual void FB_CARG reset() = 0;
|
||||
virtual void FB_CARG add(const char* name) = 0;
|
||||
virtual void FB_CARG setAttribute(unsigned char tag, const char* value) = 0;
|
||||
virtual void FB_CARG setType(const char* value) = 0;
|
||||
virtual void FB_CARG setDb(const char* value) = 0;
|
||||
};
|
||||
#define FB_AUTH_WRITER_VERSION (FB_VERSIONED_VERSION + 3)
|
||||
#define FB_AUTH_WRITER_VERSION (FB_VERSIONED_VERSION + 4)
|
||||
|
||||
// Representation of auth-related data, passed to/from server auth plugin
|
||||
class IServerBlock : public Firebird::IVersioned
|
||||
@ -149,12 +150,11 @@ class ILogonInfo : public Firebird::IVersioned
|
||||
public:
|
||||
virtual const char* FB_CARG name() = 0;
|
||||
virtual const char* FB_CARG role() = 0;
|
||||
virtual int FB_CARG forceAdmin() = 0;
|
||||
virtual const char* FB_CARG networkProtocol() = 0;
|
||||
virtual const char* FB_CARG remoteAddress() = 0;
|
||||
virtual unsigned int FB_CARG authBlock(const unsigned char** bytes) = 0;
|
||||
};
|
||||
#define FB_AUTH_LOGON_INFO_VERSION (FB_VERSIONED_VERSION + 6)
|
||||
#define FB_AUTH_LOGON_INFO_VERSION (FB_VERSIONED_VERSION + 5)
|
||||
|
||||
class IManagement : public Firebird::IPluginBase
|
||||
{
|
||||
|
@ -116,10 +116,11 @@ public:
|
||||
virtual void FB_CARG truncate(IStatus* status, unsigned count) = 0;
|
||||
virtual void FB_CARG moveNameToIndex(IStatus* status, const char* name, unsigned index) = 0;
|
||||
virtual void FB_CARG remove(IStatus* status, unsigned index) = 0;
|
||||
virtual unsigned FB_CARG addField(IStatus* status) = 0;
|
||||
|
||||
virtual IMessageMetadata* FB_CARG getMetadata(IStatus* status) = 0;
|
||||
};
|
||||
#define FB_METADATA_BUILDER_VERSION (FB_REFCOUNTED_VERSION + 9)
|
||||
#define FB_METADATA_BUILDER_VERSION (FB_REFCOUNTED_VERSION + 10)
|
||||
|
||||
class IResultSet : public IRefCounted
|
||||
{
|
||||
|
@ -778,6 +778,17 @@ static const struct {
|
||||
{"forupdate_systbl", 335545074},
|
||||
{"forupdate_temptbl", 335545075},
|
||||
{"cant_modify_sysobj", 335545076},
|
||||
{"server_misconfigured", 335545077},
|
||||
{"alter_role", 335545078},
|
||||
{"map_already_exists", 335545079},
|
||||
{"map_not_exists", 335545080},
|
||||
{"map_load", 335545081},
|
||||
{"map_aster", 335545082},
|
||||
{"map_multi", 335545083},
|
||||
{"map_undefined", 335545084},
|
||||
{"baddpb_damaged_mode", 335545085},
|
||||
{"baddpb_buffers_range", 335545086},
|
||||
{"baddpb_temp_buffers", 335545087},
|
||||
{"gfix_db_name", 335740929},
|
||||
{"gfix_invalid_sw", 335740930},
|
||||
{"gfix_incmp_sw", 335740932},
|
||||
@ -1124,6 +1135,7 @@ static const struct {
|
||||
{"dsql_grant_failed", 336397319},
|
||||
{"dsql_revoke_failed", 336397320},
|
||||
{"dsql_cte_recursive_aggregate", 336397321},
|
||||
{"dsql_mapping_failed", 336397322},
|
||||
{"gsec_cant_open_db", 336723983},
|
||||
{"gsec_switches_error", 336723984},
|
||||
{"gsec_no_op_spec", 336723985},
|
||||
|
@ -812,6 +812,17 @@ const ISC_STATUS isc_forupdate_virtualtbl = 335545073L;
|
||||
const ISC_STATUS isc_forupdate_systbl = 335545074L;
|
||||
const ISC_STATUS isc_forupdate_temptbl = 335545075L;
|
||||
const ISC_STATUS isc_cant_modify_sysobj = 335545076L;
|
||||
const ISC_STATUS isc_server_misconfigured = 335545077L;
|
||||
const ISC_STATUS isc_alter_role = 335545078L;
|
||||
const ISC_STATUS isc_map_already_exists = 335545079L;
|
||||
const ISC_STATUS isc_map_not_exists = 335545080L;
|
||||
const ISC_STATUS isc_map_load = 335545081L;
|
||||
const ISC_STATUS isc_map_aster = 335545082L;
|
||||
const ISC_STATUS isc_map_multi = 335545083L;
|
||||
const ISC_STATUS isc_map_undefined = 335545084L;
|
||||
const ISC_STATUS isc_baddpb_damaged_mode = 335545085L;
|
||||
const ISC_STATUS isc_baddpb_buffers_range = 335545086L;
|
||||
const ISC_STATUS isc_baddpb_temp_buffers = 335545087L;
|
||||
const ISC_STATUS isc_gfix_db_name = 335740929L;
|
||||
const ISC_STATUS isc_gfix_invalid_sw = 335740930L;
|
||||
const ISC_STATUS isc_gfix_incmp_sw = 335740932L;
|
||||
@ -1158,6 +1169,7 @@ const ISC_STATUS isc_dsql_alter_user_failed = 336397318L;
|
||||
const ISC_STATUS isc_dsql_grant_failed = 336397319L;
|
||||
const ISC_STATUS isc_dsql_revoke_failed = 336397320L;
|
||||
const ISC_STATUS isc_dsql_cte_recursive_aggregate = 336397321L;
|
||||
const ISC_STATUS isc_dsql_mapping_failed = 336397322L;
|
||||
const ISC_STATUS isc_gsec_cant_open_db = 336723983L;
|
||||
const ISC_STATUS isc_gsec_switches_error = 336723984L;
|
||||
const ISC_STATUS isc_gsec_no_op_spec = 336723985L;
|
||||
@ -1259,7 +1271,7 @@ const ISC_STATUS isc_trace_switch_user_only = 337182757L;
|
||||
const ISC_STATUS isc_trace_switch_param_miss = 337182758L;
|
||||
const ISC_STATUS isc_trace_param_act_notcompat = 337182759L;
|
||||
const ISC_STATUS isc_trace_mandatory_switch_miss = 337182760L;
|
||||
const ISC_STATUS isc_err_max = 1203;
|
||||
const ISC_STATUS isc_err_max = 1215;
|
||||
|
||||
#else /* c definitions */
|
||||
|
||||
@ -2041,6 +2053,17 @@ const ISC_STATUS isc_err_max = 1203;
|
||||
#define isc_forupdate_systbl 335545074L
|
||||
#define isc_forupdate_temptbl 335545075L
|
||||
#define isc_cant_modify_sysobj 335545076L
|
||||
#define isc_server_misconfigured 335545077L
|
||||
#define isc_alter_role 335545078L
|
||||
#define isc_map_already_exists 335545079L
|
||||
#define isc_map_not_exists 335545080L
|
||||
#define isc_map_load 335545081L
|
||||
#define isc_map_aster 335545082L
|
||||
#define isc_map_multi 335545083L
|
||||
#define isc_map_undefined 335545084L
|
||||
#define isc_baddpb_damaged_mode 335545085L
|
||||
#define isc_baddpb_buffers_range 335545086L
|
||||
#define isc_baddpb_temp_buffers 335545087L
|
||||
#define isc_gfix_db_name 335740929L
|
||||
#define isc_gfix_invalid_sw 335740930L
|
||||
#define isc_gfix_incmp_sw 335740932L
|
||||
@ -2387,6 +2410,7 @@ const ISC_STATUS isc_err_max = 1203;
|
||||
#define isc_dsql_grant_failed 336397319L
|
||||
#define isc_dsql_revoke_failed 336397320L
|
||||
#define isc_dsql_cte_recursive_aggregate 336397321L
|
||||
#define isc_dsql_mapping_failed 336397322L
|
||||
#define isc_gsec_cant_open_db 336723983L
|
||||
#define isc_gsec_switches_error 336723984L
|
||||
#define isc_gsec_no_op_spec 336723985L
|
||||
@ -2488,7 +2512,7 @@ const ISC_STATUS isc_err_max = 1203;
|
||||
#define isc_trace_switch_param_miss 337182758L
|
||||
#define isc_trace_param_act_notcompat 337182759L
|
||||
#define isc_trace_mandatory_switch_miss 337182760L
|
||||
#define isc_err_max 1203
|
||||
#define isc_err_max 1215
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -621,3 +621,29 @@
|
||||
const USHORT f_sec_attr_value = 2;
|
||||
|
||||
|
||||
// Relation 45 (RDB$MAP)
|
||||
|
||||
const USHORT f_map_name = 0;
|
||||
const USHORT f_map_using = 1;
|
||||
const USHORT f_map_plugin = 2;
|
||||
const USHORT f_map_db = 3;
|
||||
const USHORT f_map_from_type = 4;
|
||||
const USHORT f_map_from = 5;
|
||||
const USHORT f_map_to_type = 6;
|
||||
const USHORT f_map_to = 7;
|
||||
const USHORT f_map_sys_flag = 8;
|
||||
const USHORT f_map_desc = 9;
|
||||
|
||||
|
||||
// Relation 46 (SEC$GLOBAL_MAP)
|
||||
|
||||
const USHORT f_sec_map_name = 0;
|
||||
const USHORT f_sec_map_using = 1;
|
||||
const USHORT f_sec_map_plugin = 2;
|
||||
const USHORT f_sec_map_db = 3;
|
||||
const USHORT f_sec_map_from_type = 4;
|
||||
const USHORT f_sec_map_from = 5;
|
||||
const USHORT f_sec_map_to_type = 6;
|
||||
const USHORT f_sec_map_to = 7;
|
||||
|
||||
|
||||
|
@ -781,6 +781,17 @@ Data source : @4"}, /* eds_statement */
|
||||
{335545074, "Cannot select system table @1 for update WITH LOCK"}, /* forupdate_systbl */
|
||||
{335545075, "Cannot select temporary table @1 for update WITH LOCK"}, /* forupdate_temptbl */
|
||||
{335545076, "System @1 @2 cannot be modified"}, /* cant_modify_sysobj */
|
||||
{335545077, "Server misconfigured - contact administrator please"}, /* server_misconfigured */
|
||||
{335545078, "Deprecated backward compatibility ALTER ROLE ... SET/DROP AUTO ADMIN mapping may be used only for RDB$ADMIN role"}, /* alter_role */
|
||||
{335545079, "Mapping @1 already exists"}, /* map_already_exists */
|
||||
{335545080, "Mapping @1 does not exist"}, /* map_not_exists */
|
||||
{335545081, "@1 failed when loading mapping cache"}, /* map_load */
|
||||
{335545082, "Invalid name <*> in authentication block"}, /* map_aster */
|
||||
{335545083, "Multiple maps found for @1"}, /* map_multi */
|
||||
{335545084, "Undefined mapping result - more than one different results found"}, /* map_undefined */
|
||||
{335545085, "Incompatible mode of attachment to damaged database"}, /* baddpb_damaged_mode */
|
||||
{335545086, "Attempt to set in database number of buffers which is out of acceptable range [@1:@2]"}, /* baddpb_buffers_range */
|
||||
{335545087, "Attempt to temporarily set number of buffers less than @1"}, /* baddpb_temp_buffers */
|
||||
{335740929, "data base file name (@1) already given"}, /* gfix_db_name */
|
||||
{335740930, "invalid switch @1"}, /* gfix_invalid_sw */
|
||||
{335740932, "incompatible switch combination"}, /* gfix_incmp_sw */
|
||||
@ -1127,6 +1138,7 @@ Data source : @4"}, /* eds_statement */
|
||||
{336397319, "GRANT failed"}, /* dsql_grant_failed */
|
||||
{336397320, "REVOKE failed"}, /* dsql_revoke_failed */
|
||||
{336397321, "Recursive member of CTE cannot use aggregate or window function"}, /* dsql_cte_recursive_aggregate */
|
||||
{336397322, "@2 MAPPING @1 failed"}, /* dsql_mapping_failed */
|
||||
{336723983, "unable to open database"}, /* gsec_cant_open_db */
|
||||
{336723984, "error in switch specifications"}, /* gsec_switches_error */
|
||||
{336723985, "no operation specified"}, /* gsec_no_op_spec */
|
||||
|
@ -777,6 +777,17 @@ static const struct {
|
||||
{335545074, -901}, /* 754 forupdate_systbl */
|
||||
{335545075, -901}, /* 755 forupdate_temptbl */
|
||||
{335545076, -901}, /* 756 cant_modify_sysobj */
|
||||
{335545077, -901}, /* 757 server_misconfigured */
|
||||
{335545078, -901}, /* 758 alter_role */
|
||||
{335545079, -901}, /* 759 map_already_exists */
|
||||
{335545080, -901}, /* 760 map_not_exists */
|
||||
{335545081, -901}, /* 761 map_load */
|
||||
{335545082, -901}, /* 762 map_aster */
|
||||
{335545083, -901}, /* 763 map_multi */
|
||||
{335545084, -901}, /* 764 map_undefined */
|
||||
{335545085, -924}, /* 765 baddpb_damaged_mode */
|
||||
{335545086, -924}, /* 766 baddpb_buffers_range */
|
||||
{335545087, -924}, /* 767 baddpb_temp_buffers */
|
||||
{335740929, -901}, /* 1 gfix_db_name */
|
||||
{335740930, -901}, /* 2 gfix_invalid_sw */
|
||||
{335740932, -901}, /* 4 gfix_incmp_sw */
|
||||
@ -1123,6 +1134,7 @@ static const struct {
|
||||
{336397319, -901}, /* 1031 dsql_grant_failed */
|
||||
{336397320, -901}, /* 1032 dsql_revoke_failed */
|
||||
{336397321, -104}, /* 1033 dsql_cte_recursive_aggregate */
|
||||
{336397322, -901}, /* 1034 dsql_mapping_failed */
|
||||
{336723983, -901}, /* 15 gsec_cant_open_db */
|
||||
{336723984, -901}, /* 16 gsec_switches_error */
|
||||
{336723985, -901}, /* 17 gsec_no_op_spec */
|
||||
|
@ -777,6 +777,17 @@ static const struct {
|
||||
{335545074, "HY000"}, // 754 forupdate_systbl
|
||||
{335545075, "HY000"}, // 755 forupdate_temptbl
|
||||
{335545076, "42000"}, // 756 cant_modify_sysobj
|
||||
{335545077, "08004"}, // 757 server_misconfigured
|
||||
{335545078, "0A000"}, // 758 alter_role
|
||||
{335545079, "42S01"}, // 759 map_already_exists
|
||||
{335545080, "42S01"}, // 760 map_not_exists
|
||||
{335545081, "08004"}, // 761 map_load
|
||||
{335545082, "08004"}, // 762 map_aster
|
||||
{335545083, "08004"}, // 763 map_multi
|
||||
{335545084, "08004"}, // 764 map_undefined
|
||||
{335545085, "HY000"}, // 765 baddpb_damaged_mode
|
||||
{335545086, "HY000"}, // 766 baddpb_buffers_range
|
||||
{335545087, "HY000"}, // 767 baddpb_temp_buffers
|
||||
{335740929, "00000"}, // 1 gfix_db_name
|
||||
{335740930, "00000"}, // 2 gfix_invalid_sw
|
||||
{335740932, "00000"}, // 4 gfix_incmp_sw
|
||||
@ -1123,6 +1134,7 @@ static const struct {
|
||||
{336397319, "42000"}, // 1031 dsql_grant_failed
|
||||
{336397320, "42000"}, // 1032 dsql_revoke_failed
|
||||
{336397321, "42000"}, // 1033 dsql_cte_recursive_aggregate
|
||||
{336397322, "42000"}, // 1034 dsql_mapping_failed
|
||||
{336723983, "00000"}, // 15 gsec_cant_open_db
|
||||
{336723984, "00000"}, // 16 gsec_switches_error
|
||||
{336723985, "00000"}, // 17 gsec_no_op_spec
|
||||
|
@ -196,6 +196,7 @@ int EXTRACT_ddl(LegacyTables flag, const SCHAR* tabname)
|
||||
listDomainConstraints();
|
||||
list_all_triggers();
|
||||
list_all_grants();
|
||||
SHOW_maps(true, "");
|
||||
SHOW_comments(false); // Let's make this an option later.
|
||||
}
|
||||
|
||||
|
@ -268,6 +268,8 @@ const int NO_GRANT_ON_FUN = 180; // There is no privilege granted on function
|
||||
const int REPORT_NEW1 = 181; // Current memory = !\nDelta memory = !\nMax memory = !\nElapsed time= ~ sec\n
|
||||
const int REPORT_NEW2 = 182; // Cpu = ~ sec\n (skipped on windows)
|
||||
const int REPORT_NEW3 = 183; // Buffers = !\nReads = !\nWrites = !\nFetches = !\n
|
||||
const int NO_MAP = 184; // There is no mapping from @1 in this database
|
||||
const int NO_MAPS = 185; // There are no mappings in this database
|
||||
|
||||
|
||||
// Initialize types
|
||||
|
@ -1458,6 +1458,8 @@ void SHOW_print_metadata_text_blob(FILE* fp, ISC_QUAD* blobid, bool escape_squot
|
||||
|
||||
if ((!fbStatus->isSuccess()) && fbStatus->get()[1] != isc_segstr_eof)
|
||||
ISQL_errmsg(fbStatus);
|
||||
|
||||
blob->close(fbStatus);
|
||||
}
|
||||
|
||||
|
||||
@ -1485,7 +1487,7 @@ processing_state SHOW_metadata(const SCHAR* const* cmd, SCHAR** lcmd)
|
||||
role, table, view, system, index, domain, exception,
|
||||
filter, function, generator, grant, procedure, trigger,
|
||||
check, database, comment, dependency, collation, security_class,
|
||||
users, package, schema, wrong
|
||||
users, package, schema, map, wrong
|
||||
};
|
||||
ShowOptions(const optionsMap* inmap, size_t insize, int wrongval)
|
||||
: OptionsBase(inmap, insize, wrongval)
|
||||
@ -1541,7 +1543,8 @@ processing_state SHOW_metadata(const SCHAR* const* cmd, SCHAR** lcmd)
|
||||
{ShowOptions::security_class, "SECCLASSES", 6},
|
||||
{ShowOptions::users, "USERS", 0},
|
||||
{ShowOptions::package, "PACKAGES", 4},
|
||||
{ShowOptions::schema, "SCHEMAS", 4}
|
||||
{ShowOptions::schema, "SCHEMAS", 4},
|
||||
{ShowOptions::map, "MAPPING", 3}
|
||||
};
|
||||
|
||||
const ShowOptions showoptions(options, FB_NELEM(options), ShowOptions::wrong);
|
||||
@ -2134,6 +2137,24 @@ processing_state SHOW_metadata(const SCHAR* const* cmd, SCHAR** lcmd)
|
||||
}
|
||||
break;
|
||||
|
||||
case ShowOptions::map:
|
||||
if (*cmd[2] == '"')
|
||||
{
|
||||
remove_delimited_double_quotes(lcmd[2]);
|
||||
ret = SHOW_maps(false, lcmd[2]);
|
||||
}
|
||||
else
|
||||
ret = SHOW_maps(false, cmd[2]);
|
||||
|
||||
if (ret == OBJECT_NOT_FOUND)
|
||||
{
|
||||
if (*cmd[2])
|
||||
key = NO_MAP;
|
||||
else
|
||||
key = NO_MAPS;
|
||||
}
|
||||
break;
|
||||
|
||||
case ShowOptions::schema:
|
||||
return ps_ERR;
|
||||
break;
|
||||
@ -4275,6 +4296,149 @@ static processing_state show_packages(const SCHAR* package_name)
|
||||
}
|
||||
|
||||
|
||||
static void printIdent(bool quote, char* ident, const char* format = NULL)
|
||||
{
|
||||
fb_utils::exact_name(ident);
|
||||
char quotedIdent[BUFFER_LENGTH128];
|
||||
if (quote && isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION)
|
||||
{
|
||||
IUTILS_copy_SQL_id(ident, quotedIdent, DBL_QUOTE);
|
||||
ident = quotedIdent;
|
||||
}
|
||||
|
||||
isqlGlob.printf(format ? format : "%s", ident);
|
||||
}
|
||||
|
||||
|
||||
static void printMap(bool extract, bool global, char* name, char* usng, char* plugin, char* db,
|
||||
char* fromType, char* from, short toType, char* to)
|
||||
{
|
||||
if (extract)
|
||||
{
|
||||
isqlGlob.printf("CREATE ");
|
||||
if (global)
|
||||
isqlGlob.printf("GLOBAL ");
|
||||
}
|
||||
printIdent(extract, name, extract ? "MAPPING %s " : "%s ");
|
||||
|
||||
isqlGlob.printf("USING ");
|
||||
switch (usng[0])
|
||||
{
|
||||
case 'P':
|
||||
if (!plugin)
|
||||
isqlGlob.printf("ANY PLUGIN ");
|
||||
else
|
||||
printIdent(extract, plugin, "PLUGIN %s ");
|
||||
break;
|
||||
case 'S':
|
||||
isqlGlob.printf("ANY PLUGIN SERVERWIDE ");
|
||||
break;
|
||||
case '*':
|
||||
isqlGlob.printf("* ");
|
||||
break;
|
||||
case 'M':
|
||||
isqlGlob.printf("MAPPING ");
|
||||
break;
|
||||
default:
|
||||
isqlGlob.printf("/*unknown = %c*/ ", usng[0]);
|
||||
}
|
||||
|
||||
if (db)
|
||||
printIdent(extract, db, "IN %s ");
|
||||
|
||||
fb_utils::exact_name(from);
|
||||
bool anyObj = strcmp(from, "*") == 0;
|
||||
isqlGlob.printf("FROM %s", anyObj ? "ANY " : "");
|
||||
printIdent(extract, fromType, "%s ");
|
||||
if (!anyObj)
|
||||
printIdent(extract, from, "%s ");
|
||||
|
||||
isqlGlob.printf("TO %s ", toType ? "ROLE" : "USER");
|
||||
if (to)
|
||||
printIdent(extract, to);
|
||||
isqlGlob.printf("%s%s", extract ? ";" : "", NEWLINE);
|
||||
}
|
||||
|
||||
|
||||
processing_state SHOW_maps(bool extract, const SCHAR* map_name)
|
||||
{
|
||||
/*************************************
|
||||
*
|
||||
* s h o w _ m a p s
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Show all maps or maps to map_name
|
||||
************************************/
|
||||
if (isqlGlob.major_ods < ODS_VERSION12)
|
||||
return OBJECT_NOT_FOUND;
|
||||
|
||||
bool first = true;
|
||||
|
||||
// List all mappings
|
||||
FOR M IN RDB$MAP WITH
|
||||
(M.RDB$SYSTEM_FLAG NE 1 OR M.RDB$SYSTEM_FLAG MISSING)
|
||||
SORTED BY M.RDB$MAP_NAME
|
||||
|
||||
Firebird::NoCaseString nm = M.RDB$MAP_NAME;
|
||||
nm.trim();
|
||||
|
||||
if ((!*map_name) || (nm == map_name))
|
||||
{
|
||||
if (first && extract)
|
||||
isqlGlob.printf("%s/* Mapping security objects for this database */%s", NEWLINE, NEWLINE);
|
||||
first = false;
|
||||
|
||||
printMap(extract, false, M.RDB$MAP_NAME, M.RDB$MAP_USING,
|
||||
M.RDB$MAP_PLUGIN.NULL ? NULL : M.RDB$MAP_PLUGIN,
|
||||
M.RDB$MAP_DB.NULL ? NULL : M.RDB$MAP_DB,
|
||||
M.RDB$MAP_FROM_TYPE, M.RDB$MAP_FROM,
|
||||
M.RDB$MAP_TO_TYPE, M.RDB$MAP_TO.NULL ? NULL : M.RDB$MAP_TO);
|
||||
}
|
||||
END_FOR
|
||||
ON_ERROR
|
||||
ISQL_errmsg(fbStatus);
|
||||
return ps_ERR;
|
||||
END_ERROR;
|
||||
|
||||
bool firstGlobal = true;
|
||||
|
||||
// List global mappings
|
||||
FOR M IN SEC$GLOBAL_MAP
|
||||
SORTED BY M.SEC$MAP_NAME
|
||||
|
||||
Firebird::NoCaseString nm = M.SEC$MAP_NAME;
|
||||
nm.trim();
|
||||
|
||||
if ((!*map_name) || (nm == map_name))
|
||||
{
|
||||
if (firstGlobal)
|
||||
{
|
||||
const char* sep = extract ? "/" : "**";
|
||||
isqlGlob.printf("%s%s* Global mapping *%s%s",
|
||||
(first && (!extract)) ? "" : NEWLINE, sep, sep, NEWLINE);
|
||||
firstGlobal = false;
|
||||
}
|
||||
|
||||
first = false;
|
||||
|
||||
printMap(extract, true, M.SEC$MAP_NAME, M.SEC$MAP_USING,
|
||||
M.SEC$MAP_PLUGIN.NULL ? NULL : M.SEC$MAP_PLUGIN,
|
||||
M.SEC$MAP_DB.NULL ? NULL : M.SEC$MAP_DB,
|
||||
M.SEC$MAP_FROM_TYPE, M.SEC$MAP_FROM,
|
||||
M.SEC$MAP_TO_TYPE, M.SEC$MAP_TO.NULL ? NULL : M.SEC$MAP_TO);
|
||||
}
|
||||
END_FOR
|
||||
ON_ERROR
|
||||
ISQL_errmsg(fbStatus);
|
||||
return ps_ERR;
|
||||
END_ERROR;
|
||||
|
||||
return first ? OBJECT_NOT_FOUND : SKIP;
|
||||
}
|
||||
|
||||
|
||||
static processing_state show_proc(const SCHAR* procname)
|
||||
{
|
||||
/**************************************
|
||||
|
@ -37,5 +37,6 @@ void SHOW_print_metadata_text_blob(FILE*, ISC_QUAD*, bool escape_squote = false)
|
||||
processing_state SHOW_metadata(const SCHAR* const*, SCHAR**);
|
||||
void SHOW_read_owner();
|
||||
const Firebird::string SHOW_trigger_action(SINT64);
|
||||
processing_state SHOW_maps(bool extract, const SCHAR* map_name);
|
||||
|
||||
#endif // ISQL_SHOW_PROTO_H
|
||||
|
1116
src/jrd/Mapping.cpp
Normal file
1116
src/jrd/Mapping.cpp
Normal file
File diff suppressed because it is too large
Load Diff
68
src/jrd/Mapping.h
Normal file
68
src/jrd/Mapping.h
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* PROGRAM: JRD access method
|
||||
* MODULE: Mapping.h
|
||||
* DESCRIPTION: Maps names in authentication block
|
||||
*
|
||||
* The contents of this file are subject to the Initial
|
||||
* Developer's Public License Version 1.0 (the "License");
|
||||
* you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
|
||||
*
|
||||
* Software distributed under the License is distributed AS IS,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing rights
|
||||
* and limitations under the License.
|
||||
*
|
||||
* The Original Code was created by Alex Peshkov
|
||||
* for the Firebird Open Source RDBMS project.
|
||||
*
|
||||
* Copyright (c) 2014 Alex Peshkov <peshkoff at mail.ru>
|
||||
* and all contributors signed below.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef JRD_MAPPING
|
||||
#define JRD_MAPPING
|
||||
|
||||
#include "../common/classes/alloc.h"
|
||||
#include "../common/classes/fb_string.h"
|
||||
#include "../common/classes/ClumpletReader.h"
|
||||
#include "../jrd/recsrc/RecordSource.h"
|
||||
#include "../jrd/DatabaseSnapshot.h"
|
||||
|
||||
namespace Jrd {
|
||||
|
||||
void mapUser(Firebird::string& name, Firebird::string& trusted_role, Firebird::string* auth_method,
|
||||
Firebird::AuthReader::AuthBlock* newAuthBlock, const Firebird::AuthReader::AuthBlock& authBlock,
|
||||
const char* db, const char* securityDb);
|
||||
void flashMap(const char* dbName);
|
||||
|
||||
class GlobalMappingScan: public VirtualTableScan
|
||||
{
|
||||
public:
|
||||
GlobalMappingScan(CompilerScratch* csb, const Firebird::string& name, StreamType stream)
|
||||
: VirtualTableScan(csb, name, stream)
|
||||
{}
|
||||
|
||||
protected:
|
||||
const Format* getFormat(thread_db* tdbb, jrd_rel* relation) const;
|
||||
bool retrieveRecord(thread_db* tdbb, jrd_rel* relation, FB_UINT64 position, Record* record) const;
|
||||
};
|
||||
|
||||
class MappingList : public DataDump
|
||||
{
|
||||
public:
|
||||
MappingList(jrd_tra* tra);
|
||||
|
||||
RecordBuffer* getList(thread_db* tdbb, jrd_rel* relation);
|
||||
};
|
||||
|
||||
} // namespace Jrd
|
||||
|
||||
|
||||
#endif // JRD_MAPPING
|
@ -88,12 +88,6 @@ UserManagement::UserManagement(jrd_tra* tra)
|
||||
return att->att_user->usr_sql_role_name.c_str();
|
||||
}
|
||||
|
||||
int FB_CARG forceAdmin()
|
||||
{
|
||||
return ((att->att_user->usr_flags & USR_trole) &&
|
||||
att->att_user->usr_sql_role_name == ADMIN_ROLE) ? 1 : 0;
|
||||
}
|
||||
|
||||
const char* FB_CARG networkProtocol()
|
||||
{
|
||||
return att->att_network_protocol.c_str();
|
||||
|
@ -81,7 +81,7 @@ const char* const ISC_USER = "ISC_USER";
|
||||
const char* const ISC_PASSWORD = "ISC_PASSWORD";
|
||||
|
||||
const char* const NULL_ROLE = "NONE";
|
||||
const char* const ADMIN_ROLE = "RDB$ADMIN";
|
||||
#define ADMIN_ROLE "RDB$ADMIN" // It's used in C-string concatenations
|
||||
|
||||
// User name assigned to any user granted USR_locksmith rights.
|
||||
// If this name is changed, modify also the trigger in
|
||||
@ -91,7 +91,6 @@ const char* const SYSDBA_USER_NAME = "SYSDBA";
|
||||
// This temporary set of flags is needed to implement minimum form of
|
||||
// ALTER ROLE RDB$ADMIN ADD/DROP SYSTEM_NAME "Domain Admins".
|
||||
// Value 1 is skipped because rdb$system_flag = 1 is used in all other cases.
|
||||
const SSHORT ROLE_FLAG_MAY_TRUST = 2;
|
||||
const SSHORT ROLE_FLAG_DBO = 4;
|
||||
|
||||
const char* const PRIMARY_KEY = "PRIMARY KEY";
|
||||
@ -359,7 +358,10 @@ static const char* const DDL_TRIGGER_ACTION_NAMES[][2] =
|
||||
{"ALTER", "PACKAGE"},
|
||||
{"DROP", "PACKAGE"},
|
||||
{"CREATE", "PACKAGE BODY"},
|
||||
{"DROP", "PACKAGE BODY"}
|
||||
{"DROP", "PACKAGE BODY"},
|
||||
{"CREATE", "MAPPING"},
|
||||
{"ALTER", "MAPPING"},
|
||||
{"DROP", "MAPPING"}
|
||||
};
|
||||
|
||||
const int DDL_TRIGGER_BEFORE = 0;
|
||||
@ -407,6 +409,9 @@ const int DDL_TRIGGER_ALTER_PACKAGE = 41;
|
||||
const int DDL_TRIGGER_DROP_PACKAGE = 42;
|
||||
const int DDL_TRIGGER_CREATE_PACKAGE_BODY = 43;
|
||||
const int DDL_TRIGGER_DROP_PACKAGE_BODY = 44;
|
||||
const int DDL_TRIGGER_CREATE_MAPPING = 45;
|
||||
const int DDL_TRIGGER_ALTER_MAPPING = 46;
|
||||
const int DDL_TRIGGER_DROP_MAPPING = 47;
|
||||
|
||||
// that's how database trigger action types are encoded
|
||||
// (TRIGGER_TYPE_DB | type)
|
||||
@ -418,11 +423,12 @@ const int DDL_TRIGGER_DROP_PACKAGE_BODY = 44;
|
||||
// is specified by the client application
|
||||
#define USERNAME_SWITCH "USER"
|
||||
#define PASSWORD_SWITCH "PASSWORD"
|
||||
/*
|
||||
#define TRUSTED_USER_SWITCH "TRUSTED_SVC"
|
||||
#define TRUSTED_USER_SWITCH_LEN (sizeof(TRUSTED_USER_SWITCH) - 1)
|
||||
#define TRUSTED_ROLE_SWITCH "TRUSTED_ROLE"
|
||||
#define TRUSTED_ROLE_SWITCH_LEN (sizeof(TRUSTED_ROLE_SWITCH) - 1)
|
||||
|
||||
*/
|
||||
const TraNumber MAX_TRA_NUMBER = ~TraNumber(0);
|
||||
|
||||
#endif // JRD_CONSTANTS_H
|
||||
|
@ -126,6 +126,7 @@
|
||||
#include "../common/utils_proto.h"
|
||||
#include "../common/classes/Hash.h"
|
||||
#include "../jrd/CryptoManager.h"
|
||||
#include "../jrd/Mapping.h"
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
@ -153,7 +154,7 @@ namespace Jrd {
|
||||
|
||||
typedef Hash<
|
||||
DeferredWork,
|
||||
DefaultHash<DeferredWork>::DEFAULT_SIZE,
|
||||
DEFAULT_HASH_SIZE,
|
||||
DeferredWork,
|
||||
DefaultKeyValue<DeferredWork>,
|
||||
DeferredWork
|
||||
@ -311,7 +312,7 @@ class DfwSavePoint;
|
||||
|
||||
typedef Hash<
|
||||
DfwSavePoint,
|
||||
DefaultHash<DfwSavePoint>::DEFAULT_SIZE,
|
||||
DEFAULT_HASH_SIZE,
|
||||
SLONG,
|
||||
DfwSavePoint
|
||||
> DfwSavePointHash;
|
||||
@ -398,6 +399,7 @@ static bool drop_package_body(thread_db*, SSHORT, DeferredWork*, jrd_tra*);
|
||||
static bool grant_privileges(thread_db*, SSHORT, DeferredWork*, jrd_tra*);
|
||||
static bool db_crypt(thread_db*, SSHORT, DeferredWork*, jrd_tra*);
|
||||
static bool set_linger(thread_db*, SSHORT, DeferredWork*, jrd_tra*);
|
||||
static bool flash_cache(thread_db*, SSHORT, DeferredWork*, jrd_tra*);
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
@ -969,6 +971,7 @@ static const deferred_task task_table[] =
|
||||
{ dfw_store_view_context_type, store_view_context_type },
|
||||
{ dfw_db_crypt, db_crypt },
|
||||
{ dfw_set_linger, set_linger },
|
||||
{ dfw_flash_cache, flash_cache },
|
||||
{ dfw_null, NULL }
|
||||
};
|
||||
|
||||
@ -2033,6 +2036,35 @@ static bool set_linger(thread_db* tdbb, SSHORT phase, DeferredWork* work, jrd_tr
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool flash_cache(thread_db* tdbb, SSHORT phase, DeferredWork* work, jrd_tra*)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
* s e t _ l i n g e r
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
* Set linger interval in Database block.
|
||||
*
|
||||
**************************************/
|
||||
|
||||
SET_TDBB(tdbb);
|
||||
Database* const dbb = tdbb->getDatabase();
|
||||
|
||||
switch (phase)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
return true;
|
||||
|
||||
case 3:
|
||||
flashMap(dbb->dbb_filename.c_str());
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool check_not_null(thread_db* tdbb, SSHORT phase, DeferredWork* work, jrd_tra* transaction)
|
||||
{
|
||||
/**************************************
|
||||
|
@ -162,7 +162,8 @@ enum drq_type_t
|
||||
drq_l_arg_src, // lookup a function argument source
|
||||
drq_l_prm_coll, // lookup procedure parameter collation
|
||||
drq_l_arg_coll, // lookup function argument collation
|
||||
drq_m_map, // modify os=>db names mapping
|
||||
drq_map_sto, // store login mapping
|
||||
drq_map_mod, // modify/erase login mapping
|
||||
drq_l_idx_name, // lookup index name
|
||||
drq_l_collation, // DSQL/DdlNodes: lookup collation
|
||||
drq_m_charset, // DSQL/DdlNodes: modify character set
|
||||
|
@ -313,15 +313,10 @@ void Connection::generateDPB(thread_db* tdbb, ClumpletWriter& dpb,
|
||||
const Jrd::Attachment* attachment = tdbb->getAttachment();
|
||||
dpb.insertInt(isc_dpb_ext_call_depth, attachment->att_ext_call_depth + 1);
|
||||
|
||||
const string& attUser = attachment->att_user->usr_user_name;
|
||||
const string& attRole = attachment->att_user->usr_sql_role_name;
|
||||
|
||||
if ((m_provider.getFlags() & prvTrustedAuth) &&
|
||||
(user.isEmpty() || user == attUser) && pwd.isEmpty() &&
|
||||
(role.isEmpty() || role == attRole))
|
||||
user.isEmpty() && pwd.isEmpty() && role.isEmpty())
|
||||
{
|
||||
dpb.insertString(isc_dpb_trusted_auth, attUser);
|
||||
dpb.insertString(isc_dpb_trusted_role, attRole);
|
||||
attachment->att_user->populateDpb(dpb);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -340,6 +335,8 @@ void Connection::generateDPB(thread_db* tdbb, ClumpletWriter& dpb,
|
||||
if (cs) {
|
||||
dpb.insertString(isc_dpb_lc_ctype, cs->getName());
|
||||
}
|
||||
|
||||
// remote network address???
|
||||
}
|
||||
|
||||
bool Connection::isSameDatabase(thread_db* tdbb, const string& dbName,
|
||||
|
@ -180,3 +180,11 @@
|
||||
FIELD(fld_auth_method , nam_auth_method , dtype_varying , 255 , dsc_text_type_ascii , NULL , true)
|
||||
|
||||
FIELD(fld_linger , nam_linger , dtype_long , sizeof(SLONG) , 0 , NULL , true)
|
||||
|
||||
FIELD(fld_map_name , nam_map_name , dtype_text , MAX_SQL_IDENTIFIER_LEN , dsc_text_type_metadata , NULL , false)
|
||||
FIELD(fld_map_using , nam_map_using, dtype_text, 1 , dsc_text_type_metadata , NULL , false)
|
||||
FIELD(fld_map_plugin , nam_map_plugin, dtype_text, MAX_SQL_IDENTIFIER_LEN , dsc_text_type_metadata , NULL , true)
|
||||
FIELD(fld_map_db , nam_map_db, dtype_text, MAX_SQL_IDENTIFIER_LEN , dsc_text_type_metadata , NULL , true)
|
||||
FIELD(fld_map_from_type , nam_map_from_type , dtype_text, MAX_SQL_IDENTIFIER_LEN , dsc_text_type_metadata , NULL , false)
|
||||
FIELD(fld_map_from , nam_map_from, dtype_text, 255 , dsc_text_type_metadata , NULL , true)
|
||||
FIELD(fld_map_to , nam_map_to, dtype_text, MAX_SQL_IDENTIFIER_LEN , dsc_text_type_metadata , NULL , true)
|
||||
|
@ -278,6 +278,10 @@ static const struct ini_idx_t indices[] =
|
||||
INDEX(51, rel_args, 0, 2)
|
||||
SEGMENT(f_arg_rname, idx_metadata), // relation name
|
||||
SEGMENT(f_arg_fname, idx_metadata) // field name
|
||||
}},
|
||||
// define index RDB$INDEX_52 for RDB$MAP RDB$MAP_NAME;
|
||||
INDEX(52, rel_map, 0, 1)
|
||||
SEGMENT(f_map_name, idx_metadata) // mapping name
|
||||
}}
|
||||
};
|
||||
|
||||
|
@ -109,6 +109,7 @@
|
||||
#include "../jrd/event_proto.h"
|
||||
#include "../yvalve/why_proto.h"
|
||||
#include "../jrd/flags.h"
|
||||
#include "../jrd/Mapping.h"
|
||||
|
||||
#include "../jrd/Database.h"
|
||||
|
||||
@ -860,7 +861,7 @@ public:
|
||||
string dpb_config;
|
||||
|
||||
public:
|
||||
static const ULONG DPB_FLAGS_MASK = DBB_damaged | DBB_security_db;
|
||||
static const ULONG DPB_FLAGS_MASK = DBB_damaged;
|
||||
|
||||
DatabaseOptions()
|
||||
{
|
||||
@ -1291,7 +1292,7 @@ JAttachment* FB_CARG JProvider::attachDatabase(IStatus* user_status, const char*
|
||||
}
|
||||
|
||||
// Check for correct credentials supplied
|
||||
getUserInfo(userId, options, org_filename.c_str(), &config);
|
||||
getUserInfo(userId, options, expanded_name.c_str(), &config);
|
||||
}
|
||||
catch (const Exception& ex)
|
||||
{
|
||||
@ -1442,14 +1443,13 @@ JAttachment* FB_CARG JProvider::attachDatabase(IStatus* user_status, const char*
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((dbb->dbb_flags & DatabaseOptions::DPB_FLAGS_MASK) != options.dpb_flags)
|
||||
if ((dbb->dbb_flags & DatabaseOptions::DPB_FLAGS_MASK) !=
|
||||
(options.dpb_flags & DatabaseOptions::DPB_FLAGS_MASK))
|
||||
{
|
||||
// looks like someone tries to attach incompatibly
|
||||
Arg::Gds err(isc_bad_dpb_content);
|
||||
if ((dbb->dbb_flags & DBB_damaged) != (options.dpb_flags & DBB_damaged))
|
||||
err << Arg::Gds(isc_random) << "incompatible damaged database mode";
|
||||
if ((dbb->dbb_flags & DBB_security_db) != (options.dpb_flags & DBB_security_db))
|
||||
err << Arg::Gds(isc_random) << "incompatible security database mode";
|
||||
err << Arg::Gds(isc_baddpb_damaged_mode);
|
||||
err.raise();
|
||||
}
|
||||
|
||||
@ -2387,7 +2387,7 @@ JAttachment* FB_CARG JProvider::createDatabase(IStatus* user_status, const char*
|
||||
}
|
||||
|
||||
// Check for correct credentials supplied
|
||||
getUserInfo(userId, options, org_filename.c_str(), &config);
|
||||
getUserInfo(userId, options, expanded_name.c_str(), &config);
|
||||
}
|
||||
catch (const Exception& ex)
|
||||
{
|
||||
@ -5471,7 +5471,7 @@ void DatabaseOptions::get(const UCHAR* dpb, USHORT dpb_length, bool& invalid_cli
|
||||
if (dpb_page_buffers &&
|
||||
(dpb_page_buffers < MIN_PAGE_BUFFERS || dpb_page_buffers > MAX_PAGE_BUFFERS))
|
||||
{
|
||||
ERR_post(Arg::Gds(isc_bad_dpb_content));
|
||||
ERR_post(Arg::Gds(isc_bad_dpb_content) << Arg::Gds(isc_baddpb_buffers_range));
|
||||
}
|
||||
dpb_set_page_buffers = true;
|
||||
break;
|
||||
@ -5480,9 +5480,11 @@ void DatabaseOptions::get(const UCHAR* dpb, USHORT dpb_length, bool& invalid_cli
|
||||
if (!Config::getSharedCache())
|
||||
{
|
||||
dpb_buffers = rdr.getInt();
|
||||
if (dpb_buffers < 10)
|
||||
int TEMP_LIMIT = 25;
|
||||
if (dpb_buffers < TEMP_LIMIT)
|
||||
{
|
||||
ERR_post(Arg::Gds(isc_bad_dpb_content));
|
||||
ERR_post(Arg::Gds(isc_bad_dpb_content) <<
|
||||
Arg::Gds(isc_baddpb_temp_buffers) << Arg::Num(TEMP_LIMIT));
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -5662,10 +5664,7 @@ void DatabaseOptions::get(const UCHAR* dpb, USHORT dpb_length, bool& invalid_cli
|
||||
case isc_dpb_sec_attach:
|
||||
dpb_sec_attach = rdr.getInt() != 0;
|
||||
if (dpb_sec_attach)
|
||||
{
|
||||
dpb_buffers = 50;
|
||||
dpb_flags |= DBB_security_db;
|
||||
}
|
||||
break;
|
||||
|
||||
case isc_dpb_gbak_attach:
|
||||
@ -6990,6 +6989,7 @@ static void getUserInfo(UserId& user, const DatabaseOptions& options,
|
||||
}
|
||||
else
|
||||
{
|
||||
auth_method = "User name in DPB";
|
||||
if (options.dpb_trusted_login.hasData())
|
||||
{
|
||||
name = options.dpb_trusted_login;
|
||||
@ -7000,32 +7000,19 @@ static void getUserInfo(UserId& user, const DatabaseOptions& options,
|
||||
}
|
||||
else if (options.dpb_auth_block.hasData())
|
||||
{
|
||||
// stub instead mapUser(....);
|
||||
AuthReader auth(options.dpb_auth_block);
|
||||
PathName secureDb;
|
||||
if (auth.getInfo(&name, &auth_method, &secureDb))
|
||||
{
|
||||
ISC_systemToUtf8(name);
|
||||
|
||||
if (secureDb.hasData())
|
||||
{
|
||||
if (config && (secureDb != (*config)->getSecurityDatabase()))
|
||||
(Arg::Gds(isc_sec_context) << dbName).raise();
|
||||
}
|
||||
else
|
||||
{
|
||||
auth.moveNext();
|
||||
if (auth.getInfo(&trusted_role, NULL, NULL))
|
||||
ISC_systemToUtf8(trusted_role);
|
||||
}
|
||||
}
|
||||
mapUser(name, trusted_role, &auth_method, &user.usr_auth_block, options.dpb_auth_block,
|
||||
dbName, config ? (*config)->getSecurityDatabase() : NULL);
|
||||
ISC_systemToUtf8(name);
|
||||
ISC_systemToUtf8(trusted_role);
|
||||
}
|
||||
else
|
||||
{
|
||||
auth_method = "OS user name";
|
||||
wheel = ISC_get_user(&name, &id, &group);
|
||||
ISC_systemToUtf8(name);
|
||||
if (id == 0)
|
||||
{
|
||||
auth_method = "OS user name / wheel";
|
||||
wheel = true;
|
||||
}
|
||||
}
|
||||
@ -7063,7 +7050,6 @@ static void getUserInfo(UserId& user, const DatabaseOptions& options,
|
||||
user.usr_auth_method = auth_method;
|
||||
user.usr_user_id = id;
|
||||
user.usr_group_id = group;
|
||||
user.usr_auth_block.assign(options.dpb_auth_block);
|
||||
|
||||
if (wheel)
|
||||
{
|
||||
|
@ -356,8 +356,30 @@ NAME("MON$TRANSACTION_ID", nam_mon_tra_id)
|
||||
NAME("MON$USER", nam_mon_user)
|
||||
NAME("MON$VARIABLE_NAME", nam_mon_var_name)
|
||||
NAME("MON$VARIABLE_VALUE", nam_mon_var_value)
|
||||
|
||||
NAME("SEC$USERS", nam_sec_users)
|
||||
NAME("SEC$USER_ATTRIBUTES", nam_sec_user_attributes)
|
||||
NAME("RDB$BOOLEAN", nam_bool)
|
||||
NAME("SEC$KEY", nam_sec_attr_key)
|
||||
NAME("SEC$VALUE", nam_sec_attr_value)
|
||||
|
||||
NAME("RDB$MAP", nam_map)
|
||||
NAME("SEC$GLOBAL_MAP", nam_sec_global_map)
|
||||
|
||||
NAME("RDB$MAP_NAME", nam_map_name)
|
||||
NAME("RDB$MAP_USING", nam_map_using)
|
||||
NAME("RDB$MAP_PLUGIN", nam_map_plugin)
|
||||
NAME("RDB$MAP_DB", nam_map_db)
|
||||
NAME("RDB$MAP_FROM_TYPE", nam_map_from_type)
|
||||
NAME("RDB$MAP_FROM", nam_map_from)
|
||||
NAME("RDB$MAP_TO_TYPE", nam_map_to_type)
|
||||
NAME("RDB$MAP_TO", nam_map_to)
|
||||
|
||||
NAME("SEC$MAP_NAME", nam_sec_map_name)
|
||||
NAME("SEC$MAP_USING", nam_sec_map_using)
|
||||
NAME("SEC$MAP_PLUGIN", nam_sec_map_plugin)
|
||||
NAME("SEC$MAP_DB", nam_sec_map_db)
|
||||
NAME("SEC$MAP_FROM_TYPE", nam_sec_map_from_type)
|
||||
NAME("SEC$MAP_FROM", nam_sec_map_from)
|
||||
NAME("SEC$MAP_TO_TYPE", nam_sec_map_to_type)
|
||||
NAME("SEC$MAP_TO", nam_sec_map_to)
|
||||
|
@ -84,6 +84,7 @@
|
||||
#include "../common/classes/objects_array.h"
|
||||
#include "../jrd/recsrc/RecordSource.h"
|
||||
#include "../jrd/recsrc/Cursor.h"
|
||||
#include "../jrd/Mapping.h"
|
||||
|
||||
#include "../jrd/Optimizer.h"
|
||||
#include "../dsql/BoolNodes.h"
|
||||
@ -2285,7 +2286,11 @@ static RecordSource* gen_retrieval(thread_db* tdbb,
|
||||
else if (relation->isVirtual())
|
||||
{
|
||||
// Virtual table: monitoring or security
|
||||
if (relation->rel_id == rel_sec_users || relation->rel_id == rel_sec_user_attributes)
|
||||
if (relation->rel_id == rel_sec_global_map)
|
||||
{
|
||||
rsb = FB_NEW(*tdbb->getDefaultPool()) GlobalMappingScan(csb, alias, stream);
|
||||
}
|
||||
else if (relation->rel_id == rel_sec_users || relation->rel_id == rel_sec_user_attributes)
|
||||
{
|
||||
rsb = FB_NEW(*tdbb->getDefaultPool()) UsersTableScan(csb, alias, stream);
|
||||
}
|
||||
|
@ -619,3 +619,29 @@ RELATION(nam_sec_user_attributes, rel_sec_user_attributes, ODS_12_0, rel_virtual
|
||||
FIELD(f_sec_attr_key, nam_sec_attr_key, fld_attr_key, 0, ODS_12_0)
|
||||
FIELD(f_sec_attr_value, nam_sec_attr_value, fld_attr_value, 0, ODS_12_0)
|
||||
END_RELATION
|
||||
|
||||
// Relation 45 (RDB$MAP)
|
||||
RELATION(nam_map, rel_map, ODS_12_0, rel_persistent)
|
||||
FIELD(f_map_name, nam_map_name, fld_map_name, 1, ODS_12_0)
|
||||
FIELD(f_map_using, nam_map_using, fld_map_using, 1, ODS_12_0)
|
||||
FIELD(f_map_plugin, nam_map_plugin, fld_map_plugin, 1, ODS_12_0)
|
||||
FIELD(f_map_db, nam_map_db, fld_map_db, 1, ODS_12_0)
|
||||
FIELD(f_map_from_type, nam_map_from_type, fld_map_from_type, 1, ODS_12_0)
|
||||
FIELD(f_map_from, nam_map_from, fld_map_from, 1, ODS_12_0)
|
||||
FIELD(f_map_to_type, nam_map_to_type, fld_obj_type, 1, ODS_8_0)
|
||||
FIELD(f_map_to, nam_map_to, fld_map_to, 1, ODS_12_0)
|
||||
FIELD(f_map_sys_flag, nam_sys_flag, fld_flag, 1, ODS_12_0)
|
||||
FIELD(f_map_desc, nam_description, fld_description, 1, ODS_12_0)
|
||||
END_RELATION
|
||||
|
||||
// Relation 46 (SEC$GLOBAL_MAP)
|
||||
RELATION(nam_sec_global_map, rel_sec_global_map, ODS_12_0, rel_virtual)
|
||||
FIELD(f_sec_map_name, nam_sec_map_name, fld_map_name, 1, ODS_12_0)
|
||||
FIELD(f_sec_map_using, nam_sec_map_using, fld_map_using, 0, ODS_12_0)
|
||||
FIELD(f_sec_map_plugin, nam_sec_map_plugin, fld_map_plugin, 0, ODS_12_0)
|
||||
FIELD(f_sec_map_db, nam_sec_map_db, fld_map_db, 0, ODS_12_0)
|
||||
FIELD(f_sec_map_from_type, nam_sec_map_from_type, fld_map_from_type, 0, ODS_12_0)
|
||||
FIELD(f_sec_map_from, nam_sec_map_from, fld_map_from, 0, ODS_12_0)
|
||||
FIELD(f_sec_map_to_type, nam_sec_map_to_type, fld_obj_type, 0, ODS_8_0)
|
||||
FIELD(f_sec_map_to, nam_sec_map_to, fld_map_to, 0, ODS_12_0)
|
||||
END_RELATION
|
||||
|
@ -56,6 +56,7 @@
|
||||
#include "../common/classes/array.h"
|
||||
#include "../common/config/config.h"
|
||||
#include "../common/os/os_utils.h"
|
||||
#include "../common/classes/ClumpletWriter.h"
|
||||
|
||||
|
||||
const int UIC_BASE = 10;
|
||||
@ -872,20 +873,8 @@ void SCL_init(thread_db* tdbb, bool create, const UserId& tempId)
|
||||
}
|
||||
END_FOR
|
||||
}
|
||||
|
||||
if (!found && (tempId.usr_flags & USR_trole))
|
||||
{
|
||||
request.reset(tdbb, irq_verify_trusted_role, IRQ_REQUESTS);
|
||||
|
||||
FOR (REQUEST_HANDLE request) FIRST 1 RR IN RDB$ROLES
|
||||
WITH RR.RDB$ROLE_NAME EQ sql_role
|
||||
AND RR.RDB$SYSTEM_FLAG > 0
|
||||
{
|
||||
if (RR.RDB$SYSTEM_FLAG & ROLE_FLAG_MAY_TRUST)
|
||||
found = true;
|
||||
}
|
||||
END_FOR
|
||||
}
|
||||
else
|
||||
found = true;
|
||||
|
||||
if (!found)
|
||||
role_name = NULL_ROLE;
|
||||
@ -1452,3 +1441,10 @@ static SecurityClass::flags_t walk_acl(thread_db* tdbb,
|
||||
return privilege;
|
||||
}
|
||||
|
||||
void Jrd::UserId::populateDpb(Firebird::ClumpletWriter& dpb)
|
||||
{
|
||||
if (usr_auth_block.hasData())
|
||||
dpb.insertBytes(isc_dpb_auth_block, usr_auth_block.begin(), usr_auth_block.getCount());
|
||||
else
|
||||
dpb.insertString(isc_dpb_user_name, usr_user_name);
|
||||
}
|
||||
|
@ -28,6 +28,10 @@
|
||||
#include "../common/classes/tree.h"
|
||||
#include "../common/security.h"
|
||||
|
||||
namespace Firebird {
|
||||
class ClumpletWriter;
|
||||
}
|
||||
|
||||
namespace Jrd {
|
||||
|
||||
const size_t ACL_BLOB_BUFFER_SIZE = MAX_USHORT; // used to read/write acl blob
|
||||
@ -91,7 +95,7 @@ public:
|
||||
Firebird::string usr_project_name; // Project name
|
||||
Firebird::string usr_org_name; // Organization name
|
||||
Firebird::string usr_auth_method; // Authentication method
|
||||
Auth::UserData::AuthenticationBlock usr_auth_block; // Authentication block like it was passed to engine
|
||||
Auth::UserData::AuthenticationBlock usr_auth_block; // Authentication block after mapping
|
||||
USHORT usr_user_id; // User id
|
||||
USHORT usr_group_id; // Group id
|
||||
USHORT usr_flags; // Misc. crud
|
||||
@ -146,6 +150,8 @@ public:
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void populateDpb(Firebird::ClumpletWriter& dpb);
|
||||
};
|
||||
|
||||
// These numbers are arbitrary and only used at run-time. Can be changed if necessary at any moment.
|
||||
|
@ -56,11 +56,13 @@
|
||||
#include "../common/classes/ClumpletWriter.h"
|
||||
#include "../jrd/ibase.h"
|
||||
#include "../common/utils_proto.h"
|
||||
#include "../common/db_alias.h"
|
||||
#include "../jrd/scl.h"
|
||||
#include "../jrd/msg_encode.h"
|
||||
#include "../jrd/trace/TraceManager.h"
|
||||
#include "../jrd/trace/TraceObjects.h"
|
||||
#include "../jrd/EngineInterface.h"
|
||||
#include "../jrd/Mapping.h"
|
||||
|
||||
#include "../common/classes/DbImplementation.h"
|
||||
|
||||
@ -244,17 +246,9 @@ void Service::getOptions(ClumpletReader& spb)
|
||||
svc_auth_block.add(spb.getBytes(), spb.getClumpLength());
|
||||
break;
|
||||
|
||||
case isc_spb_trusted_auth:
|
||||
spb.getString(svc_trusted_login);
|
||||
break;
|
||||
|
||||
case isc_spb_trusted_role:
|
||||
svc_trusted_role = true;
|
||||
break;
|
||||
|
||||
case isc_spb_command_line:
|
||||
spb.getString(svc_command_line);
|
||||
{
|
||||
/* {
|
||||
// HACK: this does not care about the words on allowed places.
|
||||
string cLine = svc_command_line;
|
||||
cLine.upper();
|
||||
@ -264,6 +258,10 @@ void Service::getOptions(ClumpletReader& spb)
|
||||
(Arg::Gds(isc_bad_spb_form) << Arg::Gds(isc_no_trusted_spb)).raise();
|
||||
}
|
||||
}
|
||||
*/ break;
|
||||
|
||||
case isc_spb_expected_db:
|
||||
spb.getPath(svc_expected_db);
|
||||
break;
|
||||
|
||||
case isc_spb_address_path:
|
||||
@ -711,7 +709,7 @@ Service::Service(const TEXT* service_name, USHORT spb_length, const UCHAR* spb_d
|
||||
svc_resp_alloc(getPool()), svc_resp_buf(0), svc_resp_ptr(0), svc_resp_buf_len(0),
|
||||
svc_resp_len(0), svc_flags(0), svc_user_flag(0), svc_spb_version(0), svc_do_shutdown(false),
|
||||
svc_username(getPool()), svc_auth_block(getPool()),
|
||||
svc_trusted_login(getPool()), svc_trusted_role(false), svc_utf8(false),
|
||||
svc_expected_db(getPool()), svc_trusted_role(false), svc_utf8(false),
|
||||
svc_switches(getPool()), svc_perm_sw(getPool()), svc_address_path(getPool()),
|
||||
svc_command_line(getPool()),
|
||||
svc_network_protocol(getPool()), svc_remote_address(getPool()), svc_remote_process(getPool()),
|
||||
@ -766,26 +764,21 @@ Service::Service(const TEXT* service_name, USHORT spb_length, const UCHAR* spb_d
|
||||
}
|
||||
else
|
||||
{
|
||||
if (svc_trusted_login.hasData())
|
||||
{
|
||||
svc_username = svc_trusted_login;
|
||||
}
|
||||
|
||||
if (!svc_username.hasData())
|
||||
{
|
||||
if (svc_auth_block.hasData())
|
||||
{
|
||||
// stub instead mapUser(....);
|
||||
AuthReader auth(svc_auth_block);
|
||||
Firebird::string method;
|
||||
if (auth.getInfo(&svc_username, &method, NULL) && method == "Win_Sspi")
|
||||
{
|
||||
auth.moveNext();
|
||||
if (!auth.isEof())
|
||||
{
|
||||
svc_trusted_role = true;
|
||||
}
|
||||
}
|
||||
PathName dummy;
|
||||
RefPtr<Config> config;
|
||||
expandDatabaseName(svc_expected_db, dummy, &config);
|
||||
|
||||
string trusted_role;
|
||||
mapUser(svc_username, trusted_role, NULL, &svc_auth_block, svc_auth_block,
|
||||
NULL, config->getSecurityDatabase());
|
||||
|
||||
// to be changed after refsoft special roles patch!!!
|
||||
trusted_role.upper();
|
||||
svc_trusted_role = trusted_role == ADMIN_ROLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2045,17 +2038,9 @@ void Service::start(USHORT spb_length, const UCHAR* spb_data)
|
||||
{
|
||||
if (svc_username.hasData())
|
||||
{
|
||||
string auth = "-";
|
||||
auth += TRUSTED_USER_SWITCH;
|
||||
auth += ' ';
|
||||
string auth = "-user ";
|
||||
auth += svc_username;
|
||||
auth += ' ';
|
||||
if (svc_trusted_role)
|
||||
{
|
||||
auth += "-";
|
||||
auth += TRUSTED_ROLE_SWITCH;
|
||||
auth += ' ';
|
||||
}
|
||||
svc_switches = auth + svc_switches;
|
||||
}
|
||||
}
|
||||
@ -2782,14 +2767,14 @@ bool Service::process_switches(ClumpletReader& spb, string& switches)
|
||||
string s;
|
||||
spb.getString(s);
|
||||
|
||||
// HACK: this does not care about the words on allowed places.
|
||||
/* // HACK: this does not care about the words on allowed places.
|
||||
string cLine = s;
|
||||
cLine.upper();
|
||||
if (cLine.find(TRUSTED_USER_SWITCH) != string::npos ||
|
||||
cLine.find(TRUSTED_ROLE_SWITCH) != string::npos)
|
||||
{
|
||||
(Arg::Gds(isc_bad_spb_form) << Arg::Gds(isc_no_trusted_spb)).raise();
|
||||
}
|
||||
} */
|
||||
|
||||
switches += s;
|
||||
switches += ' ';
|
||||
|
@ -289,7 +289,7 @@ private:
|
||||
|
||||
Firebird::string svc_username;
|
||||
Firebird::AuthReader::AuthBlock svc_auth_block;
|
||||
Firebird::string svc_trusted_login;
|
||||
Firebird::PathName svc_expected_db;
|
||||
bool svc_trusted_role;
|
||||
bool svc_utf8;
|
||||
Firebird::string svc_switches; // Full set of switches
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "../jrd/intl_classes.h"
|
||||
#include "../common/ThreadStart.h"
|
||||
#include "../jrd/UserManagement.h"
|
||||
#include "../jrd/Mapping.h"
|
||||
#include "../jrd/blb_proto.h"
|
||||
#include "../jrd/cch_proto.h"
|
||||
#include "../jrd/cmp_proto.h"
|
||||
@ -73,6 +74,7 @@
|
||||
#include "../jrd/trace/TraceJrdHelpers.h"
|
||||
#include "../jrd/Function.h"
|
||||
#include "../jrd/Collation.h"
|
||||
#include "../jrd/Mapping.h"
|
||||
|
||||
|
||||
const int DYN_MSG_FAC = 8;
|
||||
@ -375,6 +377,23 @@ void TRA_commit(thread_db* tdbb, jrd_tra* transaction, const bool retaining_flag
|
||||
if (!(transaction->tra_flags & TRA_prepared))
|
||||
DFW_perform_work(tdbb, transaction);
|
||||
|
||||
// Commit associated transaction in security DB
|
||||
|
||||
SecDbContext* secContext = transaction->getSecDbContext();
|
||||
if (secContext && secContext->tra)
|
||||
{
|
||||
LocalStatus s;
|
||||
secContext->tra->commit(&s);
|
||||
|
||||
if (!s.isSuccess())
|
||||
status_exception::raise(s.get());
|
||||
|
||||
secContext->tra = NULL;
|
||||
flashMap(tdbb->getDatabase()->dbb_config->getSecurityDatabase());
|
||||
|
||||
transaction->eraseSecDbContext();
|
||||
}
|
||||
|
||||
if (transaction->tra_flags & (TRA_prepare2 | TRA_reconnected))
|
||||
MET_update_transaction(tdbb, transaction, true);
|
||||
|
||||
@ -958,6 +977,17 @@ void TRA_prepare(thread_db* tdbb, jrd_tra* transaction, USHORT length, const UCH
|
||||
transaction->tra_flags |= TRA_prepare2;
|
||||
}
|
||||
|
||||
// Prepare associated transaction in security DB
|
||||
|
||||
SecDbContext* secContext = transaction->getSecDbContext();
|
||||
if (secContext && secContext->tra)
|
||||
{
|
||||
LocalStatus s;
|
||||
secContext->tra->prepare(&s, length, msg);
|
||||
if (!s.isSuccess())
|
||||
status_exception::raise(s.get());
|
||||
}
|
||||
|
||||
// Perform any meta data work deferred
|
||||
|
||||
DFW_perform_work(tdbb, transaction);
|
||||
@ -3302,6 +3332,7 @@ jrd_tra::~jrd_tra()
|
||||
delete tra_undo_record;
|
||||
delete tra_undo_space;
|
||||
delete tra_user_management;
|
||||
delete tra_mapping_list;
|
||||
delete tra_gen_ids;
|
||||
|
||||
if (!tra_outer)
|
||||
@ -3325,6 +3356,8 @@ jrd_tra::~jrd_tra()
|
||||
{
|
||||
MemoryPool::deletePool(tra_autonomous_pool);
|
||||
}
|
||||
|
||||
delete tra_sec_db_context;
|
||||
}
|
||||
|
||||
|
||||
@ -3358,6 +3391,16 @@ UserManagement* jrd_tra::getUserManagement()
|
||||
}
|
||||
|
||||
|
||||
MappingList* jrd_tra::getMappingList()
|
||||
{
|
||||
if (!tra_mapping_list)
|
||||
{
|
||||
tra_mapping_list = FB_NEW(*tra_pool) MappingList(this);
|
||||
}
|
||||
return tra_mapping_list;
|
||||
}
|
||||
|
||||
|
||||
jrd_tra* jrd_tra::getOuter()
|
||||
{
|
||||
jrd_tra* tra = this;
|
||||
@ -3538,3 +3581,41 @@ void TraceSweepEvent::report(ntrace_process_state_t state)
|
||||
if (state == process_state_failed || state == process_state_finished)
|
||||
m_need_trace = false;
|
||||
}
|
||||
|
||||
SecDbContext::SecDbContext(IAttachment* a, ITransaction* t)
|
||||
: att(a), tra(t), savePoint(0)
|
||||
{ }
|
||||
|
||||
SecDbContext::~SecDbContext()
|
||||
{
|
||||
LocalStatus s;
|
||||
if (tra)
|
||||
{
|
||||
tra->rollback(&s);
|
||||
tra = NULL;
|
||||
}
|
||||
if (att)
|
||||
{
|
||||
att->detach(&s);
|
||||
att = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
SecDbContext* jrd_tra::getSecDbContext()
|
||||
{
|
||||
return tra_sec_db_context;
|
||||
}
|
||||
|
||||
SecDbContext* jrd_tra::setSecDbContext(IAttachment* att, ITransaction* tra)
|
||||
{
|
||||
fb_assert(!tra_sec_db_context);
|
||||
|
||||
tra_sec_db_context = FB_NEW(*getDefaultMemoryPool()) SecDbContext(att, tra);
|
||||
return tra_sec_db_context;
|
||||
}
|
||||
|
||||
void jrd_tra::eraseSecDbContext()
|
||||
{
|
||||
delete tra_sec_db_context;
|
||||
tra_sec_db_context = NULL;
|
||||
}
|
@ -50,6 +50,11 @@ namespace EDS {
|
||||
class Transaction;
|
||||
}
|
||||
|
||||
namespace Firebird {
|
||||
class IAttachment;
|
||||
class ITransaction;
|
||||
};
|
||||
|
||||
namespace Jrd {
|
||||
|
||||
class blb;
|
||||
@ -65,8 +70,19 @@ class DeferredWork;
|
||||
class DeferredJob;
|
||||
class dsql_opn;
|
||||
class UserManagement;
|
||||
class MappingList;
|
||||
class thread_db;
|
||||
|
||||
class SecDbContext
|
||||
{
|
||||
public:
|
||||
SecDbContext(Firebird::IAttachment* a, Firebird::ITransaction* t);
|
||||
~SecDbContext();
|
||||
|
||||
Firebird::IAttachment* att;
|
||||
Firebird::ITransaction* tra;
|
||||
int savePoint;
|
||||
};
|
||||
|
||||
//Moved to fb_types.h
|
||||
//typedef ULONG TraNumber;
|
||||
@ -174,6 +190,8 @@ public:
|
||||
tra_undo_space(NULL),
|
||||
tra_undo_record(NULL),
|
||||
tra_user_management(NULL),
|
||||
tra_sec_db_context(NULL),
|
||||
tra_mapping_list(NULL),
|
||||
tra_autonomous_pool(NULL),
|
||||
tra_autonomous_cnt(0)
|
||||
{
|
||||
@ -283,6 +301,8 @@ private:
|
||||
|
||||
Record* tra_undo_record; // temporary record used for the undo purposes
|
||||
UserManagement* tra_user_management;
|
||||
SecDbContext* tra_sec_db_context;
|
||||
MappingList* tra_mapping_list;
|
||||
MemoryPool* tra_autonomous_pool;
|
||||
USHORT tra_autonomous_cnt;
|
||||
static const USHORT TRA_AUTONOMOUS_PER_POOL = 64;
|
||||
@ -335,6 +355,10 @@ public:
|
||||
}
|
||||
|
||||
UserManagement* getUserManagement();
|
||||
SecDbContext* getSecDbContext();
|
||||
SecDbContext* setSecDbContext(Firebird::IAttachment* att, Firebird::ITransaction* tra);
|
||||
void eraseSecDbContext();
|
||||
MappingList* getMappingList();
|
||||
|
||||
GenIdCache* getGenIdCache()
|
||||
{
|
||||
@ -503,7 +527,8 @@ enum dfw_t {
|
||||
dfw_arg_new_name, // new name
|
||||
dfw_arg_field_not_null, // set domain to not nullable
|
||||
dfw_db_crypt, // change database encryption status
|
||||
dfw_set_linger // set database linger
|
||||
dfw_set_linger, // set database linger
|
||||
dfw_flash_cache // flash user mapping cache
|
||||
};
|
||||
|
||||
// Verb actions
|
||||
|
@ -355,7 +355,7 @@ void fbtrace(UtilSvc* uSvc, TraceSvcIntf* traceSvc)
|
||||
|
||||
adminRole = true;
|
||||
break;
|
||||
|
||||
/*
|
||||
case IN_SW_TRACE_TRUSTED_USER:
|
||||
if (!uSvc->isService())
|
||||
usage(uSvc, isc_trace_switch_svc_only, sw->in_sw_name);
|
||||
@ -376,7 +376,7 @@ void fbtrace(UtilSvc* uSvc, TraceSvcIntf* traceSvc)
|
||||
|
||||
adminRole = true;
|
||||
break;
|
||||
|
||||
*/
|
||||
case IN_SW_TRACE_SERVICE_NAME:
|
||||
if (uSvc->isService())
|
||||
continue;
|
||||
@ -431,17 +431,17 @@ void fbtrace(UtilSvc* uSvc, TraceSvcIntf* traceSvc)
|
||||
authBlock.add(bytes, authBlockSize);
|
||||
|
||||
AuthReader auth(authBlock);
|
||||
PathName secureDb;
|
||||
AuthReader::Info info;
|
||||
|
||||
if (auth.getInfo(&user, NULL, &secureDb))
|
||||
if (auth.getInfo(info))
|
||||
{
|
||||
pwd = "";
|
||||
user = info.name.ToString();
|
||||
adminRole = false;
|
||||
if (!secureDb.hasData())
|
||||
if (!info.secDb.hasData())
|
||||
{
|
||||
auth.moveNext();
|
||||
string trusted_role;
|
||||
if (auth.getInfo(&trusted_role, NULL, NULL))
|
||||
if (auth.getInfo(info))
|
||||
{
|
||||
adminRole = true;
|
||||
}
|
||||
|
@ -73,8 +73,8 @@ static const struct Switches::in_sw_tab_t trace_auth_in_sw_table [] =
|
||||
{IN_SW_TRACE_PASSWORD, 0, PASSWORD_SWITCH, 0, 0, 0, false, 0, 1, NULL},
|
||||
{IN_SW_TRACE_SERVICE_NAME, 0, "SERVICE", 0, 0, 0, false, 0, 2, NULL},
|
||||
{IN_SW_TRACE_TRUSTED_AUTH, 0, "TRUSTED", 0, 0, 0, false, 0, 1, NULL},
|
||||
{IN_SW_TRACE_TRUSTED_USER, 0, TRUSTED_USER_SWITCH, 0, 0, 0, false, 0, TRUSTED_USER_SWITCH_LEN, NULL},
|
||||
{IN_SW_TRACE_TRUSTED_ROLE, 0, TRUSTED_ROLE_SWITCH, 0, 0, 0, false, 0, TRUSTED_ROLE_SWITCH_LEN, NULL},
|
||||
// {IN_SW_TRACE_TRUSTED_USER, 0, TRUSTED_USER_SWITCH, 0, 0, 0, false, 0, TRUSTED_USER_SWITCH_LEN, NULL},
|
||||
// {IN_SW_TRACE_TRUSTED_ROLE, 0, TRUSTED_ROLE_SWITCH, 0, 0, 0, false, 0, TRUSTED_ROLE_SWITCH_LEN, NULL},
|
||||
{IN_SW_TRACE_USERNAME, 0, USERNAME_SWITCH, 0, 0, 0, false, 0, 1, NULL},
|
||||
{0, 0, NULL, 0, 0, 0, false, 0, 0, NULL} // End of List
|
||||
};
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* MAX_NUMBER is the next number to be used, always one more than the highest message number. */
|
||||
set bulk_insert INSERT INTO FACILITIES (LAST_CHANGE, FACILITY, FAC_CODE, MAX_NUMBER) VALUES (?, ?, ?, ?);
|
||||
--
|
||||
('2014-03-31 20:48:34', 'JRD', 0, 757)
|
||||
('2014-04-04 16:13:24', 'JRD', 0, 768)
|
||||
('2012-01-23 20:10:30', 'QLI', 1, 532)
|
||||
('2013-11-13 15:59:10', 'GFIX', 3, 122)
|
||||
('1996-11-07 13:39:40', 'GPRE', 4, 1)
|
||||
@ -9,8 +9,8 @@ set bulk_insert INSERT INTO FACILITIES (LAST_CHANGE, FACILITY, FAC_CODE, MAX_NUM
|
||||
('2014-03-31 18:46:42', 'DYN', 8, 288)
|
||||
('1996-11-07 13:39:40', 'INSTALL', 10, 1)
|
||||
('1996-11-07 13:38:41', 'TEST', 11, 4)
|
||||
('2014-03-03 19:17:14', 'GBAK', 12, 353)
|
||||
('2014-01-26 23:00:00', 'SQLERR', 13, 1034)
|
||||
('2014-04-04 16:08:08', 'GBAK', 12, 354)
|
||||
('2014-04-04 16:36:53', 'SQLERR', 13, 1035)
|
||||
('1996-11-07 13:38:42', 'SQLWARN', 14, 613)
|
||||
('2006-09-10 03:04:31', 'JRD_BUGCHK', 15, 307)
|
||||
('2014-01-13 15:41:16', 'ISQL', 17, 184)
|
||||
|
@ -864,6 +864,17 @@ Data source : @4', NULL, NULL)
|
||||
('forupdate_systbl', 'PAR_rse', 'par.cpp', NULL, 0, 754, NULL, 'Cannot select system table @1 for update WITH LOCK', NULL, NULL)
|
||||
('forupdate_temptbl', 'PAR_rse', 'par.cpp', NULL, 0, 755, NULL, 'Cannot select temporary table @1 for update WITH LOCK', NULL, NULL)
|
||||
('cant_modify_sysobj', NULL, 'ExprNodes.cpp', NULL, 0, 756, NULL, 'System @1 @2 cannot be modified', NULL, 'Ex: System generator rdb$... cannot be modified')
|
||||
('server_misconfigured', 'expandDatabaseName', 'db_alias.cpp', NULL, 0, 757, NULL, 'Server misconfigured - contact administrator please', NULL, NULL);
|
||||
('alter_role', 'MappingNode::validateAdmin', 'DdlNodes.epp', NULL, 0, 758, NULL, 'Deprecated backward compatibility ALTER ROLE ... SET/DROP AUTO ADMIN mapping may be used only for RDB$ADMIN role', NULL, NULL);
|
||||
('map_already_exists', 'MappingNode::execute', 'DdlNodes.epp', NULL, 0, 759, NULL, 'Mapping @1 already exists', NULL, NULL);
|
||||
('map_not_exists', 'MappingNode::execute', 'DdlNodes.epp', NULL, 0, 760, NULL, 'Mapping @1 does not exist', NULL, NULL);
|
||||
('map_load', 'check', 'Mapping.cpp', NULL, 0, 761, NULL, '@1 failed when loading mapping cache', NULL, NULL);
|
||||
('map_aster', 'Cache::map', 'Mapping.cpp', NULL, 0, 762, NULL, 'Invalid name <*> in authentication block', NULL, NULL);
|
||||
('map_multi', 'Cache::search', 'Mapping.cpp', NULL, 0, 763, NULL, 'Multiple maps found for @1', NULL, NULL);
|
||||
('map_undefined', 'Found::set', 'Mapping.cpp', NULL, 0, 764, NULL, 'Undefined mapping result - more than one different results found', NULL, NULL);
|
||||
('baddpb_damaged_mode', 'attachDatabase', 'jrd.cpp', NULL, 0, 765, NULL, 'Incompatible mode of attachment to damaged database', NULL, NULL);
|
||||
('baddpb_buffers_range', 'DatabaseOptions::get', 'jrd.cpp', NULL, 0, 766, NULL, 'Attempt to set in database number of buffers which is out of acceptable range [@1:@2]', NULL, NULL);
|
||||
('baddpb_temp_buffers', 'DatabaseOptions::get', 'jrd.cpp', NULL, 0, 767, NULL, 'Attempt to temporarily set number of buffers less than @1', NULL, NULL);
|
||||
-- QLI
|
||||
(NULL, NULL, NULL, NULL, 1, 0, NULL, 'expected type', NULL, NULL);
|
||||
(NULL, NULL, NULL, NULL, 1, 1, NULL, 'bad block type', NULL, NULL);
|
||||
@ -2282,6 +2293,7 @@ ERROR: Backup incomplete', NULL, NULL);
|
||||
(NULL, 'fix_system_generators', 'restore.epp', NULL, 12, 350, NULL, 'fixing system generators', NULL, NULL);
|
||||
(NULL, 'BURP_abort', 'burp.cpp', NULL, 12, 351, NULL, 'Error closing database, but backup file is OK', NULL, NULL);
|
||||
(NULL, NULL, 'restore.epp', NULL, 12, 352, NULL, 'database', NULL, NULL);
|
||||
(NULL, 'get_mapping', 'restore.epp', NULL, 12, 353, NULL, 'required mapping attributes are missing in backup file', NULL, NULL);
|
||||
-- SQLERR
|
||||
(NULL, NULL, NULL, NULL, 13, 1, NULL, 'Firebird error', NULL, NULL);
|
||||
(NULL, NULL, NULL, NULL, 13, 74, NULL, 'Rollback not performed', NULL, NULL);
|
||||
@ -2559,6 +2571,7 @@ ERROR: Backup incomplete', NULL, NULL);
|
||||
('dsql_grant_failed', 'getMainErrorCode', 'DdlNodes.h', NULL, 13, 1031, NULL, 'GRANT failed', NULL, NULL);
|
||||
('dsql_revoke_failed', 'getMainErrorCode', 'DdlNodes.h', NULL, 13, 1032, NULL, 'REVOKE failed', NULL, NULL);
|
||||
('dsql_cte_recursive_aggregate', 'pass1_rse_impl', 'dsql.cpp', NULL, 13, 1033, NULL, 'Recursive member of CTE cannot use aggregate or window function', NULL, NULL);
|
||||
('dsql_mapping_failed', 'MappingNode::putErrorPrefix', 'DdlNodes.h', NULL, 13, 1034, NULL, '@2 MAPPING @1 failed', NULL, NULL);
|
||||
-- SQLWARN
|
||||
(NULL, NULL, NULL, NULL, 14, 100, NULL, 'Row not found for fetch, update or delete, or the result of a query is an empty table.', NULL, NULL);
|
||||
(NULL, NULL, NULL, NULL, 14, 101, NULL, 'segment buffer length shorter than expected', NULL, NULL);
|
||||
|
@ -757,12 +757,23 @@ set bulk_insert INSERT INTO SYSTEM_ERRORS (SQL_CODE, SQL_CLASS, SQL_SUBCLASS, FA
|
||||
(-902, '28', '000', 0, 748, 'secdb_name', NULL, NULL);
|
||||
(-902, '28', '000', 0, 749, 'auth_data', NULL, NULL);
|
||||
(-902, '28', '000', 0, 750, 'auth_datalength', NULL, NULL);
|
||||
(-901, 'HY', '007', 0, 751, 'info_unprepared_stmt', NULL, NULL)
|
||||
(-901, 'HY', '007', 0, 752, 'idx_key_value', NULL, NULL)
|
||||
(-901, 'HY', '000', 0, 753, 'forupdate_virtualtbl', NULL, NULL)
|
||||
(-901, 'HY', '000', 0, 754, 'forupdate_systbl', NULL, NULL)
|
||||
(-901, 'HY', '000', 0, 755, 'forupdate_temptbl', NULL, NULL)
|
||||
(-901, '42', '000', 0, 756, 'cant_modify_sysobj', NULL, NULL)
|
||||
(-901, 'HY', '007', 0, 751, 'info_unprepared_stmt', NULL, NULL);
|
||||
(-901, 'HY', '007', 0, 752, 'idx_key_value', NULL, NULL);
|
||||
(-901, 'HY', '000', 0, 753, 'forupdate_virtualtbl', NULL, NULL);
|
||||
(-901, 'HY', '000', 0, 754, 'forupdate_systbl', NULL, NULL);
|
||||
(-901, 'HY', '000', 0, 755, 'forupdate_temptbl', NULL, NULL);
|
||||
(-901, '42', '000', 0, 756, 'cant_modify_sysobj', NULL, NULL);
|
||||
(-901, '08', '004', 0, 757, 'server_misconfigured', NULL, NULL);
|
||||
(-901, '0A', '000', 0, 758, 'alter_role', NULL, NULL);
|
||||
(-901, '42', 'S01', 0, 759, 'map_already_exists', NULL, NULL);
|
||||
(-901, '42', 'S01', 0, 760, 'map_not_exists', NULL, NULL);
|
||||
(-901, '08', '004', 0, 761, 'map_load', NULL, NULL);
|
||||
(-901, '08', '004', 0, 762, 'map_aster', NULL, NULL);
|
||||
(-901, '08', '004', 0, 763, 'map_multi', NULL, NULL);
|
||||
(-901, '08', '004', 0, 764, 'map_undefined', NULL, NULL);
|
||||
(-924, 'HY', '000', 0, 765, 'baddpb_damaged_mode', NULL, NULL);
|
||||
(-924, 'HY', '000', 0, 766, 'baddpb_buffers_range', NULL, NULL);
|
||||
(-924, 'HY', '000', 0, 767, 'baddpb_temp_buffers', NULL, NULL);
|
||||
-- GFIX
|
||||
(-901, '00', '000', 3, 1, 'gfix_db_name', NULL, NULL)
|
||||
(-901, '00', '000', 3, 2, 'gfix_invalid_sw', NULL, NULL)
|
||||
@ -1117,6 +1128,7 @@ COMMIT WORK;
|
||||
(-901, '42', '000', 13, 1031, 'dsql_grant_failed', NULL, NULL);
|
||||
(-901, '42', '000', 13, 1032, 'dsql_revoke_failed', NULL, NULL);
|
||||
(-104, '42', '000', 13, 1033, 'dsql_cte_recursive_aggregate', NULL, NULL)
|
||||
(-901, '42', '000', 13, 1034, 'dsql_mapping_failed', NULL, NULL);
|
||||
-- GSEC
|
||||
(-901, '00', '000', 18, 15, 'gsec_cant_open_db', NULL, NULL)
|
||||
(-901, '00', '000', 18, 16, 'gsec_switches_error', NULL, NULL)
|
||||
|
@ -427,7 +427,7 @@ public:
|
||||
if (!authServer)
|
||||
{
|
||||
authServer = authItr->plugin();
|
||||
authPort->port_srv_auth_block->authBlockWriter.setMethod(authItr->name());
|
||||
authPort->port_srv_auth_block->authBlockWriter.setPlugin(authItr->name());
|
||||
}
|
||||
|
||||
// if we asked for more data but received nothing switch to next plugin
|
||||
@ -1805,7 +1805,7 @@ static bool accept_connection(rem_port* port, P_CNCT* connect, PACKET* send)
|
||||
}
|
||||
else
|
||||
{
|
||||
port->port_srv_auth_block->authBlockWriter.setMethod(plugins->name());
|
||||
port->port_srv_auth_block->authBlockWriter.setPlugin(plugins->name());
|
||||
switch (plugins->plugin()->authenticate(&status, port->port_srv_auth_block,
|
||||
&port->port_srv_auth_block->authBlockWriter))
|
||||
{
|
||||
|
@ -283,16 +283,16 @@ int gsec(Firebird::UtilSvc* uSvc)
|
||||
|
||||
uSvc->checkService();
|
||||
|
||||
fb_assert(user_data->trustedUser.entered() || user_data->authenticationBlock.hasData());
|
||||
if (user_data->trustedUser.entered() || user_data->authenticationBlock.hasData())
|
||||
fb_assert(user_data->dba.entered() || user_data->authenticationBlock.hasData());
|
||||
if (user_data->dba.entered() || user_data->authenticationBlock.hasData())
|
||||
{
|
||||
class GsecInfo : public Firebird::AutoIface<ILogonInfo, FB_AUTH_LOGON_INFO_VERSION>
|
||||
{
|
||||
public:
|
||||
GsecInfo(const char* pTrustedUser, const char* pRole, int pTrustedRole,
|
||||
GsecInfo(const char* pDba, const char* pRole,
|
||||
const char* pProtocol, const char* pAddress,
|
||||
const UserData::AuthenticationBlock* pAuthBlock)
|
||||
: trustedUser(pTrustedUser), sqlRole(pRole), trustedRole(pTrustedRole),
|
||||
: dba(pDba), sqlRole(pRole),
|
||||
protocol(pProtocol), address(pAddress),
|
||||
authBytes(pAuthBlock->getCount() ? pAuthBlock->begin() : NULL),
|
||||
authLength(pAuthBlock->getCount())
|
||||
@ -301,7 +301,7 @@ int gsec(Firebird::UtilSvc* uSvc)
|
||||
// ILogonInfo implementation
|
||||
const char* FB_CARG name()
|
||||
{
|
||||
return trustedUser;
|
||||
return dba;
|
||||
}
|
||||
|
||||
const char* FB_CARG role()
|
||||
@ -309,11 +309,6 @@ int gsec(Firebird::UtilSvc* uSvc)
|
||||
return sqlRole;
|
||||
}
|
||||
|
||||
int FB_CARG forceAdmin()
|
||||
{
|
||||
return trustedRole;
|
||||
}
|
||||
|
||||
const char* FB_CARG networkProtocol()
|
||||
{
|
||||
return protocol;
|
||||
@ -331,9 +326,8 @@ int gsec(Firebird::UtilSvc* uSvc)
|
||||
}
|
||||
|
||||
private:
|
||||
const char* trustedUser;
|
||||
const char* dba;
|
||||
const char* sqlRole;
|
||||
int trustedRole;
|
||||
const char* protocol;
|
||||
const char* address;
|
||||
const unsigned char* authBytes;
|
||||
@ -351,8 +345,7 @@ int gsec(Firebird::UtilSvc* uSvc)
|
||||
"Management plugin is missing or failed to load").value(), GsecMsg15);
|
||||
}
|
||||
|
||||
GsecInfo info(user_data->trustedUser.get(), user_data->role.get(),
|
||||
user_data->trustedRole && !user_data->role.entered(),
|
||||
GsecInfo info(user_data->dba.get(), user_data->role.get(),
|
||||
network_protocol.c_str(), remote_address.c_str(), &user_data->authenticationBlock);
|
||||
manager->start(&st, &info);
|
||||
}
|
||||
@ -881,11 +874,6 @@ static bool get_switches(Firebird::UtilSvc::ArgvType& argv,
|
||||
user_data->role.set(string);
|
||||
user_data->role.setEntered(1);
|
||||
break;
|
||||
case IN_SW_GSEC_DBA_TRUSTED_USER:
|
||||
tdsec->utilSvc->checkService();
|
||||
user_data->trustedUser.set(string);
|
||||
user_data->trustedUser.setEntered(1);
|
||||
break;
|
||||
case IN_SW_GSEC_MAPPING:
|
||||
{
|
||||
Firebird::string val(string);
|
||||
@ -993,10 +981,6 @@ static bool get_switches(Firebird::UtilSvc::ArgvType& argv,
|
||||
user_data->user.clear();
|
||||
tdsec->tsec_interactive = false;
|
||||
break;
|
||||
case IN_SW_GSEC_DBA_TRUSTED_USER:
|
||||
case IN_SW_GSEC_DBA_TRUSTED_ROLE:
|
||||
tdsec->utilSvc->checkService();
|
||||
// fall through ...
|
||||
case IN_SW_GSEC_PASSWORD:
|
||||
case IN_SW_GSEC_UID:
|
||||
case IN_SW_GSEC_GID:
|
||||
@ -1088,19 +1072,6 @@ static bool get_switches(Firebird::UtilSvc::ArgvType& argv,
|
||||
}
|
||||
user_data->dba.setSpecified(1);
|
||||
break;
|
||||
case IN_SW_GSEC_DBA_TRUSTED_USER:
|
||||
tdsec->utilSvc->checkService();
|
||||
if (user_data->trustedUser.specified())
|
||||
{
|
||||
err_msg_no = GsecMsg79;
|
||||
break;
|
||||
}
|
||||
user_data->trustedUser.setSpecified(1);
|
||||
break;
|
||||
case IN_SW_GSEC_DBA_TRUSTED_ROLE:
|
||||
tdsec->utilSvc->checkService();
|
||||
user_data->trustedRole = 1;
|
||||
break;
|
||||
case IN_SW_GSEC_DBA_PASSWORD:
|
||||
case IN_SW_GSEC_FETCH_PASSWORD:
|
||||
if (user_data->dbaPassword.specified())
|
||||
|
@ -53,8 +53,8 @@ const int IN_SW_GSEC_DBA_PASSWORD = 18; // Database Admin. Password
|
||||
const int IN_SW_GSEC_SQL_ROLE_NAME = 19; // SQL Role to assume
|
||||
const int IN_SW_GSEC_AMBIG = 20; // ambiguous switch
|
||||
//const int IN_SW_GSEC_USERNAME = 21; // placeholder for the username
|
||||
const int IN_SW_GSEC_DBA_TRUSTED_USER = 22; // Database Admin. Trusted User name
|
||||
const int IN_SW_GSEC_DBA_TRUSTED_ROLE = 23; // use trusted role for auth
|
||||
//const int IN_SW_GSEC_DBA_TRUSTED_USER = 22; // Database Admin. Trusted User name
|
||||
//const int IN_SW_GSEC_DBA_TRUSTED_ROLE = 23; // use trusted role for auth
|
||||
#ifdef TRUSTED_AUTH
|
||||
const int IN_SW_GSEC_TRUSTED_AUTH = 24; // Use trusted authentication
|
||||
#endif
|
||||
@ -86,10 +86,10 @@ static const struct Switches::in_sw_tab_t gsec_in_sw_table [] =
|
||||
{IN_SW_GSEC_DBA_PASSWORD, 0, "PASSWORD", 0, 0, 0, false, 0, 2, NULL}, // Database Admin. Password
|
||||
{IN_SW_GSEC_FETCH_PASSWORD, 0, "FETCH_PASSWORD", 0, 0, 0, false, 0, 2, NULL}, // Fetch Database Admin. Password
|
||||
{IN_SW_GSEC_SQL_ROLE_NAME, isc_spb_sql_role_name, "ROLE", 0, 0, 0, false, 0, 2, NULL}, // SQL Role to assume
|
||||
{IN_SW_GSEC_DBA_TRUSTED_USER, 0, TRUSTED_USER_SWITCH, 0, 0, 0, false, 0,
|
||||
/* {IN_SW_GSEC_DBA_TRUSTED_USER, 0, TRUSTED_USER_SWITCH, 0, 0, 0, false, 0,
|
||||
TRUSTED_USER_SWITCH_LEN, NULL}, // Database Admin. Trusted User name
|
||||
{IN_SW_GSEC_DBA_TRUSTED_ROLE, 0, TRUSTED_ROLE_SWITCH, 0, 0, 0, false, 0,
|
||||
TRUSTED_ROLE_SWITCH_LEN, NULL}, // Use trusted role for auth
|
||||
TRUSTED_ROLE_SWITCH_LEN, NULL}, // Use trusted role for auth */
|
||||
#ifdef TRUSTED_AUTH
|
||||
{IN_SW_GSEC_TRUSTED_AUTH, 0, "TRUSTED", 0, 0, 0, false, 0, 1, NULL}, // Database Admin. Trusted User name
|
||||
#endif
|
||||
|
@ -362,9 +362,9 @@ int gstat(Firebird::UtilSvc* uSvc)
|
||||
MOVE_CLEAR(user_buff, sizeof(user_buff));
|
||||
MOVE_CLEAR(pass_buff, sizeof(pass_buff));
|
||||
|
||||
TEXT tr_buff[128], *tr_user = tr_buff;
|
||||
MOVE_CLEAR(tr_buff, sizeof(tr_buff));
|
||||
bool trusted_role = false;
|
||||
// TEXT tr_buff[128], *tr_user = tr_buff;
|
||||
// MOVE_CLEAR(tr_buff, sizeof(tr_buff));
|
||||
// bool trusted_role = false;
|
||||
|
||||
#ifdef TRUSTED_AUTH
|
||||
bool trusted_auth = false;
|
||||
@ -457,7 +457,7 @@ int gstat(Firebird::UtilSvc* uSvc)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IN_SW_DBA_TRUSTED_USER:
|
||||
/* case IN_SW_DBA_TRUSTED_USER:
|
||||
uSvc->checkService();
|
||||
if (argv < end)
|
||||
fb_utils::copy_terminate(tr_user, *argv++, sizeof(tr_buff));
|
||||
@ -466,6 +466,7 @@ int gstat(Firebird::UtilSvc* uSvc)
|
||||
uSvc->checkService();
|
||||
trusted_role = true;
|
||||
break;
|
||||
*/
|
||||
#ifdef TRUSTED_AUTH
|
||||
case IN_SW_DBA_TRUSTEDAUTH:
|
||||
trusted_auth = true;
|
||||
@ -751,14 +752,14 @@ int gstat(Firebird::UtilSvc* uSvc)
|
||||
password, strlen(password));
|
||||
}
|
||||
|
||||
if (*tr_user)
|
||||
/* if (*tr_user)
|
||||
{
|
||||
uSvc->checkService();
|
||||
dpb.insertString(isc_dpb_trusted_auth, tr_user, strlen(tr_user));
|
||||
if (trusted_role)
|
||||
dpb.insertString(isc_dpb_trusted_role, ADMIN_ROLE, strlen(ADMIN_ROLE));
|
||||
}
|
||||
|
||||
*/
|
||||
#ifdef TRUSTED_AUTH
|
||||
if (trusted_auth)
|
||||
dpb.insertTag(isc_dpb_trusted_auth);
|
||||
|
@ -69,8 +69,8 @@ const static struct Switches::in_sw_tab_t dba_in_sw_table[] =
|
||||
{IN_SW_DBA_RELATION, isc_spb_sts_table, "TABLE", 0,0,0, false, 35, 1, NULL}, // msg 35: -t tablename
|
||||
// special switch to avoid including creation date, only for tests (no message)
|
||||
{IN_SW_DBA_NOCREATION, isc_spb_sts_nocreation, "NOCREATION", 0,0,0, false, 0, 1, NULL}, // msg (ignored) -n suppress creation date
|
||||
{IN_SW_DBA_TRUSTED_USER, 0, TRUSTED_USER_SWITCH, 0,0,0, false, 0, TRUSTED_USER_SWITCH_LEN, NULL}, // msg 0 - ignored
|
||||
{IN_SW_DBA_TRUSTED_ROLE, 0, TRUSTED_ROLE_SWITCH, 0,0,0, false, 0, TRUSTED_ROLE_SWITCH_LEN, NULL}, // msg 0 - ignored
|
||||
// {IN_SW_DBA_TRUSTED_USER, 0, TRUSTED_USER_SWITCH, 0,0,0, false, 0, TRUSTED_USER_SWITCH_LEN, NULL}, // msg 0 - ignored
|
||||
// {IN_SW_DBA_TRUSTED_ROLE, 0, TRUSTED_ROLE_SWITCH, 0,0,0, false, 0, TRUSTED_ROLE_SWITCH_LEN, NULL}, // msg 0 - ignored
|
||||
#ifdef TRUSTED_AUTH
|
||||
{IN_SW_DBA_TRUSTEDAUTH, 0, "TRUSTED", 0,0,0, false, 36, 2, NULL}, // msg 36: -tr use trusted authentication
|
||||
#endif
|
||||
|
@ -265,11 +265,11 @@ class NBackup
|
||||
{
|
||||
public:
|
||||
NBackup(UtilSvc* _uSvc, const PathName& _database, const string& _username,
|
||||
const string& _password, bool _run_db_triggers, const string& _trustedUser,
|
||||
bool _trustedRole, bool _direct_io)
|
||||
const string& _password, bool _run_db_triggers/*, const string& _trustedUser,
|
||||
bool _trustedRole*/, bool _direct_io)
|
||||
: uSvc(_uSvc), newdb(0), trans(0), database(_database),
|
||||
username(_username), password(_password), trustedUser(_trustedUser),
|
||||
run_db_triggers(_run_db_triggers), trustedRole(_trustedRole), direct_io(_direct_io),
|
||||
username(_username), password(_password), /*trustedUser(_trustedUser),*/
|
||||
run_db_triggers(_run_db_triggers), /*trustedRole(_trustedRole), */direct_io(_direct_io),
|
||||
dbase(0), backup(0), db_size_pages(0), m_silent(false), m_printed(false)
|
||||
{
|
||||
// Recognition of local prefix allows to work with
|
||||
@ -318,8 +318,8 @@ private:
|
||||
isc_tr_handle trans; // transaction handle
|
||||
|
||||
PathName database;
|
||||
string username, password, trustedUser;
|
||||
bool run_db_triggers, trustedRole, direct_io;
|
||||
string username, password/*, trustedUser*/;
|
||||
bool run_db_triggers, /*trustedRole, */direct_io;
|
||||
|
||||
PathName dbname; // Database file name
|
||||
PathName bakname;
|
||||
@ -638,7 +638,7 @@ void NBackup::attach_database()
|
||||
|
||||
if (password.hasData())
|
||||
dpb.insertString(isc_dpb_password, password);
|
||||
|
||||
/*
|
||||
if (trustedUser.hasData())
|
||||
{
|
||||
uSvc->checkService();
|
||||
@ -649,7 +649,7 @@ void NBackup::attach_database()
|
||||
{
|
||||
uSvc->checkService();
|
||||
dpb.insertString(isc_dpb_trusted_role, ADMIN_ROLE, strlen(ADMIN_ROLE));
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
if (!run_db_triggers)
|
||||
@ -1425,8 +1425,8 @@ void nbackup(UtilSvc* uSvc)
|
||||
NBackup::BackupFiles backup_files;
|
||||
int level;
|
||||
bool print_size = false, version = false;
|
||||
string trustedUser;
|
||||
bool trustedRole = false;
|
||||
// string trustedUser;
|
||||
// bool trustedRole = false;
|
||||
string onOff;
|
||||
|
||||
const Switches switches(nbackup_action_in_sw_table, FB_NELEM(nbackup_action_in_sw_table),
|
||||
@ -1449,7 +1449,7 @@ void nbackup(UtilSvc* uSvc)
|
||||
|
||||
switch (rc->in_sw)
|
||||
{
|
||||
case IN_SW_NBK_TRUSTED_USER:
|
||||
/* case IN_SW_NBK_TRUSTED_USER:
|
||||
uSvc->checkService();
|
||||
if (++itr >= argc)
|
||||
missingParameterForSwitch(uSvc, argv[itr - 1]);
|
||||
@ -1461,7 +1461,7 @@ void nbackup(UtilSvc* uSvc)
|
||||
uSvc->checkService();
|
||||
trustedRole = true;
|
||||
break;
|
||||
|
||||
*/
|
||||
case IN_SW_NBK_USER_NAME:
|
||||
if (++itr >= argc)
|
||||
missingParameterForSwitch(uSvc, argv[itr - 1]);
|
||||
@ -1624,7 +1624,7 @@ void nbackup(UtilSvc* uSvc)
|
||||
usage(uSvc, isc_nbackup_size_with_lock);
|
||||
}
|
||||
|
||||
NBackup nbk(uSvc, database, username, password, run_db_triggers, trustedUser, trustedRole, direct_io);
|
||||
NBackup nbk(uSvc, database, username, password, run_db_triggers, /*trustedUser, trustedRole, */direct_io);
|
||||
try
|
||||
{
|
||||
switch (op)
|
||||
|
@ -75,8 +75,8 @@ static const struct Switches::in_sw_tab_t nbackup_action_in_sw_table [] =
|
||||
{IN_SW_NBK_PASSWORD, 0, "PASSWORD", 0, 0, 0, false, 14, 1, NULL, nboGeneral},
|
||||
{IN_SW_NBK_FETCH, 0, "FETCH_PASSWORD", 0, 0, 0, false, 15, 2, NULL, nboGeneral},
|
||||
{IN_SW_NBK_VERSION, 0, "Z", 0, 0, 0, false, 18, 1, NULL, nboGeneral},
|
||||
{IN_SW_NBK_TRUSTED_USER, 0, TRUSTED_USER_SWITCH, 0, 0, 0, false, 0, TRUSTED_USER_SWITCH_LEN, NULL, nboGeneral},
|
||||
{IN_SW_NBK_TRUSTED_ROLE, 0, TRUSTED_ROLE_SWITCH, 0, 0, 0, false, 0, TRUSTED_ROLE_SWITCH_LEN, NULL, nboGeneral},
|
||||
// {IN_SW_NBK_TRUSTED_USER, 0, TRUSTED_USER_SWITCH, 0, 0, 0, false, 0, TRUSTED_USER_SWITCH_LEN, NULL, nboGeneral},
|
||||
// {IN_SW_NBK_TRUSTED_ROLE, 0, TRUSTED_ROLE_SWITCH, 0, 0, 0, false, 0, TRUSTED_ROLE_SWITCH_LEN, NULL, nboGeneral},
|
||||
{IN_SW_NBK_HELP, 0, "?", 0, 0, 0, false, 0, 1, NULL, 0},
|
||||
{IN_SW_NBK_0, 0, NULL, 0, 0, 0, false, 0, 0, NULL, 0} // End of List
|
||||
};
|
||||
|
@ -250,10 +250,17 @@ int FB_CARG MasterImplementation::same(IVersioned* first, IVersioned* second)
|
||||
|
||||
IMetadataBuilder* MasterImplementation::getMetadataBuilder(IStatus* status, unsigned fieldCount)
|
||||
{
|
||||
MsgMetadata* msgMetadata = new MsgMetadata;
|
||||
msgMetadata->items.grow(fieldCount);
|
||||
|
||||
return msgMetadata->getBuilder(status);
|
||||
try
|
||||
{
|
||||
IMetadataBuilder* bld = new MetadataBuilder(fieldCount);
|
||||
bld->addRef();
|
||||
return bld;
|
||||
}
|
||||
catch(const Exception& ex)
|
||||
{
|
||||
ex.stuffException(status);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
IDebug* FB_CARG MasterImplementation::getDebug()
|
||||
|
@ -305,6 +305,7 @@ static const TOK tokens[] =
|
||||
{PI, "PI", 2, false},
|
||||
{PLACING, "PLACING", 2, false},
|
||||
{PLAN, "PLAN", 1, false},
|
||||
{PLUGIN, "PLUGIN", 2, true},
|
||||
{POSITION, "POSITION", 1, false},
|
||||
{POST_EVENT, "POST_EVENT", 1, false},
|
||||
{POWER, "POWER", 2, false},
|
||||
@ -359,6 +360,7 @@ static const TOK tokens[] =
|
||||
{SELECT, "SELECT", 1, false},
|
||||
{SENSITIVE, "SENSITIVE", 2, false},
|
||||
{SEQUENCE, "SEQUENCE", 2, true},
|
||||
{SERVERWIDE, "SERVERWIDE", 2, true},
|
||||
{SET, "SET", 1, false},
|
||||
{SHADOW, "SHADOW", 1, false},
|
||||
{KW_SHARED, "SHARED", 1, false},
|
||||
|
Loading…
Reference in New Issue
Block a user