예제 #1
0
 virtual void addRequiredPrivileges(const std::string& dbname,
                                    const BSONObj& cmdObj,
                                    std::vector<Privilege>* out) {
     ActionSet actions;
     actions.addAction(ActionType::listCollections);
     out->push_back(Privilege(ResourcePattern::forDatabaseName(dbname), actions));
 }
예제 #2
0
Privilege AuthorizationSession::_modifyPrivilegeForSpecialCases(const Privilege& privilege) {
    ActionSet newActions;
    newActions.addAllActionsFromSet(privilege.getActions());
    NamespaceString ns( privilege.getResource() );

    if (ns.coll() == "system.users") {
        if (newActions.contains(ActionType::insert) ||
                newActions.contains(ActionType::update) ||
                newActions.contains(ActionType::remove)) {
            // End users can't modify system.users directly, only the system can.
            newActions.addAction(ActionType::userAdminV1);
        } else {
            newActions.addAction(ActionType::userAdmin);
        }
        newActions.removeAction(ActionType::find);
        newActions.removeAction(ActionType::insert);
        newActions.removeAction(ActionType::update);
        newActions.removeAction(ActionType::remove);
    } else if (ns.coll() == "system.profile") {
        newActions.removeAction(ActionType::find);
        newActions.addAction(ActionType::profileRead);
    } else if (ns.coll() == "system.indexes" && newActions.contains(ActionType::find)) {
        newActions.removeAction(ActionType::find);
        newActions.addAction(ActionType::indexRead);
    }

    return Privilege(privilege.getResource(), newActions);
}
예제 #3
0
    bool AuthorizationManager::checkAuthorization(const std::string& resource,
                                                  ActionSet actions) {
        if (_externalState->shouldIgnoreAuthChecks())
            return true;

        return _acquiredPrivileges.hasPrivilege(Privilege(nsToDatabase(resource), actions));
    }
void AuthorizationSession::addAuthorizedPrincipal(Principal* principal) {

    // Log out any already-logged-in user on the same database as "principal".
    logoutDatabase(principal->getName().getDB().toString());  // See SERVER-8144.

    _authenticatedPrincipals.add(principal);
    if (!principal->isImplicitPrivilegeAcquisitionEnabled())
        return;

    const std::string dbname = principal->getName().getDB().toString();
    if (dbname == StringData("local", StringData::LiteralTag()) &&
            principal->getName().getUser() == internalSecurity.user) {

        // Grant full access to internal user
        ActionSet allActions;
        allActions.addAllActions();
        acquirePrivilege(Privilege(PrivilegeSet::WILDCARD_RESOURCE, allActions),
                         principal->getName());
        return;
    }

    _acquirePrivilegesForPrincipalFromDatabase(ADMIN_DBNAME, principal->getName());
    principal->markDatabaseAsProbed(ADMIN_DBNAME);
    _acquirePrivilegesForPrincipalFromDatabase(dbname, principal->getName());
    principal->markDatabaseAsProbed(dbname);
    _externalState->onAddAuthorizedPrincipal(principal);
}
예제 #5
0
 virtual Status checkAuthForCommand( ClientBasic* client,
                                     const std::string& dbname,
                                     const BSONObj& cmdObj ) {
     return client->getAuthorizationSession()->checkAuthForPrivilege(
         Privilege( AuthorizationManager::CLUSTER_RESOURCE_NAME,
                    ActionType::mergeChunks ) );
 }
 void CmdShutdown::addRequiredPrivileges(const std::string& dbname,
     const BSONObj& cmdObj,
     std::vector<Privilege>* out) {
     ActionSet actions;
     actions.addAction(ActionType::shutdown);
     out->push_back(Privilege(ResourcePattern::forClusterResource(), actions));
 }
예제 #7
0
파일: shard.cpp 프로젝트: ahopedog/mongo
 virtual void addRequiredPrivileges(const std::string& dbname,
                                    const BSONObj& cmdObj,
                                    std::vector<Privilege>* out) {
     ActionSet actions;
     actions.addAction(ActionType::getShardMap);
     out->push_back(Privilege(AuthorizationManager::CLUSTER_RESOURCE_NAME, actions));
 }
예제 #8
0
 virtual void addRequiredPrivileges(const std::string& dbname,
                                    const BSONObj& cmdObj,
                                    std::vector<Privilege>* out) {
     ActionSet actions;
     actions.addAction(ActionType::find);
     out->push_back(Privilege(parseNs(dbname, cmdObj), actions));
 }
void addPrivilegesRequiredForFindAndModify(Command* commandTemplate,
                                           const std::string& dbname,
                                           const BSONObj& cmdObj,
                                           std::vector<Privilege>* out) {
    bool update = cmdObj["update"].trueValue();
    bool upsert = cmdObj["upsert"].trueValue();
    bool remove = cmdObj["remove"].trueValue();

    ActionSet actions;
    actions.addAction(ActionType::find);
    if (update) {
        actions.addAction(ActionType::update);
    }
    if (upsert) {
        actions.addAction(ActionType::insert);
    }
    if (remove) {
        actions.addAction(ActionType::remove);
    }
    ResourcePattern resource(commandTemplate->parseResourcePattern(dbname, cmdObj));
    uassert(17137,
            "Invalid target namespace " + resource.toString(),
            resource.isExactNamespacePattern());
    out->push_back(Privilege(resource, actions));
}
예제 #10
0
 void addRequiredPrivileges(const std::string& dbname,
                            const BSONObj& cmdObj,
                            std::vector<Privilege>* out) const override {
     ActionSet actions;
     actions.addAction(ActionType::convertToCapped);
     out->push_back(Privilege(parseResourcePattern(dbname, cmdObj), actions));
 }
예제 #11
0
    Status AuthorizationManager::_buildPrivilegeSetFromOldStylePrivilegeDocument(
            const std::string& dbname,
            const PrincipalName& principal,
            const BSONObj& privilegeDocument,
            PrivilegeSet* result) {
        if (!(privilegeDocument.hasField(USERNAME_FIELD_NAME) &&
              privilegeDocument.hasField(PASSWORD_FIELD_NAME))) {

            return Status(ErrorCodes::UnsupportedFormat,
                          mongoutils::str::stream() << "Invalid old-style privilege document "
                                  "received when trying to extract privileges: "
                                   << privilegeDocument,
                          0);
        }
        if (privilegeDocument[USERNAME_FIELD_NAME].str() != principal.getUser()) {
            return Status(ErrorCodes::BadValue,
                          mongoutils::str::stream() << "Principal name from privilege document \""
                                  << privilegeDocument[USERNAME_FIELD_NAME].str()
                                  << "\" doesn't match name of provided Principal \""
                                  << principal.getUser()
                                  << "\"",
                          0);
        }

        bool readOnly = privilegeDocument[READONLY_FIELD_NAME].trueValue();
        ActionSet actions = getActionsForOldStyleUser(dbname, readOnly);
        std::string resourceName = (dbname == ADMIN_DBNAME || dbname == LOCAL_DBNAME) ?
            PrivilegeSet::WILDCARD_RESOURCE : dbname;
        result->grantPrivilege(Privilege(resourceName, actions), principal);

        return Status::OK();
    }
예제 #12
0
 virtual void addRequiredPrivileges(const std::string& dbname,
                                    const BSONObj& cmdObj,
                                    std::vector<Privilege>* out) {
     ActionSet actions;
     actions.addAction(ActionType::dropIndex);
     out->push_back(Privilege(parseResourcePattern(dbname, cmdObj), actions));
 }
예제 #13
0
 virtual void addRequiredPrivileges(const std::string& dbname,
                                    const BSONObj& cmdObj,
                                    std::vector<Privilege>* out) {
     ActionSet actions;
     actions.addAction(ActionType::connPoolStats);
     out->push_back(Privilege(ResourcePattern::forClusterResource(), actions));
 }
예제 #14
0
Status Pipeline::checkAuthForCommand(ClientBasic* client,
                                     const std::string& db,
                                     const BSONObj& cmdObj) {
    NamespaceString inputNs(db, cmdObj.firstElement().str());
    auto inputResource = ResourcePattern::forExactNamespace(inputNs);
    uassert(17138,
            mongoutils::str::stream() << "Invalid input namespace, " << inputNs.ns(),
            inputNs.isValid());

    std::vector<Privilege> privileges;

    if (cmdObj.getFieldDotted("pipeline.0.$indexStats")) {
        Privilege::addPrivilegeToPrivilegeVector(
            &privileges,
            Privilege(ResourcePattern::forAnyNormalResource(), ActionType::indexStats));
    } else {
        // If no source requiring an alternative permission scheme is specified then default to
        // requiring find() privileges on the given namespace.
        Privilege::addPrivilegeToPrivilegeVector(&privileges,
                                                 Privilege(inputResource, ActionType::find));
    }

    BSONObj pipeline = cmdObj.getObjectField("pipeline");
    BSONForEach(stageElem, pipeline) {
        BSONObj stage = stageElem.embeddedObjectUserCheck();
        StringData stageName = stage.firstElementFieldName();
        if (stageName == "$out" && stage.firstElementType() == String) {
            NamespaceString outputNs(db, stage.firstElement().str());
            uassert(17139,
                    mongoutils::str::stream() << "Invalid $out target namespace, " << outputNs.ns(),
                    outputNs.isValid());

            ActionSet actions;
            actions.addAction(ActionType::remove);
            actions.addAction(ActionType::insert);
            if (shouldBypassDocumentValidationForCommand(cmdObj)) {
                actions.addAction(ActionType::bypassDocumentValidation);
            }
            Privilege::addPrivilegeToPrivilegeVector(
                &privileges, Privilege(ResourcePattern::forExactNamespace(outputNs), actions));
        } else if (stageName == "$lookup" && stage.firstElementType() == Object) {
            NamespaceString fromNs(db, stage.firstElement()["from"].str());
            Privilege::addPrivilegeToPrivilegeVector(
                &privileges,
                Privilege(ResourcePattern::forExactNamespace(fromNs), ActionType::find));
        }
    }
예제 #15
0
    /**
     * Adds to "outPrivileges" the privileges associated with having the named "role" on "dbname".
     *
     * Returns non-OK status if "role" is not a defined role in "dbname".
     */
    static Status _addPrivilegesForSystemRole(const std::string& dbname,
                                              const std::string& role,
                                              std::vector<Privilege>* outPrivileges) {
        const bool isAdminDB = (dbname == ADMIN_DBNAME);

        if (role == SYSTEM_ROLE_READ) {
            outPrivileges->push_back(Privilege(dbname, readRoleActions));
        }
        else if (role == SYSTEM_ROLE_READ_WRITE) {
            outPrivileges->push_back(Privilege(dbname, readWriteRoleActions));
        }
        else if (role == SYSTEM_ROLE_USER_ADMIN) {
            outPrivileges->push_back(Privilege(dbname, userAdminRoleActions));
        }
        else if (role == SYSTEM_ROLE_DB_ADMIN) {
            outPrivileges->push_back(Privilege(dbname, dbAdminRoleActions));
        }
        else if (isAdminDB && role == SYSTEM_ROLE_READ_ANY_DB) {
            outPrivileges->push_back(Privilege(PrivilegeSet::WILDCARD_RESOURCE, readRoleActions));
        }
        else if (isAdminDB && role == SYSTEM_ROLE_READ_WRITE_ANY_DB) {
            outPrivileges->push_back(
                    Privilege(PrivilegeSet::WILDCARD_RESOURCE, readWriteRoleActions));
        }
        else if (isAdminDB && role == SYSTEM_ROLE_USER_ADMIN_ANY_DB) {
            outPrivileges->push_back(
                    Privilege(PrivilegeSet::WILDCARD_RESOURCE, userAdminRoleActions));
        }
        else if (isAdminDB && role == SYSTEM_ROLE_DB_ADMIN_ANY_DB) {
            outPrivileges->push_back(
                    Privilege(PrivilegeSet::WILDCARD_RESOURCE, dbAdminRoleActions));
        }
        else if (isAdminDB && role == SYSTEM_ROLE_SERVER_ADMIN) {
            outPrivileges->push_back(
                    Privilege(PrivilegeSet::WILDCARD_RESOURCE, serverAdminRoleActions));
        }
        else if (isAdminDB && role == SYSTEM_ROLE_CLUSTER_ADMIN) {
            outPrivileges->push_back(
                    Privilege(PrivilegeSet::WILDCARD_RESOURCE, clusterAdminRoleActions));
        }
        else {
            return Status(ErrorCodes::BadValue,
                          mongoutils::str::stream() <<"No such role, " << role <<
                          ", in database " << dbname);
        }
        return Status::OK();
    }
예제 #16
0
 virtual void addRequiredPrivileges(const std::string& dbname,
                                    const BSONObj& cmdObj,
                                    std::vector<Privilege>* out) {
     // TODO: update this with the new rules around user creation in 2.6.
     ActionSet actions;
     actions.addAction(ActionType::userAdmin);
     out->push_back(Privilege(dbname, actions));
 }
예제 #17
0
    void AuthorizationSession::grantInternalAuthorization(const UserName& userName) {
        Principal* principal = new Principal(userName);
        ActionSet actions;
        actions.addAllActions();

        addAuthorizedPrincipal(principal);
        fassert(16581, acquirePrivilege(Privilege(PrivilegeSet::WILDCARD_RESOURCE, actions),
                                    principal->getName()).isOK());
    }
예제 #18
0
 void AuthorizationManager::grantInternalAuthorization() {
     Principal* internalPrincipal = new Principal("__system");
     _authenticatedPrincipals.add(internalPrincipal);
     ActionSet allActions;
     allActions.addAllActions();
     AcquiredPrivilege privilege(Privilege("*", allActions), internalPrincipal);
     Status status = acquirePrivilege(privilege);
     verify (status == Status::OK());
 }
예제 #19
0
    void AuthorizationManager::grantInternalAuthorization(const std::string& principalName) {
        Principal* principal = new Principal(PrincipalName(principalName, "local"));
        ActionSet actions;
        actions.addAllActions();

        addAuthorizedPrincipal(principal);
        fassert(16581, acquirePrivilege(Privilege(PrivilegeSet::WILDCARD_RESOURCE, actions),
                                    principal->getName()).isOK());
    }
예제 #20
0
        virtual void addRequiredPrivileges(const std::string& dbname,
                                           const BSONObj& cmdObj,
                                           std::vector<Privilege>* out) {
            ActionSet sourceActions;
            sourceActions.addAction(ActionType::find);
            out->push_back(Privilege(parseResourcePattern(dbname, cmdObj), sourceActions));

            ActionSet targetActions;
            targetActions.addAction(ActionType::insert);
            targetActions.addAction(ActionType::createIndex);
            targetActions.addAction(ActionType::convertToCapped);
            std::string collection = cmdObj.getStringField("toCollection");
            uassert(16708, "bad 'toCollection' value", !collection.empty());

            out->push_back(Privilege(ResourcePattern::forExactNamespace(
                                             NamespaceString(dbname, collection)),
                                     targetActions));
        }
예제 #21
0
    void Pipeline::addRequiredPrivileges(Command* commandTemplate,
                                         const string& db,
                                         BSONObj cmdObj,
                                         vector<Privilege>* out) {
        ResourcePattern inputResource(commandTemplate->parseResourcePattern(db, cmdObj));
        uassert(17138,
                mongoutils::str::stream() << "Invalid input resource, " << inputResource.toString(),
                inputResource.isExactNamespacePattern());

        if (false && cmdObj["allowDiskUsage"].trueValue()) {
            // TODO no privilege for this yet.
        }

        out->push_back(Privilege(inputResource, ActionType::find));

        BSONObj pipeline = cmdObj.getObjectField("pipeline");
        BSONForEach(stageElem, pipeline) {
            BSONObj stage = stageElem.embeddedObjectUserCheck();
            if (str::equals(stage.firstElementFieldName(), "$out")) {
                // TODO Figure out how to handle temp collection privileges. For now, using the
                // output ns is ok since we only do db-level privilege checks.
                NamespaceString outputNs(db, stage.firstElement().str());
                uassert(17139,
                        mongoutils::str::stream() << "Invalid $out target namespace, " <<
                        outputNs.ns(),
                        outputNs.isValid());

                ActionSet actions;
                // logically on output ns
                actions.addAction(ActionType::remove);
                actions.addAction(ActionType::insert);

                // on temp ns due to implementation, but not logically on output ns
                actions.addAction(ActionType::createCollection);
                actions.addAction(ActionType::createIndex);
                actions.addAction(ActionType::dropCollection);
                actions.addAction(ActionType::renameCollectionSameDB);

                out->push_back(Privilege(ResourcePattern::forExactNamespace(outputNs), actions));
                out->push_back(Privilege(ResourcePattern::forExactNamespace(
                                                 NamespaceString(db, "system.indexes")),
                                         ActionType::find));
            }
        }
 Status checkAuthForOperation(OperationContext* opCtx,
                              const std::string& dbname,
                              const BSONObj& cmdObj) const override {
     // Must be authenticated as an internal cluster member.
     auto authSession = AuthorizationSession::get(opCtx->getClient());
     if (!authSession->isAuthorizedForPrivilege(
             Privilege(ResourcePattern::forClusterResource(), ActionType::impersonate))) {
         return {ErrorCodes::Unauthorized, "unauthorized"};
     }
     return Status::OK();
 }
        virtual void addRequiredPrivileges(const std::string& dbname,
                                           const BSONObj& cmdObj,
                                           std::vector<Privilege>* out) {
            ActionSet actions;
            actions.addAction(ActionType::logApplicationMessage);

            // TODO: Investigate if using the 'normal resource'
            // pattern of the new ResourcePattern API matches our
            // original use of SERVER_RESOURCE_NAME. We may want
            // to use somethine scoped to the given database name.
            out->push_back(Privilege(ResourcePattern::forAnyNormalResource(), actions));
        }
예제 #24
0
Status checkAuthForWriteCommand(AuthorizationSession* authzSession,
                                BatchedCommandRequest::BatchType cmdType,
                                const OpMsgRequest& request) {
    std::vector<Privilege> privileges;
    ActionSet actionsOnCommandNSS;

    if (shouldBypassDocumentValidationForCommand(request.body)) {
        actionsOnCommandNSS.addAction(ActionType::bypassDocumentValidation);
    }

    NamespaceString cmdNSS;
    if (cmdType == BatchedCommandRequest::BatchType_Insert) {
        auto op = Insert::parse(IDLParserErrorContext("insert"), request);
        cmdNSS = op.getNamespace();
        if (!op.getNamespace().isSystemDotIndexes()) {
            actionsOnCommandNSS.addAction(ActionType::insert);
        } else {
            // Special-case indexes until we have a command
            const auto swNssToIndex = getIndexedNss(op.getDocuments());
            if (!swNssToIndex.isOK()) {
                return swNssToIndex.getStatus();
            }

            const auto& nssToIndex = swNssToIndex.getValue();
            privileges.push_back(
                Privilege(ResourcePattern::forExactNamespace(nssToIndex), ActionType::createIndex));
        }
    } else if (cmdType == BatchedCommandRequest::BatchType_Update) {
        auto op = Update::parse(IDLParserErrorContext("update"), request);
        cmdNSS = op.getNamespace();
        actionsOnCommandNSS.addAction(ActionType::update);

        // Upsert also requires insert privs
        if (containsUpserts(op.getUpdates())) {
            actionsOnCommandNSS.addAction(ActionType::insert);
        }
    } else {
        fassert(17251, cmdType == BatchedCommandRequest::BatchType_Delete);
        auto op = Delete::parse(IDLParserErrorContext("delete"), request);
        cmdNSS = op.getNamespace();
        actionsOnCommandNSS.addAction(ActionType::remove);
    }

    if (!actionsOnCommandNSS.empty()) {
        privileges.emplace_back(ResourcePattern::forExactNamespace(cmdNSS), actionsOnCommandNSS);
    }

    if (authzSession->isAuthorizedForPrivileges(privileges))
        return Status::OK();

    return Status(ErrorCodes::Unauthorized, "unauthorized");
}
예제 #25
0
    Status AuthorizationManager::_buildPrivilegeSetFromOldStylePrivilegeDocument(
            const std::string& dbname,
            Principal* principal,
            const BSONObj& privilegeDocument,
            PrivilegeSet* result) {
        if (!(privilegeDocument.hasField("user") && privilegeDocument.hasField("pwd"))) {
            return Status(ErrorCodes::UnsupportedFormat,
                          mongoutils::str::stream() << "Invalid old-style privilege document "
                                  "received when trying to extract privileges: "
                                   << privilegeDocument,
                          0);
        }

        bool readOnly = false;
        ActionSet actions;
        if (privilegeDocument.hasField("readOnly") && privilegeDocument["readOnly"].trueValue()) {
            actions.addAllActionsFromSet(readRoleActions);
            readOnly = true;
        }
        else {
            actions.addAllActionsFromSet(readWriteRoleActions);
            actions.addAllActionsFromSet(dbAdminRoleActions);
            actions.addAllActionsFromSet(userAdminRoleActions);
        }

        if (dbname == "admin" || dbname == "local") {
            // Make all basic actions available on all databases
            result->grantPrivilege(AcquiredPrivilege(Privilege("*", actions), principal));
            // Make server and cluster admin actions available on admin database.
            if (!readOnly) {
                actions.addAllActionsFromSet(serverAdminRoleActions);
                actions.addAllActionsFromSet(clusterAdminRoleActions);
            }
        }

        result->grantPrivilege(AcquiredPrivilege(Privilege(dbname, actions), principal));

        return Status::OK();
    }
예제 #26
0
    void addPrivilegesRequiredForRenameCollection(const BSONObj& cmdObj,
                                                  std::vector<Privilege>* out) {
        NamespaceString sourceNS = NamespaceString(cmdObj.getStringField("renameCollection"));
        NamespaceString targetNS = NamespaceString(cmdObj.getStringField("to"));
        uassert(17140, "Invalid source namespace " + sourceNS.ns(), sourceNS.isValid());
        uassert(17141, "Invalid target namespace " + targetNS.ns(), targetNS.isValid());
        ActionSet sourceActions;
        ActionSet targetActions;

        if (sourceNS.db() == targetNS.db()) {
            sourceActions.addAction(ActionType::renameCollectionSameDB);
            targetActions.addAction(ActionType::renameCollectionSameDB);
        } else {
            sourceActions.addAction(ActionType::cloneCollectionLocalSource);
            sourceActions.addAction(ActionType::dropCollection);
            targetActions.addAction(ActionType::createCollection);
            targetActions.addAction(ActionType::cloneCollectionTarget);
            targetActions.addAction(ActionType::createIndex);
        }

        out->push_back(Privilege(ResourcePattern::forExactNamespace(sourceNS), sourceActions));
        out->push_back(Privilege(ResourcePattern::forExactNamespace(targetNS), targetActions));
    }
예제 #27
0
 virtual void addRequiredPrivileges(const std::string &dbname,
                                    const BSONObj &cmdObj,
                                    std::vector<Privilege> *out) {
     ActionSet actions;
     actions.addAction(ActionType::transactionCommands);
     if (cmdObj["isolation"].valuestringdatasafe() == "serializable") {
         actions.addAction(ActionType::beginSerializableTransaction);
     }
     // This doesn't really need to be specific to this dbname, but it ensures that you are
     // authed as someone and aren't just anonymous.  This means that if you're running with
     // auth, you need to issue transaction commands against a db that you have privileges
     // on, which doesn't seem like that big of a requirement.
     out->push_back(Privilege(dbname, actions));
 }
예제 #28
0
        void addPrivilegesRequiredForMapReduce(Command* commandTemplate,
                                               const std::string& dbname,
                                               const BSONObj& cmdObj,
                                               std::vector<Privilege>* out) {
            Config::OutputOptions outputOptions = Config::parseOutputOptions(dbname, cmdObj);

            ResourcePattern inputResource(commandTemplate->parseResourcePattern(dbname, cmdObj));
            uassert(17142, mongoutils::str::stream() <<
                    "Invalid input resource " << inputResource.toString(),
                    inputResource.isExactNamespacePattern());
            out->push_back(Privilege(inputResource, ActionType::find));

            if (outputOptions.outType != Config::INMEMORY) {
                ActionSet outputActions;
                outputActions.addAction(ActionType::insert);
                if (outputOptions.outType == Config::REPLACE) {
                    outputActions.addAction(ActionType::remove);
                }
                else {
                    outputActions.addAction(ActionType::update);
                }

                if (shouldBypassDocumentValidationforCommand(cmdObj)) {
                    outputActions.addAction(ActionType::bypassDocumentValidation);
                }

                ResourcePattern outputResource(
                        ResourcePattern::forExactNamespace(
                                NamespaceString(outputOptions.finalNamespace)));
                uassert(17143, mongoutils::str::stream() << "Invalid target namespace " <<
                        outputResource.ns().ns(),
                        outputResource.ns().isValid());

                // TODO: check if outputNs exists and add createCollection privilege if not
                out->push_back(Privilege(outputResource, outputActions));
            }
        }
예제 #29
0
        void addPrivilegesRequiredForMapReduce(const std::string& dbname,
                                               const BSONObj& cmdObj,
                                               std::vector<Privilege>* out) {
            Config::OutputOptions outputOptions = Config::parseOutputOptions(dbname, cmdObj);
            ActionSet inputActions, outputActions;

            inputActions.addAction(ActionType::find);
            std::string inputNs = dbname + '.' + cmdObj.firstElement().valuestr();
            out->push_back(Privilege(inputNs, inputActions));

            if (outputOptions.outType != Config::INMEMORY) {
                outputActions.addAction(ActionType::insert);
                if (outputOptions.outType == Config::REPLACE) {
                    outputActions.addAction(ActionType::remove);
                }
                else {
                    outputActions.addAction(ActionType::update);
                }

                std::string outputNs = outputOptions.finalNamespace;
                // TODO: check if outputNs exists and add createCollection privilege if not
                out->push_back(Privilege(outputNs, outputActions));
            }
        }
ImpersonationSessionGuard::ImpersonationSessionGuard(OperationContext* opCtx) : _opCtx(opCtx) {
    auto authSession = AuthorizationSession::get(_opCtx->getClient());
    const auto impersonatedUsersAndRoles = rpc::getImpersonatedUserMetadata(opCtx);
    if (impersonatedUsersAndRoles) {
        uassert(ErrorCodes::Unauthorized,
                "Unauthorized use of impersonation metadata.",
                authSession->isAuthorizedForPrivilege(
                    Privilege(ResourcePattern::forClusterResource(), ActionType::impersonate)));
        fassert(ErrorCodes::InternalError, !authSession->isImpersonating());
        authSession->setImpersonatedUserData(impersonatedUsersAndRoles->getUsers(),
                                             impersonatedUsersAndRoles->getRoles());
        _active = true;
        return;
    }
}