mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-24 01:23:03 +01:00
CLIENT_ADDRESS and NETWORK_PROTOCOL variables support
This commit is contained in:
parent
4e7a45d022
commit
55c4e0ac85
@ -59,6 +59,8 @@ static const char
|
||||
|
||||
// System variables names
|
||||
static const char
|
||||
NETWORK_PROTOCOL_NAME[] = "NETWORK_PROTOCOL",
|
||||
CLIENT_ADDRESS_NAME[] = "CLIENT_ADDRESS",
|
||||
DATABASE_NAME[] = "DB_NAME",
|
||||
ISOLATION_LEVEL_NAME[] = "ISOLATION_LEVEL",
|
||||
TRANSACTION_ID_NAME[] = "TRANSACTION_ID",
|
||||
@ -171,6 +173,22 @@ vary* get_context(const vary* ns_vary, const vary* name_vary)
|
||||
// Handle system variables
|
||||
if (ns_str == SYSTEM_NAMESPACE)
|
||||
{
|
||||
if (name_str == NETWORK_PROTOCOL_NAME)
|
||||
{
|
||||
if (att->att_network_protocol.isEmpty())
|
||||
return NULL;
|
||||
|
||||
return make_result_str(att->att_network_protocol);
|
||||
}
|
||||
|
||||
if (name_str == CLIENT_ADDRESS_NAME)
|
||||
{
|
||||
if (att->att_remote_address.isEmpty())
|
||||
return NULL;
|
||||
|
||||
return make_result_str(att->att_remote_address);
|
||||
}
|
||||
|
||||
if (name_str == DATABASE_NAME)
|
||||
{
|
||||
return make_result_str(dbb->dbb_database_name.c_str(),
|
||||
|
@ -33,7 +33,7 @@
|
||||
*
|
||||
*/
|
||||
/*
|
||||
$Id: ibase.h,v 1.95 2004-11-07 14:50:31 alexpeshkoff Exp $
|
||||
$Id: ibase.h,v 1.96 2004-11-26 01:00:42 skidder Exp $
|
||||
*/
|
||||
|
||||
#ifndef JRD_IBASE_H
|
||||
@ -1238,10 +1238,54 @@ int ISC_EXPORT isc_get_client_minor_version ();
|
||||
#define isc_dpb_sql_dialect 63
|
||||
#define isc_dpb_set_db_readonly 64
|
||||
#define isc_dpb_set_db_sql_dialect 65
|
||||
#define isc_dpb_gfix_attach 66
|
||||
#define isc_dpb_gstat_attach 67
|
||||
#define isc_dpb_set_db_charset 68
|
||||
#define isc_dpb_gfix_attach 66
|
||||
#define isc_dpb_gstat_attach 67
|
||||
#define isc_dpb_set_db_charset 68
|
||||
#define isc_dpb_gsec_attach 69
|
||||
#define isc_dpb_address_path 70
|
||||
|
||||
/**************************************************/
|
||||
/* clumplet tags used inside isc_dpb_address_path */
|
||||
/**************************************************/
|
||||
|
||||
/* Format of this clumplet is the following:
|
||||
|
||||
<address-path-clumplet> ::=
|
||||
isc_dpb_address_path <byte-clumplet-length> <address-stack>
|
||||
|
||||
<address-stack> ::=
|
||||
<address-descriptor> |
|
||||
<address-stack> <address-descriptor>
|
||||
|
||||
<address-descriptor> ::=
|
||||
isc_dpb_address <byte-clumplet-length> <address-elements>
|
||||
|
||||
<address-elements> ::=
|
||||
<address-element> |
|
||||
<address-elements> <address-element>
|
||||
|
||||
<address-element> ::=
|
||||
isc_dpb_addr_protocol <byte-clumplet-length> <protocol-string> |
|
||||
isc_dpb_addr_endpoint <byte-clumplet-length> <remote-endpoint-string>
|
||||
|
||||
<protocol-string> ::=
|
||||
"TCPv4" |
|
||||
"TCPv6" |
|
||||
"XNET" |
|
||||
"WNET" |
|
||||
....
|
||||
|
||||
<remote-endpoint-string> ::=
|
||||
<IPv4-address> | // such as "172.20.1.1"
|
||||
<IPv6-address> | // such as "2001:0:13FF:09FF::1"
|
||||
<xnet-process-id> | // such as "17864"
|
||||
...
|
||||
*/
|
||||
|
||||
#define isc_dpb_address 1
|
||||
|
||||
#define isc_dpb_addr_protocol 1
|
||||
#define isc_dpb_addr_endpoint 2
|
||||
|
||||
/*********************************/
|
||||
/* isc_dpb_verify specific flags */
|
||||
|
@ -330,6 +330,8 @@ public:
|
||||
Firebird::string dpb_gbak_attach;
|
||||
Firebird::PathName dpb_working_directory;
|
||||
Firebird::string dpb_set_db_charset;
|
||||
Firebird::string dpb_network_protocol;
|
||||
Firebird::string dpb_remote_address;
|
||||
public:
|
||||
DatabaseOptions()
|
||||
{
|
||||
@ -692,6 +694,8 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
|
||||
|
||||
tdbb->tdbb_attachment = attachment = FB_NEW(*dbb->dbb_permanent) Attachment(dbb);
|
||||
attachment->att_filename = expanded_name;
|
||||
attachment->att_network_protocol = options.dpb_network_protocol;
|
||||
attachment->att_remote_address = options.dpb_remote_address;
|
||||
|
||||
attachment->att_next = dbb->dbb_attachments;
|
||||
dbb->dbb_attachments = attachment;
|
||||
@ -1802,6 +1806,8 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status,
|
||||
|
||||
tdbb->tdbb_attachment = attachment = FB_NEW(*dbb->dbb_permanent) Attachment(dbb);
|
||||
attachment->att_filename = expanded_name;
|
||||
attachment->att_network_protocol = options.dpb_network_protocol;
|
||||
attachment->att_remote_address = options.dpb_remote_address;
|
||||
attachment->att_next = dbb->dbb_attachments;
|
||||
dbb->dbb_attachments = attachment;
|
||||
dbb->dbb_flags &= ~DBB_being_opened;
|
||||
@ -5198,6 +5204,34 @@ void DatabaseOptions::get(const UCHAR* dpb, USHORT dpb_length)
|
||||
rdr.getString(dpb_set_db_charset);
|
||||
break;
|
||||
|
||||
case isc_dpb_address_path: {
|
||||
Firebird::ClumpletReader address_stack(false,
|
||||
rdr.getBytes(), rdr.getClumpLength());
|
||||
while (!address_stack.isEof()) {
|
||||
if (address_stack.getClumpTag() != isc_dpb_address) {
|
||||
address_stack.moveNext();
|
||||
continue;
|
||||
}
|
||||
Firebird::ClumpletReader address(false,
|
||||
address_stack.getBytes(), address_stack.getClumpLength());
|
||||
while (!address.isEof()) {
|
||||
switch (address.getClumpTag()) {
|
||||
case isc_dpb_addr_protocol:
|
||||
address.getString(dpb_network_protocol);
|
||||
break;
|
||||
case isc_dpb_addr_endpoint:
|
||||
address.getString(dpb_remote_address);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
address.moveNext();
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -433,7 +433,9 @@ public:
|
||||
att_lc_messages(*dbb->dbb_permanent),
|
||||
att_working_directory(*dbb->dbb_permanent),
|
||||
att_filename(*dbb->dbb_permanent),
|
||||
att_context_vars(*dbb->dbb_permanent) { }
|
||||
att_context_vars(*dbb->dbb_permanent),
|
||||
att_network_protocol(*dbb->dbb_permanent),
|
||||
att_remote_address(*dbb->dbb_permanent) { }
|
||||
/* Attachment()
|
||||
: att_database(0),
|
||||
att_next(0),
|
||||
@ -495,6 +497,8 @@ public:
|
||||
Firebird::PathName att_filename; // alias used to attach the database
|
||||
Firebird::TimeStamp att_timestamp; // connection date and time
|
||||
Firebird::StringMap att_context_vars; // Context variables for the connection
|
||||
Firebird::string att_network_protocol; // Network protocol used by client for connection
|
||||
Firebird::string att_remote_address; // Protocol-specific addess of remote client
|
||||
};
|
||||
|
||||
|
||||
|
@ -41,7 +41,7 @@
|
||||
*
|
||||
*/
|
||||
/*
|
||||
$Id: inet.cpp,v 1.128 2004-11-16 06:16:19 robocop Exp $
|
||||
$Id: inet.cpp,v 1.129 2004-11-26 01:01:16 skidder Exp $
|
||||
*/
|
||||
#include "firebird.h"
|
||||
#include <stdio.h>
|
||||
@ -1274,6 +1274,25 @@ static int accept_connection(rem_port* port,
|
||||
temp.printf("%s.%ld.%ld", name, eff_gid, eff_uid);
|
||||
port->port_user_name = REMOTE_make_string(temp.c_str());
|
||||
|
||||
port->port_protocol_str = REMOTE_make_string("TCPv4");
|
||||
|
||||
struct sockaddr_in address;
|
||||
socklen_t l = sizeof(address);
|
||||
|
||||
inet_zero((SCHAR *) &address, sizeof(address));
|
||||
int status = getpeername((SOCKET) port->port_handle, (struct sockaddr *) &address, &l);
|
||||
if (status == 0) {
|
||||
Firebird::string addr_str;
|
||||
UCHAR* ip = (UCHAR*) &address.sin_addr;
|
||||
addr_str.printf(
|
||||
"%d.%d.%d.%d",
|
||||
static_cast<int>(ip[0]),
|
||||
static_cast<int>(ip[1]),
|
||||
static_cast<int>(ip[2]),
|
||||
static_cast<int>(ip[3]) );
|
||||
port->port_address_str = REMOTE_make_string(addr_str.c_str());
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -1883,6 +1902,12 @@ static void cleanup_port( rem_port* port)
|
||||
if (port->port_object_vector)
|
||||
ALLR_free((UCHAR *) port->port_object_vector);
|
||||
|
||||
if (port->port_protocol_str)
|
||||
ALLR_free((UCHAR *) port->port_protocol_str);
|
||||
|
||||
if (port->port_address_str)
|
||||
ALLR_free((UCHAR *) port->port_address_str);
|
||||
|
||||
#ifdef DEBUG_XDR_MEMORY
|
||||
if (port->port_packet_vector)
|
||||
ALLR_free((UCHAR *) port->port_packet_vector);
|
||||
|
@ -621,6 +621,10 @@ static int accept_connection( rem_port* port, P_CNCT * cnct)
|
||||
id += *id + 1;
|
||||
}
|
||||
|
||||
// NS: Put in connection address. I have no good idea where to get an
|
||||
// address of the remote end of named pipe so let's live without it for now
|
||||
port->port_protocol_str = REMOTE_make_string("WNET");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -914,6 +918,12 @@ static void cleanup_port( rem_port* port)
|
||||
if (port->port_user_name)
|
||||
ALLR_free((UCHAR *) port->port_user_name);
|
||||
|
||||
if (port->port_protocol_str)
|
||||
ALLR_free((UCHAR *) port->port_protocol_str);
|
||||
|
||||
if (port->port_address_str)
|
||||
ALLR_free((UCHAR *) port->port_address_str);
|
||||
|
||||
if (port->port_host)
|
||||
ALLR_free((UCHAR *) port->port_host);
|
||||
|
||||
|
@ -416,6 +416,8 @@ struct rem_port
|
||||
rem_str* port_connection; /* Name of connection */
|
||||
rem_str* port_user_name;
|
||||
rem_str* port_passwd;
|
||||
rem_str* port_protocol_str; // String containing protocol name for this port
|
||||
rem_str* port_address_str; // Protocol-specific address string for the port
|
||||
rpr* port_rpr; /* port stored procedure reference */
|
||||
rsr* port_statement; /* Statement for execute immediate */
|
||||
rmtque* port_receive_rmtque; /* for client, responses waiting */
|
||||
|
@ -54,6 +54,7 @@
|
||||
#include "../jrd/thread_proto.h"
|
||||
#include "../jrd/why_proto.h"
|
||||
#include "../common/classes/semaphore.h"
|
||||
#include "../common/classes/ClumpletWriter.h"
|
||||
#ifdef DEBUG
|
||||
#include "gen/iberror.h"
|
||||
#endif
|
||||
@ -750,57 +751,79 @@ static ISC_STATUS attach_database(
|
||||
* Process an attach or create packet.
|
||||
*
|
||||
**************************************/
|
||||
UCHAR new_dpb_buffer[512];
|
||||
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;
|
||||
|
||||
// CVC: A false sense of constness is worse than no const at all.
|
||||
// Make "dpb" non const until we fix this instead of throwing constness later.
|
||||
UCHAR* dpb = attach->p_atch_dpb.cstr_address;
|
||||
// NS: Claudio, could you please remove the comment if it doesn't apply anymore?
|
||||
|
||||
const UCHAR* dpb = attach->p_atch_dpb.cstr_address;
|
||||
USHORT dl = attach->p_atch_dpb.cstr_length;
|
||||
|
||||
/* If we have user identification, append it to database parameter block */
|
||||
|
||||
Firebird::ClumpletWriter dpb_buffer(true, MAX_SSHORT);
|
||||
|
||||
UCHAR* new_dpb = new_dpb_buffer;
|
||||
if (dl)
|
||||
dpb_buffer.reset(dpb, dl);
|
||||
else
|
||||
dpb_buffer.reset(isc_dpb_version1);
|
||||
|
||||
// If we have user identification, append it to database parameter block
|
||||
rem_str* string = port->port_user_name;
|
||||
if (string) {
|
||||
if ((size_t)(dl + 3 + string->str_length) > sizeof(new_dpb_buffer))
|
||||
new_dpb = ALLR_alloc((SLONG) (dl + 3 + string->str_length));
|
||||
UCHAR* p = new_dpb;
|
||||
if (dl) {
|
||||
for (const UCHAR* const end = dpb + dl; dpb < end;)
|
||||
*p++ = *dpb++;
|
||||
}
|
||||
else
|
||||
*p++ = isc_dpb_version1;
|
||||
*p++ = isc_dpb_sys_user_name;
|
||||
*p++ = (UCHAR) string->str_length;
|
||||
dpb = (UCHAR *) string->str_data;
|
||||
for (const UCHAR* const end = dpb + string->str_length; dpb < end;)
|
||||
*p++ = *dpb++;
|
||||
dpb = new_dpb;
|
||||
dl = p - new_dpb;
|
||||
dpb_buffer.setCurOffset(dpb_buffer.getBufferLength());
|
||||
dpb_buffer.insertString(isc_dpb_sys_user_name,
|
||||
string->str_data, string->str_length);
|
||||
}
|
||||
|
||||
// Now, insert remote endpoint data into DPB address stack
|
||||
dpb_buffer.setCurOffset(1);
|
||||
while (!dpb_buffer.isEof() && dpb_buffer.getClumpTag() != isc_dpb_address_path)
|
||||
dpb_buffer.moveNext();
|
||||
|
||||
Firebird::ClumpletWriter address_stack_buffer(false, MAX_UCHAR - 2);
|
||||
if (!dpb_buffer.isEof()) {
|
||||
address_stack_buffer.reset(dpb_buffer.getBytes(), dpb_buffer.getClumpLength());
|
||||
dpb_buffer.deleteClumplet();
|
||||
}
|
||||
|
||||
Firebird::ClumpletWriter address_record(false, MAX_UCHAR - 2);
|
||||
if (port->port_protocol_str)
|
||||
address_record.insertString(isc_dpb_addr_protocol,
|
||||
port->port_protocol_str->str_data, port->port_protocol_str->str_length);
|
||||
if (port->port_address_str)
|
||||
address_record.insertString(isc_dpb_addr_endpoint,
|
||||
port->port_address_str->str_data, port->port_address_str->str_length);
|
||||
|
||||
// We always insert remote address descriptor as a first element
|
||||
// of appropriate clumplet so user cannot fake it and engine may somewhat trust it.
|
||||
fb_assert(address_stack_buffer.getCurOffset() == 0);
|
||||
address_stack_buffer.insertBytes(isc_dpb_address,
|
||||
address_record.getBuffer(), address_record.getBufferLength());
|
||||
|
||||
dpb_buffer.insertBytes(isc_dpb_address_path,
|
||||
address_stack_buffer.getBuffer(), address_stack_buffer.getBufferLength());
|
||||
|
||||
/* Disable remote gsec attachments */
|
||||
for (dpb_buffer.setCurOffset(1); !dpb_buffer.isEof(); ) {
|
||||
if (dpb_buffer.getClumpTag() == isc_dpb_gsec_attach)
|
||||
dpb_buffer.deleteClumplet();
|
||||
else
|
||||
dpb_buffer.moveNext();
|
||||
}
|
||||
|
||||
dpb = dpb_buffer.getBuffer();
|
||||
dl = dpb_buffer.getBufferLength();
|
||||
|
||||
/* See if user has specified parameters relevant to the connection,
|
||||
they will be stuffed in the DPB if so. */
|
||||
REMOTE_get_timeout_params(port, dpb, dl);
|
||||
|
||||
/* Disable remote gsec attachments */
|
||||
UCHAR* p = dpb;
|
||||
const UCHAR* const end = dpb + dl;
|
||||
while (p < end)
|
||||
{
|
||||
if (p[0] == isc_dpb_gsec_attach && p[1])
|
||||
{
|
||||
p[2] = 0;
|
||||
}
|
||||
p += (2 + p[1]);
|
||||
}
|
||||
|
||||
THREAD_EXIT();
|
||||
if (operation == op_attach)
|
||||
{
|
||||
@ -814,10 +837,6 @@ static ISC_STATUS attach_database(
|
||||
}
|
||||
THREAD_ENTER();
|
||||
|
||||
if (new_dpb != new_dpb_buffer) {
|
||||
ALLR_free(new_dpb);
|
||||
}
|
||||
|
||||
if (!status_vector[1])
|
||||
{
|
||||
RDB rdb = (RDB) ALLR_block(type_rdb, 0);
|
||||
@ -3228,10 +3247,10 @@ bool process_packet(rem_port* port,
|
||||
ThreadData::restoreSpecific();
|
||||
|
||||
} // try
|
||||
catch (const std::exception&) {
|
||||
/* There must be something better to do here. BUT WHAT? */
|
||||
catch (const std::exception& ex) {
|
||||
Firebird::stuff_exception(tdrdb->trdb_status_vector, ex);
|
||||
|
||||
gds__log("SERVER/process_packet: out of memory", 0);
|
||||
gds__log_status("unknown, SERVER/process_packet", tdrdb->trdb_status_vector);
|
||||
|
||||
/* It would be nice to log an error to the user, instead of just terminating them! */
|
||||
port->send_response(sendL, 0, 0, tdrdb->trdb_status_vector);
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "../jrd/isc_proto.h"
|
||||
#include "../jrd/sch_proto.h"
|
||||
#include "../jrd/thread_proto.h"
|
||||
#include "fb_string.h"
|
||||
#include <time.h>
|
||||
|
||||
#ifdef WIN_NT
|
||||
@ -825,6 +826,19 @@ static int accept_connection(rem_port* port, P_CNCT * cnct)
|
||||
* Accept an incoming request for connection.
|
||||
*
|
||||
**************************************/
|
||||
port->port_protocol_str = REMOTE_make_string("XNET");
|
||||
|
||||
// Use client process ID as remote address for XNET protocol
|
||||
XCC xcc = (XCC) port->port_xcc;
|
||||
if (xcc) {
|
||||
XPS xps = (XPS) xcc->xcc_mapped_addr;
|
||||
if (xps) {
|
||||
Firebird::string address;
|
||||
address.printf("%u", xps->xps_client_proc_id);
|
||||
port->port_address_str = REMOTE_make_string(address.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -1300,6 +1314,14 @@ static void xnet_cleanup_port(rem_port* port)
|
||||
ALLR_free((UCHAR *) port->port_object_vector);
|
||||
}
|
||||
|
||||
if (port->port_protocol_str) {
|
||||
ALLR_free((UCHAR *) port->port_protocol_str);
|
||||
}
|
||||
|
||||
if (port->port_address_str) {
|
||||
ALLR_free((UCHAR *) port->port_address_str);
|
||||
}
|
||||
|
||||
#ifdef SUPERSERVER
|
||||
if (port->port_status_vector) {
|
||||
ALLR_free(port->port_status_vector);
|
||||
|
Loading…
Reference in New Issue
Block a user