/Users/deen/code/yugabyte-db/src/yb/master/permissions_manager.h
Line | Count | Source |
1 | | // Copyright (c) YugaByte, Inc. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
4 | | // in compliance with the License. You may obtain a copy of the License at |
5 | | // |
6 | | // http://www.apache.org/licenses/LICENSE-2.0 |
7 | | // |
8 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
9 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
10 | | // or implied. See the License for the specific language governing permissions and limitations |
11 | | // under the License. |
12 | | // |
13 | | |
14 | | #ifndef YB_MASTER_PERMISSIONS_MANAGER_H |
15 | | #define YB_MASTER_PERMISSIONS_MANAGER_H |
16 | | |
17 | | #include <stdint.h> |
18 | | |
19 | | #include <set> |
20 | | #include <type_traits> |
21 | | #include <utility> |
22 | | |
23 | | #include <gflags/gflags_declare.h> |
24 | | #include <glog/logging.h> |
25 | | |
26 | | #include "yb/common/entity_ids.h" |
27 | | #include "yb/common/roles_permissions.h" |
28 | | |
29 | | #include "yb/gutil/callback.h" |
30 | | #include "yb/gutil/integral_types.h" |
31 | | |
32 | | #include "yb/master/catalog_manager.h" |
33 | | |
34 | | #include "yb/rpc/rpc.h" |
35 | | |
36 | | #include "yb/util/status_fwd.h" |
37 | | #include "yb/util/debug/lock_debug.h" |
38 | | #include "yb/util/math_util.h" |
39 | | #include "yb/util/shared_lock.h" |
40 | | #include "yb/util/status_callback.h" |
41 | | #include "yb/util/unique_lock.h" |
42 | | |
43 | | namespace yb { |
44 | | namespace master { |
45 | | |
46 | | class PermissionsManager final { |
47 | | public: |
48 | | explicit PermissionsManager(CatalogManager* catalog_manager); |
49 | | |
50 | | // Create a new role for authentication/authorization. |
51 | | // |
52 | | // The RPC context is provided for logging/tracing purposes. |
53 | | // but this function does not itself respond to the RPC. |
54 | | CHECKED_STATUS CreateRole(const CreateRoleRequestPB* req, |
55 | | CreateRoleResponsePB* resp, |
56 | | rpc::RpcContext* rpc) EXCLUDES(mutex_); |
57 | | |
58 | | // Alter an existing role for authentication/authorization. |
59 | | // |
60 | | // The RPC context is provided for logging/tracing purposes, |
61 | | // but this function does not itself respond to the RPC. |
62 | | CHECKED_STATUS AlterRole(const AlterRoleRequestPB* req, |
63 | | AlterRoleResponsePB* resp, |
64 | | rpc::RpcContext* rpc) EXCLUDES(mutex_); |
65 | | |
66 | | // Delete the role. |
67 | | // |
68 | | // The RPC context is provided for logging/tracing purposes, |
69 | | // but this function does not itself respond to the RPC. |
70 | | CHECKED_STATUS DeleteRole(const DeleteRoleRequestPB* req, |
71 | | DeleteRoleResponsePB* resp, |
72 | | rpc::RpcContext* rpc) EXCLUDES(mutex_); |
73 | | |
74 | | // Generic Create Role function for both default roles and user defined roles. |
75 | | CHECKED_STATUS CreateRoleUnlocked( |
76 | | const std::string& role_name, |
77 | | const std::string& salted_hash, |
78 | | const bool login, |
79 | | const bool superuser, |
80 | | int64_t term, |
81 | | // This value is only set to false during the creation of the |
82 | | // default role when it doesn't exist. |
83 | | const bool increment_roles_version = true) REQUIRES(mutex_); |
84 | | |
85 | | // Grant one role to another role. |
86 | | CHECKED_STATUS GrantRevokeRole(const GrantRevokeRoleRequestPB* req, |
87 | | GrantRevokeRoleResponsePB* resp, |
88 | | rpc::RpcContext* rpc) EXCLUDES(mutex_); |
89 | | |
90 | | // Grant/Revoke a permission to a role. |
91 | | CHECKED_STATUS GrantRevokePermission(const GrantRevokePermissionRequestPB* req, |
92 | | GrantRevokePermissionResponsePB* resp, |
93 | | rpc::RpcContext* rpc) EXCLUDES(mutex_); |
94 | | |
95 | | // Get all the permissions granted to resources. |
96 | | CHECKED_STATUS GetPermissions(const GetPermissionsRequestPB* req, |
97 | | GetPermissionsResponsePB* resp, |
98 | | rpc::RpcContext* rpc) EXCLUDES(mutex_); |
99 | | |
100 | | void BuildResourcePermissionsUnlocked() REQUIRES(mutex_); |
101 | | |
102 | | // Increment the version stored in roles_version_ if it exists. Otherwise, creates a |
103 | | // SysVersionInfo object with version equal to 0 to track the roles versions. |
104 | | CHECKED_STATUS IncrementRolesVersionUnlocked() REQUIRES_SHARED(mutex_); |
105 | | |
106 | | // Grant the specified permissions. |
107 | | template<class RespClass> |
108 | | CHECKED_STATUS GrantPermissions( |
109 | | const RoleName& role_name, |
110 | | const std::string& canonical_resource, |
111 | | const std::string& resource_name, |
112 | | const NamespaceName& keyspace, |
113 | | const std::vector<PermissionType>& permissions, |
114 | | const ResourceType resource_type, |
115 | | RespClass* resp) EXCLUDES(mutex_); |
116 | | |
117 | | // For each role in roles_map_ traverse all of its resources and delete any resource that matches |
118 | | // the given canonical resource. This is used when a table/keyspace/role is deleted so that we |
119 | | // don't leave old permissions alive. This is specially dangerous when a resource with the same |
120 | | // canonical name is created again. |
121 | | template<class RespClass> |
122 | | CHECKED_STATUS RemoveAllPermissionsForResourceUnlocked( |
123 | | const std::string& canonical_resource, RespClass* resp) |
124 | | REQUIRES(mutex_); |
125 | | |
126 | | template<class RespClass> |
127 | | CHECKED_STATUS RemoveAllPermissionsForResource(const std::string& canonical_resource, |
128 | | RespClass* resp) EXCLUDES(mutex_); |
129 | | |
130 | | CHECKED_STATUS PrepareDefaultRoles(int64_t term) EXCLUDES(mutex_); |
131 | | |
132 | | void GetAllRoles(std::vector<scoped_refptr<RoleInfo>>* roles) EXCLUDES(mutex_); |
133 | | |
134 | | // Find all the roles for which 'role' is a member of the list 'member_of'. |
135 | | std::vector<std::string> DirectMemberOf(const RoleName& role) REQUIRES_SHARED(mutex_); |
136 | | |
137 | | void TraverseRole(const string& role_name, std::unordered_set<RoleName>* granted_roles) |
138 | | REQUIRES_SHARED(mutex_); |
139 | | |
140 | | // Build the recursive map of roles (recursive_granted_roles_). If r1 is granted to r2, and r2 |
141 | | // is granted to r3, then recursive_granted_roles_["r3"] will contain roles r2, and r1. |
142 | | void BuildRecursiveRoles() EXCLUDES(mutex_); |
143 | | |
144 | | void BuildRecursiveRolesUnlocked() REQUIRES(mutex_); |
145 | | |
146 | | bool IsMemberOf(const RoleName& granted_role, const RoleName& role) REQUIRES_SHARED(mutex_); |
147 | | |
148 | | void AddRoleUnlocked(const RoleName& role_name, scoped_refptr<RoleInfo> role_info) |
149 | | REQUIRES(mutex_); |
150 | | void ClearRolesUnlocked() REQUIRES(mutex_); |
151 | | |
152 | | // This is invoked from PrepareDefaultSysConfig in catalog manger and sets up the default state of |
153 | | // of cluster security config. |
154 | | CHECKED_STATUS PrepareDefaultSecurityConfigUnlocked(int64_t term) |
155 | | REQUIRES(mutex_); |
156 | | |
157 | | // Sets the security config loaded from the sys catalog. |
158 | | void SetSecurityConfigOnLoadUnlocked(SysConfigInfo* security_config) |
159 | | REQUIRES(mutex_); |
160 | | |
161 | | using MutexType = rw_spinlock; |
162 | 4.37k | MutexType& mutex() RETURN_CAPABILITY(mutex_) { |
163 | 4.37k | return mutex_; |
164 | 4.37k | } |
165 | | |
166 | | private: |
167 | | // Role map: RoleName -> RoleInfo |
168 | | typedef std::unordered_map<RoleName, scoped_refptr<RoleInfo> > RoleInfoMap; |
169 | | RoleInfoMap roles_map_ GUARDED_BY(mutex_); |
170 | | |
171 | | typedef std::unordered_map<RoleName, std::unordered_set<RoleName>> RoleMemberMap; |
172 | | |
173 | | typedef std::string ResourceName; |
174 | | |
175 | | // Resource permissions map: resource -> permissions. |
176 | | typedef std::unordered_map<ResourceName, Permissions> ResourcePermissionsMap; |
177 | | |
178 | | // Role permissions map: role name -> map of resource permissions. |
179 | | typedef std::unordered_map<RoleName, ResourcePermissionsMap> RolePermissionsMap; |
180 | | |
181 | | // role_name -> set of granted roles (including those acquired transitively). |
182 | | RoleMemberMap recursive_granted_roles_ GUARDED_BY(mutex_); |
183 | | |
184 | | RolePermissionsMap recursive_granted_permissions_ GUARDED_BY(mutex_); |
185 | | |
186 | | // Permissions cache. Kept in a protobuf to avoid rebuilding it every time we receive a request |
187 | | // from a client. |
188 | | std::shared_ptr<GetPermissionsResponsePB> permissions_cache_ GUARDED_BY(mutex_); |
189 | | |
190 | | mutable MutexType mutex_ ACQUIRED_AFTER(catalog_manager_->mutex_); |
191 | | using SharedLock = NonRecursiveSharedLock<MutexType>; |
192 | | using LockGuard = std::lock_guard<MutexType>; |
193 | | |
194 | | // Cluster security config. |
195 | | scoped_refptr<SysConfigInfo> security_config_ GUARDED_BY(mutex_); |
196 | | |
197 | | CatalogManager* catalog_manager_; |
198 | | |
199 | | DISALLOW_COPY_AND_ASSIGN(PermissionsManager); |
200 | | }; |
201 | | |
202 | | } // namespace master |
203 | | } // namespace yb |
204 | | |
205 | | #endif // YB_MASTER_PERMISSIONS_MANAGER_H |