summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSpencer T Brody <spencer@10gen.com>2012-11-16 20:44:21 -0500
committerSpencer T Brody <spencer@10gen.com>2013-02-27 13:45:25 -0500
commitb4e33ce1ba54c6bfa4ff9ae0bd144d674e11c883 (patch)
treeb3901a5820ab63e0c1fe38776f0ae1f4fe71d711
parent37c3df43f01a57c3698db6e371f71371a0ddd6a4 (diff)
downloadmongo-b4e33ce1ba54c6bfa4ff9ae0bd144d674e11c883.tar.gz
SERVER-6591 Fix localhost auth exception in sharded systems
-rw-r--r--src/SConscript.client3
-rw-r--r--src/mongo/SConscript10
-rw-r--r--src/mongo/client/authentication_table.h3
-rw-r--r--src/mongo/client/authentication_table_client.cpp27
-rw-r--r--src/mongo/client/authentication_table_common.cpp (renamed from src/mongo/client/authentication_table.cpp)7
-rw-r--r--src/mongo/client/authentication_table_server.cpp30
-rw-r--r--src/mongo/client/clientAndShell.cpp4
-rw-r--r--src/mongo/db/client.cpp4
-rw-r--r--src/mongo/db/client_common.h2
-rw-r--r--src/mongo/db/security.cpp4
-rwxr-xr-xsrc/mongo/db/security.h1
-rw-r--r--src/mongo/s/client_info.cpp9
-rw-r--r--src/mongo/s/client_info.h5
-rw-r--r--src/mongo/s/security.cpp23
14 files changed, 124 insertions, 8 deletions
diff --git a/src/SConscript.client b/src/SConscript.client
index 7a6bdc9d8ea..7308518c5ed 100644
--- a/src/SConscript.client
+++ b/src/SConscript.client
@@ -8,7 +8,8 @@ Import('env clientEnv')
clientSource = [
'mongo/bson/oid.cpp',
'mongo/buildinfo.cpp',
- "mongo/client/authentication_table.cpp",
+ "mongo/client/authentication_table_common.cpp",
+ "mongo/client/authentication_table_client.cpp",
'mongo/client/clientAndShell.cpp',
'mongo/client/clientOnly.cpp',
'mongo/client/connection_factory.cpp',
diff --git a/src/mongo/SConscript b/src/mongo/SConscript
index 0cfbedcc8a4..787f423124d 100644
--- a/src/mongo/SConscript
+++ b/src/mongo/SConscript
@@ -81,7 +81,7 @@ commonFiles = [ "pch.cpp",
"util/net/message_port.cpp",
"util/net/listen.cpp",
"util/startup_test.cpp",
- "client/authentication_table.cpp",
+ "client/authentication_table_common.cpp",
"client/connpool.cpp",
"client/dbclient.cpp",
"client/dbclient_rs.cpp",
@@ -102,6 +102,7 @@ env.StaticLibrary('mongocommon', commonFiles,
'$BUILD_DIR/third_party/shim_boost'],)
env.StaticLibrary("coredb", [
+ "client/authentication_table_server.cpp",
"client/parallel.cpp",
"db/commands.cpp",
"db/commands/hashcmd.cpp",
@@ -443,7 +444,12 @@ mongos = env.Program(
"mongodandmongos"])
env.Install( '#/', mongos )
-env.Library("clientandshell", ["client/clientAndShell.cpp"], LIBDEPS=["mongocommon", "defaultversion", "gridfs", "notmongodormongos"])
+env.Library("clientandshell", ["client/authentication_table_client.cpp",
+ "client/clientAndShell.cpp"],
+ LIBDEPS=["mongocommon",
+ "defaultversion",
+ "gridfs",
+ "notmongodormongos"])
env.Library("allclient", "client/clientOnly.cpp", LIBDEPS=["clientandshell"])
if has_option( "sharedclient" ):
diff --git a/src/mongo/client/authentication_table.h b/src/mongo/client/authentication_table.h
index 20cb8c4fdba..c0476b92984 100644
--- a/src/mongo/client/authentication_table.h
+++ b/src/mongo/client/authentication_table.h
@@ -59,6 +59,9 @@ namespace mongo {
static const string fieldName;
private:
+
+ bool _shouldSendInternalSecurityTable() const;
+
typedef map<std::string,Auth> DBAuthMap;
DBAuthMap _dbs; // dbname -> auth
};
diff --git a/src/mongo/client/authentication_table_client.cpp b/src/mongo/client/authentication_table_client.cpp
new file mode 100644
index 00000000000..593d44616e6
--- /dev/null
+++ b/src/mongo/client/authentication_table_client.cpp
@@ -0,0 +1,27 @@
+/* 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.
+ */
+
+
+#include "mongo/client/authentication_table.h"
+#include "mongo/db/client_common.h"
+#include "mongo/db/security.h"
+
+namespace mongo {
+
+ bool AuthenticationTable::_shouldSendInternalSecurityTable() const {
+ return false;
+ }
+
+}
diff --git a/src/mongo/client/authentication_table.cpp b/src/mongo/client/authentication_table_common.cpp
index 9af6de4f5c7..ca6eda1a26f 100644
--- a/src/mongo/client/authentication_table.cpp
+++ b/src/mongo/client/authentication_table_common.cpp
@@ -93,7 +93,12 @@ namespace mongo {
cmdWithAuth.append(e);
}
- cmdWithAuth.append( fieldName, toBSON() );
+ if (_shouldSendInternalSecurityTable()) {
+ cmdWithAuth.append(fieldName, internalSecurityAuthenticationTable.toBSON());
+ }
+ else {
+ cmdWithAuth.append(fieldName, toBSON());
+ }
return cmdWithAuth.obj();
}
diff --git a/src/mongo/client/authentication_table_server.cpp b/src/mongo/client/authentication_table_server.cpp
new file mode 100644
index 00000000000..dc69a5629ea
--- /dev/null
+++ b/src/mongo/client/authentication_table_server.cpp
@@ -0,0 +1,30 @@
+/* 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.
+ */
+
+
+#include "mongo/client/authentication_table.h"
+#include "mongo/db/client_common.h"
+#include "mongo/db/security.h"
+
+namespace mongo {
+
+ bool AuthenticationTable::_shouldSendInternalSecurityTable() const {
+ if (!ClientBasic::hasCurrent() || !ClientBasic::getCurrent()->getAuthenticationInfo()) {
+ return false;
+ }
+ return ClientBasic::getCurrent()->getAuthenticationInfo()->isSpecialLocalhostAdmin();
+ }
+
+}
diff --git a/src/mongo/client/clientAndShell.cpp b/src/mongo/client/clientAndShell.cpp
index 6c4e3be311d..d02a153c615 100644
--- a/src/mongo/client/clientAndShell.cpp
+++ b/src/mongo/client/clientAndShell.cpp
@@ -87,4 +87,8 @@ namespace mongo {
ClientBasic* ClientBasic::getCurrent() {
return 0;
}
+
+ bool ClientBasic::hasCurrent() {
+ return false;
+ }
}
diff --git a/src/mongo/db/client.cpp b/src/mongo/db/client.cpp
index 11216632fa1..aa35f645345 100644
--- a/src/mongo/db/client.cpp
+++ b/src/mongo/db/client.cpp
@@ -445,6 +445,10 @@ namespace mongo {
}
}
+ bool ClientBasic::hasCurrent() {
+ return currentClient.get();
+ }
+
ClientBasic* ClientBasic::getCurrent() {
return currentClient.get();
}
diff --git a/src/mongo/db/client_common.h b/src/mongo/db/client_common.h
index 1d61f81b575..5bacd8a932c 100644
--- a/src/mongo/db/client_common.h
+++ b/src/mongo/db/client_common.h
@@ -43,5 +43,7 @@ namespace mongo {
virtual HostAndPort getRemote() const = 0;
static ClientBasic* getCurrent();
+ static bool hasCurrent();
+
};
}
diff --git a/src/mongo/db/security.cpp b/src/mongo/db/security.cpp
index 06ef0bf86dd..0326f6d65c7 100644
--- a/src/mongo/db/security.cpp
+++ b/src/mongo/db/security.cpp
@@ -73,6 +73,10 @@ namespace mongo {
_checkLocalHostSpecialAdmin();
}
+ bool AuthenticationInfo::isSpecialLocalhostAdmin() const {
+ return _isLocalHostAndLocalHostIsAuthorizedForAll;
+ }
+
void AuthenticationInfo::_checkLocalHostSpecialAdmin() {
if ( ! _isLocalHost )
return;
diff --git a/src/mongo/db/security.h b/src/mongo/db/security.h
index 791f38947c6..0b152296afc 100755
--- a/src/mongo/db/security.h
+++ b/src/mongo/db/security.h
@@ -44,6 +44,7 @@ namespace mongo {
}
~AuthenticationInfo() {}
bool isLocalHost() const { return _isLocalHost; } // why are you calling this? makes no sense to be externalized
+ bool isSpecialLocalhostAdmin() const;
// -- modifiers ----
diff --git a/src/mongo/s/client_info.cpp b/src/mongo/s/client_info.cpp
index d304e5eb25d..0cbcfe22156 100644
--- a/src/mongo/s/client_info.cpp
+++ b/src/mongo/s/client_info.cpp
@@ -70,6 +70,7 @@ namespace mongo {
_cur = _prev;
_prev = temp;
_cur->clear();
+ _ai.startRequest();
}
ClientInfo * ClientInfo::get() {
@@ -82,6 +83,14 @@ namespace mongo {
return info;
}
+ bool ClientInfo::exists() {
+ return _tlInfo.get();
+ }
+
+ bool ClientBasic::hasCurrent() {
+ return ClientInfo::exists();
+ }
+
ClientBasic* ClientBasic::getCurrent() {
return ClientInfo::get();
}
diff --git a/src/mongo/s/client_info.h b/src/mongo/s/client_info.h
index 504ac0e3a68..180fc049322 100644
--- a/src/mongo/s/client_info.h
+++ b/src/mongo/s/client_info.h
@@ -100,6 +100,11 @@ namespace mongo {
void noAutoSplit() { _autoSplitOk = false; }
static ClientInfo * get();
+
+ // Returns whether or not a ClientInfo for this thread has already been created and stored
+ // in _tlInfo.
+ static bool exists();
+
const AuthenticationInfo* getAuthenticationInfo() const { return (AuthenticationInfo*)&_ai; }
AuthenticationInfo* getAuthenticationInfo() { return (AuthenticationInfo*)&_ai; }
bool isAdmin() { return _ai.isAuthorized( "admin" ); }
diff --git a/src/mongo/s/security.cpp b/src/mongo/s/security.cpp
index f309369c20d..090f3afe80e 100644
--- a/src/mongo/s/security.cpp
+++ b/src/mongo/s/security.cpp
@@ -64,14 +64,28 @@ namespace mongo {
return true;
}
+ void AuthenticationInfo::startRequest() {
+ _checkLocalHostSpecialAdmin();
+ }
+
void AuthenticationInfo::setIsALocalHostConnectionWithSpecialAuthPowers() {
verify(!_isLocalHost);
_isLocalHost = true;
+ _isLocalHostAndLocalHostIsAuthorizedForAll = true;
+ _checkLocalHostSpecialAdmin();
}
bool AuthenticationInfo::_isAuthorizedSpecialChecks( const string& dbname ) const {
- if ( !_isLocalHost ) {
- return false;
+ return isSpecialLocalhostAdmin();
+ }
+
+ bool AuthenticationInfo::isSpecialLocalhostAdmin() const {
+ return _isLocalHostAndLocalHostIsAuthorizedForAll;
+ }
+
+ void AuthenticationInfo::_checkLocalHostSpecialAdmin() {
+ if (!_isLocalHost || !_isLocalHostAndLocalHostIsAuthorizedForAll) {
+ return;
}
string adminNs = "admin.system.users";
@@ -93,12 +107,13 @@ namespace mongo {
// Must return conn to pool
// TODO: Check for errors during findOne(), or just let the conn die?
conn.done();
- return true;
+ _isLocalHostAndLocalHostIsAuthorizedForAll = true;
+ return;
}
// Must return conn to pool
conn.done();
- return false;
+ _isLocalHostAndLocalHostIsAuthorizedForAll = false;
}
bool CmdLogout::run(const string& dbname , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) {