Exemplo n.º 1
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);
    }
Exemplo n.º 2
0
 void User::addPrivilege(const Privilege& privilegeToAdd) {
     ResourcePrivilegeMap::iterator it = _privileges.find(privilegeToAdd.getResource());
     if (it == _privileges.end()) {
         // No privilege exists yet for this resource
         _privileges.insert(std::make_pair(privilegeToAdd.getResource(), privilegeToAdd));
     } else {
         dassert(it->first == privilegeToAdd.getResource());
         it->second.addActions(privilegeToAdd.getActions());
     }
 }
Exemplo n.º 3
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);
    }
Exemplo n.º 4
0
    bool PrivilegeSet::hasPrivilege(const Privilege& desiredPrivilege) {
        if (desiredPrivilege.getActions().empty())
            return true;

        StringData resourceSearchList[2];
        resourceSearchList[0] = WILDCARD_RESOURCE;
        resourceSearchList[1] = desiredPrivilege.getResource();

        ActionSet unmetRequirements = desiredPrivilege.getActions();
        for (int i = 0; i < boost::size(resourceSearchList); ++i) {
            ResourcePrivilegeCacheEntry* entry = _lookupEntry(resourceSearchList[i]);
            if (NULL == entry)
                continue;
            if (entry->dirty)
                _rebuildEntry(resourceSearchList[i], entry);
            unmetRequirements.removeAllActionsFromSet(entry->actions);
            if (unmetRequirements.empty())
                return true;
        }
        return false;
    }
Exemplo n.º 5
0
    Status AuthorizationManager::_probeForPrivilege(const Privilege& privilege) {
        Privilege modifiedPrivilege = _modifyPrivilegeForSpecialCases(privilege);
        if (_acquiredPrivileges.hasPrivilege(modifiedPrivilege))
            return Status::OK();

        std::string dbname = nsToDatabase(modifiedPrivilege.getResource());
        for (PrincipalSet::iterator iter = _authenticatedPrincipals.begin(),
                 end = _authenticatedPrincipals.end();
             iter != end; ++iter) {

            Principal* principal = *iter;
            if (!principal->isImplicitPrivilegeAcquisitionEnabled())
                continue;
            if (principal->isDatabaseProbed(dbname))
                continue;
            _acquirePrivilegesForPrincipalFromDatabase(dbname, principal->getName());
            principal->markDatabaseAsProbed(dbname);
            if (_acquiredPrivileges.hasPrivilege(modifiedPrivilege))
                return Status::OK();
        }
        return Status(ErrorCodes::Unauthorized, "unauthorized", 0);
    }
Exemplo n.º 6
0
    Status AuthorizationSession::_checkAuthForPrivilegeHelper(const Privilege& privilege) {
        AuthorizationManager& authMan = getAuthorizationManager();
        Privilege modifiedPrivilege = _modifyPrivilegeForSpecialCases(privilege);

        // Need to check not just the resource of the privilege, but also just the database
        // component and the "*" resource.
        std::string resourceSearchList[3];
        resourceSearchList[0] = AuthorizationManager::WILDCARD_RESOURCE_NAME;
        resourceSearchList[1] = nsToDatabase(modifiedPrivilege.getResource());
        resourceSearchList[2] = modifiedPrivilege.getResource();


        ActionSet unmetRequirements = modifiedPrivilege.getActions();
        UserSet::iterator it = _authenticatedUsers.begin();
        while (it != _authenticatedUsers.end()) {
            User* user = *it;

            if (!user->isValid()) {
                // Make a good faith effort to acquire an up-to-date user object, since the one
                // we've cached is marked "out-of-date."
                UserName name = user->getName();
                User* updatedUser;

                Status status = authMan.acquireUser(name, &updatedUser);
                switch (status.code()) {
                case ErrorCodes::OK: {
                    // Success! Replace the old User object with the updated one.
                    fassert(17067, _authenticatedUsers.replaceAt(it, updatedUser) == user);
                    authMan.releaseUser(user);
                    user = updatedUser;
                    LOG(1) << "Updated session cache of user information for " << name;
                    break;
                }
                case ErrorCodes::UserNotFound: {
                    // User does not exist anymore; remove it from _authenticatedUsers.
                    fassert(17068, _authenticatedUsers.removeAt(it) == user);
                    authMan.releaseUser(user);
                    LOG(1) << "Removed deleted user " << name <<
                        " from session cache of user information.";
                    continue;  // No need to advance "it" in this case.
                }
                default:
                    // Unrecognized error; assume that it's transient, and continue working with the
                    // out-of-date privilege data.
                    warning() << "Could not fetch updated user privilege information for " <<
                        name << "; continuing to use old information.  Reason is " << status;
                    break;
                }
            }

            for (int i = 0; i < static_cast<int>(boost::size(resourceSearchList)); ++i) {
                ActionSet userActions = user->getActionsForResource(resourceSearchList[i]);
                unmetRequirements.removeAllActionsFromSet(userActions);

                if (unmetRequirements.empty())
                    return Status::OK();
            }
            ++it;
        }

        return Status(ErrorCodes::Unauthorized, "unauthorized");
    }