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); }
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"); }