Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-64549

User of role '__system' can not show system tables on mongos

    • Type: Icon: Bug Bug
    • Resolution: Done
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: None
    • Component/s: None
    • Labels:
      None
    • ALL

      In our exceptional circumstances, we need to creat a user of role '_system' in the sharding cluster of 4.4.8/4.4.10/5.0. We find that the user can not list system tables by the 'show tables' command. However, the user of role '_system' can show system collections by 'show tables' in the config server.

      As a user of the 'root' role, we can list system tables by the 'show tables' command both on the mongos and config server.

      The `show tables` results of 'root' and '_system' are different on mongos. This seems abnormal, because both 'root' and '_system' should be superuser and can list system tables anywhere.

      We think there is a BUG on the listCommands procedure of mongos.

      We try to locate the BUG and find that there is a command rewrite procedure on the listCollections of mongos, which will add a filter to filter all system tables.

      In the src/mongo/s/commands/commands_public.cpp of v4.4.8:

      class CmdListCollections : public BasicCommand {class CmdListCollections : public BasicCommand {public: ......    BSONObj rewriteCommandForListingOwnCollections(OperationContext* opCtx,                                                   const std::string& dbName,                                                   const BSONObj& cmdObj) {        // DB resource grants all non-system collections, so filter out system collections.        // This is done inside the $or, since some system collections might be granted specific        // privileges.        if (authzSession->isAuthorizedForAnyActionOnResource(                ResourcePattern::forDatabaseName(dbName))) {            mutablebson::Element systemCollectionsFilter = rewrittenCmdObj.makeElementObject(                "", BSON("name" << BSON("$regex" << BSONRegEx("^(?!system\\.)"))));            uassertStatusOK(newFilterOr.pushBack(systemCollectionsFilter));        }                // Compute the set of collection names which would be permissible to return.        std::set<std::string> collectionNames;        for (UserNameIterator nameIter = authzSession->getAuthenticatedUserNames(); nameIter.more();             nameIter.next()) {            User* authUser = authzSession->lookupUser(*nameIter);            const User::ResourcePrivilegeMap& resourcePrivilegeMap = authUser->getPrivileges();            for (const std::pair<ResourcePattern, Privilege>& resourcePrivilege :                 resourcePrivilegeMap) {                const auto& resource = resourcePrivilege.first;                if (resource.isCollectionPattern() ||                    (resource.isExactNamespacePattern() && resource.databaseToMatch() == dbName)) {                    collectionNames.emplace(resource.collectionToMatch().toString());                }            }        }        ...... } ......} cmdListCollections;
      

            Assignee:
            chris.kelly@mongodb.com Chris Kelly
            Reporter:
            zhangjiaqiao46@gmail.com 渣侨 渣
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: