mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-24 13:23:02 +01:00
Implement improvement CORE-2452 : Add Role Name in input parameters for EXECUTE STATEMENT
This commit is contained in:
parent
7012672b67
commit
9a749a272f
@ -1852,10 +1852,11 @@ static void gen_exec_stmt(CompiledStatement* statement, const dsql_nod* node)
|
||||
GEN_statement(statement, temp2);
|
||||
}
|
||||
|
||||
// external data source, user and password
|
||||
// external data source, user, password and role
|
||||
gen_optional_expr(statement, blr_exec_stmt_data_src, node->nod_arg[e_exec_stmt_data_src]);
|
||||
gen_optional_expr(statement, blr_exec_stmt_user, node->nod_arg[e_exec_stmt_user]);
|
||||
gen_optional_expr(statement, blr_exec_stmt_pwd, node->nod_arg[e_exec_stmt_pwd]);
|
||||
gen_optional_expr(statement, blr_exec_stmt_role, node->nod_arg[e_exec_stmt_role]);
|
||||
|
||||
// statement's transaction behavior
|
||||
temp = node->nod_arg[e_exec_stmt_tran];
|
||||
|
@ -369,12 +369,13 @@ enum nod_t
|
||||
nod_exec_stmt_datasrc,
|
||||
nod_exec_stmt_user,
|
||||
nod_exec_stmt_pwd,
|
||||
nod_exec_stmt_role,
|
||||
nod_exec_stmt_privs,
|
||||
nod_tran_params,
|
||||
nod_named_param,
|
||||
nod_dfl_collate,
|
||||
nod_class_node,
|
||||
nod_hidden_var
|
||||
nod_hidden_var // 300
|
||||
};
|
||||
|
||||
/* enumerations of the arguments to a node, offsets
|
||||
@ -445,6 +446,7 @@ enum node_args {
|
||||
e_exec_stmt_data_src,
|
||||
e_exec_stmt_user,
|
||||
e_exec_stmt_pwd,
|
||||
e_exec_stmt_role,
|
||||
e_exec_stmt_tran,
|
||||
e_exec_stmt_privs,
|
||||
e_exec_stmt_count,
|
||||
|
@ -1770,7 +1770,7 @@ exec_sql
|
||||
: EXECUTE STATEMENT exec_stmt_inputs exec_stmt_options
|
||||
{
|
||||
$$ = make_node (nod_exec_stmt, int (e_exec_stmt_count),
|
||||
($3)->nod_arg[0], ($3)->nod_arg[1], NULL, NULL, NULL, make_list($4), NULL, NULL, NULL, NULL, NULL);
|
||||
($3)->nod_arg[0], ($3)->nod_arg[1], NULL, NULL, NULL, make_list($4), NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
;
|
||||
|
||||
@ -1779,7 +1779,7 @@ exec_into
|
||||
INTO variable_list
|
||||
{
|
||||
$$ = make_node (nod_exec_stmt, int (e_exec_stmt_count),
|
||||
($3)->nod_arg[0], ($3)->nod_arg[1], make_list($6), NULL, NULL, make_list($4), NULL, NULL, NULL, NULL, NULL);
|
||||
($3)->nod_arg[0], ($3)->nod_arg[1], make_list($6), NULL, NULL, make_list($4), NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
;
|
||||
|
||||
@ -1789,7 +1789,7 @@ for_exec_into
|
||||
DO proc_block
|
||||
{
|
||||
$$ = make_node (nod_exec_stmt, int (e_exec_stmt_count),
|
||||
($5)->nod_arg[0], ($5)->nod_arg[1], make_list($8), $10, $1, make_list($6), NULL, NULL, NULL, NULL, NULL);
|
||||
($5)->nod_arg[0], ($5)->nod_arg[1], make_list($8), $10, $1, make_list($6), NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
;
|
||||
|
||||
@ -1840,6 +1840,7 @@ exec_stmt_option
|
||||
: ext_datasrc
|
||||
| ext_user
|
||||
| ext_pwd
|
||||
| ext_role
|
||||
| ext_tran
|
||||
| ext_privs
|
||||
;
|
||||
@ -1861,6 +1862,11 @@ ext_pwd
|
||||
{ $$ = make_node (nod_exec_stmt_pwd, 1, $2); }
|
||||
;
|
||||
|
||||
ext_role
|
||||
: ROLE value
|
||||
{ $$ = make_node (nod_exec_stmt_role, 1, $2); }
|
||||
;
|
||||
|
||||
ext_tran
|
||||
: WITH AUTONOMOUS TRANSACTION
|
||||
{ $$ = make_flag_node(nod_tran_params, NOD_TRAN_AUTONOMOUS, 1, NULL); }
|
||||
|
@ -1803,6 +1803,13 @@ dsql_nod* PASS1_statement(CompiledStatement* statement, dsql_nod* input)
|
||||
node->nod_arg[e_exec_stmt_pwd] = PASS1_node(statement, opt->nod_arg[0]);
|
||||
break;
|
||||
|
||||
case nod_exec_stmt_role:
|
||||
if (node->nod_arg[e_exec_stmt_role])
|
||||
dupClause = "ROLE";
|
||||
else
|
||||
node->nod_arg[e_exec_stmt_role] = PASS1_node(statement, opt->nod_arg[0]);
|
||||
break;
|
||||
|
||||
case nod_tran_params:
|
||||
if (node->nod_arg[e_exec_stmt_tran])
|
||||
dupClause = "TRANSACTION";
|
||||
|
@ -371,6 +371,7 @@
|
||||
#define blr_exec_stmt_in_params (unsigned char) 11 // not named input parameters
|
||||
#define blr_exec_stmt_in_params2 (unsigned char) 12 // named input parameters
|
||||
#define blr_exec_stmt_out_params (unsigned char) 13 // output parameters
|
||||
#define blr_exec_stmt_role (unsigned char) 14
|
||||
|
||||
#define blr_stmt_expr (unsigned char) 190
|
||||
#define blr_derived_expr (unsigned char) 191
|
||||
|
@ -1625,7 +1625,10 @@ static jrd_nod* execute_statement(thread_db* tdbb, jrd_req* request, jrd_nod* no
|
||||
Firebird::string sPwd;
|
||||
get_string(tdbb, request, node->nod_arg[e_exec_stmt_password], sPwd);
|
||||
|
||||
EDS::Connection* conn = EDS::Manager::getConnection(tdbb, sDataSrc, sUser, sPwd, tra_scope);
|
||||
Firebird::string sRole;
|
||||
get_string(tdbb, request, node->nod_arg[e_exec_stmt_role], sRole);
|
||||
|
||||
EDS::Connection* conn = EDS::Manager::getConnection(tdbb, sDataSrc, sUser, sPwd, sRole, tra_scope);
|
||||
|
||||
stmt = conn->createStatement(sSql);
|
||||
|
||||
|
@ -547,8 +547,9 @@ const int e_exec_stmt_stmt_sql = 0;
|
||||
const int e_exec_stmt_data_src = 1;
|
||||
const int e_exec_stmt_user = 2;
|
||||
const int e_exec_stmt_password = 3;
|
||||
const int e_exec_stmt_proc_block = 4;
|
||||
const int e_exec_stmt_fixed_count = 5;
|
||||
const int e_exec_stmt_role = 4;
|
||||
const int e_exec_stmt_proc_block = 5;
|
||||
const int e_exec_stmt_fixed_count = 6;
|
||||
|
||||
const int e_exec_stmt_extra_inputs = 0;
|
||||
const int e_exec_stmt_extra_input_names = 1;
|
||||
|
@ -103,7 +103,7 @@ Provider* Manager::getProvider(const string &prvName)
|
||||
}
|
||||
|
||||
Connection* Manager::getConnection(thread_db *tdbb, const string &dataSource,
|
||||
const string &user, const string &pwd, TraScope tra_scope)
|
||||
const string &user, const string &pwd, const string &role, TraScope tra_scope)
|
||||
{
|
||||
if (!m_initialized)
|
||||
{
|
||||
@ -144,7 +144,7 @@ Connection* Manager::getConnection(thread_db *tdbb, const string &dataSource,
|
||||
}
|
||||
|
||||
Provider* prv = getProvider(prvName);
|
||||
return prv->getConnection(tdbb, dbName, user, pwd, tra_scope);
|
||||
return prv->getConnection(tdbb, dbName, user, pwd, role, tra_scope);
|
||||
}
|
||||
|
||||
void Manager::jrdAttachmentEnd(thread_db *tdbb, Jrd::Attachment* att)
|
||||
@ -181,7 +181,7 @@ Provider::~Provider()
|
||||
}
|
||||
|
||||
Connection* Provider::getConnection(thread_db *tdbb, const string &dbName,
|
||||
const string &user, const string &pwd, TraScope tra_scope)
|
||||
const string &user, const string &pwd, const string &role, TraScope tra_scope)
|
||||
{
|
||||
MutexLockGuard guard(m_mutex);
|
||||
|
||||
@ -191,7 +191,7 @@ Connection* Provider::getConnection(thread_db *tdbb, const string &dbName,
|
||||
for (; conn_ptr < end; conn_ptr++)
|
||||
{
|
||||
Connection *conn = *conn_ptr;
|
||||
if (conn->isSameDatabase(tdbb, dbName, user, pwd) &&
|
||||
if (conn->isSameDatabase(tdbb, dbName, user, pwd, role) &&
|
||||
conn->isAvailable(tdbb, tra_scope))
|
||||
{
|
||||
return conn;
|
||||
@ -200,7 +200,7 @@ Connection* Provider::getConnection(thread_db *tdbb, const string &dbName,
|
||||
|
||||
Connection *conn = doCreateConnection();
|
||||
try {
|
||||
conn->attach(tdbb, dbName, user, pwd);
|
||||
conn->attach(tdbb, dbName, user, pwd, role);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
@ -289,16 +289,19 @@ Connection::~Connection()
|
||||
}
|
||||
|
||||
void Connection::generateDPB(thread_db *tdbb, ClumpletWriter &dpb,
|
||||
const string& /*dbName*/, const string &user, const string &pwd) const
|
||||
const string &user, const string &pwd, const string &role) const
|
||||
{
|
||||
dpb.reset(isc_dpb_version1);
|
||||
|
||||
Firebird::string &attUser = tdbb->getAttachment()->att_user->usr_user_name;
|
||||
string &attUser = tdbb->getAttachment()->att_user->usr_user_name;
|
||||
string &attRole = tdbb->getAttachment()->att_user->usr_sql_role_name;
|
||||
|
||||
if ((m_provider.getFlags() & prvTrustedAuth) &&
|
||||
(user.isEmpty() || user == attUser) && pwd.isEmpty())
|
||||
(user.isEmpty() || user == attUser) && pwd.isEmpty() &&
|
||||
(role.isEmpty() || role == attRole))
|
||||
{
|
||||
dpb.insertString(isc_dpb_trusted_auth, attUser);
|
||||
dpb.insertString(isc_dpb_trusted_role, attRole);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -308,6 +311,9 @@ void Connection::generateDPB(thread_db *tdbb, ClumpletWriter &dpb,
|
||||
if (!pwd.isEmpty()) {
|
||||
dpb.insertString(isc_dpb_password, pwd);
|
||||
}
|
||||
if (!role.isEmpty()) {
|
||||
dpb.insertString(isc_dpb_sql_role_name, role);
|
||||
}
|
||||
}
|
||||
|
||||
CharSet* const cs = INTL_charset_lookup(tdbb, tdbb->getAttachment()->att_charset);
|
||||
@ -317,13 +323,13 @@ void Connection::generateDPB(thread_db *tdbb, ClumpletWriter &dpb,
|
||||
}
|
||||
|
||||
bool Connection::isSameDatabase(thread_db *tdbb, const string &dbName,
|
||||
const string &user, const string &pwd) const
|
||||
const string &user, const string &pwd, const string &role) const
|
||||
{
|
||||
if (m_dbName != dbName)
|
||||
return false;
|
||||
|
||||
ClumpletWriter dpb(ClumpletReader::Tagged, MAX_DPB_SIZE, isc_dpb_version1);
|
||||
generateDPB(tdbb, dpb, dbName, user, pwd);
|
||||
generateDPB(tdbb, dpb, user, pwd, role);
|
||||
|
||||
return m_dpb.simpleCompare(dpb);
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ public:
|
||||
static Provider* getProvider(const Firebird::string &prvName);
|
||||
static Connection* getConnection(Jrd::thread_db *tdbb,
|
||||
const Firebird::string &dataSource, const Firebird::string &user,
|
||||
const Firebird::string &pwd, TraScope tra_scope);
|
||||
const Firebird::string &pwd, const Firebird::string &role, TraScope tra_scope);
|
||||
|
||||
// Notify providers when some jrd attachment is about to be released
|
||||
static void jrdAttachmentEnd(Jrd::thread_db *tdbb, Jrd::Attachment* att);
|
||||
@ -94,7 +94,8 @@ public:
|
||||
|
||||
// return existing or create new Connection
|
||||
virtual Connection* getConnection(Jrd::thread_db *tdbb, const Firebird::string &dbName,
|
||||
const Firebird::string &user, const Firebird::string &pwd, TraScope tra_scope);
|
||||
const Firebird::string &user, const Firebird::string &pwd, const Firebird::string &role,
|
||||
TraScope tra_scope);
|
||||
|
||||
// Connection gets unused, release it into pool or delete it completely
|
||||
virtual void releaseConnection(Jrd::thread_db *tdbb, Connection& conn, bool inPool = true);
|
||||
@ -156,7 +157,8 @@ public:
|
||||
Provider* getProvider() { return &m_provider; }
|
||||
|
||||
virtual void attach(Jrd::thread_db *tdbb, const Firebird::string &dbName,
|
||||
const Firebird::string &user, const Firebird::string &pwd) = 0;
|
||||
const Firebird::string &user, const Firebird::string &pwd,
|
||||
const Firebird::string &role) = 0;
|
||||
virtual void detach(Jrd::thread_db *tdbb);
|
||||
|
||||
virtual bool cancelExecution(Jrd::thread_db *tdbb) = 0;
|
||||
@ -172,7 +174,8 @@ public:
|
||||
virtual bool isConnected() const = 0;
|
||||
|
||||
virtual bool isSameDatabase(Jrd::thread_db *tdbb, const Firebird::string &dbName,
|
||||
const Firebird::string &user, const Firebird::string &pwd) const;
|
||||
const Firebird::string &user, const Firebird::string &pwd,
|
||||
const Firebird::string &role) const;
|
||||
|
||||
// Search for existing transaction of given scope, may return NULL.
|
||||
Transaction* findTransaction(Jrd::thread_db *tdbb, TraScope traScope) const;
|
||||
@ -203,8 +206,8 @@ public:
|
||||
|
||||
protected:
|
||||
void generateDPB(Jrd::thread_db *tdbb, Firebird::ClumpletWriter &dpb,
|
||||
const Firebird::string &dbName, const Firebird::string &user,
|
||||
const Firebird::string &pwd) const;
|
||||
const Firebird::string &user, const Firebird::string &pwd,
|
||||
const Firebird::string &role) const;
|
||||
|
||||
virtual Transaction* doCreateTransaction() = 0;
|
||||
virtual Statement* doCreateStatement() = 0;
|
||||
|
@ -112,14 +112,16 @@ InternalConnection::~InternalConnection()
|
||||
}
|
||||
|
||||
void InternalConnection::attach(thread_db *tdbb, const Firebird::string &dbName,
|
||||
const Firebird::string &user, const Firebird::string &pwd)
|
||||
const Firebird::string &user, const Firebird::string &pwd,
|
||||
const Firebird::string &role)
|
||||
{
|
||||
fb_assert(!m_attachment);
|
||||
Database* dbb = tdbb->getDatabase();
|
||||
fb_assert(dbName.isEmpty() || dbName == dbb->dbb_database_name.c_str());
|
||||
|
||||
Attachment* attachment = tdbb->getAttachment();
|
||||
if (user.isEmpty() || user == attachment->att_user->usr_user_name)
|
||||
if ((user.isEmpty() || user == attachment->att_user->usr_user_name) &&
|
||||
(role.isEmpty() || role == attachment->att_user->usr_sql_role_name))
|
||||
{
|
||||
m_isCurrent = true;
|
||||
m_attachment = attachment;
|
||||
@ -128,7 +130,7 @@ void InternalConnection::attach(thread_db *tdbb, const Firebird::string &dbName,
|
||||
{
|
||||
m_isCurrent = false;
|
||||
m_dbName = dbb->dbb_database_name.c_str();
|
||||
generateDPB(tdbb, m_dpb, m_dbName, user, pwd);
|
||||
generateDPB(tdbb, m_dpb, user, pwd, role);
|
||||
|
||||
ISC_STATUS_ARRAY status = {0};
|
||||
|
||||
@ -203,12 +205,13 @@ bool InternalConnection::isAvailable(thread_db *tdbb, TraScope /*traScope*/) con
|
||||
}
|
||||
|
||||
bool InternalConnection::isSameDatabase(thread_db *tdbb, const Firebird::string &dbName,
|
||||
const Firebird::string &user, const Firebird::string &pwd) const
|
||||
const Firebird::string &user, const Firebird::string &pwd,
|
||||
const Firebird::string &role) const
|
||||
{
|
||||
if (m_isCurrent)
|
||||
return (tdbb->getAttachment() == m_attachment);
|
||||
else
|
||||
return Connection::isSameDatabase(tdbb, dbName, user, pwd);
|
||||
return Connection::isSameDatabase(tdbb, dbName, user, pwd, role);
|
||||
}
|
||||
|
||||
Transaction* InternalConnection::doCreateTransaction()
|
||||
|
@ -64,7 +64,8 @@ protected:
|
||||
|
||||
public:
|
||||
virtual void attach(Jrd::thread_db *tdbb, const Firebird::string &dbName,
|
||||
const Firebird::string &user, const Firebird::string &pwd);
|
||||
const Firebird::string &user, const Firebird::string &pwd,
|
||||
const Firebird::string &role);
|
||||
|
||||
virtual bool cancelExecution(Jrd::thread_db *tdbb);
|
||||
|
||||
@ -73,7 +74,8 @@ public:
|
||||
virtual bool isConnected() const { return (m_attachment != 0); }
|
||||
|
||||
virtual bool isSameDatabase(Jrd::thread_db *tdbb, const Firebird::string &dbName,
|
||||
const Firebird::string &user, const Firebird::string &pwd) const;
|
||||
const Firebird::string &user, const Firebird::string &pwd,
|
||||
const Firebird::string &role) const;
|
||||
|
||||
bool isCurrent() const { return m_isCurrent; }
|
||||
|
||||
|
@ -103,10 +103,10 @@ IscConnection::~IscConnection()
|
||||
}
|
||||
|
||||
void IscConnection::attach(thread_db *tdbb, const string &dbName, const string &user,
|
||||
const string &pwd)
|
||||
const string &pwd, const string &role)
|
||||
{
|
||||
m_dbName = dbName;
|
||||
generateDPB(tdbb, m_dpb, dbName, user, pwd);
|
||||
generateDPB(tdbb, m_dpb, user, pwd, role);
|
||||
|
||||
ISC_STATUS_ARRAY status = {0};
|
||||
{
|
||||
|
@ -511,7 +511,8 @@ public:
|
||||
FB_API_HANDLE& getAPIHandle() { return m_handle; }
|
||||
|
||||
virtual void attach(Jrd::thread_db *tdbb, const Firebird::string &dbName,
|
||||
const Firebird::string &user, const Firebird::string &pwd);
|
||||
const Firebird::string &user, const Firebird::string &pwd,
|
||||
const Firebird::string &role);
|
||||
|
||||
virtual bool cancelExecution(Jrd::thread_db *tdbb);
|
||||
|
||||
|
@ -1589,9 +1589,7 @@ int API_ROUTINE gds__msg_open(void** handle, const TEXT* filename)
|
||||
}
|
||||
|
||||
if (header.msghdr_major_version != MSG_MAJOR_VERSION
|
||||
#if FB_MSG_MINOR_VERSION > 0
|
||||
|| header.msghdr_minor_version < MSG_MINOR_VERSION
|
||||
#endif
|
||||
|| header.msghdr_minor_version > MSG_MINOR_VERSION
|
||||
)
|
||||
{
|
||||
close(n);
|
||||
@ -3327,6 +3325,7 @@ static void blr_print_verb(gds_ctl* control, SSHORT level)
|
||||
case blr_exec_stmt_data_src:
|
||||
case blr_exec_stmt_user:
|
||||
case blr_exec_stmt_pwd:
|
||||
case blr_exec_stmt_role:
|
||||
offset = blr_print_line(control, offset);
|
||||
level++;
|
||||
blr_print_verb(control, level);
|
||||
|
@ -2844,6 +2844,10 @@ jrd_nod* PAR_parse_node(thread_db* tdbb, CompilerScratch* csb, USHORT expected)
|
||||
node->nod_arg[e_exec_stmt_password] = PAR_parse_node(tdbb, csb, VALUE);
|
||||
break;
|
||||
|
||||
case blr_exec_stmt_role:
|
||||
node->nod_arg[e_exec_stmt_role] = PAR_parse_node(tdbb, csb, VALUE);
|
||||
break;
|
||||
|
||||
case blr_exec_stmt_tran:
|
||||
PAR_syntax_error(csb, "external transaction parameters");
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user