1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2014 Red Hat
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
14 #ifndef MDS_AUTH_CAPS_H
15 #define MDS_AUTH_CAPS_H
19 #include <string_view>
22 #include "include/common_fwd.h"
23 #include "include/types.h"
24 #include "common/debug.h"
28 // unix-style capabilities
32 MAY_EXECUTE
= (1 << 2),
35 MAY_SET_VXATTR
= (1 << 6),
36 MAY_SNAPSHOT
= (1 << 7),
41 static const unsigned ALL
= (1 << 0);
42 static const unsigned READ
= (1 << 1);
43 static const unsigned WRITE
= (1 << 2);
44 // if the capability permits setting vxattrs (layout, quota, etc)
45 static const unsigned SET_VXATTR
= (1 << 3);
46 // if the capability permits mksnap/rmsnap
47 static const unsigned SNAPSHOT
= (1 << 4);
49 static const unsigned RW
= (READ
|WRITE
);
50 static const unsigned RWP
= (READ
|WRITE
|SET_VXATTR
);
51 static const unsigned RWS
= (READ
|WRITE
|SNAPSHOT
);
52 static const unsigned RWPS
= (READ
|WRITE
|SET_VXATTR
|SNAPSHOT
);
54 MDSCapSpec() = default;
55 MDSCapSpec(unsigned _caps
) : caps(_caps
) {
60 bool allow_all() const {
63 bool allow_read() const {
66 bool allow_write() const {
67 return (caps
& WRITE
);
70 bool allows(bool r
, bool w
) const {
73 if (r
&& !allow_read())
75 if (w
&& !allow_write())
80 bool allow_snapshot() const {
81 return (caps
& SNAPSHOT
);
83 bool allow_set_vxattr() const {
84 return (caps
& SET_VXATTR
);
90 // conditions before we are allowed to do it
92 static const int64_t MDS_AUTH_UID_ANY
= -1;
94 MDSCapMatch() : uid(MDS_AUTH_UID_ANY
), fs_name(std::string()) {}
96 MDSCapMatch(int64_t uid_
, std::vector
<gid_t
>& gids_
) :
97 uid(uid_
), gids(gids_
), fs_name(std::string()) {}
99 explicit MDSCapMatch(const std::string
&path_
)
100 : uid(MDS_AUTH_UID_ANY
), path(path_
), fs_name(std::string()) {
104 explicit MDSCapMatch(std::string path
, std::string fs_name
) :
105 uid(MDS_AUTH_UID_ANY
), path(std::move(path
)), fs_name(std::move(fs_name
))
110 explicit MDSCapMatch(std::string path
, std::string fs_name
, bool root_squash_
) :
111 uid(MDS_AUTH_UID_ANY
), path(std::move(path
)), fs_name(std::move(fs_name
)), root_squash(root_squash_
)
116 MDSCapMatch(const std::string
& path_
, int64_t uid_
, std::vector
<gid_t
>& gids_
)
117 : uid(uid_
), gids(gids_
), path(path_
), fs_name(std::string()) {
121 void normalize_path();
123 bool is_match_all() const
125 return uid
== MDS_AUTH_UID_ANY
&& path
== "";
128 // check whether this grant matches against a given file and caller uid:gid
129 bool match(std::string_view target_path
,
130 const int caller_uid
,
131 const int caller_gid
,
132 const std::vector
<uint64_t> *caller_gid_list
) const;
135 * Check whether this path *might* be accessible (actual permission
136 * depends on the stronger check in match()).
138 * @param target_path filesystem path without leading '/'
140 bool match_path(std::string_view target_path
) const;
142 int64_t uid
; // Require UID to be equal to this, if !=MDS_AUTH_UID_ANY
143 std::vector
<gid_t
> gids
; // Use these GIDs
144 std::string path
; // Require path to be child of this (may be "" or "/" for any)
146 bool root_squash
=false;
150 MDSCapGrant(const MDSCapSpec
&spec_
, const MDSCapMatch
&match_
,
151 boost::optional
<std::string
> n
)
152 : spec(spec_
), match(match_
) {
160 void parse_network();
167 entity_addr_t network_parsed
;
168 unsigned network_prefix
= 0;
169 bool network_valid
= true;
175 MDSAuthCaps() = default;
176 explicit MDSAuthCaps(CephContext
*cct_
) : cct(cct_
) {}
178 // this ctor is used by spirit/phoenix; doesn't need cct.
179 explicit MDSAuthCaps(const std::vector
<MDSCapGrant
>& grants_
) : grants(grants_
) {}
185 void set_allow_all();
186 bool parse(CephContext
*cct
, std::string_view str
, std::ostream
*err
);
188 bool allow_all() const;
189 bool is_capable(std::string_view inode_path
,
190 uid_t inode_uid
, gid_t inode_gid
, unsigned inode_mode
,
191 uid_t uid
, gid_t gid
, const std::vector
<uint64_t> *caller_gid_list
,
192 unsigned mask
, uid_t new_uid
, gid_t new_gid
,
193 const entity_addr_t
& addr
) const;
194 bool path_capable(std::string_view inode_path
) const;
196 bool fs_name_capable(std::string_view fs_name
, unsigned mask
) const {
201 for (const MDSCapGrant
&g
: grants
) {
202 if (g
.match
.fs_name
== fs_name
|| g
.match
.fs_name
.empty() ||
203 g
.match
.fs_name
== "*") {
204 if (mask
& MAY_READ
&& g
.spec
.allow_read()) {
208 if (mask
& MAY_WRITE
&& g
.spec
.allow_write()) {
217 friend std::ostream
&operator<<(std::ostream
&out
, const MDSAuthCaps
&cap
);
219 CephContext
*cct
= nullptr;
220 std::vector
<MDSCapGrant
> grants
;
223 std::ostream
&operator<<(std::ostream
&out
, const MDSCapMatch
&match
);
224 std::ostream
&operator<<(std::ostream
&out
, const MDSCapSpec
&spec
);
225 std::ostream
&operator<<(std::ostream
&out
, const MDSCapGrant
&grant
);
226 std::ostream
&operator<<(std::ostream
&out
, const MDSAuthCaps
&cap
);
228 #endif // MDS_AUTH_CAPS_H