| 105 | namespace Jrd { |
| 106 | |
| 107 | bool checkCreateDatabaseGrant(const MetaString& userName, const MetaString& trustedRole, |
| 108 | const MetaString& sqlRole, const char* securityDb) |
| 109 | { |
| 110 | if (userName == DBA_USER_NAME) |
| 111 | return true; |
| 112 | |
| 113 | RefPtr<IAttachment> att; |
| 114 | RefPtr<ITransaction> tra; |
| 115 | bool hasDb = openDb(securityDb, att, tra); |
| 116 | |
| 117 | FbLocalStatus st; |
| 118 | MetaString role(sqlRole); |
| 119 | if (hasDb && role.hasData()) |
| 120 | { |
| 121 | const UCHAR info[] = { isc_info_db_sql_dialect, isc_info_end }; |
| 122 | UCHAR buffer[BUFFER_TINY]; |
| 123 | att->getInfo(&st, sizeof(info), info, sizeof(buffer), buffer); |
| 124 | check("IAttachment::getInfo", &st); |
| 125 | |
| 126 | int dialect = SQL_DIALECT_V5; // reasonable default |
| 127 | |
| 128 | for (ClumpletReader p(ClumpletReader::InfoResponse, buffer, sizeof(buffer)); !p.isEof(); p.moveNext()) |
| 129 | { |
| 130 | switch (p.getClumpTag()) |
| 131 | { |
| 132 | case isc_info_db_sql_dialect: |
| 133 | dialect = p.getInt(); |
| 134 | break; |
| 135 | } |
| 136 | } |
| 137 | |
| 138 | UserId::makeRoleName(role, dialect); |
| 139 | |
| 140 | // We need to check is role granted to userName in security DB |
| 141 | const char* sql = "select count(*) from RDB$USER_PRIVILEGES " |
| 142 | "where RDB$USER = ? and RDB$RELATION_NAME = ? and RDB$PRIVILEGE = 'M'"; |
| 143 | |
| 144 | Message prm; |
| 145 | Field<Varying> u(prm, MAX_SQL_IDENTIFIER_LEN); |
| 146 | Field<Varying> r(prm, MAX_SQL_IDENTIFIER_LEN); |
| 147 | u = userName.c_str(); |
| 148 | r = role.c_str(); |
| 149 | |
| 150 | Message result; |
| 151 | Field<ISC_INT64> cnt(result); |
| 152 | |
| 153 | att->execute(&st, tra, 0, sql, SQL_DIALECT_V6, prm.getMetadata(), prm.getBuffer(), |
| 154 | result.getMetadata(), result.getBuffer()); |
| 155 | |
| 156 | if (st->getState() & IStatus::STATE_ERRORS) |
| 157 | { |
| 158 | // isc_dsql_relation_err when exec SQL - i.e. table RDB$USER_PRIVILEGES |
| 159 | // is missing due to non-FB security DB |
| 160 | if (!fb_utils::containsErrorCode(st->getErrors(), isc_dsql_relation_err)) |
| 161 | check("IAttachment::execute", &st); |
| 162 | |
| 163 | role = ""; |
| 164 | } |
no test coverage detected