8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-24 20:43:04 +01:00

Implement improvement CORE-2452 : Add Role Name in input parameters for EXECUTE STATEMENT

This commit is contained in:
hvlad 2009-05-14 10:21:47 +00:00
parent 7012672b67
commit 9a749a272f
15 changed files with 76 additions and 37 deletions

View File

@ -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];

View File

@ -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,

View File

@ -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); }

View File

@ -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";

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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);
}

View File

@ -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;

View File

@ -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()

View File

@ -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; }

View File

@ -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};
{

View File

@ -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);

View File

@ -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);

View File

@ -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;