diff options
author | Spencer T Brody <spencer@10gen.com> | 2013-08-14 17:35:37 -0400 |
---|---|---|
committer | Spencer T Brody <spencer@10gen.com> | 2013-08-19 16:49:44 -0400 |
commit | d5b52f08ce9757f1a6825ddc91d4792e266784df (patch) | |
tree | 77ca5e0919f508f5dd85960265ea9e6d6455a3d6 /src/mongo | |
parent | e726d215f06146bb83d42427d7e9d7e37bd294d5 (diff) | |
download | mongo-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.cpp | 29 | ||||
-rw-r--r-- | src/mongo/db/restapi.cpp | 44 | ||||
-rw-r--r-- | src/mongo/db/restapi.h | 3 | ||||
-rw-r--r-- | src/mongo/util/admin_access.h | 5 |
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 |