6 #include "CoralBase/AttributeList.h"
7 #include "CoralBase/Attribute.h"
8 #include "CoralKernel/Context.h"
9 #include "CoralCommon/URIParser.h"
10 #include "RelationalAccess/AuthenticationCredentials.h"
11 #include "RelationalAccess/IBulkOperation.h"
12 #include "RelationalAccess/IConnection.h"
13 #include "RelationalAccess/ISession.h"
14 #include "RelationalAccess/IRelationalService.h"
15 #include "RelationalAccess/IRelationalDomain.h"
16 #include "RelationalAccess/ITransaction.h"
17 #include "RelationalAccess/ISchema.h"
18 #include "RelationalAccess/ITable.h"
19 #include "RelationalAccess/TableDescription.h"
20 #include "RelationalAccess/ITableDataEditor.h"
21 #include "RelationalAccess/ITablePrivilegeManager.h"
22 #include "RelationalAccess/IQuery.h"
23 #include "RelationalAccess/ICursor.h"
25 #include "RelationalAccess/AuthenticationCredentials.h"
38 for (
auto iData = m_data.begin(); iData != m_data.end(); ++iData)
54 std::map<std::pair<std::string, std::string>, coral::AuthenticationCredentials*>::iterator iData =
56 if (iData == m_data.end()) {
57 iData = m_data.insert(std::make_pair(connKey,
new coral::AuthenticationCredentials(
serviceName))).first;
59 iData = m_data.insert(std::make_pair(connKey,
new coral::AuthenticationCredentials(
serviceName))).first;
60 iData->second->registerItem(itemName, itemValue);
74 std::map<std::pair<std::string, std::string>, coral::AuthenticationCredentials*>::iterator iData =
76 if (iData != m_data.end()) {
78 m_data.erase(connKey);
80 iData = m_data.insert(std::make_pair(connKey,
new coral::AuthenticationCredentials(
serviceName))).first;
81 iData->second->registerItem(coral::IAuthenticationCredentials::userItem(),
userName);
82 iData->second->registerItem(coral::IAuthenticationCredentials::passwordItem(),
password);
86 for (
std::map<std::pair<std::string, std::string>, coral::AuthenticationCredentials*>::const_iterator iData =
88 iData !=
data.m_data.end();
90 registerCredentials(iData->first.first,
92 iData->second->valueForItem(coral::IAuthenticationCredentials::userItem()),
93 iData->second->valueForItem(coral::IAuthenticationCredentials::passwordItem()));
104 const coral::IAuthenticationCredentials*
ret =
nullptr;
106 std::map<std::pair<std::string, std::string>, coral::AuthenticationCredentials*>::const_iterator iData =
107 m_data.find(connKey);
108 if (iData != m_data.end()) {
114 const std::map<std::pair<std::string, std::string>, coral::AuthenticationCredentials*>&
152 if (schemaVersion.empty())
191 void start(
bool readOnly =
true) { m_store.startSession(readOnly); }
192 void close() { m_store.closeSession(); }
206 coral::ISchema& schema,
210 coral::AttributeList readBuff;
215 coral::AttributeList whereData;
219 query->defineOutput(readBuff);
224 query->setCondition(whereClause, whereData);
225 coral::ICursor& cursor =
query->execute();
229 const coral::AttributeList& row = cursor.currentRow();
248 coral::ISchema& schema,
252 coral::AttributeList readBuff;
258 coral::AttributeList whereData;
262 query->defineOutput(readBuff);
268 query->setCondition(whereClause, whereData);
269 coral::ICursor& cursor =
query->execute();
272 const coral::AttributeList& row = cursor.currentRow();
291 coral::ISchema& schema,
297 coral::AttributeList readBuff;
301 coral::AttributeList whereData;
305 whereData[
P_ID_COL].data<
int>() = principalId;
308 std::stringstream whereClause;
312 query->defineOutput(readBuff);
316 query->setCondition(whereClause.str(), whereData);
317 coral::ICursor& cursor =
query->execute();
320 const coral::AttributeList& row = cursor.currentRow();
330 coral::ISchema& schema,
335 query->limitReturnedRows(1, 0);
338 query->setForUpdate();
340 coral::AttributeList rowData;
343 query->setCondition(whereClause, rowData);
344 coral::ICursor& cursor =
query->execute();
346 value = cursor.currentRow().begin()->data<
int>() + 1;
352 coral::AttributeList updateData;
357 coral::AttributeList::iterator iAttribute = updateData.begin();
360 iAttribute->data<
int>() =
value;
361 schema.tableHandle(
tname(
SEQUENCE_TABLE, schemaVersion)).dataEditor().updateRows(setClause, whClause, updateData);
366 coral::ISchema& schema,
371 std::stringstream&
log) {
380 int principalId = princData.
id;
384 coral::ITableDataEditor& editor = schema.tableHandle(authentication_table_name).dataEditor();
386 log <<
"Updating existing principal " << principalName <<
" (id: " << principalId <<
" )" << std::endl;
388 coral::AttributeList updateData;
397 std::stringstream setClause;
402 editor.updateRows(setClause.str(), whereClause, updateData);
405 principalKey = adminKey;
410 coral::ITableDataEditor& editor0 = schema.tableHandle(authentication_table_name).dataEditor();
413 throwException(
"Can't find " + authentication_table_name +
" sequence.",
"CredentialStore::updatePrincipal");
414 log <<
"Creating new principal " << principalName <<
" (id: " << principalId <<
" )" << std::endl;
415 coral::AttributeList authData;
416 editor0.rowBuffer(authData);
422 editor0.insertRow(authData);
425 return std::make_pair(principalId, principalKey);
429 coral::ISchema& schema,
436 std::stringstream&
log) {
446 coral::ITableDataEditor& editor = schema.tableHandle(authorization_table_name).dataEditor();
448 log <<
"Updating permission for principal id " << principalId <<
" to access resource " <<
connectionString
449 <<
" with role " << role << std::endl;
450 coral::AttributeList updateData;
455 updateData[
C_ID_COL].data<
int>() = connectionId;
459 editor.updateRows(setCl, whereCl, updateData);
463 throwException(
"Can't find " + authorization_table_name +
" sequence.",
"CredentialStore::setPermission");
464 log <<
"Setting permission for principal id " << principalId <<
" to access resource " <<
connectionString
465 <<
" with role " << role << std::endl;
466 coral::AttributeList insertData;
474 insertData[
P_ID_COL].data<
int>() = principalId;
478 insertData[
C_ID_COL].data<
int>() = connectionId;
479 editor.insertRow(insertData);
485 coral::ISchema& schema,
491 std::stringstream&
log) {
494 int connId = credsData.
id;
499 coral::ITableDataEditor& editor = schema.tableHandle(credential_table_name).dataEditor();
504 if (verificationKey != connectionLabel) {
505 throwException(
"Decoding of connection key failed.",
"CredentialStore::updateConnection");
510 log <<
"Forcing update of connection " << connectionLabel << std::endl;
511 coral::AttributeList updateData;
518 std::stringstream setCl;
522 editor.updateRows(setCl.str(), whereCl, updateData);
533 throwException(
"Can't find " + credential_table_name +
" sequence.",
"CredentialStore::updateConnection");
534 log <<
"Creating new connection " << connectionLabel << std::endl;
535 coral::AttributeList insertData;
549 editor.insertRow(insertData);
551 return std::make_pair(connId, connectionKey);
558 if (m_session.get()) {
559 if (m_session->transaction().isActive()) {
561 m_session->transaction().commit();
563 m_session->transaction().rollback();
566 m_session->endUserSession();
569 if (m_connection.get()) {
570 m_connection->disconnect();
572 m_connection.reset();
573 m_log <<
"Session has been closed." << std::endl;
577 coral::IHandle<coral::IRelationalService> relationalService =
579 if (!relationalService.isValid()) {
583 coral::IRelationalDomain& domain = relationalService->domainForConnection(
connectionString);
584 std::pair<std::string, std::string> connTokens = domain.decodeUserConnectionString(
connectionString);
585 m_connection.reset(domain.newConnection(connTokens.first));
586 m_connection->connect();
594 coral::AccessMode accessMode = coral::ReadOnly;
596 accessMode = coral::Update;
597 m_session.reset(m_connection->newSession(schemaName, accessMode));
600 m_session->transaction().start(readMode);
601 m_log <<
"New session opened." << std::endl;
607 std::pair<std::string, std::string> connTokens = openConnection(
connectionString);
613 if (!m_serviceData) {
614 throwException(
"The credential store has not been initialized.",
"cond::CredentialStore::openConnection");
616 const std::string& storeConnectionString = m_serviceData->connectionString;
618 std::pair<std::string, std::string> connTokens = openConnection(storeConnectionString);
625 coral::ISchema& schema = m_session->nominalSchema();
626 const std::string& schemaVersion = m_key.version();
630 throwException(
"Credential database does not exists in \"" + storeConnectionString +
"\"",
631 "CredentialStore::startSession");
634 const std::string& principalName = m_key.principalName();
637 if (!
selectPrincipal(schemaVersion, m_session->nominalSchema(), principalName, princData)) {
638 throwException(
"Invalid credentials provided.(0)",
"CredentialStore::startSession");
642 if (verifStr != principalName) {
643 throwException(
"Invalid credentials provided (1)",
"CredentialStore::startSession");
646 m_principalId = princData.
id;
647 m_principalKey = cipher0.b64decrypt(princData.
principalKey);
652 if (adminKey != m_principalKey) {
654 throwException(
"Provided credentials does not allow admin operation.",
"CredentialStore::openSession");
658 std::unique_ptr<coral::IQuery>
query(schema.newQuery());
661 coral::AttributeList readBuff;
667 coral::AttributeList whereData;
671 whereData[
P_ID_COL].data<
int>() = m_principalId;
674 std::stringstream whereClause;
679 query->defineOutput(readBuff);
685 query->setCondition(whereClause.str(), whereData);
686 coral::ICursor& cursor =
query->execute();
691 const coral::AttributeList& row = cursor.currentRow();
699 if (verificationKey != connLabel) {
700 throwException(
"Could not decrypt credentials.Provided key is invalid.",
"CredentialStore::startSession");
702 writeUserName = cipher1.
b64decrypt(encryptedUserName);
703 writePassword = cipher1.
b64decrypt(encryptedPassword);
707 throwException(
"Provided credentials are invalid for write access.",
"CredentialStore::openSession");
709 m_session->transaction().commit();
710 m_session->endUserSession();
711 openSession(connTokens.second, writeUserName, writePassword,
false);
722 m_serviceData(nullptr),
730 throwException(
"Service name has not been provided.",
"cond::CredentialStore::setUpConnection");
732 m_serviceName.clear();
733 m_serviceData =
nullptr;
736 throwException(
"The authentication Path has not been provided.",
"cond::CredentialStore::setUpForService");
739 if (!std::filesystem::exists(
authPath) || !std::filesystem::is_directory(
authPath)) {
740 throwException(
"Authentication Path is invalid.",
"cond::CredentialStore::setUpForService");
747 std::map<std::string, auth::ServiceCredentials>::const_iterator iK = m_key.services().find(
serviceName);
748 if (iK == m_key.services().end()) {
750 msg +=
"Service \"" +
serviceName +
"\" can't be open with the current key.";
754 m_serviceData = &iK->second;
755 m_log <<
"Opening Credential Store for service " << m_serviceName <<
" on " << m_serviceData->connectionString
757 return m_serviceData->connectionString;
762 coral::IHandle<coral::IRelationalService> relationalService =
764 if (!relationalService.isValid()) {
768 coral::IRelationalDomain& domain = relationalService->domainForConnection(
connectionString);
769 std::pair<std::string, std::string> connTokens = domain.decodeUserConnectionString(
connectionString);
776 coral::AttributeList insertData;
779 coral::AttributeList::iterator iAttribute = insertData.begin();
782 iAttribute->data<
int>() = -1;
783 schema.tableHandle(
tname(
SEQUENCE_TABLE, schemaVersion)).dataEditor().insertRow(insertData);
792 coral::ISchema& schema = m_session->nominalSchema();
794 if (schema.existsTable(authentication_table_name)) {
795 throwException(
"Credential database, already exists.",
"CredentialStore::create");
798 m_log <<
"Creating sequence table." << std::endl;
800 coral::TableDescription dseq;
801 dseq.setName(sequence_table_name);
802 dseq.insertColumn(
SEQUENCE_NAME_COL, coral::AttributeSpecification::typeNameForType<std::string>());
804 dseq.insertColumn(
SEQUENCE_VALUE_COL, coral::AttributeSpecification::typeNameForType<int>());
807 schema.createTable(dseq);
809 int columnSize = 2000;
811 m_log <<
"Creating authentication table." << std::endl;
813 addSequence(m_key.version(), schema, authentication_table_name);
814 coral::TableDescription descr0;
815 descr0.setName(authentication_table_name);
816 descr0.insertColumn(
PRINCIPAL_ID_COL, coral::AttributeSpecification::typeNameForType<int>());
818 PRINCIPAL_NAME_COL, coral::AttributeSpecification::typeNameForType<std::string>(), columnSize,
false);
820 VERIFICATION_COL, coral::AttributeSpecification::typeNameForType<std::string>(), columnSize,
false);
822 PRINCIPAL_KEY_COL, coral::AttributeSpecification::typeNameForType<std::string>(), columnSize,
false);
823 descr0.insertColumn(
ADMIN_KEY_COL, coral::AttributeSpecification::typeNameForType<std::string>(), columnSize,
false);
829 std::vector<std::string> columnsUnique;
831 descr0.setUniqueConstraint(columnsUnique);
832 std::vector<std::string> columnsForIndex;
834 descr0.setPrimaryKey(columnsForIndex);
835 schema.createTable(descr0);
837 m_log <<
"Creating authorization table." << std::endl;
840 addSequence(m_key.version(), schema, authorization_table_name);
841 coral::TableDescription descr1;
842 descr1.setName(authorization_table_name);
843 descr1.insertColumn(
AUTH_ID_COL, coral::AttributeSpecification::typeNameForType<int>());
844 descr1.insertColumn(
P_ID_COL, coral::AttributeSpecification::typeNameForType<int>());
845 descr1.insertColumn(
ROLE_COL, coral::AttributeSpecification::typeNameForType<std::string>(), columnSize,
false);
846 descr1.insertColumn(
SCHEMA_COL, coral::AttributeSpecification::typeNameForType<std::string>(), columnSize,
false);
847 descr1.insertColumn(
AUTH_KEY_COL, coral::AttributeSpecification::typeNameForType<std::string>(), columnSize,
false);
848 descr1.insertColumn(
C_ID_COL, coral::AttributeSpecification::typeNameForType<int>());
850 descr1.setNotNullConstraint(
P_ID_COL);
851 descr1.setNotNullConstraint(
ROLE_COL);
854 descr1.setNotNullConstraint(
C_ID_COL);
855 columnsUnique.clear();
859 descr1.setUniqueConstraint(columnsUnique);
860 columnsForIndex.clear();
862 descr1.setPrimaryKey(columnsForIndex);
863 schema.createTable(descr1);
865 m_log <<
"Creating credential table." << std::endl;
868 addSequence(m_key.version(), schema, credential_table_name);
869 coral::TableDescription descr2;
870 descr2.setName(credential_table_name);
871 descr2.insertColumn(
CONNECTION_ID_COL, coral::AttributeSpecification::typeNameForType<int>());
873 CONNECTION_LABEL_COL, coral::AttributeSpecification::typeNameForType<std::string>(), columnSize,
false);
874 descr2.insertColumn(
USERNAME_COL, coral::AttributeSpecification::typeNameForType<std::string>(), columnSize,
false);
875 descr2.insertColumn(
PASSWORD_COL, coral::AttributeSpecification::typeNameForType<std::string>(), columnSize,
false);
877 VERIFICATION_KEY_COL, coral::AttributeSpecification::typeNameForType<std::string>(), columnSize,
false);
879 CONNECTION_KEY_COL, coral::AttributeSpecification::typeNameForType<std::string>(), columnSize,
false);
886 columnsUnique.clear();
888 descr2.setUniqueConstraint(columnsUnique);
889 columnsForIndex.clear();
891 descr2.setPrimaryKey(columnsForIndex);
892 schema.createTable(descr2);
895 schema.tableHandle(authentication_table_name)
897 .grantToUser(m_serviceData->userName, coral::ITablePrivilegeManager::Select);
898 schema.tableHandle(authorization_table_name)
900 .grantToUser(m_serviceData->userName, coral::ITablePrivilegeManager::Select);
901 schema.tableHandle(credential_table_name)
903 .grantToUser(m_serviceData->userName, coral::ITablePrivilegeManager::Select);
905 std::cout <<
"WARNING: Could not grant select access to user " << m_serviceData->userName <<
": [" <<
e.what()
908 m_log <<
"Granting ADMIN access permission." << std::endl;
912 m_key.version(), schema, m_key.principalKey(), m_key.principalName(), m_principalKey,
true, m_log);
915 m_key.version(), schema, m_principalKey, credentialAccessLabel,
userName,
password,
true, m_log);
935 m_log <<
"Dropping AUTHORIZATION, CREDENTIAL, AUTHENTICATION and SEQUENCE tables." << std::endl;
936 coral::ISchema& schema = m_session->nominalSchema();
946 if (!m_serviceData) {
947 throwException(
"The credential store has not been initialized.",
"cond::CredentialStore::installAdmin");
954 coral::ISchema& schema = m_session->nominalSchema();
955 const std::string& principalName = m_key.principalName();
956 const std::string& authenticationKey = m_key.principalKey();
958 if (!
selectPrincipal(m_key.version(), schema, principalName, princData)) {
960 msg += principalName +
"\" has not been found.";
966 auto p =
updatePrincipalData(m_key.version(), schema, authenticationKey, principalName, m_principalKey,
false, m_log);
969 m_key.version(), schema, m_principalKey, credentialAccessLabel,
userName,
password,
true, m_log);
987 session.
start(
false);
988 coral::ISchema& schema = m_session->nominalSchema();
990 updatePrincipalData(m_key.version(), schema, authenticationKey, principalName, m_principalKey,
false, m_log);
993 int princId = princData.first;
995 std::string connString = m_serviceData->connectionString;
998 throwException(
"The current operating user is not admin user on the underlying Credential Store.",
999 "CredentialStore::updatePrincipal");
1004 throwException(
"Credential Store connection has not been defined.",
"CredentialStore::updatePrincipal");
1026 session.
start(
false);
1028 coral::ISchema& schema = m_session->nominalSchema();
1034 std::string msg =
"Principal \"" + principal +
"\" does not exist in the database.";
1038 m_log <<
"Principal " << principal <<
" id: " << princData.
id << std::endl;
1043 std::string msg =
"Connection named \"" + connectionLabel +
"\" does not exist in the database.";
1068 session.
start(
false);
1069 coral::ISchema& schema = m_session->nominalSchema();
1075 std::string msg =
"Principal \"" + principal +
"\" does not exist in the database.";
1078 m_log <<
"Removing permission for principal " << principal <<
" (id: " << princData.
id <<
") to access resource "
1081 coral::AttributeList deleteData;
1085 deleteData[
P_ID_COL].data<
int>() = princData.
id;
1088 std::stringstream whereClause;
1092 editor.deleteRows(whereClause.str(), deleteData);
1101 session.
start(
false);
1103 m_session->transaction().start();
1104 coral::ISchema& schema = m_session->nominalSchema();
1114 session.
start(
false);
1115 coral::ISchema& schema = m_session->nominalSchema();
1121 std::string msg =
"Principal \"" + principal +
"\" does not exist in the database.";
1125 m_log <<
"Removing principal " << principal <<
" (id: " << princData.
id <<
")" << std::endl;
1129 coral::AttributeList deleteData0;
1131 deleteData0[
P_ID_COL].data<
int>() = princData.
id;
1133 editor0.deleteRows(whereClause0, deleteData0);
1137 coral::AttributeList deleteData1;
1141 editor1.deleteRows(whereClause1, deleteData1);
1150 session.
start(
false);
1151 coral::ISchema& schema = m_session->nominalSchema();
1157 std::string msg =
"Connection named \"" + connectionLabel +
"\" does not exist in the database.";
1161 m_log <<
"Removing connection " << connectionLabel << std::endl;
1164 coral::AttributeList deleteData0;
1166 deleteData0[
C_ID_COL].data<
int>() = credsData.
id;
1168 editor0.deleteRows(whereClause0, deleteData0);
1170 coral::ITableDataEditor& editor1 = schema.tableHandle(
tname(
CREDENTIAL_TABLE, m_key.version())).dataEditor();
1172 coral::AttributeList deleteData1;
1176 editor1.deleteRows(whereClause1, deleteData1);
1185 session.
start(
true);
1186 coral::ISchema& schema = m_session->nominalSchema();
1190 std::unique_ptr<coral::IQuery>
query(schema.newQuery());
1193 coral::AttributeList readBuff;
1201 coral::AttributeList whereData;
1203 whereData[
P_ID_COL].data<
int>() = m_principalId;
1204 std::stringstream whereClause;
1205 whereClause <<
"AUTHO." <<
C_ID_COL <<
"="
1207 whereClause <<
" AND "
1209 query->defineOutput(readBuff);
1217 query->setCondition(whereClause.str(), whereData);
1218 coral::ICursor& cursor =
query->execute();
1219 while (cursor.next()) {
1220 const coral::AttributeList& row = cursor.currentRow();
1230 if (verificationString == connectionLabel) {
1242 session.
start(
true);
1243 coral::ISchema& schema = m_session->nominalSchema();
1247 std::unique_ptr<coral::IQuery>
query(schema.newQuery());
1250 coral::AttributeList readBuff;
1256 coral::AttributeList whereData;
1260 whereData[
P_ID_COL].data<
int>() = m_principalId;
1263 std::stringstream whereClause;
1264 whereClause <<
"AUTHO." <<
C_ID_COL <<
"="
1266 whereClause <<
" AND "
1268 whereClause <<
" AND "
1270 whereClause <<
" AND "
1272 query->defineOutput(readBuff);
1278 query->setCondition(whereClause.str(), whereData);
1279 coral::ICursor& cursor =
query->execute();
1281 if (cursor.next()) {
1282 const coral::AttributeList& row = cursor.currentRow();
1290 if (verificationString == connectionLabel) {
1301 bool forceUpdateConnection) {
1303 session.
start(
false);
1304 coral::ISchema& schema = m_session->nominalSchema();
1310 std::string msg =
"Principal \"" + principal +
"\" does not exist in the database.";
1314 bool imported =
false;
1318 const std::map<std::pair<std::string, std::string>, coral::AuthenticationCredentials*>& creds =
dataSource.data();
1319 for (
std::map<std::pair<std::string, std::string>, coral::AuthenticationCredentials*>::const_iterator iConn =
1321 iConn != creds.end();
1328 std::string userName = iConn->second->valueForItem(coral::IAuthenticationCredentials::userItem());
1329 std::string password = iConn->second->valueForItem(coral::IAuthenticationCredentials::passwordItem());
1337 forceUpdateConnection,
1351 session.
start(
true);
1352 coral::ISchema& schema = m_session->nominalSchema();
1355 coral::AttributeList readBuff;
1357 query->defineOutput(readBuff);
1359 coral::ICursor& cursor =
query->execute();
1361 while (cursor.next()) {
1363 const coral::AttributeList& row = cursor.currentRow();
1372 session.
start(
true);
1373 coral::ISchema& schema = m_session->nominalSchema();
1376 coral::AttributeList readBuff;
1382 query->defineOutput(readBuff);
1388 coral::ICursor& cursor =
query->execute();
1391 while (cursor.next()) {
1394 const coral::AttributeList& row = cursor.currentRow();
1401 if (verif == connLabel) {
1419 session.
start(
true);
1420 coral::ISchema& schema = m_session->nominalSchema();
1421 std::unique_ptr<coral::IQuery>
query(schema.newQuery());
1425 coral::AttributeList readBuff;
1430 coral::AttributeList whereData;
1431 std::stringstream whereClause;
1433 whereClause <<
" AND AUTHO." <<
C_ID_COL <<
"="
1435 if (!principalName.empty()) {
1440 if (!role.empty()) {
1451 query->defineOutput(readBuff);
1456 query->setCondition(whereClause.str(), whereData);
1460 coral::ICursor& cursor =
query->execute();
1462 while (cursor.next()) {
1463 const coral::AttributeList& row = cursor.currentRow();
1478 session.
start(
true);
1479 coral::ISchema& schema = m_session->nominalSchema();
1480 std::unique_ptr<coral::IQuery>
query(schema.newQuery());
1483 coral::AttributeList readBuff;
1491 coral::AttributeList whereData;
1492 std::stringstream whereClause;
1493 whereClause <<
"AUTHO." <<
C_ID_COL <<
"="
1496 query->defineOutput(readBuff);
1504 query->setCondition(whereClause.str(), whereData);
1505 coral::ICursor& cursor =
query->execute();
1508 while (cursor.next()) {
1509 const coral::AttributeList& row = cursor.currentRow();
1520 if (verifKey == connectionLabel) {