summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mongo/db/auth/SConscript1
-rw-r--r--src/mongo/db/auth/action_set.cpp8
-rw-r--r--src/mongo/db/auth/action_set.h5
-rw-r--r--src/mongo/db/auth/action_set_test.cpp101
-rw-r--r--src/mongo/db/auth/action_type_test.cpp59
-rw-r--r--src/mongo/db/auth/authorization_manager.cpp123
-rw-r--r--src/mongo/db/auth/authorization_manager.h7
-rw-r--r--src/mongo/db/auth/authorization_manager_test.cpp57
-rw-r--r--src/mongo/db/auth/capability_set_test.cpp68
-rwxr-xr-xsrc/mongo/db/auth/generate_action_types.py91
10 files changed, 331 insertions, 189 deletions
diff --git a/src/mongo/db/auth/SConscript b/src/mongo/db/auth/SConscript
index 510ffb2563f..ce47be521ab 100644
--- a/src/mongo/db/auth/SConscript
+++ b/src/mongo/db/auth/SConscript
@@ -20,7 +20,6 @@ env.StaticLibrary('authcore', ['action_set.cpp',
env.StaticLibrary('auth', ['external_state.cpp'], LIBDEPS=['authcore'])
env.CppUnitTest('action_set_test', 'action_set_test.cpp', LIBDEPS=['authcore'])
-env.CppUnitTest('action_type_test', 'action_type_test.cpp', LIBDEPS=['authcore'])
env.CppUnitTest('capability_set_test', 'capability_set_test.cpp', LIBDEPS=['authcore'])
env.CppUnitTest('principal_set_test', 'principal_set_test.cpp', LIBDEPS=['authcore'])
env.CppUnitTest('authorization_manager_test', 'authorization_manager_test.cpp',
diff --git a/src/mongo/db/auth/action_set.cpp b/src/mongo/db/auth/action_set.cpp
index 7c37cb258d5..e8580190cf6 100644
--- a/src/mongo/db/auth/action_set.cpp
+++ b/src/mongo/db/auth/action_set.cpp
@@ -32,6 +32,14 @@ namespace mongo {
_actions.set(action.getIdentifier(), true);
}
+ void ActionSet::addAllActionsFromSet(const ActionSet& actions) {
+ _actions |= actions._actions;
+ }
+
+ void ActionSet::addAllActions() {
+ _actions = ~std::bitset<ActionType::NUM_ACTION_TYPES>();
+ }
+
bool ActionSet::contains(const ActionType& action) const {
return _actions[action.getIdentifier()];
}
diff --git a/src/mongo/db/auth/action_set.h b/src/mongo/db/auth/action_set.h
index f73a8161e68..ba43583d75e 100644
--- a/src/mongo/db/auth/action_set.h
+++ b/src/mongo/db/auth/action_set.h
@@ -33,6 +33,8 @@ namespace mongo {
ActionSet() : _actions(0) {}
void addAction(const ActionType& action);
+ void addAllActionsFromSet(const ActionSet& actionSet);
+ void addAllActions();
bool contains(const ActionType& action) const;
@@ -49,7 +51,8 @@ namespace mongo {
private:
- std::bitset<128> _actions; // bitmask of actions this capability grants
+ // bitmask of actions this capability grants
+ std::bitset<ActionType::NUM_ACTION_TYPES> _actions;
};
} // namespace mongo
diff --git a/src/mongo/db/auth/action_set_test.cpp b/src/mongo/db/auth/action_set_test.cpp
index cfb4387ae60..ba3b65af2a4 100644
--- a/src/mongo/db/auth/action_set_test.cpp
+++ b/src/mongo/db/auth/action_set_test.cpp
@@ -28,40 +28,32 @@ namespace {
TEST(ActionSetTest, ParseActionSetFromString) {
ActionSet result;
- ASSERT_OK(ActionSet::parseActionSetFromString("r,w,u,d,s,c", &result));
- ASSERT_TRUE(result.contains(ActionType::READ));
- ASSERT_TRUE(result.contains(ActionType::READ_WRITE));
- ASSERT_TRUE(result.contains(ActionType::USER_ADMIN));
- ASSERT_TRUE(result.contains(ActionType::DB_ADMIN));
- ASSERT_TRUE(result.contains(ActionType::SERVER_ADMIN));
- ASSERT_TRUE(result.contains(ActionType::CLUSTER_ADMIN));
-
- // Order of the letters doesn't matter
- ASSERT_OK(ActionSet::parseActionSetFromString("c,u,s,w,d,r", &result));
- ASSERT_TRUE(result.contains(ActionType::READ));
- ASSERT_TRUE(result.contains(ActionType::READ_WRITE));
- ASSERT_TRUE(result.contains(ActionType::USER_ADMIN));
- ASSERT_TRUE(result.contains(ActionType::DB_ADMIN));
- ASSERT_TRUE(result.contains(ActionType::SERVER_ADMIN));
- ASSERT_TRUE(result.contains(ActionType::CLUSTER_ADMIN));
-
- ASSERT_OK(ActionSet::parseActionSetFromString("r", &result));
-
- ASSERT_TRUE(result.contains(ActionType::READ));
- ASSERT_FALSE(result.contains(ActionType::READ_WRITE));
- ASSERT_FALSE(result.contains(ActionType::USER_ADMIN));
- ASSERT_FALSE(result.contains(ActionType::DB_ADMIN));
- ASSERT_FALSE(result.contains(ActionType::SERVER_ADMIN));
- ASSERT_FALSE(result.contains(ActionType::CLUSTER_ADMIN));
+ ASSERT_OK(ActionSet::parseActionSetFromString("find,insert,update,delete", &result));
+ ASSERT_TRUE(result.contains(ActionType::FIND));
+ ASSERT_TRUE(result.contains(ActionType::INSERT));
+ ASSERT_TRUE(result.contains(ActionType::UPDATE));
+ ASSERT_TRUE(result.contains(ActionType::DELETE));
+
+ // Order of the strings doesn't matter
+ ASSERT_OK(ActionSet::parseActionSetFromString("update,find,delete,insert", &result));
+ ASSERT_TRUE(result.contains(ActionType::FIND));
+ ASSERT_TRUE(result.contains(ActionType::INSERT));
+ ASSERT_TRUE(result.contains(ActionType::UPDATE));
+ ASSERT_TRUE(result.contains(ActionType::DELETE));
+
+ ASSERT_OK(ActionSet::parseActionSetFromString("find", &result));
+
+ ASSERT_TRUE(result.contains(ActionType::FIND));
+ ASSERT_FALSE(result.contains(ActionType::INSERT));
+ ASSERT_FALSE(result.contains(ActionType::UPDATE));
+ ASSERT_FALSE(result.contains(ActionType::DELETE));
ASSERT_OK(ActionSet::parseActionSetFromString("", &result));
- ASSERT_FALSE(result.contains(ActionType::READ));
- ASSERT_FALSE(result.contains(ActionType::READ_WRITE));
- ASSERT_FALSE(result.contains(ActionType::USER_ADMIN));
- ASSERT_FALSE(result.contains(ActionType::DB_ADMIN));
- ASSERT_FALSE(result.contains(ActionType::SERVER_ADMIN));
- ASSERT_FALSE(result.contains(ActionType::CLUSTER_ADMIN));
+ ASSERT_FALSE(result.contains(ActionType::FIND));
+ ASSERT_FALSE(result.contains(ActionType::INSERT));
+ ASSERT_FALSE(result.contains(ActionType::UPDATE));
+ ASSERT_FALSE(result.contains(ActionType::DELETE));
ASSERT_EQUALS(ErrorCodes::FailedToParse,
ActionSet::parseActionSetFromString("INVALID INPUT", &result).code());
@@ -71,40 +63,33 @@ namespace {
ActionSet actionSet;
ASSERT_EQUALS("", actionSet.toString());
- actionSet.addAction(ActionType::READ);
- ASSERT_EQUALS("r", actionSet.toString());
- actionSet.addAction(ActionType::READ_WRITE);
- ASSERT_EQUALS("r,w", actionSet.toString());
- actionSet.addAction(ActionType::USER_ADMIN);
- ASSERT_EQUALS("r,w,u", actionSet.toString());
- actionSet.addAction(ActionType::DB_ADMIN);
- ASSERT_EQUALS("r,w,u,d", actionSet.toString());
- actionSet.addAction(ActionType::SERVER_ADMIN);
- ASSERT_EQUALS("r,w,u,d,s", actionSet.toString());
- actionSet.addAction(ActionType::CLUSTER_ADMIN);
- ASSERT_EQUALS("r,w,u,d,s,c", actionSet.toString());
+ actionSet.addAction(ActionType::FIND);
+ ASSERT_EQUALS("find", actionSet.toString());
+ actionSet.addAction(ActionType::INSERT);
+ ASSERT_EQUALS("find,insert", actionSet.toString());
+ actionSet.addAction(ActionType::UPDATE);
+ ASSERT_EQUALS("find,insert,update", actionSet.toString());
+ actionSet.addAction(ActionType::DELETE);
+ ASSERT_EQUALS("delete,find,insert,update", actionSet.toString());
// Now make sure adding actions in a different order doesn't change anything.
ActionSet actionSet2;
- actionSet2.addAction(ActionType::DB_ADMIN);
- ASSERT_EQUALS("d", actionSet2.toString());
- actionSet2.addAction(ActionType::READ);
- ASSERT_EQUALS("r,d", actionSet2.toString());
- actionSet2.addAction(ActionType::CLUSTER_ADMIN);
- ASSERT_EQUALS("r,d,c", actionSet2.toString());
- actionSet2.addAction(ActionType::USER_ADMIN);
- ASSERT_EQUALS("r,u,d,c", actionSet2.toString());
- actionSet2.addAction(ActionType::SERVER_ADMIN);
- ASSERT_EQUALS("r,u,d,s,c", actionSet2.toString());
- actionSet2.addAction(ActionType::READ_WRITE);
- ASSERT_EQUALS("r,w,u,d,s,c", actionSet2.toString());
+ ASSERT_EQUALS("", actionSet2.toString());
+ actionSet2.addAction(ActionType::INSERT);
+ ASSERT_EQUALS("insert", actionSet2.toString());
+ actionSet2.addAction(ActionType::DELETE);
+ ASSERT_EQUALS("delete,insert", actionSet2.toString());
+ actionSet2.addAction(ActionType::FIND);
+ ASSERT_EQUALS("delete,find,insert", actionSet2.toString());
+ actionSet2.addAction(ActionType::UPDATE);
+ ASSERT_EQUALS("delete,find,insert,update", actionSet2.toString());
}
TEST(ActionSetTest, IsSupersetOf) {
ActionSet set1, set2, set3;
- ASSERT_OK(ActionSet::parseActionSetFromString("r,w,u", &set1));
- ASSERT_OK(ActionSet::parseActionSetFromString("r,w,d", &set2));
- ASSERT_OK(ActionSet::parseActionSetFromString("r,w", &set3));
+ ASSERT_OK(ActionSet::parseActionSetFromString("find,update,insert", &set1));
+ ASSERT_OK(ActionSet::parseActionSetFromString("find,update,delete", &set2));
+ ASSERT_OK(ActionSet::parseActionSetFromString("find,update", &set3));
ASSERT_FALSE(set1.isSupersetOf(set2));
ASSERT_TRUE(set1.isSupersetOf(set3));
diff --git a/src/mongo/db/auth/action_type_test.cpp b/src/mongo/db/auth/action_type_test.cpp
deleted file mode 100644
index 3d5c24086f3..00000000000
--- a/src/mongo/db/auth/action_type_test.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Copyright 2012 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Unit tests of the ActionType type.
- */
-
-#include "mongo/db/auth/action_type.h"
-#include "mongo/unittest/unittest.h"
-
-#define ASSERT_OK(EXPR) ASSERT_EQUALS(Status::OK(), (EXPR))
-
-namespace mongo {
-namespace {
-
- TEST(ActionTypeTest, ParseActionFromString) {
- ActionType result;
- ASSERT_OK(ActionType::parseActionFromString("r", &result));
- ASSERT_EQUALS(ActionType::READ.getIdentifier(), result.getIdentifier());
- ASSERT_OK(ActionType::parseActionFromString("w", &result));
- ASSERT_EQUALS(ActionType::READ_WRITE, result);
- ASSERT_OK(ActionType::parseActionFromString("u", &result));
- ASSERT_EQUALS(ActionType::USER_ADMIN, result);
- ASSERT_OK(ActionType::parseActionFromString("d", &result));
- ASSERT_EQUALS(ActionType::DB_ADMIN, result);
- ASSERT_OK(ActionType::parseActionFromString("s", &result));
- ASSERT_EQUALS(ActionType::SERVER_ADMIN, result);
- ASSERT_OK(ActionType::parseActionFromString("c", &result));
- ASSERT_EQUALS(ActionType::CLUSTER_ADMIN, result);
-
- ASSERT_EQUALS(ErrorCodes::FailedToParse,
- ActionType::parseActionFromString("INVALID INPUT", &result).code());
- ASSERT_EQUALS(ErrorCodes::FailedToParse,
- ActionType::parseActionFromString("", &result).code());
- }
-
- TEST(ActionTypeTest, ActionToString) {
- ASSERT_EQUALS("r", ActionType::actionToString(ActionType::READ));
- ASSERT_EQUALS("w", ActionType::actionToString(ActionType::READ_WRITE));
- ASSERT_EQUALS("u", ActionType::actionToString(ActionType::USER_ADMIN));
- ASSERT_EQUALS("d", ActionType::actionToString(ActionType::DB_ADMIN));
- ASSERT_EQUALS("s", ActionType::actionToString(ActionType::SERVER_ADMIN));
- ASSERT_EQUALS("c", ActionType::actionToString(ActionType::CLUSTER_ADMIN));
- }
-
-} // namespace
-} // namespace mongo
diff --git a/src/mongo/db/auth/authorization_manager.cpp b/src/mongo/db/auth/authorization_manager.cpp
index afafe95e8c4..8930cfaa032 100644
--- a/src/mongo/db/auth/authorization_manager.cpp
+++ b/src/mongo/db/auth/authorization_manager.cpp
@@ -18,6 +18,7 @@
#include <string>
+#include "mongo/base/init.h"
#include "mongo/base/status.h"
#include "mongo/client/dbclientinterface.h"
#include "mongo/db/auth/action_set.h"
@@ -36,6 +37,106 @@ namespace mongo {
Principal specialAdminPrincipal("special");
}
+ // ActionSets for the various system roles. These ActionSets contain all the actions that
+ // a user of each system role is granted.
+ ActionSet readRoleActions;
+ ActionSet readWriteRoleActions;
+ ActionSet userAdminRoleActions;
+ ActionSet dbAdminRoleActions;
+ ActionSet serverAdminRoleActions;
+ ActionSet clusterAdminRoleActions;
+
+ // This sets up the system role ActionSets. This is what determines what actions each role
+ // is authorized to perform
+ MONGO_INITIALIZER(AuthorizationSystemRoles)(InitializerContext* context) {
+ // Read role
+ // TODO: Remove OLD_READ once commands require the proper actions
+ readRoleActions.addAction(ActionType::OLD_READ);
+ readRoleActions.addAction(ActionType::COLL_STATS);
+ readRoleActions.addAction(ActionType::DB_STATS);
+ readRoleActions.addAction(ActionType::FIND);
+
+ // Read-write role
+ readWriteRoleActions.addAllActionsFromSet(readRoleActions);
+ // TODO: Remove OLD_WRITE once commands require the proper actions
+ readWriteRoleActions.addAction(ActionType::OLD_WRITE);
+ readWriteRoleActions.addAction(ActionType::CONVERT_TO_CAPPED);
+ readWriteRoleActions.addAction(ActionType::CREATE_COLLECTION); // TODO: should db admin get this also?
+ readWriteRoleActions.addAction(ActionType::DELETE);
+ readWriteRoleActions.addAction(ActionType::DROP_COLLECTION);
+ readWriteRoleActions.addAction(ActionType::DROP_INDEXES);
+ readWriteRoleActions.addAction(ActionType::EMPTYCAPPED);
+ readWriteRoleActions.addAction(ActionType::ENSURE_INDEX);
+ readWriteRoleActions.addAction(ActionType::INSERT);
+ readWriteRoleActions.addAction(ActionType::UPDATE);
+
+ // User admin role
+ userAdminRoleActions.addAction(ActionType::USER_ADMIN);
+
+ // DB admin role
+ dbAdminRoleActions.addAction(ActionType::CLEAN);
+ dbAdminRoleActions.addAction(ActionType::COLL_MOD);
+ dbAdminRoleActions.addAction(ActionType::COLL_STATS);
+ dbAdminRoleActions.addAction(ActionType::COMPACT);
+ dbAdminRoleActions.addAction(ActionType::CONVERT_TO_CAPPED);
+ dbAdminRoleActions.addAction(ActionType::DB_STATS);
+ dbAdminRoleActions.addAction(ActionType::DROP_COLLECTION);
+ dbAdminRoleActions.addAction(ActionType::RE_INDEX); // TODO: Should readWrite have this also? This isn't consistent with ENSURE_INDEX and DROP_INDEXES
+ dbAdminRoleActions.addAction(ActionType::RENAME_COLLECTION);
+ dbAdminRoleActions.addAction(ActionType::VALIDATE);
+
+ // Server admin role
+ serverAdminRoleActions.addAction(ActionType::CLOSE_ALL_DATABASES);
+ serverAdminRoleActions.addAction(ActionType::CONN_POOL_STATS);
+ serverAdminRoleActions.addAction(ActionType::CONN_POOL_SYNC);
+ serverAdminRoleActions.addAction(ActionType::CPU_PROFILER);
+ serverAdminRoleActions.addAction(ActionType::CURSOR_INFO);
+ serverAdminRoleActions.addAction(ActionType::DIAG_LOGGING);
+ serverAdminRoleActions.addAction(ActionType::FSYNC);
+ serverAdminRoleActions.addAction(ActionType::GET_CMD_LINE_OPTS);
+ serverAdminRoleActions.addAction(ActionType::GET_LOG);
+ serverAdminRoleActions.addAction(ActionType::GET_PARAMETER);
+ serverAdminRoleActions.addAction(ActionType::GET_SHARD_MAP);
+ serverAdminRoleActions.addAction(ActionType::GET_SHARD_VERSION);
+ serverAdminRoleActions.addAction(ActionType::HOST_INFO);
+ serverAdminRoleActions.addAction(ActionType::LIST_DATABASES);
+ serverAdminRoleActions.addAction(ActionType::LOG_ROTATE);
+ serverAdminRoleActions.addAction(ActionType::PROFILE);
+ serverAdminRoleActions.addAction(ActionType::REPAIR_DATABASE);
+ serverAdminRoleActions.addAction(ActionType::REPL_SET_FREEZE);
+ serverAdminRoleActions.addAction(ActionType::REPL_SET_GET_STATUS);
+ serverAdminRoleActions.addAction(ActionType::REPL_SET_INITIATE);
+ serverAdminRoleActions.addAction(ActionType::REPL_SET_MAINTENANCE);
+ serverAdminRoleActions.addAction(ActionType::REPL_SET_RECONFIG);
+ serverAdminRoleActions.addAction(ActionType::REPL_SET_STEP_DOWN);
+ serverAdminRoleActions.addAction(ActionType::REPL_SET_SYNC_FROM);
+ serverAdminRoleActions.addAction(ActionType::RESYNC);
+ serverAdminRoleActions.addAction(ActionType::SET_PARAMETER);
+ serverAdminRoleActions.addAction(ActionType::SHUTDOWN);
+ serverAdminRoleActions.addAction(ActionType::TOP);
+ serverAdminRoleActions.addAction(ActionType::TOUCH);
+
+ // Cluster admin role
+ clusterAdminRoleActions.addAction(ActionType::ADD_SHARD);
+ clusterAdminRoleActions.addAction(ActionType::DROP_DATABASE); // TODO: Should there be a CREATE_DATABASE also?
+ clusterAdminRoleActions.addAction(ActionType::ENABLE_SHARDING);
+ clusterAdminRoleActions.addAction(ActionType::FLUSH_ROUTER_CONFIG);
+ clusterAdminRoleActions.addAction(ActionType::LIST_SHARDS);
+ clusterAdminRoleActions.addAction(ActionType::MOVE_CHUNK);
+ clusterAdminRoleActions.addAction(ActionType::MOVE_PRIMARY);
+ clusterAdminRoleActions.addAction(ActionType::NETSTAT);
+ clusterAdminRoleActions.addAction(ActionType::REMOVE_SHARD);
+ clusterAdminRoleActions.addAction(ActionType::SET_SHARD_VERSION); // TODO: should this be internal?
+ clusterAdminRoleActions.addAction(ActionType::SHARD_COLLECTION);
+ clusterAdminRoleActions.addAction(ActionType::SHARDING_STATE);
+ clusterAdminRoleActions.addAction(ActionType::SPLIT);
+ clusterAdminRoleActions.addAction(ActionType::SPLIT_CHUNK);
+ clusterAdminRoleActions.addAction(ActionType::SPLIT_VECTOR);
+ clusterAdminRoleActions.addAction(ActionType::UNSET_SHARDING);
+
+ return Status::OK();
+ }
+
AuthorizationManager::AuthorizationManager(ExternalState* externalState) {
_externalState.reset(externalState);
}
@@ -65,6 +166,16 @@ namespace mongo {
return Status::OK();
}
+ void AuthorizationManager::grantInternalAuthorization() {
+ Principal* internalPrincipal = new Principal("__system");
+ _authenticatedPrincipals.add(internalPrincipal);
+ ActionSet allActions;
+ allActions.addAllActions();
+ Capability capability("*", internalPrincipal, allActions);
+ Status status = acquireCapability(capability);
+ verify (status == Status::OK());
+ }
+
Status AuthorizationManager::getPrivilegeDocument(DBClientBase* conn,
const std::string& dbname,
const std::string& userName,
@@ -129,13 +240,13 @@ namespace mongo {
bool readOnly = false;
ActionSet actions;
if (privilegeDocument.hasField("readOnly") && privilegeDocument["readOnly"].trueValue()) {
- actions.addAction(ActionType::READ);
+ actions.addAllActionsFromSet(readRoleActions);
readOnly = true;
}
else {
- actions.addAction(ActionType::READ_WRITE); // TODO: should this also add READ?
- actions.addAction(ActionType::DB_ADMIN);
- actions.addAction(ActionType::USER_ADMIN);
+ actions.addAllActionsFromSet(readWriteRoleActions);
+ actions.addAllActionsFromSet(dbAdminRoleActions);
+ actions.addAllActionsFromSet(userAdminRoleActions);
}
if (dbname == "admin" || dbname == "local") {
@@ -143,8 +254,8 @@ namespace mongo {
result->grantCapability(Capability("*", principal, actions));
// Make server and cluster admin actions available on admin database.
if (!readOnly) {
- actions.addAction(ActionType::SERVER_ADMIN);
- actions.addAction(ActionType::CLUSTER_ADMIN);
+ actions.addAllActionsFromSet(serverAdminRoleActions);
+ actions.addAllActionsFromSet(clusterAdminRoleActions);
}
}
diff --git a/src/mongo/db/auth/authorization_manager.h b/src/mongo/db/auth/authorization_manager.h
index 9ee38ace641..2f3a7528f78 100644
--- a/src/mongo/db/auth/authorization_manager.h
+++ b/src/mongo/db/auth/authorization_manager.h
@@ -55,6 +55,11 @@ namespace mongo {
// Grant this connection the given capability.
Status acquireCapability(const Capability& capability);
+ // This should be called when the connection gets authenticated as the internal user.
+ // This grants a capability on all the actions for the internal role, with the
+ // internalPrincipal as the principal.
+ void grantInternalAuthorization();
+
// Checks if this connection has the capabilities required to perform the given action
// on the given resource. Contains all the authorization logic including handling things
// like the localhost exception. If it is authorized, returns the principal that granted
@@ -95,8 +100,6 @@ namespace mongo {
CapabilitySet _aquiredCapabilities;
// All principals who have been authenticated on this connection
PrincipalSet _authenticatedPrincipals;
-
- // TODO: handle temporary authorization from $auth table for commands
};
} // namespace mongo
diff --git a/src/mongo/db/auth/authorization_manager_test.cpp b/src/mongo/db/auth/authorization_manager_test.cpp
index 38c1b321056..886b72917b7 100644
--- a/src/mongo/db/auth/authorization_manager_test.cpp
+++ b/src/mongo/db/auth/authorization_manager_test.cpp
@@ -34,28 +34,41 @@ namespace {
TEST(AuthorizationManagerTest, AcquireCapabilityAndCheckAuthorization) {
Principal* principal = new Principal("Spencer");
ActionSet actions;
- actions.addAction(ActionType::READ_WRITE);
+ actions.addAction(ActionType::INSERT);
Capability writeCapability("test", principal, actions);
Capability allDBsWriteCapability("*", principal, actions);
ExternalStateMock* externalState = new ExternalStateMock();
AuthorizationManager authManager(externalState);
- ASSERT_NULL(authManager.checkAuthorization("test", ActionType::READ_WRITE));
+ ASSERT_NULL(authManager.checkAuthorization("test", ActionType::INSERT));
externalState->setReturnValueForShouldIgnoreAuthChecks(true);
ASSERT_EQUALS("special",
- authManager.checkAuthorization("test", ActionType::READ_WRITE)->getName());
+ authManager.checkAuthorization("test", ActionType::INSERT)->getName());
externalState->setReturnValueForShouldIgnoreAuthChecks(false);
- ASSERT_NULL(authManager.checkAuthorization("test", ActionType::READ_WRITE));
+ ASSERT_NULL(authManager.checkAuthorization("test", ActionType::INSERT));
ASSERT_EQUALS(ErrorCodes::UserNotFound,
authManager.acquireCapability(writeCapability).code());
authManager.addAuthorizedPrincipal(principal);
ASSERT_OK(authManager.acquireCapability(writeCapability));
- ASSERT_EQUALS(principal, authManager.checkAuthorization("test", ActionType::READ_WRITE));
+ ASSERT_EQUALS(principal, authManager.checkAuthorization("test", ActionType::INSERT));
- ASSERT_NULL(authManager.checkAuthorization("otherDb", ActionType::READ_WRITE));
+ ASSERT_NULL(authManager.checkAuthorization("otherDb", ActionType::INSERT));
ASSERT_OK(authManager.acquireCapability(allDBsWriteCapability));
- ASSERT_EQUALS(principal, authManager.checkAuthorization("otherDb", ActionType::READ_WRITE));
+ ASSERT_EQUALS(principal, authManager.checkAuthorization("otherDb", ActionType::INSERT));
+ }
+
+ TEST(AuthorizationManagerTest, GrantInternalAuthorization) {
+ ExternalStateMock* externalState = new ExternalStateMock();
+ AuthorizationManager authManager(externalState);
+
+ ASSERT_NULL(authManager.checkAuthorization("test", ActionType::INSERT));
+ ASSERT_NULL(authManager.checkAuthorization("test", ActionType::REPL_SET_HEARTBEAT));
+
+ authManager.grantInternalAuthorization();
+
+ ASSERT_NON_NULL(authManager.checkAuthorization("test", ActionType::INSERT));
+ ASSERT_NON_NULL(authManager.checkAuthorization("test", ActionType::REPL_SET_HEARTBEAT));
}
TEST(AuthorizationManagerTest, GetCapabilitiesFromPrivilegeDocument) {
@@ -76,37 +89,37 @@ namespace {
principal,
readOnly,
&capabilitySet));
- ASSERT_NULL(capabilitySet.getCapabilityForAction("test", ActionType::READ_WRITE));
- ASSERT_NON_NULL(capabilitySet.getCapabilityForAction("test", ActionType::READ));
+ ASSERT_NULL(capabilitySet.getCapabilityForAction("test", ActionType::INSERT));
+ ASSERT_NON_NULL(capabilitySet.getCapabilityForAction("test", ActionType::FIND));
ASSERT_OK(AuthorizationManager::buildCapabilitySet("test",
principal,
readWrite,
&capabilitySet));
- ASSERT_NON_NULL(capabilitySet.getCapabilityForAction("test", ActionType::READ));
- ASSERT_NON_NULL(capabilitySet.getCapabilityForAction("test", ActionType::READ_WRITE));
+ ASSERT_NON_NULL(capabilitySet.getCapabilityForAction("test", ActionType::FIND));
+ ASSERT_NON_NULL(capabilitySet.getCapabilityForAction("test", ActionType::INSERT));
ASSERT_NON_NULL(capabilitySet.getCapabilityForAction("test", ActionType::USER_ADMIN));
- ASSERT_NON_NULL(capabilitySet.getCapabilityForAction("test", ActionType::DB_ADMIN));
- ASSERT_NULL(capabilitySet.getCapabilityForAction("test", ActionType::SERVER_ADMIN));
- ASSERT_NULL(capabilitySet.getCapabilityForAction("test", ActionType::CLUSTER_ADMIN));
+ ASSERT_NON_NULL(capabilitySet.getCapabilityForAction("test", ActionType::COMPACT));
+ ASSERT_NULL(capabilitySet.getCapabilityForAction("test", ActionType::SHUTDOWN));
+ ASSERT_NULL(capabilitySet.getCapabilityForAction("test", ActionType::ADD_SHARD));
- ASSERT_NULL(capabilitySet.getCapabilityForAction("admin", ActionType::READ));
- ASSERT_NULL(capabilitySet.getCapabilityForAction("*", ActionType::READ));
+ ASSERT_NULL(capabilitySet.getCapabilityForAction("admin", ActionType::FIND));
+ ASSERT_NULL(capabilitySet.getCapabilityForAction("*", ActionType::FIND));
ASSERT_OK(AuthorizationManager::buildCapabilitySet("admin",
principal,
readOnly,
&capabilitySet));
- ASSERT_NON_NULL(capabilitySet.getCapabilityForAction("admin", ActionType::READ));
- ASSERT_NON_NULL(capabilitySet.getCapabilityForAction("*", ActionType::READ));
+ ASSERT_NON_NULL(capabilitySet.getCapabilityForAction("admin", ActionType::FIND));
+ ASSERT_NON_NULL(capabilitySet.getCapabilityForAction("*", ActionType::FIND));
- ASSERT_NULL(capabilitySet.getCapabilityForAction("admin", ActionType::READ_WRITE));
- ASSERT_NULL(capabilitySet.getCapabilityForAction("*", ActionType::READ_WRITE));
+ ASSERT_NULL(capabilitySet.getCapabilityForAction("admin", ActionType::INSERT));
+ ASSERT_NULL(capabilitySet.getCapabilityForAction("*", ActionType::INSERT));
ASSERT_OK(AuthorizationManager::buildCapabilitySet("admin",
principal,
readWrite,
&capabilitySet));
- ASSERT_NON_NULL(capabilitySet.getCapabilityForAction("admin", ActionType::READ_WRITE));
- ASSERT_NON_NULL(capabilitySet.getCapabilityForAction("*", ActionType::READ_WRITE));
+ ASSERT_NON_NULL(capabilitySet.getCapabilityForAction("admin", ActionType::INSERT));
+ ASSERT_NON_NULL(capabilitySet.getCapabilityForAction("*", ActionType::INSERT));
}
} // namespace
diff --git a/src/mongo/db/auth/capability_set_test.cpp b/src/mongo/db/auth/capability_set_test.cpp
index 84eeb572d2a..5293ed5579a 100644
--- a/src/mongo/db/auth/capability_set_test.cpp
+++ b/src/mongo/db/auth/capability_set_test.cpp
@@ -33,68 +33,68 @@ namespace {
Principal user1("user1");
Principal user2("user2");
- ASSERT_OK(ActionSet::parseActionSetFromString("r,w,u,d", &actions));
- Capability fooAdmin("foo", &user1, actions);
+ ASSERT_OK(ActionSet::parseActionSetFromString("find,update", &actions));
+ Capability fooUser("foo", &user2, actions);
- ASSERT_OK(ActionSet::parseActionSetFromString("r,w", &actions));
- Capability barUser("bar", &user1, actions);
+ ASSERT_OK(ActionSet::parseActionSetFromString("find,update,userAdmin,delete", &actions));
+ Capability fooUser2("foo", &user1, actions);
- ASSERT_OK(ActionSet::parseActionSetFromString("r,w", &actions));
- Capability fooUser("foo", &user2, actions);
+ ASSERT_OK(ActionSet::parseActionSetFromString("find,update", &actions));
+ Capability barUser("bar", &user1, actions);
- ASSERT_OK(ActionSet::parseActionSetFromString("r", &actions));
+ ASSERT_OK(ActionSet::parseActionSetFromString("find", &actions));
Capability barReadOnly("bar", &user2, actions);
const Capability* capPtr;
// No capabilities
- ASSERT(!capSet.getCapabilityForAction("foo", ActionType::READ));
+ ASSERT(!capSet.getCapabilityForAction("foo", ActionType::FIND));
capSet.grantCapability(fooUser);
- capPtr = capSet.getCapabilityForAction("foo", ActionType::READ);
- ASSERT_TRUE(capPtr->includesAction(ActionType::READ));
- ASSERT_FALSE(capPtr->includesAction(ActionType::DB_ADMIN));
+ capPtr = capSet.getCapabilityForAction("foo", ActionType::FIND);
+ ASSERT_TRUE(capPtr->includesAction(ActionType::FIND));
+ ASSERT_FALSE(capPtr->includesAction(ActionType::DELETE));
- ASSERT(!capSet.getCapabilityForAction("foo", ActionType::DB_ADMIN));
+ ASSERT(!capSet.getCapabilityForAction("foo", ActionType::DELETE));
- capSet.grantCapability(fooAdmin);
+ capSet.grantCapability(fooUser2);
capPtr = capSet.getCapabilityForAction("foo", ActionType::USER_ADMIN);
- ASSERT_TRUE(capPtr->includesAction(ActionType::READ));
- ASSERT_TRUE(capPtr->includesAction(ActionType::DB_ADMIN));
+ ASSERT_TRUE(capPtr->includesAction(ActionType::FIND));
+ ASSERT_TRUE(capPtr->includesAction(ActionType::DELETE));
// No capabilities
- ASSERT(!capSet.getCapabilityForAction("bar", ActionType::READ));
+ ASSERT(!capSet.getCapabilityForAction("bar", ActionType::FIND));
capSet.grantCapability(barReadOnly);
- capPtr = capSet.getCapabilityForAction("bar", ActionType::READ);
- ASSERT_TRUE(capPtr->includesAction(ActionType::READ));
- ASSERT_FALSE(capPtr->includesAction(ActionType::READ_WRITE));
- ASSERT_FALSE(capPtr->includesAction(ActionType::DB_ADMIN));
+ capPtr = capSet.getCapabilityForAction("bar", ActionType::FIND);
+ ASSERT_TRUE(capPtr->includesAction(ActionType::FIND));
+ ASSERT_FALSE(capPtr->includesAction(ActionType::UPDATE));
+ ASSERT_FALSE(capPtr->includesAction(ActionType::DELETE));
- ASSERT(!capSet.getCapabilityForAction("bar", ActionType::READ_WRITE));
+ ASSERT(!capSet.getCapabilityForAction("bar", ActionType::UPDATE));
capSet.grantCapability(barUser);
- capPtr = capSet.getCapabilityForAction("bar", ActionType::READ_WRITE);
- ASSERT_TRUE(capPtr->includesAction(ActionType::READ));
- ASSERT_TRUE(capPtr->includesAction(ActionType::READ_WRITE));
- ASSERT_FALSE(capPtr->includesAction(ActionType::DB_ADMIN));
+ capPtr = capSet.getCapabilityForAction("bar", ActionType::UPDATE);
+ ASSERT_TRUE(capPtr->includesAction(ActionType::FIND));
+ ASSERT_TRUE(capPtr->includesAction(ActionType::UPDATE));
+ ASSERT_FALSE(capPtr->includesAction(ActionType::DELETE));
// Now let's start revoking capabilities
capSet.revokeCapabilitiesFromPrincipal(&user1);
- capPtr = capSet.getCapabilityForAction("foo", ActionType::READ);
- ASSERT_TRUE(capPtr->includesAction(ActionType::READ));
- ASSERT_FALSE(capPtr->includesAction(ActionType::DB_ADMIN));
+ capPtr = capSet.getCapabilityForAction("foo", ActionType::FIND);
+ ASSERT_TRUE(capPtr->includesAction(ActionType::FIND));
+ ASSERT_FALSE(capPtr->includesAction(ActionType::DELETE));
- capPtr = capSet.getCapabilityForAction("bar", ActionType::READ);
- ASSERT_TRUE(capPtr->includesAction(ActionType::READ));
- ASSERT_FALSE(capPtr->includesAction(ActionType::READ_WRITE));
- ASSERT_FALSE(capPtr->includesAction(ActionType::DB_ADMIN));
+ capPtr = capSet.getCapabilityForAction("bar", ActionType::FIND);
+ ASSERT_TRUE(capPtr->includesAction(ActionType::FIND));
+ ASSERT_FALSE(capPtr->includesAction(ActionType::UPDATE));
+ ASSERT_FALSE(capPtr->includesAction(ActionType::DELETE));
capSet.revokeCapabilitiesFromPrincipal(&user2);
- ASSERT(!capSet.getCapabilityForAction("foo", ActionType::READ));
- ASSERT(!capSet.getCapabilityForAction("bar", ActionType::READ));
+ ASSERT(!capSet.getCapabilityForAction("foo", ActionType::FIND));
+ ASSERT(!capSet.getCapabilityForAction("bar", ActionType::FIND));
}
} // namespace
diff --git a/src/mongo/db/auth/generate_action_types.py b/src/mongo/db/auth/generate_action_types.py
index a9eddb6c331..3487f14a34b 100755
--- a/src/mongo/db/auth/generate_action_types.py
+++ b/src/mongo/db/auth/generate_action_types.py
@@ -26,12 +26,89 @@ import sys
# List of tuples describing the ActionTypes that should be created.
# The first value in the tuple is the name of the enum, the second is the string
# representation.
-actionTypes = [("READ", "r"),
- ("READ_WRITE", "w"),
- ("USER_ADMIN", "u"),
- ("DB_ADMIN", "d"),
- ("SERVER_ADMIN", "s"),
- ("CLUSTER_ADMIN", "c")]
+actionTypes = [("ADD_SHARD", "addShard"),
+ ("APPLY_OPS", "applyOps"),
+ ("CAPTRUNC", "captrunc"),
+ ("CLEAN", "clean"),
+ ("CLOSE_ALL_DATABASES", "closeAllDatabases"),
+ ("COLL_MOD", "collMod"),
+ ("COLL_STATS", "collStats"),
+ ("COMPACT", "compact"),
+ ("CONN_POOL_STATS", "connPoolStats"),
+ ("CONN_POOL_SYNC", "connPoolSync"),
+ ("CONVERT_TO_CAPPED", "convertToCapped"),
+ ("CPU_PROFILER", "cpuProfiler"),
+ ("CREATE_COLLECTION", "createCollection"),
+ ("CURSOR_INFO", "cursorInfo"),
+ ("DB_HASH", "dbHash"),
+ ("DB_STATS", "dbStats"),
+ ("DELETE", "delete"),
+ ("DIAG_LOGGING", "diagLogging"),
+ ("DROP_COLLECTION", "dropCollection"),
+ ("DROP_DATABASE", "dropDatabase"),
+ ("DROP_INDEXES", "dropIndexes"),
+ ("EMPTYCAPPED", "emptycapped"),
+ ("ENABLE_SHARDING", "enableSharding"),
+ ("ENSURE_INDEX", "ensureIndex"),
+ ("FIND", "find"),
+ ("FLUSH_ROUTER_CONFIG", "flushRouterConfig"),
+ ("FSYNC", "fsync"),
+ ("GET_CMD_LINE_OPTS", "getCmdLineOpts"),
+ ("GET_LOG", "getLog"),
+ ("GET_PARAMETER", "getParameter"),
+ ("GET_SHARD_MAP", "getShardMap"),
+ ("GET_SHARD_VERSION", "getShardVersion"),
+ ("HANDSHAKE", "handshake"),
+ ("HOST_INFO", "hostInfo"),
+ ("INSERT", "insert"),
+ ("LIST_DATABASES", "listDatabases"),
+ ("LIST_SHARDS", "listShards"),
+ ("LOG_ROTATE", "logRotate"),
+ ("MOVE_CHUNK", "moveChunk"),
+ ("MOVE_PRIMARY", "movePrimary"),
+ ("NETSTAT", "netstat"),
+ ("PROFILE", "profile"),
+ ("RE_INDEX", "reIndex"),
+ ("REMOVE_SHARD", "removeShard"),
+ ("RENAME_COLLECTION", "renameCollection"),
+ ("REPAIR_DATABASE", "repairDatabase"),
+ ("REPL_SET_ELECT", "replSetElect"),
+ ("REPL_SET_FREEZE", "replSetFreeze"),
+ ("REPL_SET_FRESH", "replSetFresh"),
+ ("REPL_SET_GET_RBID", "replSetGetRBID"),
+ ("REPL_SET_GET_STATUS", "replSetGetStatus"),
+ ("REPL_SET_HEARTBEAT", "replSetHeartbeat"),
+ ("REPL_SET_INITIATE", "replSetInitiate"),
+ ("REPL_SET_MAINTENANCE", "replSetMaintenance"),
+ ("REPL_SET_RECONFIG", "replSetReconfig"),
+ ("REPL_SET_STEP_DOWN", "replSetStepDown"),
+ ("REPL_SET_SYNC_FROM", "replSetSyncFrom"),
+ ("RESYNC", "resync"),
+ ("SET_PARAMETER", "setParameter"),
+ ("SET_SHARD_VERSION", "setShardVersion"),
+ ("SHARD_COLLECTION", "shardCollection"),
+ ("SHARDING_STATE", "shardingState"),
+ ("SHUTDOWN", "shutdown"),
+ ("SPLIT", "split"),
+ ("SPLIT_CHUNK", "splitChunk"),
+ ("SPLIT_VECTOR", "splitVector"),
+ ("TOP", "top"),
+ ("TOUCH", "touch"),
+ ("UNSET_SHARDING", "unsetSharding"),
+ ("UPDATE", "update"),
+ ("USER_ADMIN", "userAdmin"),
+ ("VALIDATE", "validate"),
+ ("WRITEBACKLISTEN", "writebacklisten"),
+ ("WRITE_BACKS_QUEUED", "writeBacksQueued"),
+ ("_MIGRATE_CLONE", "_migrateClone"),
+ ("_RECV_CHUNK_ABORT", "_recvChunkAbort"),
+ ("_RECV_CHUNK_COMMIT", "_recvChunkCommit"),
+ ("_RECV_CHUNK_START", "_recvChunkStart"),
+ ("_RECV_CHUNK_STATUS", "_recvChunkStatus"),
+ ("_TRANSFER_MODS", "_transferMods"),
+ ("OLD_READ", "oldRead"), # Temporary. For easing AuthorizationManager integration
+ ("OLD_WRITE", "oldWrite")] # Temporary. For easing AuthorizationManager integration
+
headerFileTemplate = """// AUTO-GENERATED FILE DO NOT EDIT
// See src/mongo/db/auth/generate_action_types.py
@@ -87,6 +164,8 @@ namespace mongo {
ACTION_TYPE_END_VALUE, // Should always be last in this enum
};
+ static const int NUM_ACTION_TYPES = ACTION_TYPE_END_VALUE;
+
private:
uint32_t _identifier; // unique identifier for this action.