mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 10:03:03 +01:00
Trusted authentication for windows
This commit is contained in:
parent
83a2065a3c
commit
1a4652f01a
@ -47,7 +47,7 @@
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
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"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
@ -115,7 +115,7 @@
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
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"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
|
@ -42,7 +42,7 @@
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
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"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
@ -115,7 +115,7 @@
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
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"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
@ -371,6 +371,15 @@
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="AuthSspi">
|
||||
<File
|
||||
RelativePath="..\..\..\src\auth\trusted\AuthSspi.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\src\auth\trusted\AuthSspi.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath="..\defs\fbclient.def">
|
||||
</File>
|
||||
|
@ -42,7 +42,7 @@
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
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"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
@ -116,7 +116,7 @@
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
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"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
@ -362,6 +362,15 @@
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="AuthSspi">
|
||||
<File
|
||||
RelativePath="..\..\..\src\auth\trusted\AuthSspi.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\src\auth\trusted\AuthSspi.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath="..\defs\fbclient.def">
|
||||
</File>
|
||||
|
@ -47,7 +47,7 @@
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
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"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
@ -115,7 +115,7 @@
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
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"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
|
@ -220,6 +220,16 @@
|
||||
RelativePath="..\..\..\src\remote\xnet_proto.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="AuthSspi"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\..\src\auth\trusted\AuthSspi.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\src\auth\trusted\AuthSspi.h">
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
|
@ -217,6 +217,15 @@
|
||||
RelativePath="..\..\..\src\remote\xnet_proto.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="AuthSspi">
|
||||
<File
|
||||
RelativePath="..\..\..\src\auth\trusted\AuthSspi.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\src\auth\trusted\AuthSspi.h">
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
|
@ -253,6 +253,9 @@ int common_main(int argc,
|
||||
|
||||
tdgbl->ALICE_data.ua_user = NULL;
|
||||
tdgbl->ALICE_data.ua_password = NULL;
|
||||
#ifdef TRUSTED_SERVICES
|
||||
tdgbl->ALICE_data.ua_tr_user = NULL;
|
||||
#endif
|
||||
|
||||
// Start by parsing switches
|
||||
|
||||
@ -318,6 +321,15 @@ int common_main(int argc,
|
||||
if (table->in_sw_value == sw_z) {
|
||||
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) ||
|
||||
(table->in_sw_requires && !(table->in_sw_requires & switches)))
|
||||
{
|
||||
@ -544,7 +556,10 @@ int common_main(int argc,
|
||||
#else
|
||||
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++)
|
||||
{
|
||||
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
|
||||
#endif
|
||||
exit_local(FINI_ERROR, tdgbl);
|
||||
|
@ -60,6 +60,9 @@ struct user_action
|
||||
ULONG ua_switches;
|
||||
const UCHAR* ua_user;
|
||||
const UCHAR* ua_password;
|
||||
#ifdef TRUSTED_SERVICES
|
||||
UCHAR* ua_tr_user;
|
||||
#endif
|
||||
bool ua_use;
|
||||
bool ua_force;
|
||||
bool ua_read_only;
|
||||
|
@ -106,7 +106,8 @@ enum alice_switches
|
||||
IN_SW_ALICE_HIDDEN_FORCE = 40,
|
||||
IN_SW_ALICE_HIDDEN_TRAN = 41,
|
||||
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";
|
||||
@ -214,6 +215,10 @@ static in_sw_tab_t alice_in_sw_table[] =
|
||||
// msg 48: \t-tran\t\tshutdown transaction startup
|
||||
{IN_SW_ALICE_USE, 0, "use", sw_use,
|
||||
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
|
||||
{IN_SW_ALICE_USER, 0, "user", sw_user,
|
||||
0, 0, FALSE, 50, 0, NULL},
|
||||
|
@ -322,6 +322,13 @@ static void buildDpb(Firebird::ClumpletWriter& dpb, const ULONG switches)
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
|
@ -202,6 +202,13 @@ bool TDR_attach_database(ISC_STATUS* status_vector,
|
||||
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;
|
||||
|
||||
|
218
src/auth/trusted/AuthSspi.cpp
Normal file
218
src/auth/trusted/AuthSspi.cpp
Normal 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
|
44
src/auth/trusted/AuthSspi.h
Normal file
44
src/auth/trusted/AuthSspi.h
Normal 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
|
@ -830,6 +830,14 @@ int common_main(int argc,
|
||||
// user name parameter missing
|
||||
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) {
|
||||
if (argv >= end)
|
||||
BURP_error(253, true, 0, 0, 0, 0, 0);
|
||||
@ -1049,6 +1057,13 @@ int common_main(int argc,
|
||||
strlen(tdgbl->gbl_sw_user));
|
||||
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):
|
||||
tdgbl->gbl_sw_verbose = true;
|
||||
break;
|
||||
|
@ -799,6 +799,8 @@ public:
|
||||
// this is VERY dirty hack to keep current behaviour
|
||||
memset (&gbl_database_file_name, 0,
|
||||
&veryEnd - reinterpret_cast<char*>(&gbl_database_file_name));
|
||||
|
||||
// normal code follows
|
||||
exit_code = FINI_ERROR; // prevent FINI_OK in case of unknown error thrown
|
||||
// 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_user;
|
||||
const SCHAR* gbl_sw_password;
|
||||
#ifdef TRUSTED_SERVICES
|
||||
const SCHAR* gbl_sw_tr_user;
|
||||
#endif
|
||||
SLONG gbl_sw_skip_count;
|
||||
SLONG gbl_sw_page_buffers;
|
||||
burp_fil* gbl_sw_files;
|
||||
|
@ -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_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
|
||||
|
||||
@ -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
|
||||
{IN_SW_BURP_USER, 0, "USER", 0, 0, 0, FALSE, 191, 0, NULL},
|
||||
// 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, 0, "VERIFY", 0, 0, 0, FALSE, 113, 0, NULL},
|
||||
// msg 113: %sVERIFY report each action taken
|
||||
|
@ -103,6 +103,7 @@
|
||||
#define isc_dpb_address_path 70
|
||||
#define isc_dpb_pid 71
|
||||
#define isc_dpb_no_db_triggers 72
|
||||
#define isc_dpb_trusted_auth 73
|
||||
|
||||
/**************************************************/
|
||||
/* clumplet tags used inside isc_dpb_address_path */
|
||||
@ -251,6 +252,7 @@
|
||||
#define isc_spb_options 108
|
||||
#define isc_spb_address_path 109
|
||||
#define isc_spb_pid 110
|
||||
#define isc_spb_trusted_auth 111
|
||||
|
||||
|
||||
#define isc_spb_connect_timeout isc_dpb_connect_timeout
|
||||
|
@ -127,4 +127,11 @@ using namespace NAMESPACE;
|
||||
#define SERVICE_THREAD
|
||||
#endif
|
||||
|
||||
#if defined(WIN_NT)
|
||||
#define TRUSTED_AUTH
|
||||
#if defined(SERVICE_THREAD)
|
||||
#define TRUSTED_SERVICES
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* INCLUDE_Firebird_H */
|
||||
|
@ -166,6 +166,9 @@ enum switch_id {
|
||||
SWITCH_ROLE2,
|
||||
SWITCH_SQLDIALECT,
|
||||
SWITCH_TERM,
|
||||
#ifdef TRUSTED_AUTH
|
||||
SWITCH_TRUSTED,
|
||||
#endif
|
||||
SWITCH_USER,
|
||||
SWITCH_VERSION,
|
||||
#ifdef DEV_BUILD
|
||||
@ -211,6 +214,9 @@ const switch_info switches[] =
|
||||
{ SWITCH_SQLDIALECT, "sqldialect", 1, SWARG_INTEGER, 137 },
|
||||
{ SWITCH_SQLDIALECT, "sql_dialect", 1, SWARG_INTEGER, -1 },
|
||||
{ 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_EXTRACT, "x", 1, SWARG_NONE, 140 },
|
||||
{ SWITCH_VERSION, "z", 1, SWARG_NONE, 141 }
|
||||
@ -383,7 +389,10 @@ XSQLDA** global_sqldap;
|
||||
USHORT global_dialect_spoken = 0;
|
||||
USHORT requested_SQL_dialect = SQL_DIALECT_V6;
|
||||
bool connecting_to_pre_v6_server = false;
|
||||
bool Quiet;
|
||||
bool Quiet = false;
|
||||
#ifdef TRUSTED_AUTH
|
||||
bool Trusted_auth = false;
|
||||
#endif
|
||||
bool Version_info = false;
|
||||
#if defined (WIN95)
|
||||
bool fAnsiCP;
|
||||
@ -5178,6 +5187,12 @@ static processing_state newdb(TEXT* dbname,
|
||||
if (Nodbtriggers)
|
||||
dpb.insertInt(isc_dpb_no_db_triggers, 1);
|
||||
|
||||
#ifdef TRUSTED_AUTH
|
||||
if (Trusted_auth) {
|
||||
dpb.insertTag(isc_dpb_trusted_auth);
|
||||
}
|
||||
#endif
|
||||
|
||||
{ // scope
|
||||
const TEXT* local_name = isqlGlob.global_Db_name;
|
||||
|
||||
@ -5788,6 +5803,12 @@ static processing_state parse_arg(int argc,
|
||||
Quiet = true;
|
||||
break;
|
||||
|
||||
#ifdef TRUSTED_AUTH
|
||||
case SWITCH_TRUSTED:
|
||||
Trusted_auth = true;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case SWITCH_VERSION:
|
||||
Version_info = true;
|
||||
ISQL_msg_get(VERSION, errbuf, FB_VERSION);
|
||||
|
140
src/jrd/isc.cpp
140
src/jrd/isc.cpp
@ -72,10 +72,6 @@
|
||||
static USHORT os_type;
|
||||
static SECURITY_ATTRIBUTES security_attr;
|
||||
|
||||
//static TEXT interbase_directory[MAXPATHLEN];
|
||||
|
||||
static bool check_user_privilege();
|
||||
|
||||
#endif // WIN_NT
|
||||
|
||||
static TEXT user_name[256];
|
||||
@ -101,6 +97,7 @@ static USHORT ast_count;
|
||||
|
||||
static POKE pokes;
|
||||
static lock_status wake_lock;
|
||||
|
||||
#endif /* of ifdef VMS */
|
||||
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
@ -595,148 +592,17 @@ int ISC_get_user(TEXT* name,
|
||||
{
|
||||
name[name_len] = 0;
|
||||
|
||||
/* NT user name is case insensitive */
|
||||
|
||||
// NT user name is case insensitive
|
||||
for (DWORD i = 0; i < name_len; 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();
|
||||
}
|
||||
|
||||
|
||||
//____________________________________________________________
|
||||
//
|
||||
// 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
|
||||
|
||||
#endif //WIN_NT
|
||||
|
||||
#ifdef VMS
|
||||
int ISC_make_desc(const TEXT* string, struct dsc$descriptor* desc, USHORT length)
|
||||
|
@ -348,6 +348,9 @@ public:
|
||||
Firebird::string dpb_set_db_charset;
|
||||
Firebird::string dpb_network_protocol;
|
||||
Firebird::string dpb_remote_address;
|
||||
#ifdef TRUSTED_AUTH
|
||||
Firebird::string dpb_trusted_login;
|
||||
#endif
|
||||
|
||||
public:
|
||||
DatabaseOptions()
|
||||
@ -965,6 +968,9 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
|
||||
options.dpb_password.nullStr(),
|
||||
options.dpb_password_enc.nullStr(),
|
||||
options.dpb_role_name.nullStr(),
|
||||
#ifdef TRUSTED_AUTH
|
||||
options.dpb_trusted_login.nullStr(),
|
||||
#endif
|
||||
tdbb);
|
||||
|
||||
initing_security = false;
|
||||
@ -1928,6 +1934,9 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status,
|
||||
options.dpb_password.nullStr(),
|
||||
options.dpb_password_enc.nullStr(),
|
||||
options.dpb_role_name.nullStr(),
|
||||
#ifdef TRUSTED_AUTH
|
||||
options.dpb_trusted_login.nullStr(),
|
||||
#endif
|
||||
tdbb);
|
||||
|
||||
initing_security = false;
|
||||
@ -5474,6 +5483,12 @@ void DatabaseOptions::get(const UCHAR* dpb, USHORT dpb_length)
|
||||
rdr.getString(dpb_password_enc);
|
||||
break;
|
||||
|
||||
#ifdef TRUSTED_AUTH
|
||||
case isc_dpb_trusted_auth:
|
||||
rdr.getString(dpb_trusted_login);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case isc_dpb_encrypt_key:
|
||||
#ifdef ISC_DATABASE_ENCRYPTION
|
||||
rdr.getString(dpb_key);
|
||||
|
@ -555,6 +555,9 @@ void SCL_init(bool create,
|
||||
const TEXT* password,
|
||||
const TEXT* password_enc,
|
||||
const TEXT* sql_role,
|
||||
#ifdef TRUSTED_AUTH
|
||||
const TEXT* trusted_user,
|
||||
#endif
|
||||
thread_db* tdbb)
|
||||
{
|
||||
/**************************************
|
||||
@ -606,6 +609,15 @@ void SCL_init(bool create,
|
||||
{
|
||||
if (!JRD_get_thread_security_disabled())
|
||||
{
|
||||
#ifdef TRUSTED_AUTH
|
||||
if (trusted_user)
|
||||
{
|
||||
strncpy(name, trusted_user, sizeof name);
|
||||
name[sizeof name - 1] = 0;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
Attachment* att = tdbb->tdbb_attachment;
|
||||
Firebird::string remote = att->att_network_protocol +
|
||||
(att->att_network_protocol.isEmpty() || att->att_remote_address.isEmpty() ? "" : "/") +
|
||||
@ -613,6 +625,7 @@ void SCL_init(bool create,
|
||||
SecurityDatabase::verifyUser(name, user_name, password, password_enc,
|
||||
&id, &group, &node_id, remote);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
strncpy(name, user_name, sizeof name);
|
||||
|
@ -41,8 +41,11 @@ void SCL_check_procedure(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::flags_t SCL_get_mask(const TEXT*, const TEXT*);
|
||||
void SCL_init(bool, const TEXT*, const TEXT*, const TEXT*, const TEXT*,
|
||||
const TEXT*, Jrd::thread_db*);
|
||||
void SCL_init(bool, const TEXT*, const TEXT*, const TEXT*, const TEXT*, const TEXT*,
|
||||
#ifdef TRUSTED_AUTH
|
||||
const TEXT*,
|
||||
#endif
|
||||
Jrd::thread_db*);
|
||||
void SCL_move_priv(UCHAR**, Jrd::SecurityClass::flags_t, Firebird::UCharBuffer&, ULONG*);
|
||||
Jrd::SecurityClass* SCL_recompute_class(Jrd::thread_db*, const TEXT*);
|
||||
void SCL_release(Jrd::SecurityClass*);
|
||||
|
@ -135,7 +135,11 @@ namespace Jrd {
|
||||
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_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);
|
||||
@ -285,6 +289,9 @@ struct Serv_param_block {
|
||||
Firebird::string spb_command_line;
|
||||
Firebird::string spb_network_protocol;
|
||||
Firebird::string spb_remote_address;
|
||||
#ifdef TRUSTED_AUTH
|
||||
Firebird::string spb_trusted_login;
|
||||
#endif
|
||||
USHORT spb_version;
|
||||
|
||||
Serv_param_block() : spb_version(0) { }
|
||||
@ -553,6 +560,13 @@ Service* SVC_attach(USHORT service_length,
|
||||
user_flag = SVC_user_none;
|
||||
}
|
||||
else {
|
||||
#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
|
||||
@ -608,6 +622,9 @@ Service* SVC_attach(USHORT service_length,
|
||||
#endif
|
||||
service->svc_spb_version = options.spb_version;
|
||||
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
|
||||
* there is no OS authentication. If the password is not yet
|
||||
@ -1785,7 +1802,19 @@ void* SVC_start(Service* service, USHORT spb_length, const SCHAR* spb_data)
|
||||
svc_id == isc_action_svc_properties)
|
||||
{
|
||||
/* add the username and password to the end of svc_switches if needed */
|
||||
if (service->svc_switches.hasData()) {
|
||||
if (service->svc_switches.hasData())
|
||||
{
|
||||
#ifdef TRUSTED_AUTH
|
||||
if (service->svc_trusted_login.hasData())
|
||||
{
|
||||
service->svc_switches += ' ';
|
||||
service->svc_switches += TRUSTED_USER_SWITCH;
|
||||
service->svc_switches += ' ';
|
||||
service->svc_switches += service->svc_username;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (service->svc_username.hasData())
|
||||
{
|
||||
service->svc_switches += ' ';
|
||||
@ -1803,6 +1832,7 @@ void* SVC_start(Service* service, USHORT spb_length, const SCHAR* spb_data)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// All services except for get_ib_log require switches
|
||||
spb.rewind();
|
||||
@ -2006,6 +2036,12 @@ static void get_options(Firebird::ClumpletReader& spb,
|
||||
spb.getString(options->spb_password_enc);
|
||||
break;
|
||||
|
||||
#ifdef TRUSTED_AUTH
|
||||
case isc_spb_trusted_auth:
|
||||
spb.getString(options->spb_trusted_login);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case isc_spb_command_line:
|
||||
spb.getString(options->spb_command_line);
|
||||
break;
|
||||
|
@ -81,6 +81,9 @@ const USHORT isc_action_max = 14;
|
||||
#else
|
||||
#define SERVICE_THD_PARAM "-svc"
|
||||
#endif
|
||||
#ifdef TRUSTED_AUTH
|
||||
#define TRUSTED_USER_SWITCH "-TRUSTED"
|
||||
#endif
|
||||
|
||||
/* Macro used to store services thread specific data */
|
||||
/* Currently we store empty string, see bug #10394 */
|
||||
@ -130,6 +133,9 @@ public:
|
||||
bool svc_do_shutdown;
|
||||
Firebird::string svc_username;
|
||||
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_perm_sw; // Switches, taken from services table
|
||||
// and/or passed using spb_command_line
|
||||
|
@ -2367,6 +2367,10 @@ inline void setTag(Firebird::ClumpletWriter& dpb, UCHAR tag, const TEXT* value)
|
||||
}
|
||||
|
||||
void setLogin(Firebird::ClumpletWriter& dpb)
|
||||
{
|
||||
#ifdef TRUSTED_AUTH
|
||||
if (!dpb.find(isc_dpb_trusted_auth))
|
||||
#endif
|
||||
{
|
||||
Firebird::string username;
|
||||
if (fb_utils::readenv("ISC_USER", username) && !dpb.find(isc_dpb_sys_user_name))
|
||||
@ -2380,4 +2384,5 @@ void setLogin(Firebird::ClumpletWriter& dpb)
|
||||
setTag(dpb, isc_dpb_password, password.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 ('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', '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 ('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);
|
||||
@ -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_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_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 ('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);
|
||||
|
@ -129,6 +129,9 @@ int CLIB_ROUTINE main( int argc, char **argv)
|
||||
QLI_columns = 80;
|
||||
#else
|
||||
QLI_columns = 80;
|
||||
#endif
|
||||
#ifdef TRUSTED_AUTH
|
||||
QLI_trusted = false;
|
||||
#endif
|
||||
QLI_lines = 60;
|
||||
QLI_name_columns = 0;
|
||||
@ -182,6 +185,12 @@ int CLIB_ROUTINE main( int argc, char **argv)
|
||||
startup_file = *argv++;
|
||||
break;
|
||||
|
||||
#ifdef TRUSTED_AUTH
|
||||
case 'K':
|
||||
QLI_trusted = true;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 'N':
|
||||
banner_flag = false;
|
||||
break;
|
||||
|
@ -499,6 +499,9 @@ EXTERN USHORT QLI_count;
|
||||
EXTERN bool QLI_explain;
|
||||
EXTERN bool QLI_hex_output;
|
||||
#endif
|
||||
#ifdef TRUSTED_AUTH
|
||||
EXTERN bool QLI_trusted;
|
||||
#endif
|
||||
|
||||
EXTERN jmp_buf QLI_env; // Error return environment
|
||||
|
||||
|
@ -1420,6 +1420,12 @@ void MET_ready( qli_syntax* node, USHORT create_flag)
|
||||
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;
|
||||
|
||||
// Start by attaching all databases
|
||||
|
@ -507,10 +507,12 @@ rem_port* INET_analyze(Firebird::PathName& file_name,
|
||||
{
|
||||
REMOTE_PROTOCOL(PROTOCOL_VERSION8, ptype_rpc, MAX_PTYPE, 1),
|
||||
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
|
||||
,
|
||||
REMOTE_PROTOCOL(PROTOCOL_SCROLLABLE_CURSORS, ptype_rpc, MAX_PTYPE, 3)
|
||||
REMOTE_PROTOCOL(PROTOCOL_SCROLLABLE_CURSORS, ptype_rpc, MAX_PTYPE, 99)
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -597,9 +599,9 @@ rem_port* INET_analyze(Firebird::PathName& file_name,
|
||||
|
||||
/* once we've decided on a protocol, concatenate the version
|
||||
string to reflect it... */
|
||||
|
||||
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);
|
||||
port->port_version = REMOTE_make_string(temp.c_str());
|
||||
|
||||
@ -1898,6 +1900,10 @@ static void cleanup_port( rem_port* port)
|
||||
delete port->port_queue;
|
||||
#endif
|
||||
|
||||
#ifdef TRUSTED_AUTH
|
||||
delete port->port_trusted_auth;
|
||||
#endif
|
||||
|
||||
ALLR_release((UCHAR *) port);
|
||||
return;
|
||||
}
|
||||
|
@ -66,6 +66,7 @@
|
||||
#include "../jrd/thread_proto.h"
|
||||
#include "../common/classes/ClumpletWriter.h"
|
||||
#include "../common/config/config.h"
|
||||
#include "../auth/trusted/AuthSspi.h"
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
@ -110,7 +111,7 @@ namespace {
|
||||
// for both services and databases attachments
|
||||
struct ParametersSet {
|
||||
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,
|
||||
isc_dpb_user_name,
|
||||
@ -118,14 +119,16 @@ namespace {
|
||||
isc_dpb_password,
|
||||
isc_dpb_password_enc,
|
||||
isc_dpb_address_path,
|
||||
isc_dpb_pid};
|
||||
isc_dpb_pid,
|
||||
isc_dpb_trusted_auth};
|
||||
const ParametersSet spbParam = {isc_spb_dummy_packet_interval,
|
||||
isc_spb_user_name,
|
||||
isc_spb_sys_user_name,
|
||||
isc_spb_password,
|
||||
isc_spb_password_enc,
|
||||
isc_spb_address_path,
|
||||
isc_spb_pid};
|
||||
isc_spb_pid,
|
||||
isc_spb_trusted_auth};
|
||||
}
|
||||
|
||||
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 info(ISC_STATUS*, RDB, P_OP, USHORT, USHORT, USHORT,
|
||||
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 ISC_STATUS mov_dsql_message(const UCHAR*, const rem_fmt*, UCHAR*, const rem_fmt*);
|
||||
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_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) {
|
||||
return error(user_status);
|
||||
@ -904,7 +909,8 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status,
|
||||
add_other_params(port, newDpb, dpbParam);
|
||||
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) {
|
||||
return error(user_status);
|
||||
}
|
||||
@ -3951,7 +3957,8 @@ ISC_STATUS GDS_SERVICE_ATTACH(ISC_STATUS* user_status,
|
||||
|
||||
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) {
|
||||
return error(user_status);
|
||||
}
|
||||
@ -5841,7 +5848,8 @@ static bool init(ISC_STATUS* user_status,
|
||||
rem_port* port,
|
||||
P_OP op,
|
||||
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();
|
||||
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;
|
||||
packet->p_operation = op;
|
||||
@ -5876,9 +5906,54 @@ static bool init(ISC_STATUS* user_status,
|
||||
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);
|
||||
disconnect(port);
|
||||
return false;
|
||||
|
@ -183,10 +183,11 @@ rem_port* WNET_analyze(Firebird::PathName& file_name,
|
||||
{
|
||||
REMOTE_PROTOCOL(PROTOCOL_VERSION7, ptype_rpc, MAX_PTYPE, 1),
|
||||
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
|
||||
,
|
||||
REMOTE_PROTOCOL(PROTOCOL_SCROLLABLE_CURSORS, ptype_rpc, MAX_PTYPE, 4)
|
||||
REMOTE_PROTOCOL(PROTOCOL_SCROLLABLE_CURSORS, ptype_rpc, MAX_PTYPE, 99)
|
||||
#endif
|
||||
};
|
||||
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... */
|
||||
|
||||
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);
|
||||
port->port_version = REMOTE_make_string(temp.c_str());
|
||||
|
||||
|
@ -289,6 +289,7 @@ bool_t xdr_protocol(XDR* xdrs, PACKET* p)
|
||||
P_SQLST *prep_stmt;
|
||||
P_SQLDATA *sqldata;
|
||||
P_TRRQ *trrq;
|
||||
P_TRAU *trau;
|
||||
#ifdef DEBUG
|
||||
xdr_save_size = xdrs->x_handy;
|
||||
#endif
|
||||
@ -786,6 +787,36 @@ bool_t xdr_protocol(XDR* xdrs, PACKET* p)
|
||||
DEBUG_PRINTSIZE(xdrs, p->p_operation);
|
||||
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:
|
||||
#ifdef DEBUG
|
||||
if (xdrs->x_op != XDR_FREE)
|
||||
|
@ -79,6 +79,24 @@ const USHORT PROTOCOL_VERSION9 = 9;
|
||||
|
||||
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
|
||||
This Protocol includes support for scrollable cursors
|
||||
and is purposely being undefined so that changes can be made
|
||||
@ -263,12 +281,15 @@ typedef enum
|
||||
op_service_start = 85,
|
||||
|
||||
op_rollback_retaining = 86,
|
||||
|
||||
// Two following opcode are used in vulcan.
|
||||
// No plans to implement protocol 11, where they are used,
|
||||
// place here only for informational reasons and to have common op-space.
|
||||
// op_update_account_info = 87,
|
||||
// op_authenticate_user = 88,
|
||||
// No plans to implement them completely for a while, but to
|
||||
// support protocol 11, where they are used, have them here.
|
||||
op_update_account_info = 87,
|
||||
op_authenticate_user = 88,
|
||||
|
||||
op_partial = 89, // packet is not complete - delay processing
|
||||
op_trusted_auth = 90,
|
||||
|
||||
op_max
|
||||
} P_OP;
|
||||
@ -574,6 +595,26 @@ typedef struct p_sqlcur {
|
||||
USHORT p_sqlcur_type; /* type of cursor */
|
||||
} 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!) */
|
||||
|
||||
typedef struct packet {
|
||||
@ -608,6 +649,9 @@ typedef struct packet {
|
||||
P_SQLCUR p_sqlcur; /* DSQL Set cursor name */
|
||||
P_SQLFREE p_sqlfree; /* DSQL Free statement */
|
||||
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;
|
||||
|
||||
#endif // REMOTE_PROTOCOL_H
|
||||
|
@ -882,3 +882,24 @@ bool_t REMOTE_getbytes (XDR * xdrs, SCHAR * buff, u_int count)
|
||||
return TRUE;
|
||||
}
|
||||
#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
|
||||
|
@ -33,6 +33,9 @@
|
||||
#include "../remote/remote_def.h"
|
||||
#include "../jrd/thd.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 */
|
||||
|
||||
@ -364,6 +367,23 @@ struct rem_que_packet
|
||||
|
||||
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 */
|
||||
|
||||
class port_interface
|
||||
@ -440,6 +460,9 @@ struct rem_port
|
||||
#ifdef SUPERSERVER
|
||||
Firebird::ObjectsArray< Firebird::Array< char > >* port_queue;
|
||||
size_t port_qoffset; // current packet in the queue
|
||||
#endif
|
||||
#ifdef TRUSTED_AUTH
|
||||
ServerAuth* port_trusted_auth;
|
||||
#endif
|
||||
UCHAR port_buffer[1];
|
||||
|
||||
@ -488,7 +511,7 @@ struct rem_port
|
||||
ISC_STATUS seek_blob(P_SEEK*, PACKET*);
|
||||
ISC_STATUS send_msg(P_DATA*, PACKET*);
|
||||
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_start(P_INFO*, 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_transaction(P_OP, P_STTR*, PACKET*);
|
||||
ISC_STATUS transact_request(P_TRRQ *, PACKET*);
|
||||
|
||||
};
|
||||
|
||||
// port_flags
|
||||
|
@ -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_next(SERVER_REQ, SERVER_REQ*);
|
||||
#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
|
||||
static void aux_connect(rem_port*, P_REQ*, PACKET*);
|
||||
#endif
|
||||
@ -644,23 +653,23 @@ static bool accept_connection(rem_port* port,
|
||||
* 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;
|
||||
P_ACPT* accept = &send->p_acpt;
|
||||
USHORT weight = 0;
|
||||
|
||||
if (!port->accept(connect)) {
|
||||
port->send(send);
|
||||
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;
|
||||
|
||||
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_VERSION8 ||
|
||||
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
|
||||
|| protocol->p_cnct_version == PROTOCOL_SCROLLABLE_CURSORS
|
||||
#endif
|
||||
@ -702,11 +712,11 @@ static bool accept_connection(rem_port* port,
|
||||
|
||||
/* and modify the version string to reflect the chosen protocol */
|
||||
|
||||
TEXT buffer[64];
|
||||
sprintf(buffer, "%s/P%d", port->port_version->str_data,
|
||||
port->port_protocol);
|
||||
Firebird::string buffer;
|
||||
buffer.printf("%s/P%d", port->port_version->str_data,
|
||||
port->port_protocol & FB_PROTOCOL_MASK);
|
||||
ALLR_free(port->port_version);
|
||||
port->port_version = REMOTE_make_string(buffer);
|
||||
port->port_version = REMOTE_make_string(buffer.c_str());
|
||||
|
||||
if (architecture == ARCHITECTURE)
|
||||
port->port_flags |= PORT_symmetric;
|
||||
@ -889,9 +899,10 @@ static void addClumplets(Firebird::ClumpletWriter& dpb_buffer,
|
||||
}
|
||||
}
|
||||
|
||||
static ISC_STATUS attach_database(
|
||||
rem_port* port,
|
||||
P_OP operation, P_ATCH * attach, PACKET* send)
|
||||
static void attach_database(rem_port* port,
|
||||
P_OP operation,
|
||||
P_ATCH * attach,
|
||||
PACKET* send)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -903,10 +914,6 @@ static ISC_STATUS attach_database(
|
||||
* 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 USHORT l = attach->p_atch_file.cstr_length;
|
||||
|
||||
@ -920,6 +927,79 @@ static ISC_STATUS attach_database(
|
||||
else
|
||||
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
|
||||
rem_str* string = port->port_user_name;
|
||||
if (string) {
|
||||
@ -970,7 +1050,12 @@ static ISC_STATUS attach_database(
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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)
|
||||
{
|
||||
/**************************************
|
||||
@ -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;
|
||||
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,
|
||||
attach->p_atch_dpb.cstr_address, attach->p_atch_dpb.cstr_length, isc_spb_current_version);
|
||||
#ifdef TRUSTED_AUTH
|
||||
// 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
|
||||
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_service_attach(status_vector,
|
||||
service_length,
|
||||
reinterpret_cast<const char*>(service_name),
|
||||
service_name,
|
||||
&handle,
|
||||
spb.getBufferLength(),
|
||||
reinterpret_cast<const char*>(spb.getBuffer()));
|
||||
@ -4636,6 +4866,8 @@ ISC_STATUS rem_port::service_attach(P_ATCH* attach, PACKET* sendL)
|
||||
|
||||
if (!status_vector[1]) {
|
||||
RDB rdb = (RDB) ALLR_block(type_rdb, 0);
|
||||
if (rdb)
|
||||
{
|
||||
this->port_context = rdb;
|
||||
#ifdef DEBUG_REMOTE_MEMORY
|
||||
printf("attach_service(server) allocate rdb %x\n", rdb);
|
||||
@ -4644,6 +4876,13 @@ ISC_STATUS rem_port::service_attach(P_ATCH* attach, PACKET* sendL)
|
||||
rdb->rdb_handle = handle;
|
||||
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);
|
||||
}
|
||||
|
@ -286,10 +286,11 @@ rem_port* XNET_analyze(Firebird::PathName& file_name,
|
||||
{
|
||||
REMOTE_PROTOCOL(PROTOCOL_VERSION7, ptype_rpc, MAX_PTYPE, 1),
|
||||
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
|
||||
,
|
||||
REMOTE_PROTOCOL(PROTOCOL_SCROLLABLE_CURSORS, ptype_rpc, MAX_PTYPE, 4)
|
||||
REMOTE_PROTOCOL(PROTOCOL_SCROLLABLE_CURSORS, ptype_rpc, MAX_PTYPE, 99)
|
||||
#endif
|
||||
};
|
||||
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...
|
||||
|
||||
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);
|
||||
port->port_version = REMOTE_make_string(temp.c_str());
|
||||
|
@ -281,16 +281,28 @@ int common_main(int argc,
|
||||
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
|
||||
|
||||
if (user_data->dba_user_name_entered) {
|
||||
#ifdef TRUSTED_SERVICES
|
||||
if (user_data->dba_trust_user_name_entered)
|
||||
{
|
||||
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,
|
||||
user_data->dba_password, strlen(user_data->dba_password));
|
||||
}
|
||||
}
|
||||
|
||||
if (user_data->sql_role_name_entered) {
|
||||
dpb.insertString(isc_dpb_sql_role_name,
|
||||
@ -698,6 +710,12 @@ static bool get_switches(
|
||||
strncpy(user_data->sql_role_name, string, sizeof(user_data->sql_role_name));
|
||||
user_data->sql_role_name_entered = true;
|
||||
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_0:
|
||||
#ifdef SERVICE_THREAD
|
||||
@ -799,6 +817,9 @@ static bool get_switches(
|
||||
case IN_SW_GSEC_MNAME:
|
||||
case IN_SW_GSEC_LNAME:
|
||||
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_PASSWORD:
|
||||
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[0] = '\0';
|
||||
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:
|
||||
if (user_data->dba_password_specified) {
|
||||
err_msg_no = GsecMsg80;
|
||||
|
@ -91,6 +91,11 @@ struct internal_user_data {
|
||||
TEXT dba_user_name [USER_NAME_LEN]; /* the user's name */
|
||||
bool dba_user_name_entered; /* user name entered 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 */
|
||||
bool dba_password_entered; /* user name entered flag */
|
||||
bool dba_password_specified; /* database specified flag */
|
||||
|
@ -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_AMBIG = 20; /* ambiguous switch */
|
||||
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 [] = {
|
||||
@ -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_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 */
|
||||
#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 */
|
||||
};
|
||||
|
||||
|
@ -326,8 +326,15 @@ int CLIB_ROUTINE main(int argc, char** argv)
|
||||
bool sw_nocreation = false;
|
||||
isc_db_handle db_handle = 0;
|
||||
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::putSpecific(tddba, &thd_context);
|
||||
@ -403,9 +410,6 @@ int CLIB_ROUTINE main(int argc, char** argv)
|
||||
}
|
||||
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;
|
||||
++argv;
|
||||
while (argv < end) {
|
||||
@ -449,12 +453,18 @@ int CLIB_ROUTINE main(int argc, char** argv)
|
||||
break;
|
||||
case IN_SW_DBA_USERNAME:
|
||||
if (argv < end)
|
||||
strcpy((char*) username, *argv++);
|
||||
strncpy((char*) username, *argv++, sizeof(user_buff) - 1);
|
||||
break;
|
||||
case IN_SW_DBA_PASSWORD:
|
||||
if (argv < end)
|
||||
strcpy((char*) password, *argv++);
|
||||
strncpy((char*) password, *argv++, sizeof(pass_buff) - 1);
|
||||
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:
|
||||
sw_system = true;
|
||||
break;
|
||||
@ -656,13 +666,21 @@ int CLIB_ROUTINE main(int argc, char** argv)
|
||||
dpb.insertTag(isc_dpb_gstat_attach);
|
||||
dpb.insertTag(isc_dpb_no_garbage_collect);
|
||||
|
||||
if (*username) {
|
||||
if (*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,
|
||||
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(),
|
||||
reinterpret_cast<const char*>(dpb.getBuffer()));
|
||||
|
@ -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_RELATION = 11; /* analyze specific relations */
|
||||
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 [] = {
|
||||
{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 */
|
||||
// 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 */
|
||||
#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 */
|
||||
};
|
||||
#endif /* DBA_DBASWI_H */
|
||||
|
Loading…
Reference in New Issue
Block a user