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