1 2 /** 3 * Copyright (C) 2018-present MongoDB, Inc. 4 * 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the Server Side Public License, version 1, 7 * as published by MongoDB, Inc. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * Server Side Public License for more details. 13 * 14 * You should have received a copy of the Server Side Public License 15 * along with this program. If not, see 16 * <http://www.mongodb.com/licensing/server-side-public-license>. 17 * 18 * As a special exception, the copyright holders give permission to link the 19 * code of portions of this program with the OpenSSL library under certain 20 * conditions as described in each individual source file and distribute 21 * linked combinations including the program with the OpenSSL library. You 22 * must comply with the Server Side Public License in all respects for 23 * all of the code used other than as permitted herein. If you modify file(s) 24 * with this exception, you may extend this exception to your version of the 25 * file(s), but you are not obligated to do so. If you do not wish to do so, 26 * delete this exception statement from your version. If you delete this 27 * exception statement from all source files in the program, then also delete 28 * it in the license file. 29 */ 30 31 #pragma once 32 33 #include <string> 34 #include <vector> 35 36 #include "mongo/base/disallow_copying.h" 37 #include "mongo/db/auth/privilege.h" 38 #include "mongo/db/auth/resource_pattern.h" 39 #include "mongo/db/auth/restriction_set.h" 40 #include "mongo/db/auth/role_name.h" 41 #include "mongo/db/auth/user_name.h" 42 #include "mongo/platform/atomic_word.h" 43 #include "mongo/platform/unordered_map.h" 44 #include "mongo/platform/unordered_set.h" 45 46 namespace mongo { 47 48 /** 49 * Represents a MongoDB user. Stores information about the user necessary for access control 50 * checks and authentications, such as what privileges this user has, as well as what roles 51 * the user belongs to. 52 * 53 * Every User object is owned by an AuthorizationManager. The AuthorizationManager is the only 54 * one that should construct, modify, or delete a User object. All other consumers of User must 55 * use only the const methods. The AuthorizationManager is responsible for maintaining the 56 * reference count on all User objects it gives out and must not mutate any User objects with 57 * a non-zero reference count (except to call invalidate()). Any consumer of a User object 58 * should check isInvalidated() before using it, and if it has been invalidated, it should 59 * return the object to the AuthorizationManager and fetch a new User object instance for this 60 * user from the AuthorizationManager. 61 */ 62 class User { 63 MONGO_DISALLOW_COPYING(User); 64 65 public: 66 struct SCRAMCredentials { SCRAMCredentialsSCRAMCredentials67 SCRAMCredentials() : iterationCount(0), salt(""), serverKey(""), storedKey("") {} 68 69 int iterationCount; 70 std::string salt; 71 std::string serverKey; 72 std::string storedKey; 73 isValidSCRAMCredentials74 bool isValid() const { 75 // 160bit -> 20octets -> * 4/3 -> 26.667 -> padded to 28 76 const size_t kEncodedSHA1Length = 28; 77 // 128bit -> 16octets -> * 4/3 -> 21.333 -> padded to 24 78 const size_t kEncodedSaltLength = 24; 79 80 return (salt.size() == kEncodedSaltLength) && base64::validate(salt) && 81 (serverKey.size() == kEncodedSHA1Length) && base64::validate(serverKey) && 82 (storedKey.size() == kEncodedSHA1Length) && base64::validate(storedKey); 83 } 84 }; 85 struct CredentialData { CredentialDataCredentialData86 CredentialData() : password(""), scram(), isExternal(false) {} 87 88 std::string password; 89 SCRAMCredentials scram; 90 bool isExternal; 91 }; 92 93 typedef unordered_map<ResourcePattern, Privilege> ResourcePrivilegeMap; 94 95 explicit User(const UserName& name); 96 ~User(); 97 98 using UserId = std::vector<std::uint8_t>; getID()99 const UserId& getID() const { 100 return _id; 101 } 102 setID(UserId id)103 void setID(UserId id) { 104 _id = std::move(id); 105 } 106 107 /** 108 * Returns the user name for this user. 109 */ 110 const UserName& getName() const; 111 112 /** 113 * Returns a digest of the user's identity 114 */ 115 const SHA256Block& getDigest() const; 116 117 /** 118 * Returns an iterator over the names of the user's direct roles 119 */ 120 RoleNameIterator getRoles() const; 121 122 /** 123 * Returns an iterator over the names of the user's indirect roles 124 */ 125 RoleNameIterator getIndirectRoles() const; 126 127 /** 128 * Returns true if this user is a member of the given role. 129 */ 130 bool hasRole(const RoleName& roleName) const; 131 132 /** 133 * Returns a reference to the information about the user's privileges. 134 */ getPrivileges()135 const ResourcePrivilegeMap& getPrivileges() const { 136 return _privileges; 137 } 138 139 /** 140 * Returns the CredentialData for this user. 141 */ 142 const CredentialData& getCredentials() const; 143 144 /** 145 * Gets the set of actions this user is allowed to perform on the given resource. 146 */ 147 const ActionSet getActionsForResource(const ResourcePattern& resource) const; 148 149 /** 150 * Returns true if this copy of information about this user is still valid. If this returns 151 * false, this object should no longer be used and should be returned to the 152 * AuthorizationManager and a new User object for this user should be requested. 153 */ 154 bool isValid() const; 155 156 /** 157 * This returns the reference count for this User. The AuthorizationManager should be the 158 * only caller of this. 159 */ 160 uint32_t getRefCount() const; 161 162 // Mutators below. Mutation functions should *only* be called by the AuthorizationManager 163 164 /** 165 * Sets this user's authentication credentials. 166 */ 167 void setCredentials(const CredentialData& credentials); 168 169 /** 170 * Replaces any existing user role membership information with the roles from "roles". 171 */ 172 void setRoles(RoleNameIterator roles); 173 174 /** 175 * Replaces any existing indirect user role membership information with the roles from 176 * "indirectRoles". 177 */ 178 void setIndirectRoles(RoleNameIterator indirectRoles); 179 180 /** 181 * Replaces any existing user privilege information with "privileges". 182 */ 183 void setPrivileges(const PrivilegeVector& privileges); 184 185 /** 186 * Adds the given role name to the list of roles of which this user is a member. 187 */ 188 void addRole(const RoleName& role); 189 190 /** 191 * Adds the given role names to the list of roles that this user belongs to. 192 */ 193 void addRoles(const std::vector<RoleName>& roles); 194 195 /** 196 * Adds the given privilege to the list of privileges this user is authorized for. 197 */ 198 void addPrivilege(const Privilege& privilege); 199 200 /** 201 * Adds the given privileges to the list of privileges this user is authorized for. 202 */ 203 void addPrivileges(const PrivilegeVector& privileges); 204 205 /** 206 * Replaces any existing authentication restrictions with "restrictions". 207 */ 208 void setRestrictions(RestrictionDocuments restrictions) &; 209 210 /** 211 * Gets any set authentication restrictions. 212 */ getRestrictions()213 const RestrictionDocuments& getRestrictions() const& noexcept { 214 return _restrictions; 215 } 216 void getRestrictions() && = delete; 217 218 /** 219 * Marks this instance of the User object as invalid, most likely because information about 220 * the user has been updated and needs to be reloaded from the AuthorizationManager. 221 * 222 * This method should *only* be called by the AuthorizationManager. 223 */ 224 void invalidate(); 225 226 /** 227 * Increments the reference count for this User object, which records how many threads have 228 * a reference to it. 229 * 230 * This method should *only* be called by the AuthorizationManager. 231 */ 232 void incrementRefCount(); 233 234 /** 235 * Decrements the reference count for this User object, which records how many threads have 236 * a reference to it. Once the reference count goes to zero, the AuthorizationManager is 237 * allowed to destroy this instance. 238 * 239 * This method should *only* be called by the AuthorizationManager. 240 */ 241 void decrementRefCount(); 242 243 private: 244 // Unique ID (often UUID) for this user. 245 // May be empty for legacy users. 246 UserId _id; 247 248 UserName _name; 249 250 // Digest of the full username 251 SHA256Block _digest; 252 253 // Maps resource name to privilege on that resource 254 ResourcePrivilegeMap _privileges; 255 256 // Roles the user has privileges from 257 unordered_set<RoleName> _roles; 258 259 // Roles that the user indirectly has privileges from, due to role inheritance. 260 std::vector<RoleName> _indirectRoles; 261 262 // Credential information. 263 CredentialData _credentials; 264 265 // Restrictions which must be met by a Client in order to authenticate as this user. 266 RestrictionDocuments _restrictions; 267 268 // _refCount and _isInvalidated are modified exclusively by the AuthorizationManager 269 // _isInvalidated can be read by any consumer of User, but _refCount can only be 270 // meaningfully read by the AuthorizationManager, as _refCount is guarded by the AM's _lock 271 uint32_t _refCount; 272 AtomicUInt32 _isValid; // Using as a boolean 273 }; 274 275 } // namespace mongo 276