Skip to content

Commit

Permalink
Implement improvement CORE-2452 : Add Role Name in input parameters f…
Browse files Browse the repository at this point in the history
…or EXECUTE STATEMENT
  • Loading branch information
hvlad committed May 14, 2009
1 parent 7012672 commit 9a749a2
Show file tree
Hide file tree
Showing 15 changed files with 76 additions and 37 deletions.
3 changes: 2 additions & 1 deletion src/dsql/gen.cpp
Expand Up @@ -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];
Expand Down
4 changes: 3 additions & 1 deletion src/dsql/node.h
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down
12 changes: 9 additions & 3 deletions src/dsql/parse.y
Expand Up @@ -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);
}
;

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

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

Expand Down Expand Up @@ -1840,6 +1840,7 @@ exec_stmt_option
: ext_datasrc
| ext_user
| ext_pwd
| ext_role
| ext_tran
| ext_privs
;
Expand All @@ -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); }
Expand Down
7 changes: 7 additions & 0 deletions src/dsql/pass1.cpp
Expand Up @@ -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";
Expand Down
1 change: 1 addition & 0 deletions src/jrd/blr.h
Expand Up @@ -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
Expand Down
5 changes: 4 additions & 1 deletion src/jrd/exe.cpp
Expand Up @@ -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);

Expand Down
5 changes: 3 additions & 2 deletions src/jrd/exe.h
Expand Up @@ -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;
Expand Down
26 changes: 16 additions & 10 deletions src/jrd/extds/ExtDS.cpp
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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);

Expand All @@ -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;
Expand All @@ -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 (...)
{
Expand Down Expand Up @@ -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
{
Expand All @@ -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);
Expand All @@ -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);
}
Expand Down
15 changes: 9 additions & 6 deletions src/jrd/extds/ExtDS.h
Expand Up @@ -65,7 +65,7 @@ class Manager : public Firebird::PermanentStorage
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);
Expand Down Expand Up @@ -94,7 +94,8 @@ class Provider : public Firebird::GlobalStorage

// 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);
Expand Down Expand Up @@ -156,7 +157,8 @@ class Connection : public Firebird::PermanentStorage
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;
Expand All @@ -172,7 +174,8 @@ class Connection : public Firebird::PermanentStorage
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;
Expand Down Expand Up @@ -203,8 +206,8 @@ class Connection : public Firebird::PermanentStorage

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;
Expand Down
13 changes: 8 additions & 5 deletions src/jrd/extds/InternalDS.cpp
Expand Up @@ -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;
Expand All @@ -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};

Expand Down Expand Up @@ -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()
Expand Down
6 changes: 4 additions & 2 deletions src/jrd/extds/InternalDS.h
Expand Up @@ -64,7 +64,8 @@ class InternalConnection : public Connection

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

Expand All @@ -73,7 +74,8 @@ class InternalConnection : public Connection
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; }

Expand Down
4 changes: 2 additions & 2 deletions src/jrd/extds/IscDS.cpp
Expand Up @@ -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};
{
Expand Down
3 changes: 2 additions & 1 deletion src/jrd/extds/IscDS.h
Expand Up @@ -511,7 +511,8 @@ class IscConnection : public Connection
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);

Expand Down
5 changes: 2 additions & 3 deletions src/jrd/gds.cpp
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
4 changes: 4 additions & 0 deletions src/jrd/par.cpp
Expand Up @@ -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;
Expand Down

0 comments on commit 9a749a2

Please sign in to comment.