/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * Copyright (C) 2017 ScyllaDB * * Modified by ScyllaDB */ /* * This file is part of Scylla. * * Scylla is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Scylla is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Scylla. If not, see . */ #include "authenticator.hh" #include "authenticated_user.hh" #include "authenticator.hh" #include "authorizer.hh" #include "password_authenticator.hh" #include "default_authorizer.hh" #include "permission.hh" #include "auth.hh" #include "db/config.hh" #include "utils/class_registrator.hh" namespace auth { static const sstring PACKAGE_NAME("com.scylladb.auth."); static const sstring TRANSITIONAL_AUTHENTICATOR_NAME(PACKAGE_NAME + "TransitionalAuthenticator"); static const sstring TRANSITIONAL_AUTHORIZER_NAME(PACKAGE_NAME + "TransitionalAuthorizer"); class transitional_authenticator : public authenticator { std::unique_ptr _authenticator; public: static const sstring PASSWORD_AUTHENTICATOR_NAME; transitional_authenticator() : transitional_authenticator(std::make_unique()) {} transitional_authenticator(std::unique_ptr a) : _authenticator(std::move(a)) {} future<> init() override { return _authenticator->init(); } const sstring& class_name() const override { return TRANSITIONAL_AUTHENTICATOR_NAME; } bool require_authentication() const override { return true; } option_set supported_options() const override { return _authenticator->supported_options(); } option_set alterable_options() const override { return _authenticator->alterable_options(); } future<::shared_ptr> authenticate(const credentials_map& credentials) const override { auto i = credentials.find(authenticator::USERNAME_KEY); if ((i == credentials.end() || i->second.empty()) && (!credentials.count(PASSWORD_KEY) || credentials.at(PASSWORD_KEY).empty())) { // return anon user return make_ready_future<::shared_ptr>(::make_shared()); } return make_ready_future().then([this, &credentials] { return _authenticator->authenticate(credentials); }).handle_exception([](auto ep) { try { std::rethrow_exception(ep); } catch (exceptions::authentication_exception&) { // return anon user return make_ready_future<::shared_ptr>(::make_shared()); } }); } future<> create(sstring username, const option_map& options) override { return _authenticator->create(username, options); } future<> alter(sstring username, const option_map& options) override { return _authenticator->alter(username, options); } future<> drop(sstring username) override { return _authenticator->drop(username); } const resource_ids& protected_resources() const override { return _authenticator->protected_resources(); } ::shared_ptr new_sasl_challenge() const override { class sasl_wrapper : public sasl_challenge { public: sasl_wrapper(::shared_ptr sasl) : _sasl(std::move(sasl)) {} bytes evaluate_response(bytes_view client_response) override { try { return _sasl->evaluate_response(client_response); } catch (exceptions::authentication_exception&) { _complete = true; return {}; } } bool is_complete() const { return _complete || _sasl->is_complete(); } future<::shared_ptr> get_authenticated_user() const { return _sasl->get_authenticated_user(); } private: ::shared_ptr _sasl; bool _complete = false; }; return ::make_shared(_authenticator->new_sasl_challenge()); } }; class transitional_authorizer : public authorizer { std::unique_ptr _authorizer; public: transitional_authorizer() : transitional_authorizer(std::make_unique()) {} transitional_authorizer(std::unique_ptr a) : _authorizer(std::move(a)) {} ~transitional_authorizer() {} future<> init() override { return _authorizer->init(); } future authorize(::shared_ptr user, data_resource resource) const override { return user->is_super().then([](bool s) { static const permission_set transitional_permissions = permission_set::of(); return make_ready_future(s ? permissions::ALL : transitional_permissions); }); } future<> grant(::shared_ptr user, permission_set ps, data_resource r, sstring s) override { return _authorizer->grant(std::move(user), std::move(ps), std::move(r), std::move(s)); } future<> revoke(::shared_ptr user, permission_set ps, data_resource r, sstring s) override { return _authorizer->revoke(std::move(user), std::move(ps), std::move(r), std::move(s)); } future> list(::shared_ptr user, permission_set ps, optional r, optional s) const override { return _authorizer->list(std::move(user), std::move(ps), std::move(r), std::move(s)); } future<> revoke_all(sstring s) override { return _authorizer->revoke_all(std::move(s)); } future<> revoke_all(data_resource r) override { return _authorizer->revoke_all(std::move(r)); } const resource_ids& protected_resources() override { return _authorizer->protected_resources(); } future<> validate_configuration() const override { return _authorizer->validate_configuration(); } }; } static const class_registrator transitional_authenticator_reg( auth::TRANSITIONAL_AUTHENTICATOR_NAME); static const class_registrator transitional_authorizer_reg( auth::TRANSITIONAL_AUTHORIZER_NAME);