OmniSciDB  29e35f4d58
SysCatalog.h
Go to the documentation of this file.
1 /*
2  * Copyright 2019 MapD Technologies, 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 "LinkDescriptor.h"
47 #include "ObjectRoleDescriptor.h"
48 #include "PkiServer.h"
49 #include "RestServer.h"
50 
51 #include "../DataMgr/DataMgr.h"
52 #include "../SqliteConnector/SqliteConnector.h"
53 #include "LeafHostInfo.h"
54 
55 #include "../Calcite/Calcite.h"
56 #include "../Shared/mapd_shared_mutex.h"
57 
58 const std::string OMNISCI_SYSTEM_CATALOG = "omnisci_system_catalog";
59 const std::string OMNISCI_DEFAULT_DB = "omnisci";
60 const std::string OMNISCI_ROOT_USER = "admin";
61 const int OMNISCI_ROOT_USER_ID = 0;
62 const std::string OMNISCI_ROOT_USER_ID_STR = "0";
63 const std::string OMNISCI_ROOT_PASSWD_DEFAULT = "HyperInteractive";
64 
65 class Calcite;
66 
67 namespace Catalog_Namespace {
68 
69 /*
70  * @type UserMetadata
71  * @brief metadata for a mapd user
72  */
73 struct UserMetadata {
74  UserMetadata(int32_t u,
75  const std::string& n,
76  const std::string& p,
77  bool s,
78  int32_t d,
79  bool l)
80  : userId(u)
81  , userName(n)
82  , passwd_hash(p)
83  , isSuper(s)
84  , defaultDbId(d)
85  , can_login(l) {}
87  UserMetadata(UserMetadata const& user_meta)
88  : UserMetadata(user_meta.userId,
89  user_meta.userName,
90  user_meta.passwd_hash,
91  user_meta.isSuper.load(),
92  user_meta.defaultDbId,
93  user_meta.can_login) {}
94  int32_t userId;
95  std::string userName;
96  std::string passwd_hash;
97  std::atomic<bool> isSuper{false};
98  int32_t defaultDbId;
99  bool can_login{true};
100 };
101 
102 /*
103  * @type DBMetadata
104  * @brief metadata for a mapd database
105  */
106 struct DBMetadata {
107  DBMetadata() : dbId(0), dbOwner(0) {}
108  int32_t dbId;
109  std::string dbName;
110  int32_t dbOwner;
111 };
112 
113 /*
114  * @type DBSummary
115  * @brief summary info for a mapd database
116  */
117 struct DBSummary {
118  std::string dbName;
119  std::string dbOwnerName;
120 };
121 using DBSummaryList = std::list<DBSummary>;
122 
124  public:
125  CommonFileOperations(std::string const& base_path) : base_path_(base_path) {}
126 
127  inline void removeCatalogByFullPath(std::string const& full_path);
128  inline void removeCatalogByName(std::string const& name);
129  inline auto duplicateAndRenameCatalog(std::string const& current_name,
130  std::string const& new_name);
131  inline auto assembleCatalogName(std::string const& name);
132 
133  private:
134  std::string const& base_path_;
135 };
136 
137 /*
138  * @type SysCatalog
139  * @brief class for the system-wide catalog, currently containing user and database
140  * metadata
141  */
143  public:
144  void init(const std::string& basePath,
145  std::shared_ptr<Data_Namespace::DataMgr> dataMgr,
146  const AuthMetadata& authMetadata,
147  std::shared_ptr<Calcite> calcite,
148  bool is_new_db,
149  bool aggregator,
150  const std::vector<LeafHostInfo>& string_dict_hosts);
151 
157  std::shared_ptr<Catalog> login(std::string& db,
158  std::string& username,
159  const std::string& password,
160  UserMetadata& user_meta,
161  bool check_password = true);
162  std::shared_ptr<Catalog> switchDatabase(std::string& dbname,
163  const std::string& username);
164  void createUser(const std::string& name,
165  const std::string& passwd,
166  bool issuper,
167  const std::string& dbname,
168  bool can_login);
169  void dropUser(const std::string& name);
170  void alterUser(const int32_t userid,
171  const std::string* passwd,
172  bool* issuper,
173  const std::string* dbname,
174  bool* can_login);
175  void renameUser(std::string const& old_name, std::string const& new_name);
176  void createDatabase(const std::string& dbname, int owner);
177  void renameDatabase(std::string const& old_name, std::string const& new_name);
178  void dropDatabase(const DBMetadata& db);
179  bool getMetadataForUser(const std::string& name, UserMetadata& user);
180  bool getMetadataForUserById(const int32_t idIn, UserMetadata& user);
181  bool checkPasswordForUser(const std::string& passwd,
182  std::string& name,
183  UserMetadata& user);
184  void getMetadataWithDefaultDB(std::string& dbname,
185  const std::string& username,
187  UserMetadata& user_meta);
188  bool getMetadataForDB(const std::string& name, DBMetadata& db);
189  bool getMetadataForDBById(const int32_t idIn, DBMetadata& db);
190  Data_Namespace::DataMgr& getDataMgr() const { return *dataMgr_; }
191  Calcite& getCalciteMgr() const { return *calciteMgr_; }
192  const std::string& getBasePath() const { return basePath_; }
193  SqliteConnector* getSqliteConnector() { return sqliteConnector_.get(); }
194  std::list<DBMetadata> getAllDBMetadata();
195  std::list<UserMetadata> getAllUserMetadata();
199  std::list<UserMetadata> getAllUserMetadata(const int64_t dbId);
200  DBSummaryList getDatabaseListForUser(const UserMetadata& user);
201  void createDBObject(const UserMetadata& user,
202  const std::string& objectName,
204  const Catalog_Namespace::Catalog& catalog,
205  int32_t objectId = -1);
206  void grantDBObjectPrivileges(const std::string& grantee,
207  const DBObject& object,
208  const Catalog_Namespace::Catalog& catalog);
209  void grantDBObjectPrivilegesBatch(const std::vector<std::string>& grantees,
210  const std::vector<DBObject>& objects,
211  const Catalog_Namespace::Catalog& catalog);
212  void revokeDBObjectPrivileges(const std::string& grantee,
213  const DBObject& object,
214  const Catalog_Namespace::Catalog& catalog);
215  void revokeDBObjectPrivilegesBatch(const std::vector<std::string>& grantees,
216  const std::vector<DBObject>& objects,
217  const Catalog_Namespace::Catalog& catalog);
218  void revokeDBObjectPrivilegesFromAll(DBObject object, Catalog* catalog);
219  void revokeDBObjectPrivilegesFromAll_unsafe(DBObject object, Catalog* catalog);
220  void getDBObjectPrivileges(const std::string& granteeName,
221  DBObject& object,
222  const Catalog_Namespace::Catalog& catalog) const;
223  bool verifyDBObjectOwnership(const UserMetadata& user,
224  DBObject object,
225  const Catalog_Namespace::Catalog& catalog);
226  void createRole(const std::string& roleName, const bool& userPrivateRole = false);
227  void dropRole(const std::string& roleName);
228  void grantRoleBatch(const std::vector<std::string>& roles,
229  const std::vector<std::string>& grantees);
230  void grantRole(const std::string& role, const std::string& grantee);
231  void revokeRoleBatch(const std::vector<std::string>& roles,
232  const std::vector<std::string>& grantees);
233  void revokeRole(const std::string& role, const std::string& grantee);
234  // check if the user has any permissions on all the given objects
235  bool hasAnyPrivileges(const UserMetadata& user, std::vector<DBObject>& privObjects);
236  // check if the user has the requested permissions on all the given objects
237  bool checkPrivileges(const UserMetadata& user,
238  const std::vector<DBObject>& privObjects) const;
239  bool checkPrivileges(const std::string& userName,
240  const std::vector<DBObject>& privObjects) const;
241  Grantee* getGrantee(const std::string& name) const;
242  Role* getRoleGrantee(const std::string& name) const;
243  User* getUserGrantee(const std::string& name) const;
244  std::vector<ObjectRoleDescriptor*> getMetadataForObject(int32_t dbId,
245  int32_t dbType,
246  int32_t objectId) const;
247  bool isRoleGrantedToGrantee(const std::string& granteeName,
248  const std::string& roleName,
249  bool only_direct) const;
250  std::vector<std::string> getRoles(bool userPrivateRole,
251  bool isSuper,
252  const std::string& userName);
253  std::vector<std::string> getRoles(const std::string& userName, const int32_t dbId);
254  void revokeDashboardSystemRole(const std::string roleName,
255  const std::vector<std::string> grantees);
256  bool isAggregator() const { return aggregator_; }
257  static SysCatalog& instance() {
258  static SysCatalog sys_cat{};
259  return sys_cat;
260  }
261 
262  void populateRoleDbObjects(const std::vector<DBObject>& objects);
263  std::string name() const { return OMNISCI_DEFAULT_DB; }
264  void renameObjectsInDescriptorMap(DBObject& object,
265  const Catalog_Namespace::Catalog& cat);
266  void syncUserWithRemoteProvider(const std::string& user_name,
267  std::vector<std::string> idp_roles,
268  bool* issuper);
269  std::unordered_map<std::string, std::vector<std::string>> getGranteesOfSharedDashboards(
270  const std::vector<std::string>& dashboard_ids);
271  void check_for_session_encryption(const std::string& pki_cert, std::string& session);
272 
273  private:
274  typedef std::map<std::string, Grantee*> GranteeMap;
275  typedef std::multimap<std::string, ObjectRoleDescriptor*> ObjectRoleDescriptorMap;
276 
278  : CommonFileOperations(basePath_)
279  , aggregator_(false)
280  , sqliteMutex_()
281  , sharedMutex_()
282  , thread_holding_sqlite_lock(std::thread::id())
283  , thread_holding_write_lock(std::thread::id()) {}
284  virtual ~SysCatalog();
285 
286  void initDB();
287  void buildRoleMap();
288  void buildUserRoleMap();
289  void buildObjectDescriptorMap();
290  void checkAndExecuteMigrations();
291  void importDataFromOldMapdDB();
292  void createUserRoles();
293  void migratePrivileges();
294  void migratePrivileged_old();
295  void updateUserSchema();
296  void updatePasswordsToHashes();
297  void updateBlankPasswordsToRandom();
298  void updateSupportUserDeactivation();
299  void migrateDBAccessPrivileges();
300 
301  void loginImpl(std::string& username,
302  const std::string& password,
303  UserMetadata& user_meta);
304  bool checkPasswordForUserImpl(const std::string& passwd,
305  std::string& name,
306  UserMetadata& user);
307 
308  // Here go functions not wrapped into transactions (necessary for nested calls)
309  void grantDefaultPrivilegesToRole_unsafe(const std::string& name, bool issuper);
310  void createRole_unsafe(const std::string& roleName,
311  const bool& userPrivateRole = false);
312  void dropRole_unsafe(const std::string& roleName);
313  void grantRoleBatch_unsafe(const std::vector<std::string>& roles,
314  const std::vector<std::string>& grantees);
315  void grantRole_unsafe(const std::string& roleName, const std::string& granteeName);
316  void revokeRoleBatch_unsafe(const std::vector<std::string>& roles,
317  const std::vector<std::string>& grantees);
318  void revokeRole_unsafe(const std::string& roleName, const std::string& granteeName);
319  void updateObjectDescriptorMap(const std::string& roleName,
320  DBObject& object,
321  bool roleType,
322  const Catalog_Namespace::Catalog& cat);
323  void deleteObjectDescriptorMap(const std::string& roleName);
324  void deleteObjectDescriptorMap(const std::string& roleName,
325  DBObject& object,
326  const Catalog_Namespace::Catalog& cat);
327  void grantDBObjectPrivilegesBatch_unsafe(const std::vector<std::string>& grantees,
328  const std::vector<DBObject>& objects,
329  const Catalog_Namespace::Catalog& catalog);
330  void grantDBObjectPrivileges_unsafe(const std::string& granteeName,
331  const DBObject object,
332  const Catalog_Namespace::Catalog& catalog);
333  void revokeDBObjectPrivilegesBatch_unsafe(const std::vector<std::string>& grantees,
334  const std::vector<DBObject>& objects,
335  const Catalog_Namespace::Catalog& catalog);
336  void revokeDBObjectPrivileges_unsafe(const std::string& granteeName,
337  DBObject object,
338  const Catalog_Namespace::Catalog& catalog);
339  void grantAllOnDatabase_unsafe(const std::string& roleName,
340  DBObject& object,
341  const Catalog_Namespace::Catalog& catalog);
342  void revokeAllOnDatabase_unsafe(const std::string& roleName,
343  int32_t dbId,
344  Grantee* grantee);
345  bool isDashboardSystemRole(const std::string& roleName);
346  void updateUserRoleName(const std::string& roleName, const std::string& newName);
347 
348  template <typename F, typename... Args>
349  void execInTransaction(F&& f, Args&&... args);
350 
351  std::string basePath_;
352  GranteeMap granteeMap_;
353  ObjectRoleDescriptorMap objectDescriptorMap_;
354  std::unique_ptr<SqliteConnector> sqliteConnector_;
355 
356  std::shared_ptr<Data_Namespace::DataMgr> dataMgr_;
357  std::unique_ptr<LdapServer> ldap_server_;
358  std::unique_ptr<RestServer> rest_server_;
359  std::unique_ptr<PkiServer> pki_server_;
361  std::shared_ptr<Calcite> calciteMgr_;
362  std::vector<LeafHostInfo> string_dict_hosts_;
364  auto yieldTransactionStreamer();
365 
366  public:
367  mutable std::mutex sqliteMutex_;
369  mutable std::atomic<std::thread::id> thread_holding_sqlite_lock;
370  mutable std::atomic<std::thread::id> thread_holding_write_lock;
371  static thread_local bool thread_holds_read_lock;
372 };
373 
374 } // namespace Catalog_Namespace
375 
376 #endif // SYS_CATALOG_H
std::unique_ptr< LdapServer > ldap_server_
Definition: SysCatalog.h:357
std::unique_ptr< RestServer > rest_server_
Definition: SysCatalog.h:358
std::string name() const
Definition: SysCatalog.h:263
SqliteConnector * getSqliteConnector()
Definition: SysCatalog.h:193
class for a per-database catalog. also includes metadata for the current database and the current use...
Definition: Catalog.h:81
DBObjectType
Definition: DBObject.h:42
Data_Namespace::DataMgr & getDataMgr() const
Definition: SysCatalog.h:190
UserMetadata(UserMetadata const &user_meta)
Definition: SysCatalog.h:87
std::atomic< std::thread::id > thread_holding_sqlite_lock
Definition: SysCatalog.h:369
ObjectRoleDescriptorMap objectDescriptorMap_
Definition: SysCatalog.h:353
const std::string OMNISCI_SYSTEM_CATALOG
Definition: SysCatalog.h:58
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:74
Definition: Grantee.h:76
const std::string & getBasePath() const
Definition: SysCatalog.h:192
std::unique_ptr< PkiServer > pki_server_
Definition: SysCatalog.h:359
const AuthMetadata * authMetadata_
Definition: SysCatalog.h:360
static SysCatalog & instance()
Definition: SysCatalog.h:257
void init(LogOptions const &log_opts)
Definition: Logger.cpp:272
const std::string OMNISCI_DEFAULT_DB
Definition: SysCatalog.h:59
std::shared_timed_mutex mapd_shared_mutex
std::shared_ptr< Data_Namespace::DataMgr > dataMgr_
Definition: SysCatalog.h:356
std::map< std::string, Grantee * > GranteeMap
Definition: SysCatalog.h:274
mapd_shared_mutex sharedMutex_
Definition: SysCatalog.h:368
std::unique_ptr< SqliteConnector > sqliteConnector_
Definition: SysCatalog.h:354
CommonFileOperations(std::string const &base_path)
Definition: SysCatalog.h:125
const std::string OMNISCI_ROOT_USER
Definition: SysCatalog.h:60
const std::string OMNISCI_ROOT_PASSWD_DEFAULT
Definition: SysCatalog.h:63
const int OMNISCI_ROOT_USER_ID
Definition: SysCatalog.h:61
Calcite & getCalciteMgr() const
Definition: SysCatalog.h:191
const std::string OMNISCI_ROOT_USER_ID_STR
Definition: SysCatalog.h:62
std::vector< LeafHostInfo > string_dict_hosts_
Definition: SysCatalog.h:362
std::shared_ptr< Calcite > calciteMgr_
Definition: SysCatalog.h:361
std::list< DBSummary > DBSummaryList
Definition: SysCatalog.h:121
static thread_local bool thread_holds_read_lock
Definition: SysCatalog.h:371
std::multimap< std::string, ObjectRoleDescriptor * > ObjectRoleDescriptorMap
Definition: SysCatalog.h:275
std::atomic< bool > isSuper
Definition: SysCatalog.h:97
std::atomic< std::thread::id > thread_holding_write_lock
Definition: SysCatalog.h:370