2
* Copyright (C) 2012 10gen Inc.
4
* This program is free software: you can redistribute it and/or modify
5
* it under the terms of the GNU Affero General Public License, version 3,
6
* as published by the Free Software Foundation.
8
* This program is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
* GNU Affero General Public License for more details.
13
* You should have received a copy of the GNU Affero General Public License
14
* along with this program. If not, see <http://www.gnu.org/licenses/>.
22
#include "mongo/base/disallow_copying.h"
23
#include "mongo/base/status.h"
24
#include "mongo/db/auth/action_set.h"
25
#include "mongo/db/auth/action_type.h"
26
#include "mongo/db/auth/auth_external_state.h"
27
#include "mongo/db/auth/principal.h"
28
#include "mongo/db/auth/principal_name.h"
29
#include "mongo/db/auth/principal_set.h"
30
#include "mongo/db/auth/privilege.h"
31
#include "mongo/db/auth/privilege_set.h"
35
// --noauth cmd line option
39
* Internal secret key info.
46
extern AuthInfo internalSecurity; // set at startup and not changed after initialization.
49
* Contains all the authorization logic for a single client connection. It contains a set of
50
* the principals which have been authenticated, as well as a set of privileges that have been
51
* granted by those principals to perform various actions.
52
* An AuthorizationManager object is present within every mongo::Client object, therefore there
53
* is one per thread that corresponds to an incoming client connection.
55
class AuthorizationManager {
56
MONGO_DISALLOW_COPYING(AuthorizationManager);
59
static const std::string SERVER_RESOURCE_NAME;
60
static const std::string CLUSTER_RESOURCE_NAME;
62
static const std::string USER_NAME_FIELD_NAME;
63
static const std::string USER_SOURCE_FIELD_NAME;
64
static const std::string PASSWORD_FIELD_NAME;
66
static void setSupportOldStylePrivilegeDocuments(bool enabled);
68
// Checks to see if "doc" is a valid privilege document, assuming it is stored in the
69
// "system.users" collection of database "dbname".
71
// Returns Status::OK() if the document is good, or Status(ErrorCodes::BadValue), otherwise.
72
static Status checkValidPrivilegeDocument(const StringData& dbname, const BSONObj& doc);
74
// Takes ownership of the externalState.
75
explicit AuthorizationManager(AuthExternalState* externalState);
76
~AuthorizationManager();
78
// Should be called at the beginning of every new request. This performs the checks
79
// necessary to determine if localhost connections should be given full access.
80
// TODO: try to eliminate the need for this call.
83
// Adds "principal" to the authorization manager, and takes ownership of it.
84
void addAuthorizedPrincipal(Principal* principal);
86
// Returns the authenticated principal with the given name. Returns NULL
87
// if no such user is found.
88
// Ownership of the returned Principal remains with _authenticatedPrincipals
89
Principal* lookupPrincipal(const PrincipalName& name);
91
// Gets an iterator over the names of all authenticated principals stored in this manager.
92
PrincipalSet::NameIterator getAuthenticatedPrincipalNames();
94
// Removes any authenticated principals whose authorization credentials came from the given
95
// database, and revokes any privileges that were granted via that principal.
96
void logoutDatabase(const std::string& dbname);
98
// Grant this connection the given privilege.
99
Status acquirePrivilege(const Privilege& privilege,
100
const PrincipalName& authorizingPrincipal);
102
// Adds a new principal with the given principal name and authorizes it with full access.
103
// Used to grant internal threads full access.
104
void grantInternalAuthorization(const std::string& principalName);
106
// Checks if this connection has been authenticated as an internal user.
107
bool hasInternalAuthorization();
109
// Checks if this connection has the privileges required to perform the given action
110
// on the given resource. Contains all the authorization logic including handling things
111
// like the localhost exception. Returns true if the action may proceed on the resource.
112
// Note: this may acquire a database read lock (for automatic privilege acquisition).
113
bool checkAuthorization(const std::string& resource, ActionType action);
115
// Same as above but takes an ActionSet instead of a single ActionType. Returns true if
116
// all of the actions may proceed on the resource.
117
bool checkAuthorization(const std::string& resource, ActionSet actions);
119
// Parses the privilege documents and acquires all privileges that the privilege document
121
Status acquirePrivilegesFromPrivilegeDocument(const std::string& dbname,
122
const PrincipalName& principal,
123
const BSONObj& privilegeDocument);
125
// Returns the privilege document with the given user name in the given database. Currently
126
// this information comes from the system.users collection in that database.
127
Status getPrivilegeDocument(const std::string& dbname,
128
const PrincipalName& userName,
130
return _externalState->getPrivilegeDocument(dbname, userName, result);
133
// Checks if this connection has the privileges necessary to perform a query on the given
135
Status checkAuthForQuery(const std::string& ns);
137
// Checks if this connection has the privileges necessary to perform an update on the given
139
Status checkAuthForUpdate(const std::string& ns, bool upsert);
141
// Checks if this connection has the privileges necessary to perform an insert to the given
143
Status checkAuthForInsert(const std::string& ns);
145
// Checks if this connection has the privileges necessary to perform a delete on the given
147
Status checkAuthForDelete(const std::string& ns);
149
// Checks if this connection has the privileges necessary to perform a getMore on the given
151
Status checkAuthForGetMore(const std::string& ns);
153
// Checks if this connection is authorized for the given Privilege.
154
Status checkAuthForPrivilege(const Privilege& privilege);
156
// Checks if this connection is authorized for all the given Privileges.
157
Status checkAuthForPrivileges(const vector<Privilege>& privileges);
159
// Given a database name and a readOnly flag return an ActionSet describing all the actions
160
// that an old-style user with those attributes should be given.
161
static ActionSet getActionsForOldStyleUser(const std::string& dbname, bool readOnly);
163
// Parses the privilege document and returns a PrivilegeSet of all the Privileges that
164
// the privilege document grants.
165
static Status buildPrivilegeSet(const std::string& dbname,
166
const PrincipalName& principal,
167
const BSONObj& privilegeDocument,
168
PrivilegeSet* result);
170
// Returns an ActionSet of all actions that can be be granted to users. This does not
171
// include internal-only actions.
172
static ActionSet getAllUserActions();
175
// Finds the set of privileges attributed to "principal" in database "dbname",
176
// and adds them to the set of acquired privileges.
177
void _acquirePrivilegesForPrincipalFromDatabase(const std::string& dbname,
178
const PrincipalName& principal);
180
// Checks to see if the given privilege is allowed, performing implicit privilege
181
// acquisition if enabled and necessary to resolve the privilege.
182
Status _probeForPrivilege(const Privilege& privilege);
184
// Parses the old-style (pre 2.4) privilege document and returns a PrivilegeSet of all the
185
// Privileges that the privilege document grants.
186
static Status _buildPrivilegeSetFromOldStylePrivilegeDocument(
187
const std::string& dbname,
188
const PrincipalName& principal,
189
const BSONObj& privilegeDocument,
190
PrivilegeSet* result);
192
// Parses extended-form (2.4+) privilege documents and returns a PrivilegeSet of all the
193
// privileges that the document grants.
195
// The document, "privilegeDocument", is assumed to describe privileges for "principal", and
196
// to come from database "dbname".
197
static Status _buildPrivilegeSetFromExtendedPrivilegeDocument(
198
const std::string& dbname,
199
const PrincipalName& principal,
200
const BSONObj& privilegeDocument,
201
PrivilegeSet* result);
203
// Returns a new privilege that has replaced the actions needed to handle special casing
204
// certain namespaces like system.users and system.profile.
205
Privilege _modifyPrivilegeForSpecialCases(const Privilege& privilege);
207
static bool _doesSupportOldStylePrivileges;
209
scoped_ptr<AuthExternalState> _externalState;
211
// All the privileges that have been acquired by the authenticated principals.
212
PrivilegeSet _acquiredPrivileges;
213
// All principals who have been authenticated on this connection
214
PrincipalSet _authenticatedPrincipals;