blob: 9c793a6791b88f87c8ab2225a9eeabe12ef6b46f [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.
#ifndef __LINUX_CAPABILITIES_HPP__
#define __LINUX_CAPABILITIES_HPP__
#include <set>
#include <stout/flags.hpp>
#include <stout/nothing.hpp>
#include <stout/protobuf.hpp>
#include <stout/try.hpp>
#include <mesos/mesos.hpp>
namespace mesos {
namespace internal {
namespace capabilities {
// Superset of all capabilities. This is the set currently supported
// by linux (kernel 4.0).
enum Capability : int
{
CHOWN = 0,
DAC_OVERRIDE = 1,
DAC_READ_SEARCH = 2,
FOWNER = 3,
FSETID = 4,
KILL = 5,
SETGID = 6,
SETUID = 7,
SETPCAP = 8,
LINUX_IMMUTABLE = 9,
NET_BIND_SERVICE = 10,
NET_BROADCAST = 11,
NET_ADMIN = 12,
NET_RAW = 13,
IPC_LOCK = 14,
IPC_OWNER = 15,
SYS_MODULE = 16,
SYS_RAWIO = 17,
SYS_CHROOT = 18,
SYS_PTRACE = 19,
SYS_PACCT = 20,
SYS_ADMIN = 21,
SYS_BOOT = 22,
SYS_NICE = 23,
SYS_RESOURCE = 24,
SYS_TIME = 25,
SYS_TTY_CONFIG = 26,
MKNOD = 27,
LEASE = 28,
AUDIT_WRITE = 29,
AUDIT_CONTROL = 30,
SETFCAP = 31,
MAC_OVERRIDE = 32,
MAC_ADMIN = 33,
SYSLOG = 34,
WAKE_ALARM = 35,
BLOCK_SUSPEND = 36,
AUDIT_READ = 37,
MAX_CAPABILITY = 38,
};
enum Type
{
EFFECTIVE,
PERMITTED,
INHERITABLE,
BOUNDING,
AMBIENT,
};
/**
* Encapsulation of capability value sets.
*/
class ProcessCapabilities
{
public:
const std::set<Capability>& get(const Type& type) const;
void set(const Type& type, const std::set<Capability>& capabilities);
void add(const Type& type, const Capability& capability);
void drop(const Type& type, const Capability& capability);
bool operator==(const ProcessCapabilities& right) const
{
return right.effective == effective &&
right.permitted == permitted &&
right.inheritable == inheritable &&
right.bounding == bounding &&
right.ambient == ambient;
}
private:
friend std::ostream& operator<<(
std::ostream& stream,
const ProcessCapabilities& processCapabilities);
std::set<Capability> effective;
std::set<Capability> permitted;
std::set<Capability> inheritable;
std::set<Capability> bounding;
std::set<Capability> ambient;
};
/**
* Provides wrapper for the linux process capabilities interface.
* Note: This is a class instead of an interface because it has state
* associated with it.
*
* TODO(jojy): Currently we only support linux capabilities. Consider
* refactoring the interface so that we can support a generic
* interface which can be used for other OSes(BSD, Windows etc).
*/
class Capabilities
{
public:
/**
* Factory method to create Capabilities object.
*
* @return `Capabilities` on success;
* Error on failure. Failure conditions could be:
* - Error getting system information (e.g, version).
* - Unsupported linux kernel capabilities version.
* - Maximum capability supported by kernel exceeds the
* ones defined in the enum `Capabilities`.
*/
static Try<Capabilities> create();
/**
* Gets capability set for the calling process.
*
* @return ProcessCapabilities on success.
* Error on failure.
*/
Try<ProcessCapabilities> get() const;
/**
* Sets capabilities for the calling process.
*
* @param `ProcessCapabilities` to be set for the process.
* @return Nothing on success.
* Error on failure.
*/
Try<Nothing> set(const ProcessCapabilities& processCapabilities);
/**
* Process control interface to enforce keeping the parent process's
* capabilities after a change in uid/gid.
*
* @return Nothing on success.
* Error on failure.
*/
Try<Nothing> setKeepCaps();
/**
* Get all capabilities supported by the system.
*
* @return the set of supported capabilities.
*/
std::set<Capability> getAllSupportedCapabilities();
/**
* Whether ambient capabilities are supported on this host. If
* ambient capabilities are supported, the AMBIENT set will be
* populated when getting the process capabilities and applied
* when setting them. Otherwise the AMBIENT set will be ignored.
*/
const bool ambientCapabilitiesSupported;
private:
Capabilities(int _lastCap, bool _ambientSupported);
// Maximum count of capabilities supported by the system.
const int lastCap;
};
Capability convert(const CapabilityInfo::Capability& capability);
std::set<Capability> convert(const CapabilityInfo& capabilityInfo);
CapabilityInfo convert(const std::set<Capability>& capabilitySet);
std::ostream& operator<<(
std::ostream& stream,
const Capability& capability);
std::ostream& operator<<(
std::ostream& stream,
const Type& type);
std::ostream& operator<<(
std::ostream& stream,
const ProcessCapabilities& capabilities);
} // namespace capabilities {
} // namespace internal {
} // namespace mesos {
#endif // __LINUX_CAPABILITIES_HPP__