diff options
author | Spencer T Brody <spencer@10gen.com> | 2012-12-19 16:34:22 -0500 |
---|---|---|
committer | Spencer T Brody <spencer@10gen.com> | 2012-12-20 15:53:31 -0500 |
commit | 09acb35f3d09621ce2df9b099ddcb5db14fa0e1e (patch) | |
tree | f76938cb6e9403e69fe494ae601f684c2fbb7ab2 /src | |
parent | 458796c7cca9f299ee2f23b4dec25162d3235b29 (diff) | |
download | mongo-09acb35f3d09621ce2df9b099ddcb5db14fa0e1e.tar.gz |
SERVER-7572 Update auth checking of serverStatus sub-sections
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/db/btree_stats.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/btree_stats.h | 3 | ||||
-rw-r--r-- | src/mongo/db/client_basic.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/client_basic.h | 4 | ||||
-rw-r--r-- | src/mongo/db/clientcursor.cpp | 3 | ||||
-rw-r--r-- | src/mongo/db/commands/server_status.cpp | 35 | ||||
-rw-r--r-- | src/mongo/db/commands/server_status.h | 20 | ||||
-rw-r--r-- | src/mongo/db/d_concurrency.cpp | 6 | ||||
-rw-r--r-- | src/mongo/db/db.cpp | 5 | ||||
-rw-r--r-- | src/mongo/db/dur.cpp | 3 | ||||
-rw-r--r-- | src/mongo/db/pdfile.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/record.cpp | 6 | ||||
-rw-r--r-- | src/mongo/db/repl.cpp | 3 | ||||
-rw-r--r-- | src/mongo/db/repl/bgsync.cpp | 3 | ||||
-rw-r--r-- | src/mongo/s/d_writeback.cpp | 2 |
15 files changed, 38 insertions, 63 deletions
diff --git a/src/mongo/db/btree_stats.cpp b/src/mongo/db/btree_stats.cpp index c8037719a8a..091726c0b0a 100644 --- a/src/mongo/db/btree_stats.cpp +++ b/src/mongo/db/btree_stats.cpp @@ -40,7 +40,7 @@ namespace mongo { IndexCounters::~IndexCounters(){ } - BSONObj IndexCounters::generateSection( const BSONElement& configElement, bool userIsAdmin ) const { + BSONObj IndexCounters::generateSection(const BSONElement& configElement) const { if ( ! _memSupported ) { return BSON( "note" << "not supported on this platform" ); } diff --git a/src/mongo/db/btree_stats.h b/src/mongo/db/btree_stats.h index a2ce782c508..903286cdbc0 100644 --- a/src/mongo/db/btree_stats.h +++ b/src/mongo/db/btree_stats.h @@ -33,9 +33,8 @@ namespace mongo { virtual ~IndexCounters(); virtual bool includeByDefault() const { return true; } - virtual bool adminOnly() const { return false; } - virtual BSONObj generateSection( const BSONElement& configElement, bool userIsAdmin ) const; + virtual BSONObj generateSection(const BSONElement& configElement) const; // used without a mutex intentionally (can race) diff --git a/src/mongo/db/client_basic.cpp b/src/mongo/db/client_basic.cpp index 3312fd1846b..33185b5aae1 100644 --- a/src/mongo/db/client_basic.cpp +++ b/src/mongo/db/client_basic.cpp @@ -41,11 +41,11 @@ namespace mongo { _authenticationSession.swap(other); } - bool ClientBasic::hasAuthorizationManager() { + bool ClientBasic::hasAuthorizationManager() const { return _authorizationManager.get(); } - AuthorizationManager* ClientBasic::getAuthorizationManager() { + AuthorizationManager* ClientBasic::getAuthorizationManager() const { massert(16481, "No AuthorizationManager has been set up for this connection", hasAuthorizationManager()); diff --git a/src/mongo/db/client_basic.h b/src/mongo/db/client_basic.h index ec1a58ea8af..a8cb1f26277 100644 --- a/src/mongo/db/client_basic.h +++ b/src/mongo/db/client_basic.h @@ -43,8 +43,8 @@ namespace mongo { void resetAuthenticationSession(AuthenticationSession* newSession); void swapAuthenticationSession(boost::scoped_ptr<AuthenticationSession>& other); - bool hasAuthorizationManager(); - AuthorizationManager* getAuthorizationManager(); + bool hasAuthorizationManager() const; + AuthorizationManager* getAuthorizationManager() const; void setAuthorizationManager(AuthorizationManager* authorizationManager); bool getIsLocalHostConnection() { diff --git a/src/mongo/db/clientcursor.cpp b/src/mongo/db/clientcursor.cpp index 552bf686c58..40fb27d2078 100644 --- a/src/mongo/db/clientcursor.cpp +++ b/src/mongo/db/clientcursor.cpp @@ -761,9 +761,8 @@ namespace mongo { CursorServerStats() : ServerStatusSection( "cursors" ){} virtual bool includeByDefault() const { return true; } - virtual bool adminOnly() const { return false; } - BSONObj generateSection( const BSONElement& configElement, bool userIsAdmin ) const { + BSONObj generateSection(const BSONElement& configElement) const { BSONObjBuilder b; ClientCursor::appendStats( b ); return b.obj(); diff --git a/src/mongo/db/commands/server_status.cpp b/src/mongo/db/commands/server_status.cpp index c913ff3ceaf..bb13fb480d6 100644 --- a/src/mongo/db/commands/server_status.cpp +++ b/src/mongo/db/commands/server_status.cpp @@ -82,10 +82,7 @@ namespace mongo { BSONObjBuilder timeBuilder(256); const ClientBasic* myClientBasic = ClientBasic::getCurrent(); - const bool isAdmin = - myClientBasic && - myClientBasic->getAuthenticationInfo() && - myClientBasic->getAuthenticationInfo()->isAuthorizedReads("admin"); + AuthorizationManager* authManager = myClientBasic->getAuthorizationManager(); // --- basic fields that are global @@ -105,7 +102,9 @@ namespace mongo { for ( SectionMap::const_iterator i = _sections->begin(); i != _sections->end(); ++i ) { ServerStatusSection* section = i->second; - if ( section->adminOnly() && ! isAdmin ) + std::vector<Privilege> requiredPrivileges; + section->addRequiredPrivileges(&requiredPrivileges); + if (!authManager->checkAuthForPrivileges(requiredPrivileges).isOK()) continue; bool include = section->includeByDefault(); @@ -118,7 +117,7 @@ namespace mongo { if ( ! include ) continue; - BSONObj data = section->generateSection( e, isAdmin ); + BSONObj data = section->generateSection(e); if ( data.isEmpty() ) continue; @@ -149,11 +148,6 @@ namespace mongo { arr.done(); } } - - // --- final admin things - - if ( ! isAdmin ) - result.append( "note" , "run against admin for more info" ); timeBuilder.appendNumber( "at end" , Listener::getElapsedTimeMillis() - start ); if ( Listener::getElapsedTimeMillis() - start > 1000 ) { @@ -193,7 +187,7 @@ namespace mongo { : ServerStatusSection( sectionName ), _counters( counters ){ } - BSONObj OpCounterServerStatusSection::generateSection( const BSONElement& configElement, bool userIsAdmin ) const { + BSONObj OpCounterServerStatusSection::generateSection(const BSONElement& configElement) const { return _counters->getObj(); } @@ -238,9 +232,8 @@ namespace mongo { } } - ServerStatusMetric::ServerStatusMetric( const string& nameIn, bool adminOnly ) + ServerStatusMetric::ServerStatusMetric(const string& nameIn) : _name( nameIn ), - _adminOnly( adminOnly ), _leafName( _parseLeafName( nameIn ) ) { if ( MetricTree::theMetricTree == 0 ) @@ -264,9 +257,8 @@ namespace mongo { public: Connections() : ServerStatusSection( "connections" ){} virtual bool includeByDefault() const { return true; } - virtual bool adminOnly() const { return false; } - BSONObj generateSection( const BSONElement& configElement, bool userIsAdmin ) const { + BSONObj generateSection(const BSONElement& configElement) const { BSONObjBuilder bb; bb.append( "current" , Listener::globalTicketHolder.used() ); bb.append( "available" , Listener::globalTicketHolder.available() ); @@ -280,9 +272,8 @@ namespace mongo { public: ExtraInfo() : ServerStatusSection( "extra_info" ){} virtual bool includeByDefault() const { return true; } - virtual bool adminOnly() const { return false; } - BSONObj generateSection( const BSONElement& configElement, bool userIsAdmin ) const { + BSONObj generateSection(const BSONElement& configElement) const { BSONObjBuilder bb; bb.append("note", "fields vary by platform"); @@ -298,9 +289,8 @@ namespace mongo { public: Asserts() : ServerStatusSection( "asserts" ){} virtual bool includeByDefault() const { return true; } - virtual bool adminOnly() const { return false; } - BSONObj generateSection( const BSONElement& configElement, bool userIsAdmin ) const { + BSONObj generateSection(const BSONElement& configElement) const { BSONObjBuilder asserts; asserts.append( "regular" , assertionCount.regular ); asserts.append( "warning" , assertionCount.warning ); @@ -317,9 +307,8 @@ namespace mongo { public: Network() : ServerStatusSection( "network" ){} virtual bool includeByDefault() const { return true; } - virtual bool adminOnly() const { return false; } - BSONObj generateSection( const BSONElement& configElement, bool userIsAdmin ) const { + BSONObj generateSection(const BSONElement& configElement) const { BSONObjBuilder b; networkCounter.append( b ); return b.obj(); @@ -329,7 +318,7 @@ namespace mongo { class MemBase : public ServerStatusMetric { public: - MemBase() : ServerStatusMetric( ".mem.bits", false ) {} + MemBase() : ServerStatusMetric(".mem.bits") {} virtual void appendAtLeaf( BSONObjBuilder& b ) const { b.append( "bits", sizeof(int*) == 4 ? 32 : 64 ); diff --git a/src/mongo/db/commands/server_status.h b/src/mongo/db/commands/server_status.h index 5a45d56ccb7..8c8fb9044b7 100644 --- a/src/mongo/db/commands/server_status.h +++ b/src/mongo/db/commands/server_status.h @@ -51,17 +51,17 @@ namespace mongo { virtual bool includeByDefault() const = 0; /** - * if only admins can view this section - * API will change to better auth version + * Adds the privileges that are required to view this section + * TODO: Remove this empty default implementation and implement for every section. */ - virtual bool adminOnly() const = 0; + virtual void addRequiredPrivileges(std::vector<Privilege>* out) {}; /** * actually generate the result * @param configElement the element from the actual command related to this section * so if the section is 'foo', this is cmdObj['foo'] */ - virtual BSONObj generateSection( const BSONElement& configElement, bool userIsAdmin ) const = 0; + virtual BSONObj generateSection(const BSONElement& configElement) const = 0; private: const string _sectionName; @@ -71,9 +71,8 @@ namespace mongo { public: OpCounterServerStatusSection( const string& sectionName, OpCounters* counters ); virtual bool includeByDefault() const { return true; } - virtual bool adminOnly() const { return false; } - virtual BSONObj generateSection( const BSONElement& configElement, bool userIsAdmin ) const; + virtual BSONObj generateSection(const BSONElement& configElement) const; private: const OpCounters* _counters; @@ -87,20 +86,17 @@ namespace mongo { * otherwise it will live under the "counters" namespace * so foo.bar would be serverStatus().counters.foo.bar */ - ServerStatusMetric( const string& name, bool adminOnly ); + ServerStatusMetric(const string& name); virtual ~ServerStatusMetric(){} string getMetricName() const { return _name; } - virtual bool adminOnly() const { return _adminOnly; } - virtual void appendAtLeaf( BSONObjBuilder& b ) const = 0; protected: static string _parseLeafName( const string& name ); const string _name; - const bool _adminOnly; const string _leafName; }; @@ -119,8 +115,8 @@ namespace mongo { template< typename T > class ServerStatusMetricField : public ServerStatusMetric { public: - ServerStatusMetricField( const string& name, bool adminOnly, const T* t ) - : ServerStatusMetric( name, adminOnly ), _t(t) { + ServerStatusMetricField( const string& name, const T* t ) + : ServerStatusMetric(name), _t(t) { } const T* get() { return _t; } diff --git a/src/mongo/db/d_concurrency.cpp b/src/mongo/db/d_concurrency.cpp index b37a70986e2..49b0e40d9fc 100644 --- a/src/mongo/db/d_concurrency.cpp +++ b/src/mongo/db/d_concurrency.cpp @@ -808,9 +808,8 @@ namespace mongo { } virtual bool includeByDefault() const { return true; } - virtual bool adminOnly() const { return false; } - virtual BSONObj generateSection( const BSONElement& configElement, bool userIsAdmin ) const { + virtual BSONObj generateSection(const BSONElement& configElement) const { BSONObjBuilder t; t.append( "totalTime" , (long long)(1000 * ( curTimeMillis64() - _started ) ) ); @@ -848,9 +847,8 @@ namespace mongo { public: LockStatsServerStatusSection() : ServerStatusSection( "locks" ){} virtual bool includeByDefault() const { return true; } - virtual bool adminOnly() const { return false; } - BSONObj generateSection( const BSONElement& configElement, bool userIsAdmin ) const { + BSONObj generateSection( const BSONElement& configElement) const { BSONObjBuilder b; b.append(".", qlk.stats.report()); b.append("admin", nestableLocks[Lock::admin]->stats.report()); diff --git a/src/mongo/db/db.cpp b/src/mongo/db/db.cpp index 48a35b1954c..dd1b3af8f27 100644 --- a/src/mongo/db/db.cpp +++ b/src/mongo/db/db.cpp @@ -435,7 +435,6 @@ namespace mongo { } virtual bool includeByDefault() const { return true; } - virtual bool adminOnly() const { return false; } string name() const { return "DataFileSync"; } @@ -475,7 +474,7 @@ namespace mongo { } } - BSONObj generateSection( const BSONElement& configElement, bool userIsAdmin ) const { + BSONObj generateSection(const BSONElement& configElement) const { BSONObjBuilder b; b.appendNumber( "flushes" , _flushes ); b.appendNumber( "total_ms" , _total_time ); @@ -505,7 +504,7 @@ namespace mongo { namespace { class MemJournalServerStatusMetric : public ServerStatusMetric { public: - MemJournalServerStatusMetric() : ServerStatusMetric( ".mem.mapped", false ) {} + MemJournalServerStatusMetric() : ServerStatusMetric(".mem.mapped") {} virtual void appendAtLeaf( BSONObjBuilder& b ) const { int m = static_cast<int>(MemoryMappedFile::totalMappedLength() / ( 1024 * 1024 )); b.appendNumber( "mapped" , m ); diff --git a/src/mongo/db/dur.cpp b/src/mongo/db/dur.cpp index 41fd14614ae..95f2c454b6b 100644 --- a/src/mongo/db/dur.cpp +++ b/src/mongo/db/dur.cpp @@ -893,9 +893,8 @@ namespace mongo { public: DurSSS() : ServerStatusSection( "dur" ){} virtual bool includeByDefault() const { return true; } - virtual bool adminOnly() const { return false; } - BSONObj generateSection( const BSONElement& configElement, bool userIsAdmin ) const { + BSONObj generateSection(const BSONElement& configElement) const { if ( ! cmdLine.dur ) return BSONObj(); return dur::stats.asObj(); diff --git a/src/mongo/db/pdfile.cpp b/src/mongo/db/pdfile.cpp index 7fb7501bd91..d91df8b2c97 100644 --- a/src/mongo/db/pdfile.cpp +++ b/src/mongo/db/pdfile.cpp @@ -1101,7 +1101,7 @@ namespace mongo { } Counter64 moveCounter; - ServerStatusMetricField<Counter64> moveCounterDisplay( "record.moves", false, &moveCounter ); + ServerStatusMetricField<Counter64> moveCounterDisplay( "record.moves", &moveCounter ); /** Note: if the object shrinks a lot, we don't free up space, we leave extra at end of the record. */ diff --git a/src/mongo/db/record.cpp b/src/mongo/db/record.cpp index 414d8687834..c78ad6b046b 100644 --- a/src/mongo/db/record.cpp +++ b/src/mongo/db/record.cpp @@ -535,9 +535,8 @@ namespace mongo { public: WorkingSetSSS() : ServerStatusSection( "workingSet" ){} virtual bool includeByDefault() const { return false; } - virtual bool adminOnly() const { return false; } - BSONObj generateSection( const BSONElement& configElement, bool userIsAdmin ) const { + BSONObj generateSection(const BSONElement& configElement) const { BSONObjBuilder b; Record::appendWorkingSetInfo( b ); return b.obj(); @@ -549,9 +548,8 @@ namespace mongo { public: RecordStats() : ServerStatusSection( "recordStats" ){} virtual bool includeByDefault() const { return true; } - virtual bool adminOnly() const { return false; } - BSONObj generateSection( const BSONElement& configElement, bool userIsAdmin ) const { + BSONObj generateSection(const BSONElement& configElement) const { BSONObjBuilder record; Record::appendStats( record ); diff --git a/src/mongo/db/repl.cpp b/src/mongo/db/repl.cpp index 9b9c7a576e1..a55198311fc 100644 --- a/src/mongo/db/repl.cpp +++ b/src/mongo/db/repl.cpp @@ -245,9 +245,8 @@ namespace mongo { public: ReplicationInfoServerStatus() : ServerStatusSection( "repl" ){} bool includeByDefault() const { return true; } - bool adminOnly() const { return false; } - BSONObj generateSection( const BSONElement& configElement, bool userIsAdmin ) const { + BSONObj generateSection(const BSONElement& configElement) const { if ( ! anyReplEnabled() ) return BSONObj(); diff --git a/src/mongo/db/repl/bgsync.cpp b/src/mongo/db/repl/bgsync.cpp index e1fb29605ff..a5bbc541438 100644 --- a/src/mongo/db/repl/bgsync.cpp +++ b/src/mongo/db/repl/bgsync.cpp @@ -577,9 +577,8 @@ namespace replset { public: ReplNetworkQueueSSS() : ServerStatusSection( "replNetworkQueue" ){} virtual bool includeByDefault() const { return true; } - virtual bool adminOnly() const { return false; } - BSONObj generateSection( const BSONElement& configElement, bool userIsAdmin ) const { + BSONObj generateSection(const BSONElement& configElement) const { if ( ! theReplSet ) return BSONObj(); diff --git a/src/mongo/s/d_writeback.cpp b/src/mongo/s/d_writeback.cpp index 9e5d5be7e08..1b08c25a81e 100644 --- a/src/mongo/s/d_writeback.cpp +++ b/src/mongo/s/d_writeback.cpp @@ -226,7 +226,7 @@ namespace mongo { class WriteBacksQueuedSSM : public ServerStatusMetric { public: - WriteBacksQueuedSSM() : ServerStatusMetric( ".writeBacksQueued", false ){} + WriteBacksQueuedSSM() : ServerStatusMetric(".writeBacksQueued"){} virtual void appendAtLeaf( BSONObjBuilder& b ) const { b.appendBool( _leafName, ! writeBackManager.queuesEmpty() ); } |