Ejemplo n.º 1
0
void AuthorizationSession::_buildAuthenticatedRolesVector() {
    _authenticatedRoleNames.clear();
    for (UserSet::iterator it = _authenticatedUsers.begin(); it != _authenticatedUsers.end();
         ++it) {
        RoleNameIterator roles = (*it)->getIndirectRoles();
        while (roles.more()) {
            RoleName roleName = roles.next();
            _authenticatedRoleNames.push_back(RoleName(roleName.getRole(), roleName.getDB()));
        }
    }
}
Ejemplo n.º 2
0
    /**
     * Modifies the given User object by inspecting its roles and giving it the relevant
     * privileges from those roles.
     */
    void V1PrivilegeDocumentParser::initializeUserPrivilegesFromRoles(User* user) const {
        std::vector<Privilege> privileges;

        RoleNameIterator it = user->getRoles();
        while (it.more()) {
            const RoleName& roleName = it.next();
            _addPrivilegesForSystemRole(roleName.getDB().toString(),
                                        roleName.getRole().toString(),
                                        &privileges);
        }
        user->addPrivileges(privileges);
    }
    Status AuthzManagerExternalStateMock::getUserDescription(
            const UserName& userName, BSONObj* result) {
        BSONObj privDoc;
        Status status = getPrivilegeDocument(userName, 2, &privDoc);
        if (!status.isOK())
            return status;

        unordered_set<RoleName> indirectRoles;
        PrivilegeVector allPrivileges;
        for (BSONObjIterator iter(privDoc["roles"].Obj()); iter.more(); iter.next()) {
            if (!(*iter)["hasRole"].trueValue())
                continue;
            RoleName roleName((*iter)[AuthorizationManager::ROLE_NAME_FIELD_NAME].str(),
                              (*iter)[AuthorizationManager::ROLE_SOURCE_FIELD_NAME].str());
            indirectRoles.insert(roleName);
            for (RoleNameIterator subordinates = _roleGraph.getIndirectSubordinates(
                         roleName);
                 subordinates.more();
                 subordinates.next()) {

                indirectRoles.insert(subordinates.get());
            }
            const PrivilegeVector& rolePrivileges(_roleGraph.getAllPrivileges(roleName));
            for (PrivilegeVector::const_iterator priv = rolePrivileges.begin(),
                     end = rolePrivileges.end();
                 priv != end;
                 ++priv) {

                Privilege::addPrivilegeToPrivilegeVector(&allPrivileges, *priv);
            }
        }

        mutablebson::Document userDoc(privDoc, mutablebson::Document::kInPlaceDisabled);
        mutablebson::Element indirectRolesElement = userDoc.makeElementArray("indirectRoles");
        mutablebson::Element privilegesElement = userDoc.makeElementArray("privileges");
        mutablebson::Element warningsElement = userDoc.makeElementArray("warnings");
        fassert(17180, userDoc.root().pushBack(privilegesElement));
        fassert(17181, userDoc.root().pushBack(indirectRolesElement));

        addRoleNameObjectsToArrayElement(indirectRolesElement,
                                         makeRoleNameIteratorForContainer(indirectRoles));
        addPrivilegeObjectsOrWarningsToArrayElement(
                privilegesElement, warningsElement, allPrivileges);
        if (warningsElement.hasChildren()) {
            fassert(17182, userDoc.root().pushBack(warningsElement));
        }
        *result = userDoc.getObject();
        return Status::OK();
    }
void AuthzManagerExternalStateLocal::_resolveUserRoles(mutablebson::Document* userDoc,
                                                       const std::vector<RoleName>& directRoles) {
    unordered_set<RoleName> indirectRoles;
    PrivilegeVector allPrivileges;
    bool isRoleGraphInconsistent;
    {
        stdx::lock_guard<stdx::mutex> lk(_roleGraphMutex);
        isRoleGraphInconsistent = _roleGraphState == roleGraphStateConsistent;
        for (size_t i = 0; i < directRoles.size(); ++i) {
            const RoleName& role(directRoles[i]);
            indirectRoles.insert(role);
            if (isRoleGraphInconsistent) {
                for (RoleNameIterator subordinates = _roleGraph.getIndirectSubordinates(role);
                     subordinates.more();
                     subordinates.next()) {
                    indirectRoles.insert(subordinates.get());
                }
            }
            const PrivilegeVector& rolePrivileges(isRoleGraphInconsistent
                                                      ? _roleGraph.getAllPrivileges(role)
                                                      : _roleGraph.getDirectPrivileges(role));
            for (PrivilegeVector::const_iterator priv = rolePrivileges.begin(),
                                                 end = rolePrivileges.end();
                 priv != end;
                 ++priv) {
                Privilege::addPrivilegeToPrivilegeVector(&allPrivileges, *priv);
            }
        }
    }

    mutablebson::Element inheritedRolesElement = userDoc->makeElementArray("inheritedRoles");
    mutablebson::Element privilegesElement = userDoc->makeElementArray("inheritedPrivileges");
    mutablebson::Element warningsElement = userDoc->makeElementArray("warnings");
    fassert(17159, userDoc->root().pushBack(inheritedRolesElement));
    fassert(17158, userDoc->root().pushBack(privilegesElement));
    if (!isRoleGraphInconsistent) {
        fassert(17160,
                warningsElement.appendString(
                    "", "Role graph inconsistent, only direct privileges available."));
    }
    addRoleNameObjectsToArrayElement(inheritedRolesElement,
                                     makeRoleNameIteratorForContainer(indirectRoles));
    addPrivilegeObjectsOrWarningsToArrayElement(privilegesElement, warningsElement, allPrivileges);
    if (warningsElement.hasChildren()) {
        fassert(17161, userDoc->root().pushBack(warningsElement));
    }
}
    Status AuthzManagerExternalStateLocal::getRoleDescriptionsForDB(const std::string dbname,
                                                                    bool showPrivileges,
                                                                    bool showBuiltinRoles,
                                                                    vector<BSONObj>* result) {
        boost::lock_guard<boost::mutex> lk(_roleGraphMutex);

        for (RoleNameIterator it = _roleGraph.getRolesForDatabase(dbname);
                it.more(); it.next()) {
            if (!showBuiltinRoles && _roleGraph.isBuiltinRole(it.get())) {
                continue;
            }
            BSONObj roleDoc;
            Status status = _getRoleDescription_inlock(it.get(), showPrivileges, &roleDoc);
            if (!status.isOK()) {
                return status;
            }
            result->push_back(roleDoc);
        }
        return Status::OK();
    }
Ejemplo n.º 6
0
    Status AuthorizationManager::getBSONForRole(RoleGraph* graph,
                                                const RoleName& roleName,
                                                mutablebson::Element result) {
        if (!graph->roleExists(roleName)) {
            return Status(ErrorCodes::RoleNotFound,
                          mongoutils::str::stream() << roleName.getFullName() <<
                                  "does not name an existing role");
        }
        std::string id = mongoutils::str::stream() << roleName.getDB() << "." << roleName.getRole();
        result.appendString("_id", id);
        result.appendString(ROLE_NAME_FIELD_NAME, roleName.getRole());
        result.appendString(ROLE_SOURCE_FIELD_NAME, roleName.getDB());

        // Build privileges array
        mutablebson::Element privilegesArrayElement =
                result.getDocument().makeElementArray("privileges");
        result.pushBack(privilegesArrayElement);
        const PrivilegeVector& privileges = graph->getDirectPrivileges(roleName);
        Status status = getBSONForPrivileges(privileges, privilegesArrayElement);
        if (!status.isOK()) {
            return status;
        }

        // Build roles array
        mutablebson::Element rolesArrayElement = result.getDocument().makeElementArray("roles");
        result.pushBack(rolesArrayElement);
        for (RoleNameIterator roles = graph->getDirectSubordinates(roleName);
             roles.more();
             roles.next()) {

            const RoleName& subRole = roles.get();
            mutablebson::Element roleObj = result.getDocument().makeElementObject("");
            roleObj.appendString(ROLE_NAME_FIELD_NAME, subRole.getRole());
            roleObj.appendString(ROLE_SOURCE_FIELD_NAME, subRole.getDB());
            rolesArrayElement.pushBack(roleObj);
        }

        return Status::OK();
    }
    Status AuthzManagerExternalStateLocal::getUserDescription(
            const UserName& userName,
            BSONObj* result) {

        BSONObj userDoc;
        Status status = _getUserDocument(userName, &userDoc);
        if (!status.isOK())
            return status;

        BSONElement directRolesElement;
        status = bsonExtractTypedField(userDoc, "roles", Array, &directRolesElement);
        if (!status.isOK())
            return status;
        std::vector<RoleName> directRoles;
        status = V2UserDocumentParser::parseRoleVector(BSONArray(directRolesElement.Obj()),
                                                       &directRoles);
        if (!status.isOK())
            return status;

        unordered_set<RoleName> indirectRoles;
        PrivilegeVector allPrivileges;
        bool isRoleGraphInconsistent;
        {
            boost::lock_guard<boost::mutex> lk(_roleGraphMutex);
            isRoleGraphInconsistent = _roleGraphState == roleGraphStateConsistent;
            for (size_t i = 0; i < directRoles.size(); ++i) {
                const RoleName& role(directRoles[i]);
                indirectRoles.insert(role);
                if (isRoleGraphInconsistent) {
                    for (RoleNameIterator subordinates = _roleGraph.getIndirectSubordinates(role);
                         subordinates.more();
                         subordinates.next()) {

                        indirectRoles.insert(subordinates.get());
                    }
                }
                const PrivilegeVector& rolePrivileges(
                        isRoleGraphInconsistent ?
                        _roleGraph.getAllPrivileges(role) :
                        _roleGraph.getDirectPrivileges(role));
                for (PrivilegeVector::const_iterator priv = rolePrivileges.begin(),
                         end = rolePrivileges.end();
                     priv != end;
                     ++priv) {

                    Privilege::addPrivilegeToPrivilegeVector(&allPrivileges, *priv);
                }
            }
        }

        mutablebson::Document resultDoc(userDoc, mutablebson::Document::kInPlaceDisabled);
        mutablebson::Element inheritedRolesElement = resultDoc.makeElementArray("inheritedRoles");
        mutablebson::Element privilegesElement = resultDoc.makeElementArray("inheritedPrivileges");
        mutablebson::Element warningsElement = resultDoc.makeElementArray("warnings");
        fassert(17159, resultDoc.root().pushBack(inheritedRolesElement));
        fassert(17158, resultDoc.root().pushBack(privilegesElement));
        if (!isRoleGraphInconsistent) {
            fassert(17160, warningsElement.appendString(
                            "", "Role graph inconsistent, only direct privileges available."));
        }
        addRoleNameObjectsToArrayElement(inheritedRolesElement,
                                         makeRoleNameIteratorForContainer(indirectRoles));
        addPrivilegeObjectsOrWarningsToArrayElement(
                privilegesElement, warningsElement, allPrivileges);
        if (warningsElement.hasChildren()) {
            fassert(17161, resultDoc.root().pushBack(warningsElement));
        }
        *result = resultDoc.getObject();
        return Status::OK();
    }
Ejemplo n.º 8
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;
    }
Ejemplo n.º 9
0
void User::setIndirectRoles(RoleNameIterator indirectRoles) {
    _indirectRoles.clear();
    while (indirectRoles.more()) {
        _indirectRoles.push_back(indirectRoles.next());
    }
}
Ejemplo n.º 10
0
void User::setRoles(RoleNameIterator roles) {
    _roles.clear();
    while (roles.more()) {
        _roles.insert(roles.next());
    }
}