예제 #1
0
std::string AuthorizationSession::getAuthenticatedUserNamesToken() {
    std::string ret;
    for (UserNameIterator nameIter = getAuthenticatedUserNames(); nameIter.more();
         nameIter.next()) {
        ret += '\0';  // Using a NUL byte which isn't valid in usernames to separate them.
        ret += nameIter->getFullName();
    }

    return ret;
}
예제 #2
0
        bool run(const string&, BSONObj& cmdObj, int, string& errmsg,
                 BSONObjBuilder& result, bool fromRepl) {
            AuthorizationSession* authSession =
                    ClientBasic::getCurrent()->getAuthorizationSession();

            BSONObjBuilder authInfo(result.subobjStart("authInfo"));
            {
                BSONArrayBuilder authenticatedUsers(authInfo.subarrayStart("authenticatedUsers"));

                UserNameIterator nameIter = authSession->getAuthenticatedUserNames();
                for ( ; nameIter.more(); nameIter.next()) {
                    BSONObjBuilder userInfoBuilder(authenticatedUsers.subobjStart());
                    userInfoBuilder.append(AuthorizationManager::USER_NAME_FIELD_NAME,
                                           nameIter->getUser());
                    userInfoBuilder.append(AuthorizationManager::USER_DB_FIELD_NAME,
                                           nameIter->getDB());
                    userInfoBuilder.doneFast();
                }
                authenticatedUsers.doneFast();
            }
            authInfo.doneFast();

            return true;
        }
예제 #3
0
    bool run(OperationContext* txn,
             const string&,
             BSONObj& cmdObj,
             int,
             string& errmsg,
             BSONObjBuilder& result) {
        AuthorizationSession* authSession = AuthorizationSession::get(ClientBasic::getCurrent());

        bool showPrivileges;
        Status status =
            bsonExtractBooleanFieldWithDefault(cmdObj, "showPrivileges", false, &showPrivileges);
        if (!status.isOK()) {
            return appendCommandStatus(result, status);
        }

        BSONObjBuilder authInfo(result.subobjStart("authInfo"));
        {
            BSONArrayBuilder authenticatedUsers(authInfo.subarrayStart("authenticatedUsers"));
            UserNameIterator nameIter = authSession->getAuthenticatedUserNames();

            for (; nameIter.more(); nameIter.next()) {
                BSONObjBuilder userInfoBuilder(authenticatedUsers.subobjStart());
                userInfoBuilder.append(AuthorizationManager::USER_NAME_FIELD_NAME,
                                       nameIter->getUser());
                userInfoBuilder.append(AuthorizationManager::USER_DB_FIELD_NAME, nameIter->getDB());
            }
        }
        {
            BSONArrayBuilder authenticatedRoles(authInfo.subarrayStart("authenticatedUserRoles"));
            RoleNameIterator roleIter = authSession->getAuthenticatedRoleNames();

            for (; roleIter.more(); roleIter.next()) {
                BSONObjBuilder roleInfoBuilder(authenticatedRoles.subobjStart());
                roleInfoBuilder.append(AuthorizationManager::ROLE_NAME_FIELD_NAME,
                                       roleIter->getRole());
                roleInfoBuilder.append(AuthorizationManager::ROLE_DB_FIELD_NAME, roleIter->getDB());
            }
        }
        if (showPrivileges) {
            BSONArrayBuilder authenticatedPrivileges(
                authInfo.subarrayStart("authenticatedUserPrivileges"));

            // Create a unified map of resources to privileges, to avoid duplicate
            // entries in the connection status output.
            User::ResourcePrivilegeMap unifiedResourcePrivilegeMap;
            UserNameIterator nameIter = authSession->getAuthenticatedUserNames();

            for (; nameIter.more(); nameIter.next()) {
                User* authUser = authSession->lookupUser(*nameIter);
                const User::ResourcePrivilegeMap& resourcePrivilegeMap = authUser->getPrivileges();
                for (User::ResourcePrivilegeMap::const_iterator it = resourcePrivilegeMap.begin();
                     it != resourcePrivilegeMap.end();
                     ++it) {
                    if (unifiedResourcePrivilegeMap.find(it->first) ==
                        unifiedResourcePrivilegeMap.end()) {
                        unifiedResourcePrivilegeMap[it->first] = it->second;
                    } else {
                        unifiedResourcePrivilegeMap[it->first].addActions(it->second.getActions());
                    }
                }
            }

            for (User::ResourcePrivilegeMap::const_iterator it =
                     unifiedResourcePrivilegeMap.begin();
                 it != unifiedResourcePrivilegeMap.end();
                 ++it) {
                authenticatedPrivileges << it->second.toBSON();
            }
        }

        authInfo.doneFast();

        return true;
    }
예제 #4
0
    BSONObj rewriteCommandForListingOwnCollections(OperationContext* opCtx,
                                                   const std::string& dbName,
                                                   const BSONObj& cmdObj) {
        mutablebson::Document rewrittenCmdObj(cmdObj);
        mutablebson::Element ownCollections =
            mutablebson::findFirstChildNamed(rewrittenCmdObj.root(), "authorizedCollections");

        AuthorizationSession* authzSession = AuthorizationSession::get(opCtx->getClient());

        // We must strip $ownCollections from the delegated command.
        uassertStatusOK(ownCollections.remove());

        BSONObj collectionFilter;

        // Extract and retain any previous filter
        mutablebson::Element oldFilter =
            mutablebson::findFirstChildNamed(rewrittenCmdObj.root(), "filter");

        // Make a new filter, containing a $and array.
        mutablebson::Element newFilter = rewrittenCmdObj.makeElementObject("filter");
        mutablebson::Element newFilterAnd = rewrittenCmdObj.makeElementArray("$and");
        uassertStatusOK(newFilter.pushBack(newFilterAnd));

        // Append a rule to the $and, which rejects system collections.
        mutablebson::Element systemCollectionsFilter = rewrittenCmdObj.makeElementObject(
            "", BSON("name" << BSON("$regex" << BSONRegEx("^(?!system\\.)"))));
        uassertStatusOK(newFilterAnd.pushBack(systemCollectionsFilter));

        if (!authzSession->isAuthorizedForAnyActionOnResource(
                ResourcePattern::forDatabaseName(dbName))) {
            // We passed an auth check which said we might be able to render some collections,
            // but it doesn't seem like we should render all of them. We must filter.

            // 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());
                    }
                }
            }

            // Construct a new filter predicate which returns only collections we were found to
            // have privileges for.
            BSONObjBuilder predicateBuilder;
            BSONObjBuilder nameBuilder(predicateBuilder.subobjStart("name"));
            BSONArrayBuilder setBuilder(nameBuilder.subarrayStart("$in"));

            // Load the de-duplicated set into a BSON array
            for (StringData collectionName : collectionNames) {
                setBuilder << collectionName;
            }
            setBuilder.done();
            nameBuilder.done();

            collectionFilter = predicateBuilder.obj();

            // Filter the results by our collection names.
            mutablebson::Element newFilterAndIn =
                rewrittenCmdObj.makeElementObject("", collectionFilter);
            uassertStatusOK(newFilterAnd.pushBack(newFilterAndIn));
        }

        // If there was a pre-existing filter, compose it with our new one.
        if (oldFilter.ok()) {
            uassertStatusOK(oldFilter.remove());
            uassertStatusOK(newFilterAnd.pushBack(oldFilter));
        }

        // Attach our new composite filter back onto the listCollections command object.
        uassertStatusOK(rewrittenCmdObj.root().pushBack(newFilter));

        return rewrittenCmdObj.getObject();
    }