diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx index 27f2fba2..c6113c45 100644 --- a/common/rfb/VNCSConnectionST.cxx +++ b/common/rfb/VNCSConnectionST.cxx @@ -98,7 +98,7 @@ VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s, con user[offset] = '\0'; } - bool read, write, owner; + bool read = false, write = false, owner = false; if (!getPerms(read, write, owner)) { accessRights &= ~(WRITER_PERMS | AccessView); } @@ -1242,9 +1242,12 @@ bool VNCSConnectionST::getPerms(bool &read, bool &write, bool &owner) const { bool found = false; if (disablebasicauth) { - // We're running without basicauth + // No basicauth: grant full perms; owner is meaningless without an + // authenticated owner, so report it false (is_owner()/checkOwnerConn() + // would otherwise read it uninitialized). read = true; write = true; + owner = false; return true; } if (user[0]) { @@ -1869,7 +1872,7 @@ void VNCSConnectionST::udpDowngrade(const bool byServer) void VNCSConnectionST::subscribeUnixRelay(const char *name) { - bool read, write, owner; + bool read = false, write = false, owner = false; if (!getPerms(read, write, owner) || !write) { // Need write permissions to subscribe writer()->writeSubscribeUnixRelay(false, "No permissions"); diff --git a/common/rfb/VNCServerST.cxx b/common/rfb/VNCServerST.cxx index 21dde7b8..074f06f2 100644 --- a/common/rfb/VNCServerST.cxx +++ b/common/rfb/VNCServerST.cxx @@ -819,7 +819,7 @@ std::vector VNCServerST::getSessionUsers() { if (!client->authenticated()) { continue; } - users.push_back(SessionInfo(client->getUsername(),client->getConnectionTime())); + users.push_back(SessionInfo(client->getUsername(), client->getConnectionTime(), client->is_owner())); } return users; } @@ -830,6 +830,11 @@ void VNCServerST::updateSessionUsersList() if (!sessionUsers.empty()) { std::string sessionUsersJson = formatUsersToJson(sessionUsers); apimessager->mainUpdateSessionsInfo(sessionUsersJson); + } else { + // Last disconnect: reset to the canonical empty shape so + // /api/get_sessions signals an empty session (matches the init + // literal in GetAPIMessager.cxx). + apimessager->mainUpdateSessionsInfo("{\"users\":[]}"); } } diff --git a/common/rfb/util.cxx b/common/rfb/util.cxx index cd150153..6bee525d 100644 --- a/common/rfb/util.cxx +++ b/common/rfb/util.cxx @@ -686,7 +686,7 @@ namespace rfb { { std::string usersList = "["; bool firstUser = true; - for (const auto&[userName, connectionTime] : users) + for (const auto&[userName, connectionTime, isOwner] : users) { std::string username =userName; time_t connTime = connectionTime; @@ -702,7 +702,9 @@ namespace rfb { userEntry.append(username); userEntry.append( "\", \"connected_since\":\""); userEntry.append(timeStr); - userEntry.append("\"}"); + userEntry.append( "\", \"is_owner\":"); + userEntry.append( isOwner ? "true" : "false"); + userEntry.append("}"); usersList.append(userEntry); } diff --git a/common/rfb/util.h b/common/rfb/util.h index 1dd2ab32..6367092e 100644 --- a/common/rfb/util.h +++ b/common/rfb/util.h @@ -72,10 +72,12 @@ namespace rfb { struct SessionInfo { std::string userName; time_t connectionTime; - SessionInfo(const std::string& name, const time_t& time) + bool isOwner; + SessionInfo(const std::string& name, const time_t& time, const bool ownerFlag = false) { userName = name; connectionTime = time; + isOwner = ownerFlag; } };