Status AuthzManagerExternalStateMongos::getRoleDescription(OperationContext* opCtx,
                                                           const RoleName& roleName,
                                                           PrivilegeFormat showPrivileges,
                                                           BSONObj* result) {
    BSONObjBuilder rolesInfoCmd;
    rolesInfoCmd.append("rolesInfo",
                        BSON_ARRAY(BSON(AuthorizationManager::ROLE_NAME_FIELD_NAME
                                        << roleName.getRole()
                                        << AuthorizationManager::ROLE_DB_FIELD_NAME
                                        << roleName.getDB())));
    addShowPrivilegesToBuilder(&rolesInfoCmd, showPrivileges);

    BSONObjBuilder builder;
    const bool ok = Grid::get(opCtx)->catalogClient()->runUserManagementReadCommand(
        opCtx, "admin", rolesInfoCmd.obj(), &builder);
    BSONObj cmdResult = builder.obj();
    if (!ok) {
        return getStatusFromCommandResult(cmdResult);
    }

    std::vector<BSONElement> foundRoles = cmdResult[rolesFieldName(showPrivileges)].Array();
    if (foundRoles.size() == 0) {
        return Status(ErrorCodes::RoleNotFound, "Role \"" + roleName.toString() + "\" not found");
    }

    if (foundRoles.size() > 1) {
        return Status(ErrorCodes::RoleDataInconsistent,
                      str::stream() << "Found multiple roles on the \"" << roleName.getDB()
                                    << "\" database with name \""
                                    << roleName.getRole()
                                    << "\"");
    }
    *result = foundRoles[0].Obj().getOwned();
    return Status::OK();
}
Exemplo n.º 2
0
 Status AuthorizationManager::updateRoleDocument(OperationContext* txn,
                                                 const RoleName& role,
                                                 const BSONObj& updateObj,
                                                 const BSONObj& writeConcern) const {
     Status status = _externalState->updateOne(
             txn,
             rolesCollectionNamespace,
             BSON(AuthorizationManager::ROLE_NAME_FIELD_NAME << role.getRole() <<
                  AuthorizationManager::ROLE_DB_FIELD_NAME << role.getDB()),
             updateObj,
             false,
             writeConcern);
     if (status.isOK()) {
         return status;
     }
     if (status.code() == ErrorCodes::NoMatchingDocument) {
         return Status(ErrorCodes::RoleNotFound,
                       mongoutils::str::stream() << "Role " << role.getFullName() <<
                               " not found");
     }
     if (status.code() == ErrorCodes::UnknownError) {
         return Status(ErrorCodes::RoleModificationFailed, status.reason());
     }
     return status;
 }
Status AuthzManagerExternalStateMongos::getRoleDescription(OperationContext* txn,
                                                           const RoleName& roleName,
                                                           bool showPrivileges,
                                                           BSONObj* result) {
    BSONObj rolesInfoCmd =
        BSON("rolesInfo" << BSON_ARRAY(BSON(
                                AuthorizationManager::ROLE_NAME_FIELD_NAME
                                << roleName.getRole() << AuthorizationManager::ROLE_DB_FIELD_NAME
                                << roleName.getDB())) << "showPrivileges" << showPrivileges);
    BSONObjBuilder builder;
    const bool ok = grid.catalogManager(txn)
                        ->runUserManagementReadCommand(txn, "admin", rolesInfoCmd, &builder);
    BSONObj cmdResult = builder.obj();
    if (!ok) {
        return Command::getStatusFromCommandResult(cmdResult);
    }

    std::vector<BSONElement> foundRoles = cmdResult["roles"].Array();
    if (foundRoles.size() == 0) {
        return Status(ErrorCodes::RoleNotFound, "Role \"" + roleName.toString() + "\" not found");
    }

    if (foundRoles.size() > 1) {
        return Status(ErrorCodes::RoleDataInconsistent,
                      str::stream() << "Found multiple roles on the \"" << roleName.getDB()
                                    << "\" database with name \"" << roleName.getRole() << "\"");
    }
    *result = foundRoles[0].Obj().getOwned();
    return Status::OK();
}
Exemplo n.º 4
0
Status RoleGraph::removeAllRolesFromRole(const RoleName& victim) {
    typedef std::vector<RoleName> RoleNameVector;
    if (!roleExists(victim)) {
        return Status(ErrorCodes::RoleNotFound,
                      mongoutils::str::stream() << "Role: " << victim.getFullName()
                                                << " does not exist",
                      0);
    }
    if (isBuiltinRole(victim)) {
        return Status(ErrorCodes::InvalidRoleModification,
                      mongoutils::str::stream() << "Cannot remove roles from built-in role: "
                                                << victim.getFullName(),
                      0);
    }

    RoleNameVector& subordinatesOfVictim = _roleToSubordinates[victim];
    for (RoleNameVector::const_iterator subordinateRole = subordinatesOfVictim.begin(),
                                        end = subordinatesOfVictim.end();
         subordinateRole != end;
         ++subordinateRole) {
        RoleNameVector& membersOfSubordinate = _roleToMembers[*subordinateRole];
        RoleNameVector::iterator toErase =
            std::find(membersOfSubordinate.begin(), membersOfSubordinate.end(), victim);
        fassert(17173, toErase != membersOfSubordinate.end());
        membersOfSubordinate.erase(toErase);
    }
    subordinatesOfVictim.clear();
    return Status::OK();
}
Exemplo n.º 5
0
Status RoleGraph::addRoleToRole(const RoleName& recipient, const RoleName& role) {
    if (!roleExists(recipient)) {
        return Status(ErrorCodes::RoleNotFound,
                      mongoutils::str::stream() << "Role: " << recipient.getFullName()
                                                << " does not exist");
    }
    if (isBuiltinRole(recipient)) {
        return Status(ErrorCodes::InvalidRoleModification,
                      mongoutils::str::stream() << "Cannot grant roles to built-in role: "
                                                << role.getFullName());
    }
    if (!roleExists(role)) {
        return Status(ErrorCodes::RoleNotFound,
                      mongoutils::str::stream() << "Role: " << role.getFullName()
                                                << " does not exist");
    }

    if (std::find(_roleToSubordinates[recipient].begin(),
                  _roleToSubordinates[recipient].end(),
                  role) == _roleToSubordinates[recipient].end()) {
        // Only add role if it's not already present
        _roleToSubordinates[recipient].push_back(role);
        _roleToMembers[role].push_back(recipient);
    }

    return Status::OK();
}
Exemplo n.º 6
0
Status RoleGraph::deleteRole(const RoleName& role) {
    if (!roleExists(role)) {
        return Status(ErrorCodes::RoleNotFound,
                      mongoutils::str::stream() << "Role: " << role.getFullName()
                                                << " does not exist",
                      0);
    }
    if (isBuiltinRole(role)) {
        return Status(ErrorCodes::InvalidRoleModification,
                      mongoutils::str::stream() << "Cannot delete built-in role: "
                                                << role.getFullName(),
                      0);
    }

    for (std::vector<RoleName>::iterator it = _roleToSubordinates[role].begin();
         it != _roleToSubordinates[role].end();
         ++it) {
        _roleToMembers[*it].erase(
            std::find(_roleToMembers[*it].begin(), _roleToMembers[*it].end(), role));
    }
    for (std::vector<RoleName>::iterator it = _roleToMembers[role].begin();
         it != _roleToMembers[role].end();
         ++it) {
        _roleToSubordinates[*it].erase(
            std::find(_roleToSubordinates[*it].begin(), _roleToSubordinates[*it].end(), role));
    }
    _roleToSubordinates.erase(role);
    _roleToIndirectSubordinates.erase(role);
    _roleToMembers.erase(role);
    _directPrivilegesForRole.erase(role);
    _allPrivilegesForRole.erase(role);
    _allRoles.erase(role);
    return Status::OK();
}
 Status AuthzManagerExternalStateMongos::getRoleDescription(const RoleName& roleName,
                                                            BSONObj* result) {
     try {
         scoped_ptr<ScopedDbConnection> conn(getConnectionForAuthzCollection(
                 AuthorizationManager::rolesCollectionNamespace));
         BSONObj cmdResult;
         conn->get()->runCommand(
                 "admin",
                 BSON("rolesInfo" <<
                      BSON_ARRAY(BSON(AuthorizationManager::ROLE_NAME_FIELD_NAME <<
                                      roleName.getRole() <<
                                      AuthorizationManager::ROLE_SOURCE_FIELD_NAME <<
                                      roleName.getDB()))),
                 cmdResult);
         if (!cmdResult["ok"].trueValue()) {
             int code = cmdResult["code"].numberInt();
             if (code == 0) code = ErrorCodes::UnknownError;
             return Status(ErrorCodes::Error(code), cmdResult["errmsg"].str());
         }
         *result = cmdResult["roles"]["0"].Obj().getOwned();
         conn->done();
         return Status::OK();
     } catch (const DBException& e) {
         return e.toStatus();
     }
 }
    Status AuthzManagerExternalStateLocal::_getRoleDescription_inlock(const RoleName& roleName,
                                                                      bool showPrivileges,
                                                                      BSONObj* result) {
        if (!_roleGraph.roleExists(roleName))
            return Status(ErrorCodes::RoleNotFound, "No role named " + roleName.toString());

        mutablebson::Document resultDoc;
        fassert(17162, resultDoc.root().appendString(
                        AuthorizationManager::ROLE_NAME_FIELD_NAME, roleName.getRole()));
        fassert(17163, resultDoc.root().appendString(
                        AuthorizationManager::ROLE_SOURCE_FIELD_NAME, roleName.getDB()));
        fassert(17267,
                resultDoc.root().appendBool("isBuiltin", _roleGraph.isBuiltinRole(roleName)));
        mutablebson::Element rolesElement = resultDoc.makeElementArray("roles");
        fassert(17164, resultDoc.root().pushBack(rolesElement));
        mutablebson::Element inheritedRolesElement = resultDoc.makeElementArray("inheritedRoles");
        fassert(17165, resultDoc.root().pushBack(inheritedRolesElement));
        mutablebson::Element privilegesElement = resultDoc.makeElementArray("privileges");
        mutablebson::Element inheritedPrivilegesElement =
                resultDoc.makeElementArray("inheritedPrivileges");
        if (showPrivileges) {
            fassert(17166, resultDoc.root().pushBack(privilegesElement));
        }
        mutablebson::Element warningsElement = resultDoc.makeElementArray("warnings");

        addRoleNameObjectsToArrayElement(rolesElement, _roleGraph.getDirectSubordinates(roleName));
        if (_roleGraphState == roleGraphStateConsistent) {
            addRoleNameObjectsToArrayElement(
                    inheritedRolesElement, _roleGraph.getIndirectSubordinates(roleName));
            if (showPrivileges) {
                addPrivilegeObjectsOrWarningsToArrayElement(
                        privilegesElement,
                        warningsElement,
                        _roleGraph.getDirectPrivileges(roleName));

                addPrivilegeObjectsOrWarningsToArrayElement(
                        inheritedPrivilegesElement,
                        warningsElement,
                        _roleGraph.getAllPrivileges(roleName));

                fassert(17323, resultDoc.root().pushBack(inheritedPrivilegesElement));
            }
        }
        else if (showPrivileges) {
            warningsElement.appendString(
                    "", "Role graph state inconsistent; only direct privileges available.");
            addPrivilegeObjectsOrWarningsToArrayElement(
                    privilegesElement, warningsElement, _roleGraph.getDirectPrivileges(roleName));
        }
        if (warningsElement.hasChildren()) {
            fassert(17167, resultDoc.root().pushBack(warningsElement));
        }
        *result = resultDoc.getObject();
        return Status::OK();
    }
Exemplo n.º 9
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()));
        }
    }
}
Exemplo n.º 10
0
Status RoleGraph::removeAllPrivilegesFromRole(const RoleName& role) {
    if (!roleExists(role)) {
        return Status(ErrorCodes::RoleNotFound,
                      mongoutils::str::stream() << "Role: " << role.getFullName()
                                                << " does not exist",
                      0);
    }
    if (isBuiltinRole(role)) {
        return Status(ErrorCodes::InvalidRoleModification,
                      mongoutils::str::stream() << "Cannot remove privileges from built-in role: "
                                                << role.getFullName());
    }
    _directPrivilegesForRole[role].clear();
    return Status::OK();
}
Exemplo n.º 11
0
Status RoleGraph::removePrivilegeFromRole(const RoleName& role,
                                          const Privilege& privilegeToRemove) {
    if (!roleExists(role)) {
        return Status(ErrorCodes::RoleNotFound,
                      mongoutils::str::stream() << "Role: " << role.getFullName()
                                                << " does not exist",
                      0);
    }
    if (isBuiltinRole(role)) {
        return Status(ErrorCodes::InvalidRoleModification,
                      mongoutils::str::stream() << "Cannot remove privileges from built-in role: "
                                                << role.getFullName());
    }

    PrivilegeVector& currentPrivileges = _directPrivilegesForRole[role];
    for (PrivilegeVector::iterator it = currentPrivileges.begin(); it != currentPrivileges.end();
         ++it) {
        Privilege& curPrivilege = *it;
        if (curPrivilege.getResourcePattern() == privilegeToRemove.getResourcePattern()) {
            ActionSet curActions = curPrivilege.getActions();

            if (!curActions.isSupersetOf(privilegeToRemove.getActions())) {
                // Didn't possess all the actions being removed.
                return Status(
                    ErrorCodes::PrivilegeNotFound,
                    mongoutils::str::stream() << "Role: " << role.getFullName()
                                              << " does not contain a privilege on "
                                              << privilegeToRemove.getResourcePattern().toString()
                                              << " with actions: "
                                              << privilegeToRemove.getActions().toString(),
                    0);
            }

            curPrivilege.removeActions(privilegeToRemove.getActions());
            if (curPrivilege.getActions().empty()) {
                currentPrivileges.erase(it);
            }
            return Status::OK();
        }
    }
    return Status(ErrorCodes::PrivilegeNotFound,
                  mongoutils::str::stream() << "Role: " << role.getFullName()
                                            << " does not "
                                               "contain any privileges on "
                                            << privilegeToRemove.getResourcePattern().toString(),
                  0);
}
Exemplo n.º 12
0
Status RoleGraph::addPrivilegeToRole(const RoleName& role, const Privilege& privilegeToAdd) {
    if (!roleExists(role)) {
        return Status(ErrorCodes::RoleNotFound,
                      mongoutils::str::stream() << "Role: " << role.getFullName()
                                                << " does not exist",
                      0);
    }
    if (isBuiltinRole(role)) {
        return Status(ErrorCodes::InvalidRoleModification,
                      mongoutils::str::stream() << "Cannot grant privileges to built-in role: "
                                                << role.getFullName(),
                      0);
    }

    _addPrivilegeToRoleNoChecks(role, privilegeToAdd);
    return Status::OK();
}
Status checkAuthForDropRoleCommand(Client* client,
                                   const std::string& dbname,
                                   const BSONObj& cmdObj) {
    AuthorizationSession* authzSession = AuthorizationSession::get(client);
    RoleName roleName;
    Status status = auth::parseDropRoleCommand(cmdObj, dbname, &roleName);
    if (!status.isOK()) {
        return status;
    }

    if (!authzSession->isAuthorizedForActionsOnResource(
            ResourcePattern::forDatabaseName(roleName.getDB()), ActionType::dropRole)) {
        return Status(ErrorCodes::Unauthorized,
                      str::stream() << "Not authorized to drop roles from the " << roleName.getDB()
                                    << " database");
    }
    return Status::OK();
}
Exemplo n.º 14
0
Status RoleGraph::createRole(const RoleName& role) {
    if (roleExists(role)) {
        return Status(ErrorCodes::DuplicateKey,
                      mongoutils::str::stream() << "Role: " << role.getFullName()
                                                << " already exists",
                      0);
    }

    _createRoleDontCheckIfRoleExists(role);
    return Status::OK();
}
Exemplo n.º 15
0
// NOTE: Current runtime of this is O(n*m) where n is the size of the current PrivilegeVector
// for the given role, and m is the size of the privilegesToAdd vector.
// If this was a PrivilegeSet (sorted on resource) rather than a PrivilegeVector, we
// could do this in O(n+m) instead.
Status RoleGraph::addPrivilegesToRole(const RoleName& role,
                                      const PrivilegeVector& privilegesToAdd) {
    if (!roleExists(role)) {
        return Status(ErrorCodes::RoleNotFound,
                      mongoutils::str::stream() << "Role: " << role.getFullName()
                                                << " does not exist",
                      0);
    }
    if (isBuiltinRole(role)) {
        return Status(ErrorCodes::InvalidRoleModification,
                      mongoutils::str::stream() << "Cannot grant privileges to built-in role: "
                                                << role.getFullName(),
                      0);
    }

    for (PrivilegeVector::const_iterator it = privilegesToAdd.begin(); it != privilegesToAdd.end();
         ++it) {
        _addPrivilegeToRoleNoChecks(role, *it);
    }
    return Status::OK();
}
    Status AuthzManagerExternalStateMongos::getRoleDescription(const RoleName& roleName,
                                                               bool showPrivileges,
                                                               BSONObj* result) {
        try {
            scoped_ptr<ScopedDbConnection> conn(getConnectionForAuthzCollection(
                    AuthorizationManager::rolesCollectionNamespace));
            BSONObj cmdResult;
            conn->get()->runCommand(
                    "admin",
                    BSON("rolesInfo" <<
                         BSON_ARRAY(BSON(AuthorizationManager::ROLE_NAME_FIELD_NAME <<
                                         roleName.getRole() <<
                                         AuthorizationManager::ROLE_SOURCE_FIELD_NAME <<
                                         roleName.getDB())) <<
                         "showPrivileges" << showPrivileges),
                    cmdResult);
            if (!cmdResult["ok"].trueValue()) {
                int code = cmdResult["code"].numberInt();
                if (code == 0) code = ErrorCodes::UnknownError;
                return Status(ErrorCodes::Error(code), cmdResult["errmsg"].str());
            }

            std::vector<BSONElement> foundRoles = cmdResult["roles"].Array();
            if (foundRoles.size() == 0) {
                return Status(ErrorCodes::RoleNotFound,
                              "Role \"" + roleName.toString() + "\" not found");
            }
            if (foundRoles.size() > 1) {
                return Status(ErrorCodes::RoleDataInconsistent,
                              mongoutils::str::stream() << "Found multiple roles on the \"" <<
                                      roleName.getDB() << "\" database with name \"" <<
                                      roleName.getRole() << "\"");
            }
            *result = foundRoles[0].Obj().getOwned();
            conn->done();
            return Status::OK();
        } catch (const DBException& e) {
            return e.toStatus();
        }
    }
Exemplo n.º 17
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();
    }
Exemplo n.º 18
0
Status RoleGraph::removeRoleFromRole(const RoleName& recipient, const RoleName& role) {
    if (!roleExists(recipient)) {
        return Status(ErrorCodes::RoleNotFound,
                      mongoutils::str::stream() << "Role: " << recipient.getFullName()
                                                << " does not exist",
                      0);
    }
    if (isBuiltinRole(recipient)) {
        return Status(ErrorCodes::InvalidRoleModification,
                      mongoutils::str::stream() << "Cannot remove roles from built-in role: "
                                                << role.getFullName(),
                      0);
    }
    if (!roleExists(role)) {
        return Status(ErrorCodes::RoleNotFound,
                      mongoutils::str::stream() << "Role: " << role.getFullName()
                                                << " does not exist",
                      0);
    }

    std::vector<RoleName>::iterator itToRm =
        std::find(_roleToMembers[role].begin(), _roleToMembers[role].end(), recipient);
    if (itToRm != _roleToMembers[role].end()) {
        _roleToMembers[role].erase(itToRm);
    } else {
        return Status(ErrorCodes::RolesNotRelated,
                      mongoutils::str::stream() << recipient.getFullName() << " is not a member"
                                                                              " of "
                                                << role.getFullName(),
                      0);
    }

    itToRm = std::find(
        _roleToSubordinates[recipient].begin(), _roleToSubordinates[recipient].end(), role);
    fassert(16827, itToRm != _roleToSubordinates[recipient].end());
    _roleToSubordinates[recipient].erase(itToRm);
    return Status::OK();
}
Exemplo n.º 19
0
    bool RoleGraph::isBuiltinRole(const RoleName& role) {
        if (!NamespaceString::validDBName(role.getDB()) || role.getDB() == "$external") {
            return false;
        }

        bool isAdminDB = role.getDB() == ADMIN_DBNAME;

        if (role.getRole() == BUILTIN_ROLE_READ) {
            return true;
        }
        else if (role.getRole() == BUILTIN_ROLE_READ_WRITE) {
            return true;
        }
        else if (role.getRole() == BUILTIN_ROLE_USER_ADMIN) {
            return true;
        }
        else if (role.getRole() == BUILTIN_ROLE_DB_ADMIN) {
            return true;
        }
        else if (role.getRole() == BUILTIN_ROLE_DB_OWNER) {
            return true;
        }
        else if (isAdminDB && role.getRole() == BUILTIN_ROLE_READ_ANY_DB) {
            return true;
        }
        else if (isAdminDB && role.getRole() == BUILTIN_ROLE_READ_WRITE_ANY_DB) {
            return true;
        }
        else if (isAdminDB && role.getRole() == BUILTIN_ROLE_USER_ADMIN_ANY_DB) {
            return true;
        }
        else if (isAdminDB && role.getRole() == BUILTIN_ROLE_DB_ADMIN_ANY_DB) {
            return true;
        }
        else if (isAdminDB && role.getRole() == BUILTIN_ROLE_CLUSTER_MONITOR) {
            return true;
        }
        else if (isAdminDB && role.getRole() == BUILTIN_ROLE_HOST_MANAGEMENT) {
            return true;
        }
        else if (isAdminDB && role.getRole() == BUILTIN_ROLE_CLUSTER_MANAGEMENT) {
            return true;
        }
        else if (isAdminDB && role.getRole() == BUILTIN_ROLE_CLUSTER_ADMIN) {
            return true;
        }
        else if (isAdminDB && role.getRole() == BUILTIN_ROLE_BACKUP) {
            return true;
        }
        else if (isAdminDB && role.getRole() == BUILTIN_ROLE_RESTORE) {
            return true;
        }
        else if (isAdminDB && role.getRole() == BUILTIN_ROLE_ROOT) {
            return true;
        }
        else if (isAdminDB && role.getRole() == BUILTIN_ROLE_INTERNAL) {
            return true;
        }
        return false;
    }
Exemplo n.º 20
0
bool AuthorizationSession::isAuthorizedToRevokeRole(const RoleName& role) {
    return isAuthorizedForActionsOnResource(ResourcePattern::forDatabaseName(role.getDB()),
                                            ActionType::revokeRole);
}
Exemplo n.º 21
0
    bool RoleGraph::isBuiltinRole(const RoleName& role) {
        bool isAdminDB = role.getDB() == ADMIN_DBNAME;

        if (role.getRole() == BUILTIN_ROLE_READ) {
            return true;
        }
        else if (role.getRole() == BUILTIN_ROLE_READ_WRITE) {
            return true;
        }
        else if (role.getRole() == BUILTIN_ROLE_USER_ADMIN) {
            return true;
        }
        else if (role.getRole() == BUILTIN_ROLE_DB_ADMIN) {
            return true;
        }
        else if (role.getRole() == BUILTIN_ROLE_DB_OWNER) {
            return true;
        }
        else if (isAdminDB && role.getRole() == BUILTIN_ROLE_READ_ANY_DB) {
            return true;
        }
        else if (isAdminDB && role.getRole() == BUILTIN_ROLE_READ_WRITE_ANY_DB) {
            return true;
        }
        else if (isAdminDB && role.getRole() == BUILTIN_ROLE_USER_ADMIN_ANY_DB) {
            return true;
        }
        else if (isAdminDB && role.getRole() == BUILTIN_ROLE_DB_ADMIN_ANY_DB) {
            return true;
        }
        else if (isAdminDB && role.getRole() == BUILTIN_ROLE_CLUSTER_MONITOR) {
            return true;
        }
        else if (isAdminDB && role.getRole() == BUILTIN_ROLE_HOST_MANAGEMENT) {
            return true;
        }
        else if (isAdminDB && role.getRole() == BUILTIN_ROLE_CLUSTER_MANAGEMENT) {
            return true;
        }
        else if (isAdminDB && role.getRole() == BUILTIN_ROLE_CLUSTER_ADMIN) {
            return true;
        }
        else if (isAdminDB && role.getRole() == BUILTIN_ROLE_ROOT) {
            return true;
        }
        else if (isAdminDB && role.getRole() == BUILTIN_ROLE_INTERNAL) {
            return true;
        }
        return false;
    }
Exemplo n.º 22
0
    bool RoleGraph::addPrivilegesForBuiltinRole(const RoleName& roleName,
                                                PrivilegeVector* result) {
        const bool isAdminDB = (roleName.getDB() == ADMIN_DBNAME);

        if (roleName.getRole() == BUILTIN_ROLE_READ) {
            addReadOnlyDbPrivileges(result, roleName.getDB());
        }
        else if (roleName.getRole() == BUILTIN_ROLE_READ_WRITE) {
            addReadWriteDbPrivileges(result, roleName.getDB());
        }
        else if (roleName.getRole() == BUILTIN_ROLE_USER_ADMIN) {
            addUserAdminDbPrivileges(result, roleName.getDB());
        }
        else if (roleName.getRole() == BUILTIN_ROLE_DB_ADMIN) {
            addDbAdminDbPrivileges(result, roleName.getDB());
        }
        else if (roleName.getRole() == BUILTIN_ROLE_DB_OWNER) {
            addDbOwnerPrivileges(result, roleName.getDB());
        }
        else if (isAdminDB && roleName.getRole() == BUILTIN_ROLE_READ_ANY_DB) {
            addReadOnlyAnyDbPrivileges(result);
        }
        else if (isAdminDB && roleName.getRole() == BUILTIN_ROLE_READ_WRITE_ANY_DB) {
            addReadWriteAnyDbPrivileges(result);
        }
        else if (isAdminDB && roleName.getRole() == BUILTIN_ROLE_USER_ADMIN_ANY_DB) {
            addUserAdminAnyDbPrivileges(result);
        }
        else if (isAdminDB && roleName.getRole() == BUILTIN_ROLE_DB_ADMIN_ANY_DB) {
            addDbAdminAnyDbPrivileges(result);
        }
        else if (isAdminDB && roleName.getRole() == BUILTIN_ROLE_CLUSTER_MONITOR) {
            addClusterMonitorPrivileges(result);
        }
        else if (isAdminDB && roleName.getRole() == BUILTIN_ROLE_HOST_MANAGEMENT) {
            addHostManagerPrivileges(result);
        }
        else if (isAdminDB && roleName.getRole() == BUILTIN_ROLE_CLUSTER_MANAGEMENT) {
            addClusterManagerPrivileges(result);
        }
        else if (isAdminDB && roleName.getRole() == BUILTIN_ROLE_CLUSTER_ADMIN) {
            addClusterAdminPrivileges(result);
        }
        else if (isAdminDB && roleName.getRole() == BUILTIN_ROLE_ROOT) {
            addRootRolePrivileges(result);
        }
        else if (isAdminDB && roleName.getRole() == BUILTIN_ROLE_INTERNAL) {
            addInternalRolePrivileges(result);
        }
        else {
            return false;
        }
        return true;
    }
Exemplo n.º 23
0
        bool run(const string& dbname,
                 BSONObj& cmdObj,
                 int options,
                 string& errmsg,
                 BSONObjBuilder& result,
                 bool fromRepl) {
            AuthorizationManager* authzManager = getGlobalAuthorizationManager();
            AuthzDocumentsUpdateGuard updateGuard(authzManager);
            if (!updateGuard.tryLock("Grant privileges to role")) {
                addStatus(Status(ErrorCodes::LockBusy, "Could not lock auth data update lock."),
                          result);
                return false;
            }

            RoleName roleName;
            PrivilegeVector privilegesToAdd;
            BSONObj writeConcern;
            Status status = auth::parseAndValidateRolePrivilegeManipulationCommands(
                    cmdObj,
                    "grantPrivilegesToRole",
                    dbname,
                    &roleName,
                    &privilegesToAdd,
                    &writeConcern);
            if (!status.isOK()) {
                addStatus(status, result);
                return false;
            }

            if (!authzManager->roleExists(roleName)) {
                addStatus(Status(ErrorCodes::RoleNotFound,
                                 mongoutils::str::stream() << roleName.getFullName() <<
                                         " does not name an existing role"),
                          result);
                return false;
            }

            if (authzManager->isBuiltinRole(roleName)) {
                addStatus(Status(ErrorCodes::InvalidRoleModification,
                                 mongoutils::str::stream() << roleName.getFullName() <<
                                         " is a built-in role and cannot be modified."),
                          result);
                return false;
            }

            PrivilegeVector privileges = authzManager->getDirectPrivilegesForRole(roleName);
            for (PrivilegeVector::iterator it = privilegesToAdd.begin();
                    it != privilegesToAdd.end(); ++it) {
                Privilege::addPrivilegeToPrivilegeVector(&privileges, *it);
            }

            // Build up update modifier object to $set privileges.
            mutablebson::Document updateObj;
            mutablebson::Element setElement = updateObj.makeElementObject("$set");
            status = updateObj.root().pushBack(setElement);
            if (!status.isOK()) {
                addStatus(status, result);
                return false;
            }
            mutablebson::Element privilegesElement = updateObj.makeElementArray("privileges");
            status = setElement.pushBack(privilegesElement);
            if (!status.isOK()) {
                addStatus(status, result);
                return false;
            }
            status = authzManager->getBSONForPrivileges(privileges, privilegesElement);
            if (!status.isOK()) {
                addStatus(status, result);
                return false;
            }

            BSONObjBuilder updateBSONBuilder;
            updateObj.writeTo(&updateBSONBuilder);
            status = authzManager->updateRoleDocument(
                    roleName,
                    updateBSONBuilder.done(),
                    writeConcern);
            if (!status.isOK()) {
                addStatus(status, result);
                return false;
            }

            return true;
        }
Exemplo n.º 24
0
Status RoleGraph::_recomputePrivilegeDataHelper(const RoleName& startingRole,
                                                unordered_set<RoleName>& visitedRoles) {
    if (visitedRoles.count(startingRole)) {
        return Status::OK();
    }

    std::vector<RoleName> inProgressRoles;
    inProgressRoles.push_back(startingRole);
    while (inProgressRoles.size()) {
        const RoleName currentRole = inProgressRoles.back();
        fassert(17277, !visitedRoles.count(currentRole));

        if (!roleExists(currentRole)) {
            return Status(ErrorCodes::RoleNotFound,
                          mongoutils::str::stream() << "Role: " << currentRole.getFullName()
                                                    << " does not exist",
                          0);
        }

        // Check for cycles
        {
            const std::vector<RoleName>::const_iterator begin = inProgressRoles.begin();
            // The currentRole will always be last so don't look there.
            const std::vector<RoleName>::const_iterator end = --inProgressRoles.end();
            const std::vector<RoleName>::const_iterator firstOccurence =
                std::find(begin, end, currentRole);
            if (firstOccurence != end) {
                std::ostringstream os;
                os << "Cycle in dependency graph: ";
                for (std::vector<RoleName>::const_iterator it = firstOccurence; it != end; ++it) {
                    os << it->getFullName() << " -> ";
                }
                os << currentRole.getFullName();
                return Status(ErrorCodes::GraphContainsCycle, os.str());
            }
        }

        // Make sure we've already visited all subordinate roles before worrying about this one.
        const std::vector<RoleName>& currentRoleDirectRoles = _roleToSubordinates[currentRole];
        std::vector<RoleName>::const_iterator roleIt;
        for (roleIt = currentRoleDirectRoles.begin(); roleIt != currentRoleDirectRoles.end();
             ++roleIt) {
            const RoleName& childRole = *roleIt;
            if (!visitedRoles.count(childRole)) {
                inProgressRoles.push_back(childRole);
                break;
            }
        }
        // If roleIt didn't reach the end of currentRoleDirectRoles that means we found a child
        // of currentRole that we haven't visited yet.
        if (roleIt != currentRoleDirectRoles.end()) {
            continue;
        }
        // At this point, we know that we've already visited all child roles of currentRole
        // and thus their "all privileges" sets are correct and can be added to currentRole's
        // "all privileges" set

        // Need to clear out the "all privileges" vector for the current role, and re-fill it
        // with just the direct privileges for this role.
        PrivilegeVector& currentRoleAllPrivileges = _allPrivilegesForRole[currentRole];
        currentRoleAllPrivileges = _directPrivilegesForRole[currentRole];

        // Need to do the same thing for the indirect roles
        unordered_set<RoleName>& currentRoleIndirectRoles =
            _roleToIndirectSubordinates[currentRole];
        currentRoleIndirectRoles.clear();
        for (std::vector<RoleName>::const_iterator it = currentRoleDirectRoles.begin();
             it != currentRoleDirectRoles.end();
             ++it) {
            currentRoleIndirectRoles.insert(*it);
        }

        // Recursively add children's privileges to current role's "all privileges" vector, and
        // children's roles to current roles's "indirect roles" vector.
        for (std::vector<RoleName>::const_iterator roleIt = currentRoleDirectRoles.begin();
             roleIt != currentRoleDirectRoles.end();
             ++roleIt) {
            // At this point, we already know that the "all privilege" set for the child is
            // correct, so add those privileges to our "all privilege" set.
            const RoleName& childRole = *roleIt;

            const PrivilegeVector& childsPrivileges = _allPrivilegesForRole[childRole];
            for (PrivilegeVector::const_iterator privIt = childsPrivileges.begin();
                 privIt != childsPrivileges.end();
                 ++privIt) {
                Privilege::addPrivilegeToPrivilegeVector(&currentRoleAllPrivileges, *privIt);
            }

            // We also know that the "indirect roles" for the child is also correct, so we can
            // add those roles to our "indirect roles" set.
            const unordered_set<RoleName>& childsRoles = _roleToIndirectSubordinates[childRole];
            for (unordered_set<RoleName>::const_iterator childsRoleIt = childsRoles.begin();
                 childsRoleIt != childsRoles.end();
                 ++childsRoleIt) {
                currentRoleIndirectRoles.insert(*childsRoleIt);
            }
        }

        visitedRoles.insert(currentRole);
        inProgressRoles.pop_back();
    }
    return Status::OK();
}