OmniSciDB  0b528656ed
SysCatalog.h
Go to the documentation of this file.
1 /*
2  * Copyright 2019 OmniSci, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
29 #ifndef SYS_CATALOG_H
30 #define SYS_CATALOG_H
31 
32 #include <atomic>
33 #include <cstdint>
34 #include <ctime>
35 #include <limits>
36 #include <list>
37 #include <map>
38 #include <mutex>
39 #include <string>
40 #include <unordered_map>
41 #include <utility>
42 #include <vector>
43 
44 #include "Grantee.h"
45 #include "LdapServer.h"
46 #include "ObjectRoleDescriptor.h"
47 #include "PkiServer.h"
48 #include "RestServer.h"
49 
50 #include "../DataMgr/DataMgr.h"
51 #include "../SqliteConnector/SqliteConnector.h"
52 #include "LeafHostInfo.h"
53 
54 #include "../Calcite/Calcite.h"
55 #include "../Shared/mapd_shared_mutex.h"
56 
57 const std::string OMNISCI_SYSTEM_CATALOG = "omnisci_system_catalog";
58 const std::string OMNISCI_DEFAULT_DB = "omnisci";
59 const std::string OMNISCI_ROOT_USER = "admin";
60 const int OMNISCI_ROOT_USER_ID = 0;
61 const std::string OMNISCI_ROOT_USER_ID_STR = "0";
62 const std::string OMNISCI_ROOT_PASSWD_DEFAULT = "HyperInteractive";
63 
64 class Calcite;
65 
66 namespace Catalog_Namespace {
67 
68 /*
69  * @type UserMetadata
70  * @brief metadata for a db user
71  */
72 struct UserMetadata {
73  UserMetadata(int32_t u,
74  const std::string& n,
75  const std::string& p,
76  bool s,
77  int32_t d,
78  bool l)
79  : userId(u)
80  , userName(n)
81  , passwd_hash(p)
82  , isSuper(s)
83  , defaultDbId(d)
84  , can_login(l) {}
86  UserMetadata(UserMetadata const& user_meta)
87  : UserMetadata(user_meta.userId,
88  user_meta.userName,
89  user_meta.passwd_hash,
90  user_meta.isSuper.load(),
91  user_meta.defaultDbId,
92  user_meta.can_login) {}
93  int32_t userId;
94  std::string userName;
95  std::string passwd_hash;
96  std::atomic<bool> isSuper{false};
97  int32_t defaultDbId;
98  bool can_login{true};
99 };
100 
101 /*
102  * @type DBMetadata
103  * @brief metadata for a database
104  */
105 struct DBMetadata {
106  DBMetadata() : dbId(0), dbOwner(0) {}
107  int32_t dbId;
108  std::string dbName;
109  int32_t dbOwner;
110 };
111 
112 /*
113  * @type DBSummary
114  * @brief summary info for a database
115  */
116 struct DBSummary {
117  std::string dbName;
118  std::string dbOwnerName;
119 };
120 using DBSummaryList = std::list<DBSummary>;
121 
123  public:
124  CommonFileOperations(std::string const& base_path) : base_path_(base_path) {}
125 
126  inline void removeCatalogByFullPath(std::string const& full_path);
127  inline void removeCatalogByName(std::string const& name);
128  inline auto duplicateAndRenameCatalog(std::string const& current_name,
129  std::string const& new_name);
130  inline auto assembleCatalogName(std::string const& name);
131 
132  private:
133  std::string const& base_path_;
134 };
135 
136 /*
137  * @type SysCatalog
138  * @brief class for the system-wide catalog, currently containing user and database
139  * metadata
140  */
142  public:
143  void init(const std::string& basePath,
144  std::shared_ptr<Data_Namespace::DataMgr> dataMgr,
145  const AuthMetadata& authMetadata,
146  std::shared_ptr<Calcite> calcite,
147  bool is_new_db,
148  bool aggregator,
149  const std::vector<LeafHostInfo>& string_dict_hosts);
150 
156  std::shared_ptr<Catalog> login(std::string& db,
157  std::string& username,
158  const std::string& password,
159  UserMetadata& user_meta,
160  bool check_password = true);
161  std::shared_ptr<Catalog> switchDatabase(std::string& dbname,
162  const std::string& username);
163  void createUser(const std::string& name,
164  const std::string& passwd,
165  bool issuper,
166  const std::string& dbname,
167  bool can_login);
168  void dropUser(const std::string& name);
169  void alterUser(const int32_t userid,
170  const std::string* passwd,
171  bool* issuper,
172  const std::string* dbname,
173  bool* can_login);
174  void renameUser(std::string const& old_name, std::string const& new_name);
175  void createDatabase(const std::string& dbname, int owner);
176  void renameDatabase(std::string const& old_name, std::string const& new_name);
177  void dropDatabase(const DBMetadata& db);
178  bool getMetadataForUser(const std::string& name, UserMetadata& user);
179  bool getMetadataForUserById(const int32_t idIn, UserMetadata& user);
180  bool checkPasswordForUser(const std::string& passwd,
181  std::string& name,
182  UserMetadata& user);
183  void getMetadataWithDefaultDB(std::string& dbname,
184  const std::string& username,
186  UserMetadata& user_meta);
187  bool getMetadataForDB(const std::string& name, DBMetadata& db);
188  bool getMetadataForDBById(const int32_t idIn, DBMetadata& db);
189  Data_Namespace::DataMgr& getDataMgr() const { return *dataMgr_; }
190  Calcite& getCalciteMgr() const { return *calciteMgr_; }
191  const std::string& getBasePath() const { return basePath_; }
192  SqliteConnector* getSqliteConnector() { return sqliteConnector_.get(); }
193  std::list<DBMetadata> getAllDBMetadata();
194  std::list<UserMetadata> getAllUserMetadata();
198  std::list<UserMetadata> getAllUserMetadata(const int64_t dbId);
199  DBSummaryList getDatabaseListForUser(const UserMetadata& user);
200  void createDBObject(const UserMetadata& user,
201  const std::string& objectName,
203  const Catalog_Namespace::Catalog& catalog,
204  int32_t objectId = -1);
214  void renameDBObject(const std::string& objectName,
215  const std::string& newName,
216  DBObjectType type,
217  int32_t objectId,
218  const Catalog_Namespace::Catalog& catalog);
219  void grantDBObjectPrivileges(const std::string& grantee,
220  const DBObject& object,
221  const Catalog_Namespace::Catalog& catalog);
222  void grantDBObjectPrivilegesBatch(const std::vector<std::string>& grantees,
223  const std::vector<DBObject>& objects,
224  const Catalog_Namespace::Catalog& catalog);
225  void revokeDBObjectPrivileges(const std::string& grantee,
226  const DBObject& object,
227  const Catalog_Namespace::Catalog& catalog);
228  void revokeDBObjectPrivilegesBatch(const std::vector<std::string>& grantees,
229  const std::vector<DBObject>& objects,
230  const Catalog_Namespace::Catalog& catalog);
231  void revokeDBObjectPrivilegesFromAll(DBObject object, Catalog* catalog);
232  void revokeDBObjectPrivilegesFromAll_unsafe(DBObject object, Catalog* catalog);
233  void getDBObjectPrivileges(const std::string& granteeName,
234  DBObject& object,
235  const Catalog_Namespace::Catalog& catalog) const;
236  bool verifyDBObjectOwnership(const UserMetadata& user,
237  DBObject object,
238  const Catalog_Namespace::Catalog& catalog);
248  void changeDBObjectOwnership(const UserMetadata& new_owner,
249  const UserMetadata& previous_owner,
250  DBObject object,
251  const Catalog_Namespace::Catalog& catalog,
252  bool revoke_privileges = true);
253  void createRole(const std::string& roleName, const bool& userPrivateRole = false);
254  void dropRole(const std::string& roleName);
255  void grantRoleBatch(const std::vector<std::string>& roles,
256  const std::vector<std::string>& grantees);
257  void grantRole(const std::string& role, const std::string& grantee);
258  void revokeRoleBatch(const std::vector<std::string>& roles,
259  const std::vector<std::string>& grantees);
260  void revokeRole(const std::string& role, const std::string& grantee);
261  // check if the user has any permissions on all the given objects
262  bool hasAnyPrivileges(const UserMetadata& user, std::vector<DBObject>& privObjects);
263  // check if the user has the requested permissions on all the given objects
264  bool checkPrivileges(const UserMetadata& user,
265  const std::vector<DBObject>& privObjects) const;
266  bool checkPrivileges(const std::string& userName,
267  const std::vector<DBObject>& privObjects) const;
268  Grantee* getGrantee(const std::string& name) const;
269  Role* getRoleGrantee(const std::string& name) const;
270  User* getUserGrantee(const std::string& name) const;
271  std::vector<ObjectRoleDescriptor*> getMetadataForObject(int32_t dbId,
272  int32_t dbType,
273  int32_t objectId) const;
274  bool isRoleGrantedToGrantee(const std::string& granteeName,
275  const std::string& roleName,
276  bool only_direct) const;
277  std::vector<std::string> getRoles(bool userPrivateRole,
278  bool isSuper,
279  const std::string& userName);
280  std::vector<std::string> getRoles(const std::string& userName, const int32_t dbId);
281  void revokeDashboardSystemRole(const std::string roleName,
282  const std::vector<std::string> grantees);
283  bool isAggregator() const { return aggregator_; }
284  static SysCatalog& instance() {
285  static SysCatalog sys_cat{};
286  return sys_cat;
287  }
288 
289  void populateRoleDbObjects(const std::vector<DBObject>& objects);
290  std::string name() const { return OMNISCI_DEFAULT_DB; }
291  void renameObjectsInDescriptorMap(DBObject& object,
293  void syncUserWithRemoteProvider(const std::string& user_name,
294  std::vector<std::string> idp_roles,
295  bool* issuper);
296  std::unordered_map<std::string, std::vector<std::string>> getGranteesOfSharedDashboards(
297  const std::vector<std::string>& dashboard_ids);
298  void check_for_session_encryption(const std::string& pki_cert, std::string& session);
299 
300  private:
301  using GranteeMap = std::map<std::string, Grantee*>;
302  using ObjectRoleDescriptorMap = std::multimap<std::string, ObjectRoleDescriptor*>;
303 
305  : CommonFileOperations(basePath_)
306  , aggregator_(false)
307  , sqliteMutex_()
308  , sharedMutex_()
309  , thread_holding_sqlite_lock(std::thread::id())
310  , thread_holding_write_lock(std::thread::id()) {}
311  virtual ~SysCatalog();
312 
313  void initDB();
314  void buildRoleMap();
315  void buildUserRoleMap();
316  void buildObjectDescriptorMap();
317  void checkAndExecuteMigrations();
318  void importDataFromOldMapdDB();
319  void createUserRoles();
320  void migratePrivileges();
321  void migratePrivileged_old();
322  void updateUserSchema();
323  void updatePasswordsToHashes();
324  void updateBlankPasswordsToRandom();
325  void updateSupportUserDeactivation();
326  void migrateDBAccessPrivileges();
327  void loginImpl(std::string& username,
328  const std::string& password,
329  UserMetadata& user_meta);
330  bool checkPasswordForUserImpl(const std::string& passwd,
331  std::string& name,
332  UserMetadata& user);
333 
334  // Here go functions not wrapped into transactions (necessary for nested calls)
335  void grantDefaultPrivilegesToRole_unsafe(const std::string& name, bool issuper);
336  void createRole_unsafe(const std::string& roleName,
337  const bool& userPrivateRole = false);
338  void dropRole_unsafe(const std::string& roleName);
339  void grantRoleBatch_unsafe(const std::vector<std::string>& roles,
340  const std::vector<std::string>& grantees);
341  void grantRole_unsafe(const std::string& roleName, const std::string& granteeName);
342  void revokeRoleBatch_unsafe(const std::vector<std::string>& roles,
343  const std::vector<std::string>& grantees);
344  void revokeRole_unsafe(const std::string& roleName, const std::string& granteeName);
345  void updateObjectDescriptorMap(const std::string& roleName,
346  DBObject& object,
347  bool roleType,
348  const Catalog_Namespace::Catalog& cat);
349  void deleteObjectDescriptorMap(const std::string& roleName);
350  void deleteObjectDescriptorMap(const std::string& roleName,
351  DBObject& object,
352  const Catalog_Namespace::Catalog& cat);
353  void grantDBObjectPrivilegesBatch_unsafe(const std::vector<std::string>& grantees,
354  const std::vector<DBObject>& objects,
355  const Catalog_Namespace::Catalog& catalog);
356  void grantDBObjectPrivileges_unsafe(const std::string& granteeName,
357  const DBObject object,
358  const Catalog_Namespace::Catalog& catalog);
359  void revokeDBObjectPrivilegesBatch_unsafe(const std::vector<std::string>& grantees,
360  const std::vector<DBObject>& objects,
361  const Catalog_Namespace::Catalog& catalog);
362  void revokeDBObjectPrivileges_unsafe(const std::string& granteeName,
363  DBObject object,
364  const Catalog_Namespace::Catalog& catalog);
365  void grantAllOnDatabase_unsafe(const std::string& roleName,
366  DBObject& object,
367  const Catalog_Namespace::Catalog& catalog);
368  void revokeAllOnDatabase_unsafe(const std::string& roleName,
369  int32_t dbId,
370  Grantee* grantee);
371  bool isDashboardSystemRole(const std::string& roleName);
372  void updateUserRoleName(const std::string& roleName, const std::string& newName);
373 
374  template <typename F, typename... Args>
375  void execInTransaction(F&& f, Args&&... args);
376 
377  std::string basePath_;
380  std::unique_ptr<SqliteConnector> sqliteConnector_;
381 
382  std::shared_ptr<Data_Namespace::DataMgr> dataMgr_;
383  std::unique_ptr<LdapServer> ldap_server_;
384  std::unique_ptr<RestServer> rest_server_;
385  std::unique_ptr<PkiServer> pki_server_;
387  std::shared_ptr<Calcite> calciteMgr_;
388  std::vector<LeafHostInfo> string_dict_hosts_;
390  auto yieldTransactionStreamer();
391 
392  public:
393  mutable std::mutex sqliteMutex_;
395  mutable std::atomic<std::thread::id> thread_holding_sqlite_lock;
396  mutable std::atomic<std::thread::id> thread_holding_write_lock;
397  static thread_local bool thread_holds_read_lock;
398 };
399 
400 } // namespace Catalog_Namespace
401 
402 #endif // SYS_CATALOG_H
std::unique_ptr< LdapServer > ldap_server_
Definition: SysCatalog.h:383
std::unique_ptr< RestServer > rest_server_
Definition: SysCatalog.h:384
std::string name() const
Definition: SysCatalog.h:290
SqliteConnector * getSqliteConnector()
Definition: SysCatalog.h:192
class for a per-database catalog. also includes metadata for the current database and the current use...
Definition: Catalog.h:86
DBObjectType
Definition: DBObject.h:42
std::map< std::string, Grantee * > GranteeMap
Definition: SysCatalog.h:301
Data_Namespace::DataMgr & getDataMgr() const
Definition: SysCatalog.h:189
UserMetadata(UserMetadata const &user_meta)
Definition: SysCatalog.h:86
std::atomic< std::thread::id > thread_holding_sqlite_lock
Definition: SysCatalog.h:395
ObjectRoleDescriptorMap objectDescriptorMap_
Definition: SysCatalog.h:379
const std::string OMNISCI_SYSTEM_CATALOG
Definition: SysCatalog.h:57
Definition: Grantee.h:70
UserMetadata(int32_t u, const std::string &n, const std::string &p, bool s, int32_t d, bool l)
Definition: SysCatalog.h:73
Definition: Grantee.h:76
const std::string & getBasePath() const
Definition: SysCatalog.h:191
std::unique_ptr< PkiServer > pki_server_
Definition: SysCatalog.h:385
const AuthMetadata * authMetadata_
Definition: SysCatalog.h:386
static SysCatalog & instance()
Definition: SysCatalog.h:284
std::string cat(Ts &&... args)
void init(LogOptions const &log_opts)
Definition: Logger.cpp:276
const std::string OMNISCI_DEFAULT_DB
Definition: SysCatalog.h:58
std::shared_timed_mutex mapd_shared_mutex
std::shared_ptr< Data_Namespace::DataMgr > dataMgr_
Definition: SysCatalog.h:382
mapd_shared_mutex sharedMutex_
Definition: SysCatalog.h:394
std::unique_ptr< SqliteConnector > sqliteConnector_
Definition: SysCatalog.h:380
CommonFileOperations(std::string const &base_path)
Definition: SysCatalog.h:124
const std::string OMNISCI_ROOT_USER
Definition: SysCatalog.h:59
const std::string OMNISCI_ROOT_PASSWD_DEFAULT
Definition: SysCatalog.h:62
const int OMNISCI_ROOT_USER_ID
Definition: SysCatalog.h:60
Calcite & getCalciteMgr() const
Definition: SysCatalog.h:190
const std::string OMNISCI_ROOT_USER_ID_STR
Definition: SysCatalog.h:61
std::vector< LeafHostInfo > string_dict_hosts_
Definition: SysCatalog.h:388
std::shared_ptr< Calcite > calciteMgr_
Definition: SysCatalog.h:387
std::list< DBSummary > DBSummaryList
Definition: SysCatalog.h:120
static thread_local bool thread_holds_read_lock
Definition: SysCatalog.h:397
std::multimap< std::string, ObjectRoleDescriptor * > ObjectRoleDescriptorMap
Definition: SysCatalog.h:302
std::atomic< bool > isSuper
Definition: SysCatalog.h:96
std::atomic< std::thread::id > thread_holding_write_lock
Definition: SysCatalog.h:396