Ejemplo n.º 1
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")) {
                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);
                out->push_back(Privilege(ResourcePattern::forExactNamespace(outputNs), actions));
            }
        }
Ejemplo n.º 2
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));
 }
Ejemplo n.º 3
0
        virtual Status checkAuthForCommand(ClientBasic* client,
                                           const std::string& dbname,
                                           const BSONObj& cmdObj) {
            ActionSet actions;
            actions.addAction(ActionType::insert);
            actions.addAction(ActionType::createIndex);
            if (shouldBypassDocumentValidationforCommand(cmdObj)) {
                actions.addAction(ActionType::bypassDocumentValidation);
            }

            if (!AuthorizationSession::get(client)->isAuthorizedForActionsOnResource(
                    ResourcePattern::forDatabaseName(dbname), actions)) {
                return Status(ErrorCodes::Unauthorized, "Unauthorized");
            }
            return Status::OK();
        }
Ejemplo n.º 4
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));
        }
    }
Status checkAuthForWriteCommand(AuthorizationSession* authzSession,
                                BatchedCommandRequest::BatchType cmdType,
                                const NamespaceString& cmdNSS,
                                const BSONObj& cmdObj) {
    vector<Privilege> privileges;
    ActionSet actionsOnCommandNSS;

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

    if (cmdType == BatchedCommandRequest::BatchType_Insert) {
        if (!cmdNSS.isSystemDotIndexes()) {
            actionsOnCommandNSS.addAction(ActionType::insert);
        } else {
            // Special-case indexes until we have a command
            string nsToIndex, errMsg;
            if (!BatchedCommandRequest::getIndexedNS(cmdObj, &nsToIndex, &errMsg)) {
                return Status(ErrorCodes::FailedToParse, errMsg);
            }

            NamespaceString nssToIndex(nsToIndex);
            privileges.push_back(
                Privilege(ResourcePattern::forExactNamespace(nssToIndex), ActionType::createIndex));
        }
    } else if (cmdType == BatchedCommandRequest::BatchType_Update) {
        actionsOnCommandNSS.addAction(ActionType::update);

        // Upsert also requires insert privs
        if (BatchedCommandRequest::containsUpserts(cmdObj)) {
            actionsOnCommandNSS.addAction(ActionType::insert);
        }
    } else {
        fassert(17251, cmdType == BatchedCommandRequest::BatchType_Delete);
        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");
}
Ejemplo n.º 6
0
    Privilege AuthorizationManager::_modifyPrivilegeForSpecialCases(const Privilege& privilege) {
        ActionSet newActions;
        newActions.addAllActionsFromSet(privilege.getActions());
        std::string collectionName = NamespaceString(privilege.getResource()).coll;
        if (collectionName == "system.users") {
            newActions.removeAction(ActionType::find);
            newActions.removeAction(ActionType::insert);
            newActions.removeAction(ActionType::update);
            newActions.removeAction(ActionType::remove);
            newActions.addAction(ActionType::userAdmin);
        } else if (collectionName == "system.profle" && newActions.contains(ActionType::find)) {
            newActions.removeAction(ActionType::find);
            newActions.addAction(ActionType::profileRead);
        }

        return Privilege(privilege.getResource(), newActions);
    }
Ejemplo n.º 7
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));
 }
    Status checkAuthForRenameCollectionCommand(ClientBasic* client,
                                               const std::string& dbname,
                                               const BSONObj& cmdObj) {
        NamespaceString sourceNS = NamespaceString(cmdObj.getStringField("renameCollection"));
        NamespaceString targetNS = NamespaceString(cmdObj.getStringField("to"));
        bool dropTarget = cmdObj["dropTarget"].trueValue();

        if (sourceNS.db() == targetNS.db() && !sourceNS.isSystem() && !targetNS.isSystem()) {
            bool authed1 = client->getAuthorizationSession()->isAuthorizedForActionsOnResource(
                    ResourcePattern::forDatabaseName(sourceNS.db()),
                    ActionType::renameCollectionSameDB);

            bool authed2 = true;
            if (dropTarget) {
                authed2 = client->getAuthorizationSession()->isAuthorizedForActionsOnResource(
                        ResourcePattern::forExactNamespace(targetNS), ActionType::dropCollection);
            }

            if (authed1 && authed2) {
                return Status::OK();
            }
        }

        // Check privileges on source collection
        ActionSet actions;
        actions.addAction(ActionType::find);
        actions.addAction(ActionType::dropCollection);
        if (!client->getAuthorizationSession()->isAuthorizedForActionsOnResource(
                ResourcePattern::forExactNamespace(sourceNS), actions)) {
            return Status(ErrorCodes::Unauthorized, "Unauthorized");
        }

        // Check privileges on dest collection
        actions.removeAllActions();
        actions.addAction(ActionType::insert);
        actions.addAction(ActionType::createIndex);
        if (dropTarget) {
            actions.addAction(ActionType::dropCollection);
        }
        if (!client->getAuthorizationSession()->isAuthorizedForActionsOnResource(
                ResourcePattern::forExactNamespace(targetNS), actions)) {
            return Status(ErrorCodes::Unauthorized, "Unauthorized");
        }

        return Status::OK();
    }
Ejemplo n.º 9
0
    void Pipeline::addRequiredPrivileges(const string& db,
                                         BSONObj cmdObj,
                                         vector<Privilege>* out) {
        ActionSet actions;
        actions.addAction(ActionType::find);
        out->push_back(Privilege(db + '.' + cmdObj.firstElement().str(), actions));

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

        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.
                const string outputNs = db + '.' + stage.firstElement().str();

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

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

                out->push_back(Privilege(outputNs, actions));
            }
        }
Ejemplo n.º 10
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));
        }
Ejemplo n.º 11
0
    virtual Status checkAuthForCommand(ClientBasic* client,
                                       const std::string& dbname,
                                       const BSONObj& cmdObj) {
        std::string ns = parseNs(dbname, cmdObj);

        ActionSet actions;
        actions.addAction(ActionType::insert);
        actions.addAction(ActionType::createIndex);  // SERVER-11418
        if (shouldBypassDocumentValidationForCommand(cmdObj)) {
            actions.addAction(ActionType::bypassDocumentValidation);
        }

        if (!AuthorizationSession::get(client)->isAuthorizedForActionsOnResource(
                ResourcePattern::forExactNamespace(NamespaceString(ns)), actions)) {
            return Status(ErrorCodes::Unauthorized, "Unauthorized");
        }
        return Status::OK();
    }
Ejemplo n.º 12
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));
            }
        }
Ejemplo n.º 13
0
 virtual Status checkAuthForCommand(ClientBasic* client,
                                    const std::string& dbname,
                                    const BSONObj& cmdObj) {
     ActionSet actions;
     actions.addAction(ActionType::createIndex);
     Privilege p(parseResourcePattern(dbname, cmdObj), actions);
     if ( client->getAuthorizationSession()->isAuthorizedForPrivilege(p) )
         return Status::OK();
     return Status(ErrorCodes::Unauthorized, "Unauthorized");
 }
Ejemplo n.º 14
0
 // TODO: remove this default implementation so that all Command subclasses have to explicitly
 // declare their own.
 void Command::addRequiredPrivileges(const std::string& dbname,
                                     const BSONObj& cmdObj,
                                     std::vector<Privilege>* out) {
     if (!requiresAuth()) {
         return;
     }
     ActionSet actions;
     actions.addAction(locktype() == WRITE ? ActionType::oldWrite : ActionType::oldRead);
     Privilege privilege(adminOnly() ? "admin" : dbname, actions);
     out->push_back(privilege);
 }
Ejemplo n.º 15
0
    Privilege AuthorizationSession::_modifyPrivilegeForSpecialCases(const Privilege& privilege) {
        ActionSet newActions;
        newActions.addAllActionsFromSet(privilege.getActions());
        NamespaceString ns( privilege.getResource() );

        if (ns.coll() == "system.users") {
            newActions.removeAction(ActionType::find);
            newActions.removeAction(ActionType::insert);
            newActions.removeAction(ActionType::update);
            newActions.removeAction(ActionType::remove);
            newActions.addAction(ActionType::userAdmin);
        } 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);
    }
        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));
        }
Status checkAuthForMergeAuthzCollectionsCommand(Client* client, const BSONObj& cmdObj) {
    auth::MergeAuthzCollectionsArgs args;
    Status status = auth::parseMergeAuthzCollectionsCommand(cmdObj, &args);
    if (!status.isOK()) {
        return status;
    }

    AuthorizationSession* authzSession = AuthorizationSession::get(client);
    ActionSet actions;
    actions.addAction(ActionType::createUser);
    actions.addAction(ActionType::createRole);
    actions.addAction(ActionType::grantRole);
    actions.addAction(ActionType::revokeRole);
    if (args.drop) {
        actions.addAction(ActionType::dropUser);
        actions.addAction(ActionType::dropRole);
    }
    if (!authzSession->isAuthorizedForActionsOnResource(ResourcePattern::forAnyNormalResource(),
                                                        actions)) {
        return Status(ErrorCodes::Unauthorized,
                      "Not authorized to update user/role data using _mergeAuthzCollections"
                      " command");
    }
    if (!args.usersCollName.empty() &&
        !authzSession->isAuthorizedForActionsOnResource(
            ResourcePattern::forExactNamespace(NamespaceString(args.usersCollName)),
            ActionType::find)) {
        return Status(ErrorCodes::Unauthorized,
                      str::stream() << "Not authorized to read " << args.usersCollName);
    }
    if (!args.rolesCollName.empty() &&
        !authzSession->isAuthorizedForActionsOnResource(
            ResourcePattern::forExactNamespace(NamespaceString(args.rolesCollName)),
            ActionType::find)) {
        return Status(ErrorCodes::Unauthorized,
                      str::stream() << "Not authorized to read " << args.rolesCollName);
    }
    return Status::OK();
}
Ejemplo n.º 18
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);

        const auto nssElt = cmdObj["toCollection"];
        uassert(ErrorCodes::TypeMismatch,
                "'toCollection' must be of type String",
                nssElt.type() == BSONType::String);
        const NamespaceString nss(dbname, nssElt.valueStringData());
        uassert(ErrorCodes::InvalidNamespace,
                str::stream() << "Invalid target namespace: " << nss.ns(),
                nss.isValid());

        out->push_back(Privilege(ResourcePattern::forExactNamespace(nss), targetActions));
    }
Ejemplo n.º 19
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));
            }
        }
Ejemplo n.º 20
0
 Status ActionSet::parseActionSetFromString(const std::string& actionsString,
                                            ActionSet* result) {
     std::vector<std::string> actionsList;
     splitStringDelim(actionsString, &actionsList, ',');
     ActionSet actions;
     for (size_t i = 0; i < actionsList.size(); i++) {
         ActionType action;
         Status status = ActionType::parseActionFromString(actionsList[i], &action);
         if (status != Status::OK()) {
             ActionSet empty;
             *result = empty;
             return status;
         }
         actions.addAction(action);
     }
     *result = actions;
     return Status::OK();
 }
Ejemplo n.º 21
0
Status AuthorizationSession::checkAuthForUpdate(const NamespaceString& ns,
                                                const BSONObj& query,
                                                const BSONObj& update,
                                                bool upsert) {
    if (!upsert) {
        if (!isAuthorizedForActionsOnNamespace(ns, ActionType::update)) {
            return Status(ErrorCodes::Unauthorized,
                          str::stream() << "not authorized for update on " << ns.ns());
        }
    } else {
        ActionSet required;
        required.addAction(ActionType::update);
        required.addAction(ActionType::insert);
        if (!isAuthorizedForActionsOnNamespace(ns, required)) {
            return Status(ErrorCodes::Unauthorized,
                          str::stream() << "not authorized for upsert on " << ns.ns());
        }
    }
    return Status::OK();
}
Ejemplo n.º 22
0
 Status ActionSet::parseActionSetFromStringVector(const std::vector<std::string>& actionsVector,
                                                  ActionSet* result) {
     ActionSet actions;
     for (size_t i = 0; i < actionsVector.size(); i++) {
         ActionType action;
         Status status = ActionType::parseActionFromString(actionsVector[i], &action);
         if (status != Status::OK()) {
             ActionSet empty;
             *result = empty;
             return status;
         }
         if (action == ActionType::anyAction) {
             actions.addAllActions();
             break;
         }
         actions.addAction(action);
     }
     *result = actions;
     return Status::OK();
 }
Ejemplo n.º 23
0
 Status AuthorizationManager::checkAuthForUpdate(const std::string& ns, bool upsert) {
     NamespaceString namespaceString(ns);
     if (!upsert) {
         if (!checkAuthorization(ns, ActionType::update)) {
             return Status(ErrorCodes::Unauthorized,
                           mongoutils::str::stream() << "not authorized for update on " << ns,
                           0);
         }
     }
     else {
         ActionSet required;
         required.addAction(ActionType::update);
         required.addAction(ActionType::insert);
         if (!checkAuthorization(ns, required)) {
             return Status(ErrorCodes::Unauthorized,
                           mongoutils::str::stream() << "not authorized for upsert on " << ns,
                           0);
         }
     }
     return Status::OK();
 }
Ejemplo n.º 24
0
PrivilegeVector AuthorizationSession::getDefaultPrivileges() {
    PrivilegeVector defaultPrivileges;

    // If localhost exception is active (and no users exist),
    // return a vector of the minimum privileges required to bootstrap
    // a system and add the first user.
    if (_externalState->shouldAllowLocalhost()) {
        ResourcePattern adminDBResource = ResourcePattern::forDatabaseName(ADMIN_DBNAME);
        ActionSet setupAdminUserActionSet;
        setupAdminUserActionSet.addAction(ActionType::createUser);
        setupAdminUserActionSet.addAction(ActionType::grantRole);
        Privilege setupAdminUserPrivilege = Privilege(adminDBResource, setupAdminUserActionSet);

        ResourcePattern externalDBResource = ResourcePattern::forDatabaseName("$external");
        Privilege setupExternalUserPrivilege =
            Privilege(externalDBResource, ActionType::createUser);

        ActionSet setupServerConfigActionSet;

        // If this server is an arbiter, add specific privileges meant to circumvent
        // the behavior of an arbiter in an authenticated replset. See SERVER-5479.
        if (_externalState->serverIsArbiter()) {
            setupServerConfigActionSet.addAction(ActionType::getCmdLineOpts);
            setupServerConfigActionSet.addAction(ActionType::getParameter);
            setupServerConfigActionSet.addAction(ActionType::serverStatus);
            setupServerConfigActionSet.addAction(ActionType::shutdown);
        }

        setupServerConfigActionSet.addAction(ActionType::addShard);
        setupServerConfigActionSet.addAction(ActionType::replSetConfigure);
        setupServerConfigActionSet.addAction(ActionType::replSetGetStatus);
        Privilege setupServerConfigPrivilege =
            Privilege(ResourcePattern::forClusterResource(), setupServerConfigActionSet);

        Privilege::addPrivilegeToPrivilegeVector(&defaultPrivileges, setupAdminUserPrivilege);
        Privilege::addPrivilegeToPrivilegeVector(&defaultPrivileges, setupExternalUserPrivilege);
        Privilege::addPrivilegeToPrivilegeVector(&defaultPrivileges, setupServerConfigPrivilege);
        return defaultPrivileges;
    }

    return defaultPrivileges;
}
Ejemplo n.º 25
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));
    }