From: <ale...@us...> - 2014-04-04 15:57:23
|
Revision: 59358 http://sourceforge.net/p/firebird/code/59358 Author: alexpeshkoff Date: 2014-04-04 15:57:18 +0000 (Fri, 04 Apr 2014) Log Message: ----------- Implemented CORE-3370: Resolve additional aspects of multiple security databases from services and cross-database requests POV (mapping names) Modified Paths: -------------- firebird/trunk/builds/install/misc/databases.conf.in firebird/trunk/lang_helpers/gds_codes.ftn firebird/trunk/lang_helpers/gds_codes.pas firebird/trunk/src/alice/alice.cpp firebird/trunk/src/alice/aliceswi.h firebird/trunk/src/auth/AuthDbg.cpp firebird/trunk/src/auth/AuthDbg.h firebird/trunk/src/auth/SecureRemotePassword/Message.h firebird/trunk/src/auth/SecureRemotePassword/manage/SrpManagement.cpp firebird/trunk/src/auth/SecureRemotePassword/server/SrpServer.cpp firebird/trunk/src/auth/SecurityDatabase/LegacyManagement.epp firebird/trunk/src/auth/SecurityDatabase/LegacyServer.cpp firebird/trunk/src/auth/trusted/AuthSspi.cpp firebird/trunk/src/auth/trusted/AuthSspi.h firebird/trunk/src/burp/backup.epp firebird/trunk/src/burp/burp.cpp firebird/trunk/src/burp/burp.h firebird/trunk/src/burp/burpswi.h firebird/trunk/src/burp/restore.epp firebird/trunk/src/common/Auth.cpp firebird/trunk/src/common/Auth.h firebird/trunk/src/common/MsgMetadata.cpp firebird/trunk/src/common/MsgMetadata.h firebird/trunk/src/common/StatusArg.cpp firebird/trunk/src/common/StatusArg.h firebird/trunk/src/common/classes/ClumpletReader.cpp firebird/trunk/src/common/classes/ClumpletReader.h firebird/trunk/src/common/classes/Hash.h firebird/trunk/src/common/db_alias.cpp firebird/trunk/src/common/db_alias.h firebird/trunk/src/common/isc_s_proto.h firebird/trunk/src/common/security.cpp firebird/trunk/src/common/security.h firebird/trunk/src/dsql/DdlNodes.epp firebird/trunk/src/dsql/DdlNodes.h firebird/trunk/src/dsql/parse.y firebird/trunk/src/include/firebird/Auth.h firebird/trunk/src/include/firebird/Provider.h firebird/trunk/src/include/gen/codetext.h firebird/trunk/src/include/gen/iberror.h firebird/trunk/src/include/gen/ids.h firebird/trunk/src/include/gen/msgs.h firebird/trunk/src/include/gen/sql_code.h firebird/trunk/src/include/gen/sql_state.h firebird/trunk/src/isql/extract.epp firebird/trunk/src/isql/isql.h firebird/trunk/src/isql/show.epp firebird/trunk/src/isql/show_proto.h firebird/trunk/src/jrd/UserManagement.cpp firebird/trunk/src/jrd/constants.h firebird/trunk/src/jrd/dfw.epp firebird/trunk/src/jrd/drq.h firebird/trunk/src/jrd/extds/ExtDS.cpp firebird/trunk/src/jrd/fields.h firebird/trunk/src/jrd/idx.h firebird/trunk/src/jrd/jrd.cpp firebird/trunk/src/jrd/names.h firebird/trunk/src/jrd/opt.cpp firebird/trunk/src/jrd/relations.h firebird/trunk/src/jrd/scl.epp firebird/trunk/src/jrd/scl.h firebird/trunk/src/jrd/svc.cpp firebird/trunk/src/jrd/svc.h firebird/trunk/src/jrd/tra.cpp firebird/trunk/src/jrd/tra.h firebird/trunk/src/jrd/trace/TraceCmdLine.cpp firebird/trunk/src/jrd/trace/traceswi.h firebird/trunk/src/msgs/facilities2.sql firebird/trunk/src/msgs/messages2.sql firebird/trunk/src/msgs/system_errors2.sql firebird/trunk/src/remote/server/server.cpp firebird/trunk/src/utilities/gsec/gsec.cpp firebird/trunk/src/utilities/gsec/gsecswi.h firebird/trunk/src/utilities/gstat/dba.epp firebird/trunk/src/utilities/gstat/dbaswi.h firebird/trunk/src/utilities/nbackup/nbackup.cpp firebird/trunk/src/utilities/nbackup/nbkswi.h firebird/trunk/src/yvalve/MasterImplementation.cpp firebird/trunk/src/yvalve/keywords.cpp Added Paths: ----------- firebird/trunk/doc/sql.extensions/README.mapping.html firebird/trunk/src/jrd/Mapping.cpp firebird/trunk/src/jrd/Mapping.h Modified: firebird/trunk/builds/install/misc/databases.conf.in =================================================================== --- firebird/trunk/builds/install/misc/databases.conf.in 2014-04-04 08:53:05 UTC (rev 59357) +++ firebird/trunk/builds/install/misc/databases.conf.in 2014-04-04 15:57:18 UTC (rev 59358) @@ -27,6 +27,7 @@ security.db = $(dir_secDb)/security3.fdb { RemoteAccess = false + DefaultDbCachePages = 50 } # Added: firebird/trunk/doc/sql.extensions/README.mapping.html =================================================================== --- firebird/trunk/doc/sql.extensions/README.mapping.html (rev 0) +++ firebird/trunk/doc/sql.extensions/README.mapping.html 2014-04-04 15:57:18 UTC (rev 59358) @@ -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:pes...@ma...">pes...@ma...</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> \ No newline at end of file Property changes on: firebird/trunk/doc/sql.extensions/README.mapping.html ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/html \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Modified: firebird/trunk/lang_helpers/gds_codes.ftn =================================================================== --- firebird/trunk/lang_helpers/gds_codes.ftn 2014-04-04 08:53:05 UTC (rev 59357) +++ firebird/trunk/lang_helpers/gds_codes.ftn 2014-04-04 15:57:18 UTC (rev 59358) @@ -1564,6 +1564,28 @@ 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 @@ 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 Modified: firebird/trunk/lang_helpers/gds_codes.pas =================================================================== --- firebird/trunk/lang_helpers/gds_codes.pas 2014-04-04 08:53:05 UTC (rev 59357) +++ firebird/trunk/lang_helpers/gds_codes.pas 2014-04-04 15:57:18 UTC (rev 59358) @@ -789,6 +789,17 @@ 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 @@ 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; Modified: firebird/trunk/src/alice/alice.cpp =================================================================== --- firebird/trunk/src/alice/alice.cpp 2014-04-04 08:53:05 UTC (rev 59357) +++ firebird/trunk/src/alice/alice.cpp 2014-04-04 15:57:18 UTC (rev 59358) @@ -200,7 +200,7 @@ 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 @@ 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 @@ } 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()) { Modified: firebird/trunk/src/alice/aliceswi.h =================================================================== --- firebird/trunk/src/alice/aliceswi.h 2014-04-04 08:53:05 UTC (rev 59357) +++ firebird/trunk/src/alice/aliceswi.h 2014-04-04 15:57:18 UTC (rev 59358) @@ -60,8 +60,8 @@ 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 @@ #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 @@ 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 @@ 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}, Modified: firebird/trunk/src/auth/AuthDbg.cpp =================================================================== --- firebird/trunk/src/auth/AuthDbg.cpp 2014-04-04 08:53:05 UTC (rev 59357) +++ firebird/trunk/src/auth/AuthDbg.cpp 2014-04-04 15:57:18 UTC (rev 59358) @@ -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 @@ 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 @@ 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) Modified: firebird/trunk/src/auth/AuthDbg.h =================================================================== --- firebird/trunk/src/auth/AuthDbg.h 2014-04-04 08:53:05 UTC (rev 59357) +++ firebird/trunk/src/auth/AuthDbg.h 2014-04-04 15:57:18 UTC (rev 59358) @@ -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 @@ private: Firebird::string str; + Firebird::RefPtr<Firebird::IConfig> config; }; class DebugClient FB_FINAL : public Firebird::StdPlugin<IClient, FB_AUTH_CLIENT_VERSION> Modified: firebird/trunk/src/auth/SecureRemotePassword/Message.h =================================================================== --- firebird/trunk/src/auth/SecureRemotePassword/Message.h 2014-04-04 08:53:05 UTC (rev 59357) +++ firebird/trunk/src/auth/SecureRemotePassword/Message.h 2014-04-04 15:57:18 UTC (rev 59358) @@ -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 @@ } 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 + } } + else + { + fb_assert(builder); - t = metadata->getType(&st, fieldCount); - check(&st); - sz = metadata->getLength(&st, fieldCount); - check(&st); - if (!checkType<T>(t, sz)) - { - (Firebird::Arg::Gds(isc_random) << "Incompatible data type").raise(); + 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 @@ { 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; + } -private: - Firebird::UCharBuffer dataBuf; - unsigned fieldCount; -}; + // access to message's data buffer + unsigned char* getBuffer() + { + if (!buffer) + { + getMetadata(); + createBuffer(metadata); + while(fieldList) + { + fieldList->linkWithMessage(buffer); + fieldList = fieldList->next; + } + } -// 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); -} + return buffer; + } -template <> -bool Message::checkType<ISC_QUAD>(unsigned t, unsigned sz) -{ - return (t == SQL_BLOB || t == SQL_QUAD) && sz == sizeof(ISC_QUAD); -} +private: + void createBuffer(Firebird::IMessageMetadata* aMeta) + { + unsigned l = aMeta->getMessageLength(s); + check(s); + buffer = new unsigned char[l]; + } -template <> -bool Message::checkType<ISC_INT64>(unsigned t, unsigned sz) -{ - return t == SQL_INT64 && sz == sizeof(ISC_INT64); -} +public: + Firebird::IStatus* s; -template <> -bool Message::checkType<FB_BOOLEAN>(unsigned t, unsigned sz) -{ - return t == SQL_BOOLEAN && sz == sizeof(FB_BOOLEAN); -} +private: +#ifdef INTERNAL_FIREBIRD + Firebird::LocalStatus st; +#endif + Firebird::IMessageMetadata* metadata; + unsigned char* buffer; + Firebird::IMetadataBuilder* builder; + unsigned fieldCount; + FieldLink* fieldList; +}; 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 @@ 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 @@ 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 @@ }; 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 @@ } 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 @@ }; 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 @@ } 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 @@ 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; +} Modified: firebird/trunk/src/auth/SecureRemotePassword/manage/SrpManagement.cpp =================================================================== --- firebird/trunk/src/auth/SecureRemotePassword/manage/SrpManagement.cpp 2014-04-04 08:53:05 UTC (rev 59357) +++ firebird/trunk/src/auth/SecureRemotePassword/manage/SrpManagement.cpp 2014-04-04 15:57:18 UTC (rev 59358) @@ -75,7 +75,7 @@ "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 @@ { 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 @@ 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 @@ 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 @@ { 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ " 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 @@ 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 @@ } 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); Modified: firebird/trunk/src/auth/SecureRemotePassword/server/SrpServer.cpp =================================================================== --- firebird/trunk/src/auth/SecureRemotePassword/server/SrpServer.cpp 2014-04-04 08:53:05 UTC (rev 59357) +++ firebird/trunk/src/auth/SecureRemotePassword/server/SrpServer.cpp 2014-04-04 15:57:18 UTC (rev 59358) @@ -174,7 +174,8 @@ 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 @@ { 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; } } Modified: firebird/trunk/src/auth/SecurityDatabase/LegacyManagement.epp =================================================================== --- firebird/trunk/src/auth/SecurityDatabase/LegacyManagement.epp 2014-04-04 08:53:05 UTC (rev 59357) +++ firebird/trunk/src/auth/SecurityDatabase/LegacyManagement.epp 2014-04-04 15:57:18 UTC (rev 59358) @@ -68,7 +68,7 @@ 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 @@ 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 @@ 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 @@ 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) Modified: firebird/trunk/src/auth/SecurityDatabase/LegacyServer.cpp =================================================================== --- firebird/trunk/src/auth/SecurityDatabase/LegacyServer.cpp 2014-04-04 08:53:05 UTC (rev 59357) +++ firebird/trunk/src/auth/SecurityDatabase/LegacyServer.cpp 2014-04-04 15:57:18 UTC (rev 59358) @@ -351,7 +351,7 @@ 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; } Modified: firebird/trunk/src/auth/trusted/AuthSspi.cpp =================================================================== --- firebird/trunk/src/auth/trusted/AuthSspi.cpp 2014-04-04 08:53:05 UTC (rev 59357) +++ firebird/trunk/src/auth/trusted/AuthSspi.cpp 2014-04-04 15:57:18 UTC (rev 59358) @@ -369,8 +369,13 @@ 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; } Modified: firebird/trunk/src/auth/trusted/AuthSspi.h =================================================================== --- firebird/trunk/src/auth/trusted/AuthSspi.h 2014-04-04 08:53:05 UTC (rev 59357) +++ firebird/trunk/src/auth/trusted/AuthSspi.h 2014-04-04 15:57:18 UTC (rev 59358) @@ -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> Modified: firebird/trunk/src/burp/backup.epp =================================================================== --- firebird/trunk/src/burp/backup.epp 2014-04-04 08:53:05 UTC (rev 59357) +++ firebird/trunk/src/burp/backup.epp 2014-04-04 15:57:18 UTC (rev 59358) @@ -4073,16 +4073,45 @@ * **************************************/ 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); Modified: firebird/trunk/src/burp/burp.cpp =================================================================== --- firebird/trunk/src/burp/burp.cpp 2014-04-04 08:53:05 UTC (rev 59357) +++ firebird/trunk/src/burp/burp.cpp 2014-04-04 15:57:18 UTC (rev 59358) @@ -683,7 +683,7 @@ } 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 @@ } 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 @@ } break; - case IN_SW_BURP_TRUSTED_USER: +/* case IN_SW_BURP_TRUSTED_USER: uSvc->checkService(); if (!authBlock) { @@ -1046,7 +1046,7 @@ 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)) Modified: firebird/trunk/src/burp/burp.h =================================================================== --- firebird/trunk/src/burp/burp.h 2014-04-04 08:53:05 UTC (rev 59357) +++ firebird/trunk/src/burp/burp.h 2014-04-04 15:57:18 UTC (rev 59358) @@ -596,10 +596,16 @@ 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, Modified: firebird/trunk/src/burp/burpswi.h =================================================================== --- firebird/trunk/src/burp/burpswi.h 2014-04-04 08:53:05 UTC (rev 59357) +++ firebird/trunk/src/burp/burpswi.h 2014-04-04 15:57:18 UTC (rev 59358) @@ -171,8 +171,8 @@ {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}, */ Modified: firebird/trunk/src/burp/restore.epp =================================================================== --- firebird/trunk/src/burp/restore.epp 2014-04-04 08:53:05 UTC (rev 59357) +++ firebird/trunk/src/burp/restore.epp 2014-04-04 15:57:18 UTC (rev 59358) @@ -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 @@ * * 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: + case att_auto_map_role: l = GET_TEXT(temp); role.assign(temp, l); break; - case att_map_os: - l = GET_TEXT(temp); - os.assign(temp, l); + case att_map_to_type: + get_int32(tdgbl); break; - */ - case att_auto_map_role: - l = GET_TEXT(temp); - role.assign(temp, l); + + 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 @@ return true; // silently skip attributes on old server } + if (tdgbl->firstMap) + { + tdgbl->firstMap = false; + BURP_verbose(301); + // msg 301, restoring names mapping + } + if (role != ADMIN_ROLE) { BURP_error(300, false); return true; } - if (tdgbl->firstMap) - { - tdgbl->firstMap = false; - BURP_verbose(301); - // msg 301, restoring names mapping - } 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); Modified: firebird/trunk/src/common/Auth.cpp =================================================================== --- firebird/trunk/src/common/Auth.cpp 2014-04-04 08:53:05 UTC (rev 59357) +++ firebird/trunk/src/common/Auth.cpp 2014-04-04 15:57:18 UTC (rev 59358) @@ -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 @@ WriterImplementation::WriterIm... [truncated message content] |