summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
authorSpencer T Brody <spencer@10gen.com>2013-08-14 17:35:37 -0400
committerSpencer T Brody <spencer@10gen.com>2013-08-19 16:49:44 -0400
commitd5b52f08ce9757f1a6825ddc91d4792e266784df (patch)
tree77ca5e0919f508f5dd85960265ea9e6d6455a3d6 /src/mongo
parente726d215f06146bb83d42427d7e9d7e37bd294d5 (diff)
downloadmongo-d5b52f08ce9757f1a6825ddc91d4792e266784df.tar.gz
SERVER-9518 SERVER-10323 Fix access control in the web server
Diffstat (limited to 'src/mongo')
-rw-r--r--src/mongo/db/dbwebserver.cpp29
-rw-r--r--src/mongo/db/restapi.cpp44
-rw-r--r--src/mongo/db/restapi.h3
-rw-r--r--src/mongo/util/admin_access.h5
4 files changed, 33 insertions, 48 deletions
diff --git a/src/mongo/db/dbwebserver.cpp b/src/mongo/db/dbwebserver.cpp
index 726b1c896ef..3006c96d98d 100644
--- a/src/mongo/db/dbwebserver.cpp
+++ b/src/mongo/db/dbwebserver.cpp
@@ -32,6 +32,7 @@
#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/auth/principal.h"
#include "mongo/db/auth/privilege.h"
+#include "mongo/db/auth/user_name.h"
#include "mongo/db/background.h"
#include "mongo/db/cmdline.h"
#include "mongo/db/commands.h"
@@ -80,22 +81,16 @@ namespace mongo {
ss << "</pre>";
}
- void _authorizePrincipal(const std::string& principalName, bool readOnly) {
- // TODO(spencer): Re-enable this using the new way of authorizing users. SERVER-10323
-// Principal* principal = new Principal(UserName(principalName, "local"));
-// ActionSet actions = getGlobalAuthorizationManager()->getActionsForOldStyleUser(
-// "admin", readOnly);
-//
-// AuthorizationSession* authorizationSession = cc().getAuthorizationSession();
-// authorizationSession->addPrincipal(principal);
-// Status status = authorizationSession->acquirePrivilege(
-// Privilege(PrivilegeSet::WILDCARD_RESOURCE, actions), principal->getName());
-// verify (status == Status::OK());
+ void _authorizePrincipal(const UserName& userName) {
+ Status status = cc().getAuthorizationSession()->addAndAuthorizeUser(userName);
+ uassertStatusOK(status);
}
bool allowed( const char * rq , vector<string>& headers, const SockAddr &from ) {
if ( from.isLocalHost() || !_webUsers->haveAdminUsers() ) {
- _authorizePrincipal("RestUser", false);
+ // TODO(spencer): should the above check use "&&" not "||"? Currently this is much
+ // more permissive than the server's localhost auth bypass.
+ cc().getAuthorizationSession()->grantInternalAuthorization();
return true;
}
@@ -113,7 +108,9 @@ namespace mongo {
parms[name] = val;
}
- BSONObj user = _webUsers->getAdminUser( parms["username"] );
+ // Only users in the admin DB are visible by the webserver
+ UserName userName(parms["username"], "admin");
+ BSONObj user = _webUsers->getAdminUser(userName);
if ( ! user.isEmpty() ) {
string ha1 = user["pwd"].str();
string ha2 = md5simpledigest( (string)"GET" + ":" + parms["uri"] );
@@ -133,11 +130,7 @@ namespace mongo {
string r1 = md5simpledigest( r.str() );
if ( r1 == parms["response"] ) {
- std::string principalName = user["user"].str();
- bool readOnly = user[ "readOnly" ].isBoolean() &&
- user[ "readOnly" ].boolean();
-
- _authorizePrincipal(principalName, readOnly);
+ _authorizePrincipal(userName);
return true;
}
}
diff --git a/src/mongo/db/restapi.cpp b/src/mongo/db/restapi.cpp
index adfd7eb5994..e18c70f74de 100644
--- a/src/mongo/db/restapi.cpp
+++ b/src/mongo/db/restapi.cpp
@@ -21,6 +21,9 @@
#include "mongo/db/restapi.h"
+#include "mongo/db/auth/authorization_manager.h"
+#include "mongo/db/auth/authorization_session.h"
+#include "mongo/db/auth/user_name.h"
#include "mongo/db/background.h"
#include "mongo/db/clientcursor.h"
#include "mongo/db/dbhelpers.h"
@@ -245,37 +248,24 @@ namespace mongo {
} restHandler;
- void openAdminDb() {
- {
- readlocktry rl(/*"admin.system.users", */10000);
- uassert( 16172 , "couldn't get readlock to open admin db" , rl.got() );
- if( dbHolder().get("admin.system.users",dbpath) )
- return;
- }
-
- writelocktry wl(10000);
- verify( wl.got() );
- Client::Context cx("admin.system.users", dbpath);
- }
-
bool RestAdminAccess::haveAdminUsers() const {
- openAdminDb();
- readlocktry rl(/*"admin.system.users", */10000);
- uassert( 16173 , "couldn't get read lock to get admin auth credentials" , rl.got() );
- Client::Context cx("admin.system.users", dbpath);
- return ! Helpers::isEmpty("admin.system.users");
+ AuthorizationSession* authzSession = cc().getAuthorizationSession();
+ return authzSession->getAuthorizationManager().hasPrivilegeDocument("admin");
}
- BSONObj RestAdminAccess::getAdminUser( const string& username ) const {
- openAdminDb();
- Client::GodScope gs;
- readlocktry rl(/*"admin.system.users", */10000);
- uassert( 16174 , "couldn't get read lock to check admin user" , rl.got() );
- Client::Context cx( "admin.system.users" );
+ BSONObj RestAdminAccess::getAdminUser(const UserName& username) const {
+ AuthorizationSession* authzSession = cc().getAuthorizationSession();
BSONObj user;
- if ( Helpers::findOne( "admin.system.users" , BSON( "user" << username ) , user ) )
- return user.copy();
- return BSONObj();
+ Status status = authzSession->getAuthorizationManager().getPrivilegeDocument("admin",
+ username,
+ &user);
+ if (status.isOK()) {
+ return user;
+ }
+ if (status.code() == ErrorCodes::UserNotFound) {
+ return BSONObj();
+ }
+ uasserted(17050, status.reason());
}
class LowLevelMongodStatus : public WebStatusPlugin {
diff --git a/src/mongo/db/restapi.h b/src/mongo/db/restapi.h
index 2f80be04725..43eceb93c3c 100644
--- a/src/mongo/db/restapi.h
+++ b/src/mongo/db/restapi.h
@@ -21,6 +21,7 @@
#include <string>
+#include "mongo/db/auth/user_name.h"
#include "mongo/db/jsobj.h"
#include "mongo/util/admin_access.h"
@@ -31,7 +32,7 @@ namespace mongo {
virtual ~RestAdminAccess() { }
virtual bool haveAdminUsers() const;
- virtual BSONObj getAdminUser( const std::string& username ) const;
+ virtual BSONObj getAdminUser(const UserName& username) const;
};
} // namespace mongo
diff --git a/src/mongo/util/admin_access.h b/src/mongo/util/admin_access.h
index 99322272d2d..7e09a1fcea0 100644
--- a/src/mongo/util/admin_access.h
+++ b/src/mongo/util/admin_access.h
@@ -20,6 +20,7 @@
#pragma once
#include "mongo/db/jsobj.h"
+#include "mongo/db/auth/user_name.h"
namespace mongo {
@@ -40,7 +41,7 @@ namespace mongo {
/** @return privileged user with this name. This should not block
* for long and throw if can't get a lock if needed
*/
- virtual BSONObj getAdminUser( const string& username ) const = 0;
+ virtual BSONObj getAdminUser(const UserName& username) const = 0;
};
class NoAdminAccess : public AdminAccess {
@@ -48,7 +49,7 @@ namespace mongo {
virtual ~NoAdminAccess() { }
virtual bool haveAdminUsers() const { return false; }
- virtual BSONObj getAdminUser( const string& username ) const { return BSONObj(); }
+ virtual BSONObj getAdminUser(const UserName& username) const { return BSONObj(); }
};
} // namespace mongo