blob: 7261005522fc46953507ed02e06da3818f68a221 [file] [log] [blame]
// 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.
#pragma once
#include <memory>
#include <string>
#include <unordered_set>
#include <utility>
#include "kudu/gutil/port.h"
#include "kudu/gutil/ref_counted.h"
#include "kudu/ranger/ranger.pb.h"
#include "kudu/subprocess/server.h"
#include "kudu/subprocess/subprocess_proxy.h"
#include "kudu/util/metrics.h"
#include "kudu/util/status.h"
namespace kudu {
class Env;
namespace ranger {
struct ActionHash {
public:
int operator()(const ActionPB& action) const {
return action;
}
};
struct RangerSubprocessMetrics : public subprocess::SubprocessMetrics {
explicit RangerSubprocessMetrics(const scoped_refptr<MetricEntity>& entity);
};
typedef subprocess::SubprocessProxy<RangerRequestListPB, RangerResponseListPB,
RangerSubprocessMetrics> RangerSubprocess;
// A client for the Ranger service that communicates with a Java subprocess.
//
// The Ranger subprocess itself is configured using xml files, like
// core-site.xml and ranger-kudu-security.xml. The only configuration that is
// coming from this class are environmental, like Java binary location, location
// of config files, and krb5.conf file (setting it doesn't enable Kerberos, that
// depends on core-site.xml).
//
// These methods return non-OK status only if something goes wrong between the
// client and the subprocess (e.g. IOError, EndOfFile, Corruption), but they
// never return NotAuthorized. The authz provider is responsible to return
// NotAuthorized based on RangerClient's out parameters and return Status.
class RangerClient {
public:
// The privilege scope can indicate the hierarchy of authorizables
// (e.g. database -> table -> column). For example, authorizable 'db=a' has
// database level scope, while authorizable 'db=a->table=b' has table level scope.
// Note that COLUMN level scope is not defined in the enum as it is not
// used yet in the code (although the concept still apply when
// authorizing column level privileges).
enum Scope {
DATABASE,
TABLE
};
// Creates a Ranger client.
explicit RangerClient(Env* env, const scoped_refptr<MetricEntity>& metric_entity);
// Starts the RangerClient, initializes the subprocess server.
Status Start() WARN_UNUSED_RESULT;
// Authorizes an action on the table. Sets 'authorized' to true if it's
// authorized, false otherwise.
Status AuthorizeAction(const std::string& user_name, const ActionPB& action,
const std::string& database, const std::string& table, bool* authorized,
Scope scope = Scope::TABLE) WARN_UNUSED_RESULT;
// Authorizes action on multiple tables. It sets 'table_names' to the
// tables the user is authorized to access.
Status AuthorizeActionMultipleTables(const std::string& user_name, const ActionPB& action,
std::unordered_set<std::string>* tables)
WARN_UNUSED_RESULT;
// Authorizes action on multiple columns. It sets 'column_names' to the
// columns the user is authorized to access.
Status AuthorizeActionMultipleColumns(const std::string& user_name, const ActionPB& action,
const std::string& database, const std::string& table,
std::unordered_set<std::string>* column_names)
WARN_UNUSED_RESULT;
// Authorizes multiple table-level actions on a single table. It sets
// 'actions' to the actions the user is authorized to perform.
Status AuthorizeActions(const std::string& user_name, const std::string& database,
const std::string& table,
std::unordered_set<ActionPB, ActionHash>* actions) WARN_UNUSED_RESULT;
// Replaces the subprocess server in the subprocess proxy.
void ReplaceServerForTests(std::unique_ptr<subprocess::SubprocessServer> server) {
// Creates a dummy RangerSubprocess if it is not initialized.
if (!subprocess_) {
subprocess_.reset(new RangerSubprocess(env_, "", {""}, metric_entity_));
}
subprocess_->ReplaceServerForTests(std::move(server));
}
private:
Env* env_;
std::unique_ptr<RangerSubprocess> subprocess_;
scoped_refptr<MetricEntity> metric_entity_;
};
} // namespace ranger
} // namespace kudu