8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 10:43:03 +01:00

Trusted authentication for windows

This commit is contained in:
alexpeshkoff 2006-12-08 18:38:15 +00:00
parent 83a2065a3c
commit 1a4652f01a
44 changed files with 1117 additions and 254 deletions

View File

@ -47,7 +47,7 @@
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386" AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="comctl32.lib ws2_32.lib mpr.lib version.lib icuuc.lib icuin.lib" AdditionalDependencies="comctl32.lib ws2_32.lib mpr.lib version.lib secur32.lib icuuc.lib icuin.lib"
OutputFile="..\..\..\temp\release\firebird\bin\fb_inet_server.exe" OutputFile="..\..\..\temp\release\firebird\bin\fb_inet_server.exe"
LinkIncremental="1" LinkIncremental="1"
SuppressStartupBanner="TRUE" SuppressStartupBanner="TRUE"
@ -115,7 +115,7 @@
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386" AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="comctl32.lib ws2_32.lib mpr.lib version.lib icuuc.lib icuin.lib" AdditionalDependencies="comctl32.lib ws2_32.lib mpr.lib version.lib secur32.lib icuuc.lib icuin.lib"
OutputFile="..\..\..\temp\debug\firebird\bin\fb_inet_server.exe" OutputFile="..\..\..\temp\debug\firebird\bin\fb_inet_server.exe"
LinkIncremental="1" LinkIncremental="1"
SuppressStartupBanner="TRUE" SuppressStartupBanner="TRUE"

View File

@ -42,7 +42,7 @@
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386" AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="comctl32.lib ws2_32.lib mpr.lib version.lib" AdditionalDependencies="comctl32.lib ws2_32.lib mpr.lib version.lib secur32.lib"
OutputFile="..\..\..\temp\debug\firebird\bin\fbclient.dll" OutputFile="..\..\..\temp\debug\firebird\bin\fbclient.dll"
LinkIncremental="1" LinkIncremental="1"
SuppressStartupBanner="TRUE" SuppressStartupBanner="TRUE"
@ -115,7 +115,7 @@
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386" AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="comctl32.lib ws2_32.lib mpr.lib version.lib" AdditionalDependencies="comctl32.lib ws2_32.lib mpr.lib version.lib secur32.Lib"
OutputFile="..\..\..\temp\release\firebird\bin\fbclient.dll" OutputFile="..\..\..\temp\release\firebird\bin\fbclient.dll"
LinkIncremental="1" LinkIncremental="1"
SuppressStartupBanner="TRUE" SuppressStartupBanner="TRUE"
@ -371,6 +371,15 @@
</FileConfiguration> </FileConfiguration>
</File> </File>
</Filter> </Filter>
<Filter
Name="AuthSspi">
<File
RelativePath="..\..\..\src\auth\trusted\AuthSspi.cpp">
</File>
<File
RelativePath="..\..\..\src\auth\trusted\AuthSspi.h">
</File>
</Filter>
<File <File
RelativePath="..\defs\fbclient.def"> RelativePath="..\defs\fbclient.def">
</File> </File>

View File

@ -42,7 +42,7 @@
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386" AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="comctl32.lib ws2_32.lib mpr.lib version.lib icuuc.lib icuin.lib" AdditionalDependencies="comctl32.lib ws2_32.lib mpr.lib version.lib secur32.lib icuuc.lib icuin.lib"
OutputFile="..\..\..\temp\debug\firebird\bin\fbembed.dll" OutputFile="..\..\..\temp\debug\firebird\bin\fbembed.dll"
LinkIncremental="1" LinkIncremental="1"
SuppressStartupBanner="TRUE" SuppressStartupBanner="TRUE"
@ -116,7 +116,7 @@
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386" AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="mpr.lib ws2_32.lib version.lib icuuc.lib icuin.lib" AdditionalDependencies="mpr.lib ws2_32.lib version.lib secur32.lib icuuc.lib icuin.lib"
OutputFile="..\..\..\temp\release\firebird/bin/fbembed.dll" OutputFile="..\..\..\temp\release\firebird/bin/fbembed.dll"
LinkIncremental="1" LinkIncremental="1"
SuppressStartupBanner="TRUE" SuppressStartupBanner="TRUE"
@ -362,6 +362,15 @@
</FileConfiguration> </FileConfiguration>
</File> </File>
</Filter> </Filter>
<Filter
Name="AuthSspi">
<File
RelativePath="..\..\..\src\auth\trusted\AuthSspi.cpp">
</File>
<File
RelativePath="..\..\..\src\auth\trusted\AuthSspi.h">
</File>
</Filter>
<File <File
RelativePath="..\defs\fbclient.def"> RelativePath="..\defs\fbclient.def">
</File> </File>

View File

@ -47,7 +47,7 @@
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386" AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="comctl32.lib ws2_32.lib mpr.lib version.lib icuuc.lib icuin.lib" AdditionalDependencies="comctl32.lib ws2_32.lib mpr.lib secur32.lib version.lib icuuc.lib icuin.lib"
OutputFile="..\..\..\temp\release\firebird\bin\fbserver.exe" OutputFile="..\..\..\temp\release\firebird\bin\fbserver.exe"
LinkIncremental="1" LinkIncremental="1"
SuppressStartupBanner="TRUE" SuppressStartupBanner="TRUE"
@ -115,7 +115,7 @@
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386" AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="comctl32.lib ws2_32.lib mpr.lib version.lib icuuc.lib icuin.lib" AdditionalDependencies="comctl32.lib ws2_32.lib mpr.lib secur32.lib version.lib icuuc.lib icuin.lib"
OutputFile="..\..\..\temp\debug\firebird\bin\fbserver.exe" OutputFile="..\..\..\temp\debug\firebird\bin\fbserver.exe"
LinkIncremental="1" LinkIncremental="1"
SuppressStartupBanner="TRUE" SuppressStartupBanner="TRUE"

View File

@ -220,6 +220,16 @@
RelativePath="..\..\..\src\remote\xnet_proto.h"> RelativePath="..\..\..\src\remote\xnet_proto.h">
</File> </File>
</Filter> </Filter>
<Filter
Name="AuthSspi"
Filter="">
<File
RelativePath="..\..\..\src\auth\trusted\AuthSspi.cpp">
</File>
<File
RelativePath="..\..\..\src\auth\trusted\AuthSspi.h">
</File>
</Filter>
</Files> </Files>
<Globals> <Globals>
</Globals> </Globals>

View File

@ -217,6 +217,15 @@
RelativePath="..\..\..\src\remote\xnet_proto.h"> RelativePath="..\..\..\src\remote\xnet_proto.h">
</File> </File>
</Filter> </Filter>
<Filter
Name="AuthSspi">
<File
RelativePath="..\..\..\src\auth\trusted\AuthSspi.cpp">
</File>
<File
RelativePath="..\..\..\src\auth\trusted\AuthSspi.h">
</File>
</Filter>
</Files> </Files>
<Globals> <Globals>
</Globals> </Globals>

View File

@ -253,6 +253,9 @@ int common_main(int argc,
tdgbl->ALICE_data.ua_user = NULL; tdgbl->ALICE_data.ua_user = NULL;
tdgbl->ALICE_data.ua_password = NULL; tdgbl->ALICE_data.ua_password = NULL;
#ifdef TRUSTED_SERVICES
tdgbl->ALICE_data.ua_tr_user = NULL;
#endif
// Start by parsing switches // Start by parsing switches
@ -318,6 +321,15 @@ int common_main(int argc,
if (table->in_sw_value == sw_z) { if (table->in_sw_value == sw_z) {
ALICE_print(3, GDS_VERSION, 0, 0, 0, 0); // msg 3: gfix version %s ALICE_print(3, GDS_VERSION, 0, 0, 0, 0); // msg 3: gfix version %s
} }
#ifdef TRUSTED_SERVICES
if (strcmp(table->in_sw_name, "trusted") == 0) {
if (--argc <= 0) {
ALICE_error(13); // msg 13: user name required
}
tdgbl->ALICE_data.ua_tr_user = (UCHAR*)(*argv++);
continue;
}
#endif
if ((table->in_sw_incompatibilities & switches) || if ((table->in_sw_incompatibilities & switches) ||
(table->in_sw_requires && !(table->in_sw_requires & switches))) (table->in_sw_requires && !(table->in_sw_requires & switches)))
{ {
@ -544,7 +556,10 @@ int common_main(int argc,
#else #else
ALICE_print(21, 0, 0, 0, 0, 0); // msg 21: plausible options are:\n ALICE_print(21, 0, 0, 0, 0, 0); // msg 21: plausible options are:\n
for (table = alice_in_sw_table; table->in_sw_msg; table++) for (table = alice_in_sw_table; table->in_sw_msg; table++)
ALICE_print(table->in_sw_msg, 0, 0, 0, 0, 0); {
if (table->in_sw_msg)
ALICE_print(table->in_sw_msg, 0, 0, 0, 0, 0);
}
ALICE_print(22, 0, 0, 0, 0, 0); // msg 22: \n qualifiers show the major option in parenthesis ALICE_print(22, 0, 0, 0, 0, 0); // msg 22: \n qualifiers show the major option in parenthesis
#endif #endif
exit_local(FINI_ERROR, tdgbl); exit_local(FINI_ERROR, tdgbl);

View File

@ -60,6 +60,9 @@ struct user_action
ULONG ua_switches; ULONG ua_switches;
const UCHAR* ua_user; const UCHAR* ua_user;
const UCHAR* ua_password; const UCHAR* ua_password;
#ifdef TRUSTED_SERVICES
UCHAR* ua_tr_user;
#endif
bool ua_use; bool ua_use;
bool ua_force; bool ua_force;
bool ua_read_only; bool ua_read_only;

View File

@ -106,7 +106,8 @@ enum alice_switches
IN_SW_ALICE_HIDDEN_FORCE = 40, IN_SW_ALICE_HIDDEN_FORCE = 40,
IN_SW_ALICE_HIDDEN_TRAN = 41, IN_SW_ALICE_HIDDEN_TRAN = 41,
IN_SW_ALICE_HIDDEN_ATTACH = 42, IN_SW_ALICE_HIDDEN_ATTACH = 42,
IN_SW_ALICE_SET_DB_SQL_DIALECT = 43 IN_SW_ALICE_SET_DB_SQL_DIALECT = 43,
IN_SW_ALICE_TRUSTED_USER = 44
}; };
static const char* ALICE_SW_ASYNC = "async"; static const char* ALICE_SW_ASYNC = "async";
@ -214,6 +215,10 @@ static in_sw_tab_t alice_in_sw_table[] =
// msg 48: \t-tran\t\tshutdown transaction startup // msg 48: \t-tran\t\tshutdown transaction startup
{IN_SW_ALICE_USE, 0, "use", sw_use, {IN_SW_ALICE_USE, 0, "use", sw_use,
0, ~(sw_use | sw_user | sw_password), FALSE, 49, 0, NULL}, 0, ~(sw_use | sw_user | sw_password), FALSE, 49, 0, NULL},
#ifdef TRUSTED_SERVICES
{IN_SW_ALICE_TRUSTED_USER, 0, "trusted", 0, 0, 0,
FALSE, 0, 0, NULL},
#endif
// msg 49: \t-use\t\tuse full or reserve space for versions // msg 49: \t-use\t\tuse full or reserve space for versions
{IN_SW_ALICE_USER, 0, "user", sw_user, {IN_SW_ALICE_USER, 0, "user", sw_user,
0, 0, FALSE, 50, 0, NULL}, 0, 0, FALSE, 50, 0, NULL},

View File

@ -322,6 +322,13 @@ static void buildDpb(Firebird::ClumpletWriter& dpb, const ULONG switches)
tdgbl->ALICE_data.ua_password, tdgbl->ALICE_data.ua_password,
strlen(reinterpret_cast<const char*>(tdgbl->ALICE_data.ua_password))); strlen(reinterpret_cast<const char*>(tdgbl->ALICE_data.ua_password)));
} }
#ifdef TRUSTED_SERVICES
if (tdgbl->ALICE_data.ua_tr_user) {
dpb.insertBytes(isc_dpb_trusted_auth,
tdgbl->ALICE_data.ua_tr_user,
strlen(reinterpret_cast<const char*>(tdgbl->ALICE_data.ua_tr_user)));
}
#endif
} }

View File

@ -202,6 +202,13 @@ bool TDR_attach_database(ISC_STATUS* status_vector,
tdgbl->ALICE_data.ua_password, tdgbl->ALICE_data.ua_password,
strlen(reinterpret_cast<const char*>(tdgbl->ALICE_data.ua_password))); strlen(reinterpret_cast<const char*>(tdgbl->ALICE_data.ua_password)));
} }
#ifdef TRUSTED_SERVICES
if (tdgbl->ALICE_data.ua_tr_user) {
dpb.insertBytes(isc_dpb_trusted_auth,
tdgbl->ALICE_data.ua_tr_user,
strlen(reinterpret_cast<const char*>(tdgbl->ALICE_data.ua_tr_user)));
}
#endif
trans->tdr_db_handle = 0; trans->tdr_db_handle = 0;

View File

@ -0,0 +1,218 @@
#include "AuthSspi.h"
#ifdef TRUSTED_AUTH
#include <../common/classes/ClumpletReader.h>
AuthSspi::AuthSspi()
: hasContext(false), ctName(*getDefaultMemoryPool())
{
TimeStamp timeOut;
hasCredentials = AcquireCredentialsHandle(0, "NTLM", SECPKG_CRED_BOTH, 0, 0, 0, 0,
&secHndl, &timeOut) == SEC_E_OK;
}
AuthSspi::~AuthSspi()
{
if (hasContext)
{
DeleteSecurityContext(&ctxtHndl);
}
if (hasCredentials)
{
FreeCredentialsHandle(&secHndl);
}
}
namespace
{
void makeDesc(SecBufferDesc& d, SecBuffer& b, size_t len, void* p)
{
b.BufferType = SECBUFFER_TOKEN;
b.cbBuffer = len;
b.pvBuffer = len ? p : 0;
d.ulVersion = SECBUFFER_VERSION;
d.cBuffers = 1;
d.pBuffers = &b;
}
bool checkAdminPrivilege(PCtxtHandle phContext)
{
// Query access token from security context
SecPkgContext_AccessToken spc;
spc.AccessToken = 0;
if (QueryContextAttributes(phContext, SECPKG_ATTR_ACCESS_TOKEN, &spc) != SEC_E_OK)
{
return false;
}
// Query required buffer size
DWORD token_len = 0;
GetTokenInformation(spc.AccessToken,
TokenGroups, 0, 0, &token_len);
// Query actual group information
Firebird::Array<char> buffer;
TOKEN_GROUPS *ptg = (TOKEN_GROUPS *)buffer.getBuffer(token_len);
bool ok = GetTokenInformation(spc.AccessToken,
TokenGroups, ptg, token_len, &token_len);
FreeContextBuffer(spc.AccessToken);
if (! ok)
{
return false;
}
// Create a System Identifier for the Admin group.
SID_IDENTIFIER_AUTHORITY system_sid_authority = {SECURITY_NT_AUTHORITY};
PSID admin_sid;
if (!AllocateAndInitializeSid(&system_sid_authority, 2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0, &admin_sid))
{
return false;
}
// Finally we'll iterate through the list of groups for this access
// token looking for a match against the SID we created above.
for (DWORD i = 0; i < ptg->GroupCount; i++)
{
if (EqualSid(ptg->Groups[i].Sid, admin_sid))
{
FreeSid(admin_sid);
return true;
}
}
FreeSid(admin_sid);
return false;
}
}
bool AuthSspi::request(AuthSspi::DataHolder& data)
{
if (! hasCredentials)
{
data.clear();
return false;
}
TimeStamp timeOut;
char s[BUFSIZE];
SecBuffer outputBuffer, inputBuffer;
SecBufferDesc outputDesc, inputDesc;
makeDesc(outputDesc, outputBuffer, sizeof(s), s);
makeDesc(inputDesc, inputBuffer, data.getCount(), data.begin());
ULONG fContextAttr = 0;
SECURITY_STATUS x = InitializeSecurityContext(
&secHndl, hasContext ? &ctxtHndl : 0, 0, 0, 0, SECURITY_NATIVE_DREP,
hasContext ? &inputDesc : 0, 0, &ctxtHndl, &outputDesc, &fContextAttr, &timeOut);
switch (x)
{
case SEC_E_OK:
DeleteSecurityContext(&ctxtHndl);
hasContext = false;
break;
case SEC_I_CONTINUE_NEEDED:
hasContext = true;
break;
default:
if (hasContext)
{
DeleteSecurityContext(&ctxtHndl);
}
hasContext = false;
data.clear();
return false;
}
if (outputBuffer.cbBuffer)
{
memcpy(data.getBuffer(outputBuffer.cbBuffer),
outputBuffer.pvBuffer, outputBuffer.cbBuffer);
}
else
{
data.clear();
}
return true;
}
bool AuthSspi::accept(AuthSspi::DataHolder& data)
{
if (! hasCredentials)
{
data.clear();
return false;
}
TimeStamp timeOut;
char s[BUFSIZE];
SecBuffer outputBuffer, inputBuffer;
SecBufferDesc outputDesc, inputDesc;
makeDesc(outputDesc, outputBuffer, sizeof(s), s);
makeDesc(inputDesc, inputBuffer, data.getCount(), data.begin());
ULONG fContextAttr = 0;
SecPkgContext_Names name;
SECURITY_STATUS x = AcceptSecurityContext(
&secHndl, hasContext ? &ctxtHndl : 0, &inputDesc, 0,
SECURITY_NATIVE_DREP, &ctxtHndl, &outputDesc,
&fContextAttr, &timeOut);
switch(x)
{
case SEC_E_OK:
if (checkAdminPrivilege(&ctxtHndl))
{
ctName = "SYSDBA";
}
else if (QueryContextAttributes(&ctxtHndl, SECPKG_ATTR_NAMES, &name) == SEC_E_OK)
{
ctName = name.sUserName;
ctName.upper();
FreeContextBuffer(name.sUserName);
}
DeleteSecurityContext(&ctxtHndl);
hasContext = false;
break;
case SEC_I_CONTINUE_NEEDED:
hasContext = true;
break;
default:
if (hasContext)
{
DeleteSecurityContext(&ctxtHndl);
}
hasContext = false;
data.clear();
return false;
}
if (outputBuffer.cbBuffer)
{
memcpy(data.getBuffer(outputBuffer.cbBuffer),
outputBuffer.pvBuffer, outputBuffer.cbBuffer);
}
else
{
data.clear();
}
return true;
}
bool AuthSspi::getLogin(Firebird::string& login)
{
if (ctName.hasData())
{
login = ctName;
ctName.erase();
return true;
}
return false;
}
#endif //TRUSTED_AUTH

View File

@ -0,0 +1,44 @@
#ifndef AUTH_SPPI_H
#define AUTH_SPPI_H
#include <firebird.h>
#ifdef TRUSTED_AUTH
#include <../common/classes/fb_string.h>
#include <../common/classes/array.h>
#include <../jrd/ibase.h>
#define SECURITY_WIN32
#include <windows.h>
#include <Security.h>
#include <stdio.h>
class AuthSspi
{
private:
enum {BUFSIZE = 4096};
SecHandle secHndl;
bool hasCredentials;
CtxtHandle ctxtHndl;
bool hasContext;
Firebird::string ctName;
public:
typedef Firebird::Array<unsigned char> DataHolder;
AuthSspi();
~AuthSspi();
bool isActive()
{
return hasContext;
}
bool request(DataHolder& data);
bool accept(DataHolder& data);
bool getLogin(Firebird::string& login);
};
#endif //TRUSTED_AUTH
#endif //AUTH_SPPI_H

View File

@ -830,6 +830,14 @@ int common_main(int argc,
// user name parameter missing // user name parameter missing
tdgbl->gbl_sw_user = *argv++; tdgbl->gbl_sw_user = *argv++;
} }
#ifdef TRUSTED_SERVICES
else if (in_sw_tab->in_sw == IN_SW_BURP_TRUSTED_USER) {
if (argv >= end)
BURP_error(188, true, 0, 0, 0, 0, 0);
// trusted user name parameter missing
tdgbl->gbl_sw_tr_user = *argv++;
}
#endif
else if (in_sw_tab->in_sw == IN_SW_BURP_ROLE) { else if (in_sw_tab->in_sw == IN_SW_BURP_ROLE) {
if (argv >= end) if (argv >= end)
BURP_error(253, true, 0, 0, 0, 0, 0); BURP_error(253, true, 0, 0, 0, 0, 0);
@ -1049,6 +1057,13 @@ int common_main(int argc,
strlen(tdgbl->gbl_sw_user)); strlen(tdgbl->gbl_sw_user));
break; break;
#ifdef TRUSTED_SERVICES
case (IN_SW_BURP_TRUSTED_USER):
dpb.insertString(isc_dpb_trusted_auth,
tdgbl->gbl_sw_tr_user,
strlen(tdgbl->gbl_sw_tr_user));
break;
#endif
case (IN_SW_BURP_V): case (IN_SW_BURP_V):
tdgbl->gbl_sw_verbose = true; tdgbl->gbl_sw_verbose = true;
break; break;

View File

@ -799,6 +799,8 @@ public:
// this is VERY dirty hack to keep current behaviour // this is VERY dirty hack to keep current behaviour
memset (&gbl_database_file_name, 0, memset (&gbl_database_file_name, 0,
&veryEnd - reinterpret_cast<char*>(&gbl_database_file_name)); &veryEnd - reinterpret_cast<char*>(&gbl_database_file_name));
// normal code follows
exit_code = FINI_ERROR; // prevent FINI_OK in case of unknown error thrown exit_code = FINI_ERROR; // prevent FINI_OK in case of unknown error thrown
// would be set to FINI_OK (==0) in exit_local // would be set to FINI_OK (==0) in exit_local
} }
@ -829,6 +831,9 @@ public:
const SCHAR* gbl_sw_sql_role; const SCHAR* gbl_sw_sql_role;
const SCHAR* gbl_sw_user; const SCHAR* gbl_sw_user;
const SCHAR* gbl_sw_password; const SCHAR* gbl_sw_password;
#ifdef TRUSTED_SERVICES
const SCHAR* gbl_sw_tr_user;
#endif
SLONG gbl_sw_skip_count; SLONG gbl_sw_skip_count;
SLONG gbl_sw_page_buffers; SLONG gbl_sw_page_buffers;
burp_fil* gbl_sw_files; burp_fil* gbl_sw_files;

View File

@ -81,6 +81,9 @@ const int IN_SW_BURP_HIDDEN_RDWRITE = 37;
const int IN_SW_BURP_RECREATE = 38; // recreate database const int IN_SW_BURP_RECREATE = 38; // recreate database
const int IN_SW_BURP_NOD = 39; // do not run database triggers const int IN_SW_BURP_NOD = 39; // do not run database triggers
#ifdef TRUSTED_SERVICES
const int IN_SW_BURP_TRUSTED_USER = 40; // trusted user name to use on attach
#endif
/**************************************************************************/ /**************************************************************************/
// used 0BCDEFGILMNOPRSTUVYZ available AHJQWX // used 0BCDEFGILMNOPRSTUVYZ available AHJQWX
@ -153,6 +156,9 @@ static in_sw_tab_t burp_in_sw_table [] =
// msg 276: %sUSE_(ALL_SPACE) do not reserve space for record versions // msg 276: %sUSE_(ALL_SPACE) do not reserve space for record versions
{IN_SW_BURP_USER, 0, "USER", 0, 0, 0, FALSE, 191, 0, NULL}, {IN_SW_BURP_USER, 0, "USER", 0, 0, 0, FALSE, 191, 0, NULL},
// msg 191: %sUSER InterBase user name // msg 191: %sUSER InterBase user name
#ifdef TRUSTED_SERVICES
{IN_SW_BURP_TRUSTED_USER, 0, "TRUSTED", 0, 0, 0, FALSE, 0, 0, NULL},
#endif
{IN_SW_BURP_V, isc_spb_verbose, "VERBOSE", 0, 0, 0, FALSE, 0, 0, NULL}, {IN_SW_BURP_V, isc_spb_verbose, "VERBOSE", 0, 0, 0, FALSE, 0, 0, NULL},
{IN_SW_BURP_V, 0, "VERIFY", 0, 0, 0, FALSE, 113, 0, NULL}, {IN_SW_BURP_V, 0, "VERIFY", 0, 0, 0, FALSE, 113, 0, NULL},
// msg 113: %sVERIFY report each action taken // msg 113: %sVERIFY report each action taken

View File

@ -103,6 +103,7 @@
#define isc_dpb_address_path 70 #define isc_dpb_address_path 70
#define isc_dpb_pid 71 #define isc_dpb_pid 71
#define isc_dpb_no_db_triggers 72 #define isc_dpb_no_db_triggers 72
#define isc_dpb_trusted_auth 73
/**************************************************/ /**************************************************/
/* clumplet tags used inside isc_dpb_address_path */ /* clumplet tags used inside isc_dpb_address_path */
@ -251,6 +252,7 @@
#define isc_spb_options 108 #define isc_spb_options 108
#define isc_spb_address_path 109 #define isc_spb_address_path 109
#define isc_spb_pid 110 #define isc_spb_pid 110
#define isc_spb_trusted_auth 111
#define isc_spb_connect_timeout isc_dpb_connect_timeout #define isc_spb_connect_timeout isc_dpb_connect_timeout

View File

@ -127,4 +127,11 @@ using namespace NAMESPACE;
#define SERVICE_THREAD #define SERVICE_THREAD
#endif #endif
#if defined(WIN_NT)
#define TRUSTED_AUTH
#if defined(SERVICE_THREAD)
#define TRUSTED_SERVICES
#endif
#endif
#endif /* INCLUDE_Firebird_H */ #endif /* INCLUDE_Firebird_H */

View File

@ -166,6 +166,9 @@ enum switch_id {
SWITCH_ROLE2, SWITCH_ROLE2,
SWITCH_SQLDIALECT, SWITCH_SQLDIALECT,
SWITCH_TERM, SWITCH_TERM,
#ifdef TRUSTED_AUTH
SWITCH_TRUSTED,
#endif
SWITCH_USER, SWITCH_USER,
SWITCH_VERSION, SWITCH_VERSION,
#ifdef DEV_BUILD #ifdef DEV_BUILD
@ -211,6 +214,9 @@ const switch_info switches[] =
{ SWITCH_SQLDIALECT, "sqldialect", 1, SWARG_INTEGER, 137 }, { SWITCH_SQLDIALECT, "sqldialect", 1, SWARG_INTEGER, 137 },
{ SWITCH_SQLDIALECT, "sql_dialect", 1, SWARG_INTEGER, -1 }, { SWITCH_SQLDIALECT, "sql_dialect", 1, SWARG_INTEGER, -1 },
{ SWITCH_TERM, "terminator", 1, SWARG_STRING, 138 }, { SWITCH_TERM, "terminator", 1, SWARG_STRING, 138 },
#ifdef TRUSTED_AUTH
{ SWITCH_TRUSTED, "trusted", 2, SWARG_NONE, 155 },
#endif
{ SWITCH_USER, "user", 1, SWARG_STRING, 139 }, { SWITCH_USER, "user", 1, SWARG_STRING, 139 },
{ SWITCH_EXTRACT, "x", 1, SWARG_NONE, 140 }, { SWITCH_EXTRACT, "x", 1, SWARG_NONE, 140 },
{ SWITCH_VERSION, "z", 1, SWARG_NONE, 141 } { SWITCH_VERSION, "z", 1, SWARG_NONE, 141 }
@ -383,7 +389,10 @@ XSQLDA** global_sqldap;
USHORT global_dialect_spoken = 0; USHORT global_dialect_spoken = 0;
USHORT requested_SQL_dialect = SQL_DIALECT_V6; USHORT requested_SQL_dialect = SQL_DIALECT_V6;
bool connecting_to_pre_v6_server = false; bool connecting_to_pre_v6_server = false;
bool Quiet; bool Quiet = false;
#ifdef TRUSTED_AUTH
bool Trusted_auth = false;
#endif
bool Version_info = false; bool Version_info = false;
#if defined (WIN95) #if defined (WIN95)
bool fAnsiCP; bool fAnsiCP;
@ -5178,6 +5187,12 @@ static processing_state newdb(TEXT* dbname,
if (Nodbtriggers) if (Nodbtriggers)
dpb.insertInt(isc_dpb_no_db_triggers, 1); dpb.insertInt(isc_dpb_no_db_triggers, 1);
#ifdef TRUSTED_AUTH
if (Trusted_auth) {
dpb.insertTag(isc_dpb_trusted_auth);
}
#endif
{ // scope { // scope
const TEXT* local_name = isqlGlob.global_Db_name; const TEXT* local_name = isqlGlob.global_Db_name;
@ -5787,6 +5802,12 @@ static processing_state parse_arg(int argc,
case SWITCH_QUIET: case SWITCH_QUIET:
Quiet = true; Quiet = true;
break; break;
#ifdef TRUSTED_AUTH
case SWITCH_TRUSTED:
Trusted_auth = true;
break;
#endif
case SWITCH_VERSION: case SWITCH_VERSION:
Version_info = true; Version_info = true;

View File

@ -72,10 +72,6 @@
static USHORT os_type; static USHORT os_type;
static SECURITY_ATTRIBUTES security_attr; static SECURITY_ATTRIBUTES security_attr;
//static TEXT interbase_directory[MAXPATHLEN];
static bool check_user_privilege();
#endif // WIN_NT #endif // WIN_NT
static TEXT user_name[256]; static TEXT user_name[256];
@ -101,6 +97,7 @@ static USHORT ast_count;
static POKE pokes; static POKE pokes;
static lock_status wake_lock; static lock_status wake_lock;
#endif /* of ifdef VMS */ #endif /* of ifdef VMS */
#ifdef HAVE_SIGNAL_H #ifdef HAVE_SIGNAL_H
@ -590,153 +587,22 @@ int ISC_get_user(TEXT* name,
if (name) if (name)
{ {
name[0] = 0; name[0] = 0;
DWORD name_len = 128; DWORD name_len = 128;
if (GetUserName(name, &name_len)) if (GetUserName(name, &name_len))
{ {
name[name_len] = 0; name[name_len] = 0;
/* NT user name is case insensitive */ // NT user name is case insensitive
for (DWORD i = 0; i < name_len; i++) for (DWORD i = 0; i < name_len; i++)
{ {
name[i] = UPPER7(name[i]); name[i] = UPPER7(name[i]);
} }
/* This check is not internationalized, the security model needs to be
* reengineered, especially on SUPERSERVER where none of these local
* user (in process) assumptions are valid.
if (!strcmp(name, "ADMINISTRATOR"))
{
if (id)
*id = 0;
if (group)
*group = 0;
}
*/
} }
} }
return check_user_privilege(); return false;
} }
#endif //WIN_NT
//____________________________________________________________
//
// Check to see if the user belongs to the administrator group.
//
// This routine was adapted from code in routine RunningAsAdminstrator
// in \mstools\samples\regmpad\regdb.c.
//
static bool check_user_privilege()
{
HANDLE tkhandle;
SID_IDENTIFIER_AUTHORITY system_sid_authority = {SECURITY_NT_AUTHORITY};
// First we must open a handle to the access token for this thread.
if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &tkhandle))
{
if (GetLastError() == ERROR_NO_TOKEN)
{
// If the thread does not have an access token, we'll examine the
// access token associated with the process.
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &tkhandle))
{
CloseHandle(tkhandle);
return false;
}
}
else
{
return false;
}
}
TOKEN_GROUPS* ptg = NULL;
DWORD token_len = 0;
while (true)
{
/* Then we must query the size of the group information associated with
the token. This is guarenteed to fail the first time through
because there is no buffer. */
if (GetTokenInformation(tkhandle,
TokenGroups,
ptg,
token_len,
&token_len))
{
break;
}
/* If there had been a buffer, it's either too small or something
else is wrong. Either way, we can dispose of it. */
if (ptg)
{
gds__free(ptg);
}
/* Here we verify that GetTokenInformation failed for lack of a large
enough buffer. */
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
CloseHandle(tkhandle);
return false;
}
// Allocate a buffer for the group information.
ptg = (TOKEN_GROUPS *) gds__alloc((SLONG) token_len);
if (!ptg)
{
CloseHandle(tkhandle);
return false; /* NOMEM: */
}
// FREE: earlier in this loop, and at procedure return
}
// Create a System Identifier for the Admin group.
PSID admin_sid;
if (!AllocateAndInitializeSid(&system_sid_authority, 2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0, &admin_sid))
{
gds__free(ptg);
CloseHandle(tkhandle);
return false;
}
// Finally we'll iterate through the list of groups for this access
// token looking for a match against the SID we created above.
bool admin_priv = false;
for (DWORD i = 0; i < ptg->GroupCount; i++)
{
if (EqualSid(ptg->Groups[i].Sid, admin_sid))
{
admin_priv = true;
break;
}
}
// Deallocate the SID we created.
FreeSid(admin_sid);
gds__free(ptg);
CloseHandle(tkhandle);
return admin_priv;
}
#endif
#ifdef VMS #ifdef VMS
int ISC_make_desc(const TEXT* string, struct dsc$descriptor* desc, USHORT length) int ISC_make_desc(const TEXT* string, struct dsc$descriptor* desc, USHORT length)

View File

@ -348,6 +348,9 @@ public:
Firebird::string dpb_set_db_charset; Firebird::string dpb_set_db_charset;
Firebird::string dpb_network_protocol; Firebird::string dpb_network_protocol;
Firebird::string dpb_remote_address; Firebird::string dpb_remote_address;
#ifdef TRUSTED_AUTH
Firebird::string dpb_trusted_login;
#endif
public: public:
DatabaseOptions() DatabaseOptions()
@ -965,6 +968,9 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
options.dpb_password.nullStr(), options.dpb_password.nullStr(),
options.dpb_password_enc.nullStr(), options.dpb_password_enc.nullStr(),
options.dpb_role_name.nullStr(), options.dpb_role_name.nullStr(),
#ifdef TRUSTED_AUTH
options.dpb_trusted_login.nullStr(),
#endif
tdbb); tdbb);
initing_security = false; initing_security = false;
@ -1928,6 +1934,9 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status,
options.dpb_password.nullStr(), options.dpb_password.nullStr(),
options.dpb_password_enc.nullStr(), options.dpb_password_enc.nullStr(),
options.dpb_role_name.nullStr(), options.dpb_role_name.nullStr(),
#ifdef TRUSTED_AUTH
options.dpb_trusted_login.nullStr(),
#endif
tdbb); tdbb);
initing_security = false; initing_security = false;
@ -5474,6 +5483,12 @@ void DatabaseOptions::get(const UCHAR* dpb, USHORT dpb_length)
rdr.getString(dpb_password_enc); rdr.getString(dpb_password_enc);
break; break;
#ifdef TRUSTED_AUTH
case isc_dpb_trusted_auth:
rdr.getString(dpb_trusted_login);
break;
#endif
case isc_dpb_encrypt_key: case isc_dpb_encrypt_key:
#ifdef ISC_DATABASE_ENCRYPTION #ifdef ISC_DATABASE_ENCRYPTION
rdr.getString(dpb_key); rdr.getString(dpb_key);

View File

@ -555,6 +555,9 @@ void SCL_init(bool create,
const TEXT* password, const TEXT* password,
const TEXT* password_enc, const TEXT* password_enc,
const TEXT* sql_role, const TEXT* sql_role,
#ifdef TRUSTED_AUTH
const TEXT* trusted_user,
#endif
thread_db* tdbb) thread_db* tdbb)
{ {
/************************************** /**************************************
@ -606,12 +609,22 @@ void SCL_init(bool create,
{ {
if (!JRD_get_thread_security_disabled()) if (!JRD_get_thread_security_disabled())
{ {
Attachment* att = tdbb->tdbb_attachment; #ifdef TRUSTED_AUTH
Firebird::string remote = att->att_network_protocol + if (trusted_user)
(att->att_network_protocol.isEmpty() || att->att_remote_address.isEmpty() ? "" : "/") + {
att->att_remote_address; strncpy(name, trusted_user, sizeof name);
SecurityDatabase::verifyUser(name, user_name, password, password_enc, name[sizeof name - 1] = 0;
&id, &group, &node_id, remote); }
else
#endif
{
Attachment* att = tdbb->tdbb_attachment;
Firebird::string remote = att->att_network_protocol +
(att->att_network_protocol.isEmpty() || att->att_remote_address.isEmpty() ? "" : "/") +
att->att_remote_address;
SecurityDatabase::verifyUser(name, user_name, password, password_enc,
&id, &group, &node_id, remote);
}
} }
else else
{ {

View File

@ -41,8 +41,11 @@ void SCL_check_procedure(const dsc*, Jrd::SecurityClass::flags_t);
void SCL_check_relation(const dsc*, Jrd::SecurityClass::flags_t); void SCL_check_relation(const dsc*, Jrd::SecurityClass::flags_t);
Jrd::SecurityClass* SCL_get_class(const TEXT*); Jrd::SecurityClass* SCL_get_class(const TEXT*);
Jrd::SecurityClass::flags_t SCL_get_mask(const TEXT*, const TEXT*); Jrd::SecurityClass::flags_t SCL_get_mask(const TEXT*, const TEXT*);
void SCL_init(bool, const TEXT*, const TEXT*, const TEXT*, const TEXT*, void SCL_init(bool, const TEXT*, const TEXT*, const TEXT*, const TEXT*, const TEXT*,
const TEXT*, Jrd::thread_db*); #ifdef TRUSTED_AUTH
const TEXT*,
#endif
Jrd::thread_db*);
void SCL_move_priv(UCHAR**, Jrd::SecurityClass::flags_t, Firebird::UCharBuffer&, ULONG*); void SCL_move_priv(UCHAR**, Jrd::SecurityClass::flags_t, Firebird::UCharBuffer&, ULONG*);
Jrd::SecurityClass* SCL_recompute_class(Jrd::thread_db*, const TEXT*); Jrd::SecurityClass* SCL_recompute_class(Jrd::thread_db*, const TEXT*);
void SCL_release(Jrd::SecurityClass*); void SCL_release(Jrd::SecurityClass*);

View File

@ -135,7 +135,11 @@ namespace Jrd {
svc_stdout_head(0), svc_stdout_tail(0), svc_stdout(0), svc_argv(p), svc_argc(0), svc_stdout_head(0), svc_stdout_tail(0), svc_stdout(0), svc_argv(p), svc_argc(0),
svc_service(se), svc_resp_buf(0), svc_resp_ptr(0), svc_resp_buf_len(0), svc_service(se), 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_resp_len(0), svc_flags(0), svc_user_flag(0), svc_spb_version(0), svc_do_shutdown(false),
svc_username(p), svc_enc_password(p), svc_switches(p), svc_perm_sw(p) svc_username(p), svc_enc_password(p),
#ifdef TRUSTED_AUTH
svc_trusted_login(p),
#endif
svc_switches(p), svc_perm_sw(p)
{ {
memset(svc_start_event, 0, sizeof svc_start_event); memset(svc_start_event, 0, sizeof svc_start_event);
@ -285,6 +289,9 @@ struct Serv_param_block {
Firebird::string spb_command_line; Firebird::string spb_command_line;
Firebird::string spb_network_protocol; Firebird::string spb_network_protocol;
Firebird::string spb_remote_address; Firebird::string spb_remote_address;
#ifdef TRUSTED_AUTH
Firebird::string spb_trusted_login;
#endif
USHORT spb_version; USHORT spb_version;
Serv_param_block() : spb_version(0) { } Serv_param_block() : spb_version(0) { }
@ -553,7 +560,14 @@ Service* SVC_attach(USHORT service_length,
user_flag = SVC_user_none; user_flag = SVC_user_none;
} }
else { else {
if (!options.spb_user_name.hasData()) #ifdef TRUSTED_AUTH
if (options.spb_trusted_login.hasData())
{
options.spb_user_name = options.spb_trusted_login;
}
else
#endif
if (!options.spb_user_name.hasData())
{ {
// user name and password are required while // user name and password are required while
// attaching to the services manager // attaching to the services manager
@ -608,6 +622,9 @@ Service* SVC_attach(USHORT service_length,
#endif #endif
service->svc_spb_version = options.spb_version; service->svc_spb_version = options.spb_version;
service->svc_username = options.spb_user_name; service->svc_username = options.spb_user_name;
#ifdef TRUSTED_AUTH
service->svc_trusted_login = options.spb_trusted_login;
#endif
/* The password will be issued to the service threads on NT since /* The password will be issued to the service threads on NT since
* there is no OS authentication. If the password is not yet * there is no OS authentication. If the password is not yet
@ -1785,21 +1802,34 @@ void* SVC_start(Service* service, USHORT spb_length, const SCHAR* spb_data)
svc_id == isc_action_svc_properties) svc_id == isc_action_svc_properties)
{ {
/* add the username and password to the end of svc_switches if needed */ /* add the username and password to the end of svc_switches if needed */
if (service->svc_switches.hasData()) { if (service->svc_switches.hasData())
if (service->svc_username.hasData()) {
#ifdef TRUSTED_AUTH
if (service->svc_trusted_login.hasData())
{ {
service->svc_switches += ' '; service->svc_switches += ' ';
service->svc_switches += USERNAME_SWITCH; service->svc_switches += TRUSTED_USER_SWITCH;
service->svc_switches += ' '; service->svc_switches += ' ';
service->svc_switches += service->svc_username; service->svc_switches += service->svc_username;
} }
else
if (service->svc_enc_password.hasData()) #endif
{ {
service->svc_switches += ' '; if (service->svc_username.hasData())
service->svc_switches += PASSWORD_SWITCH; {
service->svc_switches += ' '; service->svc_switches += ' ';
service->svc_switches += service->svc_enc_password; service->svc_switches += USERNAME_SWITCH;
service->svc_switches += ' ';
service->svc_switches += service->svc_username;
}
if (service->svc_enc_password.hasData())
{
service->svc_switches += ' ';
service->svc_switches += PASSWORD_SWITCH;
service->svc_switches += ' ';
service->svc_switches += service->svc_enc_password;
}
} }
} }
} }
@ -2006,6 +2036,12 @@ static void get_options(Firebird::ClumpletReader& spb,
spb.getString(options->spb_password_enc); spb.getString(options->spb_password_enc);
break; break;
#ifdef TRUSTED_AUTH
case isc_spb_trusted_auth:
spb.getString(options->spb_trusted_login);
break;
#endif
case isc_spb_command_line: case isc_spb_command_line:
spb.getString(options->spb_command_line); spb.getString(options->spb_command_line);
break; break;

View File

@ -81,6 +81,9 @@ const USHORT isc_action_max = 14;
#else #else
#define SERVICE_THD_PARAM "-svc" #define SERVICE_THD_PARAM "-svc"
#endif #endif
#ifdef TRUSTED_AUTH
#define TRUSTED_USER_SWITCH "-TRUSTED"
#endif
/* Macro used to store services thread specific data */ /* Macro used to store services thread specific data */
/* Currently we store empty string, see bug #10394 */ /* Currently we store empty string, see bug #10394 */
@ -130,6 +133,9 @@ public:
bool svc_do_shutdown; bool svc_do_shutdown;
Firebird::string svc_username; Firebird::string svc_username;
Firebird::string svc_enc_password; Firebird::string svc_enc_password;
#ifdef TRUSTED_AUTH
Firebird::string svc_trusted_login;
#endif
Firebird::string svc_switches; // Full set of switches Firebird::string svc_switches; // Full set of switches
Firebird::string svc_perm_sw; // Switches, taken from services table Firebird::string svc_perm_sw; // Switches, taken from services table
// and/or passed using spb_command_line // and/or passed using spb_command_line

View File

@ -2368,16 +2368,21 @@ inline void setTag(Firebird::ClumpletWriter& dpb, UCHAR tag, const TEXT* value)
void setLogin(Firebird::ClumpletWriter& dpb) void setLogin(Firebird::ClumpletWriter& dpb)
{ {
Firebird::string username; #ifdef TRUSTED_AUTH
if (fb_utils::readenv("ISC_USER", username) && !dpb.find(isc_dpb_sys_user_name)) if (!dpb.find(isc_dpb_trusted_auth))
#endif
{ {
setTag(dpb, isc_dpb_user_name, username.c_str()); Firebird::string username;
} if (fb_utils::readenv("ISC_USER", username) && !dpb.find(isc_dpb_sys_user_name))
{
setTag(dpb, isc_dpb_user_name, username.c_str());
}
Firebird::string password; Firebird::string password;
if (fb_utils::readenv("ISC_PASSWORD", password) && !dpb.find(isc_dpb_password_enc)) if (fb_utils::readenv("ISC_PASSWORD", password) && !dpb.find(isc_dpb_password_enc))
{ {
setTag(dpb, isc_dpb_password, password.c_str()); setTag(dpb, isc_dpb_password, password.c_str());
}
} }
} }

View File

@ -1797,7 +1797,7 @@ without specifying a character set.', NULL);
INSERT INTO MESSAGES (SYMBOL, ROUTINE, MODULE, TRANS_NOTES, FAC_CODE, NUMBER, FLAGS, TEXT, "ACTION", EXPLANATION) VALUES ('existing_priv_mod', 'trigger_messages', 'ini.e', NULL, 0, 209, NULL, 'cannot modify an existing user privilege', NULL, NULL); INSERT INTO MESSAGES (SYMBOL, ROUTINE, MODULE, TRANS_NOTES, FAC_CODE, NUMBER, FLAGS, TEXT, "ACTION", EXPLANATION) VALUES ('existing_priv_mod', 'trigger_messages', 'ini.e', NULL, 0, 209, NULL, 'cannot modify an existing user privilege', NULL, NULL);
INSERT INTO MESSAGES (SYMBOL, ROUTINE, MODULE, TRANS_NOTES, FAC_CODE, NUMBER, FLAGS, TEXT, "ACTION", EXPLANATION) VALUES ('lock_timeout', '', 'lck.c', NULL, 0, 190, NULL, 'lock time-out on wait transaction', NULL, NULL); INSERT INTO MESSAGES (SYMBOL, ROUTINE, MODULE, TRANS_NOTES, FAC_CODE, NUMBER, FLAGS, TEXT, "ACTION", EXPLANATION) VALUES ('lock_timeout', '', 'lck.c', NULL, 0, 190, NULL, 'lock time-out on wait transaction', NULL, NULL);
INSERT INTO MESSAGES (SYMBOL, ROUTINE, MODULE, TRANS_NOTES, FAC_CODE, NUMBER, FLAGS, TEXT, "ACTION", EXPLANATION) VALUES (NULL, 'delete_procedure', 'dyn.e', NULL, 8, 138, NULL, 'ERASE RDB$PROCEDURE_PARAMETERS failed', NULL, NULL); INSERT INTO MESSAGES (SYMBOL, ROUTINE, MODULE, TRANS_NOTES, FAC_CODE, NUMBER, FLAGS, TEXT, "ACTION", EXPLANATION) VALUES (NULL, 'delete_procedure', 'dyn.e', NULL, 8, 138, NULL, 'ERASE RDB$PROCEDURE_PARAMETERS failed', NULL, NULL);
INSERT INTO MESSAGES (SYMBOL, ROUTINE, MODULE, TRANS_NOTES, FAC_CODE, NUMBER, FLAGS, TEXT, "ACTION", EXPLANATION) VALUES (NULL, 'delete_procedure', 'dyh.e', NULL, 8, 139, NULL, 'ERASE RDB$PROCEDURES failed', NULL, NULL); INSERT INTO MESSAGES (SYMBOL, ROUTINE, MODULE, TRANS_NOTES, FAC_CODE, NUMBER, FLAGS, TEXT, "ACTION", EXPLANATION) VALUES (NULL, 'delete_procedure', 'dyn.e', NULL, 8, 139, NULL, 'ERASE RDB$PROCEDURES failed', NULL, NULL);
INSERT INTO MESSAGES (SYMBOL, ROUTINE, MODULE, TRANS_NOTES, FAC_CODE, NUMBER, FLAGS, TEXT, "ACTION", EXPLANATION) VALUES (NULL, 'delete_procedure', 'dyn.e', NULL, 8, 140, NULL, 'Procedure %s not found', NULL, NULL); INSERT INTO MESSAGES (SYMBOL, ROUTINE, MODULE, TRANS_NOTES, FAC_CODE, NUMBER, FLAGS, TEXT, "ACTION", EXPLANATION) VALUES (NULL, 'delete_procedure', 'dyn.e', NULL, 8, 140, NULL, 'Procedure %s not found', NULL, NULL);
INSERT INTO MESSAGES (SYMBOL, ROUTINE, MODULE, TRANS_NOTES, FAC_CODE, NUMBER, FLAGS, TEXT, "ACTION", EXPLANATION) VALUES ('prcnotdef', 'par_procedure', 'PAR', NULL, 0, 191, NULL, 'procedure %s is not defined', NULL, NULL); INSERT INTO MESSAGES (SYMBOL, ROUTINE, MODULE, TRANS_NOTES, FAC_CODE, NUMBER, FLAGS, TEXT, "ACTION", EXPLANATION) VALUES ('prcnotdef', 'par_procedure', 'PAR', NULL, 0, 191, NULL, 'procedure %s is not defined', NULL, NULL);
INSERT INTO MESSAGES (SYMBOL, ROUTINE, MODULE, TRANS_NOTES, FAC_CODE, NUMBER, FLAGS, TEXT, "ACTION", EXPLANATION) VALUES ('prcmismat', 'par_procedure', 'par.c', NULL, 0, 192, NULL, 'Input parameter mismatch for procedure %s', NULL, NULL); INSERT INTO MESSAGES (SYMBOL, ROUTINE, MODULE, TRANS_NOTES, FAC_CODE, NUMBER, FLAGS, TEXT, "ACTION", EXPLANATION) VALUES ('prcmismat', 'par_procedure', 'par.c', NULL, 0, 192, NULL, 'Input parameter mismatch for procedure %s', NULL, NULL);
@ -3101,6 +3101,7 @@ INSERT INTO MESSAGES (SYMBOL, ROUTINE, MODULE, TRANS_NOTES, FAC_CODE, NUMBER, FL
INSERT INTO MESSAGES (SYMBOL, ROUTINE, MODULE, TRANS_NOTES, FAC_CODE, NUMBER, FLAGS, TEXT, "ACTION", EXPLANATION) VALUES ('dsql_cte_miss_nonrecursive', 'pass1_recursive_cte', 'dsql.cpp', NULL, 13, 945, NULL, 'Non-recursive member is missing in CTE ''%s''', NULL, NULL); INSERT INTO MESSAGES (SYMBOL, ROUTINE, MODULE, TRANS_NOTES, FAC_CODE, NUMBER, FLAGS, TEXT, "ACTION", EXPLANATION) VALUES ('dsql_cte_miss_nonrecursive', 'pass1_recursive_cte', 'dsql.cpp', NULL, 13, 945, NULL, 'Non-recursive member is missing in CTE ''%s''', NULL, NULL);
INSERT INTO MESSAGES (SYMBOL, ROUTINE, MODULE, TRANS_NOTES, FAC_CODE, NUMBER, FLAGS, TEXT, "ACTION", EXPLANATION) VALUES ('dsql_cte_nested_with', 'dsql_req::addCTEs', 'dsql.cpp', NULL, 13, 946, NULL, 'WITH clause can''t be nested', NULL, NULL); INSERT INTO MESSAGES (SYMBOL, ROUTINE, MODULE, TRANS_NOTES, FAC_CODE, NUMBER, FLAGS, TEXT, "ACTION", EXPLANATION) VALUES ('dsql_cte_nested_with', 'dsql_req::addCTEs', 'dsql.cpp', NULL, 13, 946, NULL, 'WITH clause can''t be nested', NULL, NULL);
INSERT INTO MESSAGES (SYMBOL, ROUTINE, MODULE, TRANS_NOTES, FAC_CODE, NUMBER, FLAGS, TEXT, "ACTION", EXPLANATION) VALUES ('USAGE_NODBTRIGGERS', 'ISQL_main', 'isql.epp', NULL, 17, 154, NULL, ' -nod(btriggers) do not run database triggers', NULL, NULL); INSERT INTO MESSAGES (SYMBOL, ROUTINE, MODULE, TRANS_NOTES, FAC_CODE, NUMBER, FLAGS, TEXT, "ACTION", EXPLANATION) VALUES ('USAGE_NODBTRIGGERS', 'ISQL_main', 'isql.epp', NULL, 17, 154, NULL, ' -nod(btriggers) do not run database triggers', NULL, NULL);
INSERT INTO MESSAGES (SYMBOL, ROUTINE, MODULE, TRANS_NOTES, FAC_CODE, NUMBER, FLAGS, TEXT, "ACTION", EXPLANATION) VALUES ('USAGE_TRUSTED', 'ISQL_main', 'isql.epp', NULL, 17, 155, NULL, ' -tr(usted) use windows trusted authentication', NULL, NULL);
INSERT INTO MESSAGES (SYMBOL, ROUTINE, MODULE, TRANS_NOTES, FAC_CODE, NUMBER, FLAGS, TEXT, "ACTION", EXPLANATION) VALUES (NULL, '', 'burp.cpp', NULL, 12, 294, NULL, ' %sNO_D(BTRIGGERS) do not run database triggers', NULL, NULL); INSERT INTO MESSAGES (SYMBOL, ROUTINE, MODULE, TRANS_NOTES, FAC_CODE, NUMBER, FLAGS, TEXT, "ACTION", EXPLANATION) VALUES (NULL, '', 'burp.cpp', NULL, 12, 294, NULL, ' %sNO_D(BTRIGGERS) do not run database triggers', NULL, NULL);
INSERT INTO MESSAGES (SYMBOL, ROUTINE, MODULE, TRANS_NOTES, FAC_CODE, NUMBER, FLAGS, TEXT, "ACTION", EXPLANATION) VALUES ('dsql_incompatible_trigger_type', 'define_trigger', 'ddl.cpp', NULL, 7, 30, NULL, 'Incompatible trigger type', NULL, NULL); INSERT INTO MESSAGES (SYMBOL, ROUTINE, MODULE, TRANS_NOTES, FAC_CODE, NUMBER, FLAGS, TEXT, "ACTION", EXPLANATION) VALUES ('dsql_incompatible_trigger_type', 'define_trigger', 'ddl.cpp', NULL, 7, 30, NULL, 'Incompatible trigger type', NULL, NULL);
INSERT INTO MESSAGES (SYMBOL, ROUTINE, MODULE, TRANS_NOTES, FAC_CODE, NUMBER, FLAGS, TEXT, "ACTION", EXPLANATION) VALUES ('dsql_db_trigger_type_cant_change', 'define_trigger', 'ddl.cpp', NULL, 7, 31, NULL, 'Database trigger type can''t be changed', NULL, NULL); INSERT INTO MESSAGES (SYMBOL, ROUTINE, MODULE, TRANS_NOTES, FAC_CODE, NUMBER, FLAGS, TEXT, "ACTION", EXPLANATION) VALUES ('dsql_db_trigger_type_cant_change', 'define_trigger', 'ddl.cpp', NULL, 7, 31, NULL, 'Database trigger type can''t be changed', NULL, NULL);

View File

@ -129,6 +129,9 @@ int CLIB_ROUTINE main( int argc, char **argv)
QLI_columns = 80; QLI_columns = 80;
#else #else
QLI_columns = 80; QLI_columns = 80;
#endif
#ifdef TRUSTED_AUTH
QLI_trusted = false;
#endif #endif
QLI_lines = 60; QLI_lines = 60;
QLI_name_columns = 0; QLI_name_columns = 0;
@ -182,6 +185,12 @@ int CLIB_ROUTINE main( int argc, char **argv)
startup_file = *argv++; startup_file = *argv++;
break; break;
#ifdef TRUSTED_AUTH
case 'K':
QLI_trusted = true;
break;
#endif
case 'N': case 'N':
banner_flag = false; banner_flag = false;
break; break;

View File

@ -499,6 +499,9 @@ EXTERN USHORT QLI_count;
EXTERN bool QLI_explain; EXTERN bool QLI_explain;
EXTERN bool QLI_hex_output; EXTERN bool QLI_hex_output;
#endif #endif
#ifdef TRUSTED_AUTH
EXTERN bool QLI_trusted;
#endif
EXTERN jmp_buf QLI_env; // Error return environment EXTERN jmp_buf QLI_env; // Error return environment

View File

@ -1420,6 +1420,12 @@ void MET_ready( qli_syntax* node, USHORT create_flag)
dpb.insertString(isc_dpb_password, q, length); dpb.insertString(isc_dpb_password, q, length);
} }
#ifdef TRUSTED_AUTH
if (QLI_trusted) {
dpb.insertTag(isc_dpb_trusted_auth);
}
#endif
const qli_syntax* const* const end = node->syn_arg + node->syn_count; const qli_syntax* const* const end = node->syn_arg + node->syn_count;
// Start by attaching all databases // Start by attaching all databases

View File

@ -507,10 +507,12 @@ rem_port* INET_analyze(Firebird::PathName& file_name,
{ {
REMOTE_PROTOCOL(PROTOCOL_VERSION8, ptype_rpc, MAX_PTYPE, 1), REMOTE_PROTOCOL(PROTOCOL_VERSION8, ptype_rpc, MAX_PTYPE, 1),
REMOTE_PROTOCOL(PROTOCOL_VERSION10, ptype_rpc, MAX_PTYPE, 2), REMOTE_PROTOCOL(PROTOCOL_VERSION10, ptype_rpc, MAX_PTYPE, 2),
REMOTE_PROTOCOL(PROTOCOL_VERSION10, ptype_rpc, ptype_lazy_send, 3) REMOTE_PROTOCOL(PROTOCOL_VERSION10, ptype_rpc, ptype_lazy_send, 3),
REMOTE_PROTOCOL(PROTOCOL_VERSION11, ptype_rpc, MAX_PTYPE, 4),
REMOTE_PROTOCOL(PROTOCOL_VERSION11, ptype_rpc, ptype_lazy_send, 5)
#ifdef SCROLLABLE_CURSORS #ifdef SCROLLABLE_CURSORS
, ,
REMOTE_PROTOCOL(PROTOCOL_SCROLLABLE_CURSORS, ptype_rpc, MAX_PTYPE, 3) REMOTE_PROTOCOL(PROTOCOL_SCROLLABLE_CURSORS, ptype_rpc, MAX_PTYPE, 99)
#endif #endif
}; };
@ -597,9 +599,9 @@ rem_port* INET_analyze(Firebird::PathName& file_name,
/* once we've decided on a protocol, concatenate the version /* once we've decided on a protocol, concatenate the version
string to reflect it... */ string to reflect it... */
Firebird::string temp; Firebird::string temp;
temp.printf("%s/P%d", port->port_version->str_data, port->port_protocol); temp.printf("%s/P%d", port->port_version->str_data,
port->port_protocol & FB_PROTOCOL_MASK);
ALLR_free(port->port_version); ALLR_free(port->port_version);
port->port_version = REMOTE_make_string(temp.c_str()); port->port_version = REMOTE_make_string(temp.c_str());
@ -1898,6 +1900,10 @@ static void cleanup_port( rem_port* port)
delete port->port_queue; delete port->port_queue;
#endif #endif
#ifdef TRUSTED_AUTH
delete port->port_trusted_auth;
#endif
ALLR_release((UCHAR *) port); ALLR_release((UCHAR *) port);
return; return;
} }

View File

@ -66,6 +66,7 @@
#include "../jrd/thread_proto.h" #include "../jrd/thread_proto.h"
#include "../common/classes/ClumpletWriter.h" #include "../common/classes/ClumpletWriter.h"
#include "../common/config/config.h" #include "../common/config/config.h"
#include "../auth/trusted/AuthSspi.h"
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
@ -110,7 +111,7 @@ namespace {
// for both services and databases attachments // for both services and databases attachments
struct ParametersSet { struct ParametersSet {
UCHAR dummy_packet_interval, user_name, sys_user_name, UCHAR dummy_packet_interval, user_name, sys_user_name,
password, password_enc, address_path, pid; password, password_enc, address_path, pid, trusted_auth;
}; };
const ParametersSet dpbParam = {isc_dpb_dummy_packet_interval, const ParametersSet dpbParam = {isc_dpb_dummy_packet_interval,
isc_dpb_user_name, isc_dpb_user_name,
@ -118,14 +119,16 @@ namespace {
isc_dpb_password, isc_dpb_password,
isc_dpb_password_enc, isc_dpb_password_enc,
isc_dpb_address_path, isc_dpb_address_path,
isc_dpb_pid}; isc_dpb_pid,
isc_dpb_trusted_auth};
const ParametersSet spbParam = {isc_spb_dummy_packet_interval, const ParametersSet spbParam = {isc_spb_dummy_packet_interval,
isc_spb_user_name, isc_spb_user_name,
isc_spb_sys_user_name, isc_spb_sys_user_name,
isc_spb_password, isc_spb_password,
isc_spb_password_enc, isc_spb_password_enc,
isc_spb_address_path, isc_spb_address_path,
isc_spb_pid}; isc_spb_pid,
isc_spb_trusted_auth};
} }
static RVNT add_event(rem_port*); static RVNT add_event(rem_port*);
@ -166,7 +169,8 @@ static bool get_single_user(Firebird::ClumpletReader&);
static ISC_STATUS handle_error(ISC_STATUS *, ISC_STATUS); static ISC_STATUS handle_error(ISC_STATUS *, ISC_STATUS);
static ISC_STATUS info(ISC_STATUS*, RDB, P_OP, USHORT, USHORT, USHORT, static ISC_STATUS info(ISC_STATUS*, RDB, P_OP, USHORT, USHORT, USHORT,
const SCHAR*, USHORT, const SCHAR*, USHORT, SCHAR*); const SCHAR*, USHORT, const SCHAR*, USHORT, SCHAR*);
static bool init(ISC_STATUS *, rem_port*, P_OP, Firebird::PathName&, Firebird::ClumpletWriter&); static bool init(ISC_STATUS *, rem_port*, P_OP, Firebird::PathName&,
Firebird::ClumpletWriter&, const ParametersSet&);
static RTR make_transaction(RDB, USHORT); static RTR make_transaction(RDB, USHORT);
static ISC_STATUS mov_dsql_message(const UCHAR*, const rem_fmt*, UCHAR*, const rem_fmt*); static ISC_STATUS mov_dsql_message(const UCHAR*, const rem_fmt*, UCHAR*, const rem_fmt*);
static void move_error(ISC_STATUS, ...); static void move_error(ISC_STATUS, ...);
@ -345,7 +349,8 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
add_other_params(port, newDpb, dpbParam); add_other_params(port, newDpb, dpbParam);
add_working_directory(newDpb, node_name); add_working_directory(newDpb, node_name);
const bool result = init(user_status, port, op_attach, expanded_name, newDpb); const bool result = init(user_status, port, op_attach, expanded_name,
newDpb, dpbParam);
if (!result) { if (!result) {
return error(user_status); return error(user_status);
@ -904,7 +909,8 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status,
add_other_params(port, newDpb, dpbParam); add_other_params(port, newDpb, dpbParam);
add_working_directory(newDpb, node_name); add_working_directory(newDpb, node_name);
const bool result = init(user_status, port, op_create, expanded_name, newDpb); const bool result = init(user_status, port, op_create, expanded_name,
newDpb, dpbParam);
if (!result) { if (!result) {
return error(user_status); return error(user_status);
} }
@ -3951,7 +3957,8 @@ ISC_STATUS GDS_SERVICE_ATTACH(ISC_STATUS* user_status,
add_other_params(port, newSpb, spbParam); add_other_params(port, newSpb, spbParam);
const bool result = init(user_status, port, op_service_attach, expanded_name, newSpb); const bool result = init(user_status, port, op_service_attach, expanded_name,
newSpb, spbParam);
if (!result) { if (!result) {
return error(user_status); return error(user_status);
} }
@ -5841,7 +5848,8 @@ static bool init(ISC_STATUS* user_status,
rem_port* port, rem_port* port,
P_OP op, P_OP op,
Firebird::PathName& file_name, Firebird::PathName& file_name,
Firebird::ClumpletWriter& dpb) Firebird::ClumpletWriter& dpb,
const ParametersSet& param)
{ {
/************************************** /**************************************
* *
@ -5860,7 +5868,29 @@ static bool init(ISC_STATUS* user_status,
MemoryPool& pool = *getDefaultMemoryPool(); MemoryPool& pool = *getDefaultMemoryPool();
port->port_deferred_packets = FB_NEW(pool) PacketQueue(pool); port->port_deferred_packets = FB_NEW(pool) PacketQueue(pool);
/* Make attach packet */ // Do we can & need to try trusted auth
if (dpb.find(param.trusted_auth))
{
dpb.deleteClumplet();
}
#ifdef TRUSTED_AUTH
AuthSspi authSspi;
AuthSspi::DataHolder data;
if ((port->port_protocol >= PROTOCOL_VERSION11) &&
((!dpb.find(param.user_name)) || (dpb.getClumpLength() == 0)))
{
if (authSspi.request(data))
{
// on no error we send data no matter, was context created or not
dpb.insertBytes(param.trusted_auth, data.begin(), data.getCount());
}
}
#endif //TRUSTED_AUTH
// Make attach packet
P_ATCH* attach = &packet->p_atch; P_ATCH* attach = &packet->p_atch;
packet->p_operation = op; packet->p_operation = op;
@ -5876,9 +5906,54 @@ static bool init(ISC_STATUS* user_status,
return false; return false;
} }
/* Get response */ // Get response
if (!receive_response(rdb, packet)) { #ifdef TRUSTED_AUTH
ISC_STATUS* status = packet->p_resp.p_resp_status_vector = rdb->rdb_status_vector;
if (!receive_packet(rdb->rdb_port, packet, status))
{
REMOTE_save_status_strings(user_status);
disconnect(port);
return false;
}
while (packet->p_operation == op_trusted_auth)
{
if (!authSspi.isActive())
{
disconnect(port);
return false; // isc_unavailable
}
cstring *d = &packet->p_trau.p_trau_data;
memcpy(data.getBuffer(d->cstr_length), d->cstr_address, d->cstr_length);
REMOTE_free_packet(rdb->rdb_port, packet);
if (!authSspi.request(data))
{
disconnect(port);
return false; // isc_unavailable
}
packet->p_operation = op_trusted_auth;
d->cstr_address = data.begin();
d->cstr_length = data.getCount();
if (!send_packet(rdb->rdb_port, packet, user_status))
{
disconnect(port);
return false;
}
if (!receive_packet(rdb->rdb_port, packet, status))
{
REMOTE_save_status_strings(user_status);
disconnect(port);
return false;
}
}
if (!check_response(rdb, packet))
#else // TRUSTED_AUTH
if (!receive_response(rdb, packet))
#endif //TRUSTED_AUTH
{
REMOTE_save_status_strings(user_status); REMOTE_save_status_strings(user_status);
disconnect(port); disconnect(port);
return false; return false;

View File

@ -183,10 +183,11 @@ rem_port* WNET_analyze(Firebird::PathName& file_name,
{ {
REMOTE_PROTOCOL(PROTOCOL_VERSION7, ptype_rpc, MAX_PTYPE, 1), REMOTE_PROTOCOL(PROTOCOL_VERSION7, ptype_rpc, MAX_PTYPE, 1),
REMOTE_PROTOCOL(PROTOCOL_VERSION8, ptype_rpc, MAX_PTYPE, 2), REMOTE_PROTOCOL(PROTOCOL_VERSION8, ptype_rpc, MAX_PTYPE, 2),
REMOTE_PROTOCOL(PROTOCOL_VERSION10, ptype_rpc, MAX_PTYPE, 3) REMOTE_PROTOCOL(PROTOCOL_VERSION10, ptype_rpc, MAX_PTYPE, 3),
REMOTE_PROTOCOL(PROTOCOL_VERSION11, ptype_rpc, MAX_PTYPE, 4)
#ifdef SCROLLABLE_CURSORS #ifdef SCROLLABLE_CURSORS
, ,
REMOTE_PROTOCOL(PROTOCOL_SCROLLABLE_CURSORS, ptype_rpc, MAX_PTYPE, 4) REMOTE_PROTOCOL(PROTOCOL_SCROLLABLE_CURSORS, ptype_rpc, MAX_PTYPE, 99)
#endif #endif
}; };
cnct->p_cnct_count = FB_NELEM(protocols_to_try1); cnct->p_cnct_count = FB_NELEM(protocols_to_try1);
@ -298,7 +299,8 @@ rem_port* WNET_analyze(Firebird::PathName& file_name,
string to reflect it... */ string to reflect it... */
Firebird::string temp; Firebird::string temp;
temp.printf("%s/P%d", port->port_version->str_data, port->port_protocol); temp.printf("%s/P%d", port->port_version->str_data,
port->port_protocol & FB_PROTOCOL_MASK);
ALLR_free(port->port_version); ALLR_free(port->port_version);
port->port_version = REMOTE_make_string(temp.c_str()); port->port_version = REMOTE_make_string(temp.c_str());

View File

@ -289,6 +289,7 @@ bool_t xdr_protocol(XDR* xdrs, PACKET* p)
P_SQLST *prep_stmt; P_SQLST *prep_stmt;
P_SQLDATA *sqldata; P_SQLDATA *sqldata;
P_TRRQ *trrq; P_TRRQ *trrq;
P_TRAU *trau;
#ifdef DEBUG #ifdef DEBUG
xdr_save_size = xdrs->x_handy; xdr_save_size = xdrs->x_handy;
#endif #endif
@ -786,6 +787,36 @@ bool_t xdr_protocol(XDR* xdrs, PACKET* p)
DEBUG_PRINTSIZE(xdrs, p->p_operation); DEBUG_PRINTSIZE(xdrs, p->p_operation);
return P_TRUE(xdrs, p); return P_TRUE(xdrs, p);
// the following added to have formal vulcan compatibility
case op_update_account_info:
{
p_update_account *stuff = &p->p_account_update;
MAP(xdr_short, reinterpret_cast < SSHORT & >(stuff->p_account_database));
MAP(xdr_cstring_const, stuff->p_account_apb);
DEBUG_PRINTSIZE(xdrs, p->p_operation);
return P_TRUE(xdrs, p);
}
case op_authenticate_user:
{
p_authenticate *stuff = &p->p_authenticate_user;
MAP(xdr_short, reinterpret_cast < SSHORT & >(stuff->p_auth_database));
MAP(xdr_cstring_const, stuff->p_auth_dpb);
MAP(xdr_cstring, stuff->p_auth_items);
MAP(xdr_short, reinterpret_cast < SSHORT & >(stuff->p_auth_buffer_length));
DEBUG_PRINTSIZE(xdrs, p->p_operation);
return P_TRUE(xdrs, p);
}
case op_trusted_auth:
trau = &p->p_trau;
MAP(xdr_cstring, trau->p_trau_data);
DEBUG_PRINTSIZE(xdrs, p->p_operation);
return P_TRUE(xdrs, p);
default: default:
#ifdef DEBUG #ifdef DEBUG
if (xdrs->x_op != XDR_FREE) if (xdrs->x_op != XDR_FREE)

View File

@ -79,6 +79,24 @@ const USHORT PROTOCOL_VERSION9 = 9;
const USHORT PROTOCOL_VERSION10 = 10; const USHORT PROTOCOL_VERSION10 = 10;
/*
Since protocol 11 we must be separated from Borland Interbase.
Therefore always set highmost bit in protocol version to 1.
For unsigned protocol version this does not break version's compare.
*/
const USHORT FB_PROTOCOL_FLAG = 0x8000;
const USHORT FB_PROTOCOL_MASK = ~FB_PROTOCOL_FLAG;
/*
Protocol 11 has support for user authentication related
operations (op_update_account_info, op_authenticate_user and
op_trusted_auth). When specific operation is not supported,
we say "sorry".
*/
const USHORT PROTOCOL_VERSION11 = (FB_PROTOCOL_FLAG | 11);
#ifdef SCROLLABLE_CURSORS #ifdef SCROLLABLE_CURSORS
This Protocol includes support for scrollable cursors This Protocol includes support for scrollable cursors
and is purposely being undefined so that changes can be made and is purposely being undefined so that changes can be made
@ -263,12 +281,15 @@ typedef enum
op_service_start = 85, op_service_start = 85,
op_rollback_retaining = 86, op_rollback_retaining = 86,
// Two following opcode are used in vulcan. // Two following opcode are used in vulcan.
// No plans to implement protocol 11, where they are used, // No plans to implement them completely for a while, but to
// place here only for informational reasons and to have common op-space. // support protocol 11, where they are used, have them here.
// op_update_account_info = 87, op_update_account_info = 87,
// op_authenticate_user = 88, op_authenticate_user = 88,
op_partial = 89, // packet is not complete - delay processing op_partial = 89, // packet is not complete - delay processing
op_trusted_auth = 90,
op_max op_max
} P_OP; } P_OP;
@ -574,6 +595,26 @@ typedef struct p_sqlcur {
USHORT p_sqlcur_type; /* type of cursor */ USHORT p_sqlcur_type; /* type of cursor */
} P_SQLCUR; } P_SQLCUR;
typedef struct p_trau
{
CSTRING p_trau_data; // Context
} P_TRAU;
struct p_update_account {
OBJCT p_account_database; /* Database object id */
CSTRING_CONST p_account_apb; /* Account parameter block (apb) */
};
struct p_authenticate {
OBJCT p_auth_database; /* Database object id */
CSTRING_CONST p_auth_dpb; /* Database parameter block w/ user credentials */
CSTRING p_auth_items; /* Information */
CSTRING p_auth_recv_items; /* Receive information */
USHORT p_auth_buffer_length; /* Target buffer length */
};
/* Generalize packet (sic!) */ /* Generalize packet (sic!) */
typedef struct packet { typedef struct packet {
@ -608,6 +649,9 @@ typedef struct packet {
P_SQLCUR p_sqlcur; /* DSQL Set cursor name */ P_SQLCUR p_sqlcur; /* DSQL Set cursor name */
P_SQLFREE p_sqlfree; /* DSQL Free statement */ P_SQLFREE p_sqlfree; /* DSQL Free statement */
P_TRRQ p_trrq; /* Transact request packet */ P_TRRQ p_trrq; /* Transact request packet */
P_TRAU p_trau; /* Trusted authentication */
p_update_account p_account_update;
p_authenticate p_authenticate_user;
} PACKET; } PACKET;
#endif // REMOTE_PROTOCOL_H #endif // REMOTE_PROTOCOL_H

View File

@ -882,3 +882,24 @@ bool_t REMOTE_getbytes (XDR * xdrs, SCHAR * buff, u_int count)
return TRUE; return TRUE;
} }
#endif //SUPERSERVER #endif //SUPERSERVER
#ifdef TRUSTED_AUTH
ServerAuth::ServerAuth(const char* fName, int fLen, const Firebird::ClumpletWriter& pb,
ServerAuth::Part2* p2, P_OP op)
: fileName(*getDefaultMemoryPool()), clumplet(*getDefaultMemoryPool()),
part2(p2), operation(op)
{
fileName.assign(fName, fLen);
size_t pbLen = pb.getBufferLength();
if (pbLen)
{
memcpy(clumplet.getBuffer(pbLen), pb.getBuffer(), pbLen);
}
authSspi = FB_NEW(*getDefaultMemoryPool()) AuthSspi;
}
ServerAuth::~ServerAuth()
{
delete authSspi;
}
#endif //TRUSTED_AUTH

View File

@ -33,6 +33,9 @@
#include "../remote/remote_def.h" #include "../remote/remote_def.h"
#include "../jrd/thd.h" #include "../jrd/thd.h"
#include "../common/classes/objects_array.h" #include "../common/classes/objects_array.h"
#include "../auth/trusted/AuthSspi.h"
#include "../common/classes/fb_string.h"
#include "../common/classes/ClumpletWriter.h"
/* Include some apollo include files for tasking */ /* Include some apollo include files for tasking */
@ -364,6 +367,23 @@ struct rem_que_packet
typedef Firebird::Array<rem_que_packet> PacketQueue; typedef Firebird::Array<rem_que_packet> PacketQueue;
#ifdef TRUSTED_AUTH
// delayed authentication block for trusted auth callback
class ServerAuth
{
public:
typedef void Part2(rem_port*, P_OP, const char* fName, int fLen, const UCHAR* pb, int pbLen, PACKET*);
Firebird::PathName fileName;
Firebird::HalfStaticArray<UCHAR, 128> clumplet;
AuthSspi* authSspi;
Part2* part2;
P_OP operation;
ServerAuth(const char* fName, int fLen, const Firebird::ClumpletWriter& pb, Part2* p2, P_OP op);
~ServerAuth();
};
#endif //TRUSTED_AUTH
/* Port itself */ /* Port itself */
class port_interface class port_interface
@ -440,6 +460,9 @@ struct rem_port
#ifdef SUPERSERVER #ifdef SUPERSERVER
Firebird::ObjectsArray< Firebird::Array< char > >* port_queue; Firebird::ObjectsArray< Firebird::Array< char > >* port_queue;
size_t port_qoffset; // current packet in the queue size_t port_qoffset; // current packet in the queue
#endif
#ifdef TRUSTED_AUTH
ServerAuth* port_trusted_auth;
#endif #endif
UCHAR port_buffer[1]; UCHAR port_buffer[1];
@ -488,7 +511,7 @@ struct rem_port
ISC_STATUS seek_blob(P_SEEK*, PACKET*); ISC_STATUS seek_blob(P_SEEK*, PACKET*);
ISC_STATUS send_msg(P_DATA*, PACKET*); ISC_STATUS send_msg(P_DATA*, PACKET*);
ISC_STATUS send_response(PACKET*, OBJCT, USHORT, const ISC_STATUS*, bool); ISC_STATUS send_response(PACKET*, OBJCT, USHORT, const ISC_STATUS*, bool);
ISC_STATUS service_attach(P_ATCH*, PACKET*); ISC_STATUS service_attach(const char*, const USHORT, Firebird::ClumpletWriter&, PACKET*);
ISC_STATUS service_end(P_RLSE*, PACKET*); ISC_STATUS service_end(P_RLSE*, PACKET*);
ISC_STATUS service_start(P_INFO*, PACKET*); ISC_STATUS service_start(P_INFO*, PACKET*);
ISC_STATUS set_cursor(P_SQLCUR*, PACKET*); ISC_STATUS set_cursor(P_SQLCUR*, PACKET*);
@ -496,7 +519,6 @@ struct rem_port
ISC_STATUS start_and_send(P_OP, P_DATA*, PACKET*); ISC_STATUS start_and_send(P_OP, P_DATA*, PACKET*);
ISC_STATUS start_transaction(P_OP, P_STTR*, PACKET*); ISC_STATUS start_transaction(P_OP, P_STTR*, PACKET*);
ISC_STATUS transact_request(P_TRRQ *, PACKET*); ISC_STATUS transact_request(P_TRRQ *, PACKET*);
}; };
// port_flags // port_flags

View File

@ -150,7 +150,16 @@ static ISC_STATUS allocate_statement(rem_port*, P_RLSE*, PACKET*);
static SLONG append_request_chain(SERVER_REQ, SERVER_REQ*); static SLONG append_request_chain(SERVER_REQ, SERVER_REQ*);
static SLONG append_request_next(SERVER_REQ, SERVER_REQ*); static SLONG append_request_next(SERVER_REQ, SERVER_REQ*);
#endif #endif
static ISC_STATUS attach_database(rem_port*, P_OP, P_ATCH*, PACKET*); static void attach_database(rem_port*, P_OP, P_ATCH*, PACKET*);
static void attach_service(rem_port*, P_ATCH*, PACKET*);
static void attach_database2(rem_port*, P_OP, const char*, int,
const UCHAR*, int, PACKET*);
static void attach_service2(rem_port*, P_OP, const char*, int,
const UCHAR*, int, PACKET*);
#ifdef TRUSTED_AUTH
static void trusted_auth(rem_port*, P_TRAU*, PACKET*);
#endif
#ifdef NOT_USED_OR_REPLACED #ifdef NOT_USED_OR_REPLACED
static void aux_connect(rem_port*, P_REQ*, PACKET*); static void aux_connect(rem_port*, P_REQ*, PACKET*);
#endif #endif
@ -644,23 +653,23 @@ static bool accept_connection(rem_port* port,
* Process a connect packet. * Process a connect packet.
* *
**************************************/ **************************************/
P_ARCH architecture = arch_generic;
USHORT version = 0;
USHORT type = 0;
bool accepted = false;
/* Accept the physical connection */
// Accept the physical connection
send->p_operation = op_reject; send->p_operation = op_reject;
P_ACPT* accept = &send->p_acpt; P_ACPT* accept = &send->p_acpt;
USHORT weight = 0;
if (!port->accept(connect)) { if (!port->accept(connect)) {
port->send(send); port->send(send);
return false; return false;
} }
/* Select the most appropriate protocol (this will get smarter) */
// Select the most appropriate protocol (this will get smarter)
P_ARCH architecture = arch_generic;
USHORT version = 0;
USHORT type = 0;
bool accepted = false;
USHORT weight = 0;
const p_cnct::p_cnct_repeat* protocol = connect->p_cnct_versions; const p_cnct::p_cnct_repeat* protocol = connect->p_cnct_versions;
for (const p_cnct::p_cnct_repeat* const end = protocol + connect->p_cnct_count; for (const p_cnct::p_cnct_repeat* const end = protocol + connect->p_cnct_count;
@ -673,7 +682,8 @@ static bool accept_connection(rem_port* port,
protocol->p_cnct_version == PROTOCOL_VERSION7 || protocol->p_cnct_version == PROTOCOL_VERSION7 ||
protocol->p_cnct_version == PROTOCOL_VERSION8 || protocol->p_cnct_version == PROTOCOL_VERSION8 ||
protocol->p_cnct_version == PROTOCOL_VERSION9 || protocol->p_cnct_version == PROTOCOL_VERSION9 ||
protocol->p_cnct_version == PROTOCOL_VERSION10 protocol->p_cnct_version == PROTOCOL_VERSION10 ||
protocol->p_cnct_version == PROTOCOL_VERSION11
#ifdef SCROLLABLE_CURSORS #ifdef SCROLLABLE_CURSORS
|| protocol->p_cnct_version == PROTOCOL_SCROLLABLE_CURSORS || protocol->p_cnct_version == PROTOCOL_SCROLLABLE_CURSORS
#endif #endif
@ -702,11 +712,11 @@ static bool accept_connection(rem_port* port,
/* and modify the version string to reflect the chosen protocol */ /* and modify the version string to reflect the chosen protocol */
TEXT buffer[64]; Firebird::string buffer;
sprintf(buffer, "%s/P%d", port->port_version->str_data, buffer.printf("%s/P%d", port->port_version->str_data,
port->port_protocol); port->port_protocol & FB_PROTOCOL_MASK);
ALLR_free(port->port_version); ALLR_free(port->port_version);
port->port_version = REMOTE_make_string(buffer); port->port_version = REMOTE_make_string(buffer.c_str());
if (architecture == ARCHITECTURE) if (architecture == ARCHITECTURE)
port->port_flags |= PORT_symmetric; port->port_flags |= PORT_symmetric;
@ -889,9 +899,10 @@ static void addClumplets(Firebird::ClumpletWriter& dpb_buffer,
} }
} }
static ISC_STATUS attach_database( static void attach_database(rem_port* port,
rem_port* port, P_OP operation,
P_OP operation, P_ATCH * attach, PACKET* send) P_ATCH * attach,
PACKET* send)
{ {
/************************************** /**************************************
* *
@ -903,10 +914,6 @@ static ISC_STATUS attach_database(
* Process an attach or create packet. * Process an attach or create packet.
* *
**************************************/ **************************************/
ISC_STATUS_ARRAY status_vector;
send->p_operation = op_accept;
FB_API_HANDLE handle = 0;
const char* file = reinterpret_cast<const char*>(attach->p_atch_file.cstr_address); const char* file = reinterpret_cast<const char*>(attach->p_atch_file.cstr_address);
const USHORT l = attach->p_atch_file.cstr_length; const USHORT l = attach->p_atch_file.cstr_length;
@ -920,6 +927,79 @@ static ISC_STATUS attach_database(
else else
dpb_buffer.reset(isc_dpb_version1); dpb_buffer.reset(isc_dpb_version1);
#ifdef TRUSTED_AUTH
// Do we need trusted authentication?
if (port->port_protocol >= PROTOCOL_VERSION11 && dpb_buffer.find(isc_dpb_trusted_auth))
{
try
{
// extract trusted authentication data from dpb
AuthSspi::DataHolder data;
memcpy(data.getBuffer(dpb_buffer.getClumpLength()),
dpb_buffer.getBytes(), dpb_buffer.getClumpLength());
dpb_buffer.deleteClumplet();
port->port_trusted_auth = FB_NEW(*getDefaultMemoryPool())
ServerAuth(file, l, dpb_buffer, attach_database2, operation);
AuthSspi* authSspi = port->port_trusted_auth->authSspi;
if (authSspi->accept(data) && authSspi->isActive())
{
send->p_operation = op_trusted_auth;
cstring& s = send->p_trau.p_trau_data;
s.cstr_allocated = 0;
s.cstr_length = data.getCount();
s.cstr_address = data.begin();
port->send(send);
return;
}
}
catch(const Firebird::status_exception& e)
{
ISC_STATUS_ARRAY status_vector;
Firebird::stuff_exception(status_vector, e);
port->send_response(send, 0, 0, status_vector, false);
return;
}
}
#endif //TRUSTED_AUTH
attach_database2(port, operation, file, l, dpb_buffer.getBuffer(),
dpb_buffer.getBufferLength(), send);
}
static void attach_database2(rem_port* port,
P_OP operation,
const char* file,
int l,
const UCHAR* dpb,
int dl,
PACKET* send)
{
ISC_STATUS_ARRAY status_vector;
send->p_operation = op_accept;
FB_API_HANDLE handle = 0;
Firebird::ClumpletWriter dpb_buffer(Firebird::ClumpletReader::Tagged, MAX_SSHORT);
if (dl)
dpb_buffer.reset(dpb, dl);
else
dpb_buffer.reset(isc_dpb_version1);
#ifdef TRUSTED_AUTH
// If we have trusted authentication, append it to database parameter block
if (port->port_trusted_auth)
{
AuthSspi* authSspi = port->port_trusted_auth->authSspi;
Firebird::string trustedUserName;
if (authSspi->getLogin(trustedUserName))
{
dpb_buffer.insertString(isc_dpb_trusted_auth, trustedUserName);
}
}
#endif //TRUSTED_AUTH
// If we have user identification, append it to database parameter block // If we have user identification, append it to database parameter block
rem_str* string = port->port_user_name; rem_str* string = port->port_user_name;
if (string) { if (string) {
@ -970,7 +1050,12 @@ static ISC_STATUS attach_database(
rdb->rdb_handle = handle; rdb->rdb_handle = handle;
} }
return port->send_response(send, 0, 0, status_vector, false); port->send_response(send, 0, 0, status_vector, false);
#ifdef TRUSTED_AUTH
delete port->port_trusted_auth;
port->port_trusted_auth = 0;
#endif
} }
@ -3286,7 +3371,25 @@ bool process_packet(rem_port* port,
break; break;
case op_service_attach: case op_service_attach:
port->service_attach(&receive->p_atch, sendL); attach_service(port, &receive->p_atch, sendL);
break;
case op_trusted_auth:
#ifdef TRUSTED_AUTH
trusted_auth(port, &receive->p_trau, sendL);
break;
//else
// fall down ...
#endif
case op_update_account_info:
case op_authenticate_user:
{
ISC_STATUS_ARRAY status_vector;
status_vector[0] = isc_arg_gds;
status_vector[1] = isc_wish_list;
status_vector[2] = isc_arg_end;
port->send_response(sendL, 0, 0, status_vector, false);
}
break; break;
case op_service_start: case op_service_start:
@ -3533,6 +3636,51 @@ bool process_packet(rem_port* port,
} }
#ifdef TRUSTED_AUTH
static void trusted_auth(rem_port* port, P_TRAU* p_trau, PACKET* send)
{
ISC_STATUS_ARRAY status_vector;
ServerAuth *sa = port->port_trusted_auth;
if (! sa)
{
status_vector[0] = isc_arg_gds;
status_vector[1] = isc_unavailable;
status_vector[2] = isc_arg_end;
port->send_response(send, 0, 0, status_vector, false);
}
try
{
AuthSspi::DataHolder data;
memcpy(data.getBuffer(p_trau->p_trau_data.cstr_length),
p_trau->p_trau_data.cstr_address, p_trau->p_trau_data.cstr_length);
AuthSspi* authSspi = sa->authSspi;
if (authSspi->accept(data) && authSspi->isActive())
{
send->p_operation = op_trusted_auth;
cstring& s = send->p_trau.p_trau_data;
s.cstr_allocated = 0;
s.cstr_length = data.getCount();
s.cstr_address = data.begin();
port->send(send);
return;
}
}
catch(const Firebird::status_exception& e)
{
ISC_STATUS_ARRAY status_vector;
Firebird::stuff_exception(status_vector, e);
port->send_response(send, 0, 0, status_vector, false);
return;
}
sa->part2(port, sa->operation, sa->fileName.c_str(), sa->fileName.length(),
sa->clumplet.begin(), sa->clumplet.getCount(), send);
}
#endif //TRUSTED_AUTH
ISC_STATUS rem_port::put_segment(P_OP op, P_SGMT * segment, PACKET* sendL) ISC_STATUS rem_port::put_segment(P_OP op, P_SGMT * segment, PACKET* sendL)
{ {
/************************************** /**************************************
@ -4589,7 +4737,80 @@ static void server_ast(void* event_void, USHORT length, const UCHAR* items)
} }
ISC_STATUS rem_port::service_attach(P_ATCH* attach, PACKET* sendL) static void attach_service(rem_port* port, P_ATCH* attach, PACKET* sendL)
{
const char* service_name = reinterpret_cast<const char*>
(attach->p_atch_file.cstr_address);
const USHORT service_length = attach->p_atch_file.cstr_length;
Firebird::ClumpletWriter spb(Firebird::ClumpletReader::SpbAttach, MAX_DPB_SIZE,
attach->p_atch_dpb.cstr_address, attach->p_atch_dpb.cstr_length, isc_spb_current_version);
#ifdef TRUSTED_AUTH
// Do we can & need trusted authentication?
if (port->port_protocol >= PROTOCOL_VERSION11 && spb.find(isc_spb_trusted_auth))
{
try
{
// extract trusted authentication data from spb
AuthSspi::DataHolder data;
memcpy(data.getBuffer(spb.getClumpLength()),
spb.getBytes(), spb.getClumpLength());
spb.deleteClumplet();
port->port_trusted_auth = FB_NEW(*getDefaultMemoryPool())
ServerAuth(service_name, service_length, spb, attach_service2, op_trusted_auth);
AuthSspi* authSspi = port->port_trusted_auth->authSspi;
if (authSspi->accept(data) && authSspi->isActive())
{
sendL->p_operation = op_trusted_auth;
cstring& s = sendL->p_trau.p_trau_data;
s.cstr_allocated = 0;
s.cstr_length = data.getCount();
s.cstr_address = data.begin();
port->send(sendL);
return;
}
}
catch(const Firebird::status_exception& e)
{
ISC_STATUS_ARRAY status_vector;
Firebird::stuff_exception(status_vector, e);
port->send_response(sendL, 0, 0, status_vector, false);
return;
}
}
#endif //TRUSTED_AUTH
attach_service2(port, op_trusted_auth, service_name, service_length,
spb.getBuffer(), spb.getBufferLength(), sendL);
}
static void attach_service2(rem_port* port,
P_OP,
const char* service_name,
int service_length,
const UCHAR* spb,
int sl,
PACKET* sendL)
{
port->service_attach(service_name, service_length,
Firebird::ClumpletWriter(Firebird::ClumpletReader::SpbAttach, MAX_DPB_SIZE,
spb, sl, isc_spb_current_version),
sendL);
#ifdef TRUSTED_AUTH
delete port->port_trusted_auth;
port->port_trusted_auth = 0;
#endif
}
ISC_STATUS rem_port::service_attach(const char* service_name,
const USHORT service_length,
Firebird::ClumpletWriter& spb,
PACKET* sendL)
{ {
/************************************** /**************************************
* *
@ -4603,11 +4824,20 @@ ISC_STATUS rem_port::service_attach(P_ATCH* attach, PACKET* sendL)
**************************************/ **************************************/
sendL->p_operation = op_accept; sendL->p_operation = op_accept;
FB_API_HANDLE handle = 0; FB_API_HANDLE handle = 0;
const UCHAR* service_name = attach->p_atch_file.cstr_address;
const USHORT service_length = attach->p_atch_file.cstr_length;
Firebird::ClumpletWriter spb(Firebird::ClumpletReader::SpbAttach, MAX_DPB_SIZE, #ifdef TRUSTED_AUTH
attach->p_atch_dpb.cstr_address, attach->p_atch_dpb.cstr_length, isc_spb_current_version); // If we have trusted authentication, append it to database parameter block
if (port_trusted_auth)
{
AuthSspi* authSspi = port_trusted_auth->authSspi;
Firebird::string trustedUserName;
if (authSspi->getLogin(trustedUserName))
{
spb.insertString(isc_spb_trusted_auth, trustedUserName);
}
}
#endif //TRUSTED_AUTH
// If we have user identification, append it to database parameter block // If we have user identification, append it to database parameter block
const rem_str* string = port_user_name; const rem_str* string = port_user_name;
@ -4628,7 +4858,7 @@ ISC_STATUS rem_port::service_attach(P_ATCH* attach, PACKET* sendL)
ISC_STATUS_ARRAY status_vector; ISC_STATUS_ARRAY status_vector;
isc_service_attach(status_vector, isc_service_attach(status_vector,
service_length, service_length,
reinterpret_cast<const char*>(service_name), service_name,
&handle, &handle,
spb.getBufferLength(), spb.getBufferLength(),
reinterpret_cast<const char*>(spb.getBuffer())); reinterpret_cast<const char*>(spb.getBuffer()));
@ -4636,13 +4866,22 @@ ISC_STATUS rem_port::service_attach(P_ATCH* attach, PACKET* sendL)
if (!status_vector[1]) { if (!status_vector[1]) {
RDB rdb = (RDB) ALLR_block(type_rdb, 0); RDB rdb = (RDB) ALLR_block(type_rdb, 0);
this->port_context = rdb; if (rdb)
{
this->port_context = rdb;
#ifdef DEBUG_REMOTE_MEMORY #ifdef DEBUG_REMOTE_MEMORY
printf("attach_service(server) allocate rdb %x\n", rdb); printf("attach_service(server) allocate rdb %x\n", rdb);
#endif #endif
rdb->rdb_port = this; rdb->rdb_port = this;
rdb->rdb_handle = handle; rdb->rdb_handle = handle;
rdb->rdb_flags |= RDB_service; rdb->rdb_flags |= RDB_service;
}
else
{
status_vector[0] = isc_arg_gds;
status_vector[1] = isc_bad_svc_handle;
status_vector[2] = isc_arg_end;
}
} }
return this->send_response(sendL, 0, 0, status_vector, false); return this->send_response(sendL, 0, 0, status_vector, false);

View File

@ -286,10 +286,11 @@ rem_port* XNET_analyze(Firebird::PathName& file_name,
{ {
REMOTE_PROTOCOL(PROTOCOL_VERSION7, ptype_rpc, MAX_PTYPE, 1), REMOTE_PROTOCOL(PROTOCOL_VERSION7, ptype_rpc, MAX_PTYPE, 1),
REMOTE_PROTOCOL(PROTOCOL_VERSION8, ptype_rpc, MAX_PTYPE, 2), REMOTE_PROTOCOL(PROTOCOL_VERSION8, ptype_rpc, MAX_PTYPE, 2),
REMOTE_PROTOCOL(PROTOCOL_VERSION10, ptype_rpc, MAX_PTYPE, 3) REMOTE_PROTOCOL(PROTOCOL_VERSION10, ptype_rpc, MAX_PTYPE, 3),
REMOTE_PROTOCOL(PROTOCOL_VERSION11, ptype_rpc, MAX_PTYPE, 4)
#ifdef SCROLLABLE_CURSORS #ifdef SCROLLABLE_CURSORS
, ,
REMOTE_PROTOCOL(PROTOCOL_SCROLLABLE_CURSORS, ptype_rpc, MAX_PTYPE, 4) REMOTE_PROTOCOL(PROTOCOL_SCROLLABLE_CURSORS, ptype_rpc, MAX_PTYPE, 99)
#endif #endif
}; };
cnct->p_cnct_count = FB_NELEM(protocols_to_try1); cnct->p_cnct_count = FB_NELEM(protocols_to_try1);
@ -399,7 +400,8 @@ rem_port* XNET_analyze(Firebird::PathName& file_name,
// string to reflect it... // string to reflect it...
Firebird::string temp; Firebird::string temp;
temp.printf("%s/P%d", port->port_version->str_data, port->port_protocol); temp.printf("%s/P%d", port->port_version->str_data,
port->port_protocol & FB_PROTOCOL_MASK);
ALLR_free((UCHAR *) port->port_version); ALLR_free((UCHAR *) port->port_version);
port->port_version = REMOTE_make_string(temp.c_str()); port->port_version = REMOTE_make_string(temp.c_str());

View File

@ -281,15 +281,27 @@ int common_main(int argc,
Firebird::ClumpletWriter dpb(Firebird::ClumpletReader::Tagged, MAX_DPB_SIZE, isc_dpb_version1); Firebird::ClumpletWriter dpb(Firebird::ClumpletReader::Tagged, MAX_DPB_SIZE, isc_dpb_version1);
dpb.insertByte(isc_dpb_gsec_attach, 1); // not 0 - yes, I'm gsec dpb.insertByte(isc_dpb_gsec_attach, 1); // not 0 - yes, I'm gsec
if (user_data->dba_user_name_entered) { #ifdef TRUSTED_SERVICES
dpb.insertString(isc_dpb_user_name, if (user_data->dba_trust_user_name_entered)
user_data->dba_user_name, strlen(user_data->dba_user_name)); {
dpb.insertString(isc_dpb_trusted_auth,
user_data->dba_trust_user_name, strlen(user_data->dba_trust_user_name));
} }
else
#endif
{
if (user_data->dba_user_name_entered)
{
dpb.insertString(isc_dpb_user_name,
user_data->dba_user_name, strlen(user_data->dba_user_name));
}
if (user_data->dba_password_entered) { if (user_data->dba_password_entered)
dpb.insertString(tdsec->tsec_service_gsec ? {
isc_dpb_password_enc : isc_dpb_password, dpb.insertString(tdsec->tsec_service_gsec ?
user_data->dba_password, strlen(user_data->dba_password)); isc_dpb_password_enc : isc_dpb_password,
user_data->dba_password, strlen(user_data->dba_password));
}
} }
if (user_data->sql_role_name_entered) { if (user_data->sql_role_name_entered) {
@ -698,6 +710,12 @@ static bool get_switches(
strncpy(user_data->sql_role_name, string, sizeof(user_data->sql_role_name)); strncpy(user_data->sql_role_name, string, sizeof(user_data->sql_role_name));
user_data->sql_role_name_entered = true; user_data->sql_role_name_entered = true;
break; break;
#ifdef TRUSTED_SERVICES
case IN_SW_GSEC_DBA_TRUST_USER:
strncpy(user_data->dba_trust_user_name, string, sizeof(user_data->dba_trust_user_name));
user_data->dba_trust_user_name_entered = true;
break;
#endif
case IN_SW_GSEC_Z: case IN_SW_GSEC_Z:
case IN_SW_GSEC_0: case IN_SW_GSEC_0:
#ifdef SERVICE_THREAD #ifdef SERVICE_THREAD
@ -799,6 +817,9 @@ static bool get_switches(
case IN_SW_GSEC_MNAME: case IN_SW_GSEC_MNAME:
case IN_SW_GSEC_LNAME: case IN_SW_GSEC_LNAME:
case IN_SW_GSEC_DATABASE: case IN_SW_GSEC_DATABASE:
#ifdef TRUSTED_SERVICES
case IN_SW_GSEC_DBA_TRUST_USER:
#endif
case IN_SW_GSEC_DBA_USER_NAME: case IN_SW_GSEC_DBA_USER_NAME:
case IN_SW_GSEC_DBA_PASSWORD: case IN_SW_GSEC_DBA_PASSWORD:
case IN_SW_GSEC_SQL_ROLE_NAME: case IN_SW_GSEC_SQL_ROLE_NAME:
@ -884,6 +905,16 @@ static bool get_switches(
user_data->dba_user_name_specified = true; user_data->dba_user_name_specified = true;
user_data->dba_user_name[0] = '\0'; user_data->dba_user_name[0] = '\0';
break; break;
#ifdef TRUSTED_SERVICES
case IN_SW_GSEC_DBA_TRUST_USER:
if (user_data->dba_trust_user_name_specified) {
err_msg_no = GsecMsg79;
break;
}
user_data->dba_trust_user_name_specified = true;
user_data->dba_trust_user_name[0] = '\0';
break;
#endif
case IN_SW_GSEC_DBA_PASSWORD: case IN_SW_GSEC_DBA_PASSWORD:
if (user_data->dba_password_specified) { if (user_data->dba_password_specified) {
err_msg_no = GsecMsg80; err_msg_no = GsecMsg80;

View File

@ -91,6 +91,11 @@ struct internal_user_data {
TEXT dba_user_name [USER_NAME_LEN]; /* the user's name */ TEXT dba_user_name [USER_NAME_LEN]; /* the user's name */
bool dba_user_name_entered; /* user name entered flag */ bool dba_user_name_entered; /* user name entered flag */
bool dba_user_name_specified;/* database specified flag */ bool dba_user_name_specified;/* database specified flag */
#ifdef TRUSTED_SERVICES
TEXT dba_trust_user_name [USER_NAME_LEN]; /* the trusted dba user's name */
bool dba_trust_user_name_entered; /* trusted dba user name entered flag */
bool dba_trust_user_name_specified;/* trusted dba user name specified flag */
#endif
TEXT dba_password [NAME_LEN]; /* the user's name */ TEXT dba_password [NAME_LEN]; /* the user's name */
bool dba_password_entered; /* user name entered flag */ bool dba_password_entered; /* user name entered flag */
bool dba_password_specified; /* database specified flag */ bool dba_password_specified; /* database specified flag */

View File

@ -52,6 +52,9 @@ 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_SQL_ROLE_NAME = 19; /* SQL Role to assume */
const int IN_SW_GSEC_AMBIG = 20; /* ambiguous switch */ 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_USERNAME = 21; /* placeholder for the username */
#ifdef TRUSTED_SERVICES
const int IN_SW_GSEC_DBA_TRUST_USER = 22; /* Database Admin. Trusted User name */
#endif
static struct in_sw_tab_t gsec_in_sw_table [] = { static struct in_sw_tab_t gsec_in_sw_table [] = {
@ -74,6 +77,9 @@ static struct in_sw_tab_t gsec_in_sw_table [] = {
{IN_SW_GSEC_DBA_USER_NAME, 0, "USER", 0, 0, 0, FALSE, 0, 1, NULL}, /* Database Admin. User name */ {IN_SW_GSEC_DBA_USER_NAME, 0, "USER", 0, 0, 0, FALSE, 0, 1, NULL}, /* Database Admin. User name */
{IN_SW_GSEC_DBA_PASSWORD, 0, "PASSWORD", 0, 0, 0, FALSE, 0, 2, NULL}, /* Database Admin. Password */ {IN_SW_GSEC_DBA_PASSWORD, 0, "PASSWORD", 0, 0, 0, FALSE, 0, 2, NULL}, /* 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_SQL_ROLE_NAME, isc_spb_sql_role_name, "ROLE", 0, 0, 0, FALSE, 0, 2, NULL}, /* SQL Role to assume */
#ifdef TRUSTED_SERVICES
{IN_SW_GSEC_DBA_TRUST_USER, 0, "TRUSTED", 0, 0, 0, FALSE, 0, 1, NULL}, /* Database Admin. Trusted User name */
#endif
{IN_SW_GSEC_0, 0, NULL, 0, 0, 0, FALSE, 0, 0, NULL} /* End of List */ {IN_SW_GSEC_0, 0, NULL, 0, 0, 0, FALSE, 0, 0, NULL} /* End of List */
}; };

View File

@ -326,8 +326,15 @@ int CLIB_ROUTINE main(int argc, char** argv)
bool sw_nocreation = false; bool sw_nocreation = false;
isc_db_handle db_handle = 0; isc_db_handle db_handle = 0;
UCHAR buf[256]; UCHAR buf[256];
UCHAR pass_buff[128], user_buff[128], *password = pass_buff, *username =
user_buff; UCHAR pass_buff[128], user_buff[128], *password = pass_buff, *username = user_buff;
MOVE_CLEAR(user_buff, sizeof(user_buff));
MOVE_CLEAR(pass_buff, sizeof(pass_buff));
#ifdef TRUSTED_SERVICES
UCHAR tr_buff[128], *tr_user = tr_buff;
MOVE_CLEAR(tr_buff, sizeof(tr_buff));
#endif
tdba thd_context, *tddba; tdba thd_context, *tddba;
tdba::putSpecific(tddba, &thd_context); tdba::putSpecific(tddba, &thd_context);
@ -403,9 +410,6 @@ int CLIB_ROUTINE main(int argc, char** argv)
} }
const char* name = NULL; const char* name = NULL;
MOVE_CLEAR(user_buff, sizeof(user_buff));
MOVE_CLEAR(pass_buff, sizeof(pass_buff));
const TEXT* const* const end = argv + argc; const TEXT* const* const end = argv + argc;
++argv; ++argv;
while (argv < end) { while (argv < end) {
@ -449,12 +453,18 @@ int CLIB_ROUTINE main(int argc, char** argv)
break; break;
case IN_SW_DBA_USERNAME: case IN_SW_DBA_USERNAME:
if (argv < end) if (argv < end)
strcpy((char*) username, *argv++); strncpy((char*) username, *argv++, sizeof(user_buff) - 1);
break; break;
case IN_SW_DBA_PASSWORD: case IN_SW_DBA_PASSWORD:
if (argv < end) if (argv < end)
strcpy((char*) password, *argv++); strncpy((char*) password, *argv++, sizeof(pass_buff) - 1);
break; break;
#ifdef TRUSTED_SERVICES
case IN_SW_DBA_TRUSTEDUSER:
if (argv < end)
strncpy((char*) tr_user, *argv++, sizeof(tr_buff) - 1);
break;
#endif
case IN_SW_DBA_SYSTEM: case IN_SW_DBA_SYSTEM:
sw_system = true; sw_system = true;
break; break;
@ -656,13 +666,21 @@ int CLIB_ROUTINE main(int argc, char** argv)
dpb.insertTag(isc_dpb_gstat_attach); dpb.insertTag(isc_dpb_gstat_attach);
dpb.insertTag(isc_dpb_no_garbage_collect); dpb.insertTag(isc_dpb_no_garbage_collect);
if (*username) { if (*username)
{
dpb.insertBytes(isc_dpb_user_name, username, strlen((char*) username)); dpb.insertBytes(isc_dpb_user_name, username, strlen((char*) username));
} }
if (*password) { if (*password)
{
dpb.insertBytes(called_as_service ? isc_dpb_password_enc : isc_dpb_password, dpb.insertBytes(called_as_service ? isc_dpb_password_enc : isc_dpb_password,
password, strlen((char*) password)); password, strlen((char*) password));
} }
#ifdef TRUSTED_SERVICES
if (*tr_user)
{
dpb.insertBytes(isc_dpb_trusted_auth, tr_user, strlen((char*) tr_user));
}
#endif
isc_attach_database(status_vector, 0, name, &DB, dpb.getBufferLength(), isc_attach_database(status_vector, 0, name, &DB, dpb.getBufferLength(),
reinterpret_cast<const char*>(dpb.getBuffer())); reinterpret_cast<const char*>(dpb.getBuffer()));

View File

@ -43,6 +43,9 @@ const int IN_SW_DBA_PASSWORD = 9; /* password */
const int IN_SW_DBA_RECORD = 10; /* analyze record versions */ const int IN_SW_DBA_RECORD = 10; /* analyze record versions */
const int IN_SW_DBA_RELATION = 11; /* analyze specific relations */ const int IN_SW_DBA_RELATION = 11; /* analyze specific relations */
const int IN_SW_DBA_NOCREATION = 12; /* don't print creation date */ const int IN_SW_DBA_NOCREATION = 12; /* don't print creation date */
#ifdef TRUSTED_SERVICES
const int IN_SW_DBA_TRUSTEDUSER = 13; /* trusted user name */
#endif
static struct in_sw_tab_t dba_in_sw_table [] = { static struct in_sw_tab_t dba_in_sw_table [] = {
{IN_SW_DBA_DATAIDX, 0, "ALL", 0,0,0, FALSE, 22, 0, NULL}, /* msg 22: -a analyze data and index pages */ {IN_SW_DBA_DATAIDX, 0, "ALL", 0,0,0, FALSE, 22, 0, NULL}, /* msg 22: -a analyze data and index pages */
@ -58,6 +61,9 @@ static struct in_sw_tab_t dba_in_sw_table [] = {
{IN_SW_DBA_VERSION, 0, "Z", 0,0,0, FALSE, 28, 0, NULL}, /* msg 28: -z display version number */ {IN_SW_DBA_VERSION, 0, "Z", 0,0,0, FALSE, 28, 0, NULL}, /* msg 28: -z display version number */
// special switch to avoid including creation date, only for tests (no message) // 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, 0, NULL}, /* msg 35: -n suppress creation date */ {IN_SW_DBA_NOCREATION, isc_spb_sts_nocreation, "NOCREATION", 0,0,0, FALSE, 0, 0, NULL}, /* msg 35: -n suppress creation date */
#ifdef TRUSTED_SERVICES
{IN_SW_DBA_TRUSTEDUSER, 0, "TRUSTED", 0,0,0, FALSE, 0, 0, NULL}, /* msg 0 - ignored */
#endif
{IN_SW_DBA_0, 0, NULL, 0,0,0, FALSE, 0, 0, NULL} /* End of List */ {IN_SW_DBA_0, 0, NULL, 0,0,0, FALSE, 0, 0, NULL} /* End of List */
}; };
#endif /* DBA_DBASWI_H */ #endif /* DBA_DBASWI_H */