32 #include <string_view>
38 #include <boost/algorithm/string/predicate.hpp>
39 #include <boost/filesystem.hpp>
40 #include <boost/range/adaptor/map.hpp>
41 #include <boost/version.hpp>
43 #include "MapDRelease.h"
51 #include "include/bcrypt.h"
56 using std::runtime_error;
60 using namespace std::string_literals;
72 char salt[BCRYPT_HASHSIZE], hash[BCRYPT_HASHSIZE];
73 CHECK(bcrypt_gensalt(-1, salt) == 0);
74 CHECK(bcrypt_hashpw(pwd.c_str(), salt, hash) == 0);
75 return std::string(hash, BCRYPT_HASHSIZE);
80 std::filesystem::path catalog_base_data_path;
86 catalog_base_data_path = base_data_path;
89 catalog_base_data_path = base_data_path /
"temporary";
93 CHECK_NE(catalog_base_data_path.string().find(
"temporary"), std::string::npos);
94 CHECK_NE(catalog_base_data_path, base_data_path);
95 if (std::filesystem::exists(catalog_base_data_path)) {
96 std::filesystem::remove_all(catalog_base_data_path);
98 std::filesystem::create_directories(catalog_base_data_path);
102 const auto temporary_catalog_path =
104 LOG(
INFO) <<
"copying catalog from " << normal_catalog_path <<
" to "
105 << temporary_catalog_path <<
" for read-only server";
107 temporary_catalog_path,
108 std::filesystem::copy_options::recursive);
113 std::filesystem::create_directories(catalog_base_data_path /
118 std::filesystem::create_directories(catalog_base_data_path /
123 std::filesystem::create_directories(catalog_base_data_path /
128 std::filesystem::create_directories(catalog_base_data_path /
134 std::filesystem::create_directories(catalog_base_data_path /
141 return catalog_base_data_path;
146 namespace Catalog_Namespace {
148 thread_local
bool SysCatalog::thread_holds_read_lock =
false;
149 std::mutex SysCatalog::instance_mutex_;
150 std::unique_ptr<SysCatalog> SysCatalog::instance_;
158 std::string UserMetadata::userLoggable()
const {
162 auto CommonFileOperations::assembleCatalogName(std::string
const&
name) {
166 void CommonFileOperations::removeCatalogByFullPath(std::string
const& full_path) {
167 boost::filesystem::remove(full_path);
170 void CommonFileOperations::removeCatalogByName(std::string
const&
name) {
171 boost::filesystem::remove(assembleCatalogName(name));
174 auto CommonFileOperations::duplicateAndRenameCatalog(std::string
const& current_name,
175 std::string
const& new_name) {
176 auto full_current_path = assembleCatalogName(current_name);
177 auto full_new_path = assembleCatalogName(new_name);
180 boost::filesystem::copy_file(full_current_path, full_new_path);
181 }
catch (std::exception& e) {
182 std::string err_message{
"Could not copy file " + full_current_path +
" to " +
183 full_new_path +
" exception was " + e.what()};
185 throw std::runtime_error(err_message);
188 return std::make_pair(full_current_path, full_new_path);
192 std::shared_ptr<Data_Namespace::DataMgr> dataMgr,
194 std::shared_ptr<Calcite> calcite,
197 const std::vector<LeafHostInfo>& string_dict_hosts) {
201 dcatalogMutex_ = std::make_unique<heavyai::DistributedSharedMutex>(
209 dsqliteMutex_ = std::make_unique<heavyai::DistributedSharedMutex>(
215 authMetadata_ = &authMetadata;
216 pki_server_.reset(
new PkiServer(*authMetadata_));
217 calciteMgr_ = calcite;
218 string_dict_hosts_ = string_dict_hosts;
219 aggregator_ = aggregator;
228 importDataFromOldMapdDB();
231 checkAndExecuteMigrations();
235 buildMaps(is_new_db);
236 is_initialized_ =
true;
239 bool SysCatalog::isInitialized()
const {
240 return is_initialized_;
243 void SysCatalog::buildMaps(
bool is_new_db) {
247 buildMapsUnlocked(is_new_db);
250 void SysCatalog::buildMapsUnlocked(
bool is_new_db) {
254 std::map<std::string, std::vector<std::string>> tu_map;
255 for (
auto& pair : temporary_users_by_name_) {
261 auto user_rl =
dynamic_cast<User*
>(it->second.get());
263 std::vector<std::string> current_roles = user_rl->getRoles();
264 auto result = tu_map.emplace(user.
userName, std::move(current_roles));
269 buildRoleMapUnlocked();
270 buildUserRoleMapUnlocked();
271 buildObjectDescriptorMapUnlocked();
278 initializeInformationSchemaDb();
282 for (
auto& pair : temporary_users_by_name_) {
286 createRole_unsafe(user.
userName,
true,
true);
288 auto it = tu_map.find(user.
userName);
290 for (
const auto& r : it->second) {
291 grantRole_unsafe(r, user.
userName,
true);
296 SysCatalog::SysCatalog()
303 , dummyCatalog_{std::make_shared<Catalog>()} {}
317 throw std::runtime_error(
"can't init a new database in read-only mode");
323 "CREATE TABLE mapd_users (userid integer primary key, name text unique, "
324 "passwd_hash text, issuper boolean, default_db integer references "
325 "mapd_databases, can_login boolean)");
327 "INSERT INTO mapd_users VALUES (?, ?, ?, 1, NULL, 1)",
332 "CREATE TABLE mapd_databases (dbid integer primary key, name text unique, owner "
333 "integer references mapd_users)");
335 "CREATE TABLE mapd_roles(roleName text, userName text, UNIQUE(roleName, "
338 "CREATE TABLE mapd_object_permissions ("
341 "dbId integer references mapd_databases, "
344 "objectPermissionsType integer, "
345 "objectPermissions integer, "
346 "objectOwnerId integer, UNIQUE(roleName, objectPermissionsType, dbId, "
348 }
catch (
const std::exception&) {
379 if (col_name ==
"default_db") {
388 "ALTER TABLE mapd_users ADD COLUMN default_db INTEGER REFERENCES mapd_databases");
389 }
catch (
const std::exception& e) {
399 sqliteConnector_->query(
"ATTACH DATABASE `" + mapd_db_path +
"` as old_cat");
401 LOG(
INFO) <<
"Moving global metadata into a separate catalog";
403 auto moveTableIfExists = [conn =
sqliteConnector_.get()](
const std::string& tableName,
404 bool deleteOld =
true) {
405 conn->query(
"SELECT sql FROM old_cat.sqlite_master WHERE type='table' AND name='" +
407 if (conn->getNumRows() != 0) {
408 conn->query(conn->getData<
string>(0, 0));
409 conn->query(
"INSERT INTO " + tableName +
" SELECT * FROM old_cat." + tableName);
411 conn->query(
"DROP TABLE old_cat." + tableName);
415 moveTableIfExists(
"mapd_users");
416 moveTableIfExists(
"mapd_databases");
417 moveTableIfExists(
"mapd_roles");
418 moveTableIfExists(
"mapd_object_permissions");
419 moveTableIfExists(
"mapd_privileges");
420 moveTableIfExists(
"mapd_version_history",
false);
421 }
catch (
const std::exception& e) {
422 LOG(
ERROR) <<
"Failed to move global metadata into a separate catalog: " << e.what();
426 }
catch (
const std::exception&) {
432 const std::string sys_catalog_path =
434 LOG(
INFO) <<
"Global metadata has been successfully moved into a separate catalog: "
436 <<
". Using this database with an older version of heavydb "
437 "is now impossible.";
440 }
catch (
const std::exception&) {
450 "SELECT name FROM sqlite_master WHERE type='table' AND name='mapd_roles'");
457 "CREATE TABLE mapd_roles(roleName text, userName text, UNIQUE(roleName, "
459 }
catch (
const std::exception&) {
478 std::vector<std::string> user_names;
479 for (
size_t i = 0; i < num_rows; ++i) {
482 for (
const auto& user_name : user_names) {
483 sqliteConnector_->query_with_text_param(
"DELETE FROM mapd_roles WHERE roleName = ?",
486 }
catch (
const std::exception&) {
496 std::string roleName,
501 sqliteConnector->query_with_text_params(
502 "DELETE FROM mapd_object_permissions WHERE roleName = ?1 and roleType = ?2 and "
503 "objectPermissionsType = ?3 and "
507 std::vector<std::string>{roleName,
515 std::string roleName,
518 CHECK(
object.valid());
521 sqliteConnector->query_with_text_params(
522 "INSERT OR REPLACE INTO mapd_object_permissions("
525 "objectPermissionsType, "
528 "objectPermissions, "
531 "VALUES (?1, ?2, ?3, "
532 "?4, ?5, ?6, ?7, ?8)",
533 std::vector<std::string>{
535 userRole ?
"1" :
"0",
552 "SELECT name FROM sqlite_master WHERE type='table' AND "
553 "name='mapd_object_permissions'");
561 "CREATE TABLE IF NOT EXISTS mapd_object_permissions ("
564 "dbId integer references mapd_databases, "
567 "objectPermissionsType integer, "
568 "objectPermissions integer, "
569 "objectOwnerId integer, UNIQUE(roleName, objectPermissionsType, dbId, "
574 "SELECT userid, dbid FROM mapd_privileges WHERE select_priv = 1 and insert_priv "
577 vector<pair<int, int>> db_grantees(numRows);
578 for (
size_t i = 0; i < numRows; ++i) {
585 std::unordered_map<int, string> users_by_id;
586 std::unordered_map<int, bool> user_has_privs;
587 for (
size_t i = 0; i < numRows; ++i) {
595 std::unordered_map<int, string> dbs_by_id;
596 for (
size_t i = 0; i < numRows; ++i) {
602 for (
const auto& grantee : db_grantees) {
603 user_has_privs[grantee.first] =
true;
604 auto dbName = dbs_by_id[grantee.second];
638 for (
auto user : user_has_privs) {
639 auto dbName = dbs_by_id[0];
650 }
catch (
const std::exception&) {
662 "SELECT roleName FROM mapd_object_permissions WHERE roleName = \'" +
672 }
catch (
const std::exception&) {
684 "SELECT name FROM sqlite_master WHERE type='table' AND name='mapd_users'");
693 if (col_name ==
"passwd_hash") {
702 vector<std::string> users, passwords;
703 for (
size_t i = 0; i < numRows; i++) {
708 "CREATE TABLE mapd_users_tmp (userid integer primary key, name text unique, "
709 "passwd_hash text, issuper boolean, default_db integer references "
712 "INSERT INTO mapd_users_tmp(userid, name, passwd_hash, issuper, default_db) "
713 "SELECT userid, name, null, issuper, default_db FROM mapd_users");
714 for (
size_t i = 0; i < users.size(); ++i) {
716 "UPDATE mapd_users_tmp SET passwd_hash = ? WHERE userid = ?",
721 }
catch (
const std::exception& e) {
722 LOG(
ERROR) <<
"Failed to hash passwords: " << e.what();
728 LOG(
INFO) <<
"Passwords were successfully hashed";
732 const std::string UPDATE_BLANK_PASSWORDS_TO_RANDOM =
"update_blank_passwords_to_random";
734 "SELECT migration_history FROM mapd_version_history WHERE migration_history = ?",
735 std::vector<std::string>{UPDATE_BLANK_PASSWORDS_TO_RANDOM});
744 "SELECT userid, passwd_hash, name FROM mapd_users WHERE name <> 'mapd'");
746 vector<std::string> users, passwords, names;
747 for (
size_t i = 0; i < numRows; i++) {
752 for (
size_t i = 0; i < users.size(); ++i) {
753 int pwd_check_result = bcrypt_checkpw(
"", passwords[i].c_str());
755 CHECK(pwd_check_result >= 0);
756 if (pwd_check_result != 0) {
759 LOG(
WARNING) <<
"resetting blank password for user " << names[i] <<
" (" << users[i]
760 <<
") to a random password";
762 "UPDATE mapd_users SET passwd_hash = ? WHERE userid = ?",
767 "INSERT INTO mapd_version_history(version, migration_history) values(?,?)",
769 UPDATE_BLANK_PASSWORDS_TO_RANDOM});
770 }
catch (
const std::exception& e) {
771 LOG(
ERROR) <<
"Failed to fix blank passwords: " << e.what();
779 const std::string UPDATE_SUPPORT_USER_DEACTIVATION =
"update_support_user_deactivation";
785 if (col_name ==
"can_login") {
791 sqliteConnector_->query(
"ALTER TABLE mapd_users ADD COLUMN can_login BOOLEAN");
794 "INSERT INTO mapd_version_history(version, migration_history) values(?,?)",
796 UPDATE_SUPPORT_USER_DEACTIVATION});
797 }
catch (
const std::exception& e) {
798 LOG(
ERROR) <<
"Failed to add support for user deactivation: " << e.what();
810 "select name from sqlite_master WHERE type='table' AND "
811 "name='mapd_version_history'");
814 "CREATE TABLE mapd_version_history(version integer, migration_history text "
818 "select * from mapd_version_history where migration_history = "
819 "'db_access_privileges'");
829 "INSERT INTO mapd_version_history(version, migration_history) values(?,?)",
833 std::unordered_map<int, string> databases;
840 std::unordered_map<int, string> users;
849 for (
auto db_ : databases) {
851 for (
auto user : users) {
874 }
catch (
const std::exception& e) {
875 LOG(
ERROR) <<
"Failed to migrate db access privileges: " << e.what();
880 LOG(
INFO) <<
"Successfully migrated db access privileges";
889 "CREATE TABLE IF NOT EXISTS mapd_privileges (userid integer references "
890 "mapd_users, dbid integer references "
891 "mapd_databases, select_priv boolean, insert_priv boolean, UNIQUE(userid, "
893 }
catch (
const std::exception& e) {
901 static const string duplicate_check_migration{
902 "check_duplicate_case_insensitive_db_names"};
908 "SELECT UPPER(name) AS db_name, COUNT(*) AS name_count "
909 "FROM mapd_databases GROUP BY db_name HAVING name_count > 1");
912 std::stringstream error_message;
913 error_message <<
"Duplicate case insensitive database names encountered:\n";
914 for (
size_t row = 0; row < num_rows; row++) {
918 throw std::runtime_error{error_message.str()};
924 std::string& username,
925 const std::string& password,
927 bool check_password) {
932 if (check_password) {
933 loginImpl(username, password, user_meta);
936 throw std::runtime_error(
"Invalid credentials.");
941 throw std::runtime_error(
"Unauthorized Access: User " + username +
" is deactivated");
950 const std::string& password,
953 throw std::runtime_error(
"Authentication failure");
958 const std::string& username) {
972 throw std::runtime_error(
"Unauthorized Access: user " + user_meta.
userLoggable() +
973 " is not allowed to access database " + dbname +
".");
980 std::string& session) {
1008 throw runtime_error(
"User " + user.
userLoggable() +
" already exists.");
1011 std::string
const loggable =
g_log_user_id ? std::string(
"") : name +
' ';
1012 throw runtime_error(
1013 "User " + loggable +
1014 "is same as one of existing grantees. User and role names should be unique.");
1019 throw runtime_error(
"DEFAULT_DB " + *alts.
default_db +
" not found.");
1026 throw std::runtime_error(
"Temporary users require read-only mode.");
1040 VLOG(1) <<
"Created temporary user: " << user2->userLoggable();
1047 std::vector<std::string> vals;
1055 "INSERT INTO mapd_users (name, passwd_hash, issuper, default_db, can_login) "
1056 "VALUES (?, ?, ?, ?, ?)",
1064 "INSERT INTO mapd_users (name, passwd_hash, issuper, can_login) "
1065 "VALUES (?, ?, ?, ?)",
1069 }
catch (
const std::exception& e) {
1076 VLOG(1) <<
"Created user: " << u->userLoggable();
1104 const std::string& roleName(name);
1105 sqliteConnector_->query_with_text_param(
"DELETE FROM mapd_roles WHERE userName = ?",
1111 }
catch (
const std::exception& e) {
1122 std::string
const loggable =
g_log_user_id ? std::string(
"") : name +
' ';
1126 throw runtime_error(
"Cannot drop user. User " + loggable +
"does not exist.");
1130 for (
const auto& db : dbs) {
1131 if (db.dbOwner == user.
userId) {
1132 throw runtime_error(
"Cannot drop user. User " + loggable +
"owns database " +
1141 std::vector<Catalog*> catalogs{};
1143 for (
const auto& db_metadata : db_metadata_list) {
1144 catalogs.emplace_back(
getCatalog(db_metadata,
false).
get());
1171 throw std::runtime_error(
string(
"DEFAULT_DB ") + *
default_db +
" not found.");
1187 std::stringstream ss;
1189 if (hide_password) {
1190 ss <<
"PASSWORD='XXXXXXXX'";
1192 ss <<
"PASSWORD='" << *
passwd <<
"'";
1196 if (!ss.str().empty()) {
1199 ss <<
"IS_SUPER='" << (*
is_super ?
"TRUE" :
"FALSE") <<
"'";
1202 if (!ss.str().empty()) {
1208 if (!ss.str().empty()) {
1211 ss <<
"CAN_LOGIN='" << *
can_login <<
"'";
1222 std::string
const loggable =
g_log_user_id ? std::string(
"") : name +
' ';
1223 throw runtime_error(
"Cannot alter user. User " + loggable +
"does not exist.");
1241 throw runtime_error(
string(
"DEFAULT_DB ") + *alts.
default_db +
" not found.");
1259 std::vector<std::string> values;
1273 throw runtime_error(
string(
"DEFAULT_DB ") + *alts.
default_db +
" not found.");
1285 sql =
"UPDATE mapd_users SET " + sql +
" WHERE userid = ?";
1289 }
catch (
const std::exception& e) {
1296 VLOG(1) <<
"Altered user: " << u->userLoggable();
1302 [](
auto& db_connector,
auto on_success,
auto on_failure,
auto&&... query_requests) {
1303 auto query_runner = [&db_connector](
auto&&... query_reqs) {
1304 [[gnu::unused]]
int throw_away[] = {
1305 (db_connector->query_with_text_params(
1306 std::forward<decltype(query_reqs)>(query_reqs)),
1310 db_connector->query(
"BEGIN TRANSACTION");
1312 query_runner(std::forward<decltype(query_requests)>(query_requests)...);
1314 }
catch (std::exception&) {
1315 db_connector->query(
"ROLLBACK TRANSACTION");
1319 db_connector->query(
"END TRANSACTION");
1324 const std::string& newName) {
1329 it->second->setName(newName);
1336 if (d->second->roleName == roleName) {
1337 d->second->roleName = newName;
1343 using namespace std::string_literals;
1349 std::string
const loggable =
g_log_user_id ? std::string(
"") : old_name +
' ';
1350 throw std::runtime_error(
"User " + loggable +
"doesn't exist.");
1355 throw std::runtime_error(
"User " + new_user.userLoggable() +
" already exists.");
1359 std::string
const loggable =
g_log_user_id ? std::string(
"") : new_name +
' ';
1360 throw runtime_error(
1361 "Username " + loggable +
1362 "is same as one of existing grantees. User and role names should be unique.");
1366 if (old_user.is_temporary) {
1370 node.key() = new_name;
1372 userit->second->userName = new_name;
1379 auto failure_handler = [] {};
1380 auto success_handler = [
this, &old_name, &new_name] {
1383 auto q1 = {
"UPDATE mapd_users SET name=?1 where name=?2;"s, new_name, old_name};
1384 auto q2 = {
"UPDATE mapd_object_permissions set roleName=?1 WHERE roleName=?2;"s,
1387 auto q3 = {
"UPDATE mapd_roles set userName=?1 WHERE userName=?2;"s, new_name, old_name};
1388 transaction_streamer(
sqliteConnector_, success_handler, failure_handler, q1, q2, q3);
1392 const std::string& new_owner) {
1393 using namespace std::string_literals;
1399 throw std::runtime_error(
"Database " + dbname +
" does not exists.");
1404 throw std::runtime_error(
"User with username \"" + new_owner +
"\" does not exist. " +
1405 "Database with name \"" + dbname +
1406 "\" can not have owner changed.");
1417 UpdateQueries{{
"UPDATE mapd_databases SET owner=?1 WHERE name=?2;",
1419 original_owner_exists);
1423 std::string
const& new_name) {
1424 using namespace std::string_literals;
1430 throw std::runtime_error(
"Database " + new_name +
" already exists.");
1433 throw std::runtime_error(
"Database name " + new_name +
"is reserved.");
1438 throw std::runtime_error(
"Database " + old_name +
" does not exists.");
1443 std::string old_catalog_path, new_catalog_path;
1444 std::tie(old_catalog_path, new_catalog_path) =
1448 auto failure_handler = [
this, new_catalog_path] {
1451 auto success_handler = [
this, old_catalog_path] {
1456 "UPDATE mapd_databases SET name=?1 WHERE name=?2;"s, new_name, old_db.dbName};
1458 "UPDATE mapd_object_permissions SET objectName=?1 WHERE objectNAME=?2 and (objectPermissionsType=?3 or objectId = -1) and dbId=?4;"s,
1464 transaction_streamer(
sqliteConnector_, success_handler, failure_handler, q1, q2);
1473 throw runtime_error(
"Database " + name +
" already exists.");
1476 throw runtime_error(
"Database name " + name +
" is reserved.");
1479 std::unique_ptr<SqliteConnector> dbConn(
1485 dbConn->query(
"BEGIN TRANSACTION");
1488 "CREATE TABLE mapd_tables (tableid integer primary key, name text unique, userid "
1489 "integer, ncolumns integer, "
1491 "fragments text, frag_type integer, max_frag_rows integer, max_chunk_size "
1493 "frag_page_size integer, "
1494 "max_rows bigint, partitions text, shard_column_id integer, shard integer, "
1495 "sort_column_id integer default 0, storage_type text default '', "
1496 "max_rollback_epochs integer default -1, "
1497 "is_system_table boolean default 0, "
1498 "num_shards integer, key_metainfo TEXT, version_num "
1499 "BIGINT DEFAULT 1) ");
1501 "CREATE TABLE mapd_columns (tableid integer references mapd_tables, columnid "
1502 "integer, name text, coltype "
1503 "integer, colsubtype integer, coldim integer, colscale integer, is_notnull "
1504 "boolean, compression integer, "
1505 "comp_param integer, size integer, chunks text, is_systemcol boolean, "
1506 "is_virtualcol boolean, virtual_expr "
1507 "text, is_deletedcol boolean, version_num BIGINT, default_value text, "
1508 "primary key(tableid, columnid), unique(tableid, name))");
1510 "CREATE TABLE mapd_views (tableid integer references mapd_tables, sql text)");
1512 "CREATE TABLE mapd_dashboards (id integer primary key autoincrement, name text , "
1513 "userid integer references mapd_users, state text, image_hash text, update_time "
1515 "metadata text, UNIQUE(userid, name) )");
1517 "CREATE TABLE mapd_links (linkid integer primary key, userid integer references "
1519 "link text unique, view_state text, update_time timestamp, view_metadata text)");
1521 "CREATE TABLE mapd_dictionaries (dictid integer primary key, name text unique, "
1522 "nbits int, is_shared boolean, "
1523 "refcount int, version_num BIGINT DEFAULT 1)");
1525 "CREATE TABLE mapd_logical_to_physical(logical_table_id integer, "
1526 "physical_table_id "
1528 dbConn->query(
"CREATE TABLE mapd_record_ownership_marker (dummy integer)");
1529 dbConn->query_with_text_params(
1530 "INSERT INTO mapd_record_ownership_marker (dummy) VALUES (?1)",
1538 }
catch (
const std::exception&) {
1539 dbConn->query(
"ROLLBACK TRANSACTION");
1544 dbConn->query(
"END TRANSACTION");
1546 std::shared_ptr<Catalog>
cat;
1551 "INSERT INTO mapd_databases (name, owner) VALUES (?, " +
std::to_string(owner) +
1560 object.loadKey(*cat);
1565 }
catch (
const std::exception&) {
1579 cat->createDefaultServersIfNotExists();
1590 cat->eraseDbPhysicalData();
1597 "UPDATE mapd_users SET default_db = NULL WHERE default_db = ?",
1600 const auto tables =
cat->getAllTableMetadata();
1601 for (
const auto table :
tables) {
1602 if (table->shard >= 0) {
1609 const auto dashboards =
cat->getAllDashboardsMetadata();
1610 for (
const auto dashboard : dashboards) {
1616 if (grantee.second->hasAnyPrivilegesOnDb(db.
dbId,
true)) {
1618 grantee.second->getName(), db.
dbId, grantee.second.get());
1621 sqliteConnector_->query_with_text_param(
"DELETE FROM mapd_databases WHERE dbid = ?",
1623 cat->eraseDbMetadata();
1625 }
catch (
const std::exception&) {
1647 char fake_hash[BCRYPT_HASHSIZE];
1648 CHECK(bcrypt_gensalt(-1, fake_hash) == 0);
1649 bcrypt_checkpw(passwd.c_str(), fake_hash);
1653 int pwd_check_result = bcrypt_checkpw(passwd.c_str(), user.
passwd_hash.c_str());
1655 CHECK(pwd_check_result >= 0);
1656 return pwd_check_result == 0;
1662 int numRows = conn->getNumRows();
1666 user.
userId = conn->getData<
int>(row, 0);
1667 user.
userName = conn->getData<
string>(row, 1);
1669 user.
isSuper = conn->getData<
bool>(row, 3);
1670 user.
defaultDbId = conn->isNull(row, 4) ? -1 : conn->getData<
int>(row, 4);
1671 if (conn->isNull(row, 5)) {
1673 <<
"User property 'can_login' not set for user " << user.
userLoggable()
1674 <<
". Disabling login ability. Set the users login ability with \"ALTER USER "
1676 <<
" (can_login='true');\".";
1678 user.
can_login = conn->isNull(row, 5) ?
false : conn->getData<
bool>(row, 5);
1686 "SELECT userid, name, passwd_hash, issuper, default_db, can_login FROM mapd_users "
1693 user = *userit->second;
1705 "SELECT userid, name, passwd_hash, issuper, default_db, can_login FROM mapd_users "
1712 user = *userit->second;
1725 list<DBMetadata> db_list;
1726 for (
int r = 0; r < numRows; ++r) {
1731 db_list.push_back(db);
1739 std::unique_ptr<SqliteConnector>& sqliteConnector,
1740 const int32_t dbId = -1) {
1742 sqliteConnector->query(
1743 "SELECT userid, name, passwd_hash, issuper, default_db, can_login FROM mapd_users");
1744 int numRows = sqliteConnector->getNumRows();
1745 list<UserMetadata> user_list;
1746 const bool return_all_users = dbId == -1;
1747 auto has_any_privilege = [&return_all_users, &dbId, &syscat](
const std::string&
name) {
1748 if (!return_all_users) {
1754 for (
int r = 0; r < numRows; ++r) {
1757 if (has_any_privilege(user.
userName)) {
1758 user_list.emplace_back(std::move(user));
1764 if (has_any_privilege(userptr->userName)) {
1765 user_list.emplace_back(*userptr);
1787 const std::string& username,
1792 throw std::runtime_error(
"Invalid credentials.");
1795 if (!dbname.empty()) {
1797 throw std::runtime_error(
"Database name " + dbname +
" does not exist.");
1804 throw std::runtime_error(
1807 " which does not exist.");
1814 " does not exist.");
1826 "SELECT dbid, name, owner FROM mapd_databases WHERE UPPER(name) = ?",
1841 "SELECT dbid, name, owner FROM mapd_databases WHERE dbid = ?",
1859 std::map<int32_t, std::string> user_id_to_name_map;
1860 for (
const auto& user : user_list) {
1864 for (
auto d : db_list) {
1872 if (
auto it = user_id_to_name_map.find(d.dbOwner); it != user_id_to_name_map.end()) {
1883 const std::string& objectName,
1892 object.loadKey(catalog);
1907 object.setOwner(user.
userId);
1914 throw runtime_error(
"Cannot create DBObject. User " + user.
userLoggable() +
1915 " does not exist.");
1919 }
catch (std::exception& e) {
1927 const std::string& newName,
1932 DBObject new_object(newName, type);
1940 for (
auto obj : objdescs) {
1950 const vector<string>& grantees,
1951 const vector<DBObject>& objects,
1953 for (
const auto& grantee : grantees) {
1954 for (
const auto&
object : objects) {
1962 const std::string& granteeName,
1965 object.loadKey(catalog);
1966 CHECK(
object.valid());
1975 bool is_temporary_user{
false};
1985 throw runtime_error(
"Request to grant privileges to " + granteeName +
1986 " failed because role or user with this name does not exist.");
1988 grantee->grantPrivileges(
object);
1991 std::vector<std::string> objectKey =
object.toString();
1992 object.resetPrivileges();
1993 grantee->getPrivileges(
object,
true);
1995 if (!is_temporary_user) {
2036 const vector<string>& grantees,
2037 const vector<DBObject>& objects,
2039 for (
const auto& grantee : grantees) {
2040 for (
const auto&
object : objects) {
2047 vector<DBObject>& objects,
2049 for (
const auto&
object : objects) {
2056 const std::string& granteeName,
2062 bool is_temporary_user{
false};
2072 throw runtime_error(
"Request to revoke privileges from " + granteeName +
2073 " failed because role or user with this name does not exist.");
2075 object.loadKey(catalog);
2082 auto ret_object = grantee->revokePrivileges(
object);
2084 if (!is_temporary_user) {
2091 if (!is_temporary_user) {
2104 if (!is_temporary) {
2107 "DELETE FROM mapd_object_permissions WHERE roleName = ?1 and dbId = ?2",
2112 if (d->second->roleName == roleName && d->second->dbId == dbId) {
2131 if (grantee.second->findDbObject(dbObject.
getObjectKey(),
true)) {
2144 object.loadKey(catalog);
2145 auto* found_object = grantee->
findDbObject(
object.getObjectKey(),
false);
2146 if (found_object && found_object->getOwner() == user.
userId) {
2159 bool revoke_privileges) {
2162 throw std::runtime_error(
"ownership change not allowed for temporary user(s)");
2165 object.loadKey(catalog);
2166 switch (
object.getType()) {
2191 if (!previous_owner.
isSuper && revoke_privileges) {
2196 for (
const auto& update_query : update_queries) {
2198 update_query.text_params);
2201 auto object_key =
object.getObjectKey();
2203 "UPDATE mapd_object_permissions SET objectOwnerId = ? WHERE dbId = ? AND "
2204 "objectId = ? AND objectPermissionsType = ?",
2210 for (
const auto& [user_or_role, grantee] :
granteeMap_) {
2211 grantee->reassignObjectOwner(object_key, new_owner.
userId);
2215 if (map_object_descriptor->objectId == object_key.objectId &&
2216 map_object_descriptor->objectType == object_key.permissionType &&
2217 map_object_descriptor->dbId == object_key.dbId) {
2218 map_object_descriptor->objectOwnerId = new_owner.
userId;
2221 }
catch (std::exception& e) {
2233 bool revoke_privileges) {
2235 new_owner, previous_owner,
object, catalog, {}, revoke_privileges);
2246 throw runtime_error(
2247 "Request to show privileges from " + granteeName +
2248 " failed because user is super user and has all privileges by default.");
2253 throw runtime_error(
"Request to show privileges for " + granteeName +
2254 " failed because role or user with this name does not exist.");
2256 object.loadKey(catalog);
2257 grantee->getPrivileges(
object,
true);
2261 const bool user_private_role,
2262 const bool is_temporary) {
2267 throw std::runtime_error(
"CREATE ROLE " + roleName +
2268 " failed because grantee with this name already exists.");
2270 std::unique_ptr<Grantee> g;
2271 if (user_private_role) {
2272 g.reset(
new User(roleName));
2274 g.reset(
new Role(roleName));
2287 grantee->grantPrivileges(dbObject);
2289 if (!is_temporary) {
2300 if (d->second->roleName == roleName) {
2309 if (!is_temporary) {
2311 sqliteConnector_->query_with_text_param(
"DELETE FROM mapd_roles WHERE roleName = ?",
2314 "DELETE FROM mapd_object_permissions WHERE roleName = ?", roleName);
2319 const std::vector<std::string>& grantees) {
2320 for (
const auto& role : roles) {
2321 for (
const auto& grantee : grantees) {
2322 bool is_temporary_user{
false};
2334 const std::string& granteeName,
2335 const bool is_temporary) {
2338 throw runtime_error(
"Request to grant role " + roleName +
2339 " failed because role with this name does not exist.");
2343 throw runtime_error(
"Request to grant role " + roleName +
" failed because grantee " +
2344 granteeName +
" does not exist.");
2347 if (!grantee->hasRole(rl,
true)) {
2348 grantee->grantRole(rl);
2349 if (!is_temporary) {
2352 "INSERT INTO mapd_roles(roleName, userName) VALUES (?, ?)",
2353 std::vector<std::string>{rl->getName(), grantee->getName()});
2359 const std::vector<std::string>& grantees) {
2360 for (
const auto& role : roles) {
2361 for (
const auto& grantee : grantees) {
2362 bool is_temporary_user{
false};
2374 const std::string& granteeName,
2375 const bool is_temporary) {
2378 throw runtime_error(
"Request to revoke role " + roleName +
2379 " failed because role with this name does not exist.");
2383 throw runtime_error(
"Request to revoke role from " + granteeName +
2384 " failed because grantee with this name does not exist.");
2387 grantee->revokeRole(rl);
2388 if (!is_temporary) {
2391 "DELETE FROM mapd_roles WHERE roleName = ? AND userName = ?",
2392 std::vector<std::string>{rl->getName(), grantee->getName()});
2401 bool present =
false;
2402 auto privs =
object.getPrivileges();
2408 for (
auto d = range.first; d != range.second; ++d) {
2409 if (d->second->roleName == roleName) {
2411 d->second->privs = privs;
2416 auto od = std::make_unique<ObjectRoleDescriptor>();
2417 od->roleName = roleName;
2418 od->roleType = roleType;
2419 od->objectType =
object.getObjectKey().permissionType;
2420 od->dbId =
object.getObjectKey().dbId;
2421 od->objectId =
object.getObjectKey().objectId;
2422 od->privs =
object.getPrivileges();
2423 od->objectOwnerId =
object.getOwner();
2424 od->objectName =
object.getName();
2441 for (
auto d = range.first; d != range.second; ++d) {
2443 d->second->objectName =
object.getName();
2449 "UPDATE mapd_object_permissions SET objectName = ?1 WHERE "
2450 "dbId = ?2 AND objectId = ?3",
2451 std::vector<std::string>{
object.getName(),
2454 }
catch (
const std::exception& e) {
2466 if (d->second->roleName == roleName) {
2483 for (
auto d = range.first; d != range.second;) {
2485 if (d->second->roleName == roleName) {
2494 std::vector<DBObject>& privObjects) {
2501 throw runtime_error(
"Cannot check privileges. User " + user.
userLoggable() +
2502 " does not exist.");
2504 for (std::vector<DBObject>::iterator objectIt = privObjects.begin();
2505 objectIt != privObjects.end();
2507 if (!user_rl->hasAnyPrivileges(*objectIt,
false)) {
2515 const std::vector<DBObject>& privObjects)
const {
2523 throw runtime_error(
"Cannot check privileges. User " + user.
userLoggable() +
2524 " does not exist.");
2526 for (
auto&
object : privObjects) {
2527 if (!user_rl->checkPrivileges(
object)) {
2535 const std::vector<DBObject>& privObjects)
const {
2538 std::string
const loggable =
g_log_user_id ? std::string(
"") : userName +
' ';
2539 throw runtime_error(
"Request to check privileges for user " + loggable +
2540 "failed because user with this name does not exist.");
2551 return grantee->second.get();
2562 std::vector<ObjectRoleDescriptor*>
2565 std::vector<ObjectRoleDescriptor*> objectsList;
2570 for (
auto d = range.first; d != range.second; ++d) {
2571 objectsList.push_back(d->second.get());
2578 std::vector<ObjectRoleDescriptor> objects;
2580 auto object_role = entry.second.get();
2582 objects.emplace_back(*object_role);
2589 const std::string& roleName,
2590 bool only_direct)
const {
2592 if (roleName == granteeName) {
2595 bool is_role_granted =
false;
2597 auto has_role = [&](
auto grantee_rl) {
2598 is_role_granted = target_role && grantee_rl->
hasRole(target_role, only_direct);
2601 has_role(user_role);
2607 return is_role_granted;
2619 throw std::runtime_error(
"user or role not found");
2621 return grantee->getRoles(!effective);
2625 const int32_t dbId) {
2628 "SELECT DISTINCT roleName FROM mapd_object_permissions WHERE "
2629 "objectPermissions<>0 "
2630 "AND roleType=0 AND dbId=" +
2634 std::vector<std::string> roles(0);
2635 for (
int r = 0; r < numRows; ++r) {
2639 roles.push_back(roleName);
2647 const std::string& user_name,
2648 bool ignore_deleted_user) {
2650 if (ignore_deleted_user) {
2658 std::vector<std::string> roles;
2660 if (!include_user_private_role && grantee.second->isUser()) {
2670 roles.push_back(grantee.second->getName());
2677 std::set<std::string> roles;
2680 roles.emplace(grantee->getName());
2689 "SELECT roleName, roleType, objectPermissionsType, dbId, objectId, "
2690 "objectPermissions, objectOwnerId, objectName "
2691 "from mapd_object_permissions");
2694 std::vector<std::string> objectKeyStr(4);
2697 bool userPrivateRole{
false};
2698 for (
size_t r = 0; r < numRows; ++r) {
2711 DBObject dbObject(objectKey, privs, owner);
2712 dbObject.setName(name);
2713 if (-1 == objectKey.objectId) {
2716 dbObject.setObjectType(permissionType);
2721 std::unique_ptr<Grantee> g;
2722 if (userPrivateRole) {
2723 g.reset(
new User(roleName));
2725 g.reset(
new Role(roleName));
2730 rl->grantPrivileges(dbObject);
2739 for (
auto dbobject : objects) {
2746 grantee->grantPrivileges(dbobject);
2750 }
catch (
const std::exception& e) {
2758 std::vector<std::pair<std::string, std::string>> granteeRoles;
2759 string userRoleQuery(
"SELECT roleName, userName from mapd_roles");
2762 for (
size_t r = 0; r < numRows; ++r) {
2766 if ((boost::equals(roleName,
"mapd_default_suser_role") &&
2768 (boost::equals(roleName,
"mapd_default_user_role") &&
2769 !boost::equals(userName,
"mapd_default_user_role"))) {
2776 throw runtime_error(
"Data inconsistency when building role map. Role " + roleName +
2777 " from db not found in the map.");
2779 std::pair<std::string, std::string> roleVecElem(roleName, userName);
2780 granteeRoles.push_back(roleVecElem);
2783 for (
const auto& [roleName, granteeName] : granteeRoles) {
2786 throw runtime_error(
"Data inconsistency when building role map. Grantee " +
2787 granteeName +
" not found in the map.");
2789 if (granteeName == roleName) {
2794 throw runtime_error(
"Data inconsistency when building role map. Role " + roleName +
2795 " not found in the map.");
2797 grantee->grantRole(rl);
2804 "SELECT roleName, roleType, objectPermissionsType, dbId, objectId, "
2805 "objectPermissions, objectOwnerId, objectName "
2806 "from mapd_object_permissions");
2809 for (
size_t r = 0; r < numRows; ++r) {
2810 auto od = std::make_unique<ObjectRoleDescriptor>();
2826 template <
typename F,
typename... Args>
2832 (this->*
f)(std::forward<Args>(
args)...);
2833 }
catch (std::exception&) {
2841 const bool user_private_role,
2842 const bool is_temporary) {
2852 const std::vector<std::string>& grantees) {
2857 const std::string& grantee,
2858 const bool is_temporary) {
2863 const std::vector<std::string>& grantees) {
2868 const std::string& grantee,
2869 const bool is_temporary) {
2881 const vector<DBObject>& objects,
2895 const vector<string>& grantees,
2896 const vector<DBObject>& objects,
2913 std::vector<std::string> idp_roles,
2921 if (
auto user =
getUser(user_name); !user) {
2925 user =
createUser(user_name, alts, enable_idp_temporary_users);
2926 LOG(
INFO) <<
"Remote identity provider created user [" << user->userLoggable()
2927 <<
"] with (" << alts.
toString() <<
")";
2930 LOG(
INFO) <<
"Remote identity provider altered user [" << user->userLoggable()
2931 <<
"] with (" << alts.
toString() <<
")";
2933 std::vector<std::string> current_roles = {};
2936 current_roles = user_rl->getRoles();
2939 current_roles.begin(), current_roles.end(), current_roles.begin(),
to_upper);
2941 std::list<std::string> roles_revoked, roles_granted;
2943 for (
auto& current_role_name : current_roles) {
2944 if (std::find(idp_roles.begin(), idp_roles.end(), current_role_name) ==
2948 enable_idp_temporary_users);
2949 roles_revoked.push_back(current_role_name);
2952 for (
auto& role_name : idp_roles) {
2953 if (std::find(current_roles.begin(), current_roles.end(), role_name) ==
2954 current_roles.end()) {
2959 enable_idp_temporary_users);
2960 roles_granted.push_back(role_name);
2962 LOG(
WARNING) <<
"Error synchronizing roles for user " << user_name <<
": role "
2963 << role_name <<
" does not exist";
2967 if (roles_granted.empty() && roles_revoked.empty()) {
2968 LOG(
INFO) <<
"Roles for user " << user_name
2969 <<
" are up to date with remote identity provider";
2971 if (!roles_revoked.empty()) {
2972 LOG(
INFO) <<
"Roles revoked during synchronization with identity provider for user "
2973 << user_name <<
": " <<
join(roles_revoked,
" ");
2975 if (!roles_granted.empty()) {
2976 LOG(
INFO) <<
"Roles granted during synchronization with identity provider for user "
2977 << user_name <<
": " <<
join(roles_granted,
" ");
2982 std::unordered_map<std::string, std::vector<std::string>>
2985 std::unordered_map<std::string, std::vector<std::string>> active_grantees;
2988 for (
auto dash : dashboard_ids) {
2989 std::vector<std::string> grantees = {};
2991 "SELECT roleName FROM mapd_object_permissions WHERE objectPermissions NOT IN "
2992 "(0,1) AND objectPermissionsType = ? AND objectId = ?",
2993 std::vector<std::string>{
2996 if (num_rows == 0) {
3003 active_grantees[dash] = grantees;
3006 }
catch (
const std::exception& e) {
3011 return active_grantees;
3015 dbid_to_cat_map::const_accessor cata;
3017 return cata->second;
3029 dbid_to_cat_map::const_accessor cata;
3030 for (dbid_to_cat_map::iterator cat_it =
cat_map_.begin(); cat_it !=
cat_map_.end();
3032 if (cat_it->second->getDatabaseId() == db_id) {
3033 return cat_it->second;
3042 dbid_to_cat_map::const_accessor cata;
3044 return cata->second;
3050 auto cat = std::make_shared<Catalog>(
3053 dbid_to_cat_map::accessor cata;
3056 return cata->second;
3070 const std::map<int32_t, std::vector<DBObject>>& old_owner_db_objects,
3071 int32_t new_owner_id,
3080 for (
const auto& [old_owner_id, db_objects] : old_owner_db_objects) {
3091 std::set<int32_t> old_owner_ids;
3092 for (
const auto& [old_owner_id, db_objects] : old_owner_db_objects) {
3093 old_owner_ids.emplace(old_owner_id);
3097 for (
const auto old_user_id : old_owner_ids) {
3099 "UPDATE mapd_object_permissions SET objectOwnerId = ? WHERE objectOwnerId = ? "
3100 "AND dbId = ? AND objectId != -1",
3106 for (
const auto& [user_or_role, grantee] :
granteeMap_) {
3107 grantee->reassignObjectOwners(old_owner_ids, new_owner_id, db_id);
3111 if (object_descriptor->objectId != -1 && object_descriptor->dbId == db_id &&
3113 object_descriptor->objectOwnerId = new_owner_id;
3116 }
catch (std::exception& e) {
3130 <<
"\" already exists. System table creation will be skipped. Rename "
3131 "this database in order to use system tables.";
3149 "SELECT migration_history FROM mapd_version_history WHERE migration_history = ?",
3150 std::vector<std::string>{migration_name});
3162 "INSERT INTO mapd_version_history(version, migration_history) values(?, ?)",
3169 "select name from sqlite_master WHERE type='table' AND "
3170 "name='mapd_version_history'");
3177 "CREATE TABLE mapd_version_history(version integer, migration_history text "
3190 bool populate_fragmenter) {
3193 return catalog->getMetadataForTable(table_key.table_id, populate_fragmenter);
3199 return catalog->getMetadataForColumn(column_key.table_id, column_key.column_id);
std::optional< std::string > passwd
bool contains(const T &container, const U &element)
static const AccessPrivileges VIEW_SQL_EDITOR
auto get_users(SysCatalog &syscat, std::unique_ptr< SqliteConnector > &sqliteConnector, const int32_t dbId=-1)
void recordExecutedMigration(const std::string &migration_name) const
bool hasAnyPrivilegesOnDb(int32_t dbId, bool only_direct) const
void revokeAllOnDatabase_unsafe(const std::string &roleName, int32_t dbId, Grantee *grantee)
void migrateDBAccessPrivileges()
const std::string kDataDirectoryName
void revokeDBObjectPrivilegesBatch_unsafe(const std::vector< std::string > &grantees, const std::vector< DBObject > &objects, const Catalog_Namespace::Catalog &catalog)
std::tuple< int, std::string > ColumnKey
void dropUserUnchecked(const std::string &name, const UserMetadata &user)
std::vector< Catalog * > getCatalogsForAllDbs()
void dropUser(const std::string &name)
DBObjectKey getObjectKey() const
auto duplicateAndRenameCatalog(std::string const ¤t_name, std::string const &new_name)
std::optional< std::string > default_db
class for a per-database catalog. also includes metadata for the current database and the current use...
void changeDBObjectOwnership(const UserMetadata &new_owner, const UserMetadata &previous_owner, DBObject object, const Catalog_Namespace::Catalog &catalog, bool revoke_privileges=true)
heavyai::shared_lock< heavyai::shared_mutex > read_lock
static const AccessPrivileges ALL_DATABASE
virtual void grantPrivileges(const DBObject &object)
int32_t next_temporary_user_id_
void rebuildObjectMapsUnlocked()
std::set< std::string > getCreatedRoles() const
void grantRole(const std::string &role, const std::string &grantee, const bool is_temporary=false)
void updatePrivileges(const DBObject &object)
void revokeRole(const std::string &role, const std::string &grantee, const bool is_temporary=false)
static const AccessPrivileges ALL_TABLE_MIGRATE
bool checkPasswordForUser(const std::string &passwd, std::string &name, UserMetadata &user)
void revokeDBObjectPrivileges_unsafe(const std::string &granteeName, DBObject object, const Catalog_Namespace::Catalog &catalog)
static void relaxMigrationLock()
std::optional< UserMetadata > getUser(std::string const &uname)
void checkDuplicateCaseInsensitiveDbNames() const
void createRole_unsafe(const std::string &roleName, const bool userPrivateRole, const bool is_temporary)
void revokeDBObjectPrivilegesFromAll(DBObject object, Catalog *catalog)
bool getMetadataForUser(const std::string &name, UserMetadata &user)
void revokeDBObjectPrivileges(const std::string &grantee, const DBObject &object, const Catalog_Namespace::Catalog &catalog)
void removeCatalog(const std::string &dbName)
static bool parseUserMetadataFromSQLite(const std::unique_ptr< SqliteConnector > &conn, UserMetadata &user, int row)
void createRole(const std::string &roleName, const bool user_private_role, const bool is_temporary=false)
thread_holding_write_lock()
const TableDescriptor * get_metadata_for_table(const ::shared::TableKey &table_key, bool populate_fragmenter)
const std::string kSystemCatalogName
const ColumnDescriptor * get_metadata_for_column(const ::shared::ColumnKey &column_key)
void setObjectKey(const DBObjectKey &objectKey)
ObjectRoleDescriptorMap objectDescriptorMap_
void changeDatabaseOwner(std::string const &dbname, const std::string &new_owner)
void updatePasswordsToHashes()
Grantee * getGrantee(const std::string &name) const
void dropDatabase(const DBMetadata &db)
void loginImpl(std::string &username, const std::string &password, UserMetadata &user_meta)
void setName(std::string name)
std::vector< ObjectRoleDescriptor > getMetadataForAllObjects() const
heavyai::unique_lock< heavyai::shared_mutex > write_lock
const std::string kDefaultExportDirName
bool getMetadataForUserById(const int32_t idIn, UserMetadata &user)
void setPrivileges(const AccessPrivileges &privs)
void insertOrUpdateObjectPrivileges(std::unique_ptr< SqliteConnector > &sqliteConnector, std::string roleName, bool userRole, const DBObject &object)
const std::string kInfoSchemaDbName
void reassignObjectOwners(const std::map< int32_t, std::vector< DBObject >> &old_owner_db_objects, int32_t new_owner_id, const Catalog_Namespace::Catalog &catalog)
dsqliteMutex_(std::make_unique< heavyai::DistributedSharedMutex >(std::filesystem::path(basePath_)/shared::kLockfilesDirectoryName/shared::kCatalogDirectoryName/(currentDB_.dbName+".sqlite.lockfile")))
std::string toString(bool hide_password=true) const
std::list< UpdateQuery > UpdateQueries
void importDataFromOldMapdDB()
std::optional< bool > is_super
void createDBObject(const UserMetadata &user, const std::string &objectName, DBObjectType type, const Catalog_Namespace::Catalog &catalog, int32_t objectId=-1)
DBObject * findDbObject(const DBObjectKey &objectKey, bool only_direct) const
void getDBObjectPrivileges(const std::string &granteeName, DBObject &object, const Catalog_Namespace::Catalog &catalog) const
void revokeRole_unsafe(const std::string &roleName, const std::string &granteeName, const bool is_temporary)
bool hasVersionHistoryTable() const
void grantDBObjectPrivileges_unsafe(const std::string &granteeName, const DBObject object, const Catalog_Namespace::Catalog &catalog)
static const AccessPrivileges ALL_VIEW
void grantRoleBatch(const std::vector< std::string > &roles, const std::vector< std::string > &grantees)
std::unique_ptr< PkiServer > pki_server_
void revokeDBObjectPrivilegesBatch(const std::vector< std::string > &grantees, const std::vector< DBObject > &objects, const Catalog_Namespace::Catalog &catalog)
void updateBlankPasswordsToRandom()
void grantRoleBatch_unsafe(const std::vector< std::string > &roles, const std::vector< std::string > &grantees)
This file contains the class specification and related data structures for Catalog.
bool checkPrivileges(const UserMetadata &user, const std::vector< DBObject > &privObjects) const
void buildObjectDescriptorMapUnlocked()
void renameDBObject(const std::string &objectName, const std::string &newName, DBObjectType type, int32_t objectId, const Catalog_Namespace::Catalog &catalog)
static DBObjectKey fromString(const std::vector< std::string > &key, const DBObjectType &type)
static SysCatalog & instance()
This file contains the class specification and related data structures for SysCatalog.
bool g_enable_idp_temporary_users
bool wouldChange(UserMetadata const &user_meta) const
Classes representing a parse tree.
void setPermissionType(const DBObjectType &permissionType)
void getMetadataWithDefaultDB(std::string &dbname, const std::string &username, Catalog_Namespace::DBMetadata &db_meta, UserMetadata &user_meta)
auto yieldTransactionStreamer()
const DBMetadata & getCurrentDB() const
bool g_enable_system_tables
const std::string kDefaultDbName
void grantAllOnDatabase_unsafe(const std::string &roleName, DBObject &object, const Catalog_Namespace::Catalog &catalog)
static const std::string getForeignTableSchema(bool if_not_exists=false)
void init(LogOptions const &log_opts)
DEVICE auto copy(ARGS &&...args)
std::unordered_map< std::string, std::shared_ptr< UserMetadata > > temporary_users_by_name_
virtual void revokeAllOnDatabase(int32_t dbId)
std::string hash_with_bcrypt(const std::string &pwd)
void renameObjectsInDescriptorMap(DBObject &object, const Catalog_Namespace::Catalog &cat)
bool checkPasswordForUserImpl(const std::string &passwd, std::string &name, UserMetadata &user)
static bool migrationEnabled()
std::shared_ptr< Catalog > login(std::string &db, std::string &username, const std::string &password, UserMetadata &user_meta, bool check_password=true)
void revokeRoleBatch_unsafe(const std::vector< std::string > &roles, const std::vector< std::string > &grantees)
void grantRole_unsafe(const std::string &roleName, const std::string &granteeName, const bool is_temporary)
void revokeRoleBatch(const std::vector< std::string > &roles, const std::vector< std::string > &grantees)
std::shared_ptr< Data_Namespace::DataMgr > dataMgr_
UserMetadata createUser(std::string const &name, UserAlterations alts, bool is_temporary)
std::unique_lock< T > unique_lock
DBSummaryList getDatabaseListForUser(const UserMetadata &user)
static const int32_t MAPD_VERSION
static const AccessPrivileges ALL_DASHBOARD_MIGRATE
std::shared_ptr< Catalog > switchDatabase(std::string &dbname, const std::string &username)
Role * getRoleGrantee(const std::string &name) const
static const std::string getForeignServerSchema(bool if_not_exists=false)
int getDatabaseId() const
static const AccessPrivileges ALL_SERVER
void revokeDBObjectPrivilegesFromAllBatch_unsafe(std::vector< DBObject > &objects, Catalog *catalog)
User * getUserGrantee(const std::string &name) const
void grantDBObjectPrivilegesBatch(const std::vector< std::string > &grantees, const std::vector< DBObject > &objects, const Catalog_Namespace::Catalog &catalog)
void grantDBObjectPrivileges(const std::string &grantee, const DBObject &object, const Catalog_Namespace::Catalog &catalog)
specifies the content in-memory of a row in the column metadata table
OUTPUT transform(INPUT const &input, FUNC const &func)
std::unique_ptr< SqliteConnector > sqliteConnector_
static const AccessPrivileges NONE
void updateUserRoleName(const std::string &roleName, const std::string &newName)
std::list< UserMetadata > getAllUserMetadata()
void grantDBObjectPrivilegesBatch_unsafe(const std::vector< std::string > &grantees, const std::vector< DBObject > &objects, const Catalog_Namespace::Catalog &catalog)
static const std::string SYSTEM_ROLE_TAG("#dash_system_role")
specifies the content in-memory of a row in the dashboard
void buildUserRoleMapUnlocked()
void execInTransaction(F &&f, Args &&...args)
void dropRole_unsafe(const std::string &roleName, const bool is_temporary)
void check_for_session_encryption(const std::string &pki_cert, std::string &session)
void renameUser(std::string const &old_name, std::string const &new_name)
std::shared_ptr< Catalog > getCatalog(const std::string &dbName)
void migratePrivileged_old()
bool isRoleGrantedToGrantee(const std::string &granteeName, const std::string &roleName, bool only_direct) const
const std::string kRootUsername
void setObjectType(const DBObjectType &objectType)
bool hasAnyPrivileges(const UserMetadata &user, std::vector< DBObject > &privObjects)
void deleteObjectDescriptorMap(const std::string &roleName)
void updateSupportUserDeactivation()
static const AccessPrivileges ALL_VIEW_MIGRATE
static void takeMigrationLock(const std::string &base_path)
void checkAndExecuteMigrations()
void updateObjectDescriptorMap(const std::string &roleName, DBObject &object, bool roleType, const Catalog_Namespace::Catalog &cat)
std::unordered_map< int32_t, std::shared_ptr< UserMetadata > > temporary_users_by_id_
void syncUserWithRemoteProvider(const std::string &user_name, std::vector< std::string > idp_roles, UserAlterations alts)
const std::string kDefaultRootPasswd
void dropRole(const std::string &roleName, const bool is_temporary=false)
void createVersionHistoryTable() const
std::list< DBMetadata > getAllDBMetadata()
static const std::string getCustomExpressionsSchema(bool if_not_exists=false)
void renameDatabase(std::string const &old_name, std::string const &new_name)
void revokeDBObjectPrivilegesFromAll_unsafe(DBObject object, Catalog *catalog)
const std::string kRootUserIdStr
static const AccessPrivileges ALL_DASHBOARD
static const AccessPrivileges ACCESS
bool verifyDBObjectOwnership(const UserMetadata &user, DBObject object, const Catalog_Namespace::Catalog &catalog)
static const AccessPrivileges ALL_TABLE
const std::string kCatalogDirectoryName
std::vector< LeafHostInfo > string_dict_hosts_
bool hasRole(Role *role, bool only_direct) const
std::optional< bool > can_login
std::shared_ptr< Calcite > calciteMgr_
std::unordered_map< std::string, std::vector< std::string > > getGranteesOfSharedDashboards(const std::vector< std::string > &dashboard_ids)
void runUpdateQueriesAndChangeOwnership(const UserMetadata &new_owner, const UserMetadata &previous_owner, DBObject object, const Catalog_Namespace::Catalog &catalog, const UpdateQueries &update_queries, bool revoke_privileges=true)
const std::string kLockfilesDirectoryName
std::list< DBSummary > DBSummaryList
void populateRoleDbObjects(const std::vector< DBObject > &objects)
void deleteObjectPrivileges(std::unique_ptr< SqliteConnector > &sqliteConnector, std::string roleName, bool userRole, DBObject &object)
bool isDashboardSystemRole(const std::string &roleName) const
bool hasExecutedMigration(const std::string &migration_name) const
read_lock< SysCatalog > sys_read_lock
bool getMetadataForDBById(const int32_t idIn, DBMetadata &db)
void createDatabase(const std::string &dbname, int owner)
UserMetadata alterUser(std::string const &name, UserAlterations alts)
thread_holding_sqlite_lock()
void removeCatalogByFullPath(std::string const &full_path)
DEVICE void swap(ARGS &&...args)
const std::string kInfoSchemaMigrationName
std::vector< ObjectRoleDescriptor * > getMetadataForObject(int32_t dbId, int32_t dbType, int32_t objectId) const
std::vector< std::string > getRoles(const std::string &user_name, bool effective=true)
virtual void renameDbObject(const DBObject &object)
A selection of helper methods for File I/O.
void buildRoleMapUnlocked()
std::filesystem::path copy_catalog_if_read_only(std::filesystem::path base_data_path)
bool getMetadataForDB(const std::string &name, DBMetadata &db)
void revokeDBObjectPrivilegesFromAllBatch(std::vector< DBObject > &objects, Catalog *catalog)
void initializeInformationSchemaDb()