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 #include "mongo/db/auth/user.h"
32
33 #include <vector>
34
35 #include "mongo/db/auth/authorization_manager.h"
36 #include "mongo/db/auth/privilege.h"
37 #include "mongo/db/auth/resource_pattern.h"
38 #include "mongo/db/auth/role_name.h"
39 #include "mongo/db/auth/user_name.h"
40 #include "mongo/platform/atomic_word.h"
41 #include "mongo/util/assert_util.h"
42 #include "mongo/util/sequence_util.h"
43
44 namespace mongo {
45
46 namespace {
47
computeDigest(const UserName & name)48 SHA256Block computeDigest(const UserName& name) {
49 const auto& fn = name.getFullName();
50 return SHA256Block::computeHash({ConstDataRange(fn.c_str(), fn.size())});
51 };
52
53 } // namespace
54
User(const UserName & name)55 User::User(const UserName& name)
56 : _name(name), _digest(computeDigest(_name)), _refCount(0), _isValid(1) {}
57
~User()58 User::~User() {
59 dassert(_refCount == 0);
60 }
61
getName() const62 const UserName& User::getName() const {
63 return _name;
64 }
65
getDigest() const66 const SHA256Block& User::getDigest() const {
67 return _digest;
68 }
69
getRoles() const70 RoleNameIterator User::getRoles() const {
71 return makeRoleNameIteratorForContainer(_roles);
72 }
73
getIndirectRoles() const74 RoleNameIterator User::getIndirectRoles() const {
75 return makeRoleNameIteratorForContainer(_indirectRoles);
76 }
77
hasRole(const RoleName & roleName) const78 bool User::hasRole(const RoleName& roleName) const {
79 return _roles.count(roleName);
80 }
81
getCredentials() const82 const User::CredentialData& User::getCredentials() const {
83 return _credentials;
84 }
85
isValid() const86 bool User::isValid() const {
87 return _isValid.loadRelaxed() == 1;
88 }
89
getRefCount() const90 uint32_t User::getRefCount() const {
91 return _refCount;
92 }
93
getActionsForResource(const ResourcePattern & resource) const94 const ActionSet User::getActionsForResource(const ResourcePattern& resource) const {
95 unordered_map<ResourcePattern, Privilege>::const_iterator it = _privileges.find(resource);
96 if (it == _privileges.end()) {
97 return ActionSet();
98 }
99 return it->second.getActions();
100 }
101
setCredentials(const CredentialData & credentials)102 void User::setCredentials(const CredentialData& credentials) {
103 _credentials = credentials;
104 }
105
setRoles(RoleNameIterator roles)106 void User::setRoles(RoleNameIterator roles) {
107 _roles.clear();
108 while (roles.more()) {
109 _roles.insert(roles.next());
110 }
111 }
112
setIndirectRoles(RoleNameIterator indirectRoles)113 void User::setIndirectRoles(RoleNameIterator indirectRoles) {
114 _indirectRoles.clear();
115 while (indirectRoles.more()) {
116 _indirectRoles.push_back(indirectRoles.next());
117 }
118 }
119
setPrivileges(const PrivilegeVector & privileges)120 void User::setPrivileges(const PrivilegeVector& privileges) {
121 _privileges.clear();
122 for (size_t i = 0; i < privileges.size(); ++i) {
123 const Privilege& privilege = privileges[i];
124 _privileges[privilege.getResourcePattern()] = privilege;
125 }
126 }
127
addRole(const RoleName & roleName)128 void User::addRole(const RoleName& roleName) {
129 _roles.insert(roleName);
130 }
131
addRoles(const std::vector<RoleName> & roles)132 void User::addRoles(const std::vector<RoleName>& roles) {
133 for (std::vector<RoleName>::const_iterator it = roles.begin(); it != roles.end(); ++it) {
134 addRole(*it);
135 }
136 }
137
addPrivilege(const Privilege & privilegeToAdd)138 void User::addPrivilege(const Privilege& privilegeToAdd) {
139 ResourcePrivilegeMap::iterator it = _privileges.find(privilegeToAdd.getResourcePattern());
140 if (it == _privileges.end()) {
141 // No privilege exists yet for this resource
142 _privileges.insert(std::make_pair(privilegeToAdd.getResourcePattern(), privilegeToAdd));
143 } else {
144 dassert(it->first == privilegeToAdd.getResourcePattern());
145 it->second.addActions(privilegeToAdd.getActions());
146 }
147 }
148
addPrivileges(const PrivilegeVector & privileges)149 void User::addPrivileges(const PrivilegeVector& privileges) {
150 for (PrivilegeVector::const_iterator it = privileges.begin(); it != privileges.end(); ++it) {
151 addPrivilege(*it);
152 }
153 }
154
setRestrictions(RestrictionDocuments restrictions)155 void User::setRestrictions(RestrictionDocuments restrictions)& {
156 _restrictions = std::move(restrictions);
157 }
158
invalidate()159 void User::invalidate() {
160 _isValid.store(0);
161 }
162
incrementRefCount()163 void User::incrementRefCount() {
164 ++_refCount;
165 }
166
decrementRefCount()167 void User::decrementRefCount() {
168 dassert(_refCount > 0);
169 --_refCount;
170 }
171 } // namespace mongo
172