bool run(OperationContext* opCtx,
             const string& dbname,
             const BSONObj& cmdObj,
             BSONObjBuilder& result) {
        Status status = auth::parseDropAllRolesFromDatabaseCommand(cmdObj, dbname);
        uassertStatusOK(status);

        ServiceContext* serviceContext = opCtx->getClient()->getServiceContext();
        stdx::lock_guard<stdx::mutex> lk(getAuthzDataMutex(serviceContext));

        AuthorizationManager* authzManager = AuthorizationManager::get(serviceContext);
        status = requireWritableAuthSchema28SCRAM(opCtx, authzManager);
        uassertStatusOK(status);

        // Remove these roles from all users
        long long nMatched;
        status = updateAuthzDocuments(
            opCtx,
            AuthorizationManager::usersCollectionNamespace,
            BSON("roles" << BSON(AuthorizationManager::ROLE_DB_FIELD_NAME << dbname)),
            BSON("$pull" << BSON("roles"
                                 << BSON(AuthorizationManager::ROLE_DB_FIELD_NAME << dbname))),
            false,
            true,
            &nMatched);
        // Must invalidate even on bad status - what if the write succeeded but the GLE failed?
        authzManager->invalidateUserCache();
        if (!status.isOK()) {
            uassertStatusOK(useDefaultCode(status, ErrorCodes::UserModificationFailed)
                                .withContext(str::stream() << "Failed to remove roles from \""
                                                           << dbname
                                                           << "\" db from all users"));
        }

        // Remove these roles from all other roles
        std::string sourceFieldName = str::stream() << "roles."
                                                    << AuthorizationManager::ROLE_DB_FIELD_NAME;
        status = updateAuthzDocuments(
            opCtx,
            AuthorizationManager::rolesCollectionNamespace,
            BSON(sourceFieldName << dbname),
            BSON("$pull" << BSON("roles"
                                 << BSON(AuthorizationManager::ROLE_DB_FIELD_NAME << dbname))),
            false,
            true,
            &nMatched);
        // Must invalidate even on bad status - what if the write succeeded but the GLE failed?
        authzManager->invalidateUserCache();
        if (!status.isOK()) {
            uassertStatusOK(useDefaultCode(status, ErrorCodes::RoleModificationFailed)
                                .withContext(str::stream() << "Failed to remove roles from \""
                                                           << dbname
                                                           << "\" db from all roles"));
        }

        audit::logDropAllRolesFromDatabase(Client::getCurrent(), dbname);
        // Finally, remove the actual role documents
        status = removeRoleDocuments(
            opCtx, BSON(AuthorizationManager::ROLE_DB_FIELD_NAME << dbname), &nMatched);
        // Must invalidate even on bad status - what if the write succeeded but the GLE failed?
        authzManager->invalidateUserCache();
        if (!status.isOK()) {
            uassertStatusOK(status.withContext(
                str::stream() << "Removed roles from \"" << dbname
                              << "\" db "
                                 " from all users and roles but failed to actually delete"
                                 " those roles themselves"));
        }

        result.append("n", nMatched);

        return true;
    }