Example #1
0
    bool AuthorizationSession::_isAuthorizedForPrivilege(const Privilege& privilege) {
        AuthorizationManager& authMan = getAuthorizationManager();
        const ResourcePattern& target(privilege.getResourcePattern());

        ResourcePattern resourceSearchList[resourceSearchListCapacity];
        const int resourceSearchListLength = buildResourceSearchList(target, resourceSearchList);

        ActionSet unmetRequirements = privilege.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 < resourceSearchListLength; ++i) {
                ActionSet userActions = user->getActionsForResource(resourceSearchList[i]);
                unmetRequirements.removeAllActionsFromSet(userActions);

                if (unmetRequirements.empty())
                    return true;
            }
            ++it;
        }

        return false;
    }
    bool AuthorizationSession::_isAuthorizedForPrivilege(const Privilege& privilege) {
        const ResourcePattern& target(privilege.getResourcePattern());

        ResourcePattern resourceSearchList[resourceSearchListCapacity];
        const int resourceSearchListLength = buildResourceSearchList(target, resourceSearchList);

        ActionSet unmetRequirements = privilege.getActions();

        for (UserSet::iterator it = _authenticatedUsers.begin();
                it != _authenticatedUsers.end(); ++it) {
            User* user = *it;

            if (user->getSchemaVersion() == AuthorizationManager::schemaVersion24 &&
                (target.isDatabasePattern() || target.isExactNamespacePattern()) &&
                !user->hasProbedV1(target.databaseToMatch())) {

                UserName name = user->getName();
                User* updatedUser;
                Status status = getAuthorizationManager().acquireV1UserProbedForDb(
                        name,
                        target.databaseToMatch(),
                        &updatedUser);
                if (status.isOK()) {
                    if (user != updatedUser) {
                        LOG(1) << "Updated session cache with privileges on the " <<
                                target.databaseToMatch() << " database for V1 user " << name;
                        fassert(17226, _authenticatedUsers.replaceAt(it, updatedUser) == user);
                    }
                    getAuthorizationManager().releaseUser(user);
                    user = updatedUser;
                }
                else if (status != ErrorCodes::UserNotFound) {
                    warning() << "Could not fetch updated user privilege information for V1-style "
                        "user " << name << "; continuing to use old information.  Reason is "
                              << status;
                }
            }

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

                if (unmetRequirements.empty())
                    return true;
            }
        }

        return false;
    }
    bool AuthorizationSession::isAuthorizedToChangeOwnCustomDataAsUser(const UserName& userName) {
        User* user = lookupUser(userName);
        if (!user) {
            return false;
        }
        ResourcePattern resourceSearchList[resourceSearchListCapacity];
        const int resourceSearchListLength =
                buildResourceSearchList(ResourcePattern::forClusterResource(), resourceSearchList);

        ActionSet actions;
        for (int i = 0; i < resourceSearchListLength; ++i) {
            actions.addAllActionsFromSet(user->getActionsForResource(resourceSearchList[i]));
        }
        return actions.contains(ActionType::changeOwnCustomData);
    }