summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles E. Rolke <chug@apache.org>2012-08-10 17:19:51 +0000
committerCharles E. Rolke <chug@apache.org>2012-08-10 17:19:51 +0000
commit1ca286b78d1cfd1942ef607589fdd862c2208c38 (patch)
treed627d6f256a00f87e06d0c585d86bcde93f7276a
parentf5fa3e05a419d08e2237561e925ba427546bef2f (diff)
downloadqpid-python-1ca286b78d1cfd1942ef607589fdd862c2208c38.tar.gz
QPID-4142 C++ Broker connection counting gets usernames confused
when various auth mechanism are used. The issue is that the connection's userId is changed as the auth progresses. Also, the shadowed connections change differently from the non-shadowed connections. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1371772 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--qpid/cpp/src/qpid/acl/Acl.cpp7
-rw-r--r--qpid/cpp/src/qpid/acl/Acl.h2
-rw-r--r--qpid/cpp/src/qpid/acl/AclConnectionCounter.cpp41
-rw-r--r--qpid/cpp/src/qpid/acl/AclConnectionCounter.h1
-rw-r--r--qpid/cpp/src/qpid/broker/AclModule.h4
-rw-r--r--qpid/cpp/src/qpid/broker/Connection.cpp8
6 files changed, 63 insertions, 0 deletions
diff --git a/qpid/cpp/src/qpid/acl/Acl.cpp b/qpid/cpp/src/qpid/acl/Acl.cpp
index d941577f6a..89c4b3402a 100644
--- a/qpid/cpp/src/qpid/acl/Acl.cpp
+++ b/qpid/cpp/src/qpid/acl/Acl.cpp
@@ -129,6 +129,13 @@ bool Acl::approveConnection(const qpid::broker::Connection& conn)
return connectionCounter->approveConnection(conn);
}
+
+void Acl::setUserId(const qpid::broker::Connection& connection, const std::string& username)
+{
+ connectionCounter->setUserId(connection, username);
+}
+
+
bool Acl::result(
const AclResult& aclreslt,
const std::string& id,
diff --git a/qpid/cpp/src/qpid/acl/Acl.h b/qpid/cpp/src/qpid/acl/Acl.h
index 4893f71ef2..4787934275 100644
--- a/qpid/cpp/src/qpid/acl/Acl.h
+++ b/qpid/cpp/src/qpid/acl/Acl.h
@@ -94,6 +94,8 @@ public:
virtual bool approveConnection(const broker::Connection& connection);
+ virtual void setUserId(const broker::Connection& connection, const std::string& username);
+
virtual ~Acl();
private:
bool result(
diff --git a/qpid/cpp/src/qpid/acl/AclConnectionCounter.cpp b/qpid/cpp/src/qpid/acl/AclConnectionCounter.cpp
index 052fa3c222..8c6e3eef6e 100644
--- a/qpid/cpp/src/qpid/acl/AclConnectionCounter.cpp
+++ b/qpid/cpp/src/qpid/acl/AclConnectionCounter.cpp
@@ -296,6 +296,47 @@ bool ConnectionCounter::approveConnection(const broker::Connection& connection)
}
}
+
+//
+// setUserId
+// On cluster shadow connections, track a new user id for this connection.
+//
+void ConnectionCounter::setUserId(const broker::Connection& connection,
+ const std::string& username)
+{
+ Mutex::ScopedLock locker(dataLock);
+
+ connectCountsMap_t::iterator eRef = connectProgressMap.find(connection.getMgmtId());
+ if (eRef != connectProgressMap.end()) {
+ if ((*eRef).second == C_OPENED){
+ // Connection has been opened so that current user has been counted
+ if (connection.isShadow()) {
+ // This is a shadow connection and therefore receives userId changes
+ QPID_LOG(debug, "Changing User ID for cluster connection: "
+ << connection.getMgmtId() << ", old user:'" << connection.getUserId()
+ << "', new user:'" << username << "'");
+
+ // Decrement user in-use count for old userId
+ releaseLH(connectByNameMap,
+ connection.getUserId(),
+ nameLimit);
+ // Increment user in-use count for new userId
+ (void) countConnectionLH(connectByNameMap, username, nameLimit, false);
+ } else {
+ QPID_LOG(warning, "Changing User ID for non-cluster connections is not supported: "
+ << connection.getMgmtId() << ", old user " << connection.getUserId()
+ << ", new user " << username);
+ }
+ } else {
+ // connection exists but has not been opened.
+ // setUserId is called in normal course. The user gets counted when connection is opened.
+ }
+ } else {
+ // Connection does not exist.
+ }
+}
+
+
//
// getClientIp - given a connection's mgmtId return the client host part.
//
diff --git a/qpid/cpp/src/qpid/acl/AclConnectionCounter.h b/qpid/cpp/src/qpid/acl/AclConnectionCounter.h
index eec8e90256..54fa6933ff 100644
--- a/qpid/cpp/src/qpid/acl/AclConnectionCounter.h
+++ b/qpid/cpp/src/qpid/acl/AclConnectionCounter.h
@@ -94,6 +94,7 @@ public:
// Connection counting
bool approveConnection(const broker::Connection& conn);
+ void setUserId(const broker::Connection& connection, const std::string& username);
};
}} // namespace qpid::ha
diff --git a/qpid/cpp/src/qpid/broker/AclModule.h b/qpid/cpp/src/qpid/broker/AclModule.h
index 7c180439cf..f1eb0fc5f9 100644
--- a/qpid/cpp/src/qpid/broker/AclModule.h
+++ b/qpid/cpp/src/qpid/broker/AclModule.h
@@ -145,6 +145,10 @@ namespace broker {
*/
virtual bool approveConnection (const Connection& connection)=0;
+ /** Change connection's counted userId
+ */
+ virtual void setUserId(const Connection& connection, const std::string& username)=0;
+
virtual ~AclModule() {};
};
} // namespace broker
diff --git a/qpid/cpp/src/qpid/broker/Connection.cpp b/qpid/cpp/src/qpid/broker/Connection.cpp
index 8d250a32e5..e68c906cc2 100644
--- a/qpid/cpp/src/qpid/broker/Connection.cpp
+++ b/qpid/cpp/src/qpid/broker/Connection.cpp
@@ -25,6 +25,7 @@
#include "qpid/broker/Bridge.h"
#include "qpid/broker/Broker.h"
#include "qpid/broker/Queue.h"
+#include "qpid/broker/AclModule.h"
#include "qpid/sys/SecuritySettings.h"
#include "qpid/sys/ClusterSafe.h"
@@ -278,6 +279,13 @@ void Connection::notifyConnectionForced(const string& text)
void Connection::setUserId(const string& userId)
{
+ // Account for changing userId
+ AclModule* acl = broker.getAcl();
+ if (acl)
+ {
+ acl->setUserId(*this, userId);
+ }
+
ConnectionState::setUserId(userId);
// In a cluster, the cluster code will raise the connect event
// when the connection is replicated to the cluster.